signal tx_force_pak_error : std_logic := '0';
signal send_chksum : std_logic := '0';
signal got_chksum : std_logic;
+signal got_fatal_error : std_logic;
signal enable_chksum_reg : std_logic_vector(5 downto 0) := "000000";
signal enable_chksum_comb : std_logic_vector(5 downto 0);
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" & "00" & 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" & 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 "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';
TX_ALLOW_IN => tx_allow,
RX_ALLOW_IN => rx_allow,
- --ENABLE_SEND_CHKSUM => '1', --SIM
- --ENABLE_SEND_CHKSUM => MEDIA_INT2MED.ctrl_op(8),
- ENABLE_SEND_CHKSUM => send_chksum,
+ ENABLE_SEND_CHKSUM => send_chksum,
RESET_RETRANSMIT_IN => send_link_reset_i,
--RESET_RETRANSMIT_IN => '0',
FORCE_CRC_ERROR => force_crc_error,
CRC_ERROR_DELAY => crc_error_delay,
- RESET_RETRANSMIT_IN => MEDIA_INT2MED.ctrl_op(15),
- --RESET_RETRANSMIT_IN => '0', --SIM
- --ENABLE_CHKSUM => MEDIA_INT2MED.ctrl_op(8),
+ RESET_RETRANSMIT_IN => MEDIA_INT2MED.ctrl_op(15), --REAL
+ -- RESET_RETRANSMIT_IN => '0', --SIM
ENABLE_CHKSUM => enable_chksum_comb,
GOT_CHKSUM => got_chksum,
+ GOT_FATAL_ERROR => got_fatal_error,
--send_dlm: 200 MHz, 1 clock strobe, data valid until next DLM
RX_DLM => rx_dlm_i,
CRC_ERROR_DELAY : in std_logic_vector(3 downto 0);
RESET_RETRANSMIT_IN : in std_logic;
ENABLE_CHKSUM : in std_logic_vector(5 downto 0);
- GOT_CHKSUM : out std_logic;
+ GOT_CHKSUM : out std_logic;
+ GOT_FATAL_ERROR : out std_logic;
--send_dlm: 200 MHz, 1 clock strobe, data valid until next DLM
RX_DLM : out std_logic := '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 RESET_IN_200, RESET_IN_200_i : std_logic;
+signal RX_RESET_FINISHED_200, RX_RESET_FINISHED_200_i : std_logic;
signal use_crc : std_logic := '0';
-signal use_crc_200 : std_logic := '0';
+signal use_crc_200, use_crc_200_i : std_logic := '0';
signal last_use_crc : std_logic := '0';
signal load_use_crc : std_logic := '0';
-signal load_use_crc_sys : std_logic := '0';
+signal load_use_crc_100, load_use_crc_100_i : std_logic := '0';
signal disable_crc : std_logic := '0';
signal num_crc : unsigned(3 downto 0) := (others => '0');
signal num_pak : unsigned(3 downto 0) := (others => '0');
signal resub_mode : std_logic := '0';
signal reset_retrans : std_logic;
-signal reset_retrans_200 : std_logic;
-signal enable_chksum_200 : std_logic_vector(5 downto 0);
+signal reset_retrans_200, reset_retrans_200_i : std_logic;
+signal enable_chksum_200, enable_chksum_200_i : 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';
+signal force_crc_error_200, force_crc_error_200_i : std_logic := '0';
+signal is_idle_100, is_idle_100_i, is_idle : std_logic := '0';
+signal fatal_counter : unsigned(3 downto 0) := (others => '0');
+signal fatal_error : std_logic := '0';
signal CRC_ERROR_DELAY_cnt : std_logic_vector(3 downto 0) := (others => '0');
-signal CRC_ERROR_DELAY_200 : std_logic_vector(3 downto 0) := (others => '0');
+signal CRC_ERROR_DELAY_200, CRC_ERROR_DELAY_200_i : std_logic_vector(3 downto 0) := (others => '0');
begin
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;
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);
-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);
+-- 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);
-GOT_CHKSUM <= use_crc;
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_sys = '1' then
- --if ct_fifo_empty = '1' and load_use_crc_sys = '1' then
+ 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_sys = '0') then
+ 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';
+ 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';
num_read_words <= "000";
latched_pulse_good_100 <= "00";
latched_pulse_bad_100 <= "00";
- use_crc <= '0';
+ 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