Commit cfdf688c authored by Grzegorz Daniluk's avatar Grzegorz Daniluk

wr_endpoint: keep rx pcs and rx clk alignment fifo in reset until serdes is locked

Earlier we were resetting clock alignment fifo (ep_rx_path) when GTX was still
not locked and was not producing rx clock. Xilinx document ug363 (Virtex-6 FPGA
Memory Resources) says that dual-clock fifo should have reset signal asserted
for at least three clock cycles. Chipscope says our fifo was reset while rx
clock was not yet there. This apparently was causing Xilinx fifo block going
crazy once every few boots. As a result FIFO was asserting _empty_ and
_almost_full_ outputs at the same time causing the rx path to stall forever.
parent c9eaecf7
......@@ -125,6 +125,7 @@ package endpoint_pkg is
phy_loopen_o : out std_logic;
phy_enable_o : out std_logic;
phy_syncen_o : out std_logic;
phy_rdy_i : in std_logic;
phy_ref_clk_i : in std_logic := '0';
phy_tx_data_o : out std_logic_vector(15 downto 0);
phy_tx_k_o : out std_logic_vector(1 downto 0);
......@@ -220,6 +221,7 @@ package endpoint_pkg is
phy_loopen_o : out std_logic;
phy_enable_o : out std_logic;
phy_syncen_o : out std_logic;
phy_rdy_i : in std_logic;
phy_ref_clk_i : in std_logic;
phy_tx_data_o : out std_logic_vector(15 downto 0);
phy_tx_k_o : out std_logic_vector(1 downto 0);
......
......@@ -138,6 +138,7 @@ package endpoint_private_pkg is
serdes_syncen_o : out std_logic;
serdes_loopen_o : out std_logic;
serdes_enable_o : out std_logic;
serdes_rdy_i : in std_logic;
serdes_tx_clk_i : in std_logic;
serdes_tx_data_o : out std_logic_vector(15 downto 0);
serdes_tx_k_o : out std_logic_vector(1 downto 0);
......@@ -521,6 +522,7 @@ package endpoint_private_pkg is
g_almostfull_threshold : integer);
port (
rst_n_rd_i : in std_logic;
rst_n_wr_i : in std_logic;
clk_wr_i : in std_logic;
clk_rd_i : in std_logic;
dreq_i : in std_logic;
......
......@@ -130,6 +130,9 @@ entity ep_1000basex_pcs is
-- 1: serdes TX/RX is enabled.
serdes_enable_o : out std_logic;
-- 1: serdes is locked and aligned
serdes_rdy_i : in std_logic;
---------------------------------------------------------------------------
......@@ -307,6 +310,7 @@ begin -- rtl
rmon_rx_inv_code => rmon_rx_inv_code,
rmon_rx_sync_lost=> rmon_rx_sync_lost,
phy_rdy_i => serdes_rdy_i,
phy_rx_clk_i => serdes_rx_clk_i,
phy_rx_data_i => serdes_rx_data_i,
phy_rx_k_i => serdes_rx_k_i,
......@@ -379,6 +383,7 @@ begin -- rtl
rmon_rx_inv_code => rmon_rx_inv_code,
rmon_rx_sync_lost=> rmon_rx_sync_lost,
phy_rdy_i => serdes_rdy_i,
phy_rx_clk_i => serdes_rx_clk_i,
phy_rx_data_i => serdes_rx_data_i(7 downto 0),
phy_rx_k_i => serdes_rx_k_i(0),
......
......@@ -51,6 +51,7 @@ entity ep_clock_alignment_fifo is
port(
rst_n_rd_i : in std_logic;
rst_n_wr_i : in std_logic;
clk_wr_i : in std_logic;
clk_rd_i : in std_logic;
......@@ -91,7 +92,7 @@ begin
g_almost_full_threshold => g_almostfull_threshold
)
port map (
rst_n_i => rst_n_rd_i,
rst_n_i => rst_n_wr_i,
clk_wr_i => clk_wr_i,
d_i => fifo_in,
we_i => fifo_we,
......
......@@ -289,6 +289,7 @@ begin -- behavioral
g_almostfull_threshold => 112)
port map (
rst_n_rd_i => rst_n_sys_i,
rst_n_wr_i => rst_n_rx_i,
clk_wr_i => clk_rx_i,
clk_rd_i => clk_sys_i,
dreq_i => dreq_pipe(3),
......
......@@ -77,6 +77,7 @@ entity ep_rx_pcs_16bit is
-- PHY interface
-------------------------------------------------------------------------------
phy_rdy_i : in std_logic;
phy_rx_clk_i : in std_logic;
phy_rx_data_i : in std_logic_vector(15 downto 0);
phy_rx_k_i : in std_logic_vector(1 downto 0);
......@@ -156,6 +157,7 @@ architecture behavioral of ep_rx_pcs_16bit is
end component;
signal reset_synced_rxclk : std_logic;
signal rst_n_rx : std_logic;
signal rx_state : t_tbif_rx_state;
signal preamble_cntr : unsigned(2 downto 0);
......@@ -235,7 +237,7 @@ begin
g_sync_edge => "positive")
port map (
clk_i => phy_rx_clk_i,
rst_n_i => reset_synced_rxclk,
rst_n_i => rst_n_rx,
data_i => an_rx_en_i,
synced_o => an_rx_en_synced,
npulse_o => open,
......@@ -253,6 +255,7 @@ begin
ppulse_o => open);
rx_sync_enable <= not mdio_mcr_pdown_synced;
rst_n_rx <= reset_synced_rxclk and phy_rdy_i;
-------------------------------------------------------------------------------
-- 802.3z Link Synchronization State Machine
......@@ -260,7 +263,7 @@ begin
U_SYNC_DET : ep_sync_detect_16bit
port map (
rst_n_i => reset_synced_rxclk,
rst_n_i => rst_n_rx,
rbclk_i => phy_rx_clk_i,
en_i => rx_sync_enable,
data_i => phy_rx_data_i,
......@@ -294,10 +297,10 @@ begin
-- reads: phy_rx_data_i, mdio_wr_spec_cal_crst_i
-- writes: mdio_wr_spec_rx_cal_stat_o
--
p_detect_cal : process(phy_rx_clk_i, reset_synced_rxclk)
p_detect_cal : process(phy_rx_clk_i, rst_n_rx)
begin
if rising_edge(phy_rx_clk_i) then
if reset_synced_rxclk = '0' then
if rst_n_rx = '0' then
cal_pattern_cntr <= (others => '0');
d_is_cal <= '0';
else
......@@ -331,11 +334,11 @@ begin
-- process postprocesses the raw 8b10b decoder output (phy_rx_data_i, phy_rx_k_i, phy_rx_enc_err_ior)
-- providing 1-bit signals indicating various 8b10b control patterns
p_8b10b_postprocess : process(phy_rx_clk_i, reset_synced_rxclk)
p_8b10b_postprocess : process(phy_rx_clk_i, rst_n_rx)
begin
if rising_edge(phy_rx_clk_i) then
if(reset_synced_rxclk = '0' or rx_synced = '0') then
if(rst_n_rx = '0' or rx_synced = '0') then
d_data <= (others => '0');
d_is_idle <= '0';
d_is_k <= "00";
......@@ -419,11 +422,11 @@ begin
-- writes: almost everything
rx_fsm : process (phy_rx_clk_i, reset_synced_rxclk)
rx_fsm : process (phy_rx_clk_i, rst_n_rx)
begin
if rising_edge(phy_rx_clk_i) then
-- reset or PCS disabled
if(reset_synced_rxclk = '0' or mdio_mcr_pdown_synced = '1') then
if(rst_n_rx = '0' or mdio_mcr_pdown_synced = '1') then
rx_state <= RX_NOFRAME;
rx_busy <= '0';
......@@ -728,7 +731,7 @@ begin
g_width => 3)
port map (
clk_i => phy_rx_clk_i,
rst_n_i => reset_synced_rxclk,
rst_n_i => rst_n_rx,
pulse_i => rmon_invalid_code_p_int,
extended_o => rmon_rx_inv_code);
......@@ -737,7 +740,7 @@ begin
g_width => 3)
port map (
clk_i => phy_rx_clk_i,
rst_n_i => reset_synced_rxclk,
rst_n_i => rst_n_rx,
pulse_i => rmon_rx_overrun_p_int,
extended_o => rmon_rx_overrun);
......@@ -750,7 +753,8 @@ begin
"001" when (rx_state = RX_CR) else
"010" when (rx_state = RX_SPD_PREAMBLE) else
"011" when (rx_state = RX_PAYLOAD) else
"100" when (rx_state = RX_EXTEND);
"100" when (rx_state = RX_EXTEND) else
"111";
end behavioral;
......
......@@ -83,6 +83,7 @@ entity ep_rx_pcs_8bit is
-- PHY interface
-------------------------------------------------------------------------------
phy_rdy_i : in std_logic;
phy_rx_clk_i : in std_logic;
phy_rx_data_i : in std_logic_vector(7 downto 0);
phy_rx_k_i : in std_logic;
......@@ -152,6 +153,7 @@ architecture behavioral of ep_rx_pcs_8bit is
end component;
signal reset_synced_rxclk : std_logic;
signal rst_n_rx : std_logic;
signal rx_state : t_tbif_rx_state;
signal preamble_cntr : unsigned(2 downto 0);
......@@ -241,7 +243,7 @@ begin
g_sync_edge => "positive")
port map (
clk_i => phy_rx_clk_i,
rst_n_i => reset_synced_rxclk,
rst_n_i => rst_n_rx,
data_i => an_rx_en_i,
synced_o => an_rx_en_synced,
npulse_o => open,
......@@ -259,6 +261,7 @@ begin
ppulse_o => open);
rx_sync_enable <= not mdio_mcr_pdown_synced;
rst_n_rx <= reset_synced_rxclk and phy_rdy_i;
-------------------------------------------------------------------------------
-- 802.3z Link Synchronization State Machine
......@@ -266,7 +269,7 @@ begin
U_SYNC_DET : ep_sync_detect
port map (
rst_n_i => reset_synced_rxclk,
rst_n_i => rst_n_rx,
rbclk_i => phy_rx_clk_i,
en_i => rx_sync_enable,
data_i => phy_rx_data_i,
......@@ -301,10 +304,10 @@ begin
-- reads: phy_rx_data_i, mdio_wr_spec_cal_crst_i
-- writes: mdio_wr_spec_rx_cal_stat_o
--
p_detect_cal : process(phy_rx_clk_i, reset_synced_rxclk)
p_detect_cal : process(phy_rx_clk_i, rst_n_rx)
begin
if rising_edge(phy_rx_clk_i) then
if reset_synced_rxclk = '0' then
if rst_n_rx = '0' then
cal_pattern_cntr <= (others => '0');
d_is_cal <= '0';
else
......@@ -355,11 +358,11 @@ begin
-- process postprocesses the raw 8b10b decoder output (phy_rx_data_i, phy_rx_k_i, phy_rx_enc_err_ior)
-- providing 1-bit signals indicating various 8b10b control patterns
p_8b10b_postprocess : process(phy_rx_clk_i, reset_synced_rxclk)
p_8b10b_postprocess : process(phy_rx_clk_i, rst_n_rx)
begin
if rising_edge(phy_rx_clk_i) then
if(reset_synced_rxclk = '0') then
if(rst_n_rx = '0') then
d_data <= (others => '0');
d_is_comma <= '0';
d_is_spd <= '0';
......@@ -454,11 +457,11 @@ begin
-- reads: almost everything
-- writes: almost everything
rx_fsm : process (phy_rx_clk_i, reset_synced_rxclk)
rx_fsm : process (phy_rx_clk_i, rst_n_rx)
begin
if rising_edge(phy_rx_clk_i) then
-- reset or PCS disabled
if(reset_synced_rxclk = '0' or mdio_mcr_pdown_synced = '1') then
if(rst_n_rx = '0' or mdio_mcr_pdown_synced = '1') then
rx_state <= RX_NOFRAME;
rx_busy <= '0';
......@@ -829,7 +832,7 @@ begin
g_width => 3)
port map (
clk_i => phy_rx_clk_i,
rst_n_i => reset_synced_rxclk,
rst_n_i => rst_n_rx,
pulse_i => rmon_invalid_code_p_int,
extended_o => rmon_rx_inv_code);
......@@ -838,7 +841,7 @@ begin
g_width => 3)
port map (
clk_i => phy_rx_clk_i,
rst_n_i => reset_synced_rxclk,
rst_n_i => rst_n_rx,
pulse_i => rmon_rx_overrun_p_int,
extended_o => rmon_rx_overrun);
......
......@@ -108,6 +108,7 @@ entity wr_endpoint is
phy_loopen_o : out std_logic;
phy_enable_o : out std_logic;
phy_syncen_o : out std_logic;
phy_rdy_i : in std_logic;
phy_ref_clk_i : in std_logic;
phy_tx_data_o : out std_logic_vector(15 downto 0);
......@@ -397,7 +398,8 @@ architecture syn of wr_endpoint is
signal src_in : t_wrf_source_in;
signal src_out : t_wrf_source_out;
signal rst_n_rx, rst_n_sys, rst_n_ref : std_logic;
signal rst_n_rxsync, rst_n_sys, rst_n_ref : std_logic;
signal rst_n_rx : std_logic;
signal wb_in : t_wishbone_slave_in;
signal wb_out : t_wishbone_slave_out;
......@@ -462,7 +464,7 @@ begin
clk_i => phy_rx_clk_i,
rst_n_i => '1',
data_i => rst_n_i,
synced_o => rst_n_rx);
synced_o => rst_n_rxsync);
U_Sync_Rst_REF : gc_sync_ffs
port map (
......@@ -472,7 +474,7 @@ begin
synced_o => rst_n_ref);
rst_n_sys <= rst_n_i;
rst_n_rx <= rst_n_rxsync and phy_rdy_i;
-------------------------------------------------------------------------------
-- 1000Base-X PCS
......@@ -511,6 +513,7 @@ begin
serdes_loopen_o => phy_loopen_o,
serdes_enable_o => phy_enable_o,
serdes_syncen_o => phy_syncen_o,
serdes_rdy_i => phy_rdy_i,
serdes_tx_clk_i => phy_ref_clk_i,
serdes_tx_data_o => phy_tx_data_o,
......@@ -703,7 +706,7 @@ begin
clk_ref_i => clk_ref_i,
clk_rx_i => phy_rx_clk_i,
clk_sys_i => clk_sys_i,
rst_n_rx_i => rst_n_rx,
rst_n_rx_i => rst_n_rxsync,
rst_n_sys_i => rst_n_sys,
rst_n_ref_i => rst_n_ref,
pps_csync_p1_i => pps_csync_p1_i,
......
......@@ -97,6 +97,7 @@ entity xwr_endpoint is
phy_loopen_o : out std_logic;
phy_enable_o : out std_logic;
phy_syncen_o : out std_logic;
phy_rdy_i : in std_logic;
phy_ref_clk_i : in std_logic := '0';
phy_tx_data_o : out std_logic_vector(15 downto 0);
......@@ -289,6 +290,7 @@ begin
phy_loopen_o => phy_loopen_o,
phy_enable_o => phy_enable_o,
phy_syncen_o => phy_syncen_o,
phy_rdy_i => phy_rdy_i,
phy_ref_clk_i => phy_ref_clk_i,
phy_tx_data_o => phy_tx_data_o,
phy_tx_k_o => phy_tx_k_o,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment