attribute nopad : string;
attribute nopad of hdinp, hdinn, hdoutp, hdoutn : signal is "true";
+signal mii_tx_i : CTRLBUS_TX_array_t(0 to 3);
+signal mii_rx_i : CTRLBUS_RX_array_t(0 to 3);
+
+ type u8_arr is array (0 to 3) of unsigned(7 downto 0);
+ signal cv_cnt, cv_cnt_sys : u8_arr;
+
begin
- -- SD_TXDIS_OUT <= (others =>'0'); --not (rx_allow_q or not IS_SLAVE); --slave only switches on when RX is ready
- SD_TXDIS_OUT <= (others => RESET);
+ SD_TXDIS_OUT <= (others =>'0'); --not (rx_allow_q or not IS_SLAVE); --slave only switches on when RX is ready
+ -- SD_TXDIS_OUT <= (others => RESET);
-------------------------------------------------
-- Serdes
-------------------------------------------------
STAT_RX_CONTROL => stat_rx_control_i(i*32+31 downto i*32),
DEBUG_TX_CONTROL => debug_tx_control_i(i*32+31 downto i*32),
DEBUG_RX_CONTROL => debug_rx_control_i(i*32+31 downto i*32),
- STAT_RESET => stat_fsm_reset_i(i*32+31 downto i*32)
+ STAT_RESET => stat_fsm_reset_i(i*32+31 downto i*32),
+
+ DEBUG_RETRANS_OUT => debug_retrans_i(i*32+31 downto i*32),
+
+ BUS_RX => mii_rx_i(i),
+ BUS_TX => mii_tx_i(i)
);
+
+ cv_cnt(i) <= cv_cnt(i) + 1 when rx_error(i) = '1' and rising_edge(clk_rx_full(i));
end generate;
gen_not_used : if IS_USED(i) = c_NO generate
MEDIA_MED2INT(i).dataready <= '0';
MEDIA_MED2INT(i).tx_read <= '1';
MEDIA_MED2INT(i).stat_op <= x"0007";
+ mii_tx_i(i).data <= x"00000000";
+ mii_tx_i(i).ack <= '0';
end generate;
+
end generate;
THE_SCI_READER : entity work.sci_reader
MEDIA_STATUS_REG_IN(31 downto 0) => stat_rx_control_i(31 downto 0),
MEDIA_STATUS_REG_IN(63 downto 32) => stat_tx_control_i(31 downto 0),
- MEDIA_STATUS_REG_IN(95 downto 64) => stat_fsm_reset_i(31 downto 0),
- MEDIA_STATUS_REG_IN(255 downto 96) => (others => '0'),
++
+ MEDIA_STATUS_REG_IN(191 downto 64) => stat_fsm_reset_i(127 downto 0),
+ MEDIA_STATUS_REG_IN(199 downto 192) => cv_cnt_sys(0),
+ MEDIA_STATUS_REG_IN(207 downto 200) => cv_cnt_sys(1),
+ MEDIA_STATUS_REG_IN(215 downto 208) => cv_cnt_sys(2),
+ MEDIA_STATUS_REG_IN(223 downto 216) => cv_cnt_sys(3),
+
+ MEDIA_STATUS_REG_IN(255 downto 224) => (others => '0'),
++
+ --MEDIA_STATUS_REG_IN(383 downto 256) => debug_retrans_i,
+ --MEDIA_STATUS_REG_IN(511 downto 384) => (others => '0'),
++
++
DEBUG_OUT => open
);
MEDIA_STATUS_REG_IN(63 downto 32) => stat_tx_control_i(31 downto 0),
MEDIA_STATUS_REG_IN(95 downto 64) => stat_fsm_reset_i(31 downto 0),
MEDIA_STATUS_REG_IN(255 downto 96) => (others => '0'),
++
+ --MEDIA_STATUS_REG_IN(383 downto 256) => debug_retrans_i,
+ --MEDIA_STATUS_REG_IN(511 downto 384) => (others => '0'),
++
DEBUG_OUT => open
);
signal finished_reset_rx, finished_reset_rx_q : std_logic;
signal finished_reset_tx, finished_reset_tx_q : std_logic;
-begin
+signal STAT_TX_CONTROL_i : std_logic_vector(31 downto 0);
+signal STAT_RX_CONTROL_i : std_logic_vector(31 downto 0);
+signal DEBUG_TX_CONTROL_i : std_logic_vector(31 downto 0);
+signal DEBUG_RX_CONTROL_i : std_logic_vector(31 downto 0);
+signal STAT_RESET_i : std_logic_vector(31 downto 0);
+signal DEBUG_OUT_i : std_logic_vector(31 downto 0);
+
+signal last_FORCE_CRC_ERROR_IN : std_logic;
+signal crc_error_delay : std_logic_vector(3 downto 0) := "0000";
-rst_n_tx <= not (CLEAR or sd_los_i or make_link_reset_real_i or RESET) when (IS_SYNC_SLAVE = 1 and IS_TX_RESET = 1)
- else not (CLEAR or make_link_reset_real_i or RESET);
+begin
+STAT_TX_CONTROL <= STAT_TX_CONTROL_i;
+STAT_RX_CONTROL <= STAT_RX_CONTROL_i;
+DEBUG_TX_CONTROL <= DEBUG_TX_CONTROL_i;
+DEBUG_RX_CONTROL <= DEBUG_RX_CONTROL_i;
+STAT_RESET <= STAT_RESET_i;
+DEBUG_OUT <= DEBUG_OUT_i;
- last_FORCE_CRC_ERROR_IN <= FORCE_CRC_ERROR_IN when rising_edge(CLK_SYS);
- DEBUG_RETRANS_OUT <= start_retr_counter & request_retr_counter when rising_edge(CLK_SYS);
-
- rst_n_tx <= not (CLEAR or sd_los_i or make_link_reset_real_i) when (IS_SYNC_SLAVE = 1 and IS_TX_RESET = 1)
- else not (CLEAR or make_link_reset_real_i);
-
- rst_n <= not (CLEAR or sd_los_i or make_link_reset_real_i);
++rst_n_tx <= not (CLEAR or sd_los_i or make_link_reset_real_i or RESET) when (IS_SYNC_SLAVE = 1 and IS_TX_RESET = 1)
++ else not (CLEAR or make_link_reset_real_i or RESET);
+ rst_n <= not (CLEAR or sd_los_i or make_link_reset_real_i or RESET);
reset_i <= (RESET or sd_los_i or make_link_reset_real_i);
++last_FORCE_CRC_ERROR_IN <= FORCE_CRC_ERROR_IN when rising_edge(CLK_SYS);
++DEBUG_RETRANS_OUT <= start_retr_counter & request_retr_counter when rising_edge(CLK_SYS);
media_med2int_i.clk_half <= CLK_RXHALF;
media_med2int_i.clk_full <= CLK_RXI;
-- Status signals
-------------------------------------------------
- STAT_RESET_i(3 downto 0) <= rx_fsm_state;
- STAT_RESET_i(7 downto 4) <= tx_fsm_state;
- STAT_RESET_i(8) <= tx_allow;
- STAT_RESET_i(9) <= rx_allow;
- STAT_RESET_i(15 downto 10) <= (others => '0');
- STAT_RESET_i(16) <= RX_CDR_LOL;
- STAT_RESET_i(17) <= RX_LOS;
- STAT_RESET_i(18) <= '0'; --RX_PCS_RST;
- STAT_RESET_i(19) <= '0';
- STAT_RESET_i(31 downto 20) <= std_logic_vector(start_timer(start_timer'left downto start_timer'left - 11));
++
+ STAT_RESET(3 downto 0) <= rx_fsm_state;
+ STAT_RESET(7 downto 4) <= tx_fsm_state;
+ STAT_RESET(8) <= tx_allow;
+ STAT_RESET(9) <= rx_allow;
+ STAT_RESET(15 downto 10) <= (others => '0');
+ STAT_RESET(16) <= RX_CDR_LOL;
+ STAT_RESET(17) <= RX_LOS;
+ STAT_RESET(18) <= '0';--QUAD_RST; --RX_PCS_RST;
+ STAT_RESET(19) <= '0';--TX_PCS_RST;
+ STAT_RESET(20) <= TX_LOL;
+ STAT_RESET(21) <= rst_n;
+ STAT_RESET(22) <= rst_n_tx;
+ STAT_RESET(30 downto 23) <= (others => '0');
+ STAT_RESET(31) <= start_timer(start_timer'left);
+
+
gen_link_reset : if IS_SYNC_SLAVE = 1 generate
- link_reset_pulse : signal_sync port map(RESET => '0',CLK0 => CLK_RXI,CLK1 => CLK_SYS,
- D_IN(0) => make_link_reset_i,
- D_OUT(0) => make_link_reset_sys_i);
+ link_reset_pulse : pulse_sync port map( CLK_A_IN => CLK_RXI, CLK_B_IN => CLK_SYS,
+ PULSE_A_IN => make_link_reset_i,
+ PULSE_B_OUT => make_link_reset_sys_i);
link_reset_send : signal_sync port map(RESET => '0',CLK0 => CLK_RXI,CLK1 => CLK_SYS,
D_IN(0) => send_link_reset_i,
- D_OUT(0) => send_link_reset_real_i);
+ D_OUT(0) => send_link_reset_sys_i);
end generate;
- make_link_reset_real_i <= make_link_reset_sys_i when IS_SYNC_SLAVE = 0 else
- make_link_reset_sys_i or sd_los_i when IS_SYNC_SLAVE = 1;
+ make_link_reset_real_i <= make_link_reset_sys_i or sd_los_i when IS_SYNC_SLAVE = 1
+ else '0';
+ send_link_reset_real_i <= send_link_reset_sys_i when IS_SYNC_SLAVE = 1
+ else '0';
sd_los_i <= SFP_LOS when rising_edge(CLK_SYS);
media_med2int_i.stat_op(11) <= led_tx; -- or last_led_tx;
media_med2int_i.stat_op(10) <= led_rx or last_led_rx;
media_med2int_i.stat_op(9) <= tx_allow; --led_ok
- media_med2int_i.stat_op(8) <= rx_allow;
-
- media_med2int_i.stat_op(7 downto 4) <= (others => '0');
+ media_med2int_i.stat_op(8 downto 5) <= (others => '0');
+ media_med2int_i.stat_op(4) <= rx_allow;
media_med2int_i.stat_op(3 downto 0) <= x"0" when rx_allow = '1' and tx_allow = '1' else x"7";
-DEBUG_OUT(0) <= tx_allow;
-DEBUG_OUT(1) <= rx_allow;
-DEBUG_OUT(2) <= sd_los_i;
-DEBUG_OUT(3) <= '0'; --DEBUG_RX_CONTROL(4);
+DEBUG_OUT_i(0) <= tx_allow;
+DEBUG_OUT_i(1) <= rx_allow;
+DEBUG_OUT_i(2) <= sd_los_i;
+DEBUG_OUT_i(3) <= '0'; --DEBUG_RX_CONTROL(4);
end architecture;
signal reg_rx_data_in : std_logic_vector(7 downto 0);
signal reg_rx_k_in : std_logic;
- signal reset_cnt : unsigned(7 downto 0);
+ signal reset_cnt : unsigned(11 downto 0);
+signal crc_reset : std_logic;
+signal crc_q : std_logic_vector(7 downto 0);
+signal crc_en : std_logic;
+signal crc_data : std_logic_vector(7 downto 0);
+signal pulse_good : std_logic;
+signal pulse_bad : std_logic;
+signal got_pulse_good : std_logic := '0';
+signal got_pulse_bad : std_logic := '0';
+signal pulse_good_100 : std_logic;
+signal pulse_bad_100 : std_logic;
+signal waiting_for_retr : std_logic := '0';
+signal good_pos_counter : std_logic_vector(7 downto 0) := (others => '0');
+signal num_pakets : unsigned(3 downto 0) := (others => '0');
+
+signal use_crc : std_logic := '0';
+signal last_use_crc : std_logic := '0';
+signal load_use_crc : 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 last_good_pos_counter : std_logic_vector(7 downto 0) := (others => '0');
+--signal last_send_link_reset_i : std_logic;
+signal reset_retrans : std_logic;
+
+--signal num_count : unsigned(7 downto 0) := (others => '0');
+--signal max_count : unsigned(7 downto 0) := (others => '0');
+--signal bad_crc : std_logic_vector(7 downto 0);
+--signal good_crc : std_logic_vector(7 downto 0);
+--signal store_crc : std_logic := '0';
+signal CRC_ERROR_DELAY_cnt : std_logic_vector(3 downto 0) := (others => '0');
+
+
+
begin
----------------------------------------------------------------------
case reg_rx_data_in is
when K_IDLE =>
rx_state <= GET_IDLE;
+ crc_reset <= '1';
+ resub_mode <= '0';
when K_RST =>
rx_state <= MAKE_RESET;
- reset_cnt <= x"00";
+ reset_cnt <= x"000";
when K_DLM =>
rx_state <= GET_DLM;
when K_REQ =>
rx_data(16) <= next_sop;
rx_data(17) <= '0';
ct_fifo_write <= '1';
+ num_pakets <= num_pakets+1;
rx_state <= FIRST;
else
- rx_state <= SLEEP;
+ rx_state <= FIRST; -- SLEEP;
++
+ end if;
+
+ when GET_CRC =>
+ if (use_crc = '0') then
+ -- first time
+ load_use_crc <= '1';
+ disable_crc <= '0';
+ else
+ if (crc_q /= reg_rx_data_in or waiting_for_retr = '1' or --- or num_pakets /= 5)
+ (force_crc_error = '1' and CRC_ERROR_DELAY_cnt = "0000") ) and disable_crc = '0' then
+ -- bad
+ pulse_bad <= '1';
+ if waiting_for_retr = '0' then
+ if crc_q /= reg_rx_data_in then
+ num_crc <= num_crc+1;
+ else
+ num_pak <= num_pak+1;
+ end if;
+ req_retr_i <= '1';
+ waiting_for_retr <= '1';
+ end if;
+ else
+ -- good
+ pulse_good <= '1';
+ if force_crc_error = '0' then
+ CRC_ERROR_DELAY_cnt <= CRC_ERROR_DELAY;
+ disable_crc <= '0';
+ end if;
+ end if;
+ end if;
+ crc_reset <= '1';
+ rx_state <= FIRST;
+ num_pakets <= (others => '0');
+ if force_crc_error = '1' then
+ CRC_ERROR_DELAY_cnt <= std_logic_vector(unsigned(CRC_ERROR_DELAY_cnt) - 1);
+ end if;
+
+ when GET_RETR =>
+ if force_crc_error = '1' then
+ disable_crc <= '1';
end if;
-
+ rx_state <= FIRST;
+ waiting_for_retr <= '0';
+ crc_reset <= '1';
+ num_pakets <= (others => '0');
+ resub_mode <= '1';
+
when GET_DLM =>
rx_state_bits <= x"5";
rx_dlm_i <= '1';
if RESET_IN = '1' or RX_RESET_FINISHED = '0' then
rx_state <= SLEEP;
- make_reset_i <= '0';
+ if rx_state = MAKE_RESET then
+ make_reset_i <= '1';
+ else
+ make_reset_i <= '0';
+ end if;
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;
+
end process;
reg_rx_data_in <= RX_DATA_IN when rising_edge(CLK_200);
BUS_RX : in CTRLBUS_RX;
BUS_TX : out CTRLBUS_TX;
- MEDIA_STATUS_REG_IN : in std_logic_vector(511 downto 0);
- MEDIA_STATUS_REG_IN : in std_logic_vector(255 downto 0) := (others => '0');
++ MEDIA_STATUS_REG_IN : in std_logic_vector(511 downto 0) := (others => '0');
++
DEBUG_OUT : out std_logic_vector(31 downto 0)
);
end entity;