pridan quadcount
authorMartin Prudek <prudemar@fel.cvut.cz>
Thu, 26 Mar 2015 16:58:17 +0000 (17:58 +0100)
committerMartin Prudek <prudemar@fel.cvut.cz>
Thu, 26 Mar 2015 16:58:17 +0000 (17:58 +0100)
pmsm-control/dff.vhdl [new file with mode: 0644]
pmsm-control/qcounter.vhdl [new file with mode: 0644]
pmsm-control/rpi_mc_simple_dc.vhdl

diff --git a/pmsm-control/dff.vhdl b/pmsm-control/dff.vhdl
new file mode 100644 (file)
index 0000000..c703058
--- /dev/null
@@ -0,0 +1,26 @@
+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 dff is
+  port (
+    clock: in std_logic;
+    d: in std_logic;
+    q: out std_logic
+  );
+end dff;
+
+architecture behavioral of dff is
+  signal data: std_logic := '0';
+begin
+  q <= data;
+
+  process
+  begin
+    wait until clock'event and clock = '1';
+    data <= d;
+  end process;
+
+end behavioral;
diff --git a/pmsm-control/qcounter.vhdl b/pmsm-control/qcounter.vhdl
new file mode 100644 (file)
index 0000000..e778264
--- /dev/null
@@ -0,0 +1,94 @@
+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;
+use work.dff.all;
+
+entity qcounter is
+  port (
+    clock: in std_logic;
+    reset: in std_logic;
+    a0, b0: 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
+  component dff
+    port (
+      clock: in std_logic;
+      d: in std_logic;
+      q: out std_logic
+    );
+  end component;
+
+subtype std_logic4 is std_logic_vector (3 downto 0);
+  signal a, b, a_prev, b_prev: std_logic;
+  signal count_prev: std_logic_vector (29 downto 0)
+    := "000000000000000000000000000000";
+  signal count: std_logic_vector (29 downto 0);
+begin
+  dff_a: dff
+    port map (
+      clock => clock,
+      d => a0,
+      q => a
+    );
+  dff_b: dff
+    port map (
+      clock => clock,
+      d => b0,
+      q => b
+    );
+  
+  qcount(0) <= a xor b;
+  qcount(1) <= b;
+  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 = '0') and (b_prev = '1') and (a = '0') and (b = '0') then
+      count <= count_prev + 1;
+    elsif (a_prev = '0') and (b_prev = '0') and (a = '0') and (b = '1') then
+      count <= count_prev - 1;
+    else
+      count <= count_prev;
+    end if;
+  end process;
+
+  seq: process
+  begin
+    wait until clock'event and clock = '1';
+    if reset = '1' then
+      count_prev <= "000000000000000000000000000000";
+    else
+      count_prev <= count;
+    end if;
+    a_prev <= a;
+    b_prev <= b;
+  end process;
+
+end behavioral;
index d1810c6..d6a2686 100644 (file)
@@ -14,6 +14,7 @@ library ieee;
 use ieee.std_logic_1164.all;
 use ieee.numeric_std.all;
 use work.util.all;
+use work.qcounter.all;
 
 entity rpi_mc_simple_dc is
        port (