]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/blob - hw/qcounter.vhd
IRC coprocesor, change to generic, index to user, usb commands update
[fpga/lx-cpu1/lx-rocon.git] / hw / qcounter.vhd
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.std_logic_arith.all;
4 use ieee.std_logic_unsigned.all;
5 use ieee.numeric_std.all;
6 use work.lx_rocon_pkg.all;
7
8 -- Quadcounter (for IRC)
9
10 entity qcounter is
11   port
12         (
13                 -- Inputs
14     clk_i                : in std_logic;
15     reset_i              : in std_logic;
16     a0_i, b0_i           : in std_logic;
17                 index0_i             : in std_logic;
18                 -- State
19                 reset_index_event_i  : in std_logic;
20                 reset_index_event2_i : in std_logic;
21                 reset_ab_error_i     : in std_logic;
22                 -- Outputs
23     qcount_o             : out std_logic_vector (7 downto 0);
24                 qcount_index_o       : out std_logic_vector (7 downto 0);
25                 index_event_o        : out std_logic;
26                 index_event2_o       : out std_logic;
27     a_rise_o, a_fall_o   : out std_logic;
28                 b_rise_o, b_fall_o   : out std_logic;
29                 ab_event_o           : out std_logic;
30     ab_error_o           : out std_logic
31   );
32 end qcounter;
33
34 architecture behavioral of qcounter is
35
36         signal last_reset_s       : std_logic;
37   signal a_s, b_s           : std_logic;
38         signal a_prev_s, b_prev_s : std_logic;
39         signal ab_error_s         : std_logic;
40         signal ab_error_int_s     : std_logic;
41         signal index_event_s      : std_logic;
42         signal index_event_int_s  : std_logic;
43         signal index_event2_s     : std_logic;
44         signal index_event2_int_s : std_logic;
45         signal index_s            : std_logic;
46   signal count_prev_s       : std_logic_vector (5 downto 0);
47   signal count_s            : std_logic_vector (5 downto 0);
48         signal count_index_prev_s : std_logic_vector (7 downto 0);
49   signal count_index_s      : std_logic_vector (7 downto 0);
50
51 begin
52 dff_a: dff2
53         port map
54         (
55                 clk_i   => clk_i,
56                 reset_i => '0',
57                 d_i     => a0_i,
58                 q_o     => a_s
59         );
60
61  dff_b: dff2
62         port map
63         (
64                 clk_i   => clk_i,
65                 reset_i => '0',
66                 d_i     => b0_i,
67                 q_o     => b_s
68         );
69
70 dff_index: dff2
71         port map
72         (
73                 clk_i   => clk_i,
74                 reset_i => '0',
75                 d_i     => index0_i,
76                 q_o     => index_s
77         );
78
79         qcount_o(0)           <= a_s xor b_s;
80         qcount_o(1)           <= b_s;
81         qcount_o(7 downto 2)  <= count_s;
82         --
83         qcount_index_o        <= count_index_s;
84         --
85         ab_error_o            <= ab_error_int_s;
86         index_event_o         <= index_event_int_s;
87         index_event2_o        <= index_event2_int_s;
88
89 comb_event:
90         process (reset_i, last_reset_s, a_prev_s, b_prev_s, a_s, b_s)
91         begin
92     a_rise_o   <= '0';
93     a_fall_o   <= '0';
94     b_rise_o   <= '0';
95     b_fall_o   <= '0';
96     ab_event_o <= '0';
97     ab_error_s <= '0';
98
99                 if reset_i = '0' and last_reset_s = '0' then
100                         if ((a_s xor a_prev_s) and (b_s xor b_prev_s)) = '1' then
101                                 -- forbidden double transition
102                                 ab_error_s <= '1';
103                                 ab_event_o <= '0';
104                         else
105                                 a_rise_o   <= (a_s xor a_prev_s) and a_s;
106                                 a_fall_o   <= (a_s xor a_prev_s) and (not a_s);
107                                 b_rise_o   <= (b_s xor b_prev_s) and b_s;
108                                 b_fall_o   <= (b_s xor b_prev_s) and (not b_s);
109                                 ab_event_o <= (a_s xor a_prev_s) or (b_s xor b_prev_s);
110                         end if;
111                 end if;
112   end process;
113
114 comb_count:
115         process (reset_i, last_reset_s, a_prev_s, b_prev_s, a_s, b_s,
116                                                 index_s, count_prev_s, count_index_prev_s)
117         begin
118
119                 index_event_s <= '0';
120
121                 if reset_i = '1' or last_reset_s = '1' then
122                         count_s                      <= count_prev_s;
123                         count_index_s                <= count_index_prev_s;
124                 elsif (a_prev_s = '0') and (b_prev_s = '1') and (a_s = '0') and
125                                                 (b_s = '0') then
126       count_s                      <= count_prev_s + 1;
127                         if index_s = '1' then
128                                 count_index_s(0)           <= a_s xor b_s;
129                                 count_index_s(1)           <= b_s;
130                                 count_index_s(7 downto 2)  <= count_prev_s + 1;
131                         else
132                                 count_index_s              <= count_index_prev_s;
133                         end if;
134     elsif (a_prev_s = '0') and (b_prev_s = '0') and (a_s = '0') and
135                                                 (b_s = '1') then
136       count_s                      <= count_prev_s - 1;
137
138                         if index_s = '1' then
139                                 count_index_s(0)           <= a_s xor b_s;
140                                 count_index_s(1)           <= b_s;
141                                 count_index_s(7 downto 2)  <= count_prev_s - 1;
142                                 index_event_s              <= '1';
143                         else
144                                 count_index_s              <= count_index_prev_s;
145                         end if;
146     else
147       count_s                      <= count_prev_s;
148                         if index_s = '1' then
149                                 count_index_s(0)           <= a_s xor b_s;
150                                 count_index_s(1)           <= b_s;
151                                 count_index_s(7 downto 2)  <= count_prev_s;
152                                 index_event_s              <= '1';
153                         else
154                                 count_index_s              <= count_index_prev_s;
155                         end if;
156     end if;
157
158   end process;
159
160 seq:
161         process
162         begin
163                 -- Reset for qcounter is synchronous and lasts at least one more cycle
164                 -- to prevent hazardous states after releasing it
165                 wait until clk_i'event and clk_i = '1';
166
167                 if reset_i = '1' then
168                         count_prev_s        <= (others => '0');
169                         count_index_prev_s  <= (others => '0');
170                         index_event_int_s   <= '0';
171                         index_event2_int_s  <= '0';
172                         ab_error_int_s      <= '0';
173                 else
174                         count_prev_s        <= count_s;
175                         count_index_prev_s  <= count_index_s;
176                         --
177                         if reset_index_event_i = '1' then
178                                 index_event_int_s <= '0';
179                         else
180                                 index_event_int_s <= index_event_int_s or index_event_s;
181                         end if;
182                         --
183                         if reset_index_event2_i = '1' then
184                                 index_event2_int_s <= '0';
185                         else
186                                 index_event2_int_s <= index_event2_int_s or index_event_s;
187                         end if;
188                         --
189                         if reset_ab_error_i = '1' then
190                                 ab_error_int_s    <= '0';
191                         else
192                                 ab_error_int_s    <= ab_error_int_s or ab_error_s;
193                         end if;
194                 end if;
195                 a_prev_s              <= a_s;
196                 b_prev_s              <= b_s;
197                 last_reset_s          <= reset_i;
198   end process;
199
200 end behavioral;