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

Added g_pipeline verification. Simplified verification of out_enable.

parent 9f593cb0
No related branches found
No related tags found
1 merge request!270Resolve L2SDP-791
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
-- > as 4 -- > as 4
-- > run -all -- > run -all
-- View in Wave window u_dut: r, nxt_r, and tb: in_sosi, out_sosi, -- View in Wave window u_dut: r, nxt_r, and tb: in_sosi, out_sosi,
-- out_sync, out_start -- out_sync, out_start, out_start_interval
-- --
-- Development steps: -- Development steps:
-- . Step 1 ~1 day work (idea started earlier, so requirements were clear), -- . Step 1 ~1 day work (idea started earlier, so requirements were clear),
...@@ -76,13 +76,14 @@ USE dp_lib.tb_dp_pkg.ALL; ...@@ -76,13 +76,14 @@ USE dp_lib.tb_dp_pkg.ALL;
ENTITY tb_dp_bsn_sync_scheduler IS ENTITY tb_dp_bsn_sync_scheduler IS
GENERIC ( GENERIC (
-- Input sync period and sosi ctrl -- Input sync period and sosi ctrl
g_nof_input_sync : NATURAL := 10; g_nof_input_sync : NATURAL := 10; -- Use c_nof_input_sync > g_block_size, see tb_tb_dp_bsn_sync_scheduler
g_nof_block_per_input_sync : NATURAL := 17; g_nof_block_per_input_sync : NATURAL := 17;
g_block_size : NATURAL := 2; g_block_size : NATURAL := 2;
g_input_gap_size : NATURAL := 0; g_input_gap_size : NATURAL := 0;
-- Output sync period -- Output sync period
g_nof_samples_per_output_sync : NATURAL := 45 -- 45 / g_block_size = 4.5 g_nof_samples_per_output_sync : NATURAL := 45; -- 45 / g_block_size = 4.5
g_pipeline : NATURAL := 0 -- 0 or 1
); );
END tb_dp_bsn_sync_scheduler; END tb_dp_bsn_sync_scheduler;
...@@ -108,6 +109,8 @@ ARCHITECTURE tb OF tb_dp_bsn_sync_scheduler IS ...@@ -108,6 +109,8 @@ ARCHITECTURE tb OF tb_dp_bsn_sync_scheduler IS
CONSTANT c_output_nof_blocks_min : NATURAL := g_nof_samples_per_output_sync / g_block_size; CONSTANT c_output_nof_blocks_min : NATURAL := g_nof_samples_per_output_sync / g_block_size;
CONSTANT c_enable_init_nof_bsn : NATURAL := ceil_value(c_output_nof_blocks_min / g_block_size + 10, g_nof_block_per_input_sync); CONSTANT c_enable_init_nof_bsn : NATURAL := ceil_value(c_output_nof_blocks_min / g_block_size + 10, g_nof_block_per_input_sync);
CONSTANT c_out_enable_margin : NATURAL := g_block_size;
SIGNAL clk : STD_LOGIC := '1'; SIGNAL clk : STD_LOGIC := '1';
SIGNAL rst : STD_LOGIC := '1'; SIGNAL rst : STD_LOGIC := '1';
SIGNAL cnt : INTEGER := 0; SIGNAL cnt : INTEGER := 0;
...@@ -145,26 +148,34 @@ ARCHITECTURE tb OF tb_dp_bsn_sync_scheduler IS ...@@ -145,26 +148,34 @@ ARCHITECTURE tb OF tb_dp_bsn_sync_scheduler IS
-- Output -- Output
SIGNAL out_sync : STD_LOGIC; -- declared next to in_sync, out_start and out_sosi for easier comparison in Wave window SIGNAL out_sync : STD_LOGIC; -- declared next to in_sync, out_start and out_sosi for easier comparison in Wave window
SIGNAL out_start : STD_LOGIC; SIGNAL out_start : STD_LOGIC;
SIGNAL out_start_interval : STD_LOGIC;
SIGNAL exp_start_interval : STD_LOGIC := '0';
SIGNAL first_interval : STD_LOGIC := '0';
SIGNAL out_enable : STD_LOGIC; SIGNAL out_enable : STD_LOGIC;
SIGNAL expected_out_enable : STD_LOGIC := '0';
SIGNAL out_sosi : t_dp_sosi := c_dp_sosi_init; SIGNAL out_sosi : t_dp_sosi := c_dp_sosi_init;
-- Verify -- Verify
SIGNAL in_sosi_integer_comb : t_dp_sosi_integer;
SIGNAL in_sosi_integer_pipe : t_dp_sosi_integer;
SIGNAL in_sosi_integer : t_dp_sosi_integer; SIGNAL in_sosi_integer : t_dp_sosi_integer;
SIGNAL out_sosi_integer : t_dp_sosi_integer; SIGNAL out_sosi_integer : t_dp_sosi_integer;
SIGNAL verify_sosi_equal : STD_LOGIC := '0'; SIGNAL verify_sosi_equal : STD_LOGIC := '0';
SIGNAL verify_sosi_equal_at_sop : STD_LOGIC := '0';
SIGNAL verify_sosi_equal_at_valid : STD_LOGIC := '0';
SIGNAL verify_sync : STD_LOGIC := '1'; SIGNAL verify_sync : STD_LOGIC := '1';
SIGNAL recover_from_in_lost : STD_LOGIC := '0'; SIGNAL recover_from_in_lost : STD_LOGIC := '0';
SIGNAL verifying_sync_equal : STD_LOGIC := '0'; SIGNAL verifying_sync_equal : STD_LOGIC := '0';
SIGNAL prev_ctrl_enable : STD_LOGIC := '0';
SIGNAL prev_out_enable : STD_LOGIC := '0'; SIGNAL prev_out_enable : STD_LOGIC := '0';
SIGNAL pending_out_disable : STD_LOGIC := '0'; SIGNAL out_enable_cnt : NATURAL := 0;
SIGNAL expected_out_enable : STD_LOGIC := '0'; SIGNAL nxt_out_enable_cnt : NATURAL := 0;
SIGNAL expected_out_enable1 : STD_LOGIC := '0'; SIGNAL expected_out_enable_comb : STD_LOGIC := '0';
SIGNAL expected_out_enable2 : STD_LOGIC := '0'; SIGNAL expected_out_enable_pipe : STD_LOGIC := '0';
SIGNAL expecting_out_start : STD_LOGIC := '0'; SIGNAL expecting_out_start : STD_LOGIC := '0';
SIGNAL hold_out_eop : STD_LOGIC := '0';
SIGNAL hold_out_sop : STD_LOGIC := '0'; SIGNAL hold_out_sop : STD_LOGIC := '0';
SIGNAL out_sop_cnt : NATURAL := 0; SIGNAL out_sop_cnt : NATURAL := 0;
...@@ -346,75 +357,53 @@ BEGIN ...@@ -346,75 +357,53 @@ BEGIN
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- . Verify out_enable -- . Verify out_enable
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
p_hold_out_eop : PROCESS(clk) -- The expected out_enable is difficult to determine cycle exact, because
BEGIN -- it depends on g_block_size = 2 or > 2 and on g_pipeline. Therfore use
IF rising_edge(clk) THEN -- expected_out_enable_comb = '-' to define dont care.
IF out_sosi.eop = '1' THEN -- * For g_block_size = 2 the use of r.enable (instead of v.enable) in
hold_out_eop <= '1'; -- dp_bsn_sync_scheduler.vhd causes that the output can stay enabled 2
ELSIF out_sosi.sop = '1' THEN -- cycles longer, which is ok. Using v.enable does avoid these extra
hold_out_eop <= '0'; -- cycles, but for timing closure it is preferred to use r.enable.
END IF;
END IF; -- Verify out_enable
END PROCESS; p_expected_out_enable : PROCESS(ctrl_enable, in_sosi, ctrl_start_bsn, ctrl_enable_evt, out_enable_cnt, ctrl_enable, in_sosi, ctrl_start_bsn)
-- Determine expected out_enable
p_expected_out_enable : PROCESS(ctrl_enable, ctrl_enable_evt, in_sosi, ctrl_start_bsn, out_enable, pending_out_disable, hold_out_eop)
BEGIN BEGIN
-- Expect output disable after ctrl_enable_evt -- Default
IF ctrl_enable_evt = '1' THEN expected_out_enable_comb <= '0';
IF out_enable = '0' THEN
-- Output is already disabled
expected_out_enable <= '0';
ELSE
-- Output is enabled, so this is a re-enable event.
IF hold_out_eop = '1' THEN
expected_out_enable <= '0'; -- end of block, so output can disable immediately
ELSE
pending_out_disable <= '1'; -- plan output disable before re-enable
END IF;
END IF;
END IF;
IF pending_out_disable <= '1' THEN -- Expect output enable '1' when ctrl_enable is active, but after ctrl_start_bsn
IF hold_out_eop = '1' THEN
expected_out_enable <= '0'; -- end of block, so output can disable
pending_out_disable <= '0';
END IF;
END IF;
-- Expect output enable at start BSN
IF ctrl_enable = '1' THEN IF ctrl_enable = '1' THEN
IF UNSIGNED(in_sosi.bsn) >= UNSIGNED(ctrl_start_bsn) THEN IF UNSIGNED(in_sosi.bsn) >= UNSIGNED(ctrl_start_bsn) THEN
expected_out_enable <= '1'; expected_out_enable_comb <= '1';
END IF;
END IF; END IF;
-- Introduce some dont care margin in case of ctrl_enable_evt when ctrl_enable was active and may change.
-- The ctrl_enable may go inactive (= stop) or remain active (= restart).
IF ctrl_enable_evt = '1' AND prev_ctrl_enable = '1' THEN
nxt_out_enable_cnt <= 0;
expected_out_enable_comb <= '-';
ELSIF out_enable_cnt < c_out_enable_margin THEN
nxt_out_enable_cnt <= out_enable_cnt + 1;
expected_out_enable_comb <= '-';
END IF; END IF;
END PROCESS; END PROCESS;
expected_out_enable1 <= expected_out_enable WHEN rising_edge(clk); prev_ctrl_enable <= ctrl_enable WHEN rising_edge(clk);
expected_out_enable2 <= expected_out_enable1 WHEN rising_edge(clk);
out_enable_cnt <= nxt_out_enable_cnt WHEN rising_edge(clk);
expected_out_enable_pipe <= expected_out_enable_comb WHEN rising_edge(clk);
expected_out_enable <= expected_out_enable_comb WHEN g_pipeline = 0 ELSE expected_out_enable_pipe;
p_verify_out_enable : PROCESS(clk) p_verify_out_enable : PROCESS(clk)
BEGIN BEGIN
-- Use registered values to compare, to avoid combinatorial differences
-- that can occur during a simulation delta cycle. These combinatorial
-- differences are not relevant, because they get resolved after a few
-- delta cycles.
IF rising_edge(clk) THEN IF rising_edge(clk) THEN
IF out_enable /= expected_out_enable THEN IF expected_out_enable = '1' THEN
IF out_enable = '1' THEN ASSERT out_enable = '1' REPORT "Wrong out_enable, should be active" SEVERITY ERROR;
IF g_block_size > 2 THEN ELSIF expected_out_enable = '0' THEN
REPORT "Unexpected enabled out_enable" SEVERITY ERROR; ASSERT out_enable = '0' REPORT "Wrong out_enable, should be inactive" SEVERITY ERROR;
ELSIF out_enable /= expected_out_enable2 THEN
-- For g_block_size = 2 the use of r.enable (instead of v.enable)
-- in dp_bsn_sync_scheduler.vhd causes that the output can stay
-- enabled 2 cycles longer, which is ok. Using v.enable does
-- avoid this need to use expected_out_enable2, but for timing
-- closure it is preferred to use r.enable.
REPORT "Unexpected enabled out_enable2" SEVERITY ERROR;
END IF;
ELSE
REPORT "Unexpected disabled out_enable" SEVERITY ERROR;
END IF;
END IF; END IF;
END IF; END IF;
END PROCESS; END PROCESS;
...@@ -471,6 +460,23 @@ BEGIN ...@@ -471,6 +460,23 @@ BEGIN
END IF; END IF;
END PROCESS; END PROCESS;
exp_start_interval <= out_start OR (first_interval AND NOT out_sync) WHEN rst = '0' ELSE '0';
p_verify_out_start_interval : PROCESS(clk)
BEGIN
IF rising_edge(clk) THEN
-- Create first_interval for exp_start_interval
IF out_start = '1' THEN
first_interval <= '1';
ELSIF out_sync = '1' THEN
first_interval <= '0';
END IF;
-- Verify exp_start_interval
ASSERT exp_start_interval = out_start_interval REPORT "Wrong out_start_interval" SEVERITY ERROR;
END IF;
END PROCESS;
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- . Verify out_sosi = in_sosi, for all fields except out_sosi.sync -- . Verify out_sosi = in_sosi, for all fields except out_sosi.sync
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
...@@ -480,14 +486,19 @@ BEGIN ...@@ -480,14 +486,19 @@ BEGIN
-- declaration is not sufficient. -- declaration is not sufficient.
verify_sosi_equal <= out_enable WHEN rising_edge(clk); verify_sosi_equal <= out_enable WHEN rising_edge(clk);
in_sosi_integer <= func_dp_stream_slv_to_integer(in_sosi, c_natural_w) WHEN rising_edge(clk); verify_sosi_equal_at_sop <= verify_sosi_equal AND in_sosi_integer.sop;
verify_sosi_equal_at_valid <= verify_sosi_equal AND in_sosi_integer.valid;
in_sosi_integer_comb <= func_dp_stream_slv_to_integer(in_sosi, c_natural_w) WHEN rising_edge(clk);
in_sosi_integer_pipe <= in_sosi_integer_comb WHEN rising_edge(clk);
in_sosi_integer <= in_sosi_integer_comb WHEN g_pipeline = 0 ELSE in_sosi_integer_pipe;
out_sosi_integer <= func_dp_stream_slv_to_integer(out_sosi, c_natural_w) WHEN rising_edge(clk); out_sosi_integer <= func_dp_stream_slv_to_integer(out_sosi, c_natural_w) WHEN rising_edge(clk);
proc_dp_verify_sosi_equal( "bsn", clk, verify_sosi_equal, out_sosi_integer, in_sosi_integer); proc_dp_verify_sosi_equal( "bsn", clk, verify_sosi_equal_at_sop, out_sosi_integer, in_sosi_integer);
proc_dp_verify_sosi_equal( "sop", clk, verify_sosi_equal, out_sosi_integer, in_sosi_integer); proc_dp_verify_sosi_equal( "sop", clk, verify_sosi_equal, out_sosi_integer, in_sosi_integer);
proc_dp_verify_sosi_equal( "eop", clk, verify_sosi_equal, out_sosi_integer, in_sosi_integer); proc_dp_verify_sosi_equal( "eop", clk, verify_sosi_equal, out_sosi_integer, in_sosi_integer);
proc_dp_verify_sosi_equal("valid", clk, verify_sosi_equal, out_sosi_integer, in_sosi_integer); proc_dp_verify_sosi_equal("valid", clk, verify_sosi_equal, out_sosi_integer, in_sosi_integer);
proc_dp_verify_sosi_equal( "data", clk, verify_sosi_equal, out_sosi_integer, in_sosi_integer); proc_dp_verify_sosi_equal( "data", clk, verify_sosi_equal_at_valid, out_sosi_integer, in_sosi_integer);
-- Verify that out_sosi blocks have sop and eop -- Verify that out_sosi blocks have sop and eop
proc_dp_verify_sop_and_eop(clk, out_sosi.valid, out_sosi.sop, out_sosi.eop, hold_out_sop); proc_dp_verify_sop_and_eop(clk, out_sosi.valid, out_sosi.sop, out_sosi.eop, hold_out_sop);
...@@ -558,7 +569,7 @@ BEGIN ...@@ -558,7 +569,7 @@ BEGIN
GENERIC MAP ( GENERIC MAP (
g_bsn_w => c_bsn_w, g_bsn_w => c_bsn_w,
g_block_size => g_block_size, g_block_size => g_block_size,
g_pipeline => 0 g_pipeline => g_pipeline
) )
PORT MAP ( PORT MAP (
rst => rst, rst => rst,
...@@ -578,6 +589,7 @@ BEGIN ...@@ -578,6 +589,7 @@ BEGIN
in_sosi => in_sosi, in_sosi => in_sosi,
out_sosi => out_sosi, out_sosi => out_sosi,
out_start => out_start, out_start => out_start,
out_start_interval => out_start_interval,
out_enable => out_enable out_enable => out_enable
); );
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment