Skip to content
Snippets Groups Projects

Resolve L2SDP-28

Merged Reinier van der Walle requested to merge L2SDP-28 into master
All threads resolved!
7 files
+ 178
84
Compare changes
  • Side-by-side
  • Inline
Files
7
@@ -119,18 +119,24 @@ ARCHITECTURE rtl OF dp_fifo_fill_eop IS
@@ -119,18 +119,24 @@ ARCHITECTURE rtl OF dp_fifo_fill_eop IS
SIGNAL i_src_out : t_dp_sosi;
SIGNAL i_src_out : t_dp_sosi;
SIGNAL nxt_src_out : t_dp_sosi;
SIGNAL nxt_src_out : t_dp_sosi;
 
-- EOP clock domain crossing signals
 
SIGNAL reg_wr_eop_cnt : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
 
SIGNAL reg_rd_eop_cnt : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
 
SIGNAL wr_eop_done : STD_LOGIC;
 
SIGNAL wr_eop_new : STD_LOGIC;
 
SIGNAL rd_eop_new : STD_LOGIC;
 
SIGNAL wr_eop_busy : STD_LOGIC;
 
SIGNAL wr_eop_cnt : NATURAL := 0;
 
SIGNAL rd_eop_cnt : NATURAL := 0;
 
 
-- EOP count can be negative when a packet is sent out without having received the eop. This can be the case when g_fifo_fill has been reached.
 
SIGNAL eop_cnt : INTEGER := 0;
 
SIGNAL nxt_eop_cnt : INTEGER := 0;
 
-- Signals for g_fifo_rl=1
-- Signals for g_fifo_rl=1
SIGNAL hold_src_in : t_dp_siso;
SIGNAL hold_src_in : t_dp_siso;
SIGNAL pend_src_out : t_dp_sosi;
SIGNAL pend_src_out : t_dp_sosi;
SIGNAL 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
BEGIN
-- Output monitor FIFO filling
-- Output monitor FIFO filling
@@ -144,7 +150,6 @@ BEGIN
@@ -144,7 +150,6 @@ BEGIN
rd_fill_ctrl <= rd_fill_32b(c_fifo_size_w-1 DOWNTO 0);
rd_fill_ctrl <= rd_fill_32b(c_fifo_size_w-1 DOWNTO 0);
gen_dp_fifo_sc : IF g_use_dual_clock=FALSE GENERATE
gen_dp_fifo_sc : IF g_use_dual_clock=FALSE GENERATE
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
u_dp_fifo_sc : ENTITY work.dp_fifo_sc
GENERIC MAP (
GENERIC MAP (
g_technology => g_technology,
g_technology => g_technology,
@@ -180,26 +185,27 @@ BEGIN
@@ -180,26 +185,27 @@ BEGIN
);
);
wr_fifo_usedw <= rd_fifo_usedw;
wr_fifo_usedw <= rd_fifo_usedw;
 
 
-- No need to transfer eop counter across clock domains
 
rd_eop_cnt <= wr_eop_cnt;
 
rd_eop_new <= '1';
 
p_sc: PROCESS(wr_clk, wr_rst)
 
BEGIN
 
IF wr_rst='1' THEN
 
wr_eop_cnt <= 0;
 
ELSIF rising_edge(wr_clk) THEN
 
IF snk_in.eop = '1' THEN
 
wr_eop_cnt <= 1;
 
ELSE
 
wr_eop_cnt <= 0;
 
END IF;
 
END IF;
 
END PROCESS;
 
 
END GENERATE;
END GENERATE;
gen_dp_fifo_dc : IF g_use_dual_clock=TRUE GENERATE
gen_dp_fifo_dc : IF g_use_dual_clock=TRUE GENERATE
-- 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
u_dp_fifo_dc : ENTITY work.dp_fifo_dc
GENERIC MAP (
GENERIC MAP (
g_technology => g_technology,
g_technology => g_technology,
@@ -236,6 +242,52 @@ BEGIN
@@ -236,6 +242,52 @@ BEGIN
src_in => rd_siso, -- for RL = 0 rd_siso.ready acts as read acknowledge, -- for RL = 1 rd_siso.ready acts as read request
src_in => rd_siso, -- for RL = 0 rd_siso.ready acts as read acknowledge, -- for RL = 1 rd_siso.ready acts as read request
src_out => rd_sosi
src_out => rd_sosi
);
);
 
 
-- Transfer eop counter across clock domains
 
reg_wr_eop_cnt <= TO_UVEC(wr_eop_cnt, c_word_w);
 
rd_eop_cnt <= TO_UINT(reg_rd_eop_cnt);
 
u_common_reg_cross_domain : ENTITY common_lib.common_reg_cross_domain
 
PORT MAP (
 
in_rst => wr_rst,
 
in_clk => wr_clk,
 
in_dat => reg_wr_eop_cnt,
 
in_new => wr_eop_new,
 
in_done => wr_eop_done,
 
out_rst => rd_rst,
 
out_clk => rd_clk,
 
out_dat => reg_rd_eop_cnt,
 
out_new => rd_eop_new
 
);
 
 
p_dc: PROCESS(wr_clk, wr_rst)
 
VARIABLE v_wr_eop_cnt: NATURAL;
 
BEGIN
 
IF wr_rst='1' THEN
 
wr_eop_busy <= '0';
 
wr_eop_cnt <= 0;
 
wr_eop_new <= '0';
 
ELSIF rising_edge(wr_clk) THEN
 
v_wr_eop_cnt := wr_eop_cnt;
 
IF wr_eop_done = '1' THEN
 
wr_eop_busy <= '0';
 
END IF;
 
 
IF wr_eop_busy = '0' THEN
 
wr_eop_busy <= '1';
 
wr_eop_new <= '1';
 
END IF;
 
 
IF wr_eop_new = '1' THEN
 
wr_eop_new <= '0';
 
v_wr_eop_cnt := 0;
 
END IF;
 
 
IF snk_in.eop = '1' THEN
 
v_wr_eop_cnt := v_wr_eop_cnt + 1;
 
END IF;
 
wr_eop_cnt <= v_wr_eop_cnt;
 
END IF;
 
END PROCESS;
END GENERATE;
END GENERATE;
no_fill : IF g_fifo_fill=0 GENERATE
no_fill : IF g_fifo_fill=0 GENERATE
@@ -246,40 +298,28 @@ BEGIN
@@ -246,40 +298,28 @@ BEGIN
gen_fill : IF g_fifo_fill>0 GENERATE
gen_fill : IF g_fifo_fill>0 GENERATE
src_out <= i_src_out;
src_out <= i_src_out;
p_rd_clk: PROCESS(rd_clk, rd_rst)
p_rd_clk: PROCESS(rd_clk, rd_rst)
BEGIN
BEGIN
IF rd_rst='1' THEN
IF rd_rst='1' THEN
xon_reg <= '0';
xon_reg <= '0';
state <= s_idle;
state <= s_idle;
i_src_out <= c_dp_sosi_rst;
i_src_out <= c_dp_sosi_rst;
received_eop <= FALSE;
eop_cnt <= 0;
expecting_eop <= FALSE;
ELSIF rising_edge(rd_clk) THEN
ELSIF rising_edge(rd_clk) THEN
xon_reg <= nxt_xon_reg;
xon_reg <= nxt_xon_reg;
state <= nxt_state;
state <= nxt_state;
i_src_out <= nxt_src_out;
i_src_out <= nxt_src_out;
IF crossed_domain_snk_in_eop = '1' THEN
eop_cnt <= nxt_eop_cnt;
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;
END IF;
END PROCESS;
END PROCESS;
nxt_xon_reg <= src_in.xon; -- register xon to easy timing closure
nxt_xon_reg <= src_in.xon; -- register xon to easy timing closure
gen_rl_0 : IF g_fifo_rl=0 GENERATE
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, expecting_eop)
p_state : PROCESS(state, rd_sosi, src_in, xon_reg, rd_fifo_usedw, rd_fill_ctrl, rd_eop_cnt, eop_cnt, rd_eop_new)
BEGIN
BEGIN
nxt_state <= state;
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
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
-- The output register stage increase RL=0 to 1, so it matches RL = 1 for src_in.ready
@@ -288,6 +328,10 @@ BEGIN
@@ -288,6 +328,10 @@ BEGIN
nxt_src_out.sop <= '0';
nxt_src_out.sop <= '0';
nxt_src_out.eop <= '0';
nxt_src_out.eop <= '0';
nxt_src_out.sync <= '0';
nxt_src_out.sync <= '0';
 
nxt_eop_cnt <= eop_cnt;
 
IF rd_eop_new = '1' THEN
 
nxt_eop_cnt <= eop_cnt + rd_eop_cnt;
 
END IF;
CASE state IS
CASE state IS
WHEN s_idle =>
WHEN s_idle =>
@@ -307,17 +351,17 @@ BEGIN
@@ -307,17 +351,17 @@ BEGIN
nxt_state <= s_xoff;
nxt_state <= s_xoff;
ELSE
ELSE
-- stop reading until the FIFO has been filled sufficiently
-- stop reading until the FIFO has been filled sufficiently
IF UNSIGNED(rd_fifo_usedw)<UNSIGNED(rd_fill_ctrl) AND NOT received_eop THEN
IF UNSIGNED(rd_fifo_usedw)<UNSIGNED(rd_fill_ctrl) AND eop_cnt <= 0 THEN
rd_siso <= c_dp_siso_hold; -- stop the input, hold the pend_src_out.sop
rd_siso <= c_dp_siso_hold; -- stop the input, hold the pend_src_out.sop
ELSE
ELSE
-- if the output is ready, then start outputting the frame
-- if the output is ready, then start outputting the frame
IF src_in.ready='1' THEN
IF src_in.ready='1' THEN
nxt_src_out <= rd_sosi; -- output sop that is still at FIFO output (RL=0)
nxt_src_out <= rd_sosi; -- output sop that is still at FIFO output (RL=0)
nxt_state <= s_output;
nxt_state <= s_output;
IF received_eop THEN
IF rd_eop_new = '1' THEN
nxt_received_eop <= FALSE;
nxt_eop_cnt <= eop_cnt + rd_eop_cnt - 1;
ELSE
ELSE
nxt_expecting_eop <= TRUE;
nxt_eop_cnt <= eop_cnt -1;
END IF;
END IF;
END IF;
END IF;
END IF;
END IF;
@@ -361,11 +405,9 @@ BEGIN
@@ -361,11 +405,9 @@ BEGIN
src_out_reg => i_src_out
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, expecting_eop)
p_state : PROCESS(state, src_in, xon_reg, pend_src_out, rd_fifo_usedw, rd_fill_ctrl, rd_eop_cnt, eop_cnt, rd_eop_new)
BEGIN
BEGIN
nxt_state <= state;
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
hold_src_in <= src_in; -- default request (RL=1) new input when output is ready
@@ -375,6 +417,10 @@ BEGIN
@@ -375,6 +417,10 @@ BEGIN
nxt_src_out.sop <= '0';
nxt_src_out.sop <= '0';
nxt_src_out.eop <= '0';
nxt_src_out.eop <= '0';
nxt_src_out.sync <= '0';
nxt_src_out.sync <= '0';
 
nxt_eop_cnt <= eop_cnt;
 
IF rd_eop_new = '1' THEN
 
nxt_eop_cnt <= eop_cnt + rd_eop_cnt;
 
END IF;
CASE state IS
CASE state IS
WHEN s_idle =>
WHEN s_idle =>
@@ -394,17 +440,17 @@ BEGIN
@@ -394,17 +440,17 @@ BEGIN
nxt_state <= s_xoff;
nxt_state <= s_xoff;
ELSE
ELSE
-- stop reading until the FIFO has been filled sufficiently
-- stop reading until the FIFO has been filled sufficiently
IF UNSIGNED(rd_fifo_usedw)<UNSIGNED(rd_fill_ctrl) AND NOT received_eop THEN
IF UNSIGNED(rd_fifo_usedw)<UNSIGNED(rd_fill_ctrl) AND eop_cnt <= 0 THEN
hold_src_in <= c_dp_siso_hold; -- stop the input, hold the pend_src_out.sop
hold_src_in <= c_dp_siso_hold; -- stop the input, hold the pend_src_out.sop
ELSE
ELSE
-- if the output is ready, then start outputting the input frame
-- if the output is ready, then start outputting the input frame
IF src_in.ready='1' THEN
IF src_in.ready='1' THEN
nxt_src_out <= pend_src_out; -- output sop that is still pending in dp_hold_input
nxt_src_out <= pend_src_out; -- output sop that is still pending in dp_hold_input
nxt_state <= s_output;
nxt_state <= s_output;
IF received_eop THEN
IF rd_eop_new = '1' THEN
nxt_received_eop <= FALSE;
nxt_eop_cnt <= eop_cnt + rd_eop_cnt - 1;
ELSE
ELSE
nxt_expecting_eop <= TRUE;
nxt_eop_cnt <= eop_cnt -1;
END IF;
END IF;
END IF;
END IF;
END IF;
END IF;
Loading