OpenCores
URL https://opencores.org/ocsvn/System68/System68/trunk

Subversion Repositories System68

[/] [System68/] [trunk/] [vhdl/] [timer.vhd] - Blame information for rev 8

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 dilbert57
--===========================================================================--
2
--
3
--  S Y N T H E Z I A B L E    Timer   C O R E
4
--
5
--  www.OpenCores.Org - December 2002
6
--  This core adheres to the GNU public license  
7
--
8
-- File name      : timer.vhd
9
--
10
-- entity name    : timer
11
--
12
-- Purpose        : Implements a 8 bit timer module
13
--
14
-- Dependencies   : ieee.Std_Logic_1164
15
--                  ieee.std_logic_unsigned
16
--
17
-- Author         : John E. Kent      
18
--
19
--===========================================================================----
20
--
21
-- Revision History:
22
--
23
-- Date:          Revision         Author
24
-- ?? Sep 2002    0.1              John Kent
25
-- Initial version ( 3 timers )
26
--
27
-- 6 Sep 2002     1.0              John Kent
28
-- converted to a single timer 
29
-- made syncronous with system clock
30
--
31
--===========================================================================----
32
--
33
-- Register Memory Map
34
--
35
-- addr=0 read  down count
36
-- addr=0 write preset count
37
-- addr=1 read  status
38
-- addr=1 write control
39
--
40
-- Control register
41
-- b0 = counter enable
42
-- b1 = mode (0 = counter, 1 = timer)
43
-- b7 = interrupt enable
44
--
45
-- Status register
46
-- b6 = timer output
47
-- b7 = interrupt flag
48
--
49
library ieee;
50
use ieee.std_logic_1164.all;
51
use ieee.std_logic_unsigned.all;
52
 
53
entity timer is
54
        port (
55
         clk        : in  std_logic;
56
    rst        : in  std_logic;
57
    cs         : in  std_logic;
58
    rw         : in  std_logic;
59
    addr       : in  std_logic;
60
    data_in    : in  std_logic_vector(7 downto 0);
61
         data_out   : out std_logic_vector(7 downto 0);
62
         irq        : out std_logic;
63
         timer_in   : in  std_logic;
64
         timer_out  : out std_logic
65
  );
66
end;
67
 
68
architecture timer_arch of timer is
69
signal timer_ctrl  : std_logic_vector(7 downto 0);
70
signal timer_stat  : std_logic_vector(7 downto 0);
71
signal timer_reg   : std_logic_vector(7 downto 0);
72
signal timer_count : std_logic_vector(7 downto 0);
73
signal timer_int   : std_logic; -- Timer interrupt
74
signal timer_term  : std_logic; -- Timer terminal count
75
signal timer_tog   : std_logic; -- Timer output
76
--
77
-- control/status register bits
78
--
79
constant T_enab   : integer := 0; -- 0=disable, 1=enabled
80
constant T_mode   : integer := 1; -- 0=counter, 1=timer
81
constant T_out    : integer := 6; -- 0=disabled, 1=enabled
82
constant T_irq    : integer := 7; -- 0=disabled, 1-enabled
83
 
84
begin
85
 
86
--------------------------------
87
--
88
-- write control registers
89
--
90
--------------------------------
91 6 dilbert57
timer_write : process( clk, rst, cs, rw, addr,
92
                       data_in, timer_reg, timer_ctrl )
93 4 dilbert57
begin
94 6 dilbert57
  if rst = '1' then
95
           timer_reg  <= "00000000";
96 4 dilbert57
                timer_ctrl <= "00000000";
97 6 dilbert57
  elsif clk'event and clk = '0' then
98
    if cs = '1' and rw = '0' then
99 4 dilbert57
           if addr='0' then
100 6 dilbert57
                  timer_reg  <= data_in;
101 4 dilbert57
                  timer_ctrl <= timer_ctrl;
102
           else
103 6 dilbert57
                  timer_reg  <= timer_reg;
104 4 dilbert57
                  timer_ctrl <= data_in;
105
                end if;
106
         else
107
           timer_ctrl <= timer_ctrl;
108 6 dilbert57
                timer_reg  <= timer_reg;
109 4 dilbert57
    end if;
110
  end if;
111
end process;
112
 
113
--
114
-- timer data output mux
115
--
116
timer_read : process( addr, timer_count, timer_stat )
117
begin
118
  if addr='0' then
119
    data_out <= timer_count;
120
  else
121
    data_out <= timer_stat;
122
  end if;
123
end process;
124
 
125 6 dilbert57
 
126 4 dilbert57
--------------------------------
127
--
128 6 dilbert57
-- Terminal Count
129
--
130
--------------------------------
131
timer_terminal : process( clk, rst, cs, rw, addr, data_in,
132
                       timer_term, timer_ctrl, timer_count )
133
begin
134
  if rst = '1' then
135
                timer_term <= '0';
136
  elsif clk'event and clk = '0' then
137
    if cs = '1' and rw = '0' then
138
           if addr='0' then
139
                  -- Reset terminal count on write to counter
140
                  timer_term <= '0';
141
           else
142
                  timer_term <= timer_term;
143
                end if;
144
         else
145
           if (timer_ctrl(T_enab) = '1') then
146
                  if (timer_count = "00000000" ) then
147
                    -- If timer enabled, set terminal output on zero count
148
                    timer_term <= '1';
149
                  elsif timer_ctrl(T_mode) = '0' then
150
                         -- counter mode, reset on non zero
151
                    timer_term <= '0';
152
                  else
153
                         -- timer mode, keep as is
154
                    timer_term <= timer_term;
155
                  end if; -- timer count
156
                else
157
                  timer_term <= timer_term;
158
                end if; -- timer ctrl
159
    end if;     -- cs
160
  end if;  -- rst / clk
161
end process;
162
 
163
 
164
--------------------------------
165
--
166 4 dilbert57
-- counters
167
--
168
--------------------------------
169
 
170 6 dilbert57
timer_counter: process( clk, rst, timer_ctrl, timer_count, timer_in )
171 4 dilbert57
variable timer_tmp : std_logic;
172
begin
173 6 dilbert57
  if rst = '1' then
174 4 dilbert57
           timer_count <= "00000000";
175
                timer_tmp := '0';
176 6 dilbert57
  elsif clk'event and clk = '0' then
177 4 dilbert57
      if timer_ctrl( T_enab ) = '1' then
178
                  if timer_in = '0' and timer_tmp = '1' then
179
                    timer_tmp := '0';
180
          if timer_count = "00000000" then
181
                      timer_count <= timer_reg;
182
                    else
183
                 timer_count <= timer_count - 1;
184
                    end if;
185
                  elsif timer_in = '1' and timer_tmp = '0' then
186
                    timer_tmp := '1';
187
               timer_count <= timer_count;
188
                  else
189
                    timer_tmp := timer_tmp;
190
               timer_count <= timer_count;
191
                  end if;
192
                else
193
                  timer_tmp := timer_tmp;
194
             timer_count <= timer_count;
195
           end if; -- timer_ctrl
196 6 dilbert57
  end if; -- rst / clk
197 4 dilbert57
end process;
198
 
199
--
200
-- read timer strobe to reset interrupts
201
--
202
  timer_interrupt : process( Clk, rst, cs, rw, addr,
203
                             timer_term, timer_int, timer_count, timer_ctrl )
204
  begin
205 6 dilbert57
    if clk'event and clk = '0' then
206 4 dilbert57
           if rst = '1' then
207
                  timer_int <= '0';
208
      elsif cs = '1' and rw = '1' then
209
             if addr = '0' then
210 6 dilbert57
                         -- reset interrupt on read count
211
                    timer_int <= '0';
212 4 dilbert57
                  else
213
                    timer_int <= timer_int;
214
                  end if;
215
           else
216
             if timer_term = '1' then
217
                    timer_int <= '1';
218
                  else
219
                    timer_int <= timer_int;
220
                  end if;
221
      end if;
222
    end if;
223 6 dilbert57
  end process;
224 4 dilbert57
 
225 6 dilbert57
--
226
-- read timer strobe to reset interrupts
227
--
228
  timer_irq : process( timer_int, timer_ctrl )
229
  begin
230 4 dilbert57
    if timer_ctrl( T_irq ) = '1' then
231
           irq <= timer_int;
232
         else
233
           irq <= '0';
234
         end if;
235
  end process;
236
 
237
  --
238
  -- timer status register
239
  --
240
  timer_status : process( timer_ctrl, timer_int, timer_tog )
241
  begin
242
    timer_stat(5 downto 0) <= timer_ctrl(5 downto 0);
243
         timer_stat(T_out) <= timer_tog;
244
    timer_stat(T_irq) <= timer_int;
245
  end process;
246
 
247
  --
248
  -- timer output
249
  --
250
  timer_output : process( Clk, rst, timer_term, timer_ctrl, timer_tog )
251
  variable timer_tmp : std_logic; -- tracks change in terminal count
252
  begin
253 6 dilbert57
    if clk'event and clk = '0' then
254 4 dilbert57
      if rst = '1' then
255
             timer_tog <= '0';
256
                  timer_tmp := '0';
257
           elsif timer_ctrl(T_mode) = '0' then -- free running ?
258
                  if (timer_term = '1') and (timer_tmp = '0') then
259
                    timer_tmp := '1';
260
                         timer_tog <= not timer_tog;
261
                  elsif (timer_term = '0') and (timer_tmp = '1') then
262
                    timer_tmp := '0';
263
                         timer_tog <= timer_tog;
264
                  else
265
                    timer_tmp := timer_tmp;
266
                         timer_tog <= timer_tog;
267
                  end if;
268
                else                            -- one shot timer mode, follow terminal count
269
                  if (timer_term = '1') and (timer_tmp = '0') then
270
                    timer_tmp := '1';
271
                         timer_tog <= '1';
272
                  elsif (timer_term = '0') and (timer_tmp = '1') then
273
                    timer_tmp := '0';
274
                         timer_tog <= '0';
275
                  else
276
                    timer_tmp := timer_tmp;
277
                         timer_tog <= timer_tog;
278
                  end if;
279
                end if;
280
         end if;
281
    timer_out <= timer_tog and timer_ctrl(T_out);
282
  end process;
283
 
284
end timer_arch;
285
 

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.