]> rtime.felk.cvut.cz Git - fpga/zynq/canbench-sw.git/blob - system/ip/spi_leds_and_enc_1.0/hdl/qcounter_nbit.vhdl
microzed_apo: Include counters to present 8-bit knobs positions.
[fpga/zynq/canbench-sw.git] / system / ip / spi_leds_and_enc_1.0 / hdl / qcounter_nbit.vhdl
1 --
2 -- * Quadrature Signal Decoder *
3 -- Used for IRC sensor interfacing
4 --
5 -- (c) 2010 Marek Peca <hefaistos@gmail.com>
6 --
7 -- Updated for generic size
8 --     2016 Pavel Pisa <pisa@cmp.felk.cvut.cz>
9 --
10 -- license: GNU LGPL and GPLv3+
11 --
12 library ieee;
13 use ieee.std_logic_1164.all;
14 use ieee.std_logic_arith.all;
15 use ieee.std_logic_unsigned.all;
16 use ieee.numeric_std.all;
17
18 entity qcounter_nbit is
19 generic (
20         bitwidth: integer := 32
21 );
22 port (
23         clock: in std_logic;
24         reset: in std_logic;
25         a0, b0: in std_logic;
26         qcount: out std_logic_vector (bitwidth - 1 downto 0);
27         a_rise, a_fall, b_rise, b_fall, ab_event: out std_logic;
28         ab_error: out std_logic
29 );
30 end qcounter_nbit;
31
32 architecture behavioral of qcounter_nbit is
33         component dff
34         port (
35                 clock: in std_logic;
36                 d: in std_logic;
37                 q: out std_logic
38         );
39         end component;
40
41         subtype std_logic4 is std_logic_vector (3 downto 0);
42         signal a, b, a_prev, b_prev: std_logic;
43         signal count_prev: std_logic_vector (bitwidth - 3 downto 0)
44                 := (others => '0');
45         signal count: std_logic_vector (bitwidth - 3 downto 0);
46 begin
47         -- stabilize signal a between clock ticks
48         -- active on rising edge of the clock signal
49         dff_a: dff
50         port map (
51                 clock => clock,
52                 d => a0,
53                 q => a
54         );
55         
56         -- stabilize signal b between clock ticks
57         -- active on rising edge of the clock signal
58         dff_b: dff
59         port map (
60                 clock => clock,
61                 d => b0,
62                 q => b
63         );
64  
65         -- the first two bits are combinational logic only
66         qcount(0) <= a xor b;
67         qcount(1) <= b;
68         qcount(bitwidth - 1 downto 2) <= count;
69  
70         -- purpose of this process is only to propagate signals to the pins
71         comb_event: process (a_prev, b_prev, a, b)
72         begin
73                 a_rise <= '0';
74                 a_fall <= '0';
75                 b_rise <= '0';
76                 b_fall <= '0';
77                 ab_event <= '0';
78                 ab_error <= '0';
79                 if ((a xor a_prev) and (b xor b_prev)) = '1' then -- a i b se zmenily zaroven
80                         -- forbidden double transition
81                         ab_error <= '1';
82                 else
83                         a_rise <= (a xor a_prev) and a; -- a rising
84                         a_fall <= (a xor a_prev) and not a; -- a falling
85                         b_rise <= (b xor b_prev) and b; -- b rissing
86                         b_fall <= (b xor b_prev) and not b; -- b falling
87                         ab_event <= (a xor a_prev) or (b xor b_prev); --a or b changed
88                 end if;
89         end process;
90
91         -- carry to the third bit (binary)
92         comb_count: process (a_prev, b_prev, a, b, count,count_prev)
93         begin
94                 if (a_prev = '0') and (b_prev = '1') and (a = '0') and (b = '0') then --posun dopredu 
95                         count <= count_prev + 1;
96                 elsif (a_prev = '0') and (b_prev = '0') and (a = '0') and (b = '1') then --posun dozadu
97                         count <= count_prev - 1;
98                 else
99                         count <= count_prev;
100                 end if;
101         end process;
102
103         -- all state update is done at clock signal rising edge
104         -- reset count_prev register, it propagates to combinational count
105         -- results automatically
106         seq: process
107         begin
108                 wait until clock'event and clock = '1';
109                 if reset = '1' then
110                         count_prev <= (others => '0');
111                 else
112                         count_prev <= count;
113                 end if;
114                 a_prev <= a;
115                 b_prev <= b;
116         end process;
117         
118 end behavioral;