From f701105f954a630a7b2d748c033f3d4e8d822594 Mon Sep 17 00:00:00 2001 From: Michael Boehmer Date: Thu, 25 Nov 2021 10:05:11 +0100 Subject: [PATCH] simulated files for _RS operation --- media_interfaces/sync/main_rx_reset_RS.vhd | 242 +++++++++ media_interfaces/sync/main_tx_reset_RS.vhd | 239 +++++++++ media_interfaces/sync/med_sync_control_RS.vhd | 507 +++++++----------- media_interfaces/sync/med_sync_define_RS.vhd | 250 +++++---- media_interfaces/sync/rx_control_RS.vhd | 422 ++++++++------- media_interfaces/sync/rx_lsm_RS.vhd | 187 +++++++ media_interfaces/sync/rx_reset_fsm_RS.vhd | 38 +- .../sync/tb/tb_main_rx_reset_RS.vhd | 116 ++++ .../sync/tb/tb_main_tx_reset_RS.vhd | 116 ++++ .../sync/tb/tb_med_sync_control_RS.vhd | 338 ++++++++++++ media_interfaces/sync/tb/tb_rx_control_RS.vhd | 224 ++++++++ media_interfaces/sync/tb/tb_rx_lsm_RS.vhd | 129 +++++ media_interfaces/sync/tb/tb_tx_control_RS.vhd | 190 +++++++ media_interfaces/sync/tx_control_RS.vhd | 398 ++++++++------ media_interfaces/sync/tx_reset_fsm_RS.vhd | 2 +- 15 files changed, 2597 insertions(+), 801 deletions(-) create mode 100644 media_interfaces/sync/main_rx_reset_RS.vhd create mode 100644 media_interfaces/sync/main_tx_reset_RS.vhd create mode 100644 media_interfaces/sync/rx_lsm_RS.vhd create mode 100644 media_interfaces/sync/tb/tb_main_rx_reset_RS.vhd create mode 100644 media_interfaces/sync/tb/tb_main_tx_reset_RS.vhd create mode 100644 media_interfaces/sync/tb/tb_med_sync_control_RS.vhd create mode 100644 media_interfaces/sync/tb/tb_rx_control_RS.vhd create mode 100644 media_interfaces/sync/tb/tb_rx_lsm_RS.vhd create mode 100644 media_interfaces/sync/tb/tb_tx_control_RS.vhd diff --git a/media_interfaces/sync/main_rx_reset_RS.vhd b/media_interfaces/sync/main_rx_reset_RS.vhd new file mode 100644 index 0000000..8763a8f --- /dev/null +++ b/media_interfaces/sync/main_rx_reset_RS.vhd @@ -0,0 +1,242 @@ +--Media interface RX state machine + +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.all; + +library work; +use work.trb_net_std.all; +--use work.trb_net_components.all; +use work.med_sync_define_RS.all; + +entity main_rx_reset_RS is + generic( + SIM_MODE : integer := 0; + IS_WAP_ZERO : integer := 0; + IS_MODE : integer := c_IS_SLAVE ); + 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 entity; + +-- IS_WAP_ZERO could be moved into med_ecpX_sfp_sync... + +architecture main_rx_reset_arch of main_rx_reset_RS is + + -- We use two different timing for simulation and real world. + -- Using SIM_MODE for implementation will most likely kill the link. + 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 + + 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 + + GEN_WAP_SYNC : if (IS_WAP_ZERO = 1) generate + -- sync WAP + 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; + + GEN_WAP_FIXED: if (IS_WAP_ZERO = 0) generate + wa_position_q <= x"0"; + end generate GEN_WAP_FIXED; + + -- sync SerDes signals + SYNC_SERDES_SIGS : entity work.signal_sync + generic map( + WIDTH => 4, + DEPTH => 3 + ) + 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, + 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, + D_OUT(3) => sfp_los_q + ); + + MASTER_RESET_OUT <= sfp_los_q when (IS_MODE = c_IS_SLAVE) else '0'; + + 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; + + timer2 <= counter2(count2_index); + + -- 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 + 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'; + reset_timer2 <= '1'; + if( (tx_pll_lol_q = '1') or (rx_los_low_q = '1') ) then + NEXT_STATE <= WAIT_FOR_PLOL; + 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'; + 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'; + 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; + 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 + 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; + reset_timer2 <= '1'; + else + NEXT_STATE <= NORMAL; + 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'; + 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; + reset_timer2 <= '1'; + + end case; + + end process THE_FSM_DECODE_PROC; + +end architecture; diff --git a/media_interfaces/sync/main_tx_reset_RS.vhd b/media_interfaces/sync/main_tx_reset_RS.vhd new file mode 100644 index 0000000..683bda2 --- /dev/null +++ b/media_interfaces/sync/main_tx_reset_RS.vhd @@ -0,0 +1,239 @@ +--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 + 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 entity; + +architecture main_tx_reset_RS_arch of main_tx_reset_RS is + + -- We use two different timing for simulation and real world. + -- 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 + + signal tx_pcs_rst_ch_c_int : std_logic; + signal rst_qd_c_int : std_logic; + signal sync_tx_quad_int : std_logic; + signal link_tx_ready_int : std_logic; + signal sync_tx_quad_trans : std_logic; + + signal tx_pll_lol_all : std_logic; -- combinatorial signal + signal tx_pll_lol_all_q : std_logic; -- synced + signal tx_clock_avail_q : std_logic; -- synced + + signal counter1 : unsigned(count1_index downto 0); + signal timer1 : std_logic; + signal reset_timer1 : std_logic; + + signal counter2 : unsigned(count2_index downto 0); + signal timer2 : std_logic; + signal reset_timer2 : std_logic; + +begin + +-- all four QUADs need to be ready + tx_pll_lol_all <= TX_PLL_LOL_QD_A_IN or TX_PLL_LOL_QD_B_IN or + TX_PLL_LOL_QD_C_IN or TX_PLL_LOL_QD_D_IN; + +-- synchronize, just to be on the safe side + SYNC_SFP_SIGS : entity work.signal_sync + generic map( + WIDTH => 2, + DEPTH => 3 + ) + 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, + 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; + + timer1 <= counter1(count1_index); + +-- 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; + + timer2 <= counter2(count2_index); + +-- 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'; + LINK_TX_READY_OUT <= '0'; + 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; + LINK_TX_READY_OUT <= link_tx_ready_int; + 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'; + sync_tx_quad_int <= '0'; + 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'; + 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'; + 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'; + reset_timer1 <= '1'; + reset_timer2 <= '1'; + NEXT_STATE <= WAIT_FOR_TIMER2; + + when WAIT_FOR_TIMER2 => + STATE_OUT <= x"4"; + 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; + + when SYNC_ALL => + STATE_OUT <= x"5"; + reset_timer2 <= '1'; + if( timer1 = '1' ) then + NEXT_STATE <= NORMAL; + else + NEXT_STATE <= SYNC_ALL; + end if; + + when NORMAL => + STATE_OUT <= x"6"; + tx_pcs_rst_ch_c_int <= '0'; + link_tx_ready_int <= '1'; + reset_timer1 <= '1'; + 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 => + STATE_OUT <= x"f"; + NEXT_STATE <= QUAD_RESET; + + end case; + + end process THE_FSM_DECODE_PROC; + + -- TX serializer is operational "at level" of this signal, + -- and gets reset by a transition (according to SerDes Usage Guide). + -- Timer1 is used to delay the TX link ready signal by some cycles. + THE_QUAD_SYNC_PROC: process( LOCALCLK, CLEAR ) + begin + if( CLEAR = '1' ) then + sync_tx_quad_trans <= '0'; + else + if( rising_edge(LOCALCLK) ) then + if( sync_tx_quad_int = '1' ) then + sync_tx_quad_trans <= not sync_tx_quad_trans; + end if; + end if; + end if; + end process THE_QUAD_SYNC_PROC; + + SYNC_TX_QUAD_OUT <= sync_tx_quad_trans; + +end architecture; diff --git a/media_interfaces/sync/med_sync_control_RS.vhd b/media_interfaces/sync/med_sync_control_RS.vhd index e566c98..0df56ac 100644 --- a/media_interfaces/sync/med_sync_control_RS.vhd +++ b/media_interfaces/sync/med_sync_control_RS.vhd @@ -4,56 +4,55 @@ USE IEEE.numeric_std.all; 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; +use work.med_sync_define_RS.all; entity med_sync_control_RS is - generic( - IS_WAP_ZERO : integer := 0; + generic( + 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( + -- 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; + -- Media Interface + MEDIA_MED2INT : out MED2INT; -- Media Interface IN + MEDIA_INT2MED : in INT2MED; -- Media Interface OUT + -- 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 + LINK_TX_READY_IN : in std_logic; + -- control signals to SerDes + RX_SERDES_RST : out std_logic; -- reset RX (SerDes + CDR) + RX_PCS_RST : out std_logic; -- reset RX (PCS) + -- 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 + -- ports for synchronous operation + 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 + TX_RESET_OUT : out std_logic; -- reset main TX reset FSM + -- 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); @@ -66,271 +65,198 @@ end entity; 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 + ); --- 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, + IS_WAP_ZERO => IS_WAP_ZERO, + 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, + LOCALCLK => CLK_REF, + TX_PLL_LOL_IN => '0', -- TX and RX channel are independent + RX_CDR_LOL_IN => RX_CDR_LOL_IN, -- internally synced + RX_LOS_LOW_IN => RX_LOS_IN, -- internally synced + WA_POSITION_IN => WA_POSITION_IN, -- internally synced + SFP_LOS_IN => SFP_LOS_IN, -- internally synced + RX_PCS_RST_CH_C_OUT => rx_pcs_rst_i, + RX_SERDES_RST_CH_C_OUT => rx_serdes_rst_i, + LINK_RX_READY_OUT => link_rx_ready_i, + MASTER_RESET_OUT => MASTER_RESET_OUT, -- not necessary??? + 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 + +-- 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; - + ------------------------------------------------- --- 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, + + 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_IN, + RX_K_IN => RX_K_IN, + + WORD_SYNC_OUT => WORD_SYNC_OUT, + + 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_i, + LINK_TX_READY_IN => LINK_TX_READY_IN, + LINK_HALF_DONE_IN => link_half_done_i, + LINK_FULL_DONE_IN => link_full_done_i, + + DEBUG_OUT => DEBUG_RX_CONTROL, + STAT_REG_OUT => STAT_RX_CONTROL + ); + + 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, + RXCLK => CLK_RXI, + RX_K_IN => RX_K_IN, + RX_DATA_IN => RX_DATA_IN, + LINK_HALF_DONE_OUT => link_half_done_i, + LINK_FULL_DONE_OUT => link_full_done_i, + STATE_OUT => open ); + +-- 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 + + THE_TX_CONTROL: tx_control_RS + generic map( + SIM_MODE => SIM_MODE, + IS_MODE => IS_MODE + ) 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, + -- 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, + TX_K_OUT => TX_K_OUT, + -- synchronous signals + WORD_SYNC_IN => WORD_SYNC_IN, + SEND_DLM_IN => TX_DLM_IN, + SEND_DLM_WORD_IN => TX_DLM_WORD_IN, + SEND_RST_IN => TX_RST_IN, + SEND_RST_WORD_IN => TX_RST_WORD_IN, + -- link status signals, internally synced + LINK_TX_READY_IN => LINK_TX_READY_IN, + LINK_RX_READY_IN => link_rx_ready_i, + LINK_HALF_DONE_IN => link_half_done_i, + 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 + if ( RESET = '1' ) then + 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; @@ -339,58 +265,25 @@ begin -- 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 + DEBUG_OUT(0) <= link_rx_ready_i; + DEBUG_OUT(1) <= link_half_done_i; + DEBUG_OUT(2) <= link_full_done_i; + + DEBUG_OUT(31 downto 3) <= (others => '0'); +-- DEBUG_OUT <= (others => '0'); end architecture; diff --git a/media_interfaces/sync/med_sync_define_RS.vhd b/media_interfaces/sync/med_sync_define_RS.vhd index c9e7720..a71751e 100644 --- a/media_interfaces/sync/med_sync_define_RS.vhd +++ b/media_interfaces/sync/med_sync_define_RS.vhd @@ -5,118 +5,174 @@ USE IEEE.std_logic_UNSIGNED.ALL; 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 + +-- These idles are available +constant K_BGN : std_logic_vector(7 downto 0) := x"1c"; -- K28.0 -- reserved for retransmission +constant K_28_1 : std_logic_vector(7 downto 0) := x"3c"; -- K28.1 +constant K_28_2 : std_logic_vector(7 downto 0) := x"5c"; -- K28.2 +constant K_REQ : std_logic_vector(7 downto 0) := x"7c"; -- K28.3 -- reserved for transmission +constant K_28_4 : std_logic_vector(7 downto 0) := x"9c"; -- K28.4 +constant K_IDLE : std_logic_vector(7 downto 0) := x"bc"; -- K28.5 -- used for link idle and establishment +constant K_DLM : std_logic_vector(7 downto 0) := x"dc"; -- K28.6 -- used for link delay measurement +constant K_28_7 : std_logic_vector(7 downto 0) := x"fc"; -- K28.7 +constant K_NULL : std_logic_vector(7 downto 0) := x"f7"; -- K23.7 -- used for "SerDes in reset" +constant K_SOP : std_logic_vector(7 downto 0) := x"fb"; -- K27.7 -- reserved for packet handling +constant K_EOP : std_logic_vector(7 downto 0) := x"fd"; -- K29.7 -- reserved for packet handling +constant K_RST : std_logic_vector(7 downto 0) := x"fe"; -- K30.7 -- used for reset + +-- data char for idle +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; + +component main_rx_reset_RS is + generic( + SIM_MODE : integer := 0; + IS_WAP_ZERO : integer := 0; + IS_MODE : integer := c_IS_SLAVE + ); + 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; + +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; + 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; - + +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; + 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; end package; diff --git a/media_interfaces/sync/rx_control_RS.vhd b/media_interfaces/sync/rx_control_RS.vhd index 29ebaca..4a574c3 100644 --- a/media_interfaces/sync/rx_control_RS.vhd +++ b/media_interfaces/sync/rx_control_RS.vhd @@ -4,38 +4,36 @@ use ieee.numeric_std.all; 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; + 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) ); @@ -43,222 +41,240 @@ end entity; 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 + + signal link_rx_ready_qrx : std_logic; + signal link_full_done_qrx : std_logic; + signal link_full_done_qsys : std_logic; begin + + -- Syncing things + SYNC_RXI: signal_sync + generic map( + WIDTH => 2, + DEPTH => 3 + ) + port map( + RESET => '0', + CLK0 => CLK_RXI, + CLK1 => CLK_RXI, + D_IN(0) => LINK_RX_READY_IN, + D_IN(1) => LINK_FULL_DONE_IN, + D_OUT(0) => link_rx_ready_qrx, + D_OUT(1) => link_full_done_qrx + ); + + -- 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; diff --git a/media_interfaces/sync/rx_lsm_RS.vhd b/media_interfaces/sync/rx_lsm_RS.vhd new file mode 100644 index 0000000..7ad7264 --- /dev/null +++ b/media_interfaces/sync/rx_lsm_RS.vhd @@ -0,0 +1,187 @@ +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.all; + +library work; +use work.med_sync_define_RS.all; + +entity 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 entity; + +architecture rx_lsm_arch of rx_lsm_RS is + + 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 + + signal reset_ctr_t : std_logic; + 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; + 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; + signal link_steady_int : std_logic; + +begin + + THE_CTR_T_PROC: process( RXCLK, LINK_RX_READY_IN ) + begin + if ( LINK_RX_READY_IN <= '0' ) then + 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; + + ctr_t_done <= ctr_t(4); + + THE_CTR_S_PROC: process( RXCLK, LINK_RX_READY_IN ) + begin + if ( LINK_RX_READY_IN = '0' ) then + 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); + + -- toggling idles sequence detected + THE_TOGGLE_DETECTED_PROC: process( RXCLK, LINK_RX_READY_IN ) + begin + if ( LINK_RX_READY_IN = '0' ) then + link_toggling_int <= '0'; + elsif( rising_edge(RXCLK) ) then + if( ctr_t_done = '1' ) then + link_toggling_int <= '1'; + end if; + end if; + end process THE_TOGGLE_DETECTED_PROC; + + LINK_HALF_DONE_OUT <= link_toggling_int; + + -- 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; + + 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 + if( rising_edge(RXCLK) ) then + CURRENT_STATE <= NEXT_STATE; + end if; + end if; + end process THE_FSM_PROC; + + -- State machine decoding processs + THE_FSM_DECODE_PROC: process( CURRENT_STATE, RX_K_IN, RX_DATA_IN ) + begin + reset_ctr_t <= '0'; + reset_ctr_s <= '0'; + ce_ctr_t <= '0'; + ce_ctr_s <= '0'; + STATE_OUT <= x"F"; + + case CURRENT_STATE is + + when IDLE => + STATE_OUT <= x"0"; + reset_ctr_t <= '1'; + reset_ctr_s <= '1'; + if( (RX_K_IN = '1') and (RX_DATA_IN = K_IDLE) ) then + NEXT_STATE <= K1F; + else + NEXT_STATE <= IDLE; + end if; + + when K1F => + STATE_OUT <= x"1"; + if( (RX_K_IN = '0') and (RX_DATA_IN = D_IDLE1) ) then + NEXT_STATE <= D1F; + else + NEXT_STATE <= IDLE; + end if; + + when D1F => + 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; + + when K2F => + 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; + + when D2FT => + STATE_OUT <= x"4"; + if( (RX_K_IN = '1') and (RX_DATA_IN = K_IDLE) ) then + NEXT_STATE <= K1F; + ce_ctr_t <= '1'; + else + NEXT_STATE <= IDLE; + end if; + + when D2FS => + STATE_OUT <= x"5"; + if( (RX_K_IN = '1') and (RX_DATA_IN = K_IDLE) ) then + NEXT_STATE <= K1F; + ce_ctr_s <= '1'; + else + NEXT_STATE <= IDLE; + end if; + + when others => + STATE_OUT <= x"f"; + NEXT_STATE <= IDLE; + + end case; + + end process THE_FSM_DECODE_PROC; + +end architecture; diff --git a/media_interfaces/sync/rx_reset_fsm_RS.vhd b/media_interfaces/sync/rx_reset_fsm_RS.vhd index e852df4..4ca122a 100644 --- a/media_interfaces/sync/rx_reset_fsm_RS.vhd +++ b/media_interfaces/sync/rx_reset_fsm_RS.vhd @@ -6,16 +6,16 @@ USE IEEE.numeric_std.all; 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 ; @@ -46,9 +46,7 @@ begin 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, @@ -86,16 +84,16 @@ begin 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; diff --git a/media_interfaces/sync/tb/tb_main_rx_reset_RS.vhd b/media_interfaces/sync/tb/tb_main_rx_reset_RS.vhd new file mode 100644 index 0000000..ddf98e9 --- /dev/null +++ b/media_interfaces/sync/tb/tb_main_rx_reset_RS.vhd @@ -0,0 +1,116 @@ +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.std_logic_unsigned.all; +USE ieee.numeric_std.ALL; + +library work; +use work.trb_net_std.all; +--use work.trb_net_components.all; +use work.med_sync_define_RS.all; + +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; + IS_WAP_ZERO : integer := 0; + IS_MODE : integer := c_IS_SLAVE + ); + port( + CLEAR : in std_logic; + LOCALCLK : in std_logic; + 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); + SFP_LOS_IN : in std_logic; + 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; + MASTER_RESET_OUT : out std_logic; + STATE_OUT : out std_logic_vector(3 downto 0) + ); + END COMPONENT main_rx_reset_RS; + + --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; + + --Outputs + SIGNAL RX_PCS_RST_CH_C_OUT : std_logic; + SIGNAL RX_SERDES_RST_CH_C_OUT : std_logic; + SIGNAL LINK_RX_READY_OUT : std_logic; + 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 + GENERIC MAP( + SIM_MODE => 1, + IS_WAP_ZERO => 1, + IS_MODE => c_IS_SLAVE + ) + PORT MAP( + CLEAR => CLEAR, + LOCALCLK => LOCALCLK, + TX_PLL_LOL_IN => TX_PLL_LOL_IN, + RX_CDR_LOL_IN => RX_CDR_LOL_IN, + RX_LOS_LOW_IN => RX_LOS_LOW_IN, + WA_POSITION_IN => WA_POSITION_IN, + SFP_LOS_IN => SFP_LOS_IN, + RX_PCS_RST_CH_C_OUT => RX_PCS_RST_CH_C_OUT, + RX_SERDES_RST_CH_C_OUT => RX_SERDES_RST_CH_C_OUT, + LINK_RX_READY_OUT => LINK_RX_READY_OUT, + MASTER_RESET_OUT => MASTER_RESET_OUT, + STATE_OUT => STATE_OUT + ); + +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; + +TEST_BENCH_PROC: process +begin + -- Setup signals + clear <= '0'; + 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 + clear <= '1'; + wait for 99 ns; + clear <= '0'; + wait for 99 ns; + + -- Tests may start here + wait for 555 ns; + rx_los_low_in <= '0'; + wait for 666 ns; + rx_cdr_lol_in <= '0'; + wait for 666 ns; + wa_position_in <= x"0"; + + -- Stay a while... stay forever!!! + wait; + +end process TEST_BENCH_PROC; + +END; diff --git a/media_interfaces/sync/tb/tb_main_tx_reset_RS.vhd b/media_interfaces/sync/tb/tb_main_tx_reset_RS.vhd new file mode 100644 index 0000000..ed0eac6 --- /dev/null +++ b/media_interfaces/sync/tb/tb_main_tx_reset_RS.vhd @@ -0,0 +1,116 @@ +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; + SYNC_TX_QUAD_OUT : out std_logic; + LINK_TX_READY_OUT : out std_logic; + STATE_OUT : out std_logic_vector(3 downto 0) + ); + 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; + 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 + GENERIC MAP( + SIM_MODE => 1 + ) + 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, + SYNC_TX_QUAD_OUT => SYNC_TX_QUAD_OUT, + LINK_TX_READY_OUT => LINK_TX_READY_OUT, + STATE_OUT => STATE_OUT + ); + +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; + +TEST_BENCH_PROC: process +begin + -- Setup signals + clear <= '0'; + 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'; + + wait for 77 ns; + + -- Reset the beast + clear <= '1'; + wait for 99 ns; + clear <= '0'; + wait for 99 ns; + + -- Tests may start here + tx_pll_lol_qd_a_in <= '0'; + wait for 333 ns; + 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'; + wait for 666 ns; + tx_pll_lol_qd_d_in <= '0'; + + wait for 2 us; + tx_clock_avail_in <= '0'; + wait for 33.33 ns; + tx_clock_avail_in <= '1'; + + -- Stay a while... stay forever!!! + wait; + +end process TEST_BENCH_PROC; + +END; diff --git a/media_interfaces/sync/tb/tb_med_sync_control_RS.vhd b/media_interfaces/sync/tb/tb_med_sync_control_RS.vhd new file mode 100644 index 0000000..7b3465c --- /dev/null +++ b/media_interfaces/sync/tb/tb_med_sync_control_RS.vhd @@ -0,0 +1,338 @@ +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.std_logic_unsigned.all; +USE ieee.numeric_std.ALL; + +library work; +use work.trb_net_std.all; +--use work.trb_net_components.all; +use work.med_sync_define_RS.all; + +ENTITY tb_med_sync_control_RS_vhd IS +END tb_med_sync_control_RS_vhd; + +ARCHITECTURE behavior OF tb_med_sync_control_RS_vhd IS + + -- Component Declaration for the Unit Under Test (UUT) + COMPONENT med_sync_control_RS IS + generic( + SIM_MODE : integer := 0; + IS_WAP_ZERO : integer := 0; + IS_MODE : integer := c_IS_UNUSED + ); + port( + CLK_SYS : in std_logic; -- 100MHz system clock + CLK_RXI : in std_logic; -- recovered RX clock, 200MHz + 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 + RESET : in std_logic; + CLEAR : in std_logic; + MEDIA_MED2INT : out MED2INT; + MEDIA_INT2MED : in INT2MED; + SFP_LOS_IN : in std_logic; + RX_CDR_LOL_IN : in std_logic; + RX_LOS_IN : in std_logic; + WA_POSITION_IN : in std_logic_vector(3 downto 0); + LINK_TX_READY_IN : in std_logic; + RX_SERDES_RST : out std_logic; + RX_PCS_RST : out std_logic; + TX_DATA_OUT : out std_logic_vector(7 downto 0); + TX_K_OUT : out std_logic; + RX_DATA_IN : in std_logic_vector(7 downto 0); + RX_K_IN : in std_logic; + WORD_SYNC_IN : in std_logic; + WORD_SYNC_OUT : out std_logic; + TX_DLM_WORD_IN : in std_logic_vector(7 downto 0); + TX_DLM_IN : in std_logic; + TX_RST_WORD_IN : in std_logic_vector(7 downto 0); + TX_RST_IN : in std_logic; + 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); + RX_RST_OUT : out std_logic; + MASTER_RESET_OUT : out std_logic; + TX_RESET_OUT : out std_logic; + 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); + DEBUG_RX_CONTROL : out std_logic_vector(31 downto 0); + STAT_RESET : out std_logic_vector(31 downto 0); + DEBUG_OUT : out std_logic_vector(31 downto 0) + ); + END COMPONENT med_sync_control_RS; + + --Inputs + SIGNAL M_CLK_SYS : std_logic; + SIGNAL M_CLK_RXI : std_logic; + SIGNAL M_CLK_TXI : std_logic; + SIGNAL M_CLK_REF : std_logic; + SIGNAL M_CLEAR : std_logic; + SIGNAL M_SFP_LOS_IN : std_logic; + SIGNAL M_RX_CDR_LOL_IN : std_logic; + SIGNAL M_RX_LOS_IN : std_logic; + SIGNAL M_WA_POSITION_IN : std_logic_vector(3 downto 0); + SIGNAL M_LINK_TX_READY_IN : std_logic; + SIGNAL M_RX_DATA_IN : std_logic_vector(7 downto 0); + SIGNAL M_RX_K_IN : std_logic; + SIGNAL M_WORD_SYNC_IN : std_logic; + + 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; + + --Outputs + 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; + SIGNAL M_MASTER_RESET_OUT : std_logic; + SIGNAL M_TX_RESET_OUT : std_logic; + SIGNAL M_DEBUG_OUT : std_logic_vector(31 downto 0); + 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); + + +BEGIN + + -- Instantiate the Unit Under Test (UUT) + M_uut: med_sync_control_RS + GENERIC MAP( + SIM_MODE => 1, + IS_WAP_ZERO => 1, + IS_MODE => c_IS_MASTER + ) + PORT MAP( + CLK_SYS => M_CLK_SYS, + CLK_RXI => M_CLK_RXI, + CLK_RXHALF => '0', + CLK_TXI => M_CLK_TXI, + CLK_REF => M_CLK_REF, + RESET => M_CLEAR, + CLEAR => M_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 => 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, + 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, + TX_K_OUT => M_TX_K_OUT, + RX_DATA_IN => M_RX_DATA_IN, + RX_K_IN => M_RX_K_IN, + WORD_SYNC_IN => M_WORD_SYNC_IN, + WORD_SYNC_OUT => M_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 => M_MASTER_RESET_OUT, + TX_RESET_OUT => M_TX_RESET_OUT, + STAT_TX_CONTROL => open, + STAT_RX_CONTROL => open, + DEBUG_TX_CONTROL => open, + DEBUG_RX_CONTROL => open, + STAT_RESET => open, + DEBUG_OUT => M_DEBUG_OUT + ); + + 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 + ); + + +-- MASTER clocks +CLK_200_GEN: process +begin + -- 200 MHz => 5.0 ns + m_clk_ref <= '1'; wait for 2.5 ns; + m_clk_ref <= '0'; wait for 2.5 ns; +end process CLK_200_GEN; + +-- same clock +m_clk_txi <= transport m_clk_ref after 1 ns; +m_clk_rxi <= transport m_clk_ref after 1 ns; + +CLK_100_GEN: process +begin + -- 100 MHz => 10.0 ns + m_clk_sys <= '1'; wait for 5.0 ns; + m_clk_sys <= '0'; wait for 5.0 ns; +end process CLK_100_GEN; + +-- SLAVE clocks +s_clk_ref <= transport m_clk_ref after 17 ns; +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; + +-- the link +s_rx_k_in <= transport m_tx_k_out after 2 ns; +s_rx_data_in <= transport m_tx_data_out after 2 ns; +m_rx_k_in <= transport s_tx_k_out after 2 ns; +m_rx_data_in <= transport s_tx_data_out after 2 ns; + +TEST_BENCH_PROC: process +begin + + -- Setup signals + m_clear <= '1'; + m_sfp_los_in <= '0'; + m_rx_cdr_lol_in <= '1'; + m_rx_los_in <= '1'; + m_wa_position_in <= x"0"; + m_link_tx_ready_in <= '0'; + m_word_sync_in <= '1'; + + 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'; + + -- Reset the beast + wait for 111 ns; + m_clear <= '0'; + s_clear <= '0'; + wait for 99 ns; + + -- Tests may start here + + -- start up the master TX + wait for 333 ns; + m_link_tx_ready_in <= '1'; + -- the slave receives the data stream + wait for 677 ns; + s_rx_los_in <= '0'; + wait for 444 ns; + s_rx_cdr_lol_in <= '0'; + wait until falling_edge(s_tx_reset_out); + -- slave TX is being taken into operation + wait for 333 ns; + s_link_tx_ready_in <= '1'; + -- the master receives the data stream + -- 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'; + + -- fiber removed + wait for 5 us; + s_sfp_los_in <= '1'; + wait for 111 ns; + s_rx_los_in <= '1'; + wait for 111 ns; + s_rx_cdr_lol_in <= '1'; + wait for 111 ns; + s_link_tx_ready_in <= '0'; + + 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'; + + wait; + + wait for 333 ns; + m_sfp_los_in <= '0'; + wait for 333 ns; + m_rx_los_in <= '0'; + wait for 333 ns; + m_rx_cdr_lol_in <= '0'; + +-- wait until rising_edge(s_debug_out(1)); + + -- 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'; + + -- Stay a while... stay forever!!! + wait; + +end process TEST_BENCH_PROC; + +END; diff --git a/media_interfaces/sync/tb/tb_rx_control_RS.vhd b/media_interfaces/sync/tb/tb_rx_control_RS.vhd new file mode 100644 index 0000000..807271e --- /dev/null +++ b/media_interfaces/sync/tb/tb_rx_control_RS.vhd @@ -0,0 +1,224 @@ +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.std_logic_unsigned.all; +USE ieee.numeric_std.ALL; + +library work; +use work.trb_net_std.all; +--use work.trb_net_components.all; +use work.med_sync_define_RS.all; + +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) + ); + 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, + CLK_SYS => CLK_SYS, + RESET => RESET, + 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, + 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; + +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'; + rx_data_in <= x"00"; + rx_k_in <= '0'; + 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 + wait until rising_edge(clk_rxi); + reset <= '1'; + wait until rising_edge(clk_rxi); + reset <= '0'; + wait for 99 ns; + + -- link reset done + wait for 222 ns; + link_rx_ready_in <= '1'; + link_half_done_in <= '1'; + + -- RX 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; + + link_tx_ready_in <= '1'; + + -- 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; + + link_full_done_in <= '1'; + + 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 DLM + 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"; + + 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"; + + 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; + + -- a data packet + 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"; + + + 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; diff --git a/media_interfaces/sync/tb/tb_rx_lsm_RS.vhd b/media_interfaces/sync/tb/tb_rx_lsm_RS.vhd new file mode 100644 index 0000000..1439e35 --- /dev/null +++ b/media_interfaces/sync/tb/tb_rx_lsm_RS.vhd @@ -0,0 +1,129 @@ +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.std_logic_unsigned.all; +USE ieee.numeric_std.ALL; + +library work; +use work.med_sync_define_RS.all; + +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) + ); + 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); + + --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 + PORT MAP( + LINK_RX_READY_IN => LINK_RX_READY_IN, + RXCLK => RXCLK, + RX_K_IN => RX_K_IN, + RX_DATA_IN => RX_DATA_IN, + LINK_HALF_DONE_OUT => LINK_HALF_DONE_OUT, + LINK_FULL_DONE_OUT => LINK_FULL_DONE_OUT, + STATE_OUT => STATE_OUT + ); + +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; + +TEST_BENCH_PROC: process +begin + -- Setup signals + link_rx_ready_in <= '0'; + + -- Tests may start here + + -- toggling idles + 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; + link_rx_ready_in <= '1'; + + -- 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; + + -- one wrong komma + 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"; + + 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; + + -- 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; + + wait until rising_edge(rxclk); + link_rx_ready_in <= '0'; + + + -- Stay a while... stay forever!!! + wait; + +end process TEST_BENCH_PROC; + +END; diff --git a/media_interfaces/sync/tb/tb_tx_control_RS.vhd b/media_interfaces/sync/tb/tb_tx_control_RS.vhd new file mode 100644 index 0000000..e7bb21f --- /dev/null +++ b/media_interfaces/sync/tb/tb_tx_control_RS.vhd @@ -0,0 +1,190 @@ +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.std_logic_unsigned.all; +USE ieee.numeric_std.ALL; + +library work; +use work.trb_net_std.all; +--use work.trb_net_components.all; +use work.med_sync_define_RS.all; + +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) + ); + END COMPONENT tx_control_RS; + + --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, + CLK_SYS => CLK_SYS, + RESET => RESET, + WORD_SYNC_IN => WORD_SYNC_IN, + TX_DATA_IN => TX_DATA_IN, + TX_PACKET_NUMBER_IN => TX_PACKET_NUMBER_IN, + TX_WRITE_IN => TX_WRITE_IN, + TX_READ_OUT => TX_READ_OUT, + TX_DATA_OUT => TX_DATA_OUT, + TX_K_OUT => TX_K_OUT, + 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, + 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, + 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; + +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'; + word_sync_in <= '1'; + + wait for 77 ns; + + -- Reset the beast + wait until rising_edge(clk_tx); + reset <= '1'; + wait until rising_edge(clk_tx); + reset <= '0'; + wait for 99 ns; + + -- Tests may start here + wait for 333 ns; + link_rx_ready_in <= '1'; + 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'; + + wait for 333 ns; + wait until rising_edge(clk_tx); + send_dlm_in <= '1'; + send_dlm_word_in <= x"aa"; + wait until rising_edge(clk_tx); + send_dlm_in <= '0'; + send_dlm_word_in <= x"00"; + + 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"; + + 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"; + + wait for 111 ns; + wait until rising_edge(clk_sys); + tx_packet_number_in <= b"100"; + tx_data_in <= x"0055"; + tx_write_in <= '1'; + 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; diff --git a/media_interfaces/sync/tx_control_RS.vhd b/media_interfaces/sync/tx_control_RS.vhd index 58002a2..e09bce4 100644 --- a/media_interfaces/sync/tx_control_RS.vhd +++ b/media_interfaces/sync/tx_control_RS.vhd @@ -4,39 +4,40 @@ use ieee.numeric_std.all; 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; + +-- BUG: must be kept in reset while LINK_TX_READY_IN = '0' ! entity 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; - - -- 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); + -- 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) ); @@ -44,8 +45,8 @@ end entity; 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, + 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); @@ -71,9 +72,6 @@ architecture arch of tx_control_RS is 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'; @@ -89,10 +87,65 @@ architecture arch of tx_control_RS is 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; - + + signal link_tx_ready_qtx : std_logic; + signal link_rx_ready_qtx : std_logic; + signal link_half_done_qtx : std_logic; + signal link_full_done_qtx : std_logic; + signal link_active_int : std_logic; + signal link_active_qtx : std_logic; + signal link_active_qsys : std_logic; + + signal send_steady_idle_int : std_logic; + begin + +-- Sync + 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 + ); + + -- Payload is only allowed on fully active links + link_active_int <= link_tx_ready_qtx and link_rx_ready_qtx and + link_half_done_qtx and link_full_done_qtx; + + link_active_qtx <= link_active_int when rising_edge(CLK_TX); + + -- if not set, send toggling idles + send_steady_idle_int <= link_tx_ready_qtx and link_rx_ready_qtx and + link_half_done_qtx when (IS_MODE = c_IS_MASTER) else + link_tx_ready_qtx and link_rx_ready_qtx and + link_half_done_qtx and link_full_done_qtx when (IS_MODE = c_IS_SLAVE) else + '0'; + + 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 @@ -102,8 +155,8 @@ begin 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, @@ -114,21 +167,21 @@ begin 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'; @@ -136,18 +189,18 @@ begin ---------------------------------------------------------------------- -- 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)); @@ -156,34 +209,34 @@ begin 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; @@ -192,128 +245,126 @@ begin 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 + if( (LINK_TX_READY_IN = '0') or (RESET = '1') ) then + current_state <= IDLE; + TX_K_OUT <= '1'; + TX_DATA_OUT <= K_NULL; + else + 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'; + + when IDLE => + TX_DATA_OUT <= K_NULL; + TX_K_OUT <= '1'; + current_state <= SEND_IDLE_L; + -- used to get out of async reset + + when SEND_RST_H => + TX_DATA_OUT <= send_rst_word_i; + + 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; + + --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'; + end if; + end process; + ---------------------------------------------------------------------- -- ---------------------------------------------------------------------- - 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 @@ -321,20 +372,20 @@ begin 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 @@ -342,7 +393,7 @@ begin 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; @@ -351,21 +402,21 @@ begin ---------------------------------------------------------------------- -- 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; @@ -373,17 +424,18 @@ begin 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; diff --git a/media_interfaces/sync/tx_reset_fsm_RS.vhd b/media_interfaces/sync/tx_reset_fsm_RS.vhd index 2f5c09f..eb24cf1 100644 --- a/media_interfaces/sync/tx_reset_fsm_RS.vhd +++ b/media_interfaces/sync/tx_reset_fsm_RS.vhd @@ -177,7 +177,7 @@ begin end if; when others => - ns <= QUAD_RESET; + ns <= QUAD_RESET; end case; -- 2.43.0