signal tx_force_pak_error : std_logic := '0';
signal send_chksum : std_logic := '0';
signal got_chksum : std_logic;
-signal enable_chksum_reg : std_logic_vector(3 downto 0) := "0000";
-signal enable_chksum_comb : std_logic_vector(3 downto 0);
+signal enable_chksum_reg : std_logic_vector(5 downto 0) := "000000";
+signal enable_chksum_comb : std_logic_vector(5 downto 0);
begin
-- end if;
--end process;
-enable_chksum_comb(0) <= MEDIA_INT2MED.ctrl_op(8) and not enable_chksum_reg(0);
-enable_chksum_comb(3 downto 1) <= not enable_chksum_reg(3 downto 1);
+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);
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(19 downto 16);
+ 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';
elsif BUS_RX.read = '1' then
BUS_TX.ack <= '1';
case BUS_RX.addr(1 downto 0) is
- when "00" => BUS_TX.data <= x"000" & enable_chksum_reg & x"0" & "00" & tx_force_pak_error & tx_force_crc_error & crc_error_delay & "000" & force_crc_error;
+ when "00" => BUS_TX.data <= x"00" & "00" & enable_chksum_reg & x"0" & "00" & tx_force_pak_error & tx_force_crc_error & crc_error_delay & "000" & force_crc_error;
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';
FORCE_CRC_ERROR : in std_logic;
CRC_ERROR_DELAY : in std_logic_vector(3 downto 0);
RESET_RETRANSMIT_IN : in std_logic;
- ENABLE_CHKSUM : in std_logic_vector(3 downto 0);
+ ENABLE_CHKSUM : in std_logic_vector(5 downto 0);
GOT_CHKSUM : out std_logic;
--send_dlm: 200 MHz, 1 clock strobe, data valid until next DLM
architecture rx_control_arch of rx_control is
-type rx_state_t is (SLEEP, WAIT_1, FIRST, GET_DATA, GET_IDLE, GET_DLM, MAKE_RESET, START_RETR, GET_CRC, GET_RETR);
+type rx_state_t is (SLEEP, WAIT_1, FIRST, GET_DATA, GET_IDLE, GET_DLM, MAKE_RESET, START_RETR, GET_CRC1, GET_CRC2, GET_RETR);
signal rx_state : rx_state_t;
signal rx_state_bits : std_logic_vector(3 downto 0);
signal rx_packet_num : std_logic_vector(2 downto 0);
signal latched_pulse_good_100 : unsigned(1 downto 0) := "00";
signal waiting_for_retr : std_logic := '0';
signal good_pos_counter : std_logic_vector(7 downto 0) := (others => '0');
-signal retrans_timeout : unsigned(7 downto 0) := (others => '0');
+signal retrans_timeout : unsigned(8 downto 0) := (others => '0');
signal num_pakets : unsigned(3 downto 0) := (others => '0');
--signal reg_num_pakets : unsigned(3 downto 0) := (others => '0');
signal num_read_words : unsigned(2 downto 0) := (others => '0');
+signal RESET_IN_200 : std_logic;
+signal RX_RESET_FINISHED_200 : std_logic;
signal use_crc : std_logic := '0';
signal use_crc_200 : std_logic := '0';
signal num_pak : unsigned(3 downto 0) := (others => '0');
signal resub_mode : std_logic := '0';
signal reset_retrans : std_logic;
-signal enable_chksum_200 : std_logic_vector(3 downto 0);
+signal reset_retrans_200 : std_logic;
+signal enable_chksum_200 : std_logic_vector(5 downto 0);
signal force_crc_error_int : std_logic := '0';
signal force_crc_error_200 : std_logic := '0';
signal is_idle_100, is_idle : std_logic := '0';
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);
-enable_chksum_200 <= ENABLE_CHKSUM when rising_edge(CLK_200);
load_use_crc_sys <= load_use_crc when rising_edge(CLK_100);
is_idle_100 <= is_idle when rising_edge(CLK_100);
force_crc_error_200 <= force_crc_error when rising_edge(CLK_200);
CRC_ERROR_DELAY_200 <= CRC_ERROR_DELAY when rising_edge(CLK_200);
use_crc_200 <= use_crc when rising_edge(CLK_200);
+enable_chksum_200 <= ENABLE_CHKSUM when rising_edge(CLK_200);
+reset_retrans_200 <= reset_retrans when rising_edge(CLK_200);
+RESET_IN_200 <= RESET_IN when rising_edge(CLK_200);
+RX_RESET_FINISHED_200 <= RX_RESET_FINISHED when rising_edge(CLK_200);
+
+
GOT_CHKSUM <= use_crc;
process begin
when K_REQ =>
rx_state <= START_RETR;
when K_EOP =>
- rx_state <= GET_CRC;
+ if use_crc_200 = '1' then
+ rx_state <= GET_CRC2;
+ else
+ rx_state <= GET_CRC1;
+ end if;
when K_BGN =>
rx_state <= GET_RETR;
when others => null;
crc_en <= '1';
end if;
if force_crc_error_int = '1' then
- rx_state <= GET_CRC;
+ rx_state <= GET_CRC2;
end if;
when GET_IDLE =>
if reg_rx_k_in = '0' and reg_rx_data_in = D_IDLE1 then
idle_hist_i(0) <= '1';
got_link_ready_i <= got_link_ready_i or (idle_hist_i(1) and idle_hist_i(3));
- else
- if reg_rx_k_in = '1' then
- rx_state <= FIRST;
- end if;
- if use_crc_200 = '1' and force_crc_error_int = '0' then
- rx_state <= FIRST;
- force_crc_error_int <= '1';
- end if;
+-- else
+-- if reg_rx_k_in = '1' then
+-- rx_state <= FIRST;
+-- end if;
+-- if use_crc_200 = '1' and force_crc_error_int = '0' then
+-- rx_state <= FIRST;
+-- force_crc_error_int <= '1';
+-- end if;
end if;
- if use_crc_200 = '1' and num_pakets /= 0 and force_crc_error_int = '0' and enable_chksum_200(0) = '1' and enable_chksum_200(3) = '1' then
+ if use_crc_200 = '1' and num_pakets /= 0 and force_crc_error_int = '0'
+ and disable_crc = '0'
+ and enable_chksum_200(0) = '1' and enable_chksum_200(3) = '1' then
-- IDLE only allowed after CRC, must be disabled until explicitly
-- switched on
- rx_state <= FIRST;
- --reg_num_pakets <= num_pakets; --debug
+-- rx_state <= FIRST;
force_crc_error_int <= '1';
+ if enable_chksum_200(4) = '1' and num_pakets=5 then
+ force_crc_error_int <= '0'; --mask obligatory CRC after 5 pakets
+ end if;
end if;
-
-
+
when GET_DATA =>
num_pakets <= num_pakets+1;
rx_state_bits <= x"4";
rx_state <= FIRST; -- SLEEP;
end if;
- when GET_CRC =>
- if use_crc_200 = '0' then
- -- first time
- load_use_crc <= '1';
- disable_crc <= '0';
- force_crc_error_int <= '0';
- else
- 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 disable_crc = '0' and enable_chksum_200(0) = '1' then
- -- bad
- --if force_crc_error_int = '1' then --debug
- -- reg_num_pakets <= reg_num_pakets + 1;
- --end if;
- pulse_bad <= '1';
+ when GET_CRC1 =>
+ -- first time
+ load_use_crc <= '1';
+ 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
- --if crc_q /= reg_rx_data_in then --debug
- --num_crc <= num_crc+1;
- --else
- --num_pak <= num_pak+1;
- --end if;
req_retr_i <= '1';
- retrans_timeout <= x"00";
+ retrans_timeout <= "000000000";
waiting_for_retr <= '1';
end if;
- force_crc_error_int <= '0';
else
- -- good
- pulse_good <= '1';
- force_crc_error_int <= '0';
- if force_crc_error_200 = '0' then
- CRC_ERROR_DELAY_cnt <= CRC_ERROR_DELAY_200;
- disable_crc <= '0';
- elsif CRC_ERROR_DELAY_cnt /= "0000" then
- CRC_ERROR_DELAY_cnt <= std_logic_vector(unsigned(CRC_ERROR_DELAY_cnt) - 1);
- end if;
- end if;
+ -- 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');
num_pakets <= (others => '0');
resub_mode <= '1';
next_sop <= '1';
- retrans_timeout <= x"00";
+ retrans_timeout <= "000000000";
when GET_DLM =>
rx_state_bits <= x"5";
end case;
- if waiting_for_retr = '1' and not (rx_state = FIRST) then
+ if waiting_for_retr = '1' and enable_chksum_200(5) = '0' then
retrans_timeout <= retrans_timeout+1;
- if retrans_timeout = x"ff" then
+ if retrans_timeout = "111111111" then
req_retr_i <= '1';
- retrans_timeout <= x"00";
+ retrans_timeout <= "000000000";
end if;
end if;
-
- if RESET_IN = '1' or RX_RESET_FINISHED = '0' then
+ if RESET_IN_200 = '1' or RX_RESET_FINISHED_200 = '0' then
rx_state <= SLEEP;
if rx_state = MAKE_RESET then
make_reset_i <= '1';
send_link_reset_i <= '0';
end if;
- if reset_retrans = '1' then
+ if reset_retrans_200 = '1' then
load_use_crc <= '0';
crc_reset <= '1';
waiting_for_retr <= '0';