From 5d84584b7fcf03c7cdb39e0924027b754b5e7c75 Mon Sep 17 00:00:00 2001 From: hadeshyp Date: Fri, 17 Apr 2009 13:36:30 +0000 Subject: [PATCH] *** empty log message *** --- media_interfaces/trb_net16_lsm_sfp.vhd | 2 +- media_interfaces/trb_net16_med_ecp_fot.vhd | 523 +++++++++++ media_interfaces/trb_net16_med_ecp_fot_4.vhd | 14 +- media_interfaces/trb_net16_med_ecp_sfp_4.vhd | 878 +++++++++++++++++++ 4 files changed, 1408 insertions(+), 9 deletions(-) create mode 100644 media_interfaces/trb_net16_med_ecp_fot.vhd create mode 100644 media_interfaces/trb_net16_med_ecp_sfp_4.vhd diff --git a/media_interfaces/trb_net16_lsm_sfp.vhd b/media_interfaces/trb_net16_lsm_sfp.vhd index d3debd7..ecf6ea8 100644 --- a/media_interfaces/trb_net16_lsm_sfp.vhd +++ b/media_interfaces/trb_net16_lsm_sfp.vhd @@ -207,7 +207,7 @@ begin NEXT_STATE <= SLEEP; -- SFP has been removed next_lane_rst <= '1'; next_ce_tctr <= '1'; - elsif( (sd_rxclk_bad_in = '0') and (sd_txclk_bad_in = '0') ) then + elsif( (sd_rxclk_bad_in = '0') and (sd_txclk_bad_in = '0') ) then -- NEXT_STATE <= WLOS; -- PLLs locked, signal present next_rst_tctr <= '1'; else diff --git a/media_interfaces/trb_net16_med_ecp_fot.vhd b/media_interfaces/trb_net16_med_ecp_fot.vhd new file mode 100644 index 0000000..10f6c7f --- /dev/null +++ b/media_interfaces/trb_net16_med_ecp_fot.vhd @@ -0,0 +1,523 @@ +LIBRARY ieee; +use ieee.std_logic_1164.all; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; + +entity trb_net16_med_ecp_fot is + port( + CLK : in std_logic; + CLK_25 : in std_logic; + CLK_EN : in std_logic; + RESET : in std_logic; + + --Internal Connection + MED_DATA_IN : in std_logic_vector(c_DATA_WIDTH-1 downto 0); + MED_PACKET_NUM_IN : in std_logic_vector(c_NUM_WIDTH-1 downto 0); + MED_DATAREADY_IN : in std_logic; + MED_READ_OUT : out std_logic; + MED_DATA_OUT : out std_logic_vector(c_DATA_WIDTH-1 downto 0); + MED_PACKET_NUM_OUT : out std_logic_vector(c_NUM_WIDTH-1 downto 0); + MED_DATAREADY_OUT : out std_logic; + MED_READ_IN : in std_logic; + + --SFP Connection + TXP : out std_logic; + TXN : out std_logic; + RXP : in std_logic; + RXN : in std_logic; + SD : in std_logic; + + -- Status and control port + STAT_OP : out std_logic_vector (15 downto 0); + CTRL_OP : in std_logic_vector (15 downto 0); + STAT_DEBUG : out std_logic_vector (63 downto 0); + CTRL_DEBUG : in std_logic_vector (15 downto 0) + ); +end entity; + +architecture trb_net16_med_ecp_fot_arch of trb_net16_med_ecp_fot is + +-- Placer Directives +attribute HGROUP : string; +-- for whole architecture +attribute HGROUP of trb_net16_med_ecp_fot_arch : architecture is "GROUP_PCS"; + + component serdes_fot_0 is + generic ( + USER_CONFIG_FILE : String := "serdes_fot_0.txt" + ); + port ( + core_txrefclk : in std_logic; + core_rxrefclk : in std_logic; + hdinp0 : in std_logic; + hdinn0 : in std_logic; + hdoutp0 : out std_logic; + hdoutn0 : out std_logic; + ff_rxiclk_ch0 : in std_logic; + ff_txiclk_ch0 : in std_logic; + ff_ebrd_clk_0 : in std_logic; + ff_txdata_ch0 : in std_logic_vector (7 downto 0); + ff_rxdata_ch0 : out std_logic_vector (7 downto 0); + ff_tx_k_cntrl_ch0 : in std_logic; + ff_rx_k_cntrl_ch0 : out std_logic; + ff_rxfullclk_ch0 : out std_logic; + ff_force_disp_ch0 : in std_logic; + ff_disp_sel_ch0 : in std_logic; + ff_correct_disp_ch0 : in std_logic; + ff_disp_err_ch0, ff_cv_ch0 : out std_logic; + ffc_rrst_ch0 : in std_logic; + ffc_lane_tx_rst_ch0 : in std_logic; + ffc_lane_rx_rst_ch0 : in std_logic; + ffc_txpwdnb_ch0 : in std_logic; + ffc_rxpwdnb_ch0 : in std_logic; + ffs_rlos_lo_ch0 : out std_logic; + ffs_ls_sync_status_ch0 : out std_logic; + ffs_cc_underrun_ch0 : out std_logic; + ffs_cc_overrun_ch0 : out std_logic; + ffs_txfbfifo_error_ch0 : out std_logic; + ffs_rxfbfifo_error_ch0 : out std_logic; + ffs_rlol_ch0 : out std_logic; + oob_out_ch0 : out std_logic; + ffc_macro_rst : in std_logic; + ffc_quad_rst : in std_logic; + ffc_trst : in std_logic; + ff_txfullclk : out std_logic; + ff_txhalfclk : out std_logic; + ffs_plol : out std_logic + ); + end component; + + component trb_net16_lsm_sfp is + port( + SYSCLK : in std_logic; -- fabric clock + RESET : in std_logic; -- synchronous reset + CLEAR : in std_logic; -- asynchronous reset, connect to '0' if not needed / available + -- status signals + SFP_MISSING_IN : in std_logic; -- SFP Present ('0' = no SFP mounted, '1' = SFP in place) + SFP_LOS_IN : in std_logic; -- SFP Loss Of Signal ('0' = OK, '1' = no signal) + SD_LINK_OK_IN : in std_logic; -- SerDes Link OK ('0' = not linked, '1' link established) + SD_LOS_IN : in std_logic; -- SerDes Loss Of Signal ('0' = OK, '1' = signal lost) + SD_TXCLK_BAD_IN : in std_logic; -- SerDes Tx Clock locked ('0' = locked, '1' = not locked) + SD_RXCLK_BAD_IN : in std_logic; -- SerDes Rx Clock locked ('0' = locked, '1' = not locked) + SD_RETRY_IN : in std_logic; -- '0' = handle byte swapping in logic, '1' = simply restart link and hope + SD_ALIGNMENT_IN : in std_logic_vector(1 downto 0); -- SerDes Byte alignment ("10" = swapped, "01" = correct) + SD_CV_IN : in std_logic_vector(1 downto 0); -- SerDes Code Violation ("00" = OK, everything else = BAD) + -- control signals + FULL_RESET_OUT : out std_logic; -- full reset AKA quad_reset + LANE_RESET_OUT : out std_logic; -- partial reset AKA lane_reset + TX_ALLOW_OUT : out std_logic; -- allow normal transmit operation + RX_ALLOW_OUT : out std_logic; -- allow normal receive operation + SWAP_BYTES_OUT : out std_logic; -- bytes need swapping ('0' = correct order, '1' = swapped order) + -- debug signals + STAT_OP : out std_logic_vector(15 downto 0); + CTRL_OP : in std_logic_vector(15 downto 0); + STAT_DEBUG : out std_logic_vector(31 downto 0) + ); + end component; + + component signal_sync is + generic( + WIDTH : integer := 1; -- + DEPTH : integer := 3 + ); + port( + RESET : in std_logic; --Reset is neceessary to avoid optimization to shift register + CLK0 : in std_logic; --clock for first FF + CLK1 : in std_logic; --Clock for other FF + D_IN : in std_logic_vector(WIDTH-1 downto 0); --Data input + D_OUT : out std_logic_vector(WIDTH-1 downto 0) --Data output + ); + end component; + + component lattice_ecp2m_fifo_8x8_dualport + port ( + Data: in std_logic_vector(7 downto 0); + WrClock: in std_logic; + RdClock: in std_logic; + WrEn: in std_logic; + RdEn: in std_logic; + Reset: in std_logic; + RPReset: in std_logic; + Q: out std_logic_vector(7 downto 0); + Empty: out std_logic; + Full: out std_logic + ); + end component; + + component lattice_ecp2m_fifo_16x8_dualport + port ( + Data: in std_logic_vector(15 downto 0); + WrClock: in std_logic; + RdClock: in std_logic; + WrEn: in std_logic; + RdEn: in std_logic; + Reset: in std_logic; + RPReset: in std_logic; + Q: out std_logic_vector(15 downto 0); + Empty: out std_logic; + Full: out std_logic + ); + end component; + + signal link_error : std_logic_vector(7 downto 0); + signal link_error_q: std_logic_vector(7 downto 0); + signal reg_link_error : std_logic_vector(7 downto 0); + signal ffs_plol : std_logic; + signal link_ok : std_logic; + signal tx_data : std_logic_vector(8-1 downto 0); + signal rx_data : std_logic_vector(8-1 downto 0); + signal ff_rxfullclk : std_logic; + signal ff_txfullclk : std_logic; + signal rx_k : std_logic; + signal tx_k : std_logic; + signal lane_rst : std_logic; + signal quad_rst : std_logic; + + signal byte_waiting : std_logic; + signal byte_buffer : std_logic_vector(8-1 downto 0); + signal fifo_reset : std_logic; + signal tx_fifo_dout : std_logic_vector(16-1 downto 0); + signal tx_fifo_data_in : std_logic_vector(16-1 downto 0); + signal tx_fifo_read_en : std_logic; + signal tx_fifo_write_en : std_logic; + signal tx_fifo_empty : std_logic; + signal tx_fifo_full : std_logic; + signal last_tx_fifo_read_en : std_logic; + signal last_tx_fifo_empty : std_logic; + signal tx_fifo_valid_read : std_logic; + signal tx_allow : std_logic; + + signal rx_data_reg : std_logic_vector(8-1 downto 0); + signal buf_rx_data : std_logic_vector(8-1 downto 0); + signal buf_rx_k : std_logic; + signal rx_fifo_write_en : std_logic; + signal rx_fifo_read_en : std_logic; + signal rx_fifo_empty : std_logic; + signal rx_fifo_full : std_logic; + signal rx_fifo_dout : std_logic_vector(8-1 downto 0); + signal is_idle_word : std_logic; + signal rx_starting : std_logic; + signal rx_allow : std_logic; + signal sd_q : std_logic; + signal last_rx_fifo_read_en : std_logic; + signal last_rx_fifo_empty : std_logic; + + signal buf_med_dataready_out : std_logic; + signal buf_med_read_out : std_logic; + signal buf_med_data_out : std_logic_vector(16-1 downto 0); + signal byte_select : std_logic; + signal rx_counter : std_logic_vector(c_NUM_WIDTH-1 downto 0); + signal sfp_los : std_logic; + + signal led_counter : std_logic_vector(15 downto 0); + signal rx_led : std_logic; + signal tx_led : std_logic; + + signal FSM_STAT_OP : std_logic_vector(16-1 downto 0); + signal FSM_STAT_DEBUG : std_logic_vector(64-1 downto 0); + signal FSM_CTRL_OP : std_logic_vector(16-1 downto 0); + +begin + + THE_SERDES: serdes_fot_0 + port map( + core_txrefclk => CLK_25, + core_rxrefclk => CLK_25, + hdinp0 => RXP, + hdinn0 => RXN, + hdoutp0 => TXP, + hdoutn0 => TXN, + ff_rxiclk_ch0 => ff_rxfullclk, + ff_txiclk_ch0 => ff_txfullclk, + ff_ebrd_clk_0 => ff_rxfullclk, + ff_txdata_ch0 => tx_data(7 downto 0), + ff_rxdata_ch0 => rx_data(7 downto 0), + ff_tx_k_cntrl_ch0 => tx_k, + ff_rx_k_cntrl_ch0 => rx_k, + ff_rxfullclk_ch0 => ff_rxfullclk, + ff_force_disp_ch0 => '0', + ff_disp_sel_ch0 => '0', + ff_correct_disp_ch0 => '0', + ff_disp_err_ch0 => link_error(0), + ff_cv_ch0 => link_error(1), + ffc_rrst_ch0 => '0', + ffc_lane_tx_rst_ch0 => lane_rst, --lane_rst(0), + ffc_lane_rx_rst_ch0 => lane_rst, + ffc_txpwdnb_ch0 => '1', + ffc_rxpwdnb_ch0 => '1', + ffs_rlos_lo_ch0 => link_error(2), + ffs_ls_sync_status_ch0 => link_ok, + ffs_cc_underrun_ch0 => link_error(3), + ffs_cc_overrun_ch0 => link_error(4), + ffs_txfbfifo_error_ch0 => link_error(5), + ffs_rxfbfifo_error_ch0 => link_error(6), + ffs_rlol_ch0 => link_error(7), + oob_out_ch0 => open, + + ffc_macro_rst => '0', + ffc_quad_rst => quad_rst, + ffc_trst => '0', + ff_txfullclk => ff_txfullclk, + ffs_plol => ffs_plol + ); + +--TX Control 25 +--------------- + + THE_TX_FIFO: lattice_ecp2m_fifo_16x8_dualport + port map( + Data => tx_fifo_data_in(16-1 downto 0), + WrClock => CLK, + RdClock => ff_txfullclk, + WrEn => tx_fifo_write_en, + RdEn => tx_fifo_read_en, + Reset => fifo_reset, + RPReset => fifo_reset, + Q => tx_fifo_dout(15 downto 0), + Empty => tx_fifo_empty, + Full => tx_fifo_full + ); + + THE_READ_TX_FIFO_PROC: process( ff_txfullclk ) + begin + if( rising_edge(ff_txfullclk) ) then + if( reset = '1' ) then + byte_waiting <= '0'; + tx_fifo_read_en <= '0'; + tx_k <= '1'; + tx_data(7 downto 0) <= x"EE"; + tx_fifo_valid_read <= '0'; + else + tx_fifo_read_en <= tx_allow; + last_tx_fifo_read_en <= tx_fifo_read_en; + last_tx_fifo_empty <= tx_fifo_empty; + tx_fifo_valid_read <= tx_fifo_read_en and not tx_fifo_empty; + if( byte_waiting = '0' ) then + if( (tx_fifo_valid_read = '1')) then + byte_buffer(7 downto 0) <= tx_fifo_dout(15 downto 8); + byte_waiting <= '1'; + tx_k <= '0'; + tx_data(7 downto 0) <= tx_fifo_dout(7 downto 0); + tx_fifo_read_en <= tx_allow; + else + byte_buffer(7 downto 0) <= x"50"; + byte_waiting <= '1'; + tx_k <= '1'; + tx_data(7 downto 0) <= x"BC"; + tx_fifo_read_en <= tx_allow; + end if; + else --if byte_waiting = '1' then + tx_data(7 downto 0) <= byte_buffer(7 downto 0); + tx_k <= '0'; --second byte is always data + byte_waiting <= '0'; + tx_fifo_read_en <= '0'; + end if; + end if; + end if; + end process; + + fifo_reset <= reset or quad_rst; + + --RX Control (25) + --------------------- + + THE_RX_FIFO: lattice_ecp2m_fifo_8x8_dualport + port map( + Data => rx_data_reg(7 downto 0), + WrClock => ff_rxfullclk, + RdClock => clk, + WrEn => rx_fifo_write_en, + RdEn => rx_fifo_read_en, + Reset => fifo_reset, + RPReset => fifo_reset, + Q => rx_fifo_dout(7 downto 0), + Empty => rx_fifo_empty, + Full => rx_fifo_full + ); + + THE_WRITE_RX_FIFO_PROC: process( ff_rxfullclk ) + begin + if( rising_edge(ff_rxfullclk) ) then + buf_rx_data(7 downto 0) <= rx_data(7 downto 0); + buf_rx_k <= rx_k; + if( (reset = '1') or (rx_allow = '0') ) then + rx_fifo_write_en <= '0'; + is_idle_word <= '1'; + rx_starting <= '1'; + else + rx_data_reg(7 downto 0) <= buf_rx_data(7 downto 0); + if( rx_allow = '1' ) then + if( (rx_k = '0') and (is_idle_word = '0') and (rx_starting = '0') ) then + rx_fifo_write_en <= '1'; + else + rx_fifo_write_en <= '0'; + end if; + if ( buf_rx_k = '1' ) then + is_idle_word <= '1'; + rx_starting <= '0'; + elsif( (buf_rx_k = '0') and (is_idle_word = '1') ) then + is_idle_word <= '0'; + end if; + end if; + end if; + end if; + end process THE_WRITE_RX_FIFO_PROC; + +--TX Control (100) +--------------------- + buf_med_read_out <= not tx_fifo_full and tx_allow; + tx_fifo_write_en <= buf_med_read_out and med_dataready_in; + tx_fifo_data_in(15 downto 0) <= med_data_in(15 downto 0); + med_read_out <= buf_med_read_out; + +--RX Control (100) +--------------------- + process( clk ) + begin + if( rising_edge(clk) ) then + if( reset = '1' ) then + buf_med_dataready_out <= '0'; + byte_select <= '0'; + last_rx_fifo_read_en <= '0'; + else + last_rx_fifo_read_en <= rx_fifo_read_en; + buf_med_dataready_out <= '0'; + if( (last_rx_fifo_empty = '0') and (last_rx_fifo_read_en = '1') ) then + if( byte_select = '1' ) then + buf_MED_DATA_OUT(15 downto 0) <= rx_fifo_dout(7 downto 0) + & buf_MED_DATA_OUT(7 downto 0); + buf_MED_DATAREADY_OUT <= '1'; + else + buf_MED_DATA_OUT(15 downto 0) <= x"00" & rx_fifo_dout(7 downto 0); + end if; + byte_select <= not byte_select; + end if; + end if; + end if; + end process; + + rx_fifo_read_en <= tx_allow; + MED_DATA_OUT(15 downto 0) <= buf_MED_DATA_OUT(15 downto 0); + MED_DATAREADY_OUT <= buf_MED_DATAREADY_OUT; + MED_PACKET_NUM_OUT <= rx_counter; + +--rx packet counter +--------------------- + THE_RX_PACKETS_PROC: process( clk ) + begin + if( rising_edge(clk) ) then + last_rx_fifo_empty <= rx_fifo_empty; + if( (reset = '1') or (rx_allow = '0') ) then + rx_counter <= c_H0; + else + if( buf_med_dataready_out = '1' ) then + if( rx_counter = c_max_word_number ) then + rx_counter <= (others => '0'); + else + rx_counter <= rx_counter + 1; + end if; + end if; + end if; + end if; + end process; + + + +--Link State machine +--------------------- + + + LINK_ERROR_SYNC: signal_sync + generic map( + DEPTH => 2, + WIDTH => 8 + ) + port map( + RESET => reset, + D_IN(7 downto 0) => link_error, + CLK0 => ff_rxfullclk, + CLK1 => CLK, + D_OUT(7 downto 0) => link_error_q + ); + + SD_SYNC_2: signal_sync + generic map( + DEPTH => 2, + WIDTH => 1 + ) + port map( + RESET => reset, + D_IN(0) => sd, + CLK0 => ff_rxfullclk, + CLK1 => CLK, + D_OUT(0) => sd_q + ); + +--LED Signals +--------------------- + THE_TX_RX_LED_PROC: process( clk ) + begin + if( rising_edge(CLK) ) then + led_counter <= led_counter + 1; + if ( buf_med_dataready_out = '1' ) then + rx_led <= '1'; + elsif( led_counter = 0 ) then + rx_led <= '0'; + end if; + if( tx_fifo_valid_read = '1') then + tx_led <= '1'; + elsif led_counter = 0 then + tx_led <= '0'; + end if; + end if; + end process; + + + STAT_OP(9 downto 0) <= FSM_STAT_OP(9 downto 0); + STAT_OP(10) <= rx_led; + STAT_OP(11) <= tx_led; + STAT_OP(15 downto 12) <= FSM_STAT_OP(15 downto 12); + + STAT_DEBUG(31 downto 0) <= FSM_STAT_DEBUG(31 downto 0); + STAT_DEBUG(39 downto 32) <= rx_data_reg(7 downto 0); + STAT_DEBUG(63 downto 40) <= (others => '0'); + + + + THE_SFP_LSM: trb_net16_lsm_sfp + port map( + SYSCLK => CLK, + RESET => reset, + CLEAR => reset, + SFP_MISSING_IN => '0', + SFP_LOS_IN => sfp_los, + SD_LINK_OK_IN => link_ok, + SD_LOS_IN => link_error_q(2), + SD_TXCLK_BAD_IN => ffs_plol, + SD_RXCLK_BAD_IN => link_error_q(7), + SD_RETRY_IN => '0', -- '0' = handle byte swapping in logic, '1' = simply restart link and hope + SD_ALIGNMENT_IN => "10", + SD_CV_IN(0) => link_error_q(1), + SD_CV_IN(1) => '0', + FULL_RESET_OUT => quad_rst, + LANE_RESET_OUT => lane_rst, + TX_ALLOW_OUT => tx_allow, + RX_ALLOW_OUT => rx_allow, + SWAP_BYTES_OUT => open, + STAT_OP => FSM_STAT_OP(15 downto 0), + CTRL_OP => FSM_CTRL_OP(15 downto 0), + STAT_DEBUG => FSM_STAT_DEBUG(31 downto 0) + ); + + + sfp_los <= not sd_q; + FSM_CTRL_OP <= CTRL_OP; + + + + + +end architecture; \ No newline at end of file diff --git a/media_interfaces/trb_net16_med_ecp_fot_4.vhd b/media_interfaces/trb_net16_med_ecp_fot_4.vhd index 0393b5a..70e4686 100644 --- a/media_interfaces/trb_net16_med_ecp_fot_4.vhd +++ b/media_interfaces/trb_net16_med_ecp_fot_4.vhd @@ -45,9 +45,9 @@ attribute HGROUP : string; -- for whole architecture attribute HGROUP of trb_net16_med_ecp_fot_4_arch : architecture is "GROUP_PCS"; -component serdes_full_quad is +component serdes_fot_full_quad is generic( - USER_CONFIG_FILE : String := "serdes_full_quad.txt" ); + USER_CONFIG_FILE : String := "serdes_fot_full_quad.txt" ); port( core_txrefclk : in std_logic; core_rxrefclk : in std_logic; @@ -257,8 +257,6 @@ component serdes_full_quad is ); end component; - - type link_error_t is array(0 to 3) of std_logic_vector(7 downto 0); signal link_error : link_error_t; signal link_error_q: link_error_t; @@ -321,7 +319,7 @@ component serdes_full_quad is begin - THE_SERDES: serdes_full_quad + THE_SERDES: serdes_fot_full_quad port map( core_txrefclk => CLK_25, core_rxrefclk => CLK_25, @@ -691,12 +689,12 @@ begin SFP_MISSING_IN => '0', SFP_LOS_IN => sfp_los(i), SD_LINK_OK_IN => link_ok(i), - SD_LOS_IN => link_error(i)(2), + SD_LOS_IN => link_error_q(i)(2), SD_TXCLK_BAD_IN => ffs_plol, - SD_RXCLK_BAD_IN => link_error(i)(7), + SD_RXCLK_BAD_IN => link_error_q(i)(7), SD_RETRY_IN => '0', -- '0' = handle byte swapping in logic, '1' = simply restart link and hope SD_ALIGNMENT_IN => "10", - SD_CV_IN(0) => link_error(i)(1), + SD_CV_IN(0) => link_error_q(i)(1), SD_CV_IN(1) => '0', FULL_RESET_OUT => quad_rst(i), LANE_RESET_OUT => lane_rst(i), diff --git a/media_interfaces/trb_net16_med_ecp_sfp_4.vhd b/media_interfaces/trb_net16_med_ecp_sfp_4.vhd new file mode 100644 index 0000000..bf4261d --- /dev/null +++ b/media_interfaces/trb_net16_med_ecp_sfp_4.vhd @@ -0,0 +1,878 @@ +--Media interface for Lattice ECP2M using PCS at 2GHz + + +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.std_logic_ARITH.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; + +entity trb_net16_med_ecp_sfp_4 is + generic( + REVERSE_ORDER : integer range 0 to 1 := c_NO + -- USED_PORTS : std_logic-vector(3 downto 0) := "1111" + ); + port( + CLK : in std_logic; -- SerDes clock + SYSCLK : in std_logic; -- fabric clock + RESET : in std_logic; -- synchronous reset + CLEAR : in std_logic; -- asynchronous reset + CLK_EN : in std_logic; + --Internal Connection + MED_DATA_IN : in std_logic_vector(4*c_DATA_WIDTH-1 downto 0); + MED_PACKET_NUM_IN : in std_logic_vector(4*c_NUM_WIDTH-1 downto 0); + MED_DATAREADY_IN : in std_logic_vector(3 downto 0); + MED_READ_OUT : out std_logic_vector(3 downto 0); + MED_DATA_OUT : out std_logic_vector(4*c_DATA_WIDTH-1 downto 0); + MED_PACKET_NUM_OUT : out std_logic_vector(4*c_NUM_WIDTH-1 downto 0); + MED_DATAREADY_OUT : out std_logic_vector(3 downto 0); + MED_READ_IN : in std_logic_vector(3 downto 0); + REFCLK2CORE_OUT : out std_logic; + --SFP Connection + SD_RXD_P_IN : in std_logic_vector(3 downto 0); + SD_RXD_N_IN : in std_logic_vector(3 downto 0); + SD_TXD_P_OUT : out std_logic_vector(3 downto 0); + SD_TXD_N_OUT : out std_logic_vector(3 downto 0); + SD_REFCLK_P_IN : in std_logic; + SD_REFCLK_N_IN : in std_logic; + SD_PRSNT_N_IN : in std_logic_vector(3 downto 0); -- SFP Present ('0' = SFP in place, '1' = no SFP mounted) + SD_LOS_IN : in std_logic_vector(3 downto 0); -- SFP Loss Of Signal ('0' = OK, '1' = no signal) + -- Status and control port + STAT_OP : out std_logic_vector (4*16-1 downto 0); + CTRL_OP : in std_logic_vector (4*16-1 downto 0); + STAT_DEBUG : out std_logic_vector (64*4-1 downto 0); + CTRL_DEBUG : in std_logic_vector (63 downto 0) + ); +end entity; + +architecture med_ecp_sfp_4 of trb_net16_med_ecp_sfp_4 is + + -- Placer Directives + attribute HGROUP : string; + -- for whole architecture + attribute HGROUP of med_ecp_sfp_4 : architecture is "media_interface_group"; + +component serdes_sfp_full_quad is + generic( + USER_CONFIG_FILE : String := "serdes_sfp_full_quad.txt" ); + port( + core_txrefclk : in std_logic; + core_rxrefclk : in std_logic; + + hdinp0 : in std_logic; + hdinn0 : in std_logic; + hdoutp0 : out std_logic; + hdoutn0 : out std_logic; + ff_rxiclk_ch0 : in std_logic; + ff_txiclk_ch0 : in std_logic; + ff_ebrd_clk_0 : in std_logic; + ff_txdata_ch0 : in std_logic_vector (15 downto 0); + ff_rxdata_ch0 : out std_logic_vector (15 downto 0); + ff_tx_k_cntrl_ch0 : in std_logic_vector (1 downto 0); + ff_rx_k_cntrl_ch0 : out std_logic_vector (1 downto 0); + ff_rxfullclk_ch0 : out std_logic; + ff_rxhalfclk_ch0 : out std_logic; + ff_force_disp_ch0 : in std_logic_vector (1 downto 0); + ff_disp_sel_ch0 : in std_logic_vector (1 downto 0); + ff_correct_disp_ch0 : in std_logic_vector (1 downto 0); + ff_disp_err_ch0 : out std_logic_vector (1 downto 0); + ff_cv_ch0 : out std_logic_vector (1 downto 0); + ffc_rrst_ch0 : in std_logic; + ffc_lane_tx_rst_ch0 : in std_logic; + ffc_lane_rx_rst_ch0 : in std_logic; + ffc_txpwdnb_ch0 : in std_logic; + ffc_rxpwdnb_ch0 : in std_logic; + ffs_rlos_lo_ch0 : out std_logic; + ffs_ls_sync_status_ch0 : out std_logic; + ffs_cc_underrun_ch0 : out std_logic; + ffs_cc_overrun_ch0 : out std_logic; + ffs_txfbfifo_error_ch0 : out std_logic; + ffs_rxfbfifo_error_ch0 : out std_logic; + ffs_rlol_ch0 : out std_logic; + oob_out_ch0 : out std_logic; + + hdinp1 : in std_logic; + hdinn1 : in std_logic; + hdoutp1 : out std_logic; + hdoutn1 : out std_logic; + ff_rxiclk_ch1 : in std_logic; + ff_txiclk_ch1 : in std_logic; + ff_ebrd_clk_1 : in std_logic; + ff_txdata_ch1 : in std_logic_vector (15 downto 0); + ff_rxdata_ch1 : out std_logic_vector (15 downto 0); + ff_tx_k_cntrl_ch1 : in std_logic_vector (1 downto 0); + ff_rx_k_cntrl_ch1 : out std_logic_vector (1 downto 0); + ff_rxfullclk_ch1 : out std_logic; + ff_rxhalfclk_ch1 : out std_logic; + ff_force_disp_ch1 : in std_logic_vector (1 downto 0); + ff_disp_sel_ch1 : in std_logic_vector (1 downto 0); + ff_correct_disp_ch1 : in std_logic_vector (1 downto 0); + ff_disp_err_ch1 : out std_logic_vector (1 downto 0); + ff_cv_ch1 : out std_logic_vector (1 downto 0); + ffc_rrst_ch1 : in std_logic; + ffc_lane_tx_rst_ch1 : in std_logic; + ffc_lane_rx_rst_ch1 : in std_logic; + ffc_txpwdnb_ch1 : in std_logic; + ffc_rxpwdnb_ch1 : in std_logic; + ffs_rlos_lo_ch1 : out std_logic; + ffs_ls_sync_status_ch1 : out std_logic; + ffs_cc_underrun_ch1 : out std_logic; + ffs_cc_overrun_ch1 : out std_logic; + ffs_txfbfifo_error_ch1 : out std_logic; + ffs_rxfbfifo_error_ch1 : out std_logic; + ffs_rlol_ch1 : out std_logic; + oob_out_ch1 : out std_logic; + + hdinp2 : in std_logic; + hdinn2 : in std_logic; + hdoutp2 : out std_logic; + hdoutn2 : out std_logic; + ff_rxiclk_ch2 : in std_logic; + ff_txiclk_ch2 : in std_logic; + ff_ebrd_clk_2 : in std_logic; + ff_txdata_ch2 : in std_logic_vector (15 downto 0); + ff_rxdata_ch2 : out std_logic_vector (15 downto 0); + ff_tx_k_cntrl_ch2 : in std_logic_vector (1 downto 0); + ff_rx_k_cntrl_ch2 : out std_logic_vector (1 downto 0); + ff_rxfullclk_ch2 : out std_logic; + ff_rxhalfclk_ch2 : out std_logic; + ff_force_disp_ch2 : in std_logic_vector (1 downto 0); + ff_disp_sel_ch2 : in std_logic_vector (1 downto 0); + ff_correct_disp_ch2 : in std_logic_vector (1 downto 0); + ff_disp_err_ch2 : out std_logic_vector (1 downto 0); + ff_cv_ch2 : out std_logic_vector (1 downto 0); + ffc_rrst_ch2 : in std_logic; + ffc_lane_tx_rst_ch2 : in std_logic; + ffc_lane_rx_rst_ch2 : in std_logic; + ffc_txpwdnb_ch2 : in std_logic; + ffc_rxpwdnb_ch2 : in std_logic; + ffs_rlos_lo_ch2 : out std_logic; + ffs_ls_sync_status_ch2 : out std_logic; + ffs_cc_underrun_ch2 : out std_logic; + ffs_cc_overrun_ch2 : out std_logic; + ffs_txfbfifo_error_ch2 : out std_logic; + ffs_rxfbfifo_error_ch2 : out std_logic; + ffs_rlol_ch2 : out std_logic; + oob_out_ch2 : out std_logic; + + hdinp3 : in std_logic; + hdinn3 : in std_logic; + hdoutp3 : out std_logic; + hdoutn3 : out std_logic; + ff_rxiclk_ch3 : in std_logic; + ff_txiclk_ch3 : in std_logic; + ff_ebrd_clk_3 : in std_logic; + ff_txdata_ch3 : in std_logic_vector (15 downto 0); + ff_rxdata_ch3 : out std_logic_vector (15 downto 0); + ff_tx_k_cntrl_ch3 : in std_logic_vector (1 downto 0); + ff_rx_k_cntrl_ch3 : out std_logic_vector (1 downto 0); + ff_rxfullclk_ch3 : out std_logic; + ff_rxhalfclk_ch3 : out std_logic; + ff_force_disp_ch3 : in std_logic_vector (1 downto 0); + ff_disp_sel_ch3 : in std_logic_vector (1 downto 0); + ff_correct_disp_ch3 : in std_logic_vector (1 downto 0); + ff_disp_err_ch3 : out std_logic_vector (1 downto 0); + ff_cv_ch3 : out std_logic_vector (1 downto 0); + ffc_rrst_ch3 : in std_logic; + ffc_lane_tx_rst_ch3 : in std_logic; + ffc_lane_rx_rst_ch3 : in std_logic; + ffc_txpwdnb_ch3 : in std_logic; + ffc_rxpwdnb_ch3 : in std_logic; + ffs_rlos_lo_ch3 : out std_logic; + ffs_ls_sync_status_ch3 : out std_logic; + ffs_cc_underrun_ch3 : out std_logic; + ffs_cc_overrun_ch3 : out std_logic; + ffs_txfbfifo_error_ch3 : out std_logic; + ffs_rxfbfifo_error_ch3 : out std_logic; + ffs_rlol_ch3 : out std_logic; + oob_out_ch3 : out std_logic; + + ffc_macro_rst : in std_logic; + ffc_quad_rst : in std_logic; + ffc_trst : in std_logic; + ff_txfullclk : out std_logic; + ff_txhalfclk : out std_logic; + refck2core : out std_logic; + ffs_plol : out std_logic + ); + end component; + + component trb_net16_lsm_sfp is + port( + SYSCLK : in std_logic; -- fabric clock + RESET : in std_logic; -- synchronous reset + CLEAR : in std_logic; -- asynchronous reset, connect to '0' if not needed / available + -- status signals + SFP_MISSING_IN : in std_logic; -- SFP Present ('0' = no SFP mounted, '1' = SFP in place) + SFP_LOS_IN : in std_logic; -- SFP Loss Of Signal ('0' = OK, '1' = no signal) + SD_LINK_OK_IN : in std_logic; -- SerDes Link OK ('0' = not linked, '1' link established) + SD_LOS_IN : in std_logic; -- SerDes Loss Of Signal ('0' = OK, '1' = signal lost) + SD_TXCLK_BAD_IN : in std_logic; -- SerDes Tx Clock locked ('0' = locked, '1' = not locked) + SD_RXCLK_BAD_IN : in std_logic; -- SerDes Rx Clock locked ('0' = locked, '1' = not locked) + SD_RETRY_IN : in std_logic; -- '0' = handle byte swapping in logic, '1' = simply restart link and hope + SD_ALIGNMENT_IN : in std_logic_vector(1 downto 0); -- SerDes Byte alignment ("10" = swapped, "01" = correct) + SD_CV_IN : in std_logic_vector(1 downto 0); -- SerDes Code Violation ("00" = OK, everything else = BAD) + -- control signals + FULL_RESET_OUT : out std_logic; -- full reset AKA quad_reset + LANE_RESET_OUT : out std_logic; -- partial reset AKA lane_reset + TX_ALLOW_OUT : out std_logic; -- allow normal transmit operation + RX_ALLOW_OUT : out std_logic; -- allow normal receive operation + SWAP_BYTES_OUT : out std_logic; -- bytes need swapping ('0' = correct order, '1' = swapped order) + -- debug signals + STAT_OP : out std_logic_vector(15 downto 0); + CTRL_OP : in std_logic_vector(15 downto 0); + STAT_DEBUG : out std_logic_vector(31 downto 0) + ); + end component; + + component trb_net_fifo_16bit_bram_dualport is + generic( + USE_STATUS_FLAGS : integer := c_YES + ); + port( read_clock_in : in std_logic; + write_clock_in : in std_logic; + read_enable_in : in std_logic; + write_enable_in : in std_logic; + fifo_gsr_in : in std_logic; + write_data_in : in std_logic_vector(17 downto 0); + read_data_out : out std_logic_vector(17 downto 0); + full_out : out std_logic; + empty_out : out std_logic; + fifostatus_out : out std_logic_vector(3 downto 0); + valid_read_out : out std_logic; + almost_empty_out : out std_logic; + almost_full_out : out std_logic + ); + end component; + + component signal_sync is + generic( + WIDTH : integer := 1; -- + DEPTH : integer := 3 + ); + port( + RESET : in std_logic; --Reset is neceessary to avoid optimization to shift register + CLK0 : in std_logic; --clock for first FF + CLK1 : in std_logic; --Clock for other FF + D_IN : in std_logic_vector(WIDTH-1 downto 0); --Data input + D_OUT : out std_logic_vector(WIDTH-1 downto 0) --Data output + ); + end component; + + + type link_error_t is array(0 to 3) of std_logic_vector(9 downto 0); + signal link_error : link_error_t; + + signal refck2core : std_logic; + signal clock : std_logic; + + --serdes connections + signal tx_data : std_logic_vector(4*16-1 downto 0); + signal tx_k : std_logic_vector(7 downto 0); + signal rx_data : std_logic_vector(4*16-1 downto 0); + signal rx_k : std_logic_vector(7 downto 0); + signal link_ok : std_logic_vector(3 downto 0); + + signal ff_rxhalfclk : std_logic_vector(3 downto 0); + signal ff_txhalfclk : std_logic; + --rx fifo signals + signal fifo_rx_rd_en : std_logic_vector(3 downto 0); + signal fifo_rx_wr_en : std_logic_vector(3 downto 0); + signal fifo_rx_reset : std_logic_vector(3 downto 0); + signal fifo_rx_din : std_logic_vector(4*18-1 downto 0); + signal fifo_rx_dout : std_logic_vector(4*18-1 downto 0); + signal fifo_rx_full : std_logic_vector(3 downto 0); + signal fifo_rx_empty : std_logic_vector(3 downto 0); + --tx fifo signals + signal fifo_tx_rd_en : std_logic_vector(3 downto 0); + signal fifo_tx_wr_en : std_logic_vector(3 downto 0); + signal fifo_tx_reset : std_logic_vector(3 downto 0); + signal fifo_tx_din : std_logic_vector(4*18-1 downto 0); + signal fifo_tx_dout : std_logic_vector(4*18-1 downto 0); + signal fifo_tx_full : std_logic_vector(3 downto 0); + signal fifo_tx_empty : std_logic_vector(3 downto 0); + --rx path + signal rx_counter : std_logic_vector(4*c_NUM_WIDTH-1 downto 0); + signal buf_med_dataready_out : std_logic_vector(3 downto 0); + signal buf_med_data_out : std_logic_vector(4*c_DATA_WIDTH-1 downto 0); + signal buf_med_packet_num_out : std_logic_vector(4*c_NUM_WIDTH-1 downto 0); + signal last_rx : std_logic_vector(4*9-1 downto 0); + signal last_fifo_rx_empty : std_logic_vector(3 downto 0); + --tx path + signal last_fifo_tx_empty : std_logic_vector(3 downto 0); + --link status + signal rx_k_q : std_logic_vector(4*2-1 downto 0); + signal ffs_plol : std_logic; + + signal quad_rst : std_logic_vector(3 downto 0); + signal lane_rst : std_logic_vector(3 downto 0); + signal tx_allow : std_logic_vector(3 downto 0); + signal rx_allow : std_logic_vector(3 downto 0); + + signal rx_allow_q : std_logic_vector(3 downto 0); -- clock domain changed signal + signal tx_allow_q : std_logic_vector(3 downto 0); + signal swap_bytes : std_logic_vector(3 downto 0); + signal FSM_STAT_DEBUG : std_logic_vector(4*32-1 downto 0); + signal FSM_STAT_OP : std_logic_vector(4*16-1 downto 0); + signal FSM_CTRL_OP : std_logic_vector(4*16-1 downto 0); + + -- status inputs from SFP + signal sfp_prsnt_n : std_logic_vector(3 downto 0); -- synchronized input signals + signal sfp_los : std_logic_vector(3 downto 0); -- synchronized input signals + + + type led_counter_t is array(0 to 3) of std_logic_vector(15 downto 0); + signal led_counter : led_counter_t; + signal rx_led, tx_led : std_logic_vector(3 downto 0); + + +begin + + +-------------------------------------------------------------------------- +-- Main control state machine, startup control for SFP +-------------------------------------------------------------------------- + + +-- Input synchronizer + + gen_data_lines : for i in 0 to 3 generate + THE_SFP_STATUS_SYNC: signal_sync + generic map( + DEPTH => 3, + WIDTH => 2 + ) + port map( + RESET => RESET, + D_IN(0) => SD_PRSNT_N_IN(i), + D_IN(1) => SD_LOS_IN(i), + CLK0 => SYSCLK, + CLK1 => SYSCLK, + D_OUT(0) => sfp_prsnt_n(i), + D_OUT(1) => sfp_los(i) + ); + + -- Transfering the komma delimiter in the *training* phase + THE_RX_K_SYNC: signal_sync + generic map( + DEPTH => 3, + WIDTH => 2 + ) + port map( + RESET => RESET, + D_IN => rx_k(i*2+1 downto i*2), + CLK0 => ff_rxhalfclk(i), + CLK1 => SYSCLK, + D_OUT => rx_k_q(i*2+1 downto i*2) + ); + + ---------------------------------------------------------------------------------------------------------- + -- NEW STATEMACHINE START + ---------------------------------------------------------------------------------------------------------- + THE_SFP_LSM: trb_net16_lsm_sfp + port map( + SYSCLK => SYSCLK, + RESET => reset, + CLEAR => clear, + SFP_MISSING_IN => sfp_prsnt_n(i), + SFP_LOS_IN => sfp_los(i), + SD_LINK_OK_IN => link_ok(i), + SD_LOS_IN => link_error(i)(2), + SD_TXCLK_BAD_IN => ffs_plol, + SD_RXCLK_BAD_IN => link_error(i)(7), + SD_RETRY_IN => '0', -- '0' = handle byte swapping in logic, '1' = simply restart link and hope + SD_ALIGNMENT_IN => rx_k_q(i*2+1 downto i*2), + SD_CV_IN => link_error(i)(1 downto 0), + FULL_RESET_OUT => quad_rst(i), + LANE_RESET_OUT => lane_rst(i), + TX_ALLOW_OUT => tx_allow(i), + RX_ALLOW_OUT => rx_allow(i), + SWAP_BYTES_OUT => swap_bytes(i), + STAT_OP => FSM_STAT_OP(i*16+15 downto i*16), + CTRL_OP => FSM_CTRL_OP(i*16+15 downto i*16), + STAT_DEBUG => FSM_STAT_DEBUG(i*32+31 downto i*32) + ); + ---------------------------------------------------------------------------------------------------------- + -- NEW STATEMACHINE STOP + ---------------------------------------------------------------------------------------------------------- + + end generate; + + + + +-- Instantiation of serdes module + gen_normal_serdes : if REVERSE_ORDER = c_NO generate + THE_SERDES: serdes_sfp_full_quad + port map( + core_txrefclk => clk, + core_rxrefclk => clk, + hdinp0 => SD_RXD_P_IN(0), + hdinn0 => SD_RXD_N_IN(0), + hdoutp0 => SD_TXD_P_OUT(0), + hdoutn0 => SD_TXD_N_OUT(0), + ff_rxiclk_ch0 => ff_rxhalfclk(0), + ff_txiclk_ch0 => ff_txhalfclk, + ff_ebrd_clk_0 => ff_rxhalfclk(0), + ff_txdata_ch0 => tx_data(15 downto 0), + ff_rxdata_ch0 => rx_data(15 downto 0), + ff_tx_k_cntrl_ch0 => tx_k(1 downto 0), + ff_rx_k_cntrl_ch0 => rx_k(1 downto 0), + ff_rxhalfclk_ch0 => ff_rxhalfclk(0), + ff_force_disp_ch0 => "00", + ff_disp_sel_ch0 => "00", + ff_correct_disp_ch0 => "00", + ff_disp_err_ch0 => link_error(0)(9 downto 8), + ff_cv_ch0 => link_error(0)(1 downto 0), + ffc_rrst_ch0 => '0', + ffc_lane_tx_rst_ch0 => lane_rst(0), --lane_rst(0), + ffc_lane_rx_rst_ch0 => lane_rst(0), + ffc_txpwdnb_ch0 => '1', + ffc_rxpwdnb_ch0 => '1', + ffs_rlos_lo_ch0 => link_error(0)(2), + ffs_ls_sync_status_ch0 => link_ok(0), + ffs_cc_underrun_ch0 => link_error(0)(3), + ffs_cc_overrun_ch0 => link_error(0)(4), + ffs_txfbfifo_error_ch0 => link_error(0)(5), + ffs_rxfbfifo_error_ch0 => link_error(0)(6), + ffs_rlol_ch0 => link_error(0)(7), + oob_out_ch0 => open, + + hdinp1 => SD_RXD_P_IN(1), + hdinn1 => SD_RXD_N_IN(1), + hdoutp1 => SD_TXD_P_OUT(1), + hdoutn1 => SD_TXD_N_OUT(1), + ff_rxiclk_ch1 => ff_rxhalfclk(1), + ff_txiclk_ch1 => ff_txhalfclk, + ff_ebrd_clk_1 => ff_rxhalfclk(1), + ff_txdata_ch1 => tx_data(31 downto 16), + ff_rxdata_ch1 => rx_data(31 downto 16), + ff_tx_k_cntrl_ch1 => tx_k(3 downto 2), + ff_rx_k_cntrl_ch1 => rx_k(3 downto 2), + ff_rxhalfclk_ch1 => ff_rxhalfclk(1), + ff_force_disp_ch1 => "00", + ff_disp_sel_ch1 => "00", + ff_correct_disp_ch1 => "00", + ff_disp_err_ch1 => link_error(1)(9 downto 8), + ff_cv_ch1 => link_error(1)(1 downto 0), + ffc_rrst_ch1 => '0', + ffc_lane_tx_rst_ch1 => lane_rst(1), --lane_rst(1), + ffc_lane_rx_rst_ch1 => lane_rst(1), + ffc_txpwdnb_ch1 => '1', + ffc_rxpwdnb_ch1 => '1', + ffs_rlos_lo_ch1 => link_error(1)(2), + ffs_ls_sync_status_ch1 => link_ok(1), + ffs_cc_underrun_ch1 => link_error(1)(3), + ffs_cc_overrun_ch1 => link_error(1)(4), + ffs_txfbfifo_error_ch1 => link_error(1)(5), + ffs_rxfbfifo_error_ch1 => link_error(1)(6), + ffs_rlol_ch1 => link_error(1)(7), + oob_out_ch1 => open, + + hdinp2 => SD_RXD_P_IN(2), + hdinn2 => SD_RXD_N_IN(2), + hdoutp2 => SD_TXD_P_OUT(2), + hdoutn2 => SD_TXD_N_OUT(2), + ff_rxiclk_ch2 => ff_rxhalfclk(2), + ff_txiclk_ch2 => ff_txhalfclk, + ff_ebrd_clk_2 => ff_rxhalfclk(2), + ff_txdata_ch2 => tx_data(47 downto 32), + ff_rxdata_ch2 => rx_data(47 downto 32), + ff_tx_k_cntrl_ch2 => tx_k(5 downto 4), + ff_rx_k_cntrl_ch2 => rx_k(5 downto 4), + ff_rxhalfclk_ch2 => ff_rxhalfclk(2), + ff_force_disp_ch2 => "00", + ff_disp_sel_ch2 => "00", + ff_correct_disp_ch2 => "00", + ff_disp_err_ch2 => link_error(2)(9 downto 8), + ff_cv_ch2 => link_error(2)(1 downto 0), + ffc_rrst_ch2 => '0', + ffc_lane_tx_rst_ch2 => lane_rst(2), --lane_rst(2), + ffc_lane_rx_rst_ch2 => lane_rst(2), + ffc_txpwdnb_ch2 => '1', + ffc_rxpwdnb_ch2 => '1', + ffs_rlos_lo_ch2 => link_error(2)(2), + ffs_ls_sync_status_ch2 => link_ok(2), + ffs_cc_underrun_ch2 => link_error(2)(3), + ffs_cc_overrun_ch2 => link_error(2)(4), + ffs_txfbfifo_error_ch2 => link_error(2)(5), + ffs_rxfbfifo_error_ch2 => link_error(2)(6), + ffs_rlol_ch2 => link_error(2)(7), + oob_out_ch2 => open, + + hdinp3 => SD_RXD_P_IN(3), + hdinn3 => SD_RXD_N_IN(3), + hdoutp3 => SD_TXD_P_OUT(3), + hdoutn3 => SD_TXD_N_OUT(3), + ff_rxiclk_ch3 => ff_rxhalfclk(3), + ff_txiclk_ch3 => ff_txhalfclk, + ff_ebrd_clk_3 => ff_rxhalfclk(3), + ff_txdata_ch3 => tx_data(63 downto 48), + ff_rxdata_ch3 => rx_data(63 downto 48), + ff_tx_k_cntrl_ch3 => tx_k(7 downto 6), + ff_rx_k_cntrl_ch3 => rx_k(7 downto 6), + ff_rxhalfclk_ch3 => ff_rxhalfclk(3), + ff_force_disp_ch3 => "00", + ff_disp_sel_ch3 => "00", + ff_correct_disp_ch3 => "00", + ff_disp_err_ch3 => link_error(3)(9 downto 8), + ff_cv_ch3 => link_error(3)(1 downto 0), + ffc_rrst_ch3 => '0', + ffc_lane_tx_rst_ch3 => lane_rst(3), --lane_rst(3), + ffc_lane_rx_rst_ch3 => lane_rst(3), + ffc_txpwdnb_ch3 => '1', + ffc_rxpwdnb_ch3 => '1', + ffs_rlos_lo_ch3 => link_error(3)(2), + ffs_ls_sync_status_ch3 => link_ok(3), + ffs_cc_underrun_ch3 => link_error(3)(3), + ffs_cc_overrun_ch3 => link_error(3)(4), + ffs_txfbfifo_error_ch3 => link_error(3)(5), + ffs_rxfbfifo_error_ch3 => link_error(3)(6), + ffs_rlol_ch3 => link_error(3)(7), + oob_out_ch3 => open, + + ffc_macro_rst => '0', + ffc_quad_rst => quad_rst(0), + ffc_trst => '0', + ff_txhalfclk => ff_txhalfclk, + refck2core => REFCLK2CORE_OUT, + ffs_plol => ffs_plol + ); + end generate; + + gen_twisted_serdes : if REVERSE_ORDER = c_YES generate + THE_SERDES: serdes_sfp_full_quad + port map( + core_txrefclk => clk, + core_rxrefclk => clk, + hdinp0 => SD_RXD_P_IN(0), + hdinn0 => SD_RXD_N_IN(0), + hdoutp0 => SD_TXD_P_OUT(0), + hdoutn0 => SD_TXD_N_OUT(0), + ff_rxiclk_ch0 => ff_rxhalfclk(3), + ff_txiclk_ch0 => ff_txhalfclk, + ff_ebrd_clk_0 => ff_rxhalfclk(3), + ff_txdata_ch0 => tx_data(63 downto 48), + ff_rxdata_ch0 => rx_data(63 downto 48), + ff_tx_k_cntrl_ch0 => tx_k(7 downto 6), + ff_rx_k_cntrl_ch0 => rx_k(7 downto 6), + ff_rxhalfclk_ch0 => ff_rxhalfclk(3), + ff_force_disp_ch0 => "00", + ff_disp_sel_ch0 => "00", + ff_correct_disp_ch0 => "00", + ff_disp_err_ch0 => link_error(3)(9 downto 8), + ff_cv_ch0 => link_error(3)(1 downto 0), + ffc_rrst_ch0 => '0', + ffc_lane_tx_rst_ch0 => lane_rst(3), --lane_rst(0), + ffc_lane_rx_rst_ch0 => lane_rst(3), + ffc_txpwdnb_ch0 => '1', + ffc_rxpwdnb_ch0 => '1', + ffs_rlos_lo_ch0 => link_error(3)(2), + ffs_ls_sync_status_ch0 => link_ok(3), + ffs_cc_underrun_ch0 => link_error(3)(3), + ffs_cc_overrun_ch0 => link_error(3)(4), + ffs_txfbfifo_error_ch0 => link_error(3)(5), + ffs_rxfbfifo_error_ch0 => link_error(3)(6), + ffs_rlol_ch0 => link_error(3)(7), + oob_out_ch0 => open, + + hdinp1 => SD_RXD_P_IN(1), + hdinn1 => SD_RXD_N_IN(1), + hdoutp1 => SD_TXD_P_OUT(1), + hdoutn1 => SD_TXD_N_OUT(1), + ff_rxiclk_ch1 => ff_rxhalfclk(2), + ff_txiclk_ch1 => ff_txhalfclk, + ff_ebrd_clk_1 => ff_rxhalfclk(2), + ff_txdata_ch1 => tx_data(47 downto 32), + ff_rxdata_ch1 => rx_data(47 downto 32), + ff_tx_k_cntrl_ch1 => tx_k(5 downto 4), + ff_rx_k_cntrl_ch1 => rx_k(5 downto 4), + ff_rxhalfclk_ch1 => ff_rxhalfclk(2), + ff_force_disp_ch1 => "00", + ff_disp_sel_ch1 => "00", + ff_correct_disp_ch1 => "00", + ff_disp_err_ch1 => link_error(2)(9 downto 8), + ff_cv_ch1 => link_error(2)(1 downto 0), + ffc_rrst_ch1 => '0', + ffc_lane_tx_rst_ch1 => lane_rst(2), --lane_rst(1), + ffc_lane_rx_rst_ch1 => lane_rst(2), + ffc_txpwdnb_ch1 => '1', + ffc_rxpwdnb_ch1 => '1', + ffs_rlos_lo_ch1 => link_error(2)(2), + ffs_ls_sync_status_ch1 => link_ok(2), + ffs_cc_underrun_ch1 => link_error(2)(3), + ffs_cc_overrun_ch1 => link_error(2)(4), + ffs_txfbfifo_error_ch1 => link_error(2)(5), + ffs_rxfbfifo_error_ch1 => link_error(2)(6), + ffs_rlol_ch1 => link_error(2)(7), + oob_out_ch1 => open, + + hdinp2 => SD_RXD_P_IN(2), + hdinn2 => SD_RXD_N_IN(2), + hdoutp2 => SD_TXD_P_OUT(2), + hdoutn2 => SD_TXD_N_OUT(2), + ff_rxiclk_ch2 => ff_rxhalfclk(1), + ff_txiclk_ch2 => ff_txhalfclk, + ff_ebrd_clk_2 => ff_rxhalfclk(1), + ff_txdata_ch2 => tx_data(31 downto 16), + ff_rxdata_ch2 => rx_data(31 downto 16), + ff_tx_k_cntrl_ch2 => tx_k(3 downto 2), + ff_rx_k_cntrl_ch2 => rx_k(3 downto 2), + ff_rxhalfclk_ch2 => ff_rxhalfclk(1), + ff_force_disp_ch2 => "00", + ff_disp_sel_ch2 => "00", + ff_correct_disp_ch2 => "00", + ff_disp_err_ch2 => link_error(1)(9 downto 8), + ff_cv_ch2 => link_error(1)(1 downto 0), + ffc_rrst_ch2 => '0', + ffc_lane_tx_rst_ch2 => lane_rst(1), --lane_rst(2), + ffc_lane_rx_rst_ch2 => lane_rst(1), + ffc_txpwdnb_ch2 => '1', + ffc_rxpwdnb_ch2 => '1', + ffs_rlos_lo_ch2 => link_error(1)(2), + ffs_ls_sync_status_ch2 => link_ok(1), + ffs_cc_underrun_ch2 => link_error(1)(3), + ffs_cc_overrun_ch2 => link_error(1)(4), + ffs_txfbfifo_error_ch2 => link_error(1)(5), + ffs_rxfbfifo_error_ch2 => link_error(1)(6), + ffs_rlol_ch2 => link_error(1)(7), + oob_out_ch2 => open, + + hdinp3 => SD_RXD_P_IN(3), + hdinn3 => SD_RXD_N_IN(3), + hdoutp3 => SD_TXD_P_OUT(3), + hdoutn3 => SD_TXD_N_OUT(3), + ff_rxiclk_ch3 => ff_rxhalfclk(0), + ff_txiclk_ch3 => ff_txhalfclk, + ff_ebrd_clk_3 => ff_rxhalfclk(0), + ff_txdata_ch3 => tx_data(15 downto 0), + ff_rxdata_ch3 => rx_data(15 downto 0), + ff_tx_k_cntrl_ch3 => tx_k(1 downto 0), + ff_rx_k_cntrl_ch3 => rx_k(1 downto 0), + ff_rxhalfclk_ch3 => ff_rxhalfclk(0), + ff_force_disp_ch3 => "00", + ff_disp_sel_ch3 => "00", + ff_correct_disp_ch3 => "00", + ff_disp_err_ch3 => link_error(0)(9 downto 8), + ff_cv_ch3 => link_error(0)(1 downto 0), + ffc_rrst_ch3 => '0', + ffc_lane_tx_rst_ch3 => lane_rst(0), --lane_rst(3), + ffc_lane_rx_rst_ch3 => lane_rst(0), + ffc_txpwdnb_ch3 => '1', + ffc_rxpwdnb_ch3 => '1', + ffs_rlos_lo_ch3 => link_error(0)(2), + ffs_ls_sync_status_ch3 => link_ok(0), + ffs_cc_underrun_ch3 => link_error(0)(3), + ffs_cc_overrun_ch3 => link_error(0)(4), + ffs_txfbfifo_error_ch3 => link_error(0)(5), + ffs_rxfbfifo_error_ch3 => link_error(0)(6), + ffs_rlol_ch3 => link_error(0)(7), + oob_out_ch3 => open, + + ffc_macro_rst => '0', + ffc_quad_rst => quad_rst(0), + ffc_trst => '0', + ff_txhalfclk => ff_txhalfclk, + refck2core => REFCLK2CORE_OUT, + ffs_plol => ffs_plol + ); + end generate; + +------------------------------------------------------------------------- +-- RX Fifo & Data output +------------------------------------------------------------------------- + gen_rx_logic : for i in 0 to 3 generate + THE_FIFO_SFP_TO_FPGA: trb_net_fifo_16bit_bram_dualport + generic map( + USE_STATUS_FLAGS => c_NO + ) + port map( + read_clock_in => SYSCLK, + write_clock_in => ff_rxhalfclk(i), + read_enable_in => fifo_rx_rd_en(i), + write_enable_in => fifo_rx_wr_en(i), + fifo_gsr_in => fifo_rx_reset(i), + write_data_in => fifo_rx_din(18*i+17 downto 18*i), + read_data_out => fifo_rx_dout(18*i+17 downto 18*i), + full_out => fifo_rx_full(i), + empty_out => fifo_rx_empty(i) + ); + + fifo_rx_reset(i) <= RESET; + fifo_rx_rd_en(i) <= '1'; + + -- Received bytes need to be swapped if the SerDes is "off by one" in its internal 8bit path + THE_BYTE_SWAP_PROC: process( ff_rxhalfclk ) + begin + if( rising_edge(ff_rxhalfclk(i)) ) then + last_rx(9*i+8 downto 9*i) <= rx_k(i*2+1) & rx_data(i*16+15 downto i*16+8); + if( swap_bytes(i) = '0' ) then + fifo_rx_din(i*18+17 downto i*18) <= rx_k(i*2+1) & rx_k(i*2) & rx_data(i*16+15 downto i*16+8) + & rx_data(i*16+7 downto i*16); + fifo_rx_wr_en(i) <= not rx_k(i*2) and rx_allow_q(i) and link_ok(i); + else + fifo_rx_din(i*18+17 downto i*18) <= rx_k(i*2+0) & last_rx(i*9+8) & rx_data(i*16+7 downto i*16+0) + & last_rx(i*9+7 downto i*9+0); + fifo_rx_wr_en(i) <= not last_rx(i*9+8) and rx_allow_q(i) and link_ok(i); + end if; + end if; + end process; + + buf_med_data_out(i*16+15 downto i*16) <= fifo_rx_dout(i*18+15 downto i*18); + buf_med_dataready_out(i) <= not fifo_rx_dout(i*18+17) and not fifo_rx_dout(i*18+16) + and not last_fifo_rx_empty(i) and rx_allow(i); + buf_med_packet_num_out(i*3+2 downto i*3) <= rx_counter(i*3+2 downto i*3); + med_read_out(i) <= tx_allow_q(i); + + THE_SYNC_PROC: process( SYSCLK ) + begin + if( rising_edge(SYSCLK) ) then + if RESET = '1' then + med_dataready_out(i) <= '0'; + else + med_dataready_out(i) <= buf_med_dataready_out(i); + med_data_out(i*16+15 downto i*16) <= buf_med_data_out(i*16+15 downto i*16); + med_packet_num_out(i*3+2 downto i*3) <= buf_med_packet_num_out(i*3+2 downto i*3); + end if; + end if; + end process; + + --rx packet counter + --------------------- + THE_RX_PACKETS_PROC: process( SYSCLK ) + begin + if( rising_edge(SYSCLK) ) then + last_fifo_rx_empty(i) <= fifo_rx_empty(i); + if RESET = '1' or rx_allow(i) = '0' then + rx_counter(i*3+2 downto i*3) <= c_H0; + else + if( buf_med_dataready_out(i) = '1' ) then + if( rx_counter(i*3+2 downto i*3) = c_max_word_number ) then + rx_counter(i*3+2 downto i*3) <= (others => '0'); + else + rx_counter(i*3+2 downto i*3) <= rx_counter(i*3+2 downto i*3) + 1; + end if; + end if; + end if; + end if; + end process; + +--TX Fifo & Data output to Serdes +--------------------- + THE_FIFO_FPGA_TO_SFP: trb_net_fifo_16bit_bram_dualport + generic map( + USE_STATUS_FLAGS => c_NO + ) + port map( + read_clock_in => ff_txhalfclk, + write_clock_in => SYSCLK, + read_enable_in => fifo_tx_rd_en(i), + write_enable_in => fifo_tx_wr_en(i), + fifo_gsr_in => fifo_tx_reset(i), + write_data_in => fifo_tx_din(i*18+17 downto i*18), + read_data_out => fifo_tx_dout(i*18+17 downto i*18), + full_out => fifo_tx_full(i), + empty_out => fifo_tx_empty(i) + ); + + fifo_tx_reset(i) <= reset; + fifo_tx_din(i*18+17 downto i*18) <= med_packet_num_in(i*3+2) & med_packet_num_in(i*3+0)& med_data_in(i*16+15 downto i*16); + fifo_tx_wr_en(i) <= med_dataready_in(i) and tx_allow(i); + fifo_tx_rd_en(i) <= tx_allow_q(i); + + + THE_tx_allow_SYNC: signal_sync + generic map( + DEPTH => 2, + WIDTH => 1 + ) + port map( + RESET => RESET, + D_IN(0) => tx_allow(i), + CLK0 => SYSCLK, + CLK1 => ff_txhalfclk, + D_OUT(0) => tx_allow_q(i) + ); + + THE_rx_allow_SYNC: signal_sync + generic map( + DEPTH => 2, + WIDTH => 1 + ) + port map( + RESET => RESET, + D_IN(0) => rx_allow(i), + CLK0 => SYSCLK, + CLK1 => ff_rxhalfclk(i), + D_OUT(0) => rx_allow_q(i) + ); + + THE_SERDES_INPUT_PROC: process( ff_txhalfclk ) + begin + if( rising_edge(ff_txhalfclk) ) then + last_fifo_tx_empty(i) <= fifo_tx_empty(i); + if( (last_fifo_tx_empty(i) = '1') or (tx_allow(i) = '0') ) then + tx_data(i*16+15 downto i*16) <= x"c5bc"; + tx_k(i*2+1 downto i*2) <= "01"; + else + tx_data(i*16+15 downto i*16) <= fifo_tx_dout(i*18+15 downto i*18+0); + tx_k(i*2+1 downto i*2) <= "00"; + end if; + end if; + end process; + + + + +--LED Signals +--------------------- + THE_TX_RX_LED_PROC: process( SYSCLK ) + begin + if( rising_edge(SYSCLK) ) then + led_counter(i) <= led_counter(i) + 1; + if ( buf_med_dataready_out(i) = '1' ) then + rx_led(i) <= '1'; + elsif( led_counter(i) = 0 ) then + rx_led(i) <= '0'; + end if; + if( last_fifo_tx_empty(i) = '0') then + tx_led(i) <= '1'; + elsif led_counter(i) = 0 then + tx_led(i) <= '0'; + end if; + end if; + end process; + + STAT_OP(i*16+9 downto i*16+0) <= FSM_STAT_OP(i*16+9 downto i*16+0); + STAT_OP(i*16+10) <= rx_led(i); + STAT_OP(i*16+11) <= tx_led(i); + STAT_OP(i*16+15 downto i*16+12) <= FSM_STAT_OP(i*16+15 downto i*16+12); + FSM_CTRL_OP(i*16+15 downto i*16+0) <= CTRL_OP(i*16+15 downto i*16+0); + + STAT_DEBUG(i*64+31 downto i*64+0) <= FSM_STAT_DEBUG(i*32+31 downto i*32); + STAT_DEBUG(i*64+47 downto i*64+32) <= rx_data(i*16+15 downto i*16); + STAT_DEBUG(i*64+57 downto i*64+48) <= link_error(i); + STAT_DEBUG(i*64+58) <= ffs_plol; + STAT_DEBUG(i*64+63 downto i*64+59) <= (others => '0'); + + end generate; + +-- fsm_stat_debug(3 downto 0) <= state_bits; +-- fsm_stat_debug(4) <= align_me; +-- fsm_stat_debug(5) <= buf_swap_bytes; +-- fsm_stat_debug(6) <= resync; +-- fsm_stat_debug(7) <= sfp_missing_in; +-- fsm_stat_debug(8) <= sfp_los_in; +-- STAT_DEBUG(i*64+47 downto i*64+32) <= rx_data(i*16+15 downto i*16); +-- ff_cv_ch3 => link_error(0)(1 downto 0), +-- ffs_rlos_lo_ch3 => link_error(0)(2), +-- ffs_cc_underrun_ch3 => link_error(0)(3), +-- ffs_cc_overrun_ch3 => link_error(0)(4), +-- ffs_txfbfifo_error_ch3 => link_error(0)(5), +-- ffs_rxfbfifo_error_ch3 => link_error(0)(6), +-- ffs_rlol_ch3 => link_error(0)(7), +-- ff_disp_err_ch3 => link_error(0)(9 downto 8), + +end architecture; \ No newline at end of file -- 2.43.0