--- /dev/null
+--Media interface RX state machine
+
+LIBRARY IEEE;
+USE IEEE.std_logic_1164.ALL;
+USE IEEE.numeric_std.all;
+\r
+library work;
+use work.trb_net_std.all;
+--use work.trb_net_components.all;
+use work.med_sync_define_RS.all;\r
+
+entity main_rx_reset_RS is\r
+ generic(\r
+ SIM_MODE : integer := 0;\r
+ IS_WAP_ZERO : integer := 0;\r
+ IS_MODE : integer := c_IS_SLAVE\r );
+ port(
+ CLEAR : in std_logic; -- async reset, active high
+ LOCALCLK : in std_logic; -- CDR reference clock
+ TX_PLL_LOL_IN : in std_logic; -- TX_PLOL form AUX channel
+ RX_CDR_LOL_IN : in std_logic; -- CDR LOL
+ RX_LOS_LOW_IN : in std_logic; -- RX LOS
+ WA_POSITION_IN : in std_logic_vector(3 downto 0);\r
+ SFP_LOS_IN : in std_logic; -- SFP LOS signal
+ RX_PCS_RST_CH_C_OUT : out std_logic;
+ RX_SERDES_RST_CH_C_OUT : out std_logic;
+ LINK_RX_READY_OUT : out std_logic; -- RX SerDes is fully operational\r
+ MASTER_RESET_OUT : out std_logic; -- can be used as master reset if sourced from Slave port
+ STATE_OUT : out std_logic_vector(3 downto 0)
+ );
+end entity;
+\r
+-- IS_WAP_ZERO could be moved into med_ecpX_sfp_sync...\r
+\r
+architecture main_rx_reset_arch of main_rx_reset_RS is
+\r
+ -- We use two different timing for simulation and real world.
+ -- Using SIM_MODE for implementation will most likely kill the link.\r
+ constant count2_index : integer := 20 - (SIM_MODE * 12); -- 20 for implementation, 8 for simulation
+ constant wap_index : integer := 16 - (SIM_MODE * 8); -- 16 for implementation, 8 for simulation\r
+
+ type statetype is ( WAIT_FOR_PLOL, RX_SERDES_RESET, WAIT_FOR_TIMER1, CHECK_LOL_LOS, WAIT_FOR_TIMER2, CHECK_WAP, NORMAL );
+
+ signal CURRENT_STATE : statetype; -- current state of lsm
+ signal NEXT_STATE : statetype; -- next state of lsm
+
+ signal tx_pll_lol_q : std_logic; -- synced
+ signal rx_cdr_lol_q : std_logic; -- synced
+ signal rx_los_low_q : std_logic; -- synced
+ signal sfp_los_q : std_logic; -- synced
+ signal wa_position_q : std_logic_vector(3 downto 0); -- synced
+ signal rx_lol_los : std_logic;
+ signal rx_lol_los_int : std_logic;
+ signal rx_lol_los_del : std_logic;
+ signal rx_pcs_rst_ch_c_int : std_logic;
+ signal rx_serdes_rst_ch_c_int : std_logic;
+
+ signal reset_timer2 : std_logic;
+ signal counter2 : unsigned(count2_index downto 0);
+ signal timer2 : std_logic;
+
+begin
+\r
+ GEN_WAP_SYNC : if (IS_WAP_ZERO = 1) generate\r
+ -- sync WAP\r
+ SYNC_WAP : entity work.signal_sync
+ generic map(
+ WIDTH => 4,
+ DEPTH => 3
+ )
+ port map(
+ RESET => '0',
+ CLK0 => LOCALCLK,
+ CLK1 => LOCALCLK,
+ D_IN => WA_POSITION_IN,
+ D_OUT => wa_position_q
+ );
+ end generate GEN_WAP_SYNC;\r
+\r
+ GEN_WAP_FIXED: if (IS_WAP_ZERO = 0) generate\r
+ wa_position_q <= x"0";\r
+ end generate GEN_WAP_FIXED;\r
+\r
+ -- sync SerDes signals
+ SYNC_SERDES_SIGS : entity work.signal_sync
+ generic map( \r
+ WIDTH => 4,\r
+ DEPTH => 3\r
+ )
+ port map(
+ RESET => '0',
+ CLK0 => LOCALCLK,
+ CLK1 => LOCALCLK,
+ D_IN(0) => TX_PLL_LOL_IN,
+ D_IN(1) => RX_CDR_LOL_IN,
+ D_IN(2) => RX_LOS_LOW_IN,\r
+ D_IN(3) => SFP_LOS_IN,
+ D_OUT(0) => tx_pll_lol_q,
+ D_OUT(1) => rx_cdr_lol_q,
+ D_OUT(2) => rx_los_low_q,\r
+ D_OUT(3) => sfp_los_q
+ );
+\r
+ MASTER_RESET_OUT <= sfp_los_q when (IS_MODE = c_IS_SLAVE) else '0';\r
+\r
+ rx_lol_los <= rx_cdr_lol_q or rx_los_low_q ;
+
+--timer2 = 400,000 Refclk cycles or 200,000 REFCLKDIV2 cycles
+--A 19 bit counter ([18:0]) counts 524288 cycles, so a 20 bit ([19:0]) counter will do if we set timer2 = bit[19]
+
+ THE_TIMER2_PROC: process( LOCALCLK )
+ begin
+ if( rising_edge(LOCALCLK) ) then
+ if( reset_timer2 = '1' ) then
+ counter2 <= (others => '0');
+ else
+ if( counter2(count2_index) = '0' ) then
+ counter2 <= counter2 + 1 ;
+ end if;
+ end if;
+ end if;
+ end process THE_TIMER2_PROC;
+\r
+ timer2 <= counter2(count2_index);\r
+
+ -- State machine clocked process
+ THE_FSM_PROC: process( LOCALCLK, CLEAR )
+ begin
+ if( CLEAR = '1' ) then
+ CURRENT_STATE <= WAIT_FOR_PLOL;
+ rx_lol_los_int <= '1';
+ rx_lol_los_del <= '1';
+ RX_PCS_RST_CH_C_OUT <= '1';
+ RX_SERDES_RST_CH_C_OUT <= '0';
+ else\r
+ if( rising_edge(LOCALCLK) ) then
+ CURRENT_STATE <= NEXT_STATE;
+ rx_lol_los_del <= rx_lol_los;
+ rx_lol_los_int <= rx_lol_los_del;
+ RX_PCS_RST_CH_C_OUT <= rx_pcs_rst_ch_c_int;
+ RX_SERDES_RST_CH_C_OUT <= rx_serdes_rst_ch_c_int;
+ end if;
+ end if;
+ end process THE_FSM_PROC;
+
+ THE_FSM_DECODE_PROC: process( CURRENT_STATE, tx_pll_lol_q, rx_los_low_q, rx_lol_los_int, timer2, wa_position_q, rx_lol_los_del )
+ begin
+ reset_timer2 <= '0';
+ STATE_OUT <= x"F";
+ LINK_RX_READY_OUT <= '0';
+
+ case CURRENT_STATE is
+ when WAIT_FOR_PLOL =>
+ rx_pcs_rst_ch_c_int <= '1';
+ rx_serdes_rst_ch_c_int <= '0';\r
+ reset_timer2 <= '1';
+ if( (tx_pll_lol_q = '1') or (rx_los_low_q = '1') ) then
+ NEXT_STATE <= WAIT_FOR_PLOL;\r
+ else
+ NEXT_STATE <= RX_SERDES_RESET;
+ end if;
+ STATE_OUT <= x"1";
+
+ when RX_SERDES_RESET =>
+ rx_pcs_rst_ch_c_int <= '1';
+ rx_serdes_rst_ch_c_int <= '1';\r
+ reset_timer2 <= '1';
+ NEXT_STATE <= WAIT_FOR_TIMER1;
+ STATE_OUT <= x"2";
+
+ when WAIT_FOR_TIMER1 =>
+ rx_pcs_rst_ch_c_int <= '1';
+ rx_serdes_rst_ch_c_int <= '1';
+ reset_timer2 <= '1';\r
+ NEXT_STATE <= CHECK_LOL_LOS;
+ STATE_OUT <= x"3";
+
+ when CHECK_LOL_LOS =>
+ rx_pcs_rst_ch_c_int <= '1';
+ rx_serdes_rst_ch_c_int <= '0';
+ reset_timer2 <= '1';
+ NEXT_STATE <= WAIT_FOR_TIMER2;
+ STATE_OUT <= x"4";
+
+ when WAIT_FOR_TIMER2 =>
+ rx_pcs_rst_ch_c_int <= '1';
+ rx_serdes_rst_ch_c_int <= '0';
+ if( (rx_lol_los_int = rx_lol_los_del) ) then --NO RISING OR FALLING EDGES
+ if( timer2 = '1' ) then
+ if( rx_lol_los_int = '1' ) then
+ NEXT_STATE <= WAIT_FOR_PLOL;\r
+ reset_timer2 <= '1';
+ else
+ NEXT_STATE <= CHECK_WAP;
+ reset_timer2 <= '1';
+ end if;
+ else
+ NEXT_STATE <= WAIT_FOR_TIMER2;
+ end if;
+ else
+ NEXT_STATE <= CHECK_LOL_LOS; --RESET timer2\r
+ reset_timer2 <= '1';
+ end if;
+ STATE_OUT <= x"5";
+
+ when CHECK_WAP =>
+ rx_pcs_rst_ch_c_int <= '0';
+ rx_serdes_rst_ch_c_int <= '0';
+ if( std_logic(counter2(wap_index)) = '1' ) then -- may be too long
+ if( wa_position_q /= x"0" ) then
+ NEXT_STATE <= WAIT_FOR_PLOL;\r
+ reset_timer2 <= '1';
+ else
+ NEXT_STATE <= NORMAL;\r
+ reset_timer2 <= '1';
+ end if;
+ else
+ NEXT_STATE <= CHECK_WAP;
+ end if;
+ STATE_OUT <= x"7";
+
+ when NORMAL =>
+ rx_pcs_rst_ch_c_int <= '0';
+ rx_serdes_rst_ch_c_int <= '0';\r
+ reset_timer2 <= '1';
+ if( (rx_lol_los_int = '1') or (wa_position_q /= x"0") ) then
+ NEXT_STATE <= WAIT_FOR_PLOL;
+ else
+ LINK_RX_READY_OUT <= '1';
+ NEXT_STATE <= NORMAL;
+ end if;
+ STATE_OUT <= x"6";
+
+ when others =>
+ NEXT_STATE <= WAIT_FOR_PLOL;\r
+ reset_timer2 <= '1';
+
+ end case;
+
+ end process THE_FSM_DECODE_PROC;
+\r
+end architecture;
--- /dev/null
+--Media interface TX state machine
+
+LIBRARY IEEE;
+USE IEEE.std_logic_1164.ALL;
+USE IEEE.numeric_std.all;
+
+entity main_tx_reset_RS is
+ generic(
+ SIM_MODE : integer := 0
+ );
+ port(
+ CLEAR : in std_logic; -- async reset, active high
+ LOCALCLK : in std_logic; -- usually RX_REFCLK, not TX_REFCLK!
+ TX_PLL_LOL_QD_A_IN : in std_logic; -- QUAD A
+ TX_PLL_LOL_QD_B_IN : in std_logic; -- QUAD B
+ TX_PLL_LOL_QD_C_IN : in std_logic; -- QUAD C
+ TX_PLL_LOL_QD_D_IN : in std_logic; -- QUAD D\r
+ TX_CLOCK_AVAIL_IN : in std_logic; -- recovered RX clock available (if needed)
+ RST_QD_C_OUT : out std_logic; -- full QUAD reset
+ TX_PCS_RST_CH_C_OUT : out std_logic; -- PCS reset\r
+ SYNC_TX_QUAD_OUT : out std_logic; -- sync all QUADs to TX bit 0\r
+ LINK_TX_READY_OUT : out std_logic; -- TX lane can use used now
+ STATE_OUT : out std_logic_vector(3 downto 0)
+ );
+end entity;
+
+architecture main_tx_reset_RS_arch of main_tx_reset_RS is
+\r
+ -- We use two different timing for simulation and real world.\r
+ -- Using SIM_MODE for implementation will most likely kill the link.
+ constant count2_index : integer := 20 - (SIM_MODE * 12); -- end of timer2
+ constant count1_index : integer := 3; -- end of timer1
+
+ type statetype is ( QUAD_RESET, WAIT_FOR_TIMER1, CHECK_PLOL, WAIT_FOR_TIMER2, SYNC_ALL, NORMAL );
+
+ signal CURRENT_STATE : statetype; -- current state of lsm
+ signal NEXT_STATE : statetype; -- next state of lsm
+ \r
+ signal tx_pcs_rst_ch_c_int : std_logic;
+ signal rst_qd_c_int : std_logic;\r
+ signal sync_tx_quad_int : std_logic;
+ signal link_tx_ready_int : std_logic;\r
+ signal sync_tx_quad_trans : std_logic;\r
+ \r
+ signal tx_pll_lol_all : std_logic; -- combinatorial signal\r
+ signal tx_pll_lol_all_q : std_logic; -- synced\r
+ signal tx_clock_avail_q : std_logic; -- synced\r
+ \r
+ signal counter1 : unsigned(count1_index downto 0);
+ signal timer1 : std_logic;
+ signal reset_timer1 : std_logic;
+ \r
+ signal counter2 : unsigned(count2_index downto 0);
+ signal timer2 : std_logic;
+ signal reset_timer2 : std_logic;
+\r
+begin
+\r
+-- all four QUADs need to be ready\r
+ tx_pll_lol_all <= TX_PLL_LOL_QD_A_IN or TX_PLL_LOL_QD_B_IN or\r
+ TX_PLL_LOL_QD_C_IN or TX_PLL_LOL_QD_D_IN;\r
+\r
+-- synchronize, just to be on the safe side
+ SYNC_SFP_SIGS : entity work.signal_sync\r
+ generic map(\r
+ WIDTH => 2,\r
+ DEPTH => 3\r
+ )
+ port map(
+ RESET => '0',
+ CLK0 => LOCALCLK,
+ CLK1 => LOCALCLK,
+ D_IN(0) => tx_pll_lol_all,
+ D_IN(1) => TX_CLOCK_AVAIL_IN,
+ D_OUT(0) => tx_pll_lol_all_q,\r
+ D_OUT(1) => tx_clock_avail_q
+ );
+
+-- TIMER1 = 20ns;
+-- Fastest REFLCK = 312 MHZ, or 3 ns. We need 8 REFCLK cycles.
+-- A 3 bit counter ([2:0]) counts 8 cycles, so a 4 bit ([3:0]) counter will do if we set TIMER1 = bit[3]
+
+-- Timer 1
+ THE_TIMER1_PROC: process( LOCALCLK )
+ begin
+ if( rising_edge(LOCALCLK) ) then
+ if( reset_timer1 = '1' ) then
+ counter1 <= (others => '0');
+ else
+ if( counter1(count1_index) = '0' ) then
+ counter1 <= counter1 + 1 ;
+ end if;
+ end if;
+ end if;
+ end process THE_TIMER1_PROC;
+\r
+ timer1 <= counter1(count1_index);\r
+
+-- TIMER2 = 1,400,000 UI;
+-- WORST CASE CYCLES is with smallest multipier factor.
+-- This would be with X8 clock multiplier in DIV2 mode
+-- IN this casse, 1 UI = 2/8 REFCLK CYCLES.
+-- SO 1,400,000 UI = 1,400,000/4 = 350,000 REFCLKDIV2 CYCLES
+-- A 19 bit counter ([18:0]) counts 524288 cycles, so a 20 bit ([19:0]) counter will do if we set TIMER2 = bit[19]
+
+ THE_TIMER2_PROC: process( LOCALCLK )
+ begin
+ if( rising_edge(LOCALCLK) ) then
+ if( reset_timer2 = '1' ) then
+ counter2 <= (others => '0');
+ else
+ if( counter2(count2_index) = '0' ) then
+ counter2 <= counter2 + 1 ;
+ end if;
+ end if;
+ end if;
+ end process THE_TIMER2_PROC;
+\r
+ timer2 <= counter2(count2_index);\r
+
+-- State machine clocked process
+ THE_FSM_PROC: process( LOCALCLK, CLEAR )
+ begin
+ if( CLEAR = '1' ) then
+ CURRENT_STATE <= QUAD_RESET;
+ TX_PCS_RST_CH_C_OUT <= '1';
+ RST_QD_C_OUT <= '1';\r
+ LINK_TX_READY_OUT <= '0';\r
+ else
+ if( rising_edge(LOCALCLK) ) then
+ CURRENT_STATE <= NEXT_STATE;
+ TX_PCS_RST_CH_C_OUT <= tx_pcs_rst_ch_c_int;
+ RST_QD_C_OUT <= rst_qd_c_int;\r
+ LINK_TX_READY_OUT <= link_tx_ready_int;\r
+ end if;
+ end if;
+ end process THE_FSM_PROC;
+
+ THE_FSM_DECODE_PROC: process( CURRENT_STATE, timer1, timer2, tx_pll_lol_all_q, tx_clock_avail_q )
+ begin
+ reset_timer1 <= '0';
+ reset_timer2 <= '0';
+ rst_qd_c_int <= '0';
+ tx_pcs_rst_ch_c_int <= '0';\r
+ sync_tx_quad_int <= '0';\r
+ link_tx_ready_int <= '0';
+ STATE_OUT <= x"F";
+
+ case CURRENT_STATE is
+
+ when QUAD_RESET =>
+ STATE_OUT <= x"1";
+ tx_pcs_rst_ch_c_int <= '1';
+ rst_qd_c_int <= '1';
+ reset_timer1 <= '1';\r
+ reset_timer2 <= '1';
+ NEXT_STATE <= WAIT_FOR_TIMER1;
+
+ when WAIT_FOR_TIMER1 =>
+ STATE_OUT <= x"2";
+ tx_pcs_rst_ch_c_int <= '1';
+ rst_qd_c_int <= '1';\r
+ reset_timer2 <= '1';
+ if( timer1 = '1' ) then
+ NEXT_STATE <= CHECK_PLOL;
+ else
+ NEXT_STATE <= WAIT_FOR_TIMER1;
+ end if;
+
+ when CHECK_PLOL =>
+ STATE_OUT <= x"3";
+ tx_pcs_rst_ch_c_int <= '1';\r
+ reset_timer1 <= '1';
+ reset_timer2 <= '1';
+ NEXT_STATE <= WAIT_FOR_TIMER2;
+
+ when WAIT_FOR_TIMER2 =>
+ STATE_OUT <= x"4";\r
+ reset_timer1 <= '1';
+ tx_pcs_rst_ch_c_int <= '1';
+ if( timer2 = '1' ) then
+ if( (tx_pll_lol_all_q = '1') or (tx_clock_avail_q = '0') ) then
+ NEXT_STATE <= QUAD_RESET;
+ else
+ NEXT_STATE <= SYNC_ALL;
+ sync_tx_quad_int <= '1';
+ end if;
+ else
+ NEXT_STATE <= WAIT_FOR_TIMER2;
+ end if;
+\r
+ when SYNC_ALL =>
+ STATE_OUT <= x"5";\r
+ reset_timer2 <= '1';
+ if( timer1 = '1' ) then
+ NEXT_STATE <= NORMAL;
+ else
+ NEXT_STATE <= SYNC_ALL;\r
+ end if;
+
+ when NORMAL =>
+ STATE_OUT <= x"6";
+ tx_pcs_rst_ch_c_int <= '0';\r
+ link_tx_ready_int <= '1';\r
+ reset_timer1 <= '1';\r
+ reset_timer2 <= '1';
+ if( (tx_pll_lol_all_q = '1') or (tx_clock_avail_q = '0') ) then
+ NEXT_STATE <= QUAD_RESET;
+ else
+ NEXT_STATE <= NORMAL;
+ end if;
+
+ when others =>\r
+ STATE_OUT <= x"f";
+ NEXT_STATE <= QUAD_RESET;
+
+ end case;
+
+ end process THE_FSM_DECODE_PROC;
+\r
+ -- TX serializer is operational "at level" of this signal, \r
+ -- and gets reset by a transition (according to SerDes Usage Guide).\r
+ -- Timer1 is used to delay the TX link ready signal by some cycles.\r
+ THE_QUAD_SYNC_PROC: process( LOCALCLK, CLEAR )
+ begin
+ if( CLEAR = '1' ) then\r
+ sync_tx_quad_trans <= '0';
+ else
+ if( rising_edge(LOCALCLK) ) then\r
+ if( sync_tx_quad_int = '1' ) then\r
+ sync_tx_quad_trans <= not sync_tx_quad_trans;\r
+ end if;
+ end if;
+ end if;
+ end process THE_QUAD_SYNC_PROC;
+\r
+ SYNC_TX_QUAD_OUT <= sync_tx_quad_trans;\r
+\r
+end architecture;
library work;
use work.trb_net_std.all;
-use work.trb_net_components.all;
-use work.med_sync_define.all;
-
--- IS_SYNC_SLAVE: basically "master" port
+--use work.trb_net_components.all;\r
+use work.med_sync_define_RS.all;
entity med_sync_control_RS is
- generic(
- IS_WAP_ZERO : integer := 0;
+ generic(\r
+ SIM_MODE : integer := 0; -- 0 for simulation, 1 for implementation
+ IS_WAP_ZERO : integer := 1; -- should be 1 for synchronous operation
IS_MODE : integer := c_IS_UNUSED
);
- port(
- CLK_SYS : in std_logic; -- 100MHz system clock
- CLK_RXI : in std_logic; -- recovered RX clock, 200MHz
+ port(\r
+ -- clocks and resets
+ CLK_SYS : in std_logic; -- FPGA fabric system clock
+ CLK_RXI : in std_logic; -- recovered RX clock, from SerDes RX channel
CLK_RXHALF : in std_logic; -- used for media interface
- CLK_TXI : in std_logic; -- TX clock, 200MHz
- CLK_REF : in std_logic; -- 200MHz local clock
+ CLK_TXI : in std_logic; -- TX clock, from SerDes TX channel
+ CLK_REF : in std_logic; -- SerDes reference clock
RESET : in std_logic;
- CLEAR : in std_logic;
-
- SFP_LOS : in std_logic;
- TX_LOL : in std_logic;
- RX_CDR_LOL : in std_logic;
- RX_LOS : in std_logic;
- WA_POSITION : in std_logic_vector(3 downto 0);
-
- WORD_SYNC_IN : in std_logic; -- for isochronous operation
- WORD_SYNC_OUT : out std_logic; -- for isochronous operation
-
- RX_SERDES_RST : out std_logic;
- RX_PCS_RST : out std_logic;
- QUAD_RST : out std_logic;
- TX_PCS_RST : out std_logic;
-
- MEDIA_MED2INT : out MED2INT;
- MEDIA_INT2MED : in INT2MED;
-
- TX_DATA : out std_logic_vector(7 downto 0);
- TX_K : out std_logic;
- TX_CD : out std_logic;
- RX_DATA : in std_logic_vector(7 downto 0);
- RX_K : in std_logic;
-
- TX_DLM_WORD : in std_logic_vector(7 downto 0);
- TX_DLM : in std_logic;
- RX_DLM_WORD : out std_logic_vector(7 downto 0);
- RX_DLM : out std_logic;
-
- SERDES_RX_READY_IN : in std_logic;
- SERDES_TX_READY_IN : in std_logic;
-
+ CLEAR : in std_logic;\r
+ -- Media Interface\r
+ MEDIA_MED2INT : out MED2INT; -- Media Interface IN
+ MEDIA_INT2MED : in INT2MED; -- Media Interface OUT\r
+ -- status signals from SerDes
+ SFP_LOS_IN : in std_logic; -- SFP Loss Of Signal
+ RX_CDR_LOL_IN : in std_logic; -- SerDes RX CDR status
+ RX_LOS_IN : in std_logic; -- SerDes RX input signal status
+ WA_POSITION_IN : in std_logic_vector(3 downto 0); -- WordAlignment Position\r
+ LINK_TX_READY_IN : in std_logic;\r
+ -- control signals to SerDes\r
+ RX_SERDES_RST : out std_logic; -- reset RX (SerDes + CDR)
+ RX_PCS_RST : out std_logic; -- reset RX (PCS)\r
+ -- SerDes data streams
+ TX_DATA_OUT : out std_logic_vector(7 downto 0); -- data to TX SerDes
+ TX_K_OUT : out std_logic; -- komma designator to TS SerDes
+ RX_DATA_IN : in std_logic_vector(7 downto 0); -- data from RX SerDes
+ RX_K_IN : in std_logic; -- komma designator from RX SerDes\r
+ -- ports for synchronous operation\r
+ WORD_SYNC_IN : in std_logic; -- sync signal for Byte/Word Alignment
+ WORD_SYNC_OUT : out std_logic;
+ TX_DLM_IN : in std_logic; -- transmit one DLM komma
+ TX_DLM_WORD_IN : in std_logic_vector(7 downto 0);
+ TX_RST_IN : in std_logic; -- transmit one RST komma
+ TX_RST_WORD_IN : in std_logic_vector(7 downto 0);
+ RX_DLM_OUT : out std_logic; -- one DLM komma received
+ RX_DLM_WORD_OUT : out std_logic_vector(7 downto 0);
+ RX_RST_OUT : out std_logic; -- one RST komma received
+ RX_RST_WORD_OUT : out std_logic_vector(7 downto 0);
+ MASTER_RESET_OUT : out std_logic; -- master reset for FPGA\r
+ TX_RESET_OUT : out std_logic; -- reset main TX reset FSM\r
+ -- Status and debug signals
STAT_TX_CONTROL : out std_logic_vector(31 downto 0);
STAT_RX_CONTROL : out std_logic_vector(31 downto 0);
DEBUG_TX_CONTROL : out std_logic_vector(31 downto 0);
architecture med_sync_control_arch of med_sync_control_RS is
signal rx_fsm_state : std_logic_vector(3 downto 0);
- signal tx_fsm_state : std_logic_vector(3 downto 0);
- signal wa_position_rx : std_logic_vector(3 downto 0);
- signal start_timer : unsigned(21 downto 0) := (others => '0');
-
- signal request_retr_i : std_logic;
- signal start_retr_i : std_logic;
- signal request_retr_position_i : std_logic_vector(7 downto 0);
- signal start_retr_position_i : std_logic_vector(7 downto 0);
- signal rx_dlm_i : std_logic;
signal led_ok : std_logic;
- signal led_dlm, last_led_dlm : std_logic;
signal led_rx, last_led_rx : std_logic;
signal led_tx, last_led_tx : std_logic;
signal timer : unsigned(20 downto 0);
- signal sd_los_i : std_logic;
-
- signal rx_allow : std_logic;
- signal tx_allow : std_logic;
- signal got_link_ready_i : std_logic;
+ signal sd_los_qsys : std_logic;
signal reset_i : std_logic;
- signal rst_n : std_logic;
- signal rst_n_tx : std_logic;
- signal finished_reset_rx : std_logic;
- signal finished_reset_rx_q : std_logic;
- signal finished_reset_tx : std_logic;
- signal finished_reset_tx_q : std_logic;
+ signal reset_rx_fsm_i : std_logic;
+ signal link_rx_ready_i : std_logic;
+ signal link_rx_ready_qsys : std_logic;
+ signal link_half_done_i : std_logic;
+ signal link_full_done_i : std_logic;
signal media_med2int_i : MED2INT;
signal rx_serdes_rst_i : std_logic;
signal rx_pcs_rst_i : std_logic;
- signal rx_serdes_rst_i_q : std_logic_vector(2 downto 0);
- signal rx_pcs_rst_i_q : std_logic_vector(2 downto 0);
-
- signal tx_pcs_rst_i : std_logic;
- signal quad_rst_i : std_logic;
-
- signal wap_is_zero_i : std_logic;
- signal rx_reset_finished_i : std_logic;
- signal tx_k_i : std_logic;
-
- signal debug_tx_control_i : std_logic_vector(31 downto 0);
--- signal debug_rx_control_i : std_logic_vector(31 downto 0);
-
begin
+-------------------------------------------------
+-- Reset signals
+-------------------------------------------------
-- synchronize SFP LOS signal
- sd_los_i <= SFP_LOS when rising_edge(CLK_SYS);
+ SYNC_SFP_SIGS : entity work.signal_sync
+ generic map(
+ WIDTH => 1,
+ DEPTH => 3
+ )
+ port map(
+ RESET => '0',
+ CLK0 => CLK_SYS,
+ CLK1 => CLK_SYS,
+ D_IN(0) => SFP_LOS_IN,
+ D_OUT(0) => sd_los_qsys
+ );\r
--- TX_RESET_FSM reset
- --rst_n_tx <= not (CLEAR or sd_los_i or RESET) when (IS_SYNC_SLAVE = 1 and IS_TX_RESET = 1)
- -- else not (CLEAR or RESET);
- rst_n_tx <= not (CLEAR or sd_los_i or RESET) when (IS_MODE = c_IS_SLAVE)
- else not (CLEAR or RESET);
+-- keep central TX reset FSM idle while no clock is present
+ TX_RESET_OUT <= (CLEAR or RESET or not link_rx_ready_i) when (IS_MODE = c_IS_SLAVE)
+ else (CLEAR or RESET);
-- RX_RESET_FSM reset
- rst_n <= not (CLEAR or sd_los_i or RESET);
+ reset_rx_fsm_i <= (CLEAR or RESET or sd_los_qsys);
-- TX_CONTROL and RX_CONTROL reset
- reset_i <= (RESET or sd_los_i);
-
--- clocks for media interface
- media_med2int_i.clk_half <= CLK_RXHALF;
- media_med2int_i.clk_full <= CLK_RXI;
+ reset_i <= (RESET or sd_los_qsys);
--------------------------------------------------
+-------------------------------------------------
-- Reset RX FSM
--------------------------------------------------
- THE_RX_FSM : rx_reset_fsm_RS
+-------------------------------------------------
+ THE_RX_RST_FSM: main_rx_reset_RS -- OK
+ generic map(
+ SIM_MODE => SIM_MODE,\r
+ IS_WAP_ZERO => IS_WAP_ZERO,\r
+ IS_MODE => IS_MODE
+ )
port map(
- RST_N => rst_n,
- RX_REFCLK => CLK_REF,
- TX_PLL_LOL_QD_S => '0', --TX_LOL, -- we don't use this one
- RX_CDR_LOL_CH_S => RX_CDR_LOL,
- RX_LOS_LOW_CH_S => RX_LOS,
- RX_PCS_RST_CH_C => rx_pcs_rst_i,
- RX_SERDES_RST_CH_C => rx_serdes_rst_i,
- WA_POSITION => wa_position_rx,
- NORMAL_OPERATION_OUT => finished_reset_rx,
- STATE_OUT => rx_fsm_state
+ CLEAR => reset_rx_fsm_i,\r
+ LOCALCLK => CLK_REF,\r
+ TX_PLL_LOL_IN => '0', -- TX and RX channel are independent\r
+ RX_CDR_LOL_IN => RX_CDR_LOL_IN, -- internally synced\r
+ RX_LOS_LOW_IN => RX_LOS_IN, -- internally synced\r
+ WA_POSITION_IN => WA_POSITION_IN, -- internally synced\r
+ SFP_LOS_IN => SFP_LOS_IN, -- internally synced\r
+ RX_PCS_RST_CH_C_OUT => rx_pcs_rst_i,\r
+ RX_SERDES_RST_CH_C_OUT => rx_serdes_rst_i,\r
+ LINK_RX_READY_OUT => link_rx_ready_i,\r
+ MASTER_RESET_OUT => MASTER_RESET_OUT, -- not necessary???\r
+ STATE_OUT => rx_fsm_state
);
-
--- crossing the abbyss
- THE_ABBYSS_PROC: process( CLK_RXI )
- begin
- if( rising_edge(CLK_RXI) ) then
- rx_serdes_rst_i_q <= rx_serdes_rst_i_q(1 downto 0) & rx_serdes_rst_i;
- rx_pcs_rst_i_q <= rx_pcs_rst_i_q(1 downto 0) & rx_pcs_rst_i;
- end if;
- end process THE_ABBYSS_PROC;
-
--- Reset signals must be syncronous to CLK_RXI
- RX_SERDES_RST <= rx_serdes_rst_i_q(2);
- RX_PCS_RST <= rx_pcs_rst_i_q(2);
-
--- sync WAP to CLK_REF, the SCI reader usually runs on CLK_SYS!
- SYNC_WA_POSITION_PROC: process( CLK_REF )
- begin
- if( rising_edge(CLK_REF) ) then
- if IS_WAP_ZERO = 1 then
- wa_position_rx <= WA_POSITION;
- else
- wa_position_rx <= x"0";
- end if;
- end if;
- end process SYNC_WA_POSITION_PROC;
-
- rx_reset_finished_i <= finished_reset_rx when (IS_MODE = c_IS_SLAVE) else '1';
-
--------------------------------------------------
--- Reset TX FSM
--------------------------------------------------
- THE_TX_FSM: tx_reset_fsm_RS
+\r
+-- reset signals for RX SerDes need to be sync'ed to real RX clock
+ SYNC_RST_SIGS: entity work.signal_sync
+ generic map( WIDTH => 2 )
port map(
- RST_N => rst_n_tx,
- TX_REFCLK => CLK_REF,
- TX_PLL_LOL_QD_S => TX_LOL,
- RX_RESET_FINISHED_IN => rx_reset_finished_i,
- RST_QD_C => quad_rst_i,
- TX_PCS_RST_CH_C => tx_pcs_rst_i,
- NORMAL_OPERATION_OUT => finished_reset_tx,
- STATE_OUT => tx_fsm_state
+ RESET => '0',
+ CLK0 => CLK_RXI,
+ CLK1 => CLK_RXI,
+ D_IN(0) => rx_pcs_rst_i,
+ D_IN(1) => rx_serdes_rst_i,
+ D_OUT(0) => RX_PCS_RST,
+ D_OUT(1) => RX_SERDES_RST
);
-
--- may also need sync?
- TX_PCS_RST <= tx_pcs_rst_i;
- QUAD_RST <= quad_rst_i;
-
+\r
-------------------------------------------------
--- RX & TX allow
--------------------------------------------------
--- Slave enables RX/TX when sync is done, Master waits additional time to make sure link is stable
- PROC_ALLOW: process begin
- wait until rising_edge(CLK_SYS);
- if( (finished_reset_rx_q = '1')
- and ((IS_MODE = c_IS_MASTER) or (start_timer(start_timer'left) = '1')) ) then
- rx_allow <= '1';
- else
- rx_allow <= '0';
- end if;
- if( (finished_reset_tx_q = '1' and finished_reset_rx_q = '1')
- and ((IS_MODE = c_IS_MASTER) or (start_timer(start_timer'left) = '1')) ) then
- tx_allow <= '1';
- else
- tx_allow <= '0';
- end if;
- end process PROC_ALLOW;
-
- LINK_RESET_FIN_TX: signal_sync
+-- RX Data
+-------------------------------------------------
+ THE_RX_CONTROL : rx_control_RS
+ generic map(
+ SIM_MODE => SIM_MODE
+ )
port map(
- RESET => '0',
- CLK0 => CLK_SYS,
- CLK1 => CLK_SYS,
- D_IN(0) => finished_reset_tx,
- D_OUT(0) => finished_reset_tx_q
- );
-
- LINK_RESET_FIN_RX: signal_sync
+ CLK_RXI => CLK_RXI,
+ CLK_SYS => CLK_SYS,
+ RESET => reset_i,
+\r
+ RX_DATA_OUT => media_med2int_i.data,
+ RX_PACKET_NUMBER_OUT => media_med2int_i.packet_num,
+ RX_WRITE_OUT => media_med2int_i.dataready,
+\r
+ RX_DATA_IN => RX_DATA_IN,
+ RX_K_IN => RX_K_IN,
+
+ WORD_SYNC_OUT => WORD_SYNC_OUT,
+\r
+ RX_DLM_OUT => RX_DLM_OUT,
+ RX_DLM_WORD_OUT => RX_DLM_WORD_OUT,
+
+ RX_RST_OUT => RX_RST_OUT,
+ RX_RST_WORD_OUT => RX_RST_WORD_OUT,
+\r
+ LINK_RX_READY_IN => link_rx_ready_i,\r
+ LINK_TX_READY_IN => LINK_TX_READY_IN,
+ LINK_HALF_DONE_IN => link_half_done_i,\r
+ LINK_FULL_DONE_IN => link_full_done_i,
+\r
+ DEBUG_OUT => DEBUG_RX_CONTROL,
+ STAT_REG_OUT => STAT_RX_CONTROL
+ );
+\r
+ THE_RX_LSM: rx_lsm_RS
port map(
- RESET => '0',
- CLK0 => CLK_SYS,
- CLK1 => CLK_SYS,
- D_IN(0) => finished_reset_rx,
- D_OUT(0) => finished_reset_rx_q
+ LINK_RX_READY_IN => link_rx_ready_i,\r
+ RXCLK => CLK_RXI,\r
+ RX_K_IN => RX_K_IN,\r
+ RX_DATA_IN => RX_DATA_IN,\r
+ LINK_HALF_DONE_OUT => link_half_done_i,\r
+ LINK_FULL_DONE_OUT => link_full_done_i,\r
+ STATE_OUT => open
);
+\r
+-- clocks for media interface
+ media_med2int_i.clk_half <= CLK_RXHALF;
+ media_med2int_i.clk_full <= CLK_RXI;
- START_TIMER_PROC: process( CLK_SYS )
- begin
- if( rising_edge(CLK_SYS) ) then
--- if( (finished_reset_tx_q = '1') and (finished_reset_rx_q = '1') ) then
--- if( (finished_reset_tx_q = '1') and (finished_reset_rx_q = '1') and (got_link_ready_i = '1' or IS_SYNC_SLAVE = 1) ) then
- if( (finished_reset_tx_q = '1') and (finished_reset_rx_q = '1') and (got_link_ready_i = '1' or IS_MODE = c_IS_SLAVE) ) then
- if start_timer(start_timer'left) = '0' then
- start_timer <= start_timer + 1;
- end if;
- else
- start_timer <= (others => '0');
- end if;
- end if;
- end process START_TIMER_PROC;
-
-------------------------------------------------
-- TX Data
-------------------------------------------------
- THE_TX : tx_control_RS
+\r
+ THE_TX_CONTROL: tx_control_RS
+ generic map(
+ SIM_MODE => SIM_MODE,\r
+ IS_MODE => IS_MODE\r
+ )
port map(
- CLK_200 => CLK_TXI,
- CLK_100 => CLK_SYS,
- RESET_IN => reset_i,
-
- WORD_SYNC_IN => WORD_SYNC_IN,
-
- TX_DATA_IN => MEDIA_INT2MED.data,
- TX_PACKET_NUMBER_IN => MEDIA_INT2MED.packet_num,
- TX_WRITE_IN => MEDIA_INT2MED.dataready,
- TX_READ_OUT => media_med2int_i.tx_read,
-
- TX_DATA_OUT => TX_DATA,
- TX_K_OUT => tx_k_i, --TX_K,
- TX_CD_OUT => TX_CD,
-
- SEND_DLM => TX_DLM,
- SEND_DLM_WORD => TX_DLM_WORD,
-
- TX_ALLOW_IN => tx_allow,
- RX_ALLOW_IN => rx_allow,
-
- DEBUG_OUT => debug_tx_control_i, --DEBUG_TX_CONTROL,
- STAT_REG_OUT => STAT_TX_CONTROL
- );
-
- TX_K <= tx_k_i;
-
--------------------------------------------------
--- RX Data
--------------------------------------------------
- THE_RX_CONTROL : rx_control_RS
- port map(
- CLK_200 => CLK_RXI,
- CLK_100 => CLK_SYS,
- RESET_IN => reset_i,
-
- WORD_SYNC_OUT => WORD_SYNC_OUT,
-
- RX_DATA_OUT => media_med2int_i.data,
- RX_PACKET_NUMBER_OUT => media_med2int_i.packet_num,
- RX_WRITE_OUT => media_med2int_i.dataready,
-
- RX_DATA_IN => RX_DATA,
- RX_K_IN => RX_K,
-
- RX_DLM => rx_dlm_i,
- RX_DLM_WORD => RX_DLM_WORD,
-
- RX_ALLOW_IN => rx_allow,
- RX_RESET_FINISHED => finished_reset_rx,
- GOT_LINK_READY => got_link_ready_i,
-
- DEBUG_OUT => DEBUG_RX_CONTROL,
- STAT_REG_OUT => STAT_RX_CONTROL
- );
+ CLK_TX => CLK_TXI,
+ CLK_SYS => CLK_SYS,
+ RESET => reset_i,\r
+ -- Media Interface
+ TX_DATA_IN => MEDIA_INT2MED.data,
+ TX_PACKET_NUMBER_IN => MEDIA_INT2MED.packet_num,
+ TX_WRITE_IN => MEDIA_INT2MED.dataready,
+ TX_READ_OUT => media_med2int_i.tx_read,
+ -- SerDes data stream
+ TX_DATA_OUT => TX_DATA_OUT,\r
+ TX_K_OUT => TX_K_OUT,
+ -- synchronous signals
+ WORD_SYNC_IN => WORD_SYNC_IN,\r
+ SEND_DLM_IN => TX_DLM_IN,
+ SEND_DLM_WORD_IN => TX_DLM_WORD_IN,\r
+ SEND_RST_IN => TX_RST_IN,
+ SEND_RST_WORD_IN => TX_RST_WORD_IN,\r
+ -- link status signals, internally synced
+ LINK_TX_READY_IN => LINK_TX_READY_IN,\r
+ LINK_RX_READY_IN => link_rx_ready_i,
+ LINK_HALF_DONE_IN => link_half_done_i,\r
+ LINK_FULL_DONE_IN => link_full_done_i,
+ -- debug
+ DEBUG_OUT => DEBUG_TX_CONTROL,
+ STAT_REG_OUT => STAT_TX_CONTROL
+ );
- RX_DLM <= rx_dlm_i;
MEDIA_MED2INT <= media_med2int_i;
-------------------------------------------------
-- Generate LED signals
-------------------------------------------------
- led_ok <= rx_allow and tx_allow when rising_edge(CLK_SYS);
+ led_ok <= link_full_done_i when rising_edge(CLK_SYS);
led_rx <= (media_med2int_i.dataready or led_rx) and not timer(20) when rising_edge(CLK_SYS);
- led_tx <= (MEDIA_INT2MED.dataready or led_tx or sd_los_i) and not timer(20) when rising_edge(CLK_SYS);
- led_dlm <= (led_dlm or rx_dlm_i) and not timer(20) when rising_edge(CLK_SYS);
+ led_tx <= (MEDIA_INT2MED.dataready or led_tx or sd_los_qsys) and not timer(20) when rising_edge(CLK_SYS);
- ROC_TIMER_PROC: process( CLK_SYS )
- begin
- if( rising_edge(CLK_SYS) ) then
+ ROC_TIMER_PROC: process( CLK_SYS, RESET )
+ begin\r
+ if ( RESET = '1' ) then\r
+ timer <= (others => '0');
+ elsif( rising_edge(CLK_SYS) ) then
timer <= timer + 1 ;
if timer(20) = '1' then
timer <= (others => '0');
last_led_rx <= led_rx ;
last_led_tx <= led_tx;
- last_led_dlm <= led_dlm;
end if;
end if;
end process ROC_TIMER_PROC;
-- Status signals
-------------------------------------------------
STAT_RESET(3 downto 0) <= rx_fsm_state;
- STAT_RESET(7 downto 4) <= tx_fsm_state;
- STAT_RESET(8) <= tx_allow;
- STAT_RESET(9) <= rx_allow;
- STAT_RESET(15 downto 10) <= (others => '0');
- STAT_RESET(16) <= RX_CDR_LOL;
- STAT_RESET(17) <= RX_LOS;
- STAT_RESET(18) <= '0';
- STAT_RESET(19) <= '0';
- STAT_RESET(20) <= TX_LOL;
- STAT_RESET(21) <= rst_n;
- STAT_RESET(22) <= rst_n_tx;
- STAT_RESET(30 downto 23) <= (others => '0');
- STAT_RESET(31) <= start_timer(start_timer'left);
+ STAT_RESET(31 downto 4) <= (others => '0');
media_med2int_i.stat_op(15) <= '0';
media_med2int_i.stat_op(14) <= '0';
media_med2int_i.stat_op(13) <= '0'; --make trbnet reset
- media_med2int_i.stat_op(12) <= led_dlm when rising_edge(CLK_SYS); -- or last_led_dlm;
- media_med2int_i.stat_op(11) <= led_tx; -- or last_led_tx;
+ media_med2int_i.stat_op(12) <= '0';
+ media_med2int_i.stat_op(11) <= led_tx;
media_med2int_i.stat_op(10) <= led_rx or last_led_rx;
- media_med2int_i.stat_op(9) <= tx_allow; --led_ok
+ media_med2int_i.stat_op(9) <= '0'; --led_ok
media_med2int_i.stat_op(8 downto 5) <= (others => '0');
- media_med2int_i.stat_op(4) <= rx_allow;
- media_med2int_i.stat_op(3 downto 0) <= x"0" when rx_allow = '1' and tx_allow = '1' else x"7";
-
- wap_is_zero_i <= '1' when WA_POSITION = x"0" else '0';
-
--- TEST_LINE signals
- DEBUG_OUT(0) <= TX_LOL;
- DEBUG_OUT(1) <= RX_CDR_LOL;
- DEBUG_OUT(2) <= RX_LOS;
- DEBUG_OUT(3) <= rst_n;
- DEBUG_OUT(4) <= rst_n_tx;
- DEBUG_OUT(5) <= quad_rst_i;
- DEBUG_OUT(6) <= rx_pcs_rst_i;
- DEBUG_OUT(7) <= tx_pcs_rst_i;
- DEBUG_OUT(8) <= rx_serdes_rst_i;
- DEBUG_OUT(9) <= finished_reset_rx;
- DEBUG_OUT(10) <= finished_reset_tx;
- DEBUG_OUT(11) <= '0';
- DEBUG_OUT(12) <= '0';
- DEBUG_OUT(13) <= got_link_ready_i;
- DEBUG_OUT(14) <= rx_allow;
- DEBUG_OUT(15) <= tx_allow;
- DEBUG_OUT(25 downto 16) <= (others => '0');
- DEBUG_OUT(26) <= wap_is_zero_i;
- DEBUG_OUT(27) <= rx_dlm_i;
- DEBUG_OUT(28) <= debug_tx_control_i(29); -- send_reset
- DEBUG_OUT(29) <= got_link_ready_i; --tx_k_i;
- DEBUG_OUT(30) <= debug_tx_control_i(30); -- send_dlm_i
- DEBUG_OUT(31) <= debug_tx_control_i(31); -- sending_dlm
-
- DEBUG_TX_CONTROL <= debug_tx_control_i;
+ media_med2int_i.stat_op(4) <= '0';
+ media_med2int_i.stat_op(3 downto 0) <= x"0" when link_half_done_i = '1' and link_full_done_i = '1' else x"7";
+
+-- TEST_LINE signals\r
+ DEBUG_OUT(0) <= link_rx_ready_i;\r
+ DEBUG_OUT(1) <= link_half_done_i;\r
+ DEBUG_OUT(2) <= link_full_done_i;\r
+ \r
+ DEBUG_OUT(31 downto 3) <= (others => '0');
+-- DEBUG_OUT <= (others => '0');
end architecture;
use work.trb_net_std.all;
-package med_sync_define is
-
-constant K_IDLE : std_logic_vector(7 downto 0) := x"BC";
-constant D_IDLE0 : std_logic_vector(7 downto 0) := x"C5";
-constant D_IDLE1 : std_logic_vector(7 downto 0) := x"50";
-constant K_SOP : std_logic_vector(7 downto 0) := x"FB"; -- not used
-constant K_EOP : std_logic_vector(7 downto 0) := x"FD"; -- not used
-constant K_BGN : std_logic_vector(7 downto 0) := x"1C"; -- not used
-constant K_REQ : std_logic_vector(7 downto 0) := x"7C"; -- not used
-constant K_RST : std_logic_vector(7 downto 0) := x"FE"; -- will be extended
-constant K_DLM : std_logic_vector(7 downto 0) := x"DC"; -- will be used :)
+package med_sync_define_RS is
+\r
+-- These idles are available\r
+constant K_BGN : std_logic_vector(7 downto 0) := x"1c"; -- K28.0 -- reserved for retransmission\r
+constant K_28_1 : std_logic_vector(7 downto 0) := x"3c"; -- K28.1\r
+constant K_28_2 : std_logic_vector(7 downto 0) := x"5c"; -- K28.2\r
+constant K_REQ : std_logic_vector(7 downto 0) := x"7c"; -- K28.3 -- reserved for transmission\r
+constant K_28_4 : std_logic_vector(7 downto 0) := x"9c"; -- K28.4\r
+constant K_IDLE : std_logic_vector(7 downto 0) := x"bc"; -- K28.5 -- used for link idle and establishment\r
+constant K_DLM : std_logic_vector(7 downto 0) := x"dc"; -- K28.6 -- used for link delay measurement\r
+constant K_28_7 : std_logic_vector(7 downto 0) := x"fc"; -- K28.7\r
+constant K_NULL : std_logic_vector(7 downto 0) := x"f7"; -- K23.7 -- used for "SerDes in reset"\r
+constant K_SOP : std_logic_vector(7 downto 0) := x"fb"; -- K27.7 -- reserved for packet handling\r
+constant K_EOP : std_logic_vector(7 downto 0) := x"fd"; -- K29.7 -- reserved for packet handling\r
+constant K_RST : std_logic_vector(7 downto 0) := x"fe"; -- K30.7 -- used for reset \r
+\r
+-- data char for idle\r
+constant D_IDLE0 : std_logic_vector(7 downto 0) := x"C5"; -- D5.6
+constant D_IDLE1 : std_logic_vector(7 downto 0) := x"50"; -- D16.2
+
+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_ecp3_fifo_18x16_dualport_oreg
+ port(
+ Data : in std_logic_vector(17 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(17 downto 0);
+ Empty : out std_logic;
+ Full : out std_logic;
+ AlmostFull : out std_logic
+ );
+end component;
+\r
+component main_rx_reset_RS is
+ generic(
+ SIM_MODE : integer := 0;
+ IS_WAP_ZERO : integer := 0;
+ IS_MODE : integer := c_IS_SLAVE\r
+ );
+ port(
+ CLEAR : in std_logic; -- async reset, active high
+ LOCALCLK : in std_logic; -- CDR reference clock
+ TX_PLL_LOL_IN : in std_logic; -- TX_PLOL form AUX channel
+ RX_CDR_LOL_IN : in std_logic; -- CDR LOL
+ RX_LOS_LOW_IN : in std_logic; -- RX LOS
+ WA_POSITION_IN : in std_logic_vector(3 downto 0);
+ SFP_LOS_IN : in std_logic; -- SFP LOS signal
+ RX_PCS_RST_CH_C_OUT : out std_logic;
+ RX_SERDES_RST_CH_C_OUT : out std_logic;
+ LINK_RX_READY_OUT : out std_logic; -- RX SerDes is fully operational
+ MASTER_RESET_OUT : out std_logic; -- can be used as master reset if sourced from Slave port
+ STATE_OUT : out std_logic_vector(3 downto 0)
+ );
+end component;\r
+\r
+component main_tx_reset_RS is
+ generic(
+ SIM_MODE : integer := 0
+ );
+ port(
+ CLEAR : in std_logic; -- async reset
+ LOCALCLK : in std_logic; -- usually RX_REFCLK, not TX_REFCLK!
+ TX_PLL_LOL_QD_A_IN : in std_logic; -- QUAD A
+ TX_PLL_LOL_QD_B_IN : in std_logic; -- QUAD B
+ TX_PLL_LOL_QD_C_IN : in std_logic; -- QUAD C
+ TX_PLL_LOL_QD_D_IN : in std_logic; -- QUAD D
+ TX_CLOCK_AVAIL_IN : in std_logic; -- recovered RX clock available (if needed)
+ RST_QD_C_OUT : out std_logic; -- full QUAD reset
+ TX_PCS_RST_CH_C_OUT : out std_logic; -- PCS reset
+ SYNC_TX_QUAD_OUT : out std_logic; -- sync all QUADs to TX bit 0
+ LINK_TX_READY_OUT : out std_logic; -- TX lane can use used now
+ STATE_OUT : out std_logic_vector(3 downto 0)
+ );
+end component;\r
+\r
component rx_control_RS is
+ generic(
+ SIM_MODE : integer := 0
+ );
port(
- CLK_200 : in std_logic;
- CLK_100 : in std_logic;
- RESET_IN : in std_logic;
-
- WORD_SYNC_OUT : out std_logic;
-
+ CLK_RXI : in std_logic;
+ CLK_SYS : in std_logic;
+ RESET : in std_logic; -- synchronous to RXI
+ -- Media Interface
RX_DATA_OUT : out std_logic_vector(15 downto 0);
RX_PACKET_NUMBER_OUT : out std_logic_vector(2 downto 0);
RX_WRITE_OUT : out std_logic;
-
- RX_DATA_IN : in std_logic_vector( 7 downto 0);
+ -- SerDex data stream
+ RX_DATA_IN : in std_logic_vector(7 downto 0);
RX_K_IN : in std_logic;
-
- RX_DLM : out std_logic := '0';
- RX_DLM_WORD : out std_logic_vector( 7 downto 0) := (others => '0');
-
- SEND_LINK_RESET_OUT : out std_logic := '0';
- MAKE_RESET_OUT : out std_logic := '0';
- RX_ALLOW_IN : in std_logic := '0';
- RX_RESET_FINISHED : in std_logic := '0';
- GOT_LINK_READY : out std_logic := '0';
-
+ -- synchronous link signals
+ WORD_SYNC_OUT : out std_logic;
+ RX_DLM_OUT : out std_logic;
+ RX_DLM_WORD_OUT : out std_logic_vector(7 downto 0);
+ RX_RST_OUT : out std_logic;
+ RX_RST_WORD_OUT : out std_logic_vector(7 downto 0);
+ -- link status signals
+ LINK_RX_READY_IN : in std_logic;
+ LINK_TX_READY_IN : in std_logic;
+ LINK_HALF_DONE_IN : in std_logic;
+ LINK_FULL_DONE_IN : in std_logic;
+ -- debug
DEBUG_OUT : out std_logic_vector(31 downto 0);
STAT_REG_OUT : out std_logic_vector(31 downto 0)
);
end component;
-
+\r
+component rx_lsm_RS is
+ port(
+ LINK_RX_READY_IN : in std_logic; -- serves as async reset, active low
+ RXCLK : in std_logic; -- recovered RX clock
+ RX_K_IN : in std_logic;
+ RX_DATA_IN : in std_logic_vector(7 downto 0);
+ LINK_HALF_DONE_OUT : out std_logic;
+ LINK_FULL_DONE_OUT : out std_logic;
+ STATE_OUT : out std_logic_vector(3 downto 0)
+ );
+end component;\r
+\r
component tx_control_RS is
+ generic(
+ SIM_MODE : integer := 0;
+ IS_MODE : integer := c_IS_UNUSED
+ );
port(
- CLK_200 : in std_logic;
- CLK_100 : in std_logic;
- RESET_IN : in std_logic;
-
- WORD_SYNC_IN : in std_logic;
-
- TX_DATA_IN : in std_logic_vector(15 downto 0);
- TX_PACKET_NUMBER_IN : in std_logic_vector( 2 downto 0);
- TX_WRITE_IN : in std_logic;
- TX_READ_OUT : out std_logic;
-
- TX_DATA_OUT : out std_logic_vector( 7 downto 0);
- TX_K_OUT : out std_logic;
- TX_CD_OUT : out std_logic;
-
- SEND_DLM : in std_logic := '0';
- SEND_DLM_WORD : in std_logic_vector( 7 downto 0) := (others => '0');
-
- SEND_LINK_RESET_IN : in std_logic := '0';
- TX_ALLOW_IN : in std_logic := '0';
- RX_ALLOW_IN : in std_logic := '0';
-
+ CLK_TX : in std_logic;
+ CLK_SYS : in std_logic;
+ RESET : in std_logic; -- async/sync reset
+ -- Media Interface
+ TX_DATA_IN : in std_logic_vector(15 downto 0); -- media interface
+ TX_PACKET_NUMBER_IN : in std_logic_vector(2 downto 0); -- media interface
+ TX_WRITE_IN : in std_logic; -- media interface
+ TX_READ_OUT : out std_logic; -- media interface
+ -- SerDes data stream
+ TX_DATA_OUT : out std_logic_vector(7 downto 0); -- to TX SerDes
+ TX_K_OUT : out std_logic; -- to TX SerDes
+ -- synchronous signals
+ WORD_SYNC_IN : in std_logic; -- byte/word sync
+ SEND_DLM_IN : in std_logic;
+ SEND_DLM_WORD_IN : in std_logic_vector(7 downto 0);
+ SEND_RST_IN : in std_logic;
+ SEND_RST_WORD_IN : in std_logic_vector(7 downto 0);
+ -- link status signals, internally synced
+ LINK_TX_READY_IN : in std_logic; -- local ref clock
+ LINK_RX_READY_IN : in std_logic; -- local ref clock
+ LINK_HALF_DONE_IN : in std_logic; -- recovered RX clock
+ LINK_FULL_DONE_IN : in std_logic; -- recovered RX clock
+ -- debug
DEBUG_OUT : out std_logic_vector(31 downto 0);
STAT_REG_OUT : out std_logic_vector(31 downto 0)
);
-end component;
-
-component rx_reset_fsm_RS is
- port (
- RST_N : in std_logic;
- RX_REFCLK : in std_logic;
- TX_PLL_LOL_QD_S : in std_logic;
- RX_SERDES_RST_CH_C : out std_logic;
- RX_CDR_LOL_CH_S : in std_logic;
- RX_LOS_LOW_CH_S : in std_logic;
- RX_PCS_RST_CH_C : out std_logic;
- WA_POSITION : in std_logic_vector(3 downto 0) := x"0";
- NORMAL_OPERATION_OUT : out std_logic;
- STATE_OUT : out std_logic_vector(3 downto 0)
- );
-end component;
-
-component tx_reset_fsm_RS is
- port (
- RST_N : in std_logic;
- TX_REFCLK : in std_logic;
- TX_PLL_LOL_QD_S : in std_logic;
- RX_RESET_FINISHED_IN : in std_logic;
- RST_QD_C : out std_logic;
- TX_PCS_RST_CH_C : out std_logic;
- NORMAL_OPERATION_OUT : out std_logic;
- STATE_OUT : out std_logic_vector(3 downto 0)
- );
-end component;
-
-component lattice_ecp3_fifo_18x16_dualport_oreg
- port (
- Data : in std_logic_vector(17 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(17 downto 0);
- Empty : out std_logic;
- Full : out std_logic;
- AlmostFull : out std_logic
- );
-end component;
+end component;\r
end package;
library work;
use work.trb_net_std.all;
-use work.trb_net_components.all;
+--use work.trb_net_components.all;
use work.med_sync_define_RS.all;
entity rx_control_RS is
+ generic(
+ SIM_MODE : integer := 0
+ );
port(
- CLK_200 : in std_logic;
- CLK_100 : in std_logic;
- RESET_IN : in std_logic;
-
- -- CLK_100 signals
+ CLK_RXI : in std_logic;
+ CLK_SYS : in std_logic;
+ RESET : in std_logic; -- synchronous to RXI
+ -- Media Interface
RX_DATA_OUT : out std_logic_vector(15 downto 0);
RX_PACKET_NUMBER_OUT : out std_logic_vector(2 downto 0);
RX_WRITE_OUT : out std_logic;
-
- -- CLK_200 signals
+ -- SerDex data stream
RX_DATA_IN : in std_logic_vector(7 downto 0);
RX_K_IN : in std_logic;
-
+ -- synchronous link signals
WORD_SYNC_OUT : out std_logic;
-
- RX_DLM_OUT : out std_logic := '0';
+ RX_DLM_OUT : out std_logic;
RX_DLM_WORD_OUT : out std_logic_vector(7 downto 0);
-
- RX_RST_OUT : out std_logic := '0';
+ RX_RST_OUT : out std_logic;
RX_RST_WORD_OUT : out std_logic_vector(7 downto 0);
-
- -- unknown
- RX_ALLOW_IN : in std_logic := '0';
- RX_RESET_DONE_IN : in std_logic := '0';
- GOT_LINK_READY_OUT : out std_logic := '0';
-
- -- unknown clock
+ -- link status signals
+ LINK_RX_READY_IN : in std_logic;\r
+ LINK_TX_READY_IN : in std_logic;\r
+ LINK_HALF_DONE_IN : in std_logic;\r
+ LINK_FULL_DONE_IN : in std_logic;
+ -- debug
DEBUG_OUT : out std_logic_vector(31 downto 0);
STAT_REG_OUT : out std_logic_vector(31 downto 0)
);
architecture rx_control_arch of rx_control_RS is
-type rx_state_t is (SLEEP, WAIT_1, FIRST, GET_DATA, GET_IDLE, GET_DLM, GET_RST);
-
-signal rx_state : rx_state_t;
-signal rx_state_bits : std_logic_vector(3 downto 0);
-signal rx_packet_num : std_logic_vector(2 downto 0);
-signal buf_rx_write_out : std_logic := '0';
+ type rx_state_t is (SLEEP, WAIT_1, FIRST, GET_DATA, GET_IDLE, GET_DLM, GET_RST);
-signal rx_data : std_logic_vector(17 downto 0);
-signal ct_fifo_write : std_logic := '0';
-signal ct_fifo_read : std_logic := '0';
-signal ct_fifo_reset : std_logic := '0';
-signal ct_fifo_data_out : std_logic_vector(17 downto 0);
-signal ct_fifo_empty : std_logic;
-signal ct_fifo_full : std_logic;
-signal ct_fifo_afull : std_logic;
-signal last_ct_fifo_empty : std_logic;
-signal last_ct_fifo_read : std_logic;
+ signal rx_state : rx_state_t;
+ signal rx_state_bits : std_logic_vector(3 downto 0);
+ signal rx_packet_num : std_logic_vector(2 downto 0);
+ signal buf_rx_write_out : std_logic;
-signal idle_hist_i : std_logic_vector(3 downto 0) := x"0";
-signal got_link_ready_i : std_logic := '0';
+ signal rx_data : std_logic_vector(17 downto 0);
+ signal ct_fifo_write : std_logic;
+ signal ct_fifo_read : std_logic;
+ signal ct_fifo_reset : std_logic;
+ signal ct_fifo_data_out : std_logic_vector(17 downto 0);
+ signal ct_fifo_empty : std_logic;
+ signal ct_fifo_full : std_logic;
+ signal ct_fifo_afull : std_logic;
+ signal last_ct_fifo_empty : std_logic;
+ signal last_ct_fifo_read : std_logic;
-signal rx_dlm_i : std_logic;
-signal rx_dlm_word_i : std_logic_vector(7 downto 0);
+ signal rx_dlm_i : std_logic;
+ signal rx_dlm_word_i : std_logic_vector(7 downto 0);
-signal rx_rst_i : std_logic;
-signal rx_rst_word_i : std_logic_vector(7 downto 0);
+ signal rx_rst_i : std_logic;
+ signal rx_rst_word_i : std_logic_vector(7 downto 0);
-signal next_sop : std_logic;
+ signal next_sop : std_logic;
-signal reg_rx_data_in : std_logic_vector(7 downto 0);
-signal reg_rx_k_in : std_logic;
+ signal reg_rx_data_in : std_logic_vector(7 downto 0);
+ signal reg_rx_k_in : std_logic;
-signal sync_k_i : std_logic;
+ signal sync_k_i : std_logic; -- denotes a K_IDLE detected
+\r
+ signal link_rx_ready_qrx : std_logic;
+ signal link_full_done_qrx : std_logic;
+ signal link_full_done_qsys : std_logic;
begin
+\r
+ -- Syncing things\r
+ SYNC_RXI: signal_sync \r
+ generic map( \r
+ WIDTH => 2,\r
+ DEPTH => 3\r
+ )
+ port map(
+ RESET => '0',
+ CLK0 => CLK_RXI,
+ CLK1 => CLK_RXI,
+ D_IN(0) => LINK_RX_READY_IN,\r
+ D_IN(1) => LINK_FULL_DONE_IN,
+ D_OUT(0) => link_rx_ready_qrx,\r
+ D_OUT(1) => link_full_done_qrx
+ );
+\r
+ -- Syncing things
+ SYNC_SYS: signal_sync
+ generic map(
+ WIDTH => 1,
+ DEPTH => 3
+ )
+ port map(
+ RESET => '0',
+ CLK0 => CLK_SYS,
+ CLK1 => CLK_SYS,
+ D_IN(0) => LINK_FULL_DONE_IN,
+ D_OUT(0) => link_full_done_qsys
+ );
----------------------------------------------------------------------
-- Data to Endpoint
----------------------------------------------------------------------
-
-buf_rx_write_out <= (last_ct_fifo_read and not last_ct_fifo_empty) when rising_edge(CLK_100);
-
-RX_WRITE_OUT <= buf_rx_write_out;
-RX_DATA_OUT <= ct_fifo_data_out(15 downto 0) ;
-RX_PACKET_NUMBER_OUT <= rx_packet_num;
-
-last_ct_fifo_read <= ct_fifo_read when rising_edge(CLK_100);
-last_ct_fifo_empty <= ct_fifo_empty when rising_edge(CLK_100);
-
-process begin
- wait until rising_edge(CLK_100);
- if RX_ALLOW_IN = '0' then -- DANGEROUS!!!!
- rx_packet_num <= "100";
- elsif buf_rx_write_out = '1' then
- if rx_packet_num = "100" then
- rx_packet_num <= "000";
- else
- rx_packet_num <= std_logic_vector(unsigned(rx_packet_num)+1);
- end if;
- end if;
-end process;
+ buf_rx_write_out <= (last_ct_fifo_read and not last_ct_fifo_empty) when rising_edge(CLK_SYS);
+
+ RX_WRITE_OUT <= buf_rx_write_out;
+ RX_DATA_OUT <= ct_fifo_data_out(15 downto 0) ;
+ RX_PACKET_NUMBER_OUT <= rx_packet_num;
+
+ last_ct_fifo_read <= ct_fifo_read when rising_edge(CLK_SYS);
+ last_ct_fifo_empty <= ct_fifo_empty when rising_edge(CLK_SYS);
+
+ process begin
+ wait until rising_edge(CLK_SYS);
+ if ( link_full_done_qsys = '0' ) then
+ rx_packet_num <= "100";
+ elsif( buf_rx_write_out = '1' ) then
+ if rx_packet_num = "100" then
+ rx_packet_num <= "000";
+ else
+ rx_packet_num <= std_logic_vector(unsigned(rx_packet_num)+1);
+ end if;
+ end if;
+ end process;
----------------------------------------------------------------------
-- Clock Domain Transfer
----------------------------------------------------------------------
-THE_CT_FIFO : entity work.lattice_ecp3_fifo_18x16_dualport_oreg
- port map(
- Data => rx_data,
- WrClock => CLK_200,
- RdClock => CLK_100,
- WrEn => ct_fifo_write,
- RdEn => ct_fifo_read,
- Reset => ct_fifo_reset,
- RPReset => ct_fifo_reset,
- Q(17 downto 0) => ct_fifo_data_out,
- Empty => ct_fifo_empty,
- Full => ct_fifo_full,
- AlmostFull => ct_fifo_afull
- );
-
-ct_fifo_read <= not ct_fifo_reset and not ct_fifo_empty;
-
-ct_fifo_reset <= not RX_ALLOW_IN when rising_edge(CLK_200);
+ THE_CT_FIFO : entity work.lattice_ecp3_fifo_18x16_dualport_oreg
+ port map(
+ Data => rx_data,
+ WrClock => CLK_RXI,
+ RdClock => CLK_SYS,
+ WrEn => ct_fifo_write,
+ RdEn => ct_fifo_read,
+ Reset => ct_fifo_reset,
+ RPReset => ct_fifo_reset,
+ Q(17 downto 0) => ct_fifo_data_out,
+ Empty => ct_fifo_empty,
+ Full => ct_fifo_full,
+ AlmostFull => ct_fifo_afull
+ );
+
+ ct_fifo_read <= not ct_fifo_reset and not ct_fifo_empty;
+
+ ct_fifo_reset <= not link_full_done_qrx;
----------------------------------------------------------------------
-- Read incoming data
----------------------------------------------------------------------
-PROC_RX_FSM : process begin
- wait until rising_edge(CLK_200);
- ct_fifo_write <= '0';
- rx_dlm_i <= '0';
- rx_rst_i <= '0';
- idle_hist_i(3 downto 1) <= idle_hist_i(2 downto 0);
- idle_hist_i(0) <= got_link_ready_i;
- sync_k_i <= '0';
-
- case rx_state is
- when SLEEP =>
- rx_state_bits <= x"1";
- got_link_ready_i <= '0';
- rx_data(7 downto 0) <= reg_rx_data_in;
- if reg_rx_k_in = '1' and reg_rx_data_in = K_IDLE then
- rx_state <= WAIT_1;
- sync_k_i <= '1';
- end if;
-
- when WAIT_1 =>
- rx_state <= FIRST;
-
- when FIRST =>
- rx_state_bits <= x"2";
- rx_data(7 downto 0) <= reg_rx_data_in;
- sync_k_i <= '1';
- if reg_rx_k_in = '1' then
- case reg_rx_data_in is
- when K_IDLE =>
- rx_state <= GET_IDLE;
- when K_DLM =>
- rx_state <= GET_DLM;
- when K_RST =>
- rx_state <= GET_RST;
- when others => null;
- end case;
- else
- rx_state <= GET_DATA;
- end if;
-
- when GET_IDLE =>
- rx_state_bits <= x"3";
- rx_state <= FIRST;
- next_sop <= '1';
- if reg_rx_k_in = '0' and reg_rx_data_in = D_IDLE1 then
- idle_hist_i(0) <= '1';
- got_link_ready_i <= got_link_ready_i or (idle_hist_i(1) and idle_hist_i(3));
- elsif reg_rx_k_in = '1' then -- not needed?
- rx_state <= FIRST; -- not needed?
- end if;
-
- when GET_DATA =>
- rx_state_bits <= x"4";
- -- rx_state <= FIRST
- if reg_rx_k_in = '0' then
- next_sop <= '0';
- rx_data(15 downto 8)<= reg_rx_data_in;
- rx_data(16) <= next_sop;
- rx_data(17) <= '0';
- ct_fifo_write <= '1';
- rx_state <= FIRST;
- else -- not needed?
- rx_state <= FIRST; -- not needed?
- end if;
-
- when GET_DLM =>
- rx_state_bits <= x"5";
- rx_dlm_i <= '1';
- rx_dlm_word_i <= reg_rx_data_in;
- rx_state <= FIRST;
-
- when GET_RST =>
- rx_state_bits <= x"6";
- rx_rst_i <= '1';
- rx_rst_word_i <= reg_rx_data_in;
- rx_state <= FIRST;
+ PROC_RX_FSM : process begin
+ wait until rising_edge(CLK_RXI);
+ ct_fifo_write <= '0';
+ rx_dlm_i <= '0';
+ rx_rst_i <= '0';
+ sync_k_i <= '0';
+
+ case rx_state is
+ when SLEEP =>
+ rx_state_bits <= x"1";
+ rx_data(7 downto 0) <= reg_rx_data_in;
+ if( (reg_rx_k_in = '1') and (reg_rx_data_in = K_IDLE) ) then
+ rx_state <= WAIT_1;
+ sync_k_i <= '1';
+ end if;
+
+ when WAIT_1 =>
+ rx_state <= FIRST;
+
+ when FIRST =>
+ rx_state_bits <= x"2";
+ rx_data(7 downto 0) <= reg_rx_data_in;
+ sync_k_i <= '1';
+ if( reg_rx_k_in = '1' ) then
+ case reg_rx_data_in is
+ when K_IDLE =>
+ rx_state <= GET_IDLE;
+ when K_DLM =>
+ rx_state <= GET_DLM;
+ when K_RST =>
+ rx_state <= GET_RST;
+ when others => null;
+ end case;
+ else
+ rx_state <= GET_DATA;
+ end if;
+
+ when GET_IDLE =>
+ rx_state_bits <= x"3";
+ rx_state <= FIRST;
+ next_sop <= '1';
+
+ when GET_DATA =>
+ rx_state_bits <= x"4";
+ -- rx_state <= FIRST
+ if reg_rx_k_in = '0' then
+ next_sop <= '0';
+ rx_data(15 downto 8)<= reg_rx_data_in;
+ rx_data(16) <= next_sop;
+ rx_data(17) <= '0';
+ ct_fifo_write <= '1';
+ rx_state <= FIRST;
+ else -- not needed?
+ rx_state <= FIRST; -- not needed?
+ end if;
+
+ when GET_DLM =>
+ rx_state_bits <= x"5";
+ rx_dlm_i <= '1';
+ rx_dlm_word_i <= reg_rx_data_in;
+ rx_state <= FIRST;
+
+ when GET_RST =>
+ rx_state_bits <= x"6";
+ rx_rst_i <= '1';
+ rx_rst_word_i <= reg_rx_data_in;
+ rx_state <= FIRST;
- end case;
+ end case;
- if RESET_IN = '1' or RX_RESET_DONE_IN = '0' then
- rx_state <= SLEEP;
- rx_dlm_word_i <= x"00";
- rx_rst_word_i <= x"00";
- end if;
-end process;
+ if( (RESET = '1') or (link_rx_ready_qrx = '0') ) then
+ rx_state <= SLEEP;
+ rx_dlm_word_i <= x"00";
+ rx_rst_word_i <= x"00";
+ end if;
+ end process;
-- we store incoming data in a register
-reg_rx_data_in <= RX_DATA_IN when rising_edge(CLK_200);
-reg_rx_k_in <= RX_K_IN when rising_edge(CLK_200);
+ reg_rx_data_in <= RX_DATA_IN when rising_edge(CLK_RXI);
+ reg_rx_k_in <= RX_K_IN when rising_edge(CLK_RXI);
----------------------------------------------------------------------
-- Signals out
----------------------------------------------------------------------
-GOT_LINK_READY_OUT <= got_link_ready_i;
-WORD_SYNC_OUT <= sync_k_i;
+ WORD_SYNC_OUT <= sync_k_i;
-RX_DLM_OUT <= rx_dlm_i when rising_edge(CLK_200);
-RX_DLM_WORD_OUT <= rx_dlm_word_i when rising_edge(CLK_200);
-RX_RST_OUT <= rx_rst_i when rising_edge(CLK_200);
-RX_RST_WORD_OUT <= rx_rst_word_i when rising_edge(CLK_200);
+ RX_DLM_OUT <= rx_dlm_i when rising_edge(CLK_RXI);
+ RX_DLM_WORD_OUT <= rx_dlm_word_i when rising_edge(CLK_RXI);
+ RX_RST_OUT <= rx_rst_i when rising_edge(CLK_RXI);
+ RX_RST_WORD_OUT <= rx_rst_word_i when rising_edge(CLK_RXI);
----------------------------------------------------------------------
-- Debug and Status
----------------------------------------------------------------------
-STAT_REG_OUT(3 downto 0) <= rx_state_bits;
-STAT_REG_OUT(4) <= got_link_ready_i;
-STAT_REG_OUT(5) <= ct_fifo_afull;
-STAT_REG_OUT(6) <= ct_fifo_empty;
-STAT_REG_OUT(7) <= ct_fifo_write;
-STAT_REG_OUT(15 downto 8) <= reg_rx_data_in when rising_edge(clk_100);
-STAT_REG_OUT(16) <= rx_data(16);
-STAT_REG_OUT(17) <= '0';
-STAT_REG_OUT(31 downto 18) <= (others => '0');
-
-DEBUG_OUT(3 downto 0) <= rx_state_bits;
-DEBUG_OUT(4) <= got_link_ready_i;
-DEBUG_OUT(5) <= ct_fifo_afull;
-DEBUG_OUT(6) <= ct_fifo_empty;
-DEBUG_OUT(7) <= ct_fifo_write;
-DEBUG_OUT(15 downto 8) <= rx_data(7 downto 0);
-DEBUG_OUT(16) <= reg_rx_k_in;
-DEBUG_OUT(17) <= '0';
-DEBUG_OUT(18) <= '0';
-DEBUG_OUT(19) <= '1' when rx_state_bits = x"f" else '0';
---DEBUG_OUT(16) <= rx_data(16);
-DEBUG_OUT(31 downto 20) <= (others => '0');
--- DEBUG_OUT(23 downto 16) <= rx_data(7 downto 0);
--- DEBUG_OUT(31 downto 24) <= ct_fifo_data_out(7 downto 0);
-
-
+ STAT_REG_OUT(3 downto 0) <= rx_state_bits;
+ STAT_REG_OUT(4) <= '0';
+ STAT_REG_OUT(5) <= ct_fifo_afull;
+ STAT_REG_OUT(6) <= ct_fifo_empty;
+ STAT_REG_OUT(7) <= ct_fifo_write;
+ STAT_REG_OUT(15 downto 8) <= reg_rx_data_in when rising_edge(CLK_SYS);
+ STAT_REG_OUT(16) <= rx_data(16);
+ STAT_REG_OUT(17) <= '0';
+ STAT_REG_OUT(31 downto 18) <= (others => '0');
+
+ DEBUG_OUT(3 downto 0) <= rx_state_bits;
+ DEBUG_OUT(4) <= '0';
+ DEBUG_OUT(5) <= ct_fifo_afull;
+ DEBUG_OUT(6) <= ct_fifo_empty;
+ DEBUG_OUT(7) <= ct_fifo_write;
+ DEBUG_OUT(15 downto 8) <= rx_data(7 downto 0);
+ DEBUG_OUT(16) <= reg_rx_k_in;
+ DEBUG_OUT(17) <= '0';
+ DEBUG_OUT(18) <= '0';
+ DEBUG_OUT(19) <= '1' when rx_state_bits = x"f" else '0';
+ --DEBUG_OUT(16) <= rx_data(16);
+ DEBUG_OUT(31 downto 20) <= (others => '0');
+ -- DEBUG_OUT(23 downto 16) <= rx_data(7 downto 0);
+ -- DEBUG_OUT(31 downto 24) <= ct_fifo_data_out(7 downto 0);
end architecture;
--- /dev/null
+LIBRARY IEEE;
+USE IEEE.std_logic_1164.ALL;
+USE IEEE.numeric_std.all;
+\r
+library work;
+use work.med_sync_define_RS.all;\r
+
+entity rx_lsm_RS is\r
+ port(
+ LINK_RX_READY_IN : in std_logic; -- serves as async reset, active low
+ RXCLK : in std_logic; -- recovered RX clock
+ RX_K_IN : in std_logic;
+ RX_DATA_IN : in std_logic_vector(7 downto 0); \r
+ LINK_HALF_DONE_OUT : out std_logic;\r
+ LINK_FULL_DONE_OUT : out std_logic;
+ STATE_OUT : out std_logic_vector(3 downto 0)
+ );
+end entity;
+
+architecture rx_lsm_arch of rx_lsm_RS is
+\r
+ type statetype is ( IDLE, K1F, D1F, K2F, D2FT, D2FS );
+
+ signal CURRENT_STATE : statetype; -- current state of lsm
+ signal NEXT_STATE : statetype; -- next state of lsm
+ \r
+ signal reset_ctr_t : std_logic;\r
+ signal ce_ctr_t : std_logic;
+ signal ctr_t : unsigned(4 downto 0);
+ signal ctr_t_done : std_logic;
+ signal reset_ctr_s : std_logic;\r
+ signal ce_ctr_s : std_logic;
+ signal ctr_s : unsigned(4 downto 0);
+ signal ctr_s_done : std_logic;
+ signal link_toggling_int : std_logic;\r
+ signal link_steady_int : std_logic;\r
+
+begin
+\r
+ THE_CTR_T_PROC: process( RXCLK, LINK_RX_READY_IN )
+ begin\r
+ if ( LINK_RX_READY_IN <= '0' ) then\r
+ ctr_t <= (others => '0');
+ elsif( rising_edge(RXCLK) ) then
+ if( reset_ctr_t = '1' ) then
+ ctr_t <= (others => '0');
+ else
+ if( (ctr_t(4) = '0') and (ce_ctr_t = '1') ) then
+ ctr_t <= ctr_t + 1 ;
+ end if;
+ end if;
+ end if;
+ end process THE_CTR_T_PROC;
+\r
+ ctr_t_done <= ctr_t(4);\r
+\r
+ THE_CTR_S_PROC: process( RXCLK, LINK_RX_READY_IN )
+ begin\r
+ if ( LINK_RX_READY_IN = '0' ) then\r
+ ctr_s <= (others => '0');
+ elsif( rising_edge(RXCLK) ) then
+ if( reset_ctr_s = '1' ) then
+ ctr_s <= (others => '0');
+ else
+ if( (ctr_s(4) = '0') and (ce_ctr_s = '1') ) then
+ ctr_s <= ctr_s + 1 ;
+ end if;
+ end if;
+ end if;
+ end process THE_CTR_S_PROC;
+
+ ctr_s_done <= ctr_s(4);
+\r
+ -- toggling idles sequence detected\r
+ THE_TOGGLE_DETECTED_PROC: process( RXCLK, LINK_RX_READY_IN )\r
+ begin\r
+ if ( LINK_RX_READY_IN = '0' ) then\r
+ link_toggling_int <= '0';\r
+ elsif( rising_edge(RXCLK) ) then\r
+ if( ctr_t_done = '1' ) then\r
+ link_toggling_int <= '1';\r
+ end if; \r
+ end if;\r
+ end process THE_TOGGLE_DETECTED_PROC;\r
+\r
+ LINK_HALF_DONE_OUT <= link_toggling_int;\r
+\r
+ -- steady idles sequence detected
+ THE_STEADY_DETECTED_PROC: process( RXCLK, LINK_RX_READY_IN )
+ begin
+ if ( LINK_RX_READY_IN = '0' ) then
+ link_steady_int <= '0';
+ elsif( rising_edge(RXCLK) ) then
+ if( ctr_s_done = '1' ) then
+ link_steady_int <= '1';
+ end if;
+ end if;
+ end process THE_STEADY_DETECTED_PROC;
+\r
+ LINK_FULL_DONE_OUT <= link_steady_int;
+
+ -- State machine clocked process
+ THE_FSM_PROC: process( RXCLK, LINK_RX_READY_IN )
+ begin
+ if( LINK_RX_READY_IN = '0' ) then
+ CURRENT_STATE <= IDLE;
+ else\r
+ if( rising_edge(RXCLK) ) then
+ CURRENT_STATE <= NEXT_STATE;
+ end if;
+ end if;
+ end process THE_FSM_PROC;
+\r
+ -- State machine decoding processs
+ THE_FSM_DECODE_PROC: process( CURRENT_STATE, RX_K_IN, RX_DATA_IN )
+ begin
+ reset_ctr_t <= '0';\r
+ reset_ctr_s <= '0';\r
+ ce_ctr_t <= '0';\r
+ ce_ctr_s <= '0';
+ STATE_OUT <= x"F";
+
+ case CURRENT_STATE is
+\r
+ when IDLE =>\r
+ STATE_OUT <= x"0";\r
+ reset_ctr_t <= '1';\r
+ reset_ctr_s <= '1';\r
+ if( (RX_K_IN = '1') and (RX_DATA_IN = K_IDLE) ) then\r
+ NEXT_STATE <= K1F;\r
+ else\r
+ NEXT_STATE <= IDLE;\r
+ end if;\r
+\r
+ when K1F =>\r
+ STATE_OUT <= x"1";\r
+ if( (RX_K_IN = '0') and (RX_DATA_IN = D_IDLE1) ) then\r
+ NEXT_STATE <= D1F;\r
+ else\r
+ NEXT_STATE <= IDLE;\r
+ end if; \r
+\r
+ when D1F =>\r
+ STATE_OUT <= x"2";
+ if( (RX_K_IN = '1') and (RX_DATA_IN = K_IDLE) ) then
+ NEXT_STATE <= K2F;
+ else
+ NEXT_STATE <= IDLE;
+ end if;
+\r
+ when K2F =>\r
+ STATE_OUT <= x"3";
+ if ( (RX_K_IN = '0') and (RX_DATA_IN = D_IDLE1) ) then
+ NEXT_STATE <= D2FS;
+ elsif( (RX_K_IN = '0') and (RX_DATA_IN = D_IDLE0) ) then
+ NEXT_STATE <= D2FT;
+ else
+ NEXT_STATE <= IDLE;
+ end if;
+\r
+ when D2FT =>\r
+ STATE_OUT <= x"4";
+ if( (RX_K_IN = '1') and (RX_DATA_IN = K_IDLE) ) then
+ NEXT_STATE <= K1F;\r
+ ce_ctr_t <= '1';
+ else
+ NEXT_STATE <= IDLE;
+ end if;
+\r
+ when D2FS =>\r
+ STATE_OUT <= x"5";
+ if( (RX_K_IN = '1') and (RX_DATA_IN = K_IDLE) ) then
+ NEXT_STATE <= K1F;\r
+ ce_ctr_s <= '1';
+ else
+ NEXT_STATE <= IDLE;
+ end if;
+\r
+ when others =>\r
+ STATE_OUT <= x"f";
+ NEXT_STATE <= IDLE;\r
+
+ end case;
+
+ end process THE_FSM_DECODE_PROC;
+
+end architecture;
entity rx_reset_fsm_RS is
port(
- RST_N : in std_logic;
- RX_REFCLK : in std_logic;
- TX_PLL_LOL_QD_S : in std_logic;
- RX_CDR_LOL_CH_S : in std_logic;
- RX_LOS_LOW_CH_S : in std_logic;
- RX_PCS_RST_CH_C : out std_logic;
- RX_SERDES_RST_CH_C : out std_logic;
- WA_POSITION : in std_logic_vector(3 downto 0) := x"0";
- NORMAL_OPERATION_OUT : out std_logic;
- STATE_OUT : out std_logic_vector(3 downto 0)
+ RST_N : in std_logic;
+ RX_REFCLK : in std_logic; -- CDR reference clock
+ TX_PLL_LOL_QD_S : in std_logic; -- TX_PLOL form AUX channel
+ RX_CDR_LOL_CH_S : in std_logic; -- CDR LOL
+ RX_LOS_LOW_CH_S : in std_logic; -- RX LOS
+ RX_PCS_RST_CH_C : out std_logic;
+ RX_SERDES_RST_CH_C : out std_logic;
+ WA_POSITION : in std_logic_vector(3 downto 0) := x"0";
+ NORMAL_OPERATION_OUT : out std_logic; -- RX SerDes is fully operational
+ STATE_OUT : out std_logic_vector(3 downto 0)
);
end entity ;
rx_lol_los <= rx_cdr_lol_ch_q or rx_los_low_ch_q ;
SYNC_SFP_SIGS : entity work.signal_sync
- generic map(
- WIDTH => 3
- )
+ generic map( WIDTH => 3 )
port map(
RESET => '0',
CLK0 => RX_REFCLK,
begin
if rising_edge(RX_REFCLK) then
if RST_N = '0' then
- cs <= WAIT_FOR_PLOL;
- rx_lol_los_int <= '1';
- rx_lol_los_del <= '1';
- RX_PCS_RST_CH_C <= '1';
+ cs <= WAIT_FOR_PLOL;
+ rx_lol_los_int <= '1';
+ rx_lol_los_del <= '1';
+ RX_PCS_RST_CH_C <= '1';
RX_SERDES_RST_CH_C <= '0';
else
cs <= ns;
- rx_lol_los_del <= rx_lol_los;
- rx_lol_los_int <= rx_lol_los_del;
- RX_PCS_RST_CH_C <= rx_pcs_rst_ch_c_int;
+ rx_lol_los_del <= rx_lol_los;
+ rx_lol_los_int <= rx_lol_los_del;
+ RX_PCS_RST_CH_C <= rx_pcs_rst_ch_c_int;
RX_SERDES_RST_CH_C <= rx_serdes_rst_ch_c_int;
end if;
end if;
--- /dev/null
+LIBRARY ieee;
+USE ieee.std_logic_1164.ALL;
+USE ieee.std_logic_unsigned.all;
+USE ieee.numeric_std.ALL;
+\r
+library work;
+use work.trb_net_std.all;
+--use work.trb_net_components.all;
+use work.med_sync_define_RS.all;\r
+
+ENTITY tb_main_rx_reset_RS_vhd IS
+END tb_main_rx_reset_RS_vhd;
+
+ARCHITECTURE behavior OF tb_main_rx_reset_RS_vhd IS
+
+ -- Component Declaration for the Unit Under Test (UUT)
+ COMPONENT main_rx_reset_RS IS
+ generic(
+ SIM_MODE : integer := 0;\r
+ IS_WAP_ZERO : integer := 0;\r
+ IS_MODE : integer := c_IS_SLAVE\r
+ );
+ port(
+ CLEAR : in std_logic;
+ LOCALCLK : in std_logic; \r
+ TX_PLL_LOL_IN : in std_logic;
+ RX_CDR_LOL_IN : in std_logic;
+ RX_LOS_LOW_IN : in std_logic;
+ WA_POSITION_IN : in std_logic_vector(3 downto 0);\r
+ SFP_LOS_IN : in std_logic;
+ RX_PCS_RST_CH_C_OUT : out std_logic;
+ RX_SERDES_RST_CH_C_OUT : out std_logic;\r
+ LINK_RX_READY_OUT : out std_logic;\r
+ MASTER_RESET_OUT : out std_logic;
+ STATE_OUT : out std_logic_vector(3 downto 0)
+ ); \r
+ END COMPONENT main_rx_reset_RS;\r
+\r
+ --Inputs
+ SIGNAL CLEAR : std_logic;
+ SIGNAL LOCALCLK : std_logic;
+ SIGNAL TX_PLL_LOL_IN : std_logic;
+ SIGNAL RX_CDR_LOL_IN : std_logic;
+ SIGNAL RX_LOS_LOW_IN : std_logic;
+ SIGNAL WA_POSITION_IN : std_logic_vector(3 downto 0);
+ SIGNAL SFP_LOS_IN : std_logic;\r
+
+ --Outputs
+ SIGNAL RX_PCS_RST_CH_C_OUT : std_logic;
+ SIGNAL RX_SERDES_RST_CH_C_OUT : std_logic;\r
+ SIGNAL LINK_RX_READY_OUT : std_logic;\r
+ SIGNAL MASTER_RESET_OUT : std_logic;
+ SIGNAL STATE_OUT : std_logic_vector(3 downto 0);
+
+BEGIN
+
+ -- Instantiate the Unit Under Test (UUT)
+ uut: main_rx_reset_RS \r
+ GENERIC MAP(\r
+ SIM_MODE => 1,\r
+ IS_WAP_ZERO => 1,\r
+ IS_MODE => c_IS_SLAVE\r
+ )\r
+ PORT MAP(
+ CLEAR => CLEAR,
+ LOCALCLK => LOCALCLK,
+ TX_PLL_LOL_IN => TX_PLL_LOL_IN,\r
+ RX_CDR_LOL_IN => RX_CDR_LOL_IN,\r
+ RX_LOS_LOW_IN => RX_LOS_LOW_IN,\r
+ WA_POSITION_IN => WA_POSITION_IN,\r
+ SFP_LOS_IN => SFP_LOS_IN,\r
+ RX_PCS_RST_CH_C_OUT => RX_PCS_RST_CH_C_OUT,\r
+ RX_SERDES_RST_CH_C_OUT => RX_SERDES_RST_CH_C_OUT,\r
+ LINK_RX_READY_OUT => LINK_RX_READY_OUT,\r
+ MASTER_RESET_OUT => MASTER_RESET_OUT,
+ STATE_OUT => STATE_OUT\r
+ );
+
+CLK_GEN: process
+begin
+ -- 200 MHz => 5.0 ns
+ localclk <= '1'; wait for 2.5 ns;
+ localclk <= '0'; wait for 2.5 ns;
+end process CLK_GEN;
+\r
+TEST_BENCH_PROC: process
+begin
+ -- Setup signals
+ clear <= '0';\r
+ tx_pll_lol_in <= '0';
+ rx_cdr_lol_in <= '1';
+ rx_los_low_in <= '1';
+ wa_position_in <= x"f";
+ sfp_los_in <= '1';
+ wait for 77 ns;
+
+ -- Reset the beast\r
+ clear <= '1';
+ wait for 99 ns;
+ clear <= '0';
+ wait for 99 ns;
+\r
+ -- Tests may start here\r
+ wait for 555 ns;\r
+ rx_los_low_in <= '0';\r
+ wait for 666 ns;\r
+ rx_cdr_lol_in <= '0';
+ wait for 666 ns;\r
+ wa_position_in <= x"0";\r
+\r
+ -- Stay a while... stay forever!!!
+ wait;
+
+end process TEST_BENCH_PROC;
+
+END;
--- /dev/null
+LIBRARY ieee;
+USE ieee.std_logic_1164.ALL;
+USE ieee.std_logic_unsigned.all;
+USE ieee.numeric_std.ALL;
+
+ENTITY tb_main_tx_reset_RS_vhd IS
+END tb_main_tx_reset_RS_vhd;
+
+ARCHITECTURE behavior OF tb_main_tx_reset_RS_vhd IS
+
+ -- Component Declaration for the Unit Under Test (UUT)
+ COMPONENT main_tx_reset_RS IS
+ generic(
+ SIM_MODE : integer := 0
+ );
+ port(
+ CLEAR : in std_logic;
+ LOCALCLK : in std_logic;
+ TX_PLL_LOL_QD_A_IN : in std_logic;
+ TX_PLL_LOL_QD_B_IN : in std_logic;
+ TX_PLL_LOL_QD_C_IN : in std_logic;
+ TX_PLL_LOL_QD_D_IN : in std_logic;
+ TX_CLOCK_AVAIL_IN : in std_logic;
+ RST_QD_C_OUT : out std_logic;
+ TX_PCS_RST_CH_C_OUT : out std_logic;\r
+ SYNC_TX_QUAD_OUT : out std_logic;
+ LINK_TX_READY_OUT : out std_logic;
+ STATE_OUT : out std_logic_vector(3 downto 0)
+ ); \r
+ END COMPONENT main_tx_reset_RS;
+
+ --Inputs
+ SIGNAL CLEAR : std_logic;
+ SIGNAL LOCALCLK : std_logic;
+ SIGNAL TX_PLL_LOL_QD_A_IN : std_logic;
+ SIGNAL TX_PLL_LOL_QD_B_IN : std_logic;
+ SIGNAL TX_PLL_LOL_QD_C_IN : std_logic;
+ SIGNAL TX_PLL_LOL_QD_D_IN : std_logic;
+ SIGNAL TX_CLOCK_AVAIL_IN : std_logic;
+
+ --Outputs
+ SIGNAL RST_QD_C_OUT : std_logic;
+ SIGNAL TX_PCS_RST_CH_C_OUT : std_logic;
+ SIGNAL SYNC_TX_QUAD_OUT : std_logic;\r
+ SIGNAL LINK_TX_READY_OUT : std_logic;
+ SIGNAL STATE_OUT : std_logic_vector(3 downto 0);
+
+BEGIN
+
+ -- Instantiate the Unit Under Test (UUT)
+ uut: main_tx_reset_RS \r
+ GENERIC MAP(\r
+ SIM_MODE => 1\r
+ )\r
+ PORT MAP(
+ CLEAR => CLEAR,
+ LOCALCLK => LOCALCLK,
+ TX_PLL_LOL_QD_A_IN => TX_PLL_LOL_QD_A_IN,
+ TX_PLL_LOL_QD_B_IN => TX_PLL_LOL_QD_B_IN,
+ TX_PLL_LOL_QD_C_IN => TX_PLL_LOL_QD_C_IN,
+ TX_PLL_LOL_QD_D_IN => TX_PLL_LOL_QD_D_IN,
+ TX_CLOCK_AVAIL_IN => TX_CLOCK_AVAIL_IN,
+ RST_QD_C_OUT => RST_QD_C_OUT,
+ TX_PCS_RST_CH_C_OUT => TX_PCS_RST_CH_C_OUT,\r
+ SYNC_TX_QUAD_OUT => SYNC_TX_QUAD_OUT,
+ LINK_TX_READY_OUT => LINK_TX_READY_OUT,
+ STATE_OUT => STATE_OUT\r
+ );
+
+CLK_GEN: process
+begin
+ -- 200 MHz => 5.0 ns
+ localclk <= '1'; wait for 2.5 ns;
+ localclk <= '0'; wait for 2.5 ns;
+end process CLK_GEN;
+\r
+TEST_BENCH_PROC: process
+begin
+ -- Setup signals
+ clear <= '0';\r
+ tx_pll_lol_qd_a_in <= '1';
+ tx_pll_lol_qd_b_in <= '1';
+ tx_pll_lol_qd_c_in <= '1';
+ tx_pll_lol_qd_d_in <= '1';
+ tx_clock_avail_in <= '0';\r
+
+ wait for 77 ns;
+
+ -- Reset the beast\r
+ clear <= '1';
+ wait for 99 ns;
+ clear <= '0';
+ wait for 99 ns;
+\r
+ -- Tests may start here\r
+ tx_pll_lol_qd_a_in <= '0';\r
+ wait for 333 ns;\r
+ tx_pll_lol_qd_b_in <= '0';
+ wait for 333 ns;
+ tx_pll_lol_qd_c_in <= '0';
+ wait for 555 ns;
+ tx_clock_avail_in <= '1';\r
+ wait for 666 ns;\r
+ tx_pll_lol_qd_d_in <= '0';\r
+\r
+ wait for 2 us;\r
+ tx_clock_avail_in <= '0';\r
+ wait for 33.33 ns;\r
+ tx_clock_avail_in <= '1';\r
+
+ -- Stay a while... stay forever!!!
+ wait;
+
+end process TEST_BENCH_PROC;
+
+END;
--- /dev/null
+LIBRARY ieee;\r
+USE ieee.std_logic_1164.ALL;\r
+USE ieee.std_logic_unsigned.all;\r
+USE ieee.numeric_std.ALL;\r
+\r
+library work;\r
+use work.trb_net_std.all;\r
+--use work.trb_net_components.all;\r
+use work.med_sync_define_RS.all;\r
+\r
+ENTITY tb_med_sync_control_RS_vhd IS\r
+END tb_med_sync_control_RS_vhd;\r
+\r
+ARCHITECTURE behavior OF tb_med_sync_control_RS_vhd IS \r
+\r
+ -- Component Declaration for the Unit Under Test (UUT)\r
+ COMPONENT med_sync_control_RS IS\r
+ generic(\r
+ SIM_MODE : integer := 0;\r
+ IS_WAP_ZERO : integer := 0;\r
+ IS_MODE : integer := c_IS_UNUSED\r
+ );\r
+ port(\r
+ CLK_SYS : in std_logic; -- 100MHz system clock\r
+ CLK_RXI : in std_logic; -- recovered RX clock, 200MHz\r
+ CLK_RXHALF : in std_logic; -- used for media interface\r
+ CLK_TXI : in std_logic; -- TX clock, 200MHz\r
+ CLK_REF : in std_logic; -- 200MHz local clock\r
+ RESET : in std_logic;\r
+ CLEAR : in std_logic;\r
+ MEDIA_MED2INT : out MED2INT;
+ MEDIA_INT2MED : in INT2MED;
+ SFP_LOS_IN : in std_logic;\r
+ RX_CDR_LOL_IN : in std_logic;\r
+ RX_LOS_IN : in std_logic;\r
+ WA_POSITION_IN : in std_logic_vector(3 downto 0);\r
+ LINK_TX_READY_IN : in std_logic;\r
+ RX_SERDES_RST : out std_logic;
+ RX_PCS_RST : out std_logic;
+ TX_DATA_OUT : out std_logic_vector(7 downto 0);\r
+ TX_K_OUT : out std_logic;\r
+ RX_DATA_IN : in std_logic_vector(7 downto 0);\r
+ RX_K_IN : in std_logic;\r
+ WORD_SYNC_IN : in std_logic;
+ WORD_SYNC_OUT : out std_logic;
+ TX_DLM_WORD_IN : in std_logic_vector(7 downto 0);\r
+ TX_DLM_IN : in std_logic;\r
+ TX_RST_WORD_IN : in std_logic_vector(7 downto 0);\r
+ TX_RST_IN : in std_logic;\r
+ RX_DLM_WORD_OUT : out std_logic_vector(7 downto 0);
+ RX_DLM_OUT : out std_logic;
+ RX_RST_WORD_OUT : out std_logic_vector(7 downto 0);\r
+ RX_RST_OUT : out std_logic;\r
+ MASTER_RESET_OUT : out std_logic;\r
+ TX_RESET_OUT : out std_logic;\r
+ STAT_TX_CONTROL : out std_logic_vector(31 downto 0);\r
+ STAT_RX_CONTROL : out std_logic_vector(31 downto 0);\r
+ DEBUG_TX_CONTROL : out std_logic_vector(31 downto 0);\r
+ DEBUG_RX_CONTROL : out std_logic_vector(31 downto 0);\r
+ STAT_RESET : out std_logic_vector(31 downto 0);\r
+ DEBUG_OUT : out std_logic_vector(31 downto 0)\r
+ ); \r
+ END COMPONENT med_sync_control_RS;\r
+\r
+ --Inputs\r
+ SIGNAL M_CLK_SYS : std_logic;\r
+ SIGNAL M_CLK_RXI : std_logic;\r
+ SIGNAL M_CLK_TXI : std_logic;\r
+ SIGNAL M_CLK_REF : std_logic;\r
+ SIGNAL M_CLEAR : std_logic;\r
+ SIGNAL M_SFP_LOS_IN : std_logic;\r
+ SIGNAL M_RX_CDR_LOL_IN : std_logic;\r
+ SIGNAL M_RX_LOS_IN : std_logic;\r
+ SIGNAL M_WA_POSITION_IN : std_logic_vector(3 downto 0);\r
+ SIGNAL M_LINK_TX_READY_IN : std_logic;
+ SIGNAL M_RX_DATA_IN : std_logic_vector(7 downto 0);\r
+ SIGNAL M_RX_K_IN : std_logic;\r
+ SIGNAL M_WORD_SYNC_IN : std_logic;
+\r
+ SIGNAL S_CLK_SYS : std_logic;
+ SIGNAL S_CLK_RXI : std_logic;
+ SIGNAL S_CLK_TXI : std_logic;
+ SIGNAL S_CLK_REF : std_logic;
+ SIGNAL S_CLEAR : std_logic;
+ SIGNAL S_SFP_LOS_IN : std_logic;
+ SIGNAL S_RX_CDR_LOL_IN : std_logic;
+ SIGNAL S_RX_LOS_IN : std_logic;
+ SIGNAL S_WA_POSITION_IN : std_logic_vector(3 downto 0);
+ SIGNAL S_LINK_TX_READY_IN : std_logic;
+ SIGNAL S_RX_DATA_IN : std_logic_vector(7 downto 0);
+ SIGNAL S_RX_K_IN : std_logic;
+-- SIGNAL S_WORD_SYNC_IN : std_logic;
+\r
+ --Outputs\r
+ SIGNAL M_RX_SERDES_RST : std_logic;
+ SIGNAL M_RX_PCS_RST : std_logic;
+ SIGNAL M_TX_DATA_OUT : std_logic_vector(7 downto 0);
+ SIGNAL M_TX_K_OUT : std_logic;
+ SIGNAL M_WORD_SYNC_OUT : std_logic;\r
+ SIGNAL M_MASTER_RESET_OUT : std_logic;\r
+ SIGNAL M_TX_RESET_OUT : std_logic;\r
+ SIGNAL M_DEBUG_OUT : std_logic_vector(31 downto 0);\r
+\r SIGNAL S_RX_SERDES_RST : std_logic;
+ SIGNAL S_RX_PCS_RST : std_logic;
+ SIGNAL S_TX_DATA_OUT : std_logic_vector(7 downto 0);
+ SIGNAL S_TX_K_OUT : std_logic;
+ SIGNAL S_WORD_SYNC_OUT : std_logic;
+ SIGNAL S_MASTER_RESET_OUT : std_logic;
+ SIGNAL S_TX_RESET_OUT : std_logic;
+ SIGNAL S_DEBUG_OUT : std_logic_vector(31 downto 0);
+
+\r
+BEGIN\r
+\r
+ -- Instantiate the Unit Under Test (UUT)\r
+ M_uut: med_sync_control_RS \r
+ GENERIC MAP(\r
+ SIM_MODE => 1,\r
+ IS_WAP_ZERO => 1,\r
+ IS_MODE => c_IS_MASTER\r
+ )\r
+ PORT MAP( \r
+ CLK_SYS => M_CLK_SYS,\r
+ CLK_RXI => M_CLK_RXI,\r
+ CLK_RXHALF => '0',\r
+ CLK_TXI => M_CLK_TXI,\r
+ CLK_REF => M_CLK_REF,\r
+ RESET => M_CLEAR,\r
+ CLEAR => M_CLEAR,\r
+ MEDIA_MED2INT => open,\r
+ MEDIA_INT2MED.data => x"0000",
+ MEDIA_INT2MED.packet_num => b"000",\r
+ MEDIA_INT2MED.dataready => '0',\r
+ MEDIA_INT2MED.ctrl_op => x"0000",
+ SFP_LOS_IN => M_SFP_LOS_IN,
+ RX_CDR_LOL_IN => M_RX_CDR_LOL_IN,
+ RX_LOS_IN => M_RX_LOS_IN,
+ WA_POSITION_IN => M_WA_POSITION_IN,\r
+ LINK_TX_READY_IN => M_LINK_TX_READY_IN,
+ RX_SERDES_RST => M_RX_SERDES_RST,
+ RX_PCS_RST => M_RX_PCS_RST,
+ TX_DATA_OUT => M_TX_DATA_OUT,\r
+ TX_K_OUT => M_TX_K_OUT,\r
+ RX_DATA_IN => M_RX_DATA_IN,\r
+ RX_K_IN => M_RX_K_IN,\r
+ WORD_SYNC_IN => M_WORD_SYNC_IN,
+ WORD_SYNC_OUT => M_WORD_SYNC_OUT,
+ TX_DLM_WORD_IN => x"00",\r
+ TX_DLM_IN => '0',\r
+ TX_RST_WORD_IN => x"00",\r
+ TX_RST_IN => '0',\r
+ RX_DLM_WORD_OUT => open,\r
+ RX_DLM_OUT => open,\r
+ RX_RST_WORD_OUT => open,\r
+ RX_RST_OUT => open,\r
+ MASTER_RESET_OUT => M_MASTER_RESET_OUT,\r
+ TX_RESET_OUT => M_TX_RESET_OUT,\r
+ STAT_TX_CONTROL => open,\r
+ STAT_RX_CONTROL => open,\r
+ DEBUG_TX_CONTROL => open,\r
+ DEBUG_RX_CONTROL => open,\r
+ STAT_RESET => open,\r
+ DEBUG_OUT => M_DEBUG_OUT\r
+ );\r
+\r
+ S_uut: med_sync_control_RS
+ GENERIC MAP(
+ SIM_MODE => 1,
+ IS_WAP_ZERO => 1,
+ IS_MODE => c_IS_SLAVE
+ )
+ PORT MAP(
+ CLK_SYS => S_CLK_SYS,
+ CLK_RXI => S_CLK_RXI,
+ CLK_RXHALF => '0',
+ CLK_TXI => S_CLK_TXI,
+ CLK_REF => S_CLK_REF,
+ RESET => S_CLEAR,
+ CLEAR => S_CLEAR,
+ MEDIA_MED2INT => open,
+ MEDIA_INT2MED.data => x"0000",
+ MEDIA_INT2MED.packet_num => b"000",
+ MEDIA_INT2MED.dataready => '0',
+ MEDIA_INT2MED.ctrl_op => x"0000",
+ SFP_LOS_IN => S_SFP_LOS_IN,
+ RX_CDR_LOL_IN => S_RX_CDR_LOL_IN,
+ RX_LOS_IN => S_RX_LOS_IN,
+ WA_POSITION_IN => S_WA_POSITION_IN,
+ LINK_TX_READY_IN => S_LINK_TX_READY_IN,
+ RX_SERDES_RST => S_RX_SERDES_RST,
+ RX_PCS_RST => S_RX_PCS_RST,
+ TX_DATA_OUT => S_TX_DATA_OUT,
+ TX_K_OUT => S_TX_K_OUT,
+ RX_DATA_IN => S_RX_DATA_IN,
+ RX_K_IN => S_RX_K_IN,
+ WORD_SYNC_IN => S_WORD_SYNC_OUT, --S_WORD_SYNC_IN,
+ WORD_SYNC_OUT => S_WORD_SYNC_OUT,
+ TX_DLM_WORD_IN => x"00",
+ TX_DLM_IN => '0',
+ TX_RST_WORD_IN => x"00",
+ TX_RST_IN => '0',
+ RX_DLM_WORD_OUT => open,
+ RX_DLM_OUT => open,
+ RX_RST_WORD_OUT => open,
+ RX_RST_OUT => open,
+ MASTER_RESET_OUT => S_MASTER_RESET_OUT,
+ TX_RESET_OUT => S_TX_RESET_OUT,
+ STAT_TX_CONTROL => open,
+ STAT_RX_CONTROL => open,
+ DEBUG_TX_CONTROL => open,
+ DEBUG_RX_CONTROL => open,
+ STAT_RESET => open,
+ DEBUG_OUT => S_DEBUG_OUT
+ );
+\r
+\r
+-- MASTER clocks\r
+CLK_200_GEN: process\r
+begin\r
+ -- 200 MHz => 5.0 ns\r
+ m_clk_ref <= '1'; wait for 2.5 ns;\r
+ m_clk_ref <= '0'; wait for 2.5 ns;\r
+end process CLK_200_GEN;\r
+\r
+-- same clock\r
+m_clk_txi <= transport m_clk_ref after 1 ns;\r
+m_clk_rxi <= transport m_clk_ref after 1 ns;\r
+\r
+CLK_100_GEN: process\r
+begin\r
+ -- 100 MHz => 10.0 ns\r
+ m_clk_sys <= '1'; wait for 5.0 ns;\r
+ m_clk_sys <= '0'; wait for 5.0 ns;\r
+end process CLK_100_GEN;\r
+\r
+-- SLAVE clocks\r
+s_clk_ref <= transport m_clk_ref after 17 ns;\r
+s_clk_txi <= transport m_clk_txi after 17 ns;
+s_clk_rxi <= transport m_clk_rxi after 17 ns;
+s_clk_sys <= transport m_clk_sys after 17 ns;\r
+\r
+-- the link\r
+s_rx_k_in <= transport m_tx_k_out after 2 ns;\r
+s_rx_data_in <= transport m_tx_data_out after 2 ns;\r
+m_rx_k_in <= transport s_tx_k_out after 2 ns;
+m_rx_data_in <= transport s_tx_data_out after 2 ns;
+\r
+TEST_BENCH_PROC: process\r
+begin\r
+\r
+ -- Setup signals\r
+ m_clear <= '1';\r
+ m_sfp_los_in <= '0';\r
+ m_rx_cdr_lol_in <= '1';\r
+ m_rx_los_in <= '1';\r
+ m_wa_position_in <= x"0";\r
+ m_link_tx_ready_in <= '0';\r
+ m_word_sync_in <= '1';\r
+\r
+ s_clear <= '1';
+ s_sfp_los_in <= '0';
+ s_rx_cdr_lol_in <= '1';
+ s_rx_los_in <= '1';
+ s_wa_position_in <= x"0";
+ s_link_tx_ready_in <= '0';
+-- s_word_sync_in <= '1';
+\r
+ -- Reset the beast\r
+ wait for 111 ns;\r
+ m_clear <= '0';
+ s_clear <= '0';
+ wait for 99 ns;\r
+\r
+ -- Tests may start here\r
+ \r
+ -- start up the master TX\r
+ wait for 333 ns;\r
+ m_link_tx_ready_in <= '1';\r
+ -- the slave receives the data stream\r
+ wait for 677 ns;\r
+ s_rx_los_in <= '0';\r
+ wait for 444 ns;
+ s_rx_cdr_lol_in <= '0';\r
+ wait until falling_edge(s_tx_reset_out);
+ -- slave TX is being taken into operation\r
+ wait for 333 ns;\r
+ s_link_tx_ready_in <= '1';\r
+ -- the master receives the data stream\r
+ -- the slave receives the data stream
+ wait for 677 ns;
+ m_rx_los_in <= '0';
+ wait for 444 ns;
+ m_rx_cdr_lol_in <= '0';
+\r
+ -- fiber removed\r
+ wait for 5 us;\r
+ s_sfp_los_in <= '1';\r
+ wait for 111 ns;\r
+ s_rx_los_in <= '1';\r
+ wait for 111 ns;\r
+ s_rx_cdr_lol_in <= '1';\r
+ wait for 111 ns;\r
+ s_link_tx_ready_in <= '0';\r
+\r
+ wait for 111 ns;
+ m_sfp_los_in <= '1';
+ wait for 111 ns;
+ m_rx_los_in <= '1';
+ wait for 111 ns;
+ m_rx_cdr_lol_in <= '1';
+\r
+ wait;\r
+ \r
+ wait for 333 ns;\r
+ m_sfp_los_in <= '0';\r
+ wait for 333 ns;\r
+ m_rx_los_in <= '0';\r
+ wait for 333 ns;\r
+ m_rx_cdr_lol_in <= '0';
+\r
+-- wait until rising_edge(s_debug_out(1));\r
+\r
+ -- startup the slave port
+ wait for 777 ns;
+ s_link_tx_ready_in <= '1';
+ wait for 333 ns;
+ s_sfp_los_in <= '0';
+ wait for 333 ns;
+ s_rx_los_in <= '0';
+ wait for 333 ns;
+ s_rx_cdr_lol_in <= '0';
+\r
+ -- Stay a while... stay forever!!!\r
+ wait;\r
+ \r
+end process TEST_BENCH_PROC;\r
+\r
+END;\r
--- /dev/null
+LIBRARY ieee;
+USE ieee.std_logic_1164.ALL;
+USE ieee.std_logic_unsigned.all;
+USE ieee.numeric_std.ALL;
+\r
+library work;
+use work.trb_net_std.all;
+--use work.trb_net_components.all;
+use work.med_sync_define_RS.all;\r
+
+ENTITY tb_rx_control_RS_vhd IS
+END tb_rx_control_RS_vhd;
+
+ARCHITECTURE behavior OF tb_rx_control_RS_vhd IS
+
+ -- Component Declaration for the Unit Under Test (UUT)
+ COMPONENT rx_control_RS IS
+ port(
+ CLK_RXI : in std_logic;
+ CLK_SYS : in std_logic;
+ RESET : in std_logic;
+ WORD_SYNC_OUT : out std_logic;
+ RX_DATA_OUT : out std_logic_vector(15 downto 0);
+ RX_PACKET_NUMBER_OUT : out std_logic_vector(2 downto 0);
+ RX_WRITE_OUT : out std_logic;
+ RX_DATA_IN : in std_logic_vector( 7 downto 0);
+ RX_K_IN : in std_logic;
+ RX_DLM_OUT : out std_logic;
+ RX_DLM_WORD_OUT : out std_logic_vector( 7 downto 0) := (others => '0');
+ RX_RST_OUT : out std_logic;
+ RX_RST_WORD_OUT : out std_logic_vector( 7 downto 0) := (others => '0');
+ LINK_RX_READY_IN : in std_logic;
+ LINK_TX_READY_IN : in std_logic;
+ LINK_HALF_DONE_IN : in std_logic;
+ LINK_FULL_DONE_IN : in std_logic;
+ DEBUG_OUT : out std_logic_vector(31 downto 0);
+ STAT_REG_OUT : out std_logic_vector(31 downto 0)
+ );\r
+ END COMPONENT rx_control_RS;
+
+ --Inputs
+ SIGNAL CLK_RXI : std_logic;
+ SIGNAL CLK_SYS : std_logic;
+ SIGNAL RESET : std_logic := '0';
+ SIGNAL RX_DATA_IN : std_logic_vector( 7 downto 0);
+ SIGNAL RX_K_IN : std_logic := '0';
+ SIGNAL LINK_RX_READY_IN : std_logic := '0';
+ SIGNAL LINK_TX_READY_IN : std_logic := '0';
+ SIGNAL LINK_HALF_DONE_IN : std_logic := '0';
+ SIGNAL LINK_FULL_DONE_IN : std_logic := '0';
+
+ --Outputs
+ SIGNAL WORD_SYNC_OUT : std_logic;
+ SIGNAL RX_DATA_OUT : std_logic_vector(15 downto 0);
+ SIGNAL RX_PACKET_NUMBER_OUT : std_logic_vector(2 downto 0);
+ SIGNAL RX_WRITE_OUT : std_logic;
+ SIGNAL RX_DLM_OUT : std_logic;
+ SIGNAL RX_DLM_WORD_OUT : std_logic_vector( 7 downto 0);
+ SIGNAL RX_RST_OUT : std_logic;
+ SIGNAL RX_RST_WORD_OUT : std_logic_vector( 7 downto 0);
+ SIGNAL DEBUG_OUT : std_logic_vector(31 downto 0);
+ SIGNAL STAT_REG_OUT : std_logic_vector(31 downto 0);
+
+BEGIN
+
+ -- Instantiate the Unit Under Test (UUT)
+ uut: rx_control_RS PORT MAP(
+ CLK_RXI => CLK_RXI,\r
+ CLK_SYS => CLK_SYS,
+ RESET => RESET,\r
+ WORD_SYNC_OUT => WORD_SYNC_OUT,
+ RX_DATA_OUT => RX_DATA_OUT,
+ RX_PACKET_NUMBER_OUT => RX_PACKET_NUMBER_OUT,
+ RX_WRITE_OUT => RX_WRITE_OUT,
+ RX_DATA_IN => RX_DATA_IN,
+ RX_K_IN => RX_K_IN,
+ RX_DLM_OUT => RX_DLM_OUT,
+ RX_DLM_WORD_OUT => RX_DLM_WORD_OUT,
+ RX_RST_OUT => RX_RST_OUT,
+ RX_RST_WORD_OUT => RX_RST_WORD_OUT,
+ LINK_RX_READY_IN => LINK_RX_READY_IN,
+ LINK_TX_READY_IN => LINK_TX_READY_IN,
+ LINK_HALF_DONE_IN => LINK_HALF_DONE_IN,
+ LINK_FULL_DONE_IN => LINK_FULL_DONE_IN,
+ DEBUG_OUT => DEBUG_OUT,\r
+ STAT_REG_OUT => STAT_REG_OUT
+ );
+
+CLK_RXI_GEN: process
+begin
+ -- 200 MHz => 5.0 ns
+ clk_rxi <= '1'; wait for 2.5 ns;
+ clk_rxi <= '0'; wait for 2.5 ns;
+end process CLK_RXI_GEN;
+\r
+CLK_SYS_GEN: process
+begin
+ -- 100 MHz => 10.0 ns
+ clk_sys <= '1'; wait for 5.0 ns;
+ clk_sys <= '0'; wait for 5.0 ns;
+end process CLK_SYS_GEN;
+
+TEST_BENCH_PROC: process
+begin
+ -- Setup signals
+ reset <= '0';\r
+ rx_data_in <= x"00";\r
+ rx_k_in <= '0';\r
+ link_rx_ready_in <= '0';
+ link_tx_ready_in <= '0';
+ link_half_done_in <= '0';
+ link_full_done_in <= '0';
+
+ wait for 77 ns;
+
+ -- Reset the beast\r
+ wait until rising_edge(clk_rxi);
+ reset <= '1';
+ wait until rising_edge(clk_rxi);
+ reset <= '0';
+ wait for 99 ns;
+\r
+ -- link reset done\r
+ wait for 222 ns;
+ link_rx_ready_in <= '1';\r
+ link_half_done_in <= '1';\r
+
+ -- RX link is ready\r
+ for I in 0 to 50 loop\r
+ wait until rising_edge(clk_rxi);\r
+ rx_k_in <= '1'; rx_data_in <= x"bc";\r
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '0'; rx_data_in <= x"50";
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '1'; rx_data_in <= x"bc";
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '0'; rx_data_in <= x"c5";
+ end loop;\r
+\r
+ link_tx_ready_in <= '1';
+\r
+ -- TX link is ready
+ for I in 0 to 50 loop
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '1'; rx_data_in <= x"bc";
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '0'; rx_data_in <= x"50";
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '1'; rx_data_in <= x"bc";
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '0'; rx_data_in <= x"c5";
+ end loop;
+\r
+ link_full_done_in <= '1';\r
+\r
+ for I in 0 to 100 loop
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '1'; rx_data_in <= x"bc";
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '0'; rx_data_in <= x"50";
+ end loop;
+\r
+ -- send DLM\r
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '1'; rx_data_in <= x"dc";
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '0'; rx_data_in <= x"00";
+\r
+ for I in 0 to 100 loop
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '1'; rx_data_in <= x"bc";
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '0'; rx_data_in <= x"50";
+ end loop;
+
+ -- send RST
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '1'; rx_data_in <= x"fe";
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '0'; rx_data_in <= x"01";
+\r
+ for I in 0 to 100 loop
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '1'; rx_data_in <= x"bc";
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '0'; rx_data_in <= x"50";
+ end loop;
+\r
+ -- a data packet\r
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '0'; rx_data_in <= x"00";
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '0'; rx_data_in <= x"55";
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '0'; rx_data_in <= x"11";
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '0'; rx_data_in <= x"22";
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '0'; rx_data_in <= x"33";
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '0'; rx_data_in <= x"44";
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '0'; rx_data_in <= x"55";
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '0'; rx_data_in <= x"66";
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '0'; rx_data_in <= x"77";
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '0'; rx_data_in <= x"88";
+\r
+\r
+ for I in 0 to 1000 loop
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '1'; rx_data_in <= x"bc";
+ wait until rising_edge(clk_rxi);
+ rx_k_in <= '0'; rx_data_in <= x"50";
+ end loop;
+
+ -- Stay a while... stay forever!!!
+ wait;
+
+end process TEST_BENCH_PROC;
+
+END;
--- /dev/null
+LIBRARY ieee;
+USE ieee.std_logic_1164.ALL;
+USE ieee.std_logic_unsigned.all;
+USE ieee.numeric_std.ALL;
+\r
+library work;
+use work.med_sync_define_RS.all;\r
+
+ENTITY tb_rx_lsm_RS_vhd IS
+END tb_rx_lsm_RS_vhd;
+
+ARCHITECTURE behavior OF tb_rx_lsm_RS_vhd IS
+
+ -- Component Declaration for the Unit Under Test (UUT)
+ COMPONENT rx_lsm_RS IS
+ port(
+ LINK_RX_READY_IN : in std_logic;
+ RXCLK : in std_logic; -- recovered RX clock
+ RX_K_IN : in std_logic;
+ RX_DATA_IN : in std_logic_vector(7 downto 0);
+ LINK_HALF_DONE_OUT : out std_logic;
+ LINK_FULL_DONE_OUT : out std_logic;
+ STATE_OUT : out std_logic_vector(3 downto 0)
+ ); \r
+ END COMPONENT rx_lsm_RS;
+
+ --Inputs
+ SIGNAL LINK_RX_READY_IN : std_logic;
+ SIGNAL RXCLK : std_logic;
+ SIGNAL RX_K_IN : std_logic;
+ SIGNAL RX_DATA_IN : std_logic_vector(7 downto 0);\r
+
+ --Outputs
+ SIGNAL LINK_HALF_DONE_OUT : std_logic;
+ SIGNAL LINK_FULL_DONE_OUT : std_logic;
+ SIGNAL STATE_OUT : std_logic_vector(3 downto 0);
+
+BEGIN
+
+ -- Instantiate the Unit Under Test (UUT)
+ uut: rx_lsm_RS \r
+ PORT MAP(
+ LINK_RX_READY_IN => LINK_RX_READY_IN,
+ RXCLK => RXCLK,\r
+ RX_K_IN => RX_K_IN,\r
+ RX_DATA_IN => RX_DATA_IN,\r
+ LINK_HALF_DONE_OUT => LINK_HALF_DONE_OUT,\r
+ LINK_FULL_DONE_OUT => LINK_FULL_DONE_OUT,\r
+ STATE_OUT => STATE_OUT\r
+ );
+
+CLK_GEN: process
+begin
+ -- 200 MHz => 5.0 ns
+ rxclk <= '1'; wait for 2.5 ns;
+ rxclk <= '0'; wait for 2.5 ns;
+end process CLK_GEN;
+\r
+TEST_BENCH_PROC: process
+begin
+ -- Setup signals
+ link_rx_ready_in <= '0';\r
+
+ -- Tests may start here\r
+\r
+ -- toggling idles\r
+ for I in 0 to 20 loop
+ wait until rising_edge(rxclk);
+ rx_k_in <= '1'; rx_data_in <= x"bc";
+ wait until rising_edge(rxclk);
+ rx_k_in <= '0'; rx_data_in <= x"50";
+ wait until rising_edge(rxclk);
+ rx_k_in <= '1'; rx_data_in <= x"bc";
+ wait until rising_edge(rxclk);
+ rx_k_in <= '0'; rx_data_in <= x"c5";
+ end loop;\r\r
+ link_rx_ready_in <= '1';\r
+\r
+ -- toggling idles
+ for I in 0 to 10 loop
+ wait until rising_edge(rxclk);
+ rx_k_in <= '1'; rx_data_in <= x"bc";
+ wait until rising_edge(rxclk);
+ rx_k_in <= '0'; rx_data_in <= x"50";
+ wait until rising_edge(rxclk);
+ rx_k_in <= '1'; rx_data_in <= x"bc";
+ wait until rising_edge(rxclk);
+ rx_k_in <= '0'; rx_data_in <= x"c5";
+ end loop;\r
+\r
+ -- one wrong komma\r
+ wait until rising_edge(rxclk);
+ rx_k_in <= '1'; rx_data_in <= x"ee";
+ wait until rising_edge(rxclk);
+ rx_k_in <= '0'; rx_data_in <= x"c5";
+\r
+ for I in 0 to 50 loop
+ wait until rising_edge(rxclk);
+ rx_k_in <= '1'; rx_data_in <= x"bc";
+ wait until rising_edge(rxclk);
+ rx_k_in <= '0'; rx_data_in <= x"50";
+ wait until rising_edge(rxclk);
+ rx_k_in <= '1'; rx_data_in <= x"bc";
+ wait until rising_edge(rxclk);
+ rx_k_in <= '0'; rx_data_in <= x"c5";
+ end loop;
+\r
+ -- steady idles
+ for I in 0 to 100 loop
+ wait until rising_edge(rxclk);
+ rx_k_in <= '1'; rx_data_in <= x"bc";
+ wait until rising_edge(rxclk);
+ rx_k_in <= '0'; rx_data_in <= x"50";
+ wait until rising_edge(rxclk);
+ rx_k_in <= '1'; rx_data_in <= x"bc";
+ wait until rising_edge(rxclk);
+ rx_k_in <= '0'; rx_data_in <= x"50";
+ end loop;
+\r
+ wait until rising_edge(rxclk);\r
+ link_rx_ready_in <= '0';
+ \r
+
+ -- Stay a while... stay forever!!!
+ wait;
+
+end process TEST_BENCH_PROC;
+
+END;
--- /dev/null
+LIBRARY ieee;
+USE ieee.std_logic_1164.ALL;
+USE ieee.std_logic_unsigned.all;
+USE ieee.numeric_std.ALL;
+\r
+library work;
+use work.trb_net_std.all;
+--use work.trb_net_components.all;
+use work.med_sync_define_RS.all;\r
+
+ENTITY tb_tx_control_RS_vhd IS
+END tb_tx_control_RS_vhd;
+
+ARCHITECTURE behavior OF tb_tx_control_RS_vhd IS
+
+ -- Component Declaration for the Unit Under Test (UUT)
+ COMPONENT tx_control_RS IS
+ generic(
+ SIM_MODE : integer := 0;
+ IS_MODE : integer := c_IS_UNUSED
+ );
+ port(
+ CLK_TX : in std_logic;
+ CLK_SYS : in std_logic;
+ RESET : in std_logic;
+ TX_DATA_IN : in std_logic_vector(15 downto 0);
+ TX_PACKET_NUMBER_IN : in std_logic_vector(2 downto 0);
+ TX_WRITE_IN : in std_logic;
+ TX_READ_OUT : out std_logic;
+ TX_DATA_OUT : out std_logic_vector(7 downto 0);
+ TX_K_OUT : out std_logic;
+ WORD_SYNC_IN : in std_logic;
+ SEND_DLM_IN : in std_logic;
+ SEND_DLM_WORD_IN : in std_logic_vector(7 downto 0);
+ SEND_RST_IN : in std_logic;
+ SEND_RST_WORD_IN : in std_logic_vector(7 downto 0);
+ LINK_TX_READY_IN : in std_logic;
+ LINK_RX_READY_IN : in std_logic;
+ LINK_HALF_DONE_IN : in std_logic;
+ LINK_FULL_DONE_IN : in std_logic;
+ DEBUG_OUT : out std_logic_vector(31 downto 0);
+ STAT_REG_OUT : out std_logic_vector(31 downto 0)
+ ); \r
+ END COMPONENT tx_control_RS;
+\r
+ --Inputs
+ SIGNAL CLK_TX : std_logic;
+ SIGNAL CLK_SYS : std_logic;
+ SIGNAL RESET : std_logic := '0';
+ SIGNAL WORD_SYNC_IN : std_logic := '0';
+ SIGNAL TX_DATA_IN : std_logic_vector(15 downto 0) := x"0000";
+ SIGNAL TX_PACKET_NUMBER_IN : std_logic_vector(2 downto 0) := b"000";
+ SIGNAL TX_WRITE_IN : std_logic := '0';
+ SIGNAL SEND_DLM_IN : std_logic := '0';
+ SIGNAL SEND_DLM_WORD_IN : std_logic_vector(7 downto 0) := x"00";
+ SIGNAL SEND_RST_IN : std_logic := '0';
+ SIGNAL SEND_RST_WORD_IN : std_logic_vector(7 downto 0) := x"00";
+ SIGNAL LINK_TX_READY_IN : std_logic := '0';
+ SIGNAL LINK_RX_READY_IN : std_logic := '0';
+ SIGNAL LINK_HALF_DONE_IN : std_logic := '0';
+ SIGNAL LINK_FULL_DONE_IN : std_logic := '0';
+
+ --Outputs
+ SIGNAL TX_READ_OUT : std_logic;
+ SIGNAL TX_DATA_OUT : std_logic_vector( 7 downto 0);
+ SIGNAL TX_K_OUT : std_logic;
+ SIGNAL DEBUG_OUT : std_logic_vector(31 downto 0);
+ SIGNAL STAT_REG_OUT : std_logic_vector(31 downto 0);
+
+BEGIN
+
+ -- Instantiate the Unit Under Test (UUT)
+ uut: tx_control_RS PORT MAP(
+ CLK_TX => CLK_TX,\r
+ CLK_SYS => CLK_SYS,
+ RESET => RESET,\r
+ WORD_SYNC_IN => WORD_SYNC_IN,
+ TX_DATA_IN => TX_DATA_IN,\r
+ TX_PACKET_NUMBER_IN => TX_PACKET_NUMBER_IN,
+ TX_WRITE_IN => TX_WRITE_IN,
+ TX_READ_OUT => TX_READ_OUT,\r
+ TX_DATA_OUT => TX_DATA_OUT,\r
+ TX_K_OUT => TX_K_OUT,\r
+ SEND_DLM_IN => SEND_DLM_IN,
+ SEND_DLM_WORD_IN => SEND_DLM_WORD_IN,
+ SEND_RST_IN => SEND_RST_IN,
+ SEND_RST_WORD_IN => SEND_RST_WORD_IN,\r
+ LINK_TX_READY_IN => LINK_TX_READY_IN,
+ LINK_RX_READY_IN => LINK_RX_READY_IN,
+ LINK_HALF_DONE_IN => LINK_HALF_DONE_IN,
+ LINK_FULL_DONE_IN => LINK_FULL_DONE_IN,
+ DEBUG_OUT => DEBUG_OUT,\r
+ STAT_REG_OUT => STAT_REG_OUT
+ );
+
+CLK_TX_GEN: process
+begin
+ -- 200 MHz => 5.0 ns
+ clk_tx <= '1'; wait for 2.5 ns;
+ clk_tx <= '0'; wait for 2.5 ns;
+end process CLK_TX_GEN;
+\r
+CLK_SYS_GEN: process
+begin
+ -- 100 MHz => 10.0 ns
+ clk_SYS <= '1'; wait for 5.0 ns;
+ clk_SYS <= '0'; wait for 5.0 ns;
+end process CLK_SYS_GEN;\r
+
+TEST_BENCH_PROC: process
+begin
+ -- Setup signals
+ reset <= '0';\r
+ word_sync_in <= '1';\r
+
+ wait for 77 ns;
+
+ -- Reset the beast\r
+ wait until rising_edge(clk_tx);
+ reset <= '1';
+ wait until rising_edge(clk_tx);
+ reset <= '0';
+ wait for 99 ns;
+
+ -- Tests may start here\r
+ wait for 333 ns;\r
+ link_rx_ready_in <= '1';\r
+ wait for 333 ns;
+ link_tx_ready_in <= '1';
+ wait for 333 ns;
+ link_half_done_in <= '1';
+ wait for 333 ns;
+ link_full_done_in <= '1';
+\r
+ wait for 333 ns;
+ wait until rising_edge(clk_tx);
+ send_dlm_in <= '1';\r
+ send_dlm_word_in <= x"aa";
+ wait until rising_edge(clk_tx);
+ send_dlm_in <= '0';
+ send_dlm_word_in <= x"00";\r
+\r
+ wait for 111 ns;
+ wait until rising_edge(clk_tx);
+ send_rst_in <= '1';
+ send_rst_word_in <= x"01";
+ wait until rising_edge(clk_tx);
+ send_rst_in <= '0';
+ send_rst_word_in <= x"00";
+\r
+ wait for 111 ns;
+ wait until rising_edge(clk_tx);
+ send_rst_in <= '1';
+ send_rst_word_in <= x"02";
+ wait until rising_edge(clk_tx);
+ send_rst_in <= '0';
+ send_rst_word_in <= x"00";
+\r
+ wait for 111 ns;
+ wait until rising_edge(clk_sys);
+ tx_packet_number_in <= b"100";\r
+ tx_data_in <= x"0055";\r
+ tx_write_in <= '1';\r
+ wait until rising_edge(clk_sys);
+ tx_packet_number_in <= b"000";
+ tx_data_in <= x"abcd";
+ tx_write_in <= '1';
+ wait until rising_edge(clk_sys);
+ tx_packet_number_in <= b"001";
+ tx_data_in <= x"1122";
+ tx_write_in <= '1';
+ wait until rising_edge(clk_sys);
+ tx_packet_number_in <= b"010";
+ tx_data_in <= x"3344";
+ tx_write_in <= '1';
+ wait until rising_edge(clk_sys);
+ tx_packet_number_in <= b"011";
+ tx_data_in <= x"55ff";
+ tx_write_in <= '1';
+ wait until rising_edge(clk_sys);
+ tx_packet_number_in <= b"100";
+ tx_data_in <= x"0000";
+ tx_write_in <= '0';
+
+ -- Stay a while... stay forever!!!
+ wait;
+
+end process TEST_BENCH_PROC;
+
+END;
library work;
use work.trb_net_std.all;
-use work.trb_net_components.all;
+--use work.trb_net_components.all;
use work.med_sync_define_RS.all;
+\r
+-- BUG: must be kept in reset while LINK_TX_READY_IN = '0' !\r
entity tx_control_RS is
+ generic(
+ SIM_MODE : integer := 0;\r
+ IS_MODE : integer := c_IS_UNUSED
+ );\r
port(
- CLK_200 : in std_logic;
- CLK_100 : in std_logic;
- RESET_IN : in std_logic;
-
- -- CLK_100 signals
- TX_DATA_IN : in std_logic_vector(15 downto 0);
- TX_PACKET_NUMBER_IN : in std_logic_vector(2 downto 0);
- TX_WRITE_IN : in std_logic;
- TX_READ_OUT : out std_logic;
-
- -- CLK_200 signals
- TX_DATA_OUT : out std_logic_vector(7 downto 0);
- TX_K_OUT : out std_logic;
- TX_CD_OUT : out std_logic;
-
- WORD_SYNC_IN : in std_logic;
-
+ CLK_TX : in std_logic;
+ CLK_SYS : in std_logic;
+ RESET : in std_logic; -- async/sync reset
+ -- Media Interface
+ TX_DATA_IN : in std_logic_vector(15 downto 0); -- media interface
+ TX_PACKET_NUMBER_IN : in std_logic_vector(2 downto 0); -- media interface
+ TX_WRITE_IN : in std_logic; -- media interface
+ TX_READ_OUT : out std_logic; -- media interface
+ -- SerDes data stream
+ TX_DATA_OUT : out std_logic_vector(7 downto 0); -- to TX SerDes
+ TX_K_OUT : out std_logic; -- to TX SerDes
+ -- synchronous signals
+ WORD_SYNC_IN : in std_logic; -- byte/word sync
SEND_DLM_IN : in std_logic;
SEND_DLM_WORD_IN : in std_logic_vector(7 downto 0);
-
SEND_RST_IN : in std_logic;
- SEND_RST_WORD_IN : in std_logic_vector(7 downto 0);
-
- -- internally synced
- TX_ALLOW_IN : in std_logic := '0';
- RX_ALLOW_IN : in std_logic := '0';
-
- -- unknown clock
+ SEND_RST_WORD_IN : in std_logic_vector(7 downto 0);\r
+ -- link status signals, internally synced\r
+ LINK_TX_READY_IN : in std_logic; -- local ref clock\r
+ LINK_RX_READY_IN : in std_logic; -- local ref clock\r
+ LINK_HALF_DONE_IN : in std_logic; -- recovered RX clock\r
+ LINK_FULL_DONE_IN : in std_logic; -- recovered RX clock
+ -- debug
DEBUG_OUT : out std_logic_vector(31 downto 0);
STAT_REG_OUT : out std_logic_vector(31 downto 0)
);
architecture arch of tx_control_RS is
- type state_t is (SEND_IDLE_L, SEND_IDLE_H, SEND_DATA_L, SEND_DATA_H, SEND_DLM_L, SEND_DLM_H,
- SEND_RST_L, SEND_RST_H);
+ type state_t is (IDLE, SEND_IDLE_L, SEND_IDLE_H, SEND_DATA_L, SEND_DATA_H, \r
+ SEND_DLM_L, SEND_DLM_H, SEND_RST_L, SEND_RST_H);
signal current_state : state_t;
signal state_bits : std_logic_vector(3 downto 0);
signal buf_tx_read_out : std_logic;
signal tx_data_200 : std_logic_vector(17 downto 0);
- signal tx_allow_qtx : std_logic;
- signal rx_allow_qtx : std_logic;
- signal tx_allow_q : std_logic;
signal ct_fifo_empty : std_logic;
signal ct_fifo_write : std_logic := '0';
signal ct_fifo_read : std_logic := '0';
signal save_eop : std_logic;
signal load_sop : std_logic;
signal load_eop : std_logic;
- signal first_idle : std_logic;
signal toggle_idle : std_logic;
-
+ \r
+ signal link_tx_ready_qtx : std_logic;\r
+ signal link_rx_ready_qtx : std_logic;
+ signal link_half_done_qtx : std_logic;
+ signal link_full_done_qtx : std_logic;\r
+ signal link_active_int : std_logic;
+ signal link_active_qtx : std_logic;
+ signal link_active_qsys : std_logic;\r
+\r
+ signal send_steady_idle_int : std_logic;\r
+
begin
+\r
+-- Sync\r
+ SYNC_STATUS_SIGS : entity work.signal_sync
+ generic map(
+ WIDTH => 4,
+ DEPTH => 3
+ )
+ port map(
+ RESET => '0',
+ CLK0 => CLK_TX,
+ CLK1 => CLK_TX,
+ D_IN(0) => LINK_TX_READY_IN,
+ D_IN(1) => LINK_RX_READY_IN,
+ D_IN(2) => LINK_HALF_DONE_IN,
+ D_IN(3) => LINK_FULL_DONE_IN,
+ D_OUT(0) => link_tx_ready_qtx,
+ D_OUT(1) => link_rx_ready_qtx,
+ D_OUT(2) => link_half_done_qtx,
+ D_OUT(3) => link_full_done_qtx
+ );
+\r
+ -- Payload is only allowed on fully active links\r
+ link_active_int <= link_tx_ready_qtx and link_rx_ready_qtx and
+ link_half_done_qtx and link_full_done_qtx;
+\r
+ link_active_qtx <= link_active_int when rising_edge(CLK_TX);\r
+\r
+ -- if not set, send toggling idles\r
+ send_steady_idle_int <= link_tx_ready_qtx and link_rx_ready_qtx and \r
+ link_half_done_qtx when (IS_MODE = c_IS_MASTER) else\r
+ link_tx_ready_qtx and link_rx_ready_qtx and\r
+ link_half_done_qtx and link_full_done_qtx when (IS_MODE = c_IS_SLAVE) else\r
+ '0';\r
+\r
+ SYNC_SYSCLK : entity work.signal_sync
+ generic map(
+ WIDTH => 1,
+ DEPTH => 3
+ )
+ port map(
+ RESET => '0',
+ CLK0 => CLK_SYS,
+ CLK1 => CLK_SYS,
+ D_IN(0) => link_active_int,
+ D_OUT(0) => link_active_qsys
+ );
----------------------------------------------------------------------
-- Clock Domain Transfer
Data(15 downto 0) => TX_DATA_IN,
Data(16) => save_sop,
Data(17) => save_eop,
- WrClock => CLK_100,
- RdClock => CLK_200,
+ WrClock => CLK_SYS,
+ RdClock => CLK_TX,
WrEn => ct_fifo_write,
RdEn => ct_fifo_read,
Reset => ct_fifo_reset,
AlmostFull => ct_fifo_afull
);
- THE_RD_PROC : process(CLK_100)
+ THE_RD_PROC : process(CLK_SYS)
begin
- if rising_edge(CLK_100) then
- buf_tx_read_out <= tx_allow_q and not ct_fifo_afull ;
+ if rising_edge(CLK_SYS) then
+ buf_tx_read_out <= link_active_qsys and not ct_fifo_afull ;
end if;
end process;
- ct_fifo_reset <= not tx_allow_qtx;
+ ct_fifo_reset <= not link_active_qtx;
TX_READ_OUT <= buf_tx_read_out;
ct_fifo_write <= buf_tx_read_out and TX_WRITE_IN;
- ct_fifo_read <= tx_allow_qtx and not ram_afull and not ct_fifo_empty;
+ ct_fifo_read <= link_active_qtx and not ram_afull and not ct_fifo_empty;
- last_ct_fifo_read <= ct_fifo_read when rising_edge(CLK_200);
- last_ct_fifo_empty <= ct_fifo_empty when rising_edge(CLK_200);
+ last_ct_fifo_read <= ct_fifo_read when rising_edge(CLK_TX);
+ last_ct_fifo_empty <= ct_fifo_empty when rising_edge(CLK_TX);
save_sop <= '1' when (TX_PACKET_NUMBER_IN = c_H0) else '0';
save_eop <= '1' when (TX_PACKET_NUMBER_IN = c_F3) else '0';
----------------------------------------------------------------------
-- RAM
----------------------------------------------------------------------
- THE_RAM_WR_PROC : process(CLK_200)
+ THE_RAM_WR_PROC : process(CLK_TX)
begin
- if rising_edge(CLK_200) then
+ if( rising_edge(CLK_TX) ) then
ram_write <= last_ct_fifo_read and not last_ct_fifo_empty;
end if;
end process;
--RAM
- THE_RAM_PROC : process(CLK_200)
+ THE_RAM_PROC : process(CLK_TX)
begin
- if rising_edge(CLK_200) then
- if ram_write = '1' then
+ if( rising_edge(CLK_TX) ) then
+ if( ram_write = '1' ) then
ram((to_integer(ram_write_addr))) <= tx_data_200;
end if;
next_ram_dout <= ram(to_integer(ram_read_addr));
end process;
--RAM read pointer
- THE_READ_CNT : process(CLK_200)
+ THE_READ_CNT : process(CLK_TX)
begin
- if rising_edge(CLK_200) then
- if tx_allow_qtx = '0' then
+ if( rising_edge(CLK_TX) ) then
+ if( link_active_qtx = '0' ) then
ram_read_addr <= (others => '0');
- elsif ram_read = '1' then
+ elsif( ram_read = '1' ) then
ram_read_addr <= ram_read_addr + to_unsigned(1,1);
end if;
end if;
end process;
--RAM write pointer
- THE_WRITE_CNT : process(CLK_200)
+ THE_WRITE_CNT : process(CLK_TX)
begin
- if rising_edge(CLK_200) then
- if tx_allow_qtx = '0' then
+ if( rising_edge(CLK_TX) ) then
+ if( link_active_qtx = '0' ) then
ram_write_addr <= (others => '0');
- elsif ram_write = '1' then
+ elsif( ram_write = '1' ) then
ram_write_addr <= ram_write_addr + to_unsigned(1,1);
end if;
end if;
end process;
--RAM fill level counter
- THE_FILL_CNT : process(CLK_200)
+ THE_FILL_CNT : process(CLK_TX)
begin
- if rising_edge(CLK_200) then
- if tx_allow_qtx = '0' then
+ if( rising_edge(CLK_TX) ) then
+ if( link_active_qtx = '0' ) then
ram_fill_level <= (others => '0');
else
ram_fill_level <= last_ram_write_addr - ram_read_addr;
end process;
--RAM empty
- ram_empty <= '1' when (last_ram_write_addr = ram_read_addr) or RESET_IN = '1' else '0';
+ ram_empty <= '1' when (last_ram_write_addr = ram_read_addr) or RESET = '1' else '0';
ram_afull <= '1' when ram_fill_level >= 4 else '0';
- last_ram_write_addr <= ram_write_addr when rising_edge(CLK_200);
+ last_ram_write_addr <= ram_write_addr when rising_edge(CLK_TX);
----------------------------------------------------------------------
-- TX control state machine
----------------------------------------------------------------------
- THE_DATA_CONTROL_FSM : process(CLK_200, RESET_IN)
- begin
- if rising_edge(CLK_200) then
- TX_K_OUT <= '0';
- TX_CD_OUT <= '0';
- debug_sending_dlm <= '0';
- debug_sending_rst <= '0';
- first_idle <= '1';
- case current_state is
- when SEND_IDLE_L =>
- TX_DATA_OUT <= K_IDLE;
- TX_K_OUT <= '1';
- if WORD_SYNC_IN = '1' then
- current_state <= SEND_IDLE_H;
- else
+ THE_DATA_CONTROL_FSM : process(CLK_TX, LINK_TX_READY_IN, RESET)
+ begin\r
+ if( (LINK_TX_READY_IN = '0') or (RESET = '1') ) then\r
+ current_state <= IDLE;\r
+ TX_K_OUT <= '1';\r
+ TX_DATA_OUT <= K_NULL;\r
+ else \r
+ if( rising_edge(CLK_TX) ) then
+ TX_K_OUT <= '0';
+ debug_sending_dlm <= '0';
+ debug_sending_rst <= '0';
+ case current_state is
+ when SEND_IDLE_L =>
+ TX_DATA_OUT <= K_IDLE;
+ TX_K_OUT <= '1';
+ if( WORD_SYNC_IN = '1' )then
+ current_state <= SEND_IDLE_H;
+ else
+ current_state <= SEND_IDLE_L;
+ end if;
+
+ when SEND_IDLE_H =>
+ if( (send_steady_idle_int = '1') or (toggle_idle = '1') ) then
+ TX_DATA_OUT <= D_IDLE1;
+ toggle_idle <= send_steady_idle_int;
+ else
+ TX_DATA_OUT <= D_IDLE0;
+ toggle_idle <= '1';
+ end if;
+
+ when SEND_DATA_L =>
+ TX_DATA_OUT <= ram_dout(7 downto 0);
+ load_sop <= ram_dout(16);
+ load_eop <= ram_dout(17);
+ current_state <= SEND_DATA_H;
+
+ when SEND_DATA_H =>
+ TX_DATA_OUT <= ram_dout(15 downto 8);
+
+ when SEND_DLM_L =>
+ TX_DATA_OUT <= K_DLM;
+ TX_K_OUT <= '1';
+ current_state <= SEND_DLM_H;
+ debug_sending_dlm <= '1';
+
+ when SEND_DLM_H =>
+ TX_DATA_OUT <= send_dlm_word_i;
+
+ when SEND_RST_L =>
+ TX_DATA_OUT <= K_RST;
+ TX_K_OUT <= '1';
+ current_state <= SEND_RST_H;
+ debug_sending_rst <= '1';
+\r
+ when IDLE =>\r
+ TX_DATA_OUT <= K_NULL;\r
+ TX_K_OUT <= '1';\r
+ current_state <= SEND_IDLE_L;\r
+ -- used to get out of async reset
+
+ when SEND_RST_H =>
+ TX_DATA_OUT <= send_rst_word_i;
+\r
+ when others =>
current_state <= SEND_IDLE_L;
- end if;
- first_idle <= first_idle;
-
- when SEND_IDLE_H =>
- if rx_allow_qtx = '1' or toggle_idle = '1' then
- TX_DATA_OUT <= D_IDLE1;
- toggle_idle <= rx_allow_qtx;
+ end case;
+
+ if( (current_state = SEND_IDLE_H) or (current_state = SEND_DATA_H) or
+ (current_state = SEND_DLM_H) or (current_state = SEND_RST_H) ) then
+ if ( link_active_qtx = '0' ) then
+ current_state <= SEND_IDLE_L;
+ elsif( send_dlm_i = '1' ) then
+ current_state <= SEND_DLM_L;
+ elsif( send_rst_i = '1' ) then
+ current_state <= SEND_RST_L;
+ elsif( ram_empty = '0' ) then
+ current_state <= SEND_DATA_L;
else
- TX_DATA_OUT <= D_IDLE0;
- toggle_idle <= '1';
+ current_state <= SEND_IDLE_L;
end if;
- TX_CD_OUT <= first_idle;
- first_idle <= '0';
-
- when SEND_DATA_L =>
- TX_DATA_OUT <= ram_dout(7 downto 0);
- load_sop <= ram_dout(16);
- load_eop <= ram_dout(17);
- current_state <= SEND_DATA_H;
-
- when SEND_DATA_H =>
- TX_DATA_OUT <= ram_dout(15 downto 8);
-
- when SEND_DLM_L =>
- TX_DATA_OUT <= K_DLM;
- TX_K_OUT <= '1';
- current_state <= SEND_DLM_H;
- debug_sending_dlm <= '1';
-
- when SEND_DLM_H =>
- TX_DATA_OUT <= send_dlm_word_i;
-
- when SEND_RST_L =>
- TX_DATA_OUT <= K_RST;
- TX_K_OUT <= '1';
- current_state <= SEND_RST_H;
- debug_sending_rst <= '1';
-
- when SEND_RST_H =>
- TX_DATA_OUT <= send_rst_word_i;
-
- when others =>
- current_state <= SEND_IDLE_L;
- end case;
-
- if current_state = SEND_IDLE_H or
- current_state = SEND_DATA_H or
- current_state = SEND_DLM_H or
- current_state = SEND_RST_H then
- if tx_allow_qtx = '0' then
- current_state <= SEND_IDLE_L;
- elsif send_dlm_i = '1' then
- current_state <= SEND_DLM_L;
- elsif send_rst_i = '1' then
- current_state <= SEND_RST_L;
- elsif ram_empty = '0' then
- current_state <= SEND_DATA_L;
- else
- current_state <= SEND_IDLE_L;
- end if;
+ end if;
end if;
- end if;
- --async because of oreg.
- if (current_state = SEND_IDLE_H or current_state = SEND_DATA_H or current_state = SEND_DLM_H or current_state = SEND_RST_H)
- and ram_empty = '0' and tx_allow_qtx = '1' and send_dlm_i = '0' and send_rst_i = '0' then
+ end if;\r
+\r
+ --async because of oreg.
+ if ((current_state = SEND_IDLE_H) or (current_state = SEND_DATA_H) or (current_state = SEND_DLM_H) or (current_state = SEND_RST_H))
+ and (ram_empty = '0') and (link_active_qtx = '1') and (send_dlm_i = '0') and (send_rst_i = '0') then
ram_read <= '1';
else
ram_read <= '0';
end if;
- if RESET_IN = '1' then
- ram_read <= '0';
- end if;
+ if RESET = '1' then
+ ram_read <= '0';\r
+ end if;\r
+
end process;
+\r
----------------------------------------------------------------------
--
----------------------------------------------------------------------
- txallow_sync : signal_sync port map(RESET => '0',CLK0 => CLK_200, CLK1 => CLK_200,
- D_IN(0) => TX_ALLOW_IN,
- D_OUT(0) => tx_allow_qtx);
- rxallow_sync : signal_sync port map(RESET => '0',CLK0 => CLK_200, CLK1 => CLK_200,
- D_IN(0) => RX_ALLOW_IN,
- D_OUT(0) => rx_allow_qtx);
- txallow_sync2 : signal_sync port map(RESET => '0',CLK0 => CLK_100, CLK1 => CLK_100,
- D_IN(0) => tx_allow_qtx,
- D_OUT(0) => tx_allow_q);
-
--Send DLM message
- THE_STORE_DLM_PROC: process( CLK_200, RESET_IN )
+ THE_STORE_DLM_PROC: process( CLK_TX, RESET )
begin
- if( RESET_IN = '1' ) then
+ if( RESET = '1' ) then
send_dlm_i <= '0';
send_dlm_word_i <= (others => '0');
- elsif( rising_edge(CLK_200) ) then
- if ( tx_allow_qtx = '0' ) then
+ elsif( rising_edge(CLK_TX) ) then
+ if ( link_active_qtx = '0' ) then
send_dlm_i <= '0';
send_dlm_word_i <= (others => '0');
elsif( SEND_DLM_IN = '1' ) then
send_dlm_word_i <= SEND_DLM_WORD_IN;
elsif( current_state = SEND_DLM_L ) then
send_dlm_i <= '0';
- elsif( current_state = SEND_DLM_H ) then
+ elsif( current_state = SEND_DLM_H ) then
send_dlm_word_i <= (others => '0');
end if;
end if;
end process THE_STORE_DLM_PROC;
--Send RST message
- THE_STORE_RST_PROC: process( CLK_200, RESET_IN )
+ THE_STORE_RST_PROC: process( CLK_TX, RESET )
begin
- if( RESET_IN = '1' ) then
+ if( RESET = '1' ) then
send_rst_i <= '0';
send_rst_word_i <= (others => '0');
- elsif( rising_edge(CLK_200) ) then
- if ( tx_allow_qtx = '0' ) then
+ elsif( rising_edge(CLK_TX) ) then
+ if ( link_active_qtx = '0' ) then
send_rst_i <= '0';
send_rst_word_i <= (others => '0');
elsif( SEND_RST_IN = '1' ) then
send_rst_word_i <= SEND_RST_WORD_IN;
elsif( current_state = SEND_RST_L ) then
send_rst_i <= '0';
- elsif( current_state = SEND_RST_H ) then
+ elsif( current_state = SEND_RST_H ) then
send_rst_word_i <= (others => '0');
end if;
end if;
----------------------------------------------------------------------
-- Debug
----------------------------------------------------------------------
- DEBUG_OUT(31) <= debug_sending_dlm when rising_edge(CLK_200);
+ DEBUG_OUT(31) <= debug_sending_dlm when rising_edge(CLK_TX);
DEBUG_OUT(30) <= send_dlm_i;
- DEBUG_OUT(29) <= debug_sending_rst when rising_edge(CLK_200);
+ DEBUG_OUT(29) <= debug_sending_rst when rising_edge(CLK_TX);
DEBUG_OUT(28 downto 0) <= (others => '0');
- process(CLK_100)
+ process(CLK_SYS)
begin
- if rising_edge(CLK_100) then
+ if rising_edge(CLK_SYS) then
-- STAT_REG_OUT <= (others => '0');
STAT_REG_OUT(3 downto 0) <= state_bits;
STAT_REG_OUT(7 downto 4) <= (others => '0');
STAT_REG_OUT(15 downto 8) <= std_logic_vector(ram_read_addr);
STAT_REG_OUT(17) <= ram_empty;
- STAT_REG_OUT(18) <= tx_allow_qtx;
- STAT_REG_OUT(19) <= TX_ALLOW_IN;
+ STAT_REG_OUT(18) <= link_active_qsys;
+ STAT_REG_OUT(19) <= '0';
STAT_REG_OUT(21 downto 20) <= (others => '0');
STAT_REG_OUT(22) <= load_eop;
STAT_REG_OUT(23) <= send_dlm_i;
STAT_REG_OUT(27) <= ct_fifo_afull;
STAT_REG_OUT(28) <= ct_fifo_read;
STAT_REG_OUT(29) <= ct_fifo_write;
- STAT_REG_OUT(30) <= RESET_IN;
+ STAT_REG_OUT(30) <= RESET;
STAT_REG_OUT(31) <= '0';
end if;
end process;
-state_bits <= x"0" when current_state = SEND_IDLE_L else
- x"1" when current_state = SEND_IDLE_H else
- x"2" when current_state = SEND_DATA_L else
- x"3" when current_state = SEND_DATA_H else
- x"4" when current_state = SEND_DLM_L else
- x"5" when current_state = SEND_DLM_H else
+state_bits <= x"0" when current_state = IDLE else
+ x"1" when current_state = SEND_IDLE_L else
+ x"2" when current_state = SEND_IDLE_H else
+ x"3" when current_state = SEND_DATA_L else
+ x"4" when current_state = SEND_DATA_H else
+ x"5" when current_state = SEND_DLM_L else
+ x"6" when current_state = SEND_DLM_H else
x"F";
end architecture;
end if;
when others =>
- ns <= QUAD_RESET;
+ ns <= QUAD_RESET;
end case;