Skip to content
Snippets Groups Projects
Commit f13f1e7b authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Merge branch 'L2SDP-28' into 'master'

Resolve L2SDP-28

Closes L2SDP-28

See merge request desp/hdl!11
parents 8e99d557 1b72c3e8
No related branches found
No related tags found
1 merge request!11Resolve L2SDP-28
......@@ -263,6 +263,7 @@ test_bench_files =
tb/vhdl/tb_tb_dp_fifo_sc.vhd
tb/vhdl/tb_tb_dp_fifo_fill.vhd
tb/vhdl/tb_tb_dp_fifo_fill_sc.vhd
tb/vhdl/tb_tb_dp_fifo_fill_eop.vhd
tb/vhdl/tb_tb_dp_fifo_dc.vhd
tb/vhdl/tb_tb_dp_fifo_dc_mixed_widths.vhd
tb/vhdl/tb_tb_dp_frame_scheduler.vhd
......@@ -318,6 +319,7 @@ regression_test_vhdl =
tb/vhdl/tb_tb_dp_fifo_dc_mixed_widths.vhd
tb/vhdl/tb_tb_dp_fifo_fill.vhd
tb/vhdl/tb_tb_dp_fifo_fill_sc.vhd
tb/vhdl/tb_tb_dp_fifo_fill_eop.vhd
tb/vhdl/tb_tb_dp_fifo_info.vhd
tb/vhdl/tb_tb_dp_fifo_sc.vhd
tb/vhdl/tb_tb_dp_flush.vhd
......
......@@ -119,18 +119,24 @@ ARCHITECTURE rtl OF dp_fifo_fill_eop IS
SIGNAL i_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
SIGNAL hold_src_in : t_dp_siso;
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
-- Output monitor FIFO filling
......@@ -144,7 +150,6 @@ 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; -- No need to transfer eop across clock domains
u_dp_fifo_sc : ENTITY work.dp_fifo_sc
GENERIC MAP (
g_technology => g_technology,
......@@ -180,26 +185,27 @@ BEGIN
);
wr_fifo_usedw <= rd_fifo_usedw;
END 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)
);
-- 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;
gen_dp_fifo_dc : IF g_use_dual_clock=TRUE GENERATE
u_dp_fifo_dc : ENTITY work.dp_fifo_dc
GENERIC MAP (
g_technology => g_technology,
......@@ -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_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;
no_fill : IF g_fifo_fill=0 GENERATE
......@@ -253,33 +305,21 @@ BEGIN
xon_reg <= '0';
state <= s_idle;
i_src_out <= c_dp_sosi_rst;
received_eop <= FALSE;
expecting_eop <= FALSE;
eop_cnt <= 0;
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
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;
eop_cnt <= nxt_eop_cnt;
END IF;
END PROCESS;
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, 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
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
......@@ -288,6 +328,10 @@ BEGIN
nxt_src_out.sop <= '0';
nxt_src_out.eop <= '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
WHEN s_idle =>
......@@ -307,17 +351,17 @@ BEGIN
nxt_state <= s_xoff;
ELSE
-- 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
ELSE
-- 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_state <= s_output;
IF received_eop THEN
nxt_received_eop <= FALSE;
IF rd_eop_new = '1' THEN
nxt_eop_cnt <= eop_cnt + rd_eop_cnt - 1;
ELSE
nxt_expecting_eop <= TRUE;
nxt_eop_cnt <= eop_cnt -1;
END IF;
END IF;
END IF;
......@@ -361,11 +405,9 @@ 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, 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
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
......@@ -375,6 +417,10 @@ BEGIN
nxt_src_out.sop <= '0';
nxt_src_out.eop <= '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
WHEN s_idle =>
......@@ -394,17 +440,17 @@ BEGIN
nxt_state <= s_xoff;
ELSE
-- 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
ELSE
-- 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_state <= s_output;
IF received_eop THEN
nxt_received_eop <= FALSE;
IF rd_eop_new = '1' THEN
nxt_eop_cnt <= eop_cnt + rd_eop_cnt - 1;
ELSE
nxt_expecting_eop <= TRUE;
nxt_eop_cnt <= eop_cnt -1;
END IF;
END IF;
END IF;
......
......@@ -47,6 +47,7 @@ USE work.tb_dp_pkg.ALL;
ENTITY tb_dp_fifo_fill_eop IS
GENERIC (
-- Try FIFO settings
g_dut_use_dual_clock : BOOLEAN := TRUE;
g_dut_use_bsn : BOOLEAN := FALSE;
g_dut_use_empty : BOOLEAN := FALSE;
g_dut_use_channel : BOOLEAN := FALSE;
......@@ -54,7 +55,7 @@ ENTITY tb_dp_fifo_fill_eop IS
g_dut_fifo_rl : NATURAL := 1; -- internal RL, use 0 for look ahead FIFO, default 1 for normal FIFO
g_dut_fifo_size : NATURAL := 128;
g_dut_fifo_fill : NATURAL := 100; -- selectable >= 0 for dp_fifo_fill
g_dut_use_rd_fill_32b : BOOLEAN := False
g_dut_use_rd_fill_32b : BOOLEAN := FALSE
);
END tb_dp_fifo_fill_eop;
......@@ -131,7 +132,7 @@ ARCHITECTURE tb OF tb_dp_fifo_fill_eop IS
SIGNAL out_val : STD_LOGIC;
SIGNAL out_sop : STD_LOGIC;
SIGNAL out_eop : STD_LOGIC;
SIGNAL prev_out_data : STD_LOGIC_VECTOR(out_data'RANGE);
SIGNAL prev_out_data : STD_LOGIC_VECTOR(out_data'RANGE) := (OTHERS=>'0');
SIGNAL state : t_dp_state_enum;
......@@ -204,7 +205,7 @@ BEGIN
proc_dp_verify_value(e_at_least, clk, verify_done, exp_data, out_data);
-- Verify fill level
p_verify_fifo_fill : PROCESS
p_tb_end : PROCESS
BEGIN
IF g_dut_fifo_fill>0 THEN
-- Use rd_fill_32b /= g_dut_fifo_fill to verify dynamic control
......@@ -212,14 +213,6 @@ BEGIN
rd_fill_32b <= TO_UVEC(g_dut_fifo_size/5, c_word_w);
END IF;
-- Check fill level at first output
proc_common_wait_until_high(clk, out_val);
ASSERT UNSIGNED(rd_usedw)=UNSIGNED(rd_fill_32b) REPORT "Usedw is not equal to fill level at start" SEVERITY ERROR;
-- Check fill level after last output (account for block length given by c_tx_period_sop)
proc_common_wait_until_high(clk, verify_done);
proc_common_wait_some_cycles(clk, g_dut_fifo_size);
ASSERT UNSIGNED(rd_usedw)>=UNSIGNED(rd_fill_32b)-c_tx_period_sop REPORT "Usedw does not match fill level at end" SEVERITY ERROR;
END IF;
proc_common_wait_until_high(clk, tb_done);
......@@ -255,6 +248,7 @@ BEGIN
dut : ENTITY work.dp_fifo_fill_eop
GENERIC MAP (
g_use_dual_clock => g_dut_use_dual_clock,
g_data_w => c_dp_data_w,
g_bsn_w => c_dp_bsn_w,
g_empty_w => c_dp_empty_w,
......
-------------------------------------------------------------------------------
--
-- Copyright 2020
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Author: R. van der Walle
-- Purpose:
-- Multi test bench for dp_fifo_fill_eop
-- Description:
-- Runs two tb_dp_fifo_fill_eop testbenches, one for single clock and one for
-- dual clock.
-- Remark:
-- Usage:
-- > as 10
-- > run -all
-- . signal tb_end will stop the simulation by stopping the clk
-- . the tb is self checking
-------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
ENTITY tb_tb_dp_fifo_fill_eop IS
END tb_tb_dp_fifo_fill_eop;
ARCHITECTURE tb OF tb_tb_dp_fifo_fill_eop IS
SIGNAL tb_end : STD_LOGIC := '0'; -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end'
BEGIN
-- Try FIFO settings : GENERIC MAP (g_dut_use_dual_clock, g_dut_use_bsn, g_dut_use_empty, g_dut_use_channel, g_dut_use_sync, g_dut_fifo_rl, g_dut_fifo_size, g_dut_fifo_fill, g_dut_use_rd_fill_32b)
u_dut_sc : ENTITY work.tb_dp_fifo_fill_eop GENERIC MAP (g_dut_use_dual_clock => FALSE);
u_dut_dc : ENTITY work.tb_dp_fifo_fill_eop GENERIC MAP (g_dut_use_dual_clock => TRUE);
END tb;
......@@ -169,7 +169,7 @@ BEGIN
sample_store_irq_irq => open
);
PROCESS(eoc, mm_rst)
PROCESS(mm_clk, mm_rst)
BEGIN
IF mm_rst = '1' THEN
controller_csr_write <= '0';
......
......@@ -95,7 +95,7 @@ ARCHITECTURE rtl of nw_ping_response IS
BEGIN
-- Combinational Process
p_comb : PROCESS(r, rst, snk_in, dp_pipeline_src_out, dp_fifo_sc_rd_emp)
p_comb : PROCESS(r, rst, snk_in, dp_pipeline_src_out, dp_fifo_sc_rd_emp, eth_src_mac)
VARIABLE v : t_reg;
BEGIN
v := r;
......
......@@ -64,7 +64,7 @@ BEGIN
-------------------------------------------------
-- process to calculate the ip_header_checksum --
-------------------------------------------------
p_calc_chksum : PROCESS(clk)
p_calc_chksum : PROCESS(clk, rst)
BEGIN
IF rst = '1' THEN
sum <= (OTHERS => '0');
......@@ -99,7 +99,7 @@ BEGIN
-- process to insert checksum in outgoing stream --
---------------------------------------------------
checksum <= NOT(STD_LOGIC_VECTOR(sum(c_halfword_w-1 DOWNTO 0)+sum(sum'HIGH DOWNTO c_halfword_w))); -- checksum = inverted (sum + carry)
p_insert_chksum : PROCESS(dp_pipeline_src_out, checksum, count)
p_insert_chksum : PROCESS(dp_pipeline_src_out, checksum, count_p)
BEGIN
src_out <= dp_pipeline_src_out;
IF TO_UINT(count_p) = 2 THEN
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment