preformatovani
[fpga/rpi-motor-control.git] / pmsm-control / 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 use work.dff.all;
7
8 entity qcounter is
9 port (
10         clock: in std_logic;
11         reset: in std_logic;
12         a0, b0: in std_logic;
13         qcount: out std_logic_vector (31 downto 0);
14         a_rise, a_fall, b_rise, b_fall, ab_event: out std_logic;
15         ab_error: out std_logic
16 );
17 end qcounter;
18
19 architecture behavioral of qcounter is
20         component dff
21         port (
22                 clock: in std_logic;
23                 d: in std_logic;
24                 q: out std_logic
25         );
26         end component;
27
28         subtype std_logic4 is std_logic_vector (3 downto 0);
29         signal a, b, a_prev, b_prev: std_logic;
30         signal count_prev: std_logic_vector (29 downto 0)
31                 := "000000000000000000000000000000";
32         signal count: std_logic_vector (29 downto 0);
33 begin
34         dff_a: dff
35         port map (
36                 clock => clock,
37                 d => a0,
38                 q => a
39         );
40         
41         dff_b: dff
42         port map (
43                 clock => clock,
44                 d => b0,
45                 q => b
46         );
47   
48         qcount(0) <= a xor b;
49         qcount(1) <= b;
50         qcount(31 downto 2) <= count;
51   
52         comb_event: process (a_prev, b_prev, a, b)
53         begin
54                 a_rise <= '0';
55                 a_fall <= '0';
56                 b_rise <= '0';
57                 b_fall <= '0';
58                 ab_event <= '0';
59                 ab_error <= '0';
60                 if ((a xor a_prev) and (b xor b_prev)) = '1' then
61                         -- forbidden double transition
62                         ab_error <= '1';
63                 else
64                         a_rise <= (a xor a_prev) and a;
65                         a_fall <= (a xor a_prev) and not a;
66                         b_rise <= (b xor b_prev) and b;
67                         b_fall <= (b xor b_prev) and not b;
68                         ab_event <= (a xor a_prev) or (b xor b_prev);
69                 end if;
70         end process;
71
72         comb_count: process (a_prev, b_prev, a, b, count)
73         begin
74                 if (a_prev = '0') and (b_prev = '1') and (a = '0') and (b = '0') then
75                         count <= count_prev + 1;
76                 elsif (a_prev = '0') and (b_prev = '0') and (a = '0') and (b = '1') then
77                         count <= count_prev - 1;
78                 else
79                         count <= count_prev;
80                 end if;
81         end process;
82
83         seq: process
84         begin
85                 wait until clock'event and clock = '1';
86                 if reset = '1' then
87                         count_prev <= "000000000000000000000000000000";
88                 else
89                         count_prev <= count;
90                 end if;
91                 a_prev <= a;
92                 b_prev <= b;
93         end process;
94         
95 end behavioral;