-- Media Interface TX/RX
MEDIA_MED2INT : out med2int_array_t(0 to 3);
MEDIA_INT2MED : in int2med_array_t(0 to 3);
- -- Sync operation
+ -- komma operation
RX_DLM_OUT : out std_logic_vector(3 downto 0); -- DLM received
RX_DLM_WORD_OUT : out std_logic_vector(4*8-1 downto 0);
TX_DLM_IN : in std_logic;
RX_RST_WORD_OUT : out std_logic_vector(7 downto 0);
TX_RST_IN : in std_logic;
TX_RST_WORD_IN : in std_logic_vector(7 downto 0);
- WORD_SYNC_IN : in std_logic;
- WORD_SYNC_OUT : out std_logic;
+ -- sync operation
+ WORD_SYNC_IN : in std_logic; -- byte alignment for DLM/RST forwarding (to master port)
+ WORD_SYNC_OUT : out std_logic; -- byte alignment for DLM/RST forwarding (from slave port)
MASTER_CLK_IN : in std_logic; -- recovered RX clock in (only master ports in quad)
MASTER_CLK_OUT : out std_logic; -- recovered RX clock out (slave port in quad)
- MASTER_RESET_OUT : out std_logic;
- DESTROY_LINK_IN : in std_logic_vector(3 downto 0); -- disable SFP transmitter
- LINK_TX_READY_IN : in std_logic; -- TX PLLs are operational
+ GLOBAL_RESET_IN : in std_logic; -- needed for MI with master port(s) only
+ GLOBAL_RESET_OUT : out std_logic; -- only available on MI with slave port
+ TX_PLL_LOL_IN : in std_logic; -- and'ed TX PLL LOL to sync startup
TX_PLL_LOL_OUT : out std_logic; -- status signal of TX PLL
- TX_RESET_OUT : out std_logic;
- SYNC_TX_PLL_IN : in std_logic; -- bit0 alignment for TX Serializer
- RST_QUAD_IN : in std_logic;
- RST_TX_PCS_IN : in std_logic;
+ TX_CLK_AVAIL_OUT : out std_logic; -- stable RX recovered clock available
+ TX_PCS_RST_IN : in std_logic; -- TX PCS reset signal
+ SYNC_TX_PLL_IN : in std_logic; -- bit0 alignment for TX serializer
+ LINK_TX_READY_IN : in std_logic; --
+ DESTROY_LINK_IN : in std_logic_vector(3 downto 0); -- hard reset for links
--SFP Connection
SD_PRSNT_N_IN : in std_logic_vector(3 downto 0); -- SFP Present ('0' = SFP in place, '1' = no SFP mounted)
SD_LOS_IN : in std_logic_vector(3 downto 0); -- SFP Loss Of Signal ('0' = OK, '1' = no signal)
signal rx_k : std_logic_vector(3 downto 0);
signal rx_error : std_logic_vector(3 downto 0);
- signal rst_n : std_logic;
signal rx_serdes_rst : std_logic_vector(3 downto 0);
signal rx_pcs_rst : std_logic_vector(3 downto 0);
- signal rst_qd : std_logic_vector(3 downto 0);
+ signal tx_pcs_rst : std_logic_vector(3 downto 0);
signal rx_los_low : std_logic_vector(3 downto 0);
signal lsm_status : std_logic_vector(3 downto 0);
signal rx_cdr_lol : std_logic_vector(3 downto 0);
- signal tx_pll_lol : std_logic;
signal sci_ch_i : std_logic_vector(4 downto 0);
signal sci_addr_i : std_logic_vector(5 downto 0);
signal sci_read_i : std_logic;
signal sci_write_i : std_logic;
- signal wa_position : std_logic_vector(15 downto 0) := x"FFFF";
-
+ signal wa_position_i : std_logic_vector(15 downto 0) := x"FFFF";
+ signal wa_read_i : std_logic;
+
signal stat_rx_control_i : std_logic_vector(4*32-1 downto 0);
signal stat_tx_control_i : std_logic_vector(4*32-1 downto 0);
signal debug_rx_control_i : std_logic_vector(4*32-1 downto 0);
signal rx_rst_word_i : std_logic_vector(4*8-1 downto 0);
signal rx_rst_i : std_logic_vector(3 downto 0);
- signal master_reset_i : std_logic_vector(3 downto 0);
- signal tx_reset_i : std_logic_vector(3 downto 0);
+ signal global_reset_i : std_logic_vector(3 downto 0);
- signal master_reset_sel : std_logic;
+ signal global_reset_sel : std_logic;
signal pll_lol_i : std_logic;
+
+ signal link_rx_ready_i : std_logic_vector(3 downto 0);
+ signal tx_clk_avail_sel : std_logic;
signal quad_mode : integer range 0 to 100;
begin
--- unused = 0
--- master = 1
--- slave = 8
+-- constants used as reminder
+-- unused = 0, master = 1, slave = 8
-------------------------------------------------
-- check settings of media interface
-------------------------------------------------
-- SFPs are disabled on unused SerDes channels
--------------------------------------------------
- -- we can include the LINK_TX_READY_IN signal here for master ports
+-------------------------------------------------
+-- BUG: link_tx_ready(i) for master ports to be included
+-- BUG: slave ports need also disable with link_tx_ready(i)
SD_TXDIS_OUT(3) <= DESTROY_LINK_IN(3) when IS_MODE(3) = c_IS_MASTER else
'1' when IS_MODE(3) = c_IS_UNUSED else
'0';
-------------------------------------------------
-- TX ref clock
+-- output only if a slave port is available in QUAD
-------------------------------------------------
MASTER_CLK_OUT <= clk_rx_full(0) when ((quad_mode >= 8) and (IS_MODE(0) = c_IS_SLAVE)) else
clk_rx_full(1) when ((quad_mode >= 8) and (IS_MODE(1) = c_IS_SLAVE)) else
'0';
-------------------------------------------------
--- master reset
+-- global reset
+-- output only if a slave port is available in QUAD
-------------------------------------------------
- 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'; -- we need a master reset in!
+ global_reset_sel <= global_reset_i(0) when ((quad_mode >= 8) and (IS_MODE(0) = c_IS_SLAVE)) else
+ global_reset_i(1) when ((quad_mode >= 8) and (IS_MODE(1) = c_IS_SLAVE)) else
+ global_reset_i(2) when ((quad_mode >= 8) and (IS_MODE(2) = c_IS_SLAVE)) else
+ global_reset_i(3) when ((quad_mode >= 8) and (IS_MODE(3) = c_IS_SLAVE)) else
+ GLOBAL_RESET_IN;
- MASTER_RESET_OUT <= master_reset_sel;
+ GLOBAL_RESET_OUT <= global_reset_sel;
+
+-------------------------------------------------
+-- stable RX recovered clock available
+-------------------------------------------------
+ tx_clk_avail_sel <= link_rx_ready_i(0) when ((quad_mode >= 8) and (IS_MODE(0) = c_IS_SLAVE)) else
+ link_rx_ready_i(1) when ((quad_mode >= 8) and (IS_MODE(1) = c_IS_SLAVE)) else
+ link_rx_ready_i(2) when ((quad_mode >= 8) and (IS_MODE(2) = c_IS_SLAVE)) else
+ link_rx_ready_i(3) when ((quad_mode >= 8) and (IS_MODE(3) = c_IS_SLAVE)) else
+ '1';
+
+ TX_CLK_AVAIL_OUT <= tx_clk_avail_sel;
-------------------------------------------------
-- reset komma
+-- output only if a slave port is available in QUAD
-------------------------------------------------
RX_RST_OUT <= rx_rst_i(0) when ((quad_mode >= 8) and (IS_MODE(0) = c_IS_SLAVE)) else
rx_rst_i(1) when ((quad_mode >= 8) and (IS_MODE(1) = c_IS_SLAVE)) else
rx_rst_i(3) when ((quad_mode >= 8) and (IS_MODE(3) = c_IS_SLAVE)) else
'0';
- RX_RST_WORD_OUT <= rx_rst_word_i(7 downto 0) when ((quad_mode >= 8) and (IS_MODE(0) = c_IS_SLAVE)) else
- rx_rst_word_i(15 downto 8) when ((quad_mode >= 8) and (IS_MODE(1) = c_IS_SLAVE)) else
- rx_rst_word_i(23 downto 16) when ((quad_mode >= 8) and (IS_MODE(2) = c_IS_SLAVE)) else
- rx_rst_word_i(31 downto 24) when ((quad_mode >= 8) and (IS_MODE(3) = c_IS_SLAVE)) else
+ RX_RST_WORD_OUT <= rx_rst_word_i(0*8+7 downto 0*8) when ((quad_mode >= 8) and (IS_MODE(0) = c_IS_SLAVE)) else
+ rx_rst_word_i(1*8+7 downto 1*8) when ((quad_mode >= 8) and (IS_MODE(1) = c_IS_SLAVE)) else
+ rx_rst_word_i(2*8+7 downto 2*8) when ((quad_mode >= 8) and (IS_MODE(2) = c_IS_SLAVE)) else
+ rx_rst_word_i(3*8+7 downto 3*8) when ((quad_mode >= 8) and (IS_MODE(3) = c_IS_SLAVE)) else
x"00";
--------------------------------------------------
--- TX PLL reset
--------------------------------------------------
- TX_RESET_OUT <= tx_reset_i(0) when ((quad_mode >= 8) and (IS_MODE(0) = c_IS_SLAVE)) else
- tx_reset_i(1) when ((quad_mode >= 8) and (IS_MODE(1) = c_IS_SLAVE)) else
- tx_reset_i(2) when ((quad_mode >= 8) and (IS_MODE(2) = c_IS_SLAVE)) else
- tx_reset_i(3) when ((quad_mode >= 8) and (IS_MODE(3) = c_IS_SLAVE)) else
- '0';
-
-------------------------------------------------
-- Serdes
-------------------------------------------------
- gen_pcs3: if SERDES_NUM = 3 generate
+ gen_pcs3: if SERDES_NUM = 3 generate -- needed for LPF constraints, should be changed
THE_SERDES : entity work.serdes_sync_all_RS
port map(
hdinp_ch0 => hdinp(0),
rx_serdes_rst_ch0_c => rx_serdes_rst(0),
sb_felb_ch0_c => '0',
sb_felb_rst_ch0_c => '0',
- tx_pcs_rst_ch0_c => RST_TX_PCS_IN, -- was wrong
+ tx_pcs_rst_ch0_c => tx_pcs_rst(0), -- was wrong
tx_pwrup_ch0_c => powerup_ch(0), -- new
rx_pcs_rst_ch0_c => rx_pcs_rst(0),
rx_pwrup_ch0_c => powerup_ch(0), -- new
rx_serdes_rst_ch1_c => rx_serdes_rst(1),
sb_felb_ch1_c => '0',
sb_felb_rst_ch1_c => '0',
- tx_pcs_rst_ch1_c => RST_TX_PCS_IN, -- was wrong
+ tx_pcs_rst_ch1_c => tx_pcs_rst(1), -- was wrong
tx_pwrup_ch1_c => powerup_ch(1), -- new
rx_pcs_rst_ch1_c => rx_pcs_rst(1),
rx_pwrup_ch1_c => powerup_ch(1), -- new
rx_serdes_rst_ch2_c => rx_serdes_rst(2),
sb_felb_ch2_c => '0',
sb_felb_rst_ch2_c => '0',
- tx_pcs_rst_ch2_c => RST_TX_PCS_IN, -- was wrong
+ tx_pcs_rst_ch2_c => tx_pcs_rst(2), -- was wrong
tx_pwrup_ch2_c => powerup_ch(2), -- new
rx_pcs_rst_ch2_c => rx_pcs_rst(2),
rx_pwrup_ch2_c => powerup_ch(2), -- new
rx_serdes_rst_ch3_c => rx_serdes_rst(3),
sb_felb_ch3_c => '0',
sb_felb_rst_ch3_c => '0',
- tx_pcs_rst_ch3_c => RST_TX_PCS_IN, -- was wrong
+ tx_pcs_rst_ch3_c => tx_pcs_rst(3), -- was wrong
tx_pwrup_ch3_c => powerup_ch(3), -- new
rx_pcs_rst_ch3_c => rx_pcs_rst(3),
rx_pwrup_ch3_c => powerup_ch(3), -- new
fpga_txrefclk => MASTER_CLK_IN, -- reference TX clock
tx_serdes_rst_c => '0',
- tx_pll_lol_qd_s => pll_lol_i,
- rst_qd_c => master_reset_sel, --RST_QUAD_IN, -- deadlock caused by this...
+ tx_pll_lol_qd_s => TX_PLL_LOL_OUT,
+ rst_qd_c => GLOBAL_RESET_IN,
serdes_rst_qd_c => '0', -- was wrong
tx_sync_qd_c => SYNC_TX_PLL_IN
);
end generate;
-
- TX_PLL_LOL_OUT <= '1';
-
+
gen_control : for i in 0 to 3 generate
gen_used_control : if (IS_MODE(i) = c_IS_SLAVE) or (IS_MODE(i) = c_IS_MASTER) generate
THE_MED_CONTROL : entity work.med_sync_control_RS
SFP_LOS_IN => SD_LOS_IN(i),
RX_CDR_LOL_IN => rx_cdr_lol(i),
RX_LOS_IN => rx_los_low(i),
- CV_IN => rx_error(i),
- LSM_IN => lsm_status(i),
- PLL_LOL_IN => pll_lol_i,
- WA_POSITION_IN => wa_position(i*4+3 downto i*4),
- LINK_TX_READY_IN => LINK_TX_READY_IN,
+ RX_CV_IN => rx_error(i),
+ RX_LSM_IN => lsm_status(i),
+ TX_PLL_LOL_IN => TX_PLL_LOL_IN,
+ WA_POSITION_IN => wa_position_i(i*4+3 downto i*4),
-- control signals to SerDes
RX_SERDES_RST => rx_serdes_rst(i),
RX_PCS_RST => rx_pcs_rst(i),
+ TX_PCS_RST => tx_pcs_rst(i),
-- SerDes data streams
TX_DATA_OUT => tx_data(i*8+7 downto i*8),
TX_K_OUT => tx_k(i),
-- ports for synchronous operation
WORD_SYNC_IN => WORD_SYNC_IN,
WORD_SYNC_OUT => WORD_SYNC_OUT,
+ GLOBAL_RESET_IN => GLOBAL_RESET_IN,
+ GLOBAL_RESET_OUT => global_reset_i(i),
+ LINK_TX_READY_IN => LINK_TX_READY_IN,
+ LINK_RX_READY_OUT => link_rx_ready_i(i),
+ -- komma operation
TX_DLM_IN => tx_dlm_i,
TX_DLM_WORD_IN => tx_dlm_word_i,
TX_RST_IN => tx_rst_i(i),
RX_DLM_WORD_OUT => RX_DLM_WORD_OUT(i*8+7 downto i*8),
RX_RST_OUT => rx_rst_i(i),
RX_RST_WORD_OUT => rx_rst_word_i(i*8+7 downto i*8),
- MASTER_RESET_OUT => master_reset_i(i),
- TX_RESET_OUT => tx_reset_i(i),
-- Status and debug signals
STAT_TX_CONTROL => stat_tx_control_i(i*32+31 downto i*32),
STAT_RX_CONTROL => stat_rx_control_i(i*32+31 downto i*32),
SCI_RD => sci_read_i,
SCI_WR => sci_write_i,
-- WAP
- WA_POS_OUT => wa_position,
- WA_READ_OUT => open,
- LINK_RX_READY_IN => '0',
+ WA_POS_OUT => wa_position_i,
+ WA_READ_OUT => wa_read_i, --open,
+ LINK_RX_READY_IN => '0', -- BUG
--Slowcontrol
BUS_RX => BUS_RX,
BUS_TX => BUS_TX,
STAT_DEBUG(63 downto 0) <= (others => '0');
- DEBUG_OUT <= debug_i(3*32+31 downto 3*32);
--- DEBUG_OUT(11 downto 0) <= debug_i(3*32+11 downto 3*32);
--- DEBUG_OUT(15 downto 12) <= rx_los_low;
--- DEBUG_OUT(31 downto 16) <= debug_i(3*32+31 downto 3*32+16);
+-- DEBUG_OUT <= debug_i(3*32+31 downto 3*32);
+ DEBUG_OUT(8 downto 0) <= debug_i(3*32+8 downto 3*32);
+ DEBUG_OUT(9) <= wa_read_i;
+ DEBUG_OUT(10) <= tx_clk_avail_sel;
+ DEBUG_OUT(11) <= GLOBAL_RESET_IN;
+ DEBUG_OUT(31 downto 12) <= debug_i(3*32+31 downto 3*32+12);
end architecture;
TX_PLL_LOL_QD_B_IN : in std_logic; -- QUAD B\r
TX_PLL_LOL_QD_C_IN : in std_logic; -- QUAD C\r
TX_PLL_LOL_QD_D_IN : in std_logic; -- QUAD D\r
+ TX_PLL_LOL_OUT : out std_logic; -- wired'or for RX state machines\r
TX_CLOCK_AVAIL_IN : in std_logic; -- recovered RX clock available (if needed)\r
- RST_QD_C_OUT : out std_logic; -- full QUAD reset\r
TX_PCS_RST_CH_C_OUT : out std_logic; -- PCS reset\r
SYNC_TX_QUAD_OUT : out std_logic; -- sync all QUADs to TX bit 0\r
LINK_TX_READY_OUT : out std_logic; -- TX lane can use used now\r
\r
-- We use two different timing for simulation and real world.\r
-- Using SIM_MODE for implementation will most likely kill the link.\r
- constant count2_index : integer := 19 - (SIM_MODE * 12); -- end of timer2\r
- constant count1_index : integer := 3; -- end of timer1\r
+ constant count_index : integer := 15 - (SIM_MODE * 9); -- end of timer\r
\r
- type statetype is ( QUAD_RESET, WAIT_FOR_TIMER1, CHECK_PLOL, WAIT_FOR_TIMER2, SYNC_ALL, NORMAL );\r
+ type statetype is ( IDLE, WAIT_FOR_TIMER, SYNC_ALL, SYNC_DONE, NORMAL );\r
\r
signal CURRENT_STATE : statetype; -- current state of lsm\r
signal NEXT_STATE : statetype; -- next state of lsm\r
signal tx_pll_lol_all_q : std_logic; -- synced\r
signal tx_clock_avail_q : std_logic; -- synced\r
\r
- signal counter1 : unsigned(count1_index downto 0);\r
- signal timer1 : std_logic;\r
- signal reset_timer1 : std_logic;\r
- \r
- signal counter2 : unsigned(count2_index downto 0);\r
- signal timer2 : std_logic;\r
- signal reset_timer2 : std_logic;\r
+ signal counter : unsigned(count_index downto 0);\r
+ signal timer : std_logic;\r
+ signal reset_timer : std_logic;\r
\r
begin\r
\r
tx_pll_lol_all <= TX_PLL_LOL_QD_A_IN or TX_PLL_LOL_QD_B_IN or\r
TX_PLL_LOL_QD_C_IN or TX_PLL_LOL_QD_D_IN;\r
\r
+ \r
+ TX_PLL_LOL_OUT <= tx_pll_lol_all;\r
+ \r
-- synchronize, just to be on the safe side\r
SYNC_SFP_SIGS : entity work.signal_sync\r
generic map(\r
D_OUT(1) => tx_clock_avail_q\r
);\r
\r
--- TIMER1 = 20ns;\r
--- Fastest REFLCK = 312 MHZ, or 3 ns. We need 8 REFCLK cycles.\r
--- A 3 bit counter ([2:0]) counts 8 cycles, so a 4 bit ([3:0]) counter will do if we set TIMER1 = bit[3]\r
\r
--- Timer 1\r
- THE_TIMER1_PROC: process( LOCALCLK )\r
+-- Timer\r
+ THE_TIMER_PROC: process( LOCALCLK )\r
begin\r
if( rising_edge(LOCALCLK) ) then\r
- if( reset_timer1 = '1' ) then\r
- counter1 <= (others => '0');\r
+ if( reset_timer = '1' ) then\r
+ counter <= (others => '0');\r
else\r
- if( counter1(count1_index) = '0' ) then\r
- counter1 <= counter1 + 1 ;\r
+ if( counter(count_index) = '0' ) then\r
+ counter <= counter + 1 ;\r
end if;\r
end if;\r
end if;\r
- end process THE_TIMER1_PROC;\r
-\r
- timer1 <= counter1(count1_index);\r
+ end process THE_TIMER_PROC;\r
\r
--- TIMER2 = 1,400,000 UI;\r
--- WORST CASE CYCLES is with smallest multipier factor.\r
--- This would be with X8 clock multiplier in DIV2 mode\r
--- IN this casse, 1 UI = 2/8 REFCLK CYCLES.\r
--- SO 1,400,000 UI = 1,400,000/4 = 350,000 REFCLK CYCLES\r
--- A 19 bit counter ([18:0]) counts 524288 cycles, so a 20 bit ([19:0]) counter will do if we set TIMER2 = bit[19]\r
-\r
- THE_TIMER2_PROC: process( LOCALCLK )\r
- begin\r
- if( rising_edge(LOCALCLK) ) then\r
- if( reset_timer2 = '1' ) then\r
- counter2 <= (others => '0');\r
- else\r
- if( counter2(count2_index) = '0' ) then\r
- counter2 <= counter2 + 1 ;\r
- end if;\r
- end if;\r
- end if;\r
- end process THE_TIMER2_PROC;\r
+ timer <= counter(count_index);\r
\r
- timer2 <= counter2(count2_index);\r
\r
-- State machine clocked process\r
THE_FSM_PROC: process( LOCALCLK, CLEAR )\r
begin\r
if( CLEAR = '1' ) then\r
- CURRENT_STATE <= QUAD_RESET;\r
+ CURRENT_STATE <= IDLE;\r
TX_PCS_RST_CH_C_OUT <= '1';\r
- RST_QD_C_OUT <= '1';\r
LINK_TX_READY_OUT <= '0';\r
else \r
if( rising_edge(LOCALCLK) ) then\r
CURRENT_STATE <= NEXT_STATE;\r
TX_PCS_RST_CH_C_OUT <= tx_pcs_rst_ch_c_int;\r
- RST_QD_C_OUT <= rst_qd_c_int;\r
LINK_TX_READY_OUT <= link_tx_ready_int;\r
end if;\r
end if;\r
end process THE_FSM_PROC;\r
\r
- THE_FSM_DECODE_PROC: process( CURRENT_STATE, timer1, timer2, tx_pll_lol_all_q, tx_clock_avail_q )\r
+ THE_FSM_DECODE_PROC: process( CURRENT_STATE, timer, tx_pll_lol_all_q, tx_clock_avail_q )\r
begin\r
- reset_timer1 <= '0';\r
- reset_timer2 <= '0';\r
- rst_qd_c_int <= '0';\r
+ reset_timer <= '0';\r
tx_pcs_rst_ch_c_int <= '0';\r
sync_tx_quad_int <= '0';\r
link_tx_ready_int <= '0';\r
\r
case CURRENT_STATE is\r
\r
- when QUAD_RESET =>\r
+ when IDLE =>\r
STATE_OUT <= x"1";\r
tx_pcs_rst_ch_c_int <= '1';\r
- rst_qd_c_int <= '1';\r
- reset_timer1 <= '1';\r
- reset_timer2 <= '1';\r
- NEXT_STATE <= WAIT_FOR_TIMER1;\r
+ reset_timer <= '1';\r
+ NEXT_STATE <= WAIT_FOR_TIMER;\r
\r
- when WAIT_FOR_TIMER1 =>\r
+ when WAIT_FOR_TIMER =>\r
STATE_OUT <= x"2";\r
tx_pcs_rst_ch_c_int <= '1';\r
- rst_qd_c_int <= '1';\r
- reset_timer2 <= '1';\r
- if( timer1 = '1' ) then\r
- NEXT_STATE <= CHECK_PLOL;\r
+ if( timer = '1' ) then\r
+ NEXT_STATE <= SYNC_ALL;\r
else\r
- NEXT_STATE <= WAIT_FOR_TIMER1;\r
+ NEXT_STATE <= WAIT_FOR_TIMER;\r
end if;\r
\r
- when CHECK_PLOL =>\r
+ when SYNC_ALL =>\r
STATE_OUT <= x"3";\r
tx_pcs_rst_ch_c_int <= '1';\r
- reset_timer1 <= '1';\r
- reset_timer2 <= '1';\r
- NEXT_STATE <= WAIT_FOR_TIMER2;\r
+ reset_timer <= '1';\r
+ NEXT_STATE <= SYNC_DONE;\r
\r
- when WAIT_FOR_TIMER2 =>\r
+ when SYNC_DONE =>\r
STATE_OUT <= x"4";\r
- reset_timer1 <= '1';\r
- tx_pcs_rst_ch_c_int <= '1';\r
- if( timer2 = '1' ) then\r
- if( (tx_pll_lol_all_q = '1') or (tx_clock_avail_q = '0') ) then\r
- NEXT_STATE <= QUAD_RESET;\r
- else\r
- NEXT_STATE <= SYNC_ALL;\r
- sync_tx_quad_int <= '1';\r
- end if;\r
- else\r
- NEXT_STATE <= WAIT_FOR_TIMER2;\r
- end if;\r
-\r
- when SYNC_ALL =>\r
- STATE_OUT <= x"5";\r
- reset_timer2 <= '1';\r
- if( timer1 = '1' ) then\r
+ if( timer = '1' ) then\r
NEXT_STATE <= NORMAL;\r
else\r
- NEXT_STATE <= SYNC_ALL;\r
+ NEXT_STATE <= SYNC_DONE;\r
end if;\r
\r
when NORMAL =>\r
- STATE_OUT <= x"6";\r
+ STATE_OUT <= x"5";\r
tx_pcs_rst_ch_c_int <= '0';\r
link_tx_ready_int <= '1';\r
- reset_timer1 <= '1';\r
- reset_timer2 <= '1';\r
+ reset_timer <= '1';\r
if( (tx_pll_lol_all_q = '1') or (tx_clock_avail_q = '0') ) then\r
- NEXT_STATE <= QUAD_RESET;\r
+ NEXT_STATE <= IDLE;\r
else\r
NEXT_STATE <= NORMAL;\r
end if;\r
\r
when others =>\r
STATE_OUT <= x"f";\r
- NEXT_STATE <= QUAD_RESET;\r
+ NEXT_STATE <= IDLE;\r
\r
end case;\r
\r
RESET : in std_logic;
CLEAR : in std_logic;
-- Media Interface
- MEDIA_MED2INT : out MED2INT; -- Media Interface IN
- MEDIA_INT2MED : in INT2MED; -- Media Interface OUT
+ MEDIA_MED2INT : out MED2INT; -- Media Interface OUT
+ MEDIA_INT2MED : in INT2MED; -- Media Interface IN
-- 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
- CV_IN : in std_logic;
- LSM_IN : in std_logic;
- PLL_LOL_IN : in std_logic;
+ RX_CV_IN : in std_logic; -- SerDes RX CodeViolation status
+ RX_LSM_IN : in std_logic; -- SerDes TX LinkStateMachine status
+ TX_PLL_LOL_IN : in std_logic; -- wired'or from all QUADs
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)
+ TX_PCS_RST : out std_logic; -- MISSING!!!
-- 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
-- ports for synchronous operation
WORD_SYNC_IN : in std_logic; -- sync signal for Byte/Word Alignment
WORD_SYNC_OUT : out std_logic;
+ GLOBAL_RESET_IN : in std_logic; -- global reset to master ports
+ GLOBAL_RESET_OUT : out std_logic; -- global reset from slave port
+ LINK_TX_READY_IN : in std_logic; --
+ LINK_RX_READY_OUT : out std_logic; --
+ -- komma handling
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
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);
signal sd_los_q : std_logic;
signal reset_i : std_logic;
- signal clr_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;
D_OUT(0) => sd_los_q
);
--- obselete
--- 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 <= '0';
-
--- RX_RESET_FSM reset
- clr_rx_fsm_i <= sd_los_q;
-
- MASTER_RESET_OUT <= sd_los_q;
+-- we use uplink signal detection as global reset (slave port)
+-- doesn't make sense to start while no link partner is available
+ GLOBAL_RESET_OUT <= sd_los_q;
-- TX_CONTROL and RX_CONTROL reset
reset_i <= (RESET or sd_los_q) when (IS_MODE = c_IS_SLAVE)
-------------------------------------------------
THE_RX_RST_FSM: rx_rsl
port map(
- CLEAR => clr_rx_fsm_i,
+ CLEAR => GLOBAL_RESET_IN,
CLK_REF => CLK_REF,
- PLL_LOL_IN => PLL_LOL_IN,
+ PLL_LOL_IN => TX_PLL_LOL_IN,
CDR_LOL_IN => RX_CDR_LOL_IN,
- CV_IN => CV_IN,
- LSM_IN => LSM_IN,
+ CV_IN => RX_CV_IN,
+ LSM_IN => RX_LSM_IN,
LOS_IN => RX_LOS_IN,
+ WAP_ZERO_IN => is_wap_zero_i,
-- outputs
RX_SERDES_RST_OUT => rx_serdes_rst_i,
RX_PCS_RST_OUT => rx_pcs_rst_i,
LINK_RX_READY_OUT => link_rx_ready_i,
STATE_OUT => rx_fsm_state
);
-
+
-- reset signals for RX SerDes need to be sync'ed to real RX clock for ECP5
SYNC_RST_SIGS: entity work.signal_sync
generic map( WIDTH => 2 )
);
is_wap_zero_i <= '1' when (WA_POSITION_IN = x"0") else '0';
-
+
+ LINK_RX_READY_OUT <= link_rx_ready_i;
+
-------------------------------------------------
-- RX Data
-------------------------------------------------
THE_RX_LSM: rx_lsm_RS
port map(
LINK_RX_READY_IN => link_rx_ready_i,
- RXCLK => CLK_RXI,
+ CLK_RXI => CLK_RXI,
RX_K_IN => RX_K_IN,
RX_DATA_IN => RX_DATA_IN,
LINK_HALF_DONE_OUT => link_half_done_i,
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_TX_READY_IN => '0', -- BUG
LINK_RX_READY_IN => link_rx_ready_i,
LINK_HALF_DONE_IN => link_half_done_i,
LINK_FULL_DONE_IN => link_full_done_i,
media_med2int_i.stat_op(10) <= led_rx or last_led_rx;
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) <= '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";
+-- media_med2int_i.stat_op(5) <= link_tx_ready_i;
+ media_med2int_i.stat_op(4) <= link_rx_ready_i;
+ 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) <= SFP_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) <= CV_IN;
- DEBUG_OUT(6) <= LSM_IN;
- DEBUG_OUT(7) <= PLL_LOL_IN;
- DEBUG_OUT(8) <= link_rx_ready_i;
- DEBUG_OUT(9) <= CLEAR;
- DEBUG_OUT(10) <= clr_rx_fsm_i;
- DEBUG_OUT(11) <= reset_i;
+ DEBUG_OUT(5) <= TX_PLL_LOL_IN;
+ DEBUG_OUT(6) <= is_wap_zero_i;
+ DEBUG_OUT(7) <= link_rx_ready_i;
+ DEBUG_OUT(8) <= LINK_TX_READY_IN;
+ DEBUG_OUT(9) <= '0';
+ DEBUG_OUT(10) <= '0';
+ DEBUG_OUT(11) <= '0';
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');
+-- Some remarks on the SerDes issue:
+-- - slave ports keep everything in global reset until SFP detects light on receiver (SFP_LOS = 0)
+-- - master ports take the slave port global reset, if available, otherwise GSR is used
+-- - the global reset connects to RST_QD_C to keep TX PLL in reset
+-- - slave ports establish the uplink first, with all checks for link integrity and WAP_ZERO_IN
+-- -
+
end architecture;
CV_IN : in std_logic;\r
LSM_IN : in std_logic;\r
LOS_IN : in std_logic;\r
+ WAP_ZERO_IN : in std_logic;\r
-- outputs\r
RX_SERDES_RST_OUT : out std_logic;\r
RX_PCS_RST_OUT : out std_logic;\r
SIM_MODE : integer := 0\r
);\r
port(\r
- CLEAR : in std_logic; -- async reset\r
+ CLEAR : in std_logic; -- async reset, active high\r
LOCALCLK : in std_logic; -- usually RX_REFCLK, not TX_REFCLK! \r
TX_PLL_LOL_QD_A_IN : in std_logic; -- QUAD A\r
TX_PLL_LOL_QD_B_IN : in std_logic; -- QUAD B\r
TX_PLL_LOL_QD_C_IN : in std_logic; -- QUAD C\r
TX_PLL_LOL_QD_D_IN : in std_logic; -- QUAD D\r
+ TX_PLL_LOL_OUT : out std_logic; -- wired'or for RX state machines\r
TX_CLOCK_AVAIL_IN : in std_logic; -- recovered RX clock available (if needed)\r
- RST_QD_C_OUT : out std_logic; -- full QUAD reset\r
TX_PCS_RST_CH_C_OUT : out std_logic; -- PCS reset\r
SYNC_TX_QUAD_OUT : out std_logic; -- sync all QUADs to TX bit 0\r
LINK_TX_READY_OUT : out std_logic; -- TX lane can use used now\r
component rx_lsm_RS is\r
port(\r
LINK_RX_READY_IN : in std_logic; -- serves as async reset, active low\r
- RXCLK : in std_logic; -- recovered RX clock\r
+ CLK_RXI : in std_logic; -- recovered RX clock\r
RX_K_IN : in std_logic;\r
RX_DATA_IN : in std_logic_vector(7 downto 0); \r
LINK_HALF_DONE_OUT : out std_logic;\r
-LIBRARY IEEE;
-USE IEEE.std_logic_1164.ALL;
-USE IEEE.numeric_std.all;
+LIBRARY IEEE;\r
+USE IEEE.std_logic_1164.ALL;\r
+USE IEEE.numeric_std.all;\r
\r
-library work;
+library work;\r
use work.med_sync_define_RS.all;\r
-
+\r
entity rx_lsm_RS is\r
- port(
- LINK_RX_READY_IN : in std_logic; -- serves as async reset, active low
- RXCLK : in std_logic; -- recovered RX clock
- RX_K_IN : in std_logic;
+ port(\r
+ LINK_RX_READY_IN : in std_logic; -- serves as async reset, active low\r
+ CLK_RXI : in std_logic; -- recovered RX clock\r
+ RX_K_IN : in std_logic;\r
RX_DATA_IN : in std_logic_vector(7 downto 0); \r
LINK_HALF_DONE_OUT : out std_logic;\r
- LINK_FULL_DONE_OUT : out std_logic;
- STATE_OUT : out std_logic_vector(3 downto 0)
- );
-end entity;
-
-architecture rx_lsm_arch of rx_lsm_RS is
-\r
- type statetype is ( IDLE, K1F, D1F, K2F, D2FT, D2FS );
-
- signal CURRENT_STATE : statetype; -- current state of lsm
- signal NEXT_STATE : statetype; -- next state of lsm
+ LINK_FULL_DONE_OUT : out std_logic;\r
+ STATE_OUT : out std_logic_vector(3 downto 0)\r
+ );\r
+end entity;\r
+\r
+architecture rx_lsm_arch of rx_lsm_RS is\r
+\r
+ type statetype is ( IDLE, K1F, D1F, K2F, D2FT, D2FS );\r
+\r
+ signal CURRENT_STATE : statetype; -- current state of lsm\r
+ signal NEXT_STATE : statetype; -- next state of lsm\r
\r
signal reset_ctr_t : std_logic;\r
- signal ce_ctr_t : std_logic;
- signal ctr_t : unsigned(4 downto 0);
- signal ctr_t_done : std_logic;
+ signal ce_ctr_t : std_logic;\r
+ signal ctr_t : unsigned(4 downto 0);\r
+ signal ctr_t_done : std_logic;\r
signal reset_ctr_s : std_logic;\r
- signal ce_ctr_s : std_logic;
- signal ctr_s : unsigned(4 downto 0);
- signal ctr_s_done : std_logic;
+ signal ce_ctr_s : std_logic;\r
+ signal ctr_s : unsigned(4 downto 0);\r
+ signal ctr_s_done : std_logic;\r
signal link_toggling_int : std_logic;\r
signal link_steady_int : std_logic;\r
-
-begin
+ \r
+begin\r
\r
- THE_CTR_T_PROC: process( RXCLK, LINK_RX_READY_IN )
+ THE_CTR_T_PROC: process( CLK_RXI, LINK_RX_READY_IN ) \r
begin\r
if ( LINK_RX_READY_IN <= '0' ) then\r
- ctr_t <= (others => '0');
- elsif( rising_edge(RXCLK) ) then
- if( reset_ctr_t = '1' ) then
- ctr_t <= (others => '0');
- else
- if( (ctr_t(4) = '0') and (ce_ctr_t = '1') ) then
- ctr_t <= ctr_t + 1 ;
- end if;
- end if;
- end if;
- end process THE_CTR_T_PROC;
+ ctr_t <= (others => '0');\r
+ elsif( rising_edge(CLK_RXI) ) then\r
+ if( reset_ctr_t = '1' ) then\r
+ ctr_t <= (others => '0');\r
+ else\r
+ if( (ctr_t(4) = '0') and (ce_ctr_t = '1') ) then\r
+ ctr_t <= ctr_t + 1 ;\r
+ end if;\r
+ end if;\r
+ end if;\r
+ end process THE_CTR_T_PROC;\r
\r
ctr_t_done <= ctr_t(4);\r
\r
- THE_CTR_S_PROC: process( RXCLK, LINK_RX_READY_IN )
+ THE_CTR_S_PROC: process( CLK_RXI, LINK_RX_READY_IN ) \r
begin\r
if ( LINK_RX_READY_IN = '0' ) then\r
- ctr_s <= (others => '0');
- elsif( rising_edge(RXCLK) ) then
- if( reset_ctr_s = '1' ) then
- ctr_s <= (others => '0');
- else
- if( (ctr_s(4) = '0') and (ce_ctr_s = '1') ) then
- ctr_s <= ctr_s + 1 ;
- end if;
- end if;
- end if;
- end process THE_CTR_S_PROC;
-
- ctr_s_done <= ctr_s(4);
+ ctr_s <= (others => '0');\r
+ elsif( rising_edge(CLK_RXI) ) then\r
+ if( reset_ctr_s = '1' ) then\r
+ ctr_s <= (others => '0');\r
+ else\r
+ if( (ctr_s(4) = '0') and (ce_ctr_s = '1') and (ctr_t_done = '1') ) then -- added to make sure correct sequence is done\r
+ ctr_s <= ctr_s + 1 ;\r
+ end if;\r
+ end if;\r
+ end if;\r
+ end process THE_CTR_S_PROC;\r
+\r
+ ctr_s_done <= ctr_s(4);\r
\r
-- toggling idles sequence detected\r
- THE_TOGGLE_DETECTED_PROC: process( RXCLK, LINK_RX_READY_IN )\r
+ THE_TOGGLE_DETECTED_PROC: process( CLK_RXI, LINK_RX_READY_IN )\r
begin\r
if ( LINK_RX_READY_IN = '0' ) then\r
link_toggling_int <= '0';\r
- elsif( rising_edge(RXCLK) ) then\r
+ elsif( rising_edge(CLK_RXI) ) then\r
if( ctr_t_done = '1' ) then\r
link_toggling_int <= '1';\r
end if; \r
\r
LINK_HALF_DONE_OUT <= link_toggling_int;\r
\r
- -- steady idles sequence detected
- THE_STEADY_DETECTED_PROC: process( RXCLK, LINK_RX_READY_IN )
- begin
- if ( LINK_RX_READY_IN = '0' ) then
- link_steady_int <= '0';
- elsif( rising_edge(RXCLK) ) then
- if( ctr_s_done = '1' ) then
- link_steady_int <= '1';
- end if;
- end if;
- end process THE_STEADY_DETECTED_PROC;
-\r
- LINK_FULL_DONE_OUT <= link_steady_int;
-
- -- State machine clocked process
- THE_FSM_PROC: process( RXCLK, LINK_RX_READY_IN )
- begin
- if( LINK_RX_READY_IN = '0' ) then
- CURRENT_STATE <= IDLE;
+ -- steady idles sequence detected\r
+ THE_STEADY_DETECTED_PROC: process( CLK_RXI, LINK_RX_READY_IN )\r
+ begin\r
+ if ( LINK_RX_READY_IN = '0' ) then\r
+ link_steady_int <= '0';\r
+ elsif( rising_edge(CLK_RXI) ) then\r
+ if( ctr_s_done = '1' ) then\r
+ link_steady_int <= '1';\r
+ end if; \r
+ end if;\r
+ end process THE_STEADY_DETECTED_PROC;\r
+\r
+ LINK_FULL_DONE_OUT <= link_steady_int;\r
+\r
+ -- State machine clocked process\r
+ THE_FSM_PROC: process( CLK_RXI, LINK_RX_READY_IN )\r
+ begin\r
+ if( LINK_RX_READY_IN = '0' ) then\r
+ CURRENT_STATE <= IDLE;\r
else\r
- if( rising_edge(RXCLK) ) then
- CURRENT_STATE <= NEXT_STATE;
- end if;
- end if;
- end process THE_FSM_PROC;
-\r
- -- State machine decoding processs
- THE_FSM_DECODE_PROC: process( CURRENT_STATE, RX_K_IN, RX_DATA_IN )
- begin
+ if( rising_edge(CLK_RXI) ) then\r
+ CURRENT_STATE <= NEXT_STATE;\r
+ end if;\r
+ end if;\r
+ end process THE_FSM_PROC;\r
+\r
+ -- State machine decoding processs\r
+ THE_FSM_DECODE_PROC: process( CURRENT_STATE, RX_K_IN, RX_DATA_IN )\r
+ begin\r
reset_ctr_t <= '0';\r
reset_ctr_s <= '0';\r
ce_ctr_t <= '0';\r
- ce_ctr_s <= '0';
- STATE_OUT <= x"F";
-
- case CURRENT_STATE is
+ ce_ctr_s <= '0';\r
+ STATE_OUT <= x"F";\r
+\r
+ case CURRENT_STATE is\r
\r
when IDLE =>\r
STATE_OUT <= x"0";\r
end if; \r
\r
when D1F =>\r
- STATE_OUT <= x"2";
- if( (RX_K_IN = '1') and (RX_DATA_IN = K_IDLE) ) then
- NEXT_STATE <= K2F;
- else
- NEXT_STATE <= IDLE;
- end if;
+ STATE_OUT <= x"2";\r
+ if( (RX_K_IN = '1') and (RX_DATA_IN = K_IDLE) ) then\r
+ NEXT_STATE <= K2F;\r
+ else\r
+ NEXT_STATE <= IDLE;\r
+ end if;\r
\r
when K2F =>\r
- STATE_OUT <= x"3";
- if ( (RX_K_IN = '0') and (RX_DATA_IN = D_IDLE1) ) then
- NEXT_STATE <= D2FS;
- elsif( (RX_K_IN = '0') and (RX_DATA_IN = D_IDLE0) ) then
- NEXT_STATE <= D2FT;
- else
- NEXT_STATE <= IDLE;
- end if;
+ STATE_OUT <= x"3";\r
+ if ( (RX_K_IN = '0') and (RX_DATA_IN = D_IDLE1) ) then\r
+ NEXT_STATE <= D2FS;\r
+ elsif( (RX_K_IN = '0') and (RX_DATA_IN = D_IDLE0) ) then\r
+ NEXT_STATE <= D2FT;\r
+ else\r
+ NEXT_STATE <= IDLE;\r
+ end if;\r
\r
when D2FT =>\r
- STATE_OUT <= x"4";
- if( (RX_K_IN = '1') and (RX_DATA_IN = K_IDLE) ) then
+ STATE_OUT <= x"4";\r
+ if( (RX_K_IN = '1') and (RX_DATA_IN = K_IDLE) ) then\r
NEXT_STATE <= K1F;\r
- ce_ctr_t <= '1';
- else
- NEXT_STATE <= IDLE;
- end if;
+ ce_ctr_t <= '1';\r
+ else\r
+ NEXT_STATE <= IDLE;\r
+ end if;\r
\r
when D2FS =>\r
- STATE_OUT <= x"5";
- if( (RX_K_IN = '1') and (RX_DATA_IN = K_IDLE) ) then
+ STATE_OUT <= x"5";\r
+ if( (RX_K_IN = '1') and (RX_DATA_IN = K_IDLE) ) then\r
NEXT_STATE <= K1F;\r
- ce_ctr_s <= '1';
- else
- NEXT_STATE <= IDLE;
- end if;
+ ce_ctr_s <= '1';\r
+ else\r
+ NEXT_STATE <= IDLE;\r
+ end if;\r
\r
when others =>\r
- STATE_OUT <= x"f";
+ STATE_OUT <= x"f";\r
NEXT_STATE <= IDLE;\r
-
- end case;
-
- end process THE_FSM_DECODE_PROC;
-
-end architecture;
+\r
+ end case;\r
+\r
+ end process THE_FSM_DECODE_PROC;\r
+\r
+end architecture;\r
CV_IN : in std_logic;\r
LSM_IN : in std_logic;\r
LOS_IN : in std_logic;\r
+ WAP_ZERO_IN : in std_logic;\r
-- outputs\r
RX_SERDES_RST_OUT : out std_logic;\r
RX_PCS_RST_OUT : out std_logic;\r
-- Remark: work of Christian Michel. Just re-edited to reflect necessary changes for ECP3.\r
-- Without this piece of code, many things would have been a real pain.\r
\r
- constant Tshort : unsigned(31 downto 0) := x"00000007";\r
---@125MHz 100ms\r
- constant Tplol : unsigned(31 downto 0) := x"00BEBC20";\r
- constant Tcdr : unsigned(31 downto 0) := x"00BEBC20";\r
- constant Tviol : unsigned(31 downto 0) := x"00BEBC20";\r
+ constant Tshort : unsigned(31 downto 0) := x"0000000a";\r
+-- @200MHz 100ms\r
+ constant Tplol : unsigned(31 downto 0) := x"003fffff"; --x"01312d00";\r
+ constant Tcdr : unsigned(31 downto 0) := x"003fffff"; --x"01312d00";\r
+ constant Tviol : unsigned(31 downto 0) := x"003fffff"; --x"01312d00";\r
\r
signal pll_lol_s : std_logic;\r
signal cdr_lol_s : std_logic;\r
signal cnt : unsigned(31 downto 0);\r
\r
type rx_sm_state is (POWERUP, APPLY_CDR_RST, WAIT_CDR_LOCK, TEST_CDR, \r
- APPLY_RXPCS_RST, WAIT_RXPCS_LOCK, TEST_RXPCS, IDLE);\r
+ APPLY_RXPCS_RST, WAIT_RXPCS_LOCK, TEST_RXPCS, \r
+ CHECK_WAP, TX_SYNC, NORMAL_OP);\r
\r
signal rx_sm : rx_sm_state;\r
\r
cdr_lol_s <= '1';\r
cv_s <= '1';\r
lsm_s <= '0';\r
- los_s <= '1'; \r
+ los_s <= '1';\r
\r
RX_SERDES_RST_OUT <= '1';\r
RX_PCS_RST_OUT <= '1';\r
LINK_RX_READY_OUT <= '0';\r
- \r
+ \r
rx_sm <= powerup;\r
+ STATE_OUT <= x"f";\r
cnt <= (others => '0'); \r
elsif( rising_edge(CLK_REF) ) then\r
pll_lol_s <= PLL_LOL_IN;\r
else\r
if( cnt = Tviol ) then\r
cnt <= (others => '0');\r
- rx_sm <= IDLE;\r
+ rx_sm <= CHECK_WAP;\r
else\r
cnt <= cnt + 1;\r
end if;\r
end if;\r
- \r
- when idle =>\r
+\r
+ when CHECK_WAP =>\r
STATE_OUT <= x"7";\r
RX_SERDES_RST_OUT <= '0';\r
RX_PCS_RST_OUT <= '0';\r
+ LINK_RX_READY_OUT <= '0';\r
+ cnt <= (others => '0');\r
+ if( WAP_ZERO_IN = '1' ) then\r
+ rx_sm <= NORMAL_OP;\r
+ else\r
+-- rx_sm <= APPLY_RXPCS_RST; -- DOESNT WORK\r
+ rx_sm <= APPLY_CDR_RST;\r
+ end if;\r
+ \r
+ when NORMAL_OP =>\r
+ STATE_OUT <= x"8";\r
+ RX_SERDES_RST_OUT <= '0';\r
+ RX_PCS_RST_OUT <= '0';\r
LINK_RX_READY_OUT <= '1';\r
+ cnt <= (others => '0');\r
if( (lsm_s = '0') or (cv_s = '1') ) then\r
rx_sm <= APPLY_RXPCS_RST; \r
- cnt <= (others => '0');\r
end if;\r
+\r
+ when others =>\r
+ -- just in case\r
+ STATE_OUT <= x"f";\r
+ RX_SERDES_RST_OUT <= '0';\r
+ RX_PCS_RST_OUT <= '0';\r
+ LINK_RX_READY_OUT <= '0';\r
+ rx_sm <= POWERUP;\r
+\r
end case;\r
\r
------------------------------------------------\r