From: Pavel Pisa Date: Wed, 8 Feb 2017 13:31:21 +0000 (+0100) Subject: microzed_apo: Include counters to present 8-bit knobs positions. X-Git-Url: https://rtime.felk.cvut.cz/gitweb/fpga/zynq/canbench-sw.git/commitdiff_plain/eadd79f510a46a1da969b97c7732ca9b005b236d microzed_apo: Include counters to present 8-bit knobs positions. Signed-off-by: Pavel Pisa --- diff --git a/system/ip/spi_leds_and_enc_1.0/component.xml b/system/ip/spi_leds_and_enc_1.0/component.xml index f967bc9..cbb33ae 100644 --- a/system/ip/spi_leds_and_enc_1.0/component.xml +++ b/system/ip/spi_leds_and_enc_1.0/component.xml @@ -263,6 +263,12 @@ xilinx_vhdlsynthesis_view_fileset + + + viewChecksum + a5dd367c + + xilinx_vhdlbehavioralsimulation @@ -273,6 +279,12 @@ xilinx_vhdlbehavioralsimulation_view_fileset + + + viewChecksum + a5dd367c + + xilinx_softwaredriver @@ -281,6 +293,12 @@ xilinx_softwaredriver_view_fileset + + + viewChecksum + 085e4a0b + + xilinx_xpgui @@ -289,6 +307,12 @@ xilinx_xpgui_view_fileset + + + viewChecksum + fd592ead + + bd_tcl @@ -297,6 +321,12 @@ bd_tcl_view_fileset + + + viewChecksum + 45a2f450 + + @@ -704,6 +734,10 @@ xilinx_vhdlsynthesis_view_fileset + + hdl/dff.vhdl + vhdlSource + hdl/spi_leds_and_enc_v1_0_spi_fsm.vhd vhdlSource @@ -712,14 +746,26 @@ hdl/spi_leds_and_enc_v1_0_S00_AXI.vhd vhdlSource + + hdl/qcounter_nbit.vhdl + vhdlSource + + + hdl/dff3cke.vhdl + vhdlSource + hdl/spi_leds_and_enc_v1_0.vhd vhdlSource - CHECKSUM_df5775b0 + CHECKSUM_2b8cd74c xilinx_vhdlbehavioralsimulation_view_fileset + + hdl/dff.vhdl + vhdlSource + hdl/spi_leds_and_enc_v1_0_spi_fsm.vhd vhdlSource @@ -728,6 +774,14 @@ hdl/spi_leds_and_enc_v1_0_S00_AXI.vhd vhdlSource + + hdl/qcounter_nbit.vhdl + vhdlSource + + + hdl/dff3cke.vhdl + vhdlSource + hdl/spi_leds_and_enc_v1_0.vhd vhdlSource @@ -848,14 +902,20 @@ AXI_Peripheral spi_leds_and_enc_v1.0 - 1 - 2017-01-23T01:27:21Z + 3 + 2017-02-08T13:24:43Z - /home/pi/fpga/zynq/canbech-sw/system/ip_repo/spi_leds_and_enc_1.0 + /home/pi/fpga/zynq/canbech-sw/system/ip/spi_leds_and_enc_1.0 2016.1 + + + + + + diff --git a/system/ip/spi_leds_and_enc_1.0/hdl/dff.vhdl b/system/ip/spi_leds_and_enc_1.0/hdl/dff.vhdl new file mode 100644 index 0000000..c703058 --- /dev/null +++ b/system/ip/spi_leds_and_enc_1.0/hdl/dff.vhdl @@ -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/system/ip/spi_leds_and_enc_1.0/hdl/dff3cke.vhdl b/system/ip/spi_leds_and_enc_1.0/hdl/dff3cke.vhdl new file mode 100644 index 0000000..603782e --- /dev/null +++ b/system/ip/spi_leds_and_enc_1.0/hdl/dff3cke.vhdl @@ -0,0 +1,69 @@ +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; + +-- D circuit (filtered) + +entity dff3cke is + port + ( + clk_i : in std_logic; + clk_en : in std_logic; + d_i : in std_logic; + q_o : out std_logic; + ch_o : out std_logic; + ch_1ck_o : out std_logic + ); +end dff3cke; + +architecture behavioral of dff3cke is + signal d_3r : std_logic; + signal d_2r : std_logic; + signal d_r : std_logic; + signal data_s : std_logic; + + -- XST attributes + --potlaceni duplikace klupnych obvodu ve fazi optimalizace + --attribute REGISTER_DUPLICATION : string; + --attribute REGISTER_DUPLICATION of d_3r : signal is "NO"; + --attribute REGISTER_DUPLICATION of d_2r : signal is "NO"; + --attribute REGISTER_DUPLICATION of d_r : signal is "NO"; + + attribute syn_keep : boolean; + attribute syn_keep of d_3r : signal is true; + attribute syn_keep of d_2r : signal is true; + attribute syn_keep of d_r : signal is true; + +begin + q_o <= data_s; + +seq: + process + begin + wait until rising_edge (clk_i); + if clk_en = '1' then + if d_3r = d_2r and d_2r = d_r then + if data_s /= d_3r then + ch_1ck_o <= '1'; + ch_o <= '1'; + else + ch_1ck_o <= '0'; + ch_o <= '0'; + end if; + data_s <= d_3r; + else + ch_1ck_o <= '0'; + ch_o <= '0'; + end if; + + d_3r <= d_2r; + d_2r <= d_r; + d_r <= d_i; + else + ch_1ck_o <= '0'; + end if; + end process; + +end behavioral; diff --git a/system/ip/spi_leds_and_enc_1.0/hdl/qcounter_nbit.vhdl b/system/ip/spi_leds_and_enc_1.0/hdl/qcounter_nbit.vhdl new file mode 100644 index 0000000..41b6369 --- /dev/null +++ b/system/ip/spi_leds_and_enc_1.0/hdl/qcounter_nbit.vhdl @@ -0,0 +1,118 @@ +-- +-- * Quadrature Signal Decoder * +-- Used for IRC sensor interfacing +-- +-- (c) 2010 Marek Peca +-- +-- Updated for generic size +-- 2016 Pavel Pisa +-- +-- license: GNU LGPL and GPLv3+ +-- +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_nbit is +generic ( + bitwidth: integer := 32 +); +port ( + clock: in std_logic; + reset: in std_logic; + a0, b0: in std_logic; + qcount: out std_logic_vector (bitwidth - 1 downto 0); + a_rise, a_fall, b_rise, b_fall, ab_event: out std_logic; + ab_error: out std_logic +); +end qcounter_nbit; + +architecture behavioral of qcounter_nbit 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 (bitwidth - 3 downto 0) + := (others => '0'); + signal count: std_logic_vector (bitwidth - 3 downto 0); +begin + -- stabilize signal a between clock ticks + -- active on rising edge of the clock signal + dff_a: dff + port map ( + clock => clock, + d => a0, + q => a + ); + + -- stabilize signal b between clock ticks + -- active on rising edge of the clock signal + dff_b: dff + port map ( + clock => clock, + d => b0, + q => b + ); + + -- the first two bits are combinational logic only + qcount(0) <= a xor b; + qcount(1) <= b; + qcount(bitwidth - 1 downto 2) <= count; + + -- purpose of this process is only to propagate signals to the pins + 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 -- a i b se zmenily zaroven + -- forbidden double transition + ab_error <= '1'; + else + a_rise <= (a xor a_prev) and a; -- a rising + a_fall <= (a xor a_prev) and not a; -- a falling + b_rise <= (b xor b_prev) and b; -- b rissing + b_fall <= (b xor b_prev) and not b; -- b falling + ab_event <= (a xor a_prev) or (b xor b_prev); --a or b changed + end if; + end process; + + -- carry to the third bit (binary) + comb_count: process (a_prev, b_prev, a, b, count,count_prev) + begin + if (a_prev = '0') and (b_prev = '1') and (a = '0') and (b = '0') then --posun dopredu + count <= count_prev + 1; + elsif (a_prev = '0') and (b_prev = '0') and (a = '0') and (b = '1') then --posun dozadu + count <= count_prev - 1; + else + count <= count_prev; + end if; + end process; + + -- all state update is done at clock signal rising edge + -- reset count_prev register, it propagates to combinational count + -- results automatically + seq: process + begin + wait until clock'event and clock = '1'; + if reset = '1' then + count_prev <= (others => '0'); + else + count_prev <= count; + end if; + a_prev <= a; + b_prev <= b; + end process; + +end behavioral; diff --git a/system/ip/spi_leds_and_enc_1.0/hdl/spi_leds_and_enc_v1_0.vhd b/system/ip/spi_leds_and_enc_1.0/hdl/spi_leds_and_enc_v1_0.vhd index dfe415d..883ffa4 100644 --- a/system/ip/spi_leds_and_enc_1.0/hdl/spi_leds_and_enc_v1_0.vhd +++ b/system/ip/spi_leds_and_enc_1.0/hdl/spi_leds_and_enc_v1_0.vhd @@ -118,6 +118,31 @@ architecture arch_imp of spi_leds_and_enc_v1_0 is ); end component; + component dff3cke is + port ( + clk_i : in std_logic; + clk_en : in std_logic; + d_i : in std_logic; + q_o : out std_logic; + ch_o : out std_logic; + ch_1ck_o : out std_logic + ); + end component; + + component qcounter_nbit is + generic ( + bitwidth: integer := 32 + ); + port ( + clock: in std_logic; + reset: in std_logic; + a0, b0: in std_logic; + qcount: out std_logic_vector (bitwidth - 1 downto 0); + a_rise, a_fall, b_rise, b_fall, ab_event: out std_logic; + ab_error: out std_logic + ); + end component; + constant spi_data_width : integer := 48; constant spi_clk_div : integer := 10; constant enc_number : integer := 3; @@ -149,6 +174,11 @@ architecture arch_imp of spi_leds_and_enc_v1_0 is signal enc_chb : std_logic_vector(enc_number downto 1); signal enc_sw : std_logic_vector(enc_number downto 1); + signal enc_cha_filt : std_logic_vector(enc_number downto 1); + signal enc_chb_filt : std_logic_vector(enc_number downto 1); + signal enc_sw_filt : std_logic_vector(enc_number downto 1); + signal enc_changes : std_logic_vector(enc_number * 3 - 1 downto 0); + begin -- Instantiation of Axi Bus Interface S00_AXI @@ -216,6 +246,52 @@ spi_leds_and_enc_v1_0_spi_fsm_inst: spi_leds_and_enc_v1_0_spi_fsm transfer_ready => spi_transfer_ready ); +irc_block: for i in enc_number downto 1 generate + filt_cha: dff3cke + port map ( + clk_i => fsm_clk, + clk_en => spi_transfer_ready, + d_i => enc_cha(i), + q_o => enc_cha_filt(i), + ch_o => open, + ch_1ck_o => enc_changes((i - 1) * 3 + 0) + ); + filt_chb: dff3cke + port map ( + clk_i => fsm_clk, + clk_en => spi_transfer_ready, + d_i => enc_chb(i), + q_o => enc_chb_filt(i), + ch_o => open, + ch_1ck_o => enc_changes((i - 1) * 3 + 1) + ); + filt_sw: dff3cke + port map ( + clk_i => fsm_clk, + clk_en => spi_transfer_ready, + d_i => enc_sw(i), + q_o => enc_sw_filt(i), + ch_o => open, + ch_1ck_o => enc_changes((i - 1) * 3 + 2) + ); + qcounter: qcounter_nbit + generic map ( + bitwidth => 8 + ) + port map ( + clock => fsm_clk, + reset => fsm_rst, + a0 => enc_cha_filt(i), + b0 => enc_chb_filt(i), + qcount => in_enc_8bit((3 - i) * 8 + 7 downto (3 - i) * 8), + a_rise => open, + a_fall => open, + b_rise => open, + b_fall => open, + ab_event => open, + ab_error => open + ); + end generate; fsm_clk <= s00_axi_aclk; fsm_rst <= not s00_axi_aresetn; @@ -254,11 +330,11 @@ data_logic_process :process in_kbd_direct <= not spi_rx_data(3 downto 0); - in_enc_buttons(2) <= enc_sw(1); - in_enc_buttons(1) <= enc_sw(2); - in_enc_buttons(0) <= enc_sw(3); + in_enc_buttons(2) <= enc_sw_filt(1); + in_enc_buttons(1) <= enc_sw_filt(2); + in_enc_buttons(0) <= enc_sw_filt(3); - in_enc_8bit <= (others => '0'); + -- in_enc_8bit <= (others => '0'); in_enc_direct <= (8 => enc_sw(1), 7 => enc_chb(1), 6 => enc_cha(1), 5 => enc_sw(2), 4 => enc_chb(2), 3 => enc_cha(2),