From ec123fd09ab4a57040c5921437dc3ca5e2d02c18 Mon Sep 17 00:00:00 2001 From: Ingo Froehlich Date: Wed, 30 Jan 2019 14:12:20 +0100 Subject: [PATCH] improved setup and reset procedure to avoid deadlocks --- media_interfaces/sync/med_sync_control.vhd | 22 +++++++-- media_interfaces/sync/med_sync_define.vhd | 2 + media_interfaces/sync/rx_control.vhd | 52 ++++++++++++++++------ 3 files changed, 58 insertions(+), 18 deletions(-) diff --git a/media_interfaces/sync/med_sync_control.vhd b/media_interfaces/sync/med_sync_control.vhd index 7fa35ea..aea5657 100644 --- a/media_interfaces/sync/med_sync_control.vhd +++ b/media_interfaces/sync/med_sync_control.vhd @@ -121,7 +121,8 @@ signal tx_got_force_error : std_logic := '0'; signal tx_got_force_error_100 : std_logic := '0'; signal tx_force_crc_error : std_logic := '0'; signal tx_force_pak_error : std_logic := '0'; - +signal send_chksum : std_logic := '0'; +signal got_chksum : std_logic; begin @@ -314,15 +315,24 @@ THE_TX : tx_control RX_ALLOW_IN => rx_allow, --ENABLE_SEND_CHKSUM => '1', --SIM - ENABLE_SEND_CHKSUM => MEDIA_INT2MED.ctrl_op(8), - --RESET_RETRANSMIT_IN => send_link_reset_i, - RESET_RETRANSMIT_IN => '0', + --ENABLE_SEND_CHKSUM => MEDIA_INT2MED.ctrl_op(8), + ENABLE_SEND_CHKSUM => send_chksum, + RESET_RETRANSMIT_IN => send_link_reset_i, + --RESET_RETRANSMIT_IN => '0', DEBUG_OUT => DEBUG_TX_CONTROL_i, STAT_REG_OUT => STAT_TX_CONTROL_i ); +chksum_send_logic1 : if IS_SYNC_SLAVE = c_NO generate + send_chksum <= MEDIA_INT2MED.ctrl_op(8); +end generate; +chksum_send_logic2 : if IS_SYNC_SLAVE = c_YES generate + send_chksum <= MEDIA_INT2MED.ctrl_op(8) and got_chksum; +end generate; + + ------------------------------------------------- -- RX Data ------------------------------------------------- @@ -350,6 +360,8 @@ THE_RX_CONTROL : rx_control CRC_ERROR_DELAY => crc_error_delay, RESET_RETRANSMIT_IN => MEDIA_INT2MED.ctrl_op(15), --RESET_RETRANSMIT_IN => '0', + ENABLE_CHKSUM => MEDIA_INT2MED.ctrl_op(8), + GOT_CHKSUM => got_chksum, --send_dlm: 200 MHz, 1 clock strobe, data valid until next DLM RX_DLM => rx_dlm_i, @@ -368,6 +380,8 @@ THE_RX_CONTROL : rx_control RX_DLM <= rx_dlm_i; MEDIA_MED2INT <= media_med2int_i; + + ------------------------------------------------- -- Generate LED signals ------------------------------------------------- diff --git a/media_interfaces/sync/med_sync_define.vhd b/media_interfaces/sync/med_sync_define.vhd index e832191..6c95195 100644 --- a/media_interfaces/sync/med_sync_define.vhd +++ b/media_interfaces/sync/med_sync_define.vhd @@ -39,6 +39,8 @@ component rx_control is FORCE_CRC_ERROR : in std_logic := '0'; CRC_ERROR_DELAY : in std_logic_vector(3 downto 0); RESET_RETRANSMIT_IN : in std_logic; + ENABLE_CHKSUM : in std_logic; + GOT_CHKSUM : out std_logic; --send_dlm: 200 MHz, 1 clock strobe, data valid until next DLM RX_DLM : out std_logic := '0'; diff --git a/media_interfaces/sync/rx_control.vhd b/media_interfaces/sync/rx_control.vhd index eaa38bd..4d1ce33 100644 --- a/media_interfaces/sync/rx_control.vhd +++ b/media_interfaces/sync/rx_control.vhd @@ -31,6 +31,8 @@ entity rx_control is 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; + GOT_CHKSUM : out std_logic; --send_dlm: 200 MHz, 1 clock strobe, data valid until next DLM RX_DLM : out std_logic := '0'; @@ -70,6 +72,7 @@ signal ct_fifo_full : std_logic; signal ct_fifo_afull : std_logic; signal last_ct_fifo_empty : std_logic; signal last_ct_fifo_read : std_logic; +signal last_ct_fifo_write : std_logic; signal idle_hist_i : std_logic_vector(3 downto 0) := x"0"; signal got_link_ready_i : std_logic := '0'; @@ -105,6 +108,7 @@ signal latched_pulse_bad_100 : unsigned(1 downto 0) := "00"; 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 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'); @@ -120,8 +124,10 @@ 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 enable_chksum_sys : std_logic; 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 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'); @@ -145,19 +151,23 @@ 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); +enable_chksum_sys <= 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); +GOT_CHKSUM <= use_crc; process begin wait until rising_edge(CLK_100); --switch only when fifo is empty: - 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_sys = '1' then -- and enable_chksum_sys = '1' then + --if ct_fifo_empty = '1' and load_use_crc_sys = '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_sys = '0') then -- or enable_chksum_sys = '0' then use_crc <= '0'; end if; @@ -299,8 +309,7 @@ PROC_RX_FSM : process begin crc_reset <= '0'; pulse_good <= '0'; pulse_bad <= '0'; - - + case rx_state is when SLEEP => rx_state_bits <= x"1"; @@ -318,12 +327,14 @@ PROC_RX_FSM : process begin rx_state_bits <= x"2"; req_retr_i <= '0'; rx_data(7 downto 0) <= reg_rx_data_in; + is_idle <= '0'; if reg_rx_k_in = '1' then case reg_rx_data_in is when K_IDLE => rx_state <= GET_IDLE; crc_reset <= '1'; resub_mode <= '0'; + is_idle <= '1'; when K_RST => rx_state <= MAKE_RESET; reset_cnt <= x"000"; @@ -361,12 +372,14 @@ PROC_RX_FSM : process begin force_crc_error_int <= '1'; end if; end if; - if use_crc_200 = '1' and num_pakets /= 0 and force_crc_error_int = '0' then - -- IDLE only allowed after CRC + if use_crc_200 = '1' and num_pakets /= 0 and force_crc_error_int = '0' and enable_chksum_sys = '1' then + -- IDLE only allowed after CRC, must be disabled until explicitly + -- switched on rx_state <= FIRST; --reg_num_pakets <= num_pakets; --debug force_crc_error_int <= '1'; end if; + when GET_DATA => num_pakets <= num_pakets+1; @@ -407,6 +420,7 @@ PROC_RX_FSM : process begin --num_pak <= num_pak+1; --end if; req_retr_i <= '1'; + retrans_timeout <= x"00"; waiting_for_retr <= '1'; end if; force_crc_error_int <= '0'; @@ -481,6 +495,14 @@ PROC_RX_FSM : process begin end if; end case; + + if waiting_for_retr = '1' and not (rx_state = FIRST) then + retrans_timeout <= retrans_timeout+1; + if retrans_timeout = x"ff" then + req_retr_i <= '1'; + end if; + end if; + if RESET_IN = '1' or RX_RESET_FINISHED = '0' then rx_state <= SLEEP; @@ -492,13 +514,13 @@ PROC_RX_FSM : process begin send_link_reset_i <= '0'; end if; --- if reset_retrans = '1' then --- load_use_crc <= '0'; --- crc_reset <= '1'; --- waiting_for_retr <= '0'; --- num_pakets <= (others => '0'); --- resub_mode <= '0'; --- end if; + if reset_retrans = '1' then + load_use_crc <= '0'; + crc_reset <= '1'; + waiting_for_retr <= '0'; + num_pakets <= (others => '0'); + resub_mode <= '0'; + end if; end process; @@ -574,8 +596,10 @@ STAT_REG_OUT(7) <= ct_fifo_write; STAT_REG_OUT(15 downto 8) <= reg_rx_data_in when rising_edge(clk_100); --rx_data(7 downto 0); STAT_REG_OUT(16) <= rx_data(16); STAT_REG_OUT(17) <= use_crc; +STAT_REG_OUT(18) <= reset_retrans; +STAT_REG_OUT(19) <= load_use_crc; --STAT_REG_OUT(31 downto 18) <= (others => '0'); -STAT_REG_OUT(23 downto 18) <= (others => '0'); +STAT_REG_OUT(23 downto 20) <= (others => '0'); STAT_REG_OUT(31 downto 24) <= good_pos_counter; -- 2.43.0