]> rtime.felk.cvut.cz Git - fpga/quadcount.git/commitdiff
quadratic decoder counter core
authorMarek Peca <mp@duch.cz>
Sat, 16 Oct 2010 21:03:40 +0000 (23:03 +0200)
committerMarek Peca <mp@duch.cz>
Sat, 16 Oct 2010 21:03:40 +0000 (23:03 +0200)
qcounter.vhdl [new file with mode: 0644]
quadcount_tb.vhdl [new file with mode: 0644]

diff --git a/qcounter.vhdl b/qcounter.vhdl
new file mode 100644 (file)
index 0000000..90f6b05
--- /dev/null
@@ -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 (file)
index 0000000..a15c6ba
--- /dev/null
@@ -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;