From 430dc563689c3acb44b1cfb22607c4805cdd4851 Mon Sep 17 00:00:00 2001 From: Pavel Pisa Date: Sun, 22 Feb 2015 12:34:06 +0100 Subject: [PATCH] LX master: implement CRC checking in receiver. Signed-off-by: Pavel Pisa --- hw/bus_lxmaster.vhd | 8 ++++++-- hw/lx_rocon_pkg.vhd | 1 + hw/lxmaster_receiver.vhd | 42 +++++++++++++++++++++++++++++++++++----- 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/hw/bus_lxmaster.vhd b/hw/bus_lxmaster.vhd index cdb3e11..f443027 100644 --- a/hw/bus_lxmaster.vhd +++ b/hw/bus_lxmaster.vhd @@ -77,6 +77,8 @@ architecture Behavioral of bus_lxmaster is signal rx_done_ratio_r : std_logic_vector(rx_done_div_width_c-1 downto 0); signal rx_done_ratio_wr_s : std_logic; signal rx_done_cnt_r : natural range 0 to (2**rx_done_cnt_width_c - 1); + -- + signal rx_crc_error_s : std_logic; begin master_transmitter: lxmaster_transmitter @@ -123,6 +125,7 @@ master_receiver: lxmaster_receiver sync_i => sync_i, -- Receive done pulse rx_done_o => rx_done_s, + rx_crc_error_o => rx_crc_error_s, -- Register register_i => register_recv_in_s, register_o => register_recv_out_s, @@ -155,7 +158,7 @@ rx_done_divider : cnt_div wire_in: process(ce_i, ce_r, reset_reg_r, bls_i, address_i, mem_trans_data_s, mem_recv_data_s, data_i, register_trans_out_s, register_recv_out_s, - register_cycle_out_s, rx_done_ratio_r, rx_done_cnt_r) + register_cycle_out_s, rx_done_ratio_r, rx_done_cnt_r, rx_crc_error_s) begin mem_trans_en_s <= '0'; @@ -261,7 +264,8 @@ wire_in: std_logic_vector(to_unsigned(rx_done_cnt_r, rx_done_cnt_width_c)); state_o_s(7 downto rx_done_cnt_width_c) <= (others => '0'); state_o_s(rx_done_div_width_c + 8 - 1 downto 8) <= rx_done_ratio_r; - state_o_s(15 downto rx_done_div_width_c + 8) <= (others => '0'); + state_o_s(14 downto rx_done_div_width_c + 8) <= (others => '0'); + state_o_s(15) <= rx_crc_error_s; end if; end if; diff --git a/hw/lx_rocon_pkg.vhd b/hw/lx_rocon_pkg.vhd index 78c3da2..4149475 100644 --- a/hw/lx_rocon_pkg.vhd +++ b/hw/lx_rocon_pkg.vhd @@ -217,6 +217,7 @@ package lx_rocon_pkg is sync_i : in std_logic; -- Receive done pulse rx_done_o : out std_logic; + rx_crc_error_o : out std_logic; -- Register register_i : in std_logic; register_o : out std_logic_vector(1 downto 0); diff --git a/hw/lxmaster_receiver.vhd b/hw/lxmaster_receiver.vhd index 3568ca0..fd005ce 100644 --- a/hw/lxmaster_receiver.vhd +++ b/hw/lxmaster_receiver.vhd @@ -17,6 +17,7 @@ entity lxmaster_receiver is sync_i : in std_logic; -- Receive done pulse rx_done_o : out std_logic; + rx_crc_error_o : out std_logic; -- Register register_i : in std_logic; register_o : out std_logic_vector(1 downto 0); @@ -78,6 +79,14 @@ architecture Behavioral of lxmaster_receiver is signal lxmaster_crc_out_s : std_logic_vector(7 downto 0); signal lxmaster_crc_reg_s : std_logic_vector(7 downto 0); signal lxmaster_crc_reg_r : std_logic_vector(7 downto 0); + + signal lxmaster_crc_error_int_s : std_logic; + signal lxmaster_crc_error_int_r : std_logic; + signal lxmaster_crc_error_s : std_logic; + signal lxmaster_crc_error_r : std_logic; + + signal rx_done_s : std_logic; + -- RAM reset signal lxmaster_ram_reset_s : std_logic; -- Register @@ -92,8 +101,9 @@ begin -- CRC lxmaster_crc_reg_s <= '0' & lxmaster_crc_reg_r(7 downto 1) when lxmaster_state_r = ST_CRC else lxmaster_crc_out_s; - lxmaster_crc_data_s <= '1' when lxmaster_state_r = ST_CRC else received_data_r(0); + lxmaster_crc_data_s <= received_data_r(received_data_r'length - 1); lxmaster_crc_reset_s <= '1' when lxmaster_state_r /= ST_XFER or reset_i = '1' else '0'; + rx_crc_error_o <= lxmaster_crc_error_r; -- Register register_o <= lxmaster_register_out_s; @@ -163,14 +173,16 @@ crosdom_ser_fifo: lx_crosdom_ser_fifo transmitter_update: process (ram_data_o_s, ram_addr_r, inc_ram_addr_r, lxmaster_state_r, lxmaster_num_data_r, lxmaster_msg_counter_r, lxmaster_last_word_r, lxmaster_data_counter_r, reset_i, lxmaster_frame_start_s, lxmaster_register_in_s, - sync_s, miso_s, prev_sync_r, received_data_r) + sync_s, miso_s, prev_sync_r, received_data_r, lxmaster_crc_reg_r, lxmaster_crc_error_int_r, + lxmaster_crc_error_r) variable ram_addr_v : std_logic_vector(8 downto 0); + variable crc_bit_mismatch_v : std_logic; begin -- Defaults lxmaster_ram_reset_s <= '0'; lxmaster_sync_last_bit_s <= '0'; - rx_done_o <= '0'; + rx_done_s <= '0'; -- Defaults of state variables (no change) ram_addr_s <= ram_addr_r; inc_ram_addr_s <= '0'; @@ -179,6 +191,8 @@ transmitter_update: lxmaster_num_data_s <= lxmaster_num_data_r; lxmaster_msg_counter_s <= lxmaster_msg_counter_r; lxmaster_last_word_s <= lxmaster_last_word_r; + lxmaster_crc_error_int_s <= lxmaster_crc_error_int_r; + lxmaster_crc_error_s <= lxmaster_crc_error_r; prev_sync_s <= sync_s; ram_we_s <= "00"; @@ -196,6 +210,7 @@ transmitter_update: ram_en_s <= '0'; -- lxmaster_ram_reset_s <= '1'; + lxmaster_crc_error_s <= '0'; else @@ -209,7 +224,7 @@ transmitter_update: -- We just read number of commands if ram_data_o_s(7 downto 0) = x"00" then lxmaster_state_s <= ST_END; --Nothing - rx_done_o <= '1'; + rx_done_s <= '1'; else lxmaster_state_s <= ST_READY; -- Make next read init the transfer ram_addr_v := ram_addr_r(8) & ram_data_o_s(15 downto 8); -- Update address @@ -221,6 +236,8 @@ transmitter_update: -- Prepare message counter lxmaster_msg_counter_s <= 0; + lxmaster_crc_error_int_s <= '0'; + when ST_READY => -- We are ready to begin transferring lxmaster_sync_s <= '1'; -- Transferring data next cycle @@ -263,6 +280,16 @@ transmitter_update: when ST_CRC => + if received_data_r(received_data_r'length - 1) /= lxmaster_crc_reg_r(0) then + crc_bit_mismatch_v := '1'; + else + crc_bit_mismatch_v := '0'; + end if; + + if crc_bit_mismatch_v = '1' then + lxmaster_crc_error_int_s <= '1'; + end if; + -- Check if this is last command, first read one more if lxmaster_data_counter_r = 0 then if lxmaster_msg_counter_r = (msg_max_count_c - 1) then @@ -292,7 +319,8 @@ transmitter_update: if lxmaster_num_data_r = x"00" then lxmaster_state_s <= ST_END; -- Last command - rx_done_o <= '1'; + rx_done_s <= '1'; + lxmaster_crc_error_s <= lxmaster_crc_error_int_r or crc_bit_mismatch_v; else -- Begin transmission of next data lxmaster_sync_s <= '1'; -- Transferring data next cycle @@ -342,6 +370,10 @@ state: lxmaster_crc_reg_r <= lxmaster_crc_reg_s; lxmaster_msg_counter_r <= lxmaster_msg_counter_s; lxmaster_last_word_r <= lxmaster_last_word_s; + lxmaster_crc_error_int_r <= lxmaster_crc_error_int_s; + lxmaster_crc_error_r <= lxmaster_crc_error_s; + + rx_done_o <= rx_done_s; -- Increment counter if reset_i = '1' then -- 2.39.2