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

Subversion Repositories System11

[/] [System11/] [trunk/] [rtl/] [vhdl/] [timer.vhd] - Blame information for rev 5

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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