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

Subversion Repositories simpcon

[/] [simpcon/] [trunk/] [vhdl/] [sc_cnt.vhd] - Blame information for rev 29

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 18 martin
--
2 29 martin
--
3
--  This file is a part of JOP, the Java Optimized Processor
4
--
5
--  Copyright (C) 2001-2008, Martin Schoeberl (martin@jopdesign.com)
6
--
7
--  This program is free software: you can redistribute it and/or modify
8
--  it under the terms of the GNU General Public License as published by
9
--  the Free Software Foundation, either version 3 of the License, or
10
--  (at your option) any later version.
11
--
12
--  This program is distributed in the hope that it will be useful,
13
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
--  GNU General Public License for more details.
16
--
17
--  You should have received a copy of the GNU General Public License
18
--  along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
--
20
 
21
 
22
--
23 18 martin
--      sc_cnt.vhd
24
--
25
--      counter, interrrupt handling and watchdog bit
26
--
27
--      Author: Martin Schoeberl        martin@good-ear.com
28
--
29
--              address map:
30
--
31
--                      0        read clk counter, write irq ena
32
--                      1       read 1 MHz counter, write timer val (us) + irq ack
33
--                      2       write generates sw-int (for yield())
34
--                      3       write wd port
35
--                      4       write generates SW exception, read exception reason
36
--
37
--      todo:
38
--
39
--
40
--      2003-07-05      new IO standard
41
--      2003-08-15      us counter, irq added
42
--      2005-11-30      change interface to SimpCon
43
--      2006-01-11      added exception
44
--      2007-03-17      changed interrupts to records
45
--
46
 
47
library ieee;
48
use ieee.std_logic_1164.all;
49
use ieee.numeric_std.all;
50
 
51
use work.jop_types.all;
52
 
53
entity sc_cnt is
54
 
55
generic (addr_bits : integer;
56
        clk_freq : integer);
57
port (
58
        clk             : in std_logic;
59
        reset   : in std_logic;
60
 
61
-- SimpCon interface
62
 
63
        address         : in std_logic_vector(addr_bits-1 downto 0);
64
        wr_data         : in std_logic_vector(31 downto 0);
65
        rd, wr          : in std_logic;
66
        rd_data         : out std_logic_vector(31 downto 0);
67
        rdy_cnt         : out unsigned(1 downto 0);
68
 
69
--
70
--      Interrupts from IO devices
71
--
72
        irq_in          : out irq_in_type;
73
        exc_req         : in exception_type;
74
 
75
        wd              : out std_logic
76
);
77
end sc_cnt ;
78
 
79
architecture rtl of sc_cnt is
80
 
81
        signal clock_cnt                : std_logic_vector(31 downto 0);
82
        signal pre_scale                : std_logic_vector(7 downto 0);
83
        signal us_cnt                   : std_logic_vector(31 downto 0);
84
 
85
        constant div_val        : integer := clk_freq/1000000-1;
86
 
87
        signal timer_int                : std_logic;
88
        signal yield_int                : std_logic;
89
        signal int_ack                  : std_logic;
90
 
91
        signal timer                    : std_logic;
92
        signal yield                    : std_logic;
93
 
94
        signal irq_cnt                  : std_logic_vector(31 downto 0);
95
        signal timer_equ                : std_logic;
96
        signal timer_dly                : std_logic;
97
 
98
        signal exc_type                 : std_logic_vector(7 downto 0);
99
 
100
begin
101
 
102
        rdy_cnt <= "00";        -- no wait states
103
--
104
--      read cnt values
105
--
106
process(clk, reset)
107
begin
108
 
109
        if (reset='1') then
110
                rd_data <= (others => '0');
111
        elsif rising_edge(clk) then
112
 
113
                if rd='1' then
114
                        case address(2 downto 0) is
115
                                when "000" =>
116
                                        rd_data <= clock_cnt;
117
                                when "001" =>
118
                                        rd_data <= us_cnt;
119
                                when others =>
120
                                        rd_data(7 downto 0) <= exc_type;
121
                                        rd_data(31 downto 8) <= (others => '0');
122
                        end case;
123
                end if;
124
        end if;
125
 
126
end process;
127
 
128
--
129
--      compare timer value and us counter
130
--      and generate single shot
131
--
132
process(us_cnt, irq_cnt) begin
133
        timer_equ <= '0';
134
        if us_cnt = irq_cnt then
135
                timer_equ <= '1';
136
        end if;
137
end process;
138
 
139
process(clk, reset, timer_equ) begin
140
        if (reset='1') then
141
                timer_dly <= '0';
142
        elsif rising_edge(clk) then
143
                timer_dly <= timer_equ;
144
        end if;
145
end process;
146
 
147
        timer_int <= timer_equ and not timer_dly;
148
 
149
--
150
--      int processing from timer and yield request
151
--
152
process(clk, reset, timer_int, yield_int) begin
153
 
154
        if (reset='1') then
155
                timer <= '0';
156
                yield <= '0';
157
        elsif rising_edge(clk) then
158
                if int_ack='1' then
159
                        timer <= '0';
160
                        yield <= '0';
161
                else
162
                        if timer_int='1' then
163
                                timer <= '1';
164
                        end if;
165
                        if yield_int='1' then
166
                                yield <= '1';
167
                        end if;
168
                end if;
169
        end if;
170
 
171
end process;
172
 
173
        irq_in.irq <= timer or yield;
174
 
175
 
176
--
177
--      counters
178
--              pre_scale is 8 bit => fmax = 255 MHz
179
--
180
process(clk, reset) begin
181
 
182
        if (reset='1') then
183
 
184
                clock_cnt <= (others => '0');
185
                us_cnt <= (others => '0');
186
                pre_scale <= std_logic_vector(to_unsigned(div_val, pre_scale'length));
187
 
188
        elsif rising_edge(clk) then
189
 
190
                clock_cnt <= std_logic_vector(unsigned(clock_cnt) + 1);
191
                pre_scale <= std_logic_vector(unsigned(pre_scale) - 1);
192
                if pre_scale = "00000000" then
193
                        pre_scale <= std_logic_vector(to_unsigned(div_val, pre_scale'length));
194
                        us_cnt <= std_logic_vector(unsigned(us_cnt) + 1);
195
                end if;
196
 
197
        end if;
198
end process;
199
 
200
--
201
--      io write processing and exception processing
202
--
203
process(clk, reset)
204
 
205
begin
206
        if (reset='1') then
207
 
208
                irq_in.irq_ena <= '0';
209
                irq_cnt <= (others => '0');
210
                int_ack <= '0';
211
                wd <= '0';
212
 
213
                exc_type <= (others => '0');
214
                irq_in.exc_int <= '0';
215
 
216
        elsif rising_edge(clk) then
217
 
218
                int_ack <= '0';
219
                yield_int <= '0';
220
 
221
                irq_in.exc_int <= '0';
222
 
223
                if exc_req.spov='1' then
224 20 martin
                        exc_type(2 downto 0) <= EXC_SPOV;
225 18 martin
                        irq_in.exc_int <= '1';
226
                end if;
227 20 martin
                if exc_req.np='1' then
228
                        exc_type(2 downto 0) <= EXC_NP;
229
                        irq_in.exc_int <= '1';
230
                end if;
231
                if exc_req.ab='1' then
232
                        exc_type(2 downto 0) <= EXC_AB;
233
                        irq_in.exc_int <= '1';
234
                end if;
235 18 martin
 
236
                if wr='1' then
237
                        case address(2 downto 0) is
238
                                when "000" =>
239
                                        irq_in.irq_ena <= wr_data(0);
240
                                when "001" =>
241
                                        irq_cnt <= wr_data;
242
                                        int_ack <= '1';
243
                                when "010" =>
244
                                        yield_int <= '1';
245
                                when "011" =>
246
                                        wd <= wr_data(0);
247
                                when others =>
248
                                        exc_type <= wr_data(7 downto 0);
249
                                        irq_in.exc_int <= '1';
250
                        end case;
251
                end if;
252
 
253
        end if;
254
end process;
255
 
256
end rtl;

powered by: WebSVN 2.1.0

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