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);
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
-- 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;
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';
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";
ram_en_s <= '0';
--
lxmaster_ram_reset_s <= '1';
+ lxmaster_crc_error_s <= '0';
else
-- 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
-- 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
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
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
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