--- /dev/null
+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
--- /dev/null
+--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