From: Ingo Froehlich Date: Fri, 13 Dec 2019 14:33:15 +0000 (+0100) Subject: added USE_RETRANSMISSION generic X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=e1158f954609d388bc8e266fd6613e23cef58aba;p=trbnet.git added USE_RETRANSMISSION generic --- e1158f954609d388bc8e266fd6613e23cef58aba diff --cc media_interfaces/med_ecp3_sfp_sync.vhd index e57c48d,308f518..e66099d --- a/media_interfaces/med_ecp3_sfp_sync.vhd +++ b/media_interfaces/med_ecp3_sfp_sync.vhd @@@ -13,6 -13,6 +13,7 @@@ use work.med_sync_define.all entity med_ecp3_sfp_sync is generic( SERDES_NUM : integer range 0 to 3 := 0; ++ USE_RETRANSMISSION : integer := c_NO; IS_SYNC_SLAVE : integer := c_NO --select slave mode ); port( @@@ -235,6 -229,6 +236,7 @@@ end generate THE_MED_CONTROL : entity work.med_sync_control generic map( IS_SYNC_SLAVE => IS_SYNC_SLAVE, ++ USE_RETRANSMISSION => USE_RETRANSMISSION, IS_TX_RESET => 1 ) port map( diff --cc media_interfaces/med_ecp3_sfp_sync_4.vhd index aa0964c,2af6d8c..a8cbdea --- a/media_interfaces/med_ecp3_sfp_sync_4.vhd +++ b/media_interfaces/med_ecp3_sfp_sync_4.vhd @@@ -14,7 -14,7 +14,8 @@@ use work.med_sync_define.all entity med_ecp3_sfp_sync_4 is generic( IS_SYNC_SLAVE : int_array_t(0 to 3) := (c_NO, c_NO, c_NO, c_NO); --select slave mode -- IS_USED : int_array_t(0 to 3) := (c_YES,c_YES,c_YES,c_YES) ++ IS_USED : int_array_t(0 to 3) := (c_YES,c_YES,c_YES,c_YES); ++ USE_RETRANSMISSION : integer := c_NO ); port( CLK_REF_FULL : in std_logic; -- 200 MHz reference clock @@@ -277,7 -273,7 +278,8 @@@ gen_control : for i in 0 to 3 generat THE_MED_CONTROL : entity work.med_sync_control generic map( IS_SYNC_SLAVE => IS_SYNC_SLAVE(i), -- IS_TX_RESET => 1 ++ IS_TX_RESET => 1, ++ USE_RETRANSMISSION => USE_RETRANSMISSION ) port map( CLK_SYS => SYSCLK, diff --cc media_interfaces/med_ecp3_sfp_sync_4_slave3.vhd index 10c3d4f,0db57c9..7e2e53d --- a/media_interfaces/med_ecp3_sfp_sync_4_slave3.vhd +++ b/media_interfaces/med_ecp3_sfp_sync_4_slave3.vhd @@@ -14,8 -14,7 +14,9 @@@ use work.med_sync_define.all entity med_ecp3_sfp_sync_4_slave3 is generic( IS_SYNC_SLAVE : int_array_t(0 to 3) := (c_NO, c_NO, c_NO, c_NO); --select slave mode - IS_USED : int_array_t(0 to 3) := (c_YES,c_YES,c_YES,c_YES) + IS_USED : int_array_t(0 to 3) := (c_YES,c_YES,c_YES,c_YES); ++ USE_RETRANSMISSION : integer := c_NO; + REG_OFFSET : std_logic_vector(7 downto 0) := x"00" ); port( CLK_REF_FULL : in std_logic; -- 200 MHz reference clock @@@ -276,7 -269,7 +277,8 @@@ gen_control : for i in 0 to 3 generat THE_MED_CONTROL : entity work.med_sync_control generic map( IS_SYNC_SLAVE => IS_SYNC_SLAVE(i), -- IS_TX_RESET => 1 ++ IS_TX_RESET => 1, ++ USE_RETRANSMISSION => USE_RETRANSMISSION ) port map( CLK_SYS => SYSCLK, diff --cc media_interfaces/med_ecp5_sfp_sync.vhd index 4e595b9,5b79883..28cfcc5 --- a/media_interfaces/med_ecp5_sfp_sync.vhd +++ b/media_interfaces/med_ecp5_sfp_sync.vhd @@@ -106,15 -106,9 +107,16 @@@ attribute nopad of hdinp, hdinn, hdout signal stat_med : std_logic_vector(31 downto 0); +signal mii_tx_i : CTRLBUS_TX; +signal mii_rx_i : CTRLBUS_RX; + +signal loc_bus_rx : CTRLBUS_RX; +signal loc_bus_tx : CTRLBUS_TX; + + begin + reset_n <= not RESET; clk_200_ref <= CLK_REF_FULL; SD_TXDIS_OUT <= not rx_ready when IS_SYNC_SLAVE = 1 else '0'; --slave only switches on when RX is ready diff --cc media_interfaces/sync/med_sync_control.vhd index 8be8a5c,bda484b..37a1146 --- a/media_interfaces/sync/med_sync_control.vhd +++ b/media_interfaces/sync/med_sync_control.vhd @@@ -9,8 -9,8 +9,9 @@@ use work.med_sync_define.all entity med_sync_control is generic( -- IS_SYNC_SLAVE : integer := 1; -- IS_TX_RESET : integer := 1 ++ IS_SYNC_SLAVE : integer := c_YES; ++ IS_TX_RESET : integer := c_YES; ++ USE_RETRANSMISSION : integer := c_NO ); port( CLK_SYS : in std_logic; @@@ -228,70 -187,11 +229,78 @@@ PROC_START_TIMER : process begi start_timer <= (others => '0'); end if; end process; - + +--PROC_RETRANS_COUNTER : process begin +-- wait until rising_edge(CLK_SYS); +-- if make_link_reset_real_i = '0' then +-- request_retr_counter <= x"0000"; +-- start_retr_counter <= x"0000"; +-- end if; +--end process; + +enable_chksum_comb(0) <= (MEDIA_INT2MED.ctrl_op(8) and not enable_chksum_reg(0)) when rising_edge(CLK_SYS); +enable_chksum_comb(5 downto 1) <= not enable_chksum_reg(5 downto 1) when rising_edge(CLK_SYS); + +PROC_REG : process begin + wait until rising_edge(CLK_SYS); + + if request_retr_i = '1' then + request_retr_counter <= std_logic_vector(unsigned(request_retr_counter) + 1); + end if; + if start_retr_i = '1' then + start_retr_counter <= std_logic_vector(unsigned(start_retr_counter) + 1); + end if; + + BUS_TX.data <= x"00000000"; + BUS_TX.unknown <= '0'; + BUS_TX.ack <= '0'; + if BUS_RX.write = '1' then + BUS_TX.ack <= '1'; + case BUS_RX.addr(1 downto 0) is + when "00" => force_crc_error <= BUS_RX.data(0); + crc_error_delay <= BUS_RX.data(7 downto 4); + tx_force_crc_error <= BUS_RX.data(8); + tx_force_pak_error <= BUS_RX.data(9); + enable_chksum_reg <= BUS_RX.data(21 downto 16); + when "01" => force_crc_error <= '0'; tx_force_crc_error <= '0'; tx_force_pak_error <= '0'; + request_retr_counter <= x"0000"; start_retr_counter <= x"0000"; + when others => BUS_TX.unknown <= '1'; + end case; + elsif BUS_RX.read = '1' then + BUS_TX.ack <= '1'; + case BUS_RX.addr(1 downto 0) is - when "00" => BUS_TX.data <= x"00" & got_fatal_error & got_chksum & enable_chksum_reg & x"0" & "00" & tx_force_pak_error & tx_force_crc_error & crc_error_delay & "000" & force_crc_error; ++ when "00" => ++ if USE_RETRANSMISSION = c_YES then ++ BUS_TX.data <= x"00" & got_fatal_error & got_chksum & enable_chksum_reg & x"0" & "00" & tx_force_pak_error & tx_force_crc_error & crc_error_delay & "000" & force_crc_error; ++ else ++ BUS_TX.data <= x"10000000"; ++ end if; + when "01" => BUS_TX.data <= request_retr_counter & start_retr_counter; + --when "11" => BUS_TX.data <= x"000000" & DEBUG_RX_CONTROL_i(31 downto 24); + when others => BUS_TX.unknown <= '1'; + end case; + end if; + + if last_FORCE_CRC_ERROR_IN = '0' and FORCE_CRC_ERROR_IN = '1' then + force_crc_error <= '1'; + elsif request_retr_i = '1' then + force_crc_error <= '0'; + end if; + + if tx_got_force_error_100 = '1' then + tx_force_crc_error <= '0'; + tx_force_pak_error <= '0'; + end if; + +end process; + ------------------------------------------------- -- TX Data ------------------------------------------------- THE_TX : tx_control ++ generic map( ++ USE_RETRANSMISSION => USE_RETRANSMISSION ++ ) port map( CLK_200 => CLK_TXI, CLK_100 => CLK_SYS, @@@ -344,6 -228,6 +353,9 @@@ end generate -- RX Data ------------------------------------------------- THE_RX_CONTROL : rx_control ++ generic map( ++ USE_RETRANSMISSION => USE_RETRANSMISSION ++ ) port map( CLK_200 => CLK_RXI, CLK_100 => CLK_SYS, diff --cc media_interfaces/sync/med_sync_define.vhd index 0ad136b,9eaf330..bf5e290 --- a/media_interfaces/sync/med_sync_define.vhd +++ b/media_interfaces/sync/med_sync_define.vhd @@@ -18,6 -18,6 +18,9 @@@ constant K_RST : std_logic_vector(7 constant K_DLM : std_logic_vector(7 downto 0) := x"DC"; component rx_control is ++ generic( ++ USE_RETRANSMISSION : integer := c_YES ++ ); port( CLK_200 : in std_logic; CLK_100 : in std_logic; @@@ -60,6 -53,6 +63,9 @@@ end component component tx_control is ++ generic( ++ USE_RETRANSMISSION : integer := c_YES ++ ); port( CLK_200 : in std_logic; CLK_100 : in std_logic; diff --cc media_interfaces/sync/rx_control.vhd index dea56ee,88c91fb..014ca44 --- a/media_interfaces/sync/rx_control.vhd +++ b/media_interfaces/sync/rx_control.vhd @@@ -8,6 -8,6 +8,9 @@@ use work.trb_net_components.all use work.med_sync_define.all; entity rx_control is ++ generic( ++ USE_RETRANSMISSION : integer := c_YES ++ ); port( CLK_200 : in std_logic; CLK_100 : in std_logic; @@@ -146,157 -86,29 +149,188 @@@ begi -- Data to Endpoint ---------------------------------------------------------------------- + +ct_fifo_read <= not ct_fifo_reset and not ct_fifo_empty and (got_pulse_good or got_pulse_bad or not use_crc); +GOT_CHKSUM <= use_crc; +GOT_FATAL_ERROR <= fatal_error; + +-- 100 MHz registers +buf_RX_DATA_OUT <= ct_fifo_data_out(15 downto 0) when rising_edge(CLK_100); +RX_DATA_OUT <= buf_RX_DATA_OUT; +RX_WRITE_OUT <= buf2_rx_write_out; +RX_PACKET_NUMBER_OUT <= rx_packet_num when rising_edge(CLK_100); + +last_ct_fifo_read <= ct_fifo_read when rising_edge(CLK_100); +last_ct_fifo_empty <= ct_fifo_empty when rising_edge(CLK_100); +last_use_crc <= use_crc when rising_edge(CLK_100); +reset_retrans <= RESET_RETRANSMIT_IN when rising_edge(CLK_100); + +-- 200 to 100 MHz transfer +load_use_crc_100_i <= load_use_crc when rising_edge(CLK_100); +load_use_crc_100 <= load_use_crc_100_i when rising_edge(CLK_100); +is_idle_100_i <= is_idle when rising_edge(CLK_100); +is_idle_100 <= is_idle_100_i when rising_edge(CLK_100); + +-- 100 to 200 MHz transfer +force_crc_error_200_i <= force_crc_error when rising_edge(CLK_200); +force_crc_error_200 <= force_crc_error_200_i when rising_edge(CLK_200); +CRC_ERROR_DELAY_200_i <= CRC_ERROR_DELAY when rising_edge(CLK_200); +CRC_ERROR_DELAY_200 <= CRC_ERROR_DELAY_200_i when rising_edge(CLK_200); +use_crc_200_i <= use_crc when rising_edge(CLK_200); +use_crc_200 <= use_crc_200_i when rising_edge(CLK_200); +enable_chksum_200_i <= ENABLE_CHKSUM when rising_edge(CLK_200); +enable_chksum_200 <= enable_chksum_200_i when rising_edge(CLK_200); +reset_retrans_200_i <= reset_retrans when rising_edge(CLK_200); +reset_retrans_200 <= reset_retrans_200_i when rising_edge(CLK_200); +RESET_IN_200_i <= RESET_IN when rising_edge(CLK_200); +RESET_IN_200 <= RESET_IN_200_i when rising_edge(CLK_200); +RX_RESET_FINISHED_200_i <= RX_RESET_FINISHED when rising_edge(CLK_200); +RX_RESET_FINISHED_200 <= RX_RESET_FINISHED_200_i when rising_edge(CLK_200); + + ++gen_used_retransmission : if USE_RETRANSMISSION = c_YES generate ++ process ++ begin ++ wait until rising_edge(CLK_100); + - process begin - wait until rising_edge(CLK_100); - - --switch only when fifo is empty: - if is_idle_100 = '1' and ct_fifo_empty = '1' and load_use_crc_100 = '1' and fatal_error = '0' then - --if ct_fifo_empty = '1' and load_use_crc_100 = '1' then - use_crc <= '1'; - elsif (ct_fifo_empty = '1' and load_use_crc_100 = '0') then - use_crc <= '0'; - end if; ++ --switch only when fifo is empty: ++ if is_idle_100 = '1' and ct_fifo_empty = '1' and load_use_crc_100 = '1' and fatal_error = '0' then ++ --if ct_fifo_empty = '1' and load_use_crc_100 = '1' then ++ use_crc <= '1'; ++ elsif (ct_fifo_empty = '1' and load_use_crc_100 = '0') then ++ use_crc <= '0'; ++ end if; + - if use_crc = '1' then - --fatal error, disable mechanism - if is_idle_100 = '1' and ct_fifo_empty = '0' then - fatal_counter <= fatal_counter + 1; - if fatal_counter = 15 then -- 6 idles with full fifo means something is wrong - fatal_error <= '1'; - use_crc <= '0'; ++ if use_crc = '1' then ++ --fatal error, disable mechanism ++ if is_idle_100 = '1' and ct_fifo_empty = '0' then ++ fatal_counter <= fatal_counter + 1; ++ if fatal_counter = 15 then -- 6 idles with full fifo means something is wrong ++ fatal_error <= '1'; ++ use_crc <= '0'; ++ end if; ++ else ++ fatal_counter <= "0000"; + end if; - else - fatal_counter <= "0000"; + end if; - end if; - - --some logic to remember the state: - if (pulse_good_100 = '1' or latched_pulse_good_100 /= "00") and (ct_fifo_empty = '1' or num_read_words = 0) then - got_pulse_good <= '1'; - got_pulse_bad <= '0'; - if latched_pulse_good_100 /= "00" then - latched_pulse_good_100 <= latched_pulse_good_100 - 1; - end if; - elsif pulse_good_100 = '1' then - latched_pulse_good_100 <= latched_pulse_good_100 + 1; - elsif (pulse_bad_100 = '1' or latched_pulse_bad_100 /= "00") and (ct_fifo_empty = '1' or num_read_words = 0) then - got_pulse_bad <= '1'; - got_pulse_good <= '0'; - if latched_pulse_bad_100 /= "00" then - latched_pulse_bad_100 <= latched_pulse_bad_100 - 1; - end if; - elsif pulse_bad_100 = '1' then - latched_pulse_bad_100 <= latched_pulse_bad_100 + 1; - end if; - - --switching the good/bad mode is only allowed after complete pakets - --(otherwise the current transfer is interrupted) - if ct_fifo_empty = '1' or num_read_words = 4 or use_crc = '0' then - if latched_pulse_bad_100 = "00" then ++ ++ --some logic to remember the state: ++ if (pulse_good_100 = '1' or latched_pulse_good_100 /= "00") and (ct_fifo_empty = '1' or num_read_words = 0) then ++ got_pulse_good <= '1'; + got_pulse_bad <= '0'; - end if; - if latched_pulse_good_100 = "00" then ++ if latched_pulse_good_100 /= "00" then ++ latched_pulse_good_100 <= latched_pulse_good_100 - 1; ++ end if; ++ elsif pulse_good_100 = '1' then ++ latched_pulse_good_100 <= latched_pulse_good_100 + 1; ++ elsif (pulse_bad_100 = '1' or latched_pulse_bad_100 /= "00") and (ct_fifo_empty = '1' or num_read_words = 0) then ++ got_pulse_bad <= '1'; + got_pulse_good <= '0'; ++ if latched_pulse_bad_100 /= "00" then ++ latched_pulse_bad_100 <= latched_pulse_bad_100 - 1; ++ end if; ++ elsif pulse_bad_100 = '1' then ++ latched_pulse_bad_100 <= latched_pulse_bad_100 + 1; ++ end if; + -ct_fifo_read <= not ct_fifo_reset and not ct_fifo_empty; -- when rising_edge(CLK_100); -buf_rx_write_out <= last_ct_fifo_read and not last_ct_fifo_empty when rising_edge(CLK_100); - -RX_DATA_OUT <= ct_fifo_data_out(15 downto 0) ; -RX_WRITE_OUT <= buf_rx_write_out; -RX_PACKET_NUMBER_OUT <= rx_packet_num; - -last_ct_fifo_read <= ct_fifo_read when rising_edge(CLK_100); -last_ct_fifo_empty <= ct_fifo_empty when rising_edge(CLK_100); - -process begin - wait until rising_edge(CLK_100); - if RX_ALLOW_IN = '0' then - rx_packet_num <= "100"; - elsif buf_rx_write_out = '1' then - if rx_packet_num = "100" then - rx_packet_num <= "000"; ++ --switching the good/bad mode is only allowed after complete pakets ++ --(otherwise the current transfer is interrupted) ++ if ct_fifo_empty = '1' or num_read_words = 4 or use_crc = '0' then ++ if latched_pulse_bad_100 = "00" then ++ got_pulse_bad <= '0'; ++ end if; ++ if latched_pulse_good_100 = "00" then ++ got_pulse_good <= '0'; ++ end if; ++ num_read_words <= "000"; ++ elsif use_crc = '1' and ct_fifo_read = '1' then ++ num_read_words <= num_read_words + 1; + end if; - num_read_words <= "000"; - elsif use_crc = '1' and ct_fifo_read = '1' then - num_read_words <= num_read_words + 1; - end if; - - --the following lines catches the case that an incomplete paket is merged - --with the fresh new paket after resubmit - --(see also pulse_bad in GET_RETR) - if (pulse_good_100 = '1' or latched_pulse_good_100 /= "00") and got_pulse_bad = '1' and num_read_words /= "010" and ct_fifo_data_out(16) = '1' then - buf_rx_write_out <= '1'; - got_pulse_good <= '1'; - got_pulse_bad <= '0'; - num_read_words <= "011"; - latched_pulse_good_100 <= "00"; - last_got_pulse_bad <= '0'; - else - --thats like it should work in normal mode: - buf_rx_write_out <= last_ct_fifo_read and not last_ct_fifo_empty and not got_pulse_bad; - if last_got_pulse_bad = '1' then - buf_rx_write_out <= '0'; ++ ++ --the following lines catches the case that an incomplete paket is merged ++ --with the fresh new paket after resubmit ++ --(see also pulse_bad in GET_RETR) ++ if (pulse_good_100 = '1' or latched_pulse_good_100 /= "00") and got_pulse_bad = '1' and num_read_words /= "010" and ct_fifo_data_out(16) = '1' then ++ buf_rx_write_out <= '1'; ++ got_pulse_good <= '1'; ++ got_pulse_bad <= '0'; ++ num_read_words <= "011"; ++ latched_pulse_good_100 <= "00"; ++ last_got_pulse_bad <= '0'; + else - rx_packet_num <= std_logic_vector(unsigned(rx_packet_num)+1); - end if; - end if; -end process; ++ --thats like it should work in normal mode: ++ buf_rx_write_out <= last_ct_fifo_read and not last_ct_fifo_empty and not got_pulse_bad; ++ if last_got_pulse_bad = '1' then ++ buf_rx_write_out <= '0'; ++ end if; ++ last_got_pulse_bad <= got_pulse_bad; ++ end if; ++ ++ if send_link_reset_i = '1' or reset_retrans = '1' then ++ good_pos_counter <= (others => '0'); ++ got_pulse_good <= '0'; ++ got_pulse_bad <= '0'; ++ num_read_words <= "000"; ++ latched_pulse_good_100 <= "00"; ++ latched_pulse_bad_100 <= "00"; ++ use_crc <= '0'; ++ fatal_error <= '0'; ++ elsif last_use_crc = '0' and buf_rx_write_out = '1' then ++ good_pos_counter <= std_logic_vector(unsigned(good_pos_counter)+1); ++ elsif pulse_good_100 = '1' then ++ good_pos_counter <= std_logic_vector(unsigned(good_pos_counter)+5); + end if; - last_got_pulse_bad <= got_pulse_bad; - end if; - - if send_link_reset_i = '1' or reset_retrans = '1' then - good_pos_counter <= (others => '0'); - got_pulse_good <= '0'; - got_pulse_bad <= '0'; - num_read_words <= "000"; - latched_pulse_good_100 <= "00"; - latched_pulse_bad_100 <= "00"; - use_crc <= '0'; - fatal_error <= '0'; - elsif last_use_crc = '0' and buf_rx_write_out = '1' then - good_pos_counter <= std_logic_vector(unsigned(good_pos_counter)+1); - elsif pulse_good_100 = '1' then - good_pos_counter <= std_logic_vector(unsigned(good_pos_counter)+5); - end if; + - if RX_ALLOW_IN = '0' then - rx_packet_num <= "100"; - elsif buf_rx_write_out = '1' then - if rx_packet_num = "100" then - rx_packet_num <= "000"; ++ if RX_ALLOW_IN = '0' then ++ rx_packet_num <= "100"; ++ elsif buf_rx_write_out = '1' then ++ if rx_packet_num = "100" then ++ rx_packet_num <= "000"; ++ else ++ rx_packet_num <= std_logic_vector(unsigned(rx_packet_num)+1); ++ end if; ++ end if; ++ end process; ++ ++ process ++ begin ++ wait until rising_edge(CLK_100); ++ if (pulse_good_100 = '1' or latched_pulse_good_100 /= "00") and got_pulse_bad = '1' and num_read_words /= "010" and ct_fifo_data_out(16) = '1' then ++ buf2_rx_write_out <= '1'; + else - rx_packet_num <= std_logic_vector(unsigned(rx_packet_num)+1); - end if; - end if; - end process; - - process begin - wait until rising_edge(CLK_100); - if (pulse_good_100 = '1' or latched_pulse_good_100 /= "00") and got_pulse_bad = '1' and num_read_words /= "010" and ct_fifo_data_out(16) = '1' then - buf2_rx_write_out <= '1'; - else ++ buf2_rx_write_out <= buf_rx_write_out; ++ end if; ++ end process; ++end generate; ++ ++gen_no_retransmission : if USE_RETRANSMISSION = c_NO generate ++ process ++ begin ++ wait until rising_edge(CLK_100); ++ + buf2_rx_write_out <= buf_rx_write_out; - end if; - end process; - ++ use_crc <= '0'; ++ ++ if send_link_reset_i = '1' or reset_retrans = '1' then ++ good_pos_counter <= (others => '0'); ++ num_read_words <= "000"; ++ use_crc <= '0'; ++ fatal_error <= '0'; ++ end if; ++ ++ if RX_ALLOW_IN = '0' then ++ rx_packet_num <= "100"; ++ elsif buf_rx_write_out = '1' then ++ if rx_packet_num = "100" then ++ rx_packet_num <= "000"; ++ else ++ rx_packet_num <= std_logic_vector(unsigned(rx_packet_num)+1); ++ end if; ++ end if; ++ ++ buf_rx_write_out <= last_ct_fifo_read and not last_ct_fifo_empty; ++ end process; ++end generate; ---------------------------------------------------------------------- -- Clock Domain Transfer @@@ -319,22 -131,6 +353,24 @@@ THE_CT_FIFO : entity work.lattice_ecp3_ ct_fifo_reset <= not RX_ALLOW_IN when rising_edge(CLK_200); +---------------------------------------------------------------------- +-- CRC +---------------------------------------------------------------------- + +crc_data <= reg_rx_data_in when rising_edge(CLK_200); + ++gen_used_retransmission2 : if USE_RETRANSMISSION = c_YES generate +CRC_CALC : trb_net_CRC8 + port map( + CLK => CLK_200, + RESET => crc_reset, + CLK_EN => crc_en, + DATA_IN => crc_data, + CRC_OUT => crc_q, + CRC_match => open + ); ++end generate; + ---------------------------------------------------------------------- -- Read incoming data ---------------------------------------------------------------------- @@@ -441,68 -196,9 +477,70 @@@ PROC_RX_FSM : process begi ct_fifo_write <= '1'; rx_state <= FIRST; else - rx_state <= FIRST; -- SLEEP; + rx_state <= FIRST; -- SLEEP; end if; - + + when GET_CRC1 => + -- first time - load_use_crc <= '1'; ++ if USE_RETRANSMISSION = c_YES then ++ load_use_crc <= '1'; ++ end if; + if disable_crc = '0' then + disable_crc <= '1'; + end if; + force_crc_error_int <= '0'; + crc_reset <= '1'; + rx_state <= FIRST; + num_pakets <= (others => '0'); + + when GET_CRC2 => + if ((crc_q /= reg_rx_data_in and enable_chksum_200(1) = '1') + or (force_crc_error_200 = '1' and CRC_ERROR_DELAY_cnt = "0000") + or waiting_for_retr = '1' + or (num_pakets /= 5 and enable_chksum_200(2) = '1') + or force_crc_error_int = '1') and enable_chksum_200(0) = '1' then + -- bad + if disable_crc = '0' then + pulse_bad <= '1'; + if waiting_for_retr = '0' then + req_retr_i <= '1'; + reset_timeout <= '1'; + waiting_for_retr <= '1'; + end if; + else + -- this disables errors until at least one good has been passed + pulse_good <= '1'; + end if; + else + -- good + pulse_good <= '1'; + if force_crc_error_200 = '0' then + CRC_ERROR_DELAY_cnt <= CRC_ERROR_DELAY_200; + disable_crc <= '0'; + else + CRC_ERROR_DELAY_cnt <= std_logic_vector(unsigned(CRC_ERROR_DELAY_cnt) - 1); + end if; + end if; + force_crc_error_int <= '0'; + crc_reset <= '1'; + rx_state <= FIRST; + num_pakets <= (others => '0'); + + when GET_RETR => + if force_crc_error_200 = '1' then + disable_crc <= '1'; + end if; + if num_pakets /= "0000" then --incomplete packet + pulse_bad <= '1'; + end if; + rx_state <= FIRST; + waiting_for_retr <= '0'; + crc_reset <= '1'; + num_pakets <= (others => '0'); + resub_mode <= '1'; + next_sop <= '1'; + reset_timeout <= '1'; + when GET_DLM => rx_state_bits <= x"5"; rx_dlm_i <= '1'; diff --cc media_interfaces/sync/tx_control.vhd index 9f738b8,298e8d2..d20710f --- a/media_interfaces/sync/tx_control.vhd +++ b/media_interfaces/sync/tx_control.vhd @@@ -8,6 -8,6 +8,9 @@@ use work.trb_net_components.all use work.med_sync_define.all; entity tx_control is ++ generic( ++ USE_RETRANSMISSION : integer := c_YES ++ ); port( CLK_200 : in std_logic; CLK_100 : in std_logic; @@@ -204,10 -180,9 +207,10 @@@ begi -- ram_read_addr <= (others => '0'); -- els if rising_edge(CLK_200) then - if tx_allow_qtx = '0' then + if tx_allow_qtx = '0' or send_link_reset_qtx = '1' or reset_retrans_200 = '1' + then ram_read_addr <= (others => '0'); -- elsif load_read_pointer_i = '1' then ++ elsif load_read_pointer_i = '1' and USE_RETRANSMISSION = c_YES then ram_read_addr <= unsigned(restart_position_i); elsif ram_read = '1' then ram_read_addr <= ram_read_addr + to_unsigned(1,1); @@@ -295,9 -263,6 +298,9 @@@ TX_DATA_OUT <= ram_dout(7 downto 0); load_sop <= ram_dout(16); load_eop <= ram_dout(17); - if ENABLE_SEND_CHKSUM = '0' then ++ if ENABLE_SEND_CHKSUM = '0' or USE_RETRANSMISSION = c_NO then + load_eop <= '0'; + end if; current_state <= SEND_DATA_H; when SEND_DATA_H =>