]> jspc29.x-matter.uni-frankfurt.de Git - trbnet.git/commitdiff
added USE_RETRANSMISSION generic
authorIngo Froehlich <ingo@nomail.fake>
Fri, 13 Dec 2019 14:33:15 +0000 (15:33 +0100)
committerIngo Froehlich <ingo@nomail.fake>
Fri, 13 Dec 2019 14:33:15 +0000 (15:33 +0100)
1  2 
media_interfaces/med_ecp3_sfp_sync.vhd
media_interfaces/med_ecp3_sfp_sync_4.vhd
media_interfaces/med_ecp3_sfp_sync_4_slave3.vhd
media_interfaces/med_ecp5_sfp_sync.vhd
media_interfaces/sync/med_sync_control.vhd
media_interfaces/sync/med_sync_define.vhd
media_interfaces/sync/rx_control.vhd
media_interfaces/sync/tx_control.vhd

index e57c48d6c095a82cf4cffb16851c8241b99f579c,308f518430de1ddc2595dc0fd6e51931945b88b6..e66099d28f6007ec6dd725f0f95d221e1caac3d4
@@@ -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(
index aa0964cc588a2086711c38e0e311877eb659f326,2af6d8c20dbe48615057cdc1b430dbc80d345313..a8cbdea60c9d3e58eeccdad6c51fb2f84910ddcd
@@@ -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,
index 10c3d4f69173a6db03548eb050ab038ceac53b77,0db57c9d5522f47961ef19fdafdb4b861360b098..7e2e53d49ad2d42068e5b9d2fd3a4b8360c1ffee
@@@ -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,
index 4e595b99df9821d064acd7e29f60c1b8c6b0ebc7,5b798839571aa534776d834b9ecd94165176241c..28cfcc51c3c2b6ee1b458096c29851f4fbaaeb0d
@@@ -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
index 8be8a5c9e96a593312a2c61878f9c74da06324b7,bda484bca4c13f3346f545902219f81b2ca38715..37a11464489833972044384df401655f5d304c51
@@@ -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,
index 0ad136b8a95e0c0a70a514025bd059eef6c5d6da,9eaf330fbd0d9bff557a1d518a01230723ce4fc3..bf5e290aba765c53bf66105aa1a82ef873c73c27
@@@ -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;
index dea56eeefbf3597c1a2e1554ccec8a9ebcb9226c,88c91fbce327fa3e934927ca49dbc15f6bc73b08..014ca44195d57097c7a043f7edd5ea411bdb18c0
@@@ -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
  ----------------------------------------------------------------------
  
- 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;
 + 
 +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);
 +
-   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';
++    --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;
 +
-     else
-       fatal_counter <= "0000";
++    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;
-   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
 +    end if;
-     end if;
-     if latched_pulse_good_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';
 -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";
++      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;  
-     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';
++    --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;
 -      rx_packet_num <= std_logic_vector(unsigned(rx_packet_num)+1);
 -    end if;  
 -  end if;
 -end process;
++
++    --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
-     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;
++      --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;
-   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";
 +    
-       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
++    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
-   end if;
- end process;
-             
++      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;
++    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';
index 9f738b8f426fff83e39e655de9e8f5281888c67b,298e8d25167601d1cf12cedbea19a9545b207703..d20710fa8072a7e39046e1de91ff9d43a7b7b6e5
@@@ -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);
              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 =>