Skip to content
Snippets Groups Projects

Resolve L2SDP-23

Merged Reinier van der Walle requested to merge L2SDP-23 into master
Files
9
@@ -22,10 +22,9 @@
-- Purpose:
-- The FIFO starts outputting data when the output is ready and it has been
-- filled with more than g_fifo_fill words or an eop signal has been received.
-- Given a fixed frame length, this is useful when the in_val is throttled while
-- the out_val should not be inactive valid between out_sop to out_eop.
-- This is necessary for frame transport over a PHY link without separate data
-- valid signal.
-- This is useful when the in_val is throttled while the out_val should not be
-- inactive valid between out_sop to out_eop. This is necessary for frame
-- transport over a PHY link without separate data valid signal.
-- Description:
-- Modified version of dp_fifo_fill_core. In addition to a frame being available
-- after the fifo has been filled sufficiently, a frame is also available when
@@ -99,6 +98,8 @@ ARCHITECTURE rtl OF dp_fifo_fill_eop IS
CONSTANT s_fill : STD_LOGIC_VECTOR(1 DOWNTO 0) := "01";
CONSTANT s_output : STD_LOGIC_VECTOR(1 DOWNTO 0) := "10";
CONSTANT s_xoff : STD_LOGIC_VECTOR(1 DOWNTO 0) := "11";
CONSTANT c_nof_spulse : NATURAL := 3;
SIGNAL state : STD_LOGIC_VECTOR(1 DOWNTO 0); -- t_state
SIGNAL nxt_state : STD_LOGIC_VECTOR(1 DOWNTO 0); -- t_state
@@ -121,7 +122,12 @@ ARCHITECTURE rtl OF dp_fifo_fill_eop IS
SIGNAL pend_src_out : t_dp_sosi;
SIGNAL received_eop : BOOLEAN := FALSE;
SIGNAL nxt_received_eop : BOOLEAN := FALSE;
SIGNAL nxt_received_eop : BOOLEAN := FALSE;
SIGNAL expecting_eop : BOOLEAN := FALSE;
SIGNAL nxt_expecting_eop : BOOLEAN := FALSE;
SIGNAL common_spulse_clken : STD_LOGIC_VECTOR(c_nof_spulse DOWNTO 0) := (OTHERS => '1');
SIGNAL common_spulse_out_pulse : STD_LOGIC_VECTOR(c_nof_spulse-1 DOWNTO 0);
SIGNAL common_spulse_busy : STD_LOGIC_VECTOR(c_nof_spulse-1 DOWNTO 0);
SIGNAL crossed_domain_snk_in_eop : STD_LOGIC := '0';
BEGIN
@@ -136,7 +142,7 @@ BEGIN
rd_fill_ctrl <= rd_fill_32b(c_fifo_size_w-1 DOWNTO 0);
gen_dp_fifo_sc : IF g_use_dual_clock=FALSE GENERATE
crossed_domain_snk_in_eop <= snk_in.eop;
crossed_domain_snk_in_eop <= snk_in.eop; -- No need to transfer eop across clock domains
u_dp_fifo_sc : ENTITY work.dp_fifo_sc
GENERIC MAP (
g_technology => g_technology,
@@ -175,15 +181,22 @@ BEGIN
END GENERATE;
gen_dp_fifo_dc : IF g_use_dual_clock=TRUE GENERATE
u_common_spulse : ENTITY common_lib.common_spulse
PORT MAP (
in_rst => wr_rst,
in_clk => wr_clk,
in_pulse => snk_in.eop,
out_rst => rd_rst,
out_clk => rd_clk,
out_pulse => crossed_domain_snk_in_eop
);
-- Transfer eop across clock domain
crossed_domain_snk_in_eop <= vector_or(common_spulse_out_pulse);
gen_spulse : FOR I IN 0 TO c_nof_spulse-1 GENERATE
common_spulse_clken(I+1) <= vector_and(common_spulse_busy(I DOWNTO 0));
u_common_spulse : ENTITY common_lib.common_spulse
PORT MAP (
in_rst => wr_rst,
in_clk => wr_clk,
in_clken => common_spulse_clken(I),
in_pulse => snk_in.eop,
in_busy => common_spulse_busy(I),
out_rst => rd_rst,
out_clk => rd_clk,
out_pulse => common_spulse_out_pulse(I)
);
END GENERATE;
u_dp_fifo_dc : ENTITY work.dp_fifo_dc
GENERIC MAP (
@@ -239,13 +252,19 @@ BEGIN
state <= s_idle;
i_src_out <= c_dp_sosi_rst;
received_eop <= FALSE;
expecting_eop <= FALSE;
ELSIF rising_edge(rd_clk) THEN
xon_reg <= nxt_xon_reg;
state <= nxt_state;
i_src_out <= nxt_src_out;
IF crossed_domain_snk_in_eop = '1' THEN
received_eop <= TRUE;
IF expecting_eop THEN
expecting_eop <= FALSE;
ELSE
received_eop <= TRUE;
END IF;
ELSE
expecting_eop <= nxt_expecting_eop;
received_eop <= nxt_received_eop;
END IF;
END IF;
@@ -254,10 +273,11 @@ BEGIN
nxt_xon_reg <= src_in.xon; -- register xon to easy timing closure
gen_rl_0 : IF g_fifo_rl=0 GENERATE
p_state : PROCESS(state, rd_sosi, src_in, xon_reg, rd_fifo_usedw, rd_fill_ctrl, received_eop)
p_state : PROCESS(state, rd_sosi, src_in, xon_reg, rd_fifo_usedw, rd_fill_ctrl, received_eop, expecting_eop)
BEGIN
nxt_state <= state;
nxt_received_eop <= received_eop;
nxt_expecting_eop <= expecting_eop;
rd_siso <= src_in; -- default acknowledge (RL=1) this input when output is ready
-- The output register stage increase RL=0 to 1, so it matches RL = 1 for src_in.ready
@@ -291,8 +311,12 @@ BEGIN
-- if the output is ready, then start outputting the frame
IF src_in.ready='1' THEN
nxt_src_out <= rd_sosi; -- output sop that is still at FIFO output (RL=0)
nxt_received_eop <= FALSE;
nxt_state <= s_output;
IF received_eop THEN
nxt_received_eop <= FALSE;
ELSE
nxt_expecting_eop <= TRUE;
END IF;
END IF;
END IF;
END IF;
@@ -335,10 +359,11 @@ BEGIN
src_out_reg => i_src_out
);
p_state : PROCESS(state, src_in, xon_reg, pend_src_out, rd_fifo_usedw, rd_fill_ctrl, received_eop)
p_state : PROCESS(state, src_in, xon_reg, pend_src_out, rd_fifo_usedw, rd_fill_ctrl, received_eop, expecting_eop)
BEGIN
nxt_state <= state;
nxt_received_eop <= received_eop;
nxt_expecting_eop <= expecting_eop;
hold_src_in <= src_in; -- default request (RL=1) new input when output is ready
@@ -373,8 +398,12 @@ BEGIN
-- if the output is ready, then start outputting the input frame
IF src_in.ready='1' THEN
nxt_src_out <= pend_src_out; -- output sop that is still pending in dp_hold_input
nxt_received_eop <= FALSE;
nxt_state <= s_output;
IF received_eop THEN
nxt_received_eop <= FALSE;
ELSE
nxt_expecting_eop <= TRUE;
END IF;
END IF;
END IF;
END IF;
Loading