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

Subversion Repositories System68

[/] [System68/] [tags/] [arelease/] [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
-- doesn't do anything yet
90
--
91
--------------------------------
92
timer_write : process( clk, rst, cs, rw, addr, data_in,
93
                       timer_reg, timer_ctrl, timer_count )
94
begin
95
  if clk'event and clk = '1' then
96
    if rst = '1' then
97
           timer_reg <= "00000000";
98
                timer_ctrl <= "00000000";
99
    elsif cs = '1' and rw = '0' then
100
           if addr='0' then
101
                  timer_reg <= data_in;
102
                  timer_ctrl <= timer_ctrl;
103
                  timer_term <= '0';
104
           else
105
                  timer_reg <= timer_reg;
106
                  timer_ctrl <= data_in;
107
                  timer_term <= timer_term;
108
                end if;
109
         else
110
           timer_ctrl <= timer_ctrl;
111
                timer_reg <= timer_reg;
112
           if (timer_ctrl(T_enab) = '1') then
113
                  if (timer_count = "00000000" ) then
114
                    timer_term <= '1';
115
                  elsif timer_ctrl(T_mode) = '0' then
116
                    timer_term <= '0'; -- counter mode, reset on non zero
117
                  else
118
                    timer_term <= timer_term; -- timer mode, keep as is
119
                  end if;
120
                else
121
                  timer_term <= timer_term;
122
                end if;
123
    end if;
124
  end if;
125
end process;
126
 
127
--
128
-- timer data output mux
129
--
130
timer_read : process( addr, timer_count, timer_stat )
131
begin
132
  if addr='0' then
133
    data_out <= timer_count;
134
  else
135
    data_out <= timer_stat;
136
  end if;
137
end process;
138
 
139
--------------------------------
140
--
141
-- counters
142
--
143
--------------------------------
144
 
145
my_counter: process( clk, rst, timer_ctrl, timer_count, timer_in )
146
variable timer_tmp : std_logic;
147
begin
148
  if clk'event and clk='1' then
149
    if rst = '1' then
150
           timer_count <= "00000000";
151
                timer_tmp := '0';
152
    else
153
      if timer_ctrl( T_enab ) = '1' then
154
                  if timer_in = '0' and timer_tmp = '1' then
155
                    timer_tmp := '0';
156
          if timer_count = "00000000" then
157
                      timer_count <= timer_reg;
158
                    else
159
                 timer_count <= timer_count - 1;
160
                    end if;
161
                  elsif timer_in = '1' and timer_tmp = '0' then
162
                    timer_tmp := '1';
163
               timer_count <= timer_count;
164
                  else
165
                    timer_tmp := timer_tmp;
166
               timer_count <= timer_count;
167
                  end if;
168
                else
169
                  timer_tmp := timer_tmp;
170
             timer_count <= timer_count;
171
           end if; -- timer_ctrl
172
    end if; -- rst
173
  end if; -- clk
174
end process;
175
 
176
--
177
-- read timer strobe to reset interrupts
178
--
179
  timer_interrupt : process( Clk, rst, cs, rw, addr,
180
                             timer_term, timer_int, timer_count, timer_ctrl )
181
  begin
182
    if clk'event and clk = '1' then
183
           if rst = '1' then
184
                  timer_int <= '0';
185
      elsif cs = '1' and rw = '1' then
186
             if addr = '0' then
187
                    timer_int <= '0'; -- reset interrupt on read count
188
                  else
189
                    timer_int <= timer_int;
190
                  end if;
191
           else
192
             if timer_term = '1' then
193
                    timer_int <= '1';
194
                  else
195
                    timer_int <= timer_int;
196
                  end if;
197
      end if;
198
    end if;
199
 
200
    if timer_ctrl( T_irq ) = '1' then
201
           irq <= timer_int;
202
         else
203
           irq <= '0';
204
         end if;
205
  end process;
206
 
207
  --
208
  -- timer status register
209
  --
210
  timer_status : process( timer_ctrl, timer_int, timer_tog )
211
  begin
212
    timer_stat(5 downto 0) <= timer_ctrl(5 downto 0);
213
         timer_stat(T_out) <= timer_tog;
214
    timer_stat(T_irq) <= timer_int;
215
  end process;
216
 
217
  --
218
  -- timer output
219
  --
220
  timer_output : process( Clk, rst, timer_term, timer_ctrl, timer_tog )
221
  variable timer_tmp : std_logic; -- tracks change in terminal count
222
  begin
223
    if clk'event and clk='1' then
224
      if rst = '1' then
225
             timer_tog <= '0';
226
                  timer_tmp := '0';
227
           elsif timer_ctrl(T_mode) = '0' then -- free running ?
228
                  if (timer_term = '1') and (timer_tmp = '0') then
229
                    timer_tmp := '1';
230
                         timer_tog <= not timer_tog;
231
                  elsif (timer_term = '0') and (timer_tmp = '1') then
232
                    timer_tmp := '0';
233
                         timer_tog <= timer_tog;
234
                  else
235
                    timer_tmp := timer_tmp;
236
                         timer_tog <= timer_tog;
237
                  end if;
238
                else                            -- one shot timer mode, follow terminal count
239
                  if (timer_term = '1') and (timer_tmp = '0') then
240
                    timer_tmp := '1';
241
                         timer_tog <= '1';
242
                  elsif (timer_term = '0') and (timer_tmp = '1') then
243
                    timer_tmp := '0';
244
                         timer_tog <= '0';
245
                  else
246
                    timer_tmp := timer_tmp;
247
                         timer_tog <= timer_tog;
248
                  end if;
249
                end if;
250
         end if;
251
    timer_out <= timer_tog and timer_ctrl(T_out);
252
  end process;
253
 
254
end timer_arch;
255
 

powered by: WebSVN 2.1.0

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