]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/blob - hw/qcounter.vhd
RoCoN: USB CDC ACM use maximal packet length - 64 bytes.
[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_o              : out std_logic;
26                 index_event_o        : out std_logic;
27                 index_event2_o       : out std_logic;
28     a_rise_o, a_fall_o   : out std_logic;
29                 b_rise_o, b_fall_o   : out std_logic;
30                 ab_event_o           : out std_logic;
31     ab_error_o           : out std_logic
32   );
33 end qcounter;
34
35 architecture behavioral of qcounter is
36
37         signal last_reset_s       : std_logic;
38   signal a_s, b_s           : std_logic;
39         signal a_prev_s, b_prev_s : std_logic;
40         signal ab_error_s         : std_logic;
41         signal ab_error_int_s     : std_logic;
42         signal index_event_int_s  : std_logic;
43         signal index_event2_int_s : std_logic;
44         signal index_s            : std_logic;
45         signal index_prev_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_out_s        : std_logic_vector (7 downto 0);
49   signal count_index_s      : std_logic_vector (7 downto 0);
50
51 begin
52 dff_a: dff3
53         port map
54         (
55                 clk_i   => clk_i,
56                 d_i     => a0_i,
57                 q_o     => a_s
58         );
59
60  dff_b: dff3
61         port map
62         (
63                 clk_i   => clk_i,
64                 d_i     => b0_i,
65                 q_o     => b_s
66         );
67
68 dff_index: dff3
69         port map
70         (
71                 clk_i   => clk_i,
72                 d_i     => index0_i,
73                 q_o     => index_s
74         );
75
76         count_out_s(0)          <= a_s xor b_s;
77         count_out_s(1)          <= b_s;
78         count_out_s(7 downto 2) <= count_s;
79         --
80         qcount_o                <= count_out_s;
81         qcount_index_o          <= count_index_s;
82         --
83         ab_error_o              <= ab_error_int_s;
84         index_o                 <= index_s;
85         index_event_o           <= index_event_int_s;
86         index_event2_o          <= index_event2_int_s;
87
88 comb_event:
89         process (reset_i, last_reset_s, a_prev_s, b_prev_s, a_s, b_s)
90         begin
91     a_rise_o   <= '0';
92     a_fall_o   <= '0';
93     b_rise_o   <= '0';
94     b_fall_o   <= '0';
95     ab_event_o <= '0';
96     ab_error_s <= '0';
97
98                 if reset_i = '0' and last_reset_s = '0' then
99                         if ((a_s xor a_prev_s) and (b_s xor b_prev_s)) = '1' then
100                                 -- forbidden double transition
101                                 ab_error_s <= '1';
102                                 ab_event_o <= '0';
103                         else
104                                 a_rise_o   <= (a_s xor a_prev_s) and a_s;
105                                 a_fall_o   <= (a_s xor a_prev_s) and (not a_s);
106                                 b_rise_o   <= (b_s xor b_prev_s) and b_s;
107                                 b_fall_o   <= (b_s xor b_prev_s) and (not b_s);
108                                 ab_event_o <= (a_s xor a_prev_s) or (b_s xor b_prev_s);
109                         end if;
110                 end if;
111   end process;
112
113 comb_count:
114         process (reset_i, last_reset_s, a_prev_s, b_prev_s, a_s, b_s,
115                                                 index_s, count_prev_s)
116         begin
117
118                 if reset_i = '1' or last_reset_s = '1' then
119                         count_s                      <= count_prev_s;
120                 elsif (a_prev_s = '0') and (b_prev_s = '1') and (a_s = '0') and
121                                                 (b_s = '0') then
122       count_s                      <= count_prev_s + 1;
123     elsif (a_prev_s = '0') and (b_prev_s = '0') and (a_s = '0') and
124                                                 (b_s = '1') then
125       count_s                      <= count_prev_s - 1;
126     else
127       count_s                      <= count_prev_s;
128     end if;
129
130   end process;
131
132 seq:
133         process
134                 variable index_event_v      : std_logic;
135         begin
136                 -- Reset for qcounter is synchronous and lasts at least one more cycle
137                 -- to prevent hazardous states after releasing it
138                 wait until clk_i'event and clk_i = '1';
139
140                 index_event_v         := '0';
141
142                 if reset_i = '1' then
143                         count_prev_s        <= (others => '0');
144                         count_index_s       <= (others => '0');
145                         index_event_int_s   <= '0';
146                         index_event2_int_s  <= '0';
147                         ab_error_int_s      <= '0';
148                         index_prev_s        <= '1';
149                 else
150
151                         if index_s = '1' and index_prev_s = '0' then
152                                 count_index_s     <= count_out_s;
153                                 index_event_v     := '1';
154                         end if;
155                         --
156                         index_event_int_s <= (index_event_int_s and not reset_index_event_i) or
157                                              index_event_v;
158                         --
159                         index_event2_int_s <= (index_event2_int_s and not reset_index_event2_i) or
160                                               reset_index_event_i;
161                         --
162                         ab_error_int_s    <= (ab_error_int_s and not reset_ab_error_i) or ab_error_s;
163                         --
164                         count_prev_s        <= count_s;
165                         index_prev_s        <= index_s;
166
167                 end if;
168
169                 a_prev_s              <= a_s;
170                 b_prev_s              <= b_s;
171                 last_reset_s          <= reset_i;
172   end process;
173
174 end behavioral;