From e96c458b8401060b2f8b7b550bcb58ae6e19ad8d Mon Sep 17 00:00:00 2001 From: Marek Peca Date: Sat, 16 Oct 2010 23:03:40 +0200 Subject: [PATCH] quadratic decoder counter core --- qcounter.vhdl | 72 +++++++++++++++++++++++++++++++++++++++++++++++ quadcount_tb.vhdl | 43 ++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 qcounter.vhdl create mode 100644 quadcount_tb.vhdl diff --git a/qcounter.vhdl b/qcounter.vhdl new file mode 100644 index 0000000..90f6b05 --- /dev/null +++ b/qcounter.vhdl @@ -0,0 +1,72 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +use ieee.numeric_std.all; + +entity qcounter is + port ( + clock: in std_logic; + reset: in std_logic; + a, b: in std_logic; + qcount: out std_logic_vector (31 downto 0); + a_rise, a_fall, b_rise, b_fall, ab_event: out std_logic; + ab_error: out std_logic + ); +end qcounter; + +architecture behavioral of qcounter is + subtype std_logic4 is std_logic_vector (3 downto 0); + signal a_prev, b_prev: std_logic; + signal count: std_logic_vector (29 downto 0) + := "000000000000000000000000000000"; + signal count_next: std_logic_vector (29 downto 0); +begin + qcount(0) <= a_prev xor b_prev; + qcount(1) <= b_prev; + qcount(31 downto 2) <= count; + + comb_event: process (a_prev, b_prev, a, b) + begin + a_rise <= '0'; + a_fall <= '0'; + b_rise <= '0'; + b_fall <= '0'; + ab_event <= '0'; + ab_error <= '0'; + if ((a xor a_prev) and (b xor b_prev)) = '1' then + -- forbidden double transition + ab_error <= '1'; + else + a_rise <= (a xor a_prev) and a; + a_fall <= (a xor a_prev) and not a; + b_rise <= (b xor b_prev) and b; + b_fall <= (b xor b_prev) and not b; + ab_event <= (a xor a_prev) or (b xor b_prev); + end if; + end process; + + comb_count: process (a_prev, b_prev, a, b, count) + begin + if (a_prev = '1') and (b_prev = '0') and (a = '0') and (b = '0') then + count_next <= count + 1; + elsif (a_prev = '0') and (b_prev = '0') and (a = '1') and (b = '0') then + count_next <= count - 1; + else + count_next <= count; + end if; + end process; + + seq: process + begin + wait until clock'event and clock = '1'; + if reset = '1' then + count <= "000000000000000000000000000000"; + else + count <= count_next; + end if; + a_prev <= a; + b_prev <= b; + end process; + +end behavioral; diff --git a/quadcount_tb.vhdl b/quadcount_tb.vhdl new file mode 100644 index 0000000..a15c6ba --- /dev/null +++ b/quadcount_tb.vhdl @@ -0,0 +1,43 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +use ieee.numeric_std.all; + +entity quadcount_tb is +end quadcount_tb; + +architecture behavioral of quadcount_tb is + component qcounter + port ( + clock: in std_logic; + reset: in std_logic; + a, b: in std_logic; + qcount: out std_logic_vector (31 downto 0); + a_rise, a_fall, b_rise, b_fall, ab_event: out std_logic; + ab_error: out std_logic + ); + end component; + + signal clock, reset, a, b: std_logic; +begin + qc0: qcounter + port map ( + clock => clock, + reset => reset, + a => a, + b => b + ); + + reset <= '0'; + a <= '0'; + b <= '0'; + + test: process + begin + clock <= '0'; + wait for 1 us; + clock <= '1'; + wait for 1 us; + end process; +end behavioral; -- 2.39.2