]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/commitdiff
LX master: implement CRC checking in receiver.
authorPavel Pisa <ppisa@pikron.com>
Sun, 22 Feb 2015 11:34:06 +0000 (12:34 +0100)
committerPavel Pisa <ppisa@pikron.com>
Sun, 22 Feb 2015 11:34:06 +0000 (12:34 +0100)
Signed-off-by: Pavel Pisa <ppisa@pikron.com>
hw/bus_lxmaster.vhd
hw/lx_rocon_pkg.vhd
hw/lxmaster_receiver.vhd

index cdb3e11a30d16c16991127b346b7f0b1f8b8faae..f4430279819664a618017a8ccab496c42b5213ce 100644 (file)
@@ -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;
 
index 78c3da2c83a595848a46d328d8889d0eff03a0a5..414947522a7ec274ee22c981f9817439a09fbff9 100644 (file)
@@ -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);
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