]> rtime.felk.cvut.cz Git - fpga/quadcount.git/blob - qcounter.vhdl
quadratic decoder counter core
[fpga/quadcount.git] / qcounter.vhdl
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
7 entity qcounter is
8   port (
9     clock: in std_logic;
10     reset: in std_logic;
11     a, b: in std_logic;
12     qcount: out std_logic_vector (31 downto 0);
13     a_rise, a_fall, b_rise, b_fall, ab_event: out std_logic;
14     ab_error: out std_logic
15   );
16 end qcounter;
17
18 architecture behavioral of qcounter is
19   subtype std_logic4 is std_logic_vector (3 downto 0);
20   signal a_prev, b_prev: std_logic;
21   signal count: std_logic_vector (29 downto 0)
22     := "000000000000000000000000000000";
23   signal count_next: std_logic_vector (29 downto 0);
24 begin
25   qcount(0) <= a_prev xor b_prev;
26   qcount(1) <= b_prev;
27   qcount(31 downto 2) <= count;
28   
29   comb_event: process (a_prev, b_prev, a, b)
30   begin
31     a_rise <= '0';
32     a_fall <= '0';
33     b_rise <= '0';
34     b_fall <= '0';
35     ab_event <= '0';
36     ab_error <= '0';
37     if ((a xor a_prev) and (b xor b_prev)) = '1' then
38       -- forbidden double transition
39       ab_error <= '1';
40     else
41       a_rise <= (a xor a_prev) and a;
42       a_fall <= (a xor a_prev) and not a;
43       b_rise <= (b xor b_prev) and b;
44       b_fall <= (b xor b_prev) and not b;
45       ab_event <= (a xor a_prev) or (b xor b_prev);
46     end if;
47   end process;
48
49   comb_count: process (a_prev, b_prev, a, b, count)
50   begin
51     if (a_prev = '1') and (b_prev = '0') and (a = '0') and (b = '0') then
52       count_next <= count + 1;
53     elsif (a_prev = '0') and (b_prev = '0') and (a = '1') and (b = '0') then
54       count_next <= count - 1;
55     else
56       count_next <= count;
57     end if;
58   end process;
59
60   seq: process
61   begin
62     wait until clock'event and clock = '1';
63     if reset = '1' then
64       count <= "000000000000000000000000000000";
65     else
66       count <= count_next;
67     end if;
68     a_prev <= a;
69     b_prev <= b;
70   end process;
71
72 end behavioral;