attribute nopad : string;
attribute nopad of hdinp, hdinn, hdoutp, hdoutn : signal is "true";
- signal stat_med : std_logic_vector(31 downto 0);
+ 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;
DEBUG_OUT => open
);
- -- STAT_DEBUG(4 downto 0) <= debug_rx_control_i(4 downto 0);
- -- STAT_DEBUG(6 downto 5) <= stat_fsm_reset_i(9 downto 8);
- -- STAT_DEBUG(7) <= '0';
- -- STAT_DEBUG(15 downto 8) <= stat_fsm_reset_i(7 downto 0);
- -- STAT_DEBUG(15 downto 0) <= debug_tx_control_i(31 downto 16);
- -- STAT_DEBUG(31 downto 0) <= debug_rx_control_i(31 downto 0);
- STAT_DEBUG(3 downto 0) <= debug_med_sync_control_i(3 downto 0);
- STAT_DEBUG(7 downto 4) <= rx_los_low & lsm_status & rx_cdr_lol & tx_pll_lol;
- -- STAT_DEBUG(9) <= CLK_REF_FULL;
- -- STAT_DEBUG(10) <= clk_rx_full;
- -- STAT_DEBUG(11) <= clk_tx_full;
++
+BUS_WRITER : process
+ begin
+ wait until rising_edge(SYSCLK);
+ loc_BUS_TX.unknown <= '0';
+ loc_BUS_TX.rack <= '0';
+ loc_BUS_TX.wack <= '0';
+ loc_BUS_TX.data <= x"00000000";
+ loc_BUS_TX.ack <= '0';
+
+ mii_rx_i.data <= loc_BUS_RX.data;
+ mii_rx_i.addr <= loc_BUS_RX.addr;
+ mii_rx_i.read <= '0';
+ mii_rx_i.write <= '0';
+
+ if loc_BUS_RX.addr(2) = '0' then
+ if loc_BUS_RX.read = '1' then
+ loc_BUS_TX.ack <= '1';
+ loc_BUS_TX.unknown <= '1';
+-- case loc_BUS_RX.addr(4 downto 0) is
+-- when "00000" => loc_BUS_TX.data <= stat_rx_control_i(31 downto 0);
+-- when "00001" => loc_BUS_TX.data <= stat_tx_control_i(31 downto 0);
+-- when "00010" => loc_BUS_TX.data <= stat_fsm_reset_i(31 downto 0);
+-- end case;
+ end if;
+ else
+ if mii_tx_i.ack = '1' then
+ loc_BUS_TX.data <= mii_tx_i.data;
+ loc_BUS_TX.ack <= '1';
+ loc_BUS_TX.unknown <= mii_tx_i.unknown;
+ end if;
+ mii_rx_i.read <= loc_BUS_RX.read;
+ mii_rx_i.write <= loc_BUS_RX.write;
+ end if;
+end process;
+
+
+ STAT_DEBUG(11 downto 0) <= debug_med_sync_control_i(11 downto 0);
+ STAT_DEBUG(15 downto 12) <= (others => '0');
+ STAT_DEBUG(31 downto 16) <= wa_position;
+ STAT_DEBUG(63 downto 32) <= (others => '0');
+
stat_med(0) <= rst_qd;
stat_med(1) <= rx_pcs_rst;
stat_med(2) <= tx_pcs_rst;
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;
- CLK_RXI : in std_logic;
+ CLK_SYS : in std_logic; -- 100MHz system clock
+ CLK_RXI : in std_logic; -- recovered RX clock, 200MHz
CLK_RXHALF : in std_logic;
- CLK_TXI : in std_logic;
+ CLK_TXI : in std_logic; -- TX clock, 200MHz
CLK_REF : in std_logic;
RESET : in std_logic;
CLEAR : in std_logic;
signal send_link_reset_real_i : std_logic := '0';
signal send_link_reset_sys_i : std_logic := '0';
- signal reset_i, rst_n, rst_n_tx : std_logic;
+ signal reset_i : std_logic;
+ signal rst_n : std_logic;
+ signal rst_n_tx : std_logic;
+ signal finished_reset_rx : std_logic;
+ signal finished_reset_rx_q : std_logic;
+ signal finished_reset_tx : std_logic;
+ signal finished_reset_tx_q : std_logic;
+
signal media_med2int_i : MED2INT;
- signal finished_reset_rx, finished_reset_rx_q : std_logic;
- signal finished_reset_tx, finished_reset_tx_q : std_logic;
+
+ signal rx_serdes_rst_i : std_logic;
+ signal rx_pcs_rst_i : std_logic;
+
+ signal rx_serdes_rst_i_q : std_logic_vector(2 downto 0);
+ signal rx_pcs_rst_i_q : std_logic_vector(2 downto 0);
+
+ signal tx_pcs_rst_i : std_logic;
+ signal quad_rst_i : std_logic;
+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 := '0';
+signal crc_error_delay : std_logic_vector(3 downto 0) := "0000";
+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;
+signal got_fatal_error : std_logic;
+signal enable_chksum_reg : std_logic_vector(5 downto 0) := "111111";
+signal enable_chksum_comb : std_logic_vector(5 downto 0);
+
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;
+
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);
+
+tx_got_force_error_100 <= tx_got_force_error when rising_edge(CLK_SYS);
+
++
media_med2int_i.clk_half <= CLK_RXHALF;
media_med2int_i.clk_full <= CLK_RXI;
D_IN(0) => finished_reset_rx,
D_OUT(0) => finished_reset_rx_q);
-
- PROC_START_TIMER : process begin
- wait until rising_edge(CLK_SYS);
- -- if got_link_ready_i = '1' then
- if finished_reset_tx_q = '1' and finished_reset_rx_q = '1' then
- if start_timer(start_timer'left) = '0' then
- start_timer <= start_timer + 1;
- end if;
- else
- start_timer <= (others => '0');
+ START_TIMER_PROC : process( CLK_SYS )
+ begin
+ if( rising_edge(CLK_SYS) ) then
+ if( (finished_reset_tx_q = '1') and (finished_reset_rx_q = '1') ) then
+ if start_timer(start_timer'left) = '0' then
+ start_timer <= start_timer + 1;
+ end if;
+ else
+ start_timer <= (others => '0');
+ end if;
end if;
- end process;
+ end process START_TIMER_PROC;
-
+
+--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" =>
+ 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
-------------------------------------------------
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_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);
++
+ DEBUG_OUT(0) <= TX_LOL;
+ DEBUG_OUT(1) <= RX_CDR_LOL;
+ DEBUG_OUT(2) <= RX_LOS;
+ DEBUG_OUT(3) <= rst_n;
+ DEBUG_OUT(4) <= rst_n_tx;
+ DEBUG_OUT(5) <= quad_rst_i;
+ DEBUG_OUT(6) <= rx_pcs_rst_i;
+ DEBUG_OUT(7) <= tx_pcs_rst_i;
+ DEBUG_OUT(8) <= rx_serdes_rst_i;
+ DEBUG_OUT(9) <= finished_reset_rx;
+ DEBUG_OUT(10) <= finished_reset_tx;
+ DEBUG_OUT(11) <= reset_i;
+ DEBUG_OUT(31 downto 12) <= (others => '0');
+
+
end architecture;
architecture rx_reset_fsm_arch of rx_reset_fsm is
-constant count_index : integer := 19;
+constant count_index : integer := 19; --REAL
+--constant count_index : integer := 9; --SIM
- type statetype is (WAIT_FOR_PLOL, RX_SERDES_RESET, WAIT_FOR_timer1, CHECK_LOL_LOS, WAIT_FOR_timer2, NORMAL);
++
+ type statetype is ( WAIT_FOR_PLOL, RX_SERDES_RESET, WAIT_FOR_TIMER1, CHECK_LOL_LOS, WAIT_FOR_TIMER2, NORMAL );
++
- signal cs: statetype; -- current state of lsm
- signal ns: statetype; -- next state of lsm
+ signal cs : statetype; -- current state of lsm
+ signal ns : statetype; -- next state of lsm
- signal tx_pll_lol_qd_q: std_logic;
- signal rx_cdr_lol_ch_q: std_logic;
- signal rx_los_low_ch_q: std_logic;
- signal rx_lol_los : std_logic;
- signal rx_lol_los_int: std_logic;
- signal rx_lol_los_del: std_logic;
- signal rx_pcs_rst_ch_c_int: std_logic;
- signal rx_serdes_rst_ch_c_int: std_logic;
+ signal tx_pll_lol_qd_q : std_logic;
+ signal rx_cdr_lol_ch_q : std_logic;
+ signal rx_los_low_ch_q : std_logic;
+ signal rx_lol_los : std_logic;
+ signal rx_lol_los_int : std_logic;
+ signal rx_lol_los_del : std_logic;
+ signal rx_pcs_rst_ch_c_int : std_logic;
+ signal rx_serdes_rst_ch_c_int : std_logic;
- signal reset_timer1: std_logic;
- signal reset_timer2: std_logic;
+ signal reset_timer1 : std_logic;
+ signal reset_timer2 : std_logic;
- signal counter1: unsigned(1 downto 0);
- signal timer1: std_logic;
+ signal counter1 : unsigned(1 downto 0);
+ signal timer1 : std_logic;
- signal counter2: unsigned(19 downto 0);
- signal timer2 : std_logic;
+ signal counter2 : unsigned(19 downto 0);
+ signal timer2 : std_logic;
begin
architecture tx_reset_fsm_arch of tx_reset_fsm is
-constant count_index : integer := 19; -- end of timer2
++
+constant count_index : integer := 19; --REAL
+--constant count_index : integer := 9; --SIM
- type statetype is (QUAD_RESET, WAIT_FOR_TIMER1, CHECK_PLOL, WAIT_FOR_TIMER2, NORMAL);
-
- signal cs: statetype; -- current state of lsm
- signal ns: statetype; -- next state of lsm
+
+ type statetype is ( QUAD_RESET, WAIT_FOR_TIMER1, CHECK_PLOL, WAIT_FOR_TIMER2, NORMAL );
+
+ signal cs : statetype; -- current state of lsm
+ signal ns : statetype; -- next state of lsm
++
- signal tx_pll_lol_qd_s_int : std_logic;
- signal tx_pcs_rst_ch_c_int : std_logic;
- signal RST_QD_C_int : std_logic;
+ signal tx_pll_lol_qd_s_int : std_logic;
+ signal tx_pcs_rst_ch_c_int : std_logic;
+ signal rst_qd_c_int : std_logic;
- signal reset_timer1: std_logic;
- signal reset_timer2: std_logic;
+ signal reset_timer1 : std_logic;
+ signal reset_timer2 : std_logic;
- signal counter1: unsigned(2 downto 0);
- signal TIMER1: std_logic;
+ signal counter1 : unsigned(2 downto 0);
+ signal timer1 : std_logic;
- signal counter2: unsigned(19 downto 0);
- signal TIMER2: std_logic;
+ signal counter2 : unsigned(19 downto 0);
+ signal timer2 : std_logic;
begin