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

Subversion Repositories System09

[/] [System09/] [tags/] [V10/] [rtl/] [vhdl/] [timer.vhd] - Blame information for rev 201

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

powered by: WebSVN 2.1.0

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