]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/blobdiff - hw/lxmaster_receiver.vhd
LX master: implement CRC checking in receiver.
[fpga/lx-cpu1/lx-rocon.git] / hw / lxmaster_receiver.vhd
index 3568ca0deb76e4dc9a4dfcce4bf1ee53bd24789e..fd005ce483f9c12318a556816148d5b4ff9e02cd 100644 (file)
@@ -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