From: Michael Boehmer Date: Thu, 2 Dec 2021 07:13:20 +0000 (+0100) Subject: still link problems X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=a4eb5d9d13abff242634d33d958715ceba8c21da;p=trbnet.git still link problems --- diff --git a/media_interfaces/med_ecp3_sfp_sync_all_RS.vhd b/media_interfaces/med_ecp3_sfp_sync_all_RS.vhd index bcd3206..063dff9 100644 --- a/media_interfaces/med_ecp3_sfp_sync_all_RS.vhd +++ b/media_interfaces/med_ecp3_sfp_sync_all_RS.vhd @@ -131,6 +131,8 @@ architecture med_ecp3_sfp_sync_all_RS_arch of med_ecp3_sfp_sync_all_RS is signal master_reset_i : std_logic_vector(3 downto 0); signal tx_reset_i : std_logic_vector(3 downto 0); + signal master_reset_sel : std_logic; + signal quad_mode : integer range 0 to 100; begin @@ -190,12 +192,14 @@ begin ------------------------------------------------- -- master reset ------------------------------------------------- - MASTER_RESET_OUT <= master_reset_i(0) when ((quad_mode >= 8) and (IS_MODE(0) = c_IS_SLAVE)) else + master_reset_sel <= master_reset_i(0) when ((quad_mode >= 8) and (IS_MODE(0) = c_IS_SLAVE)) else master_reset_i(1) when ((quad_mode >= 8) and (IS_MODE(1) = c_IS_SLAVE)) else master_reset_i(2) when ((quad_mode >= 8) and (IS_MODE(2) = c_IS_SLAVE)) else master_reset_i(3) when ((quad_mode >= 8) and (IS_MODE(3) = c_IS_SLAVE)) else - '0'; - + '0'; -- we need a master reset in! + + MASTER_RESET_OUT <= master_reset_sel; + ------------------------------------------------- -- reset komma ------------------------------------------------- @@ -363,7 +367,7 @@ begin fpga_txrefclk => MASTER_CLK_IN, -- reference TX clock tx_serdes_rst_c => '0', tx_pll_lol_qd_s => TX_PLL_LOL_OUT, - rst_qd_c => RST_QUAD_IN, + rst_qd_c => master_reset_sel, --RST_QUAD_IN, -- deadlock caused by this... serdes_rst_qd_c => '0', -- was wrong tx_sync_qd_c => SYNC_TX_PLL_IN ); diff --git a/media_interfaces/sync/main_rx_reset_RS.vhd b/media_interfaces/sync/main_rx_reset_RS.vhd index 8763a8f..9c52c39 100644 --- a/media_interfaces/sync/main_rx_reset_RS.vhd +++ b/media_interfaces/sync/main_rx_reset_RS.vhd @@ -1,242 +1,243 @@ ---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; +--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 + 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; + 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; + 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 +architecture main_rx_reset_arch of main_rx_reset_RS is - -- We use two different timing for simulation and real world. + -- 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 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 + + 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 - ); + 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 + -- 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, + ) + 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_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 - ); + 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; + 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'; + + -- 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'; + 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 + 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'; + 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_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 + 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 + 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 + 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'; + 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 => + 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; + reset_timer2 <= '1'; + + end case; + + end process THE_FSM_DECODE_PROC; -end architecture; +end architecture; diff --git a/media_interfaces/sync/med_sync_control_RS.vhd b/media_interfaces/sync/med_sync_control_RS.vhd index a2c2323..e94cb38 100644 --- a/media_interfaces/sync/med_sync_control_RS.vhd +++ b/media_interfaces/sync/med_sync_control_RS.vhd @@ -84,6 +84,9 @@ architecture med_sync_control_arch of med_sync_control_RS is signal rx_serdes_rst_i : std_logic; signal rx_pcs_rst_i : std_logic; + signal is_wap_zero_i : std_logic; + signal debug_tx_control_i : std_logic_vector(31 downto 0); + begin ------------------------------------------------- @@ -104,14 +107,15 @@ begin ); -- 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); + 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 reset_rx_fsm_i <= (CLEAR or RESET or sd_los_qsys); -- TX_CONTROL and RX_CONTROL reset - reset_i <= (RESET or sd_los_qsys); + reset_i <= (RESET or sd_los_qsys) when (IS_MODE = c_IS_SLAVE) + else (RESET); ------------------------------------------------- -- Reset RX FSM @@ -150,6 +154,8 @@ begin D_OUT(1) => RX_SERDES_RST ); + is_wap_zero_i <= '1' when (WA_POSITION_IN = x"0") else '0'; + ------------------------------------------------- -- RX Data ------------------------------------------------- @@ -234,12 +240,14 @@ begin LINK_HALF_DONE_IN => link_half_done_i, LINK_FULL_DONE_IN => link_full_done_i, -- debug - DEBUG_OUT => DEBUG_TX_CONTROL, + DEBUG_OUT => debug_tx_control_i, STAT_REG_OUT => STAT_TX_CONTROL ); MEDIA_MED2INT <= media_med2int_i; + DEBUG_TX_CONTROL <= debug_tx_control_i; + ------------------------------------------------- -- Generate LED signals ------------------------------------------------- @@ -279,13 +287,21 @@ begin 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(3) <= RX_CDR_LOL_IN; - DEBUG_OUT(4) <= RX_LOS_IN; - - DEBUG_OUT(31 downto 5) <= (others => '0'); + DEBUG_OUT(0) <= SFP_LOS_IN; + DEBUG_OUT(1) <= RX_LOS_IN; + DEBUG_OUT(2) <= RX_CDR_LOL_IN; + DEBUG_OUT(3) <= rx_pcs_rst_i; + DEBUG_OUT(4) <= rx_serdes_rst_i; + DEBUG_OUT(5) <= link_rx_ready_i; + DEBUG_OUT(6) <= link_half_done_i; + DEBUG_OUT(7) <= link_full_done_i; + DEBUG_OUT(8) <= LINK_TX_READY_IN; + DEBUG_OUT(9) <= is_wap_zero_i; + DEBUG_OUT(10) <= reset_rx_fsm_i; + DEBUG_OUT(11) <= reset_i; + DEBUG_OUT(15 downto 12) <= rx_fsm_state; + DEBUG_OUT(21 downto 16) <= debug_tx_control_i(5 downto 0); + DEBUG_OUT(31 downto 22) <= (others => '0'); -- DEBUG_OUT <= (others => '0'); end architecture; diff --git a/media_interfaces/sync/tx_control_RS.vhd b/media_interfaces/sync/tx_control_RS.vhd index e09bce4..31dcbf5 100644 --- a/media_interfaces/sync/tx_control_RS.vhd +++ b/media_interfaces/sync/tx_control_RS.vhd @@ -1,129 +1,129 @@ -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; +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; -- BUG: must be kept in reset while LINK_TX_READY_IN = '0' ! - -entity tx_control_RS is - generic( + +entity tx_control_RS is + generic( SIM_MODE : integer := 0; - IS_MODE : integer := c_IS_UNUSED + IS_MODE : integer := c_IS_UNUSED ); - port( - 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; + port( + 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 entity; - -architecture arch of tx_control_RS is - + 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 entity; + +architecture arch of tx_control_RS is + 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); - - type ram_t is array(0 to 255) of std_logic_vector(17 downto 0); - signal ram : ram_t; - - signal ram_write : std_logic := '0'; - signal ram_write_addr : unsigned(7 downto 0) := (others => '0'); - signal last_ram_write_addr : unsigned(7 downto 0) := (others => '0'); - signal ram_read : std_logic := '0'; - signal ram_read_addr : unsigned(7 downto 0) := (others => '0'); - signal ram_dout : std_logic_vector(17 downto 0); - signal next_ram_dout : std_logic_vector(17 downto 0); - signal ram_fill_level : unsigned(7 downto 0); - signal ram_empty : std_logic; - signal ram_afull : std_logic; - - signal send_dlm_i : std_logic; - signal send_dlm_word_i : std_logic_vector(7 downto 0); - - signal send_rst_i : std_logic; - signal send_rst_word_i : std_logic_vector(7 downto 0); - - signal buf_tx_read_out : std_logic; - signal tx_data_200 : std_logic_vector(17 downto 0); - signal ct_fifo_empty : std_logic; - signal ct_fifo_write : std_logic := '0'; - signal ct_fifo_read : std_logic := '0'; - signal ct_fifo_full : std_logic; - signal ct_fifo_afull : std_logic; - signal ct_fifo_reset : std_logic; - signal last_ct_fifo_empty : std_logic; - signal last_ct_fifo_read : std_logic; - signal debug_sending_dlm : std_logic; - signal debug_sending_rst : std_logic; - - signal save_sop : std_logic; - signal save_eop : std_logic; - signal load_sop : std_logic; - signal load_eop : std_logic; - signal toggle_idle : std_logic; + 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); + + type ram_t is array(0 to 255) of std_logic_vector(17 downto 0); + signal ram : ram_t; + + signal ram_write : std_logic := '0'; + signal ram_write_addr : unsigned(7 downto 0) := (others => '0'); + signal last_ram_write_addr : unsigned(7 downto 0) := (others => '0'); + signal ram_read : std_logic := '0'; + signal ram_read_addr : unsigned(7 downto 0) := (others => '0'); + signal ram_dout : std_logic_vector(17 downto 0); + signal next_ram_dout : std_logic_vector(17 downto 0); + signal ram_fill_level : unsigned(7 downto 0); + signal ram_empty : std_logic; + signal ram_afull : std_logic; + + signal send_dlm_i : std_logic; + signal send_dlm_word_i : std_logic_vector(7 downto 0); + + signal send_rst_i : std_logic; + signal send_rst_word_i : std_logic_vector(7 downto 0); + + signal buf_tx_read_out : std_logic; + signal tx_data_200 : std_logic_vector(17 downto 0); + signal ct_fifo_empty : std_logic; + signal ct_fifo_write : std_logic := '0'; + signal ct_fifo_read : std_logic := '0'; + signal ct_fifo_full : std_logic; + signal ct_fifo_afull : std_logic; + signal ct_fifo_reset : std_logic; + signal last_ct_fifo_empty : std_logic; + signal last_ct_fifo_read : std_logic; + signal debug_sending_dlm : std_logic; + signal debug_sending_rst : std_logic; + + signal save_sop : std_logic; + signal save_eop : std_logic; + signal load_sop : std_logic; + signal load_eop : 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_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_int : std_logic; + signal link_active_qtx : std_logic; signal link_active_qsys : std_logic; signal send_steady_idle_int : std_logic; - -begin + +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 - ); + 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_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); @@ -134,308 +134,311 @@ begin 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 ----------------------------------------------------------------------- - THE_CT_FIFO : lattice_ecp3_fifo_18x16_dualport_oreg - port map( - Data(15 downto 0) => TX_DATA_IN, - Data(16) => save_sop, - Data(17) => save_eop, - WrClock => CLK_SYS, - RdClock => CLK_TX, - WrEn => ct_fifo_write, - RdEn => ct_fifo_read, - Reset => ct_fifo_reset, - RPReset => ct_fifo_reset, - Q(17 downto 0) => tx_data_200, - Empty => ct_fifo_empty, - Full => ct_fifo_full, - AlmostFull => ct_fifo_afull - ); - - THE_RD_PROC : process(CLK_SYS) - begin - 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 link_active_qtx; - TX_READ_OUT <= buf_tx_read_out; - - ct_fifo_write <= buf_tx_read_out and TX_WRITE_IN; - 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_TX); - last_ct_fifo_empty <= ct_fifo_empty when rising_edge(CLK_TX); - - save_sop <= '1' when (TX_PACKET_NUMBER_IN = c_H0) else '0'; - save_eop <= '1' when (TX_PACKET_NUMBER_IN = c_F3) else '0'; - ----------------------------------------------------------------------- --- RAM ----------------------------------------------------------------------- - THE_RAM_WR_PROC : process(CLK_TX) - begin - 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_TX) - begin - 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)); - ram_dout <= next_ram_dout; - end if; - end process; - ---RAM read pointer - THE_READ_CNT : process(CLK_TX) - begin - if( rising_edge(CLK_TX) ) then - if( link_active_qtx = '0' ) then - ram_read_addr <= (others => '0'); - 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_TX) - begin - if( rising_edge(CLK_TX) ) then - if( link_active_qtx = '0' ) then - ram_write_addr <= (others => '0'); - 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_TX) - begin - if( rising_edge(CLK_TX) ) then - if( link_active_qtx = '0' ) then - ram_fill_level <= (others => '0'); - else - ram_fill_level <= last_ram_write_addr - ram_read_addr; - end if; - end if; - end process; - ---RAM empty - 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_TX); - ----------------------------------------------------------------------- --- TX control state machine ----------------------------------------------------------------------- - - THE_DATA_CONTROL_FSM : process(CLK_TX, LINK_TX_READY_IN, RESET) + 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 +---------------------------------------------------------------------- + THE_CT_FIFO : lattice_ecp3_fifo_18x16_dualport_oreg + port map( + Data(15 downto 0) => TX_DATA_IN, + Data(16) => save_sop, + Data(17) => save_eop, + WrClock => CLK_SYS, + RdClock => CLK_TX, + WrEn => ct_fifo_write, + RdEn => ct_fifo_read, + Reset => ct_fifo_reset, + RPReset => ct_fifo_reset, + Q(17 downto 0) => tx_data_200, + Empty => ct_fifo_empty, + Full => ct_fifo_full, + AlmostFull => ct_fifo_afull + ); + + THE_RD_PROC : process(CLK_SYS) + begin + 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 link_active_qtx; + TX_READ_OUT <= buf_tx_read_out; + + ct_fifo_write <= buf_tx_read_out and TX_WRITE_IN; + 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_TX); + last_ct_fifo_empty <= ct_fifo_empty when rising_edge(CLK_TX); + + save_sop <= '1' when (TX_PACKET_NUMBER_IN = c_H0) else '0'; + save_eop <= '1' when (TX_PACKET_NUMBER_IN = c_F3) else '0'; + +---------------------------------------------------------------------- +-- RAM +---------------------------------------------------------------------- + THE_RAM_WR_PROC : process(CLK_TX) + begin + 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_TX) + begin + 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)); + ram_dout <= next_ram_dout; + end if; + end process; + +--RAM read pointer + THE_READ_CNT : process(CLK_TX) + begin + if( rising_edge(CLK_TX) ) then + if( link_active_qtx = '0' ) then + ram_read_addr <= (others => '0'); + 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_TX) + begin + if( rising_edge(CLK_TX) ) then + if( link_active_qtx = '0' ) then + ram_write_addr <= (others => '0'); + 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_TX) + begin + if( rising_edge(CLK_TX) ) then + if( link_active_qtx = '0' ) then + ram_fill_level <= (others => '0'); + else + ram_fill_level <= last_ram_write_addr - ram_read_addr; + end if; + end if; + end process; + +--RAM empty + 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_TX); + +---------------------------------------------------------------------- +-- TX control state machine +---------------------------------------------------------------------- + + 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'; + 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 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 - current_state <= SEND_IDLE_L; - end if; - - end if; - end if; + -- 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 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 + 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 (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 = '1' then + --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; - - end process; - - ----------------------------------------------------------------------- --- ----------------------------------------------------------------------- - ---Send DLM message - THE_STORE_DLM_PROC: process( CLK_TX, RESET ) - begin - if( RESET = '1' ) then - send_dlm_i <= '0'; - send_dlm_word_i <= (others => '0'); - elsif( rising_edge(CLK_TX) ) then - if ( link_active_qtx = '0' ) then - send_dlm_i <= '0'; - send_dlm_word_i <= (others => '0'); - elsif( SEND_DLM_IN = '1' ) then - send_dlm_i <= '1'; - 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 - 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_TX, RESET ) - begin - if( RESET = '1' ) then - send_rst_i <= '0'; - send_rst_word_i <= (others => '0'); - elsif( rising_edge(CLK_TX) ) then - if ( link_active_qtx = '0' ) then - send_rst_i <= '0'; - send_rst_word_i <= (others => '0'); - elsif( SEND_RST_IN = '1' ) then - send_rst_i <= '1'; - 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 - send_rst_word_i <= (others => '0'); - end if; - end if; - end process THE_STORE_RST_PROC; - ----------------------------------------------------------------------- --- Debug ----------------------------------------------------------------------- - 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_TX); - DEBUG_OUT(28 downto 0) <= (others => '0'); - - process(CLK_SYS) - begin - 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) <= link_active_qsys; - STAT_REG_OUT(19) <= '0'; - STAT_REG_OUT(21 downto 20) <= (others => '0'); - STAT_REG_OUT(22) <= load_eop; - STAT_REG_OUT(23) <= send_dlm_i; - STAT_REG_OUT(26 downto 24) <= (others => '0'); - 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; - STAT_REG_OUT(31) <= '0'; - end if; - end process; - -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; + if RESET = '1' then + ram_read <= '0'; + end if; + + end process; + + +---------------------------------------------------------------------- +-- +---------------------------------------------------------------------- + +--Send DLM message + THE_STORE_DLM_PROC: process( CLK_TX, RESET ) + begin + if( RESET = '1' ) then + send_dlm_i <= '0'; + send_dlm_word_i <= (others => '0'); + elsif( rising_edge(CLK_TX) ) then + if ( link_active_qtx = '0' ) then + send_dlm_i <= '0'; + send_dlm_word_i <= (others => '0'); + elsif( SEND_DLM_IN = '1' ) then + send_dlm_i <= '1'; + 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 + 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_TX, RESET ) + begin + if( RESET = '1' ) then + send_rst_i <= '0'; + send_rst_word_i <= (others => '0'); + elsif( rising_edge(CLK_TX) ) then + if ( link_active_qtx = '0' ) then + send_rst_i <= '0'; + send_rst_word_i <= (others => '0'); + elsif( SEND_RST_IN = '1' ) then + send_rst_i <= '1'; + 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 + send_rst_word_i <= (others => '0'); + end if; + end if; + end process THE_STORE_RST_PROC; + +---------------------------------------------------------------------- +-- Debug +---------------------------------------------------------------------- + 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_TX); + DEBUG_OUT(28 downto 6) <= (others => '0'); + DEBUG_OUT(5) <= send_steady_idle_int; + DEBUG_OUT(4) <= toggle_idle; + DEBUG_OUT(3 downto 0) <= state_bits; + + process(CLK_SYS) + begin + 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) <= link_active_qsys; + STAT_REG_OUT(19) <= '0'; + STAT_REG_OUT(21 downto 20) <= (others => '0'); + STAT_REG_OUT(22) <= load_eop; + STAT_REG_OUT(23) <= send_dlm_i; + STAT_REG_OUT(26 downto 24) <= (others => '0'); + 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; + STAT_REG_OUT(31) <= '0'; + end if; + end process; + +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;