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

Verify dp_rsn_source.vhd in multi tb_tb.

parent 3d1528cc
No related branches found
No related tags found
Loading
Pipeline #46461 passed
......@@ -308,6 +308,7 @@ test_bench_files =
tb/vhdl/tb_tb_dp_bsn_align.vhd
tb/vhdl/tb_tb_dp_bsn_align_v2.vhd
tb/vhdl/tb_tb_mmp_dp_bsn_align_v2.vhd
tb/vhdl/tb_tb_dp_rsn_source.vhd
tb/vhdl/tb_tb_dp_bsn_source_v2.vhd
tb/vhdl/tb_tb_dp_bsn_sync_scheduler.vhd
tb/vhdl/tb_tb_dp_concat.vhd
......@@ -382,6 +383,7 @@ regression_test_vhdl =
tb/vhdl/tb_tb_dp_block_validate_channel.vhd
tb/vhdl/tb_tb_dp_bsn_align_v2.vhd
tb/vhdl/tb_tb_mmp_dp_bsn_align_v2.vhd
tb/vhdl/tb_tb_dp_rsn_source.vhd
tb/vhdl/tb_tb_dp_bsn_source_v2.vhd
tb/vhdl/tb_tb_dp_bsn_sync_scheduler.vhd
tb/vhdl/tb_tb_dp_concat.vhd
......
-------------------------------------------------------------------------------
--
-- Copyright 2022
-- Copyright 2023
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
......@@ -32,11 +32,12 @@
-- The bs_sosi can stop and restart. It (re)starts with bs_sosi.sync and
-- bs_sosi.sop when bs_sosi.valid becomes '1' and it stops when
-- bs_sosi.valid becomes '0' immediately after a bs_sosi.eop.
-- The rs_sosi block size is g_block_size.
-- The rs_sosi block size is g_rs_block_size.
-- The rs_sosi sync interval has g_nof_clk_per_sync. If g_nof_clk_per_sync
-- is not a multiple of g_block_size, then the rs_sosi.sync will occur at
-- is not a multiple of g_rs_block_size, then the rs_sosi.sync will occur at
-- the next start of block.
-- The initial RSN in rs_sosi.bsn is bs_sosi.bsn * g_block_size.
-- The initial RSN in rs_sosi.bsn is bs_sosi.bsn * g_bs_block_size, where
-- g_bs_block_size is the input block size of bs_sosi.
-- The rs_sosi starts when the bs_sosi starts, so when bs_sosi.sync = '1'
-- and bs_sosi.valid becomes '1'.
-- The rs_sosi ends after the rs_sosi.eop, when the bs_sosi ends. There
......@@ -56,7 +57,8 @@ USE work.dp_stream_pkg.ALL;
ENTITY dp_rsn_source IS
GENERIC (
g_block_size : NATURAL := 256; -- >= 3, see state machine
g_bs_block_size : NATURAL := 256; -- input bs_sosi block size, >= 3, see state machine
g_rs_block_size : NATURAL := 256; -- output rs_sosi block size, >= 3, see state machine
g_nof_clk_per_sync : NATURAL := 200 * 10**6;
g_bsn_w : NATURAL := 64
);
......@@ -69,7 +71,7 @@ ENTITY dp_rsn_source IS
-- Output stream sosi control using RSN
nof_clk_per_sync : IN STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0) := TO_UVEC(g_nof_clk_per_sync, c_word_w);
rs_sosi : OUT t_dp_sosi; -- output stream using RSN and g_block_size, g_nof_clk_per_sync
rs_sosi : OUT t_dp_sosi; -- output stream using RSN and g_rs_block_size, g_nof_clk_per_sync
rs_restart : OUT STD_LOGIC; -- = rs_sosi.sync for first sync after bs_sosi.valid went high
rs_new_interval : OUT STD_LOGIC -- = active during first rs_sosi.sync interval
);
......@@ -78,8 +80,9 @@ END dp_rsn_source;
ARCHITECTURE rtl OF dp_rsn_source IS
CONSTANT c_block_size_cnt_w : NATURAL := ceil_log2(g_block_size);
CONSTANT c_rsn_product_w : NATURAL := g_bsn_w + c_block_size_cnt_w;
CONSTANT c_bs_block_size_cnt_w : NATURAL := ceil_log2(g_bs_block_size) + 1; -- +1 because value 2**n requires n + 1 bits
CONSTANT c_rs_block_size_cnt_w : NATURAL := ceil_log2(g_rs_block_size) + 1; -- +1 because value 2**n requires n + 1 bits
CONSTANT c_rsn_product_w : NATURAL := g_bsn_w + c_bs_block_size_cnt_w;
TYPE t_state_enum IS (s_off, s_on_sop, s_on, s_on_eop);
......@@ -91,11 +94,11 @@ ARCHITECTURE rtl OF dp_rsn_source IS
SIGNAL nxt_sync : STD_LOGIC;
SIGNAL sync : STD_LOGIC;
SIGNAL nxt_sync_size_cnt : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
SIGNAL sync_size_cnt : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
SIGNAL nxt_sync_size_cnt : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
SIGNAL block_size_cnt : STD_LOGIC_VECTOR(c_block_size_cnt_w-1 DOWNTO 0);
SIGNAL nxt_block_size_cnt : STD_LOGIC_VECTOR(c_block_size_cnt_w-1 DOWNTO 0);
SIGNAL rs_block_size_cnt : STD_LOGIC_VECTOR(c_rs_block_size_cnt_w-1 DOWNTO 0);
SIGNAL nxt_rs_block_size_cnt : STD_LOGIC_VECTOR(c_rs_block_size_cnt_w-1 DOWNTO 0);
SIGNAL i_rs_sosi : t_dp_sosi := c_dp_sosi_init;
SIGNAL nxt_rs_sosi : t_dp_sosi;
......@@ -111,11 +114,11 @@ BEGIN
rs_restart <= i_rs_restart;
rs_new_interval <= i_rs_new_interval;
rsn <= MULT_UVEC(bs_sosi.bsn(g_bsn_w-1 DOWNTO 0), TO_UVEC(g_block_size, c_block_size_cnt_w));
rsn <= MULT_UVEC(bs_sosi.bsn(g_bsn_w-1 DOWNTO 0), TO_UVEC(g_bs_block_size, c_bs_block_size_cnt_w));
p_state : PROCESS(bs_sosi, sync, sync_size_cnt, nof_clk_per_sync,
p_state : PROCESS(bs_sosi, nxt_sync, sync, sync_size_cnt, nof_clk_per_sync,
state, prev_state,
i_rs_sosi, block_size_cnt, rsn)
i_rs_sosi, rs_block_size_cnt, rsn)
BEGIN
-- Maintain sync_size_cnt for nof_clk_per_sync
-- . nof_clk_per_sync is the number of clk per sync interval and the
......@@ -131,6 +134,9 @@ BEGIN
nxt_sync <= '1'; -- will set rs_sosi.sync on next rs_sosi.sop
nxt_sync_size_cnt <= (OTHERS=>'0');
END IF;
IF i_rs_sosi.sync = '1' THEN
nxt_sync <= '0'; -- clear when sync has been applied in rs_sosi
END IF;
-- State machine for rs_sosi
nxt_state <= state;
......@@ -139,7 +145,7 @@ BEGIN
nxt_rs_sosi.valid <= '0';
nxt_rs_sosi.sop <= '0';
nxt_rs_sosi.eop <= '0';
nxt_block_size_cnt <= block_size_cnt;
nxt_rs_block_size_cnt <= rs_block_size_cnt;
CASE state IS
WHEN s_off =>
......@@ -147,7 +153,7 @@ BEGIN
nxt_rs_sosi.bsn <= RESIZE_DP_BSN(rsn); -- RSN fits in g_bsn_w
nxt_sync <= '0';
nxt_sync_size_cnt <= (OTHERS=>'0');
nxt_block_size_cnt <= (OTHERS=>'0');
nxt_rs_block_size_cnt <= (OTHERS=>'0');
IF bs_sosi.sync = '1' THEN
nxt_rs_sosi.sync <= '1';
nxt_rs_sosi.sop <= '1';
......@@ -156,31 +162,30 @@ BEGIN
END IF;
-- using separate states s_on_sop and s_on_eop instead of only
-- s_on state and block_size_cnt, cause that g_block_size must be
-- s_on state and rs_block_size_cnt, cause that g_rs_block_size must be
-- >= 3, but that is fine.
WHEN s_on_sop =>
-- Start of block
nxt_rs_sosi.sop <= '1';
nxt_rs_sosi.valid <= '1';
nxt_state <= s_on;
-- block_size_cnt = 0 at rs_sosi.sop
nxt_block_size_cnt <= (OTHERS=>'0');
-- rs_block_size_cnt = 0 at rs_sosi.sop
nxt_rs_block_size_cnt <= (OTHERS=>'0');
-- after first block, increment bsn per block
IF prev_state = s_on_eop THEN
nxt_rs_sosi.bsn <= INCR_DP_BSN(i_rs_sosi.bsn, g_block_size, g_bsn_w); -- RSN
nxt_rs_sosi.bsn <= INCR_DP_BSN(i_rs_sosi.bsn, g_rs_block_size, g_bsn_w); -- RSN
END IF;
-- check for pending sync
IF sync = '1' THEN
IF nxt_sync = '1' THEN
nxt_rs_sosi.sync <= '1';
nxt_sync <= '0';
END IF;
WHEN s_on =>
-- During block
nxt_rs_sosi.valid <= '1';
-- block_size_cnt increments to determine end of block
nxt_block_size_cnt <= INCR_UVEC(block_size_cnt, 1);
IF UNSIGNED(block_size_cnt) >= g_block_size - 3 THEN
-- rs_block_size_cnt increments to determine end of block
nxt_rs_block_size_cnt <= INCR_UVEC(rs_block_size_cnt, 1);
IF UNSIGNED(rs_block_size_cnt) >= g_rs_block_size - 3 THEN
nxt_state <= s_on_eop;
END IF;
......@@ -189,7 +194,8 @@ BEGIN
nxt_rs_sosi.eop <= '1';
nxt_rs_sosi.valid <= '1';
nxt_state <= s_on_sop;
-- block_size_cnt is dont care at at rs_sosi.eop
nxt_rs_block_size_cnt <= INCR_UVEC(rs_block_size_cnt, 1);
-- rs_block_size_cnt is dont care at at rs_sosi.eop
-- accept dp_off after eop, to avoid fractional blocks
IF bs_sosi.valid = '0' THEN
nxt_state <= s_off;
......@@ -216,7 +222,7 @@ BEGIN
i_rs_sosi <= c_dp_sosi_rst;
sync_size_cnt <= (OTHERS=>'0');
sync <= '0';
block_size_cnt <= (OTHERS=>'0');
rs_block_size_cnt <= (OTHERS=>'0');
i_rs_restart <= '0';
reg_rs_new_interval <= '0';
ELSIF rising_edge(clk) THEN
......@@ -225,7 +231,7 @@ BEGIN
i_rs_sosi <= nxt_rs_sosi;
sync_size_cnt <= nxt_sync_size_cnt;
sync <= nxt_sync;
block_size_cnt <= nxt_block_size_cnt;
rs_block_size_cnt <= nxt_rs_block_size_cnt;
i_rs_restart <= nxt_rs_restart;
reg_rs_new_interval <= i_rs_new_interval;
END IF;
......
-------------------------------------------------------------------------------
--
-- Copyright 2022
-- Copyright 2023
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
......@@ -24,7 +24,10 @@
-- Use dp_bsn_source_v2 to create bs_sosi and extending it with dut =
-- dp_rsn_source to create and verify rs_sosi.
-- Remark:
-- * This tb is made based on tb_dp_bsn_source_v2.
-- * This tb is made based on tb_dp_bsn_source_v2. Difference is that bs_sosi
-- has block grid that starts at t_epoch = 0, whereas rs_sosi has block
-- grid that can start at any bs_sosi.sync. Therefore p_exp_grid_rs is
-- needed
LIBRARY IEEE, common_lib, dp_lib;
USE IEEE.STD_LOGIC_1164.ALL;
......@@ -36,9 +39,9 @@ USE dp_lib.tb_dp_pkg.ALL;
ENTITY tb_dp_rsn_source IS
GENERIC (
g_pps_interval : NATURAL := 16; --101;
g_bs_block_size : NATURAL := 5; --23
g_rs_block_size : NATURAL := 5 --23
g_pps_interval : NATURAL := 40; --101;
g_bs_block_size : NATURAL := 10; --23, input BSN block size <= g_pps_interval
g_rs_block_size : NATURAL := 10 --23, output RSN block size <= g_pps_interval
);
END tb_dp_rsn_source;
......@@ -62,7 +65,7 @@ ARCHITECTURE tb OF tb_dp_rsn_source IS
-- choose c_nof_pps and c_nof_repeat > c_min_nof_pps_interval, because the
-- fractional sync pattern will repeat every c_min_nof_pps_interval number
-- of g_pps_intervals.
CONSTANT c_factor : NATURAL := 3;
CONSTANT c_factor : NATURAL := 5;
CONSTANT c_nof_pps : NATURAL := c_min_nof_pps_interval * c_factor;
CONSTANT c_nof_repeat : NATURAL := c_min_nof_pps_interval * c_factor;
......@@ -71,7 +74,9 @@ ARCHITECTURE tb OF tb_dp_rsn_source IS
CONSTANT c_bsn_time_offset_w : NATURAL := ceil_log2(g_bs_block_size);
-- Minimum latency between sync and PPS, due to logic in DUT
CONSTANT c_dut_latency : NATURAL := 3;
CONSTANT c_dp_bsn_latency : NATURAL := 3;
CONSTANT c_dp_rsn_latency : NATURAL := 1;
CONSTANT c_dut_latency : NATURAL := c_dp_bsn_latency + c_dp_rsn_latency;
-- The state name tells what kind of test is being done
TYPE t_state_enum IS (
......@@ -90,45 +95,51 @@ ARCHITECTURE tb OF tb_dp_rsn_source IS
eop : STD_LOGIC; -- end of block
END RECORD;
CONSTANT c_time_grid_rst : t_time_grid := ('0', 0, 0, '0', '0', '0');
CONSTANT c_time_grid_rst : t_time_grid := ('0', 0, 0, '0', '0', '0');
-- Reference grid
SIGNAL ref_grid : t_time_grid := c_time_grid_rst;
SIGNAL ssn_eop : STD_LOGIC := '0';
SIGNAL hold_pps : STD_LOGIC := '0';
SIGNAL nxt_hold_pps : STD_LOGIC := '0';
SIGNAL ref_grid_bs : t_time_grid := c_time_grid_rst;
SIGNAL ssn_eop : STD_LOGIC := '0';
SIGNAL hold_pps : STD_LOGIC := '0';
SIGNAL nxt_hold_pps : STD_LOGIC := '0';
-- Tb
SIGNAL tb_end : STD_LOGIC := '0';
SIGNAL rst : STD_LOGIC := '1';
SIGNAL clk : STD_LOGIC := '1';
SIGNAL tb_state : t_state_enum := s_disable;
SIGNAL tb_end : STD_LOGIC := '0';
SIGNAL rst : STD_LOGIC := '1';
SIGNAL clk : STD_LOGIC := '1';
SIGNAL tb_state : t_state_enum := s_disable;
-- BSN source
SIGNAL dp_on : STD_LOGIC := '0';
SIGNAL dp_on_pps : STD_LOGIC := '0';
SIGNAL dp_on_status : STD_LOGIC;
SIGNAL bs_restart : STD_LOGIC;
SIGNAL bs_new_interval : STD_LOGIC;
SIGNAL tb_new_interval : STD_LOGIC := '0';
SIGNAL bsn_init : STD_LOGIC_VECTOR(c_bsn_w-1 DOWNTO 0) := (OTHERS=>'0');
SIGNAL bsn_time_offset : STD_LOGIC_VECTOR(c_bsn_time_offset_w-1 DOWNTO 0) := (OTHERS=>'0');
SIGNAL bs_sosi : t_dp_sosi;
SIGNAL dp_on : STD_LOGIC := '0';
SIGNAL dp_on_pps : STD_LOGIC := '0';
SIGNAL dp_on_status : STD_LOGIC;
SIGNAL bs_restart : STD_LOGIC;
SIGNAL bs_new_interval : STD_LOGIC;
SIGNAL tb_new_interval : STD_LOGIC := '0';
SIGNAL bsn_init : STD_LOGIC_VECTOR(c_bsn_w-1 DOWNTO 0) := (OTHERS=>'0');
SIGNAL bsn_time_offset : STD_LOGIC_VECTOR(c_bsn_time_offset_w-1 DOWNTO 0) := (OTHERS=>'0');
SIGNAL bs_sosi : t_dp_sosi;
SIGNAL exp_grid_bs : t_time_grid; -- to check with bs_sosi.bsn, sync, sop, eop
-- RSN source
SIGNAL rs_restart : STD_LOGIC;
SIGNAL rs_new_interval : STD_LOGIC;
SIGNAL rs_sosi : t_dp_sosi;
SIGNAL rs_restart : STD_LOGIC;
SIGNAL rs_new_interval : STD_LOGIC;
SIGNAL rs_sosi : t_dp_sosi;
SIGNAL exp_grid_rs : t_time_grid; -- to verify rs_sosi.bsn, sync, sop, eop
-- Verify
SIGNAL exp_grid : t_time_grid;
SIGNAL unexpected_bs_sync : STD_LOGIC;
SIGNAL exp_rs_start_bsn : NATURAL;
SIGNAL exp_rs_sync_cnt : NATURAL;
SIGNAL exp_rs_block_cnt : NATURAL;
SIGNAL hold_exp_rs_sync : STD_LOGIC := '0';
SIGNAL unexpected_rs_sync : STD_LOGIC;
SIGNAL sl0 : STD_LOGIC := '0';
SIGNAL verify_en : STD_LOGIC := '0';
SIGNAL verify_sync : STD_LOGIC := '0';
SIGNAL hold_bs_sop : STD_LOGIC;
SIGNAL prev_bs_valid : STD_LOGIC;
SIGNAL bs_starts_cnt : NATURAL := 0;
SIGNAL hold_rs_sop : STD_LOGIC := '0';
SIGNAL prev_rs_valid : STD_LOGIC;
SIGNAL rs_starts_cnt : NATURAL := 0;
SIGNAL dbg_c_nof_pps : NATURAL := c_nof_pps;
SIGNAL dbg_c_nof_repeat : NATURAL := c_nof_repeat;
......@@ -143,32 +154,32 @@ BEGIN
clk <= (NOT clk) OR tb_end AFTER c_clk_period/2;
-----------------------------------------------------------------------------
-- Generate reference time grid
-- Generate reference time grid for bs_sosi
-----------------------------------------------------------------------------
proc_common_gen_pulse(1, g_pps_interval, '1', sl0, clk, ref_grid.pps);
proc_common_gen_pulse(1, g_bs_block_size, '1', sl0, clk, ref_grid.sop);
ref_grid.eop <= ref_grid.sop'DELAYED((g_bs_block_size - 1) * c_clk_period);
ssn_eop <= ref_grid.pps'DELAYED((g_pps_interval - 1) * c_clk_period);
ref_grid.ssn <= ref_grid.ssn + 1 WHEN rising_edge(clk) AND ssn_eop = '1';
ref_grid.bsn <= ref_grid.bsn + 1 WHEN rising_edge(clk) AND ref_grid.eop = '1';
proc_common_gen_pulse(1, g_pps_interval, '1', sl0, clk, ref_grid_bs.pps);
proc_common_gen_pulse(1, g_bs_block_size, '1', sl0, clk, ref_grid_bs.sop);
ref_grid_bs.eop <= ref_grid_bs.sop'DELAYED((g_bs_block_size - 1) * c_clk_period);
ssn_eop <= ref_grid_bs.pps'DELAYED((g_pps_interval - 1) * c_clk_period);
ref_grid_bs.ssn <= ref_grid_bs.ssn + 1 WHEN rising_edge(clk) AND ssn_eop = '1';
ref_grid_bs.bsn <= ref_grid_bs.bsn + 1 WHEN rising_edge(clk) AND ref_grid_bs.eop = '1';
-- Issue sync at start of block
p_ref_grid_sync : PROCESS(ref_grid, hold_pps)
p_ref_grid_bs_sync : PROCESS(ref_grid_bs, hold_pps)
BEGIN
ref_grid.sync <= '0';
ref_grid_bs.sync <= '0';
nxt_hold_pps <= hold_pps;
IF ref_grid.pps = '1' THEN
IF ref_grid.sop = '1' THEN
ref_grid.sync <= '1'; -- immediately issue sync
IF ref_grid_bs.pps = '1' THEN
IF ref_grid_bs.sop = '1' THEN
ref_grid_bs.sync <= '1'; -- immediately issue sync
ELSE
nxt_hold_pps <= '1'; -- wait until next block
END IF;
END IF;
IF hold_pps = '1' THEN
IF ref_grid.sop = '1' THEN
ref_grid.sync <= '1'; -- issue pending sync
IF ref_grid_bs.sop = '1' THEN
ref_grid_bs.sync <= '1'; -- issue pending sync
nxt_hold_pps <= '0';
END IF;
END IF;
......@@ -176,7 +187,71 @@ BEGIN
hold_pps <= nxt_hold_pps WHEN rising_edge(clk);
exp_grid <= ref_grid'DELAYED(c_dut_latency * c_clk_period);
exp_grid_bs <= ref_grid_bs'DELAYED(c_dp_bsn_latency * c_clk_period);
-----------------------------------------------------------------------------
-- Generate reference time grid for rs_sosi
-----------------------------------------------------------------------------
-- using clk process accounts for c_dp_rsn_latency = 1
p_exp_grid_rs : PROCESS(clk)
VARIABLE v_sop : STD_LOGIC;
BEGIN
IF rising_edge(clk) THEN
v_sop := '0';
-- same pps, ssn
exp_grid_rs.pps <= exp_grid_bs.pps;
exp_grid_rs.ssn <= exp_grid_bs.ssn;
exp_grid_rs.sync <= '0';
exp_grid_rs.sop <= '0';
exp_grid_rs.eop <= '0';
-- bs blocks start at t_epoch = 0, but rs sync and blocks start at
-- bs_restart, so not necessarily at t_epoch = 0
IF bs_restart = '1' THEN
exp_rs_sync_cnt <= 0;
exp_rs_block_cnt <= 0;
exp_grid_rs.sync <= '1';
exp_grid_rs.sop <= '1';
exp_grid_rs.bsn <= exp_grid_bs.bsn * g_bs_block_size;
exp_rs_start_bsn <= exp_grid_bs.bsn * g_bs_block_size;
hold_exp_rs_sync <= '0';
ELSE
-- expected rs_sosi sop, eop
IF exp_rs_block_cnt < g_rs_block_size-2 THEN
exp_rs_block_cnt <= exp_rs_block_cnt + 1;
ELSIF exp_rs_block_cnt = g_rs_block_size-2 THEN
exp_rs_block_cnt <= exp_rs_block_cnt + 1;
exp_grid_rs.eop <= '1';
ELSIF exp_rs_block_cnt = g_rs_block_size-1 THEN
v_sop := '1';
exp_rs_block_cnt <= 0;
exp_grid_rs.sop <= '1';
exp_grid_rs.bsn <= exp_grid_rs.bsn + g_rs_block_size;
-- check for pending rs_sosi sync
IF hold_exp_rs_sync = '1' THEN
exp_grid_rs.sync <= '1';
hold_exp_rs_sync <= '0';
END IF;
END IF;
-- expected rs_sosi sync
IF exp_rs_sync_cnt < g_pps_interval-1 THEN
exp_rs_sync_cnt <= exp_rs_sync_cnt + 1;
ELSE
exp_rs_sync_cnt <= 0;
IF v_sop = '1' THEN
exp_grid_rs.sync <= '1'; -- issue sync immediately at this exp_grid_rs.sop
ELSE
hold_exp_rs_sync <= '1'; -- pend sync until next exp_grid_rs.sop
END IF;
END IF;
END IF;
END IF;
END PROCESS;
-----------------------------------------------------------------------------
-- Stimuli
......@@ -199,7 +274,9 @@ BEGIN
tb_state <= s_disable;
dp_on <= '0';
dp_on_pps <= '0';
proc_common_wait_some_cycles(clk, 10);
-- Wait sufficient until bs_sosi is idle again
proc_common_wait_some_cycles(clk, 5*g_pps_interval);
-- Start synchronously by making dp_on and dp_on_pps high
verify_en <= '1'; -- verify automatically in test bench
......@@ -207,17 +284,17 @@ BEGIN
FOR I IN 0 TO c_nof_repeat-1 LOOP
-- Wait some variable time between tests, to enforce testing different
-- bsn_time_offset values
proc_common_wait_some_cycles(clk, 20);
proc_common_wait_some_cycles(clk, 5*g_pps_interval);
proc_common_wait_some_cycles(clk, I*g_pps_interval);
-- Wait until in the beginning of PPS interval
proc_common_wait_until_hi_lo(clk, ref_grid.pps);
proc_common_wait_some_cycles(clk, c_dut_latency);
proc_common_wait_until_hi_lo(clk, ref_grid_bs.pps);
proc_common_wait_some_cycles(clk, c_dp_bsn_latency);
-- Determine bsn_init and bsn_time_offset for BSN source start
-- . bsn_init = BSN at sync
-- . bsn_time_offset = number of clk that sync occurs after PPS
v_ssn := ref_grid.ssn + 1; -- +1 to prepare start in next PPS interval
v_ssn := ref_grid_bs.ssn + 1; -- +1 to prepare start in next PPS interval
v_bsn_init := ceil_div(v_SSN * g_pps_interval, g_bs_block_size); -- Equation 3.6 in [1]
v_bsn_time_offset := v_bsn_init * g_bs_block_size - v_SSN * g_pps_interval; -- Equation 3.7 in [1]
bsn_init <= TO_UVEC(v_bsn_init, c_bsn_w); --
......@@ -233,7 +310,7 @@ BEGIN
END LOOP;
proc_common_wait_some_cycles(clk, 10);
ASSERT bs_starts_cnt = 1 + c_nof_repeat REPORT "Wrong number of BSN source starts." SEVERITY ERROR;
ASSERT rs_starts_cnt = 1 + c_nof_repeat REPORT "Wrong number of BSN source starts." SEVERITY ERROR;
tb_end <= '1';
WAIT;
......@@ -242,79 +319,80 @@ BEGIN
-----------------------------------------------------------------------------
-- Verification
-- . Some aspects of bs_sosi are verified multiple times in different ways,
-- . Some aspects of rs_sosi are verified multiple times in different ways,
-- this overlap is fine, because the tb and DUT are rather complicated, so
-- using different approaches also helpt to verify the tb itself.
-----------------------------------------------------------------------------
verify_sync <= verify_en AND bs_sosi.valid;
verify_sync <= verify_en AND rs_sosi.valid;
proc_dp_verify_sop_and_eop(clk, bs_sosi.valid, bs_sosi.sop, bs_sosi.eop, hold_bs_sop); -- Verify that sop and eop come in pairs
--proc_dp_verify_sync(clk, verify_sync, bs_sosi.sync, exp_grid.sop, exp_grid.sync); -- Verify sync at sop and at expected_sync
proc_dp_verify_sop_and_eop(clk, rs_sosi.valid, rs_sosi.sop, rs_sosi.eop, hold_rs_sop); -- Verify that sop and eop come in pairs
--proc_dp_verify_sync(clk, verify_sync, rs_sosi.sync, exp_grid_rs.sop, exp_grid_rs.sync); -- Verify sync at sop and at expected_sync
-- Verify sync at sop and at expected_sync
proc_dp_verify_sync(0, -- start bsn of PPS grid and BSN grid is 0, see [1]
proc_dp_verify_sync(exp_rs_start_bsn,
g_pps_interval,
g_bs_block_size,
g_rs_block_size,
TRUE, -- use BSN as RSN
clk,
verify_en,
bs_sosi.sync,
bs_sosi.sop,
bs_sosi.bsn,
rs_sosi.sync,
rs_sosi.sop,
rs_sosi.bsn,
dbg_nof_blk,
dbg_accumulate,
dbg_expected_bsn);
-- Verify bs_sosi by comparing with exp_grid, this again verifies bs_sosi.sync, sop and bsn
p_verify_bs_sosi_grid : PROCESS(clk)
-- Verify rs_sosi by comparing with exp_grid_rs, this again verifies rs_sosi.sync, sop and bsn
p_verify_rs_sosi_grid : PROCESS(clk)
BEGIN
IF rising_edge(clk) THEN
unexpected_bs_sync <= '0';
IF verify_en = '1' AND bs_sosi.valid = '1' THEN
ASSERT TO_UINT(bs_sosi.bsn) = exp_grid.bsn REPORT "Wrong bs_sosi.bsn /= exp_grid.bsn" SEVERITY ERROR;
ASSERT bs_sosi.sync = exp_grid.sync REPORT "Wrong bs_sosi.sync /= exp_grid.sync" SEVERITY ERROR;
ASSERT bs_sosi.sop = exp_grid.sop REPORT "Wrong bs_sosi.sop /= exp_grid.sop" SEVERITY ERROR;
ASSERT bs_sosi.eop = exp_grid.eop REPORT "Wrong bs_sosi.eop /= exp_grid.eop" SEVERITY ERROR;
unexpected_rs_sync <= '0';
IF verify_en = '1' AND rs_sosi.valid = '1' THEN
ASSERT TO_UINT(rs_sosi.bsn) = exp_grid_rs.bsn REPORT "Wrong rs_sosi.bsn /= exp_grid_rs.bsn" SEVERITY ERROR;
ASSERT rs_sosi.sync = exp_grid_rs.sync REPORT "Wrong rs_sosi.sync /= exp_grid_rs.sync" SEVERITY ERROR;
ASSERT rs_sosi.sop = exp_grid_rs.sop REPORT "Wrong rs_sosi.sop /= exp_grid_rs.sop" SEVERITY ERROR;
ASSERT rs_sosi.eop = exp_grid_rs.eop REPORT "Wrong rs_sosi.eop /= exp_grid_rs.eop" SEVERITY ERROR;
-- Mark error in Wave window
IF bs_sosi.sync = '1' AND bs_sosi.sync /= exp_grid.sync THEN
unexpected_bs_sync <= '1';
IF rs_sosi.sync = '1' AND rs_sosi.sync /= exp_grid_rs.sync THEN
unexpected_rs_sync <= '1';
END IF;
END IF;
END IF;
END PROCESS;
-- Verify that bs_sosi.valid = '1' did happen after dp_on by verifying bs_start
prev_bs_valid <= bs_sosi.valid WHEN rising_edge(clk);
bs_starts_cnt <= bs_starts_cnt + 1 WHEN rising_edge(clk) AND bs_sosi.valid = '1' AND prev_bs_valid = '0';
-- Verify that rs_sosi.valid = '1' did happen after dp_on by verifying rs_start
prev_rs_valid <= rs_sosi.valid WHEN rising_edge(clk);
rs_starts_cnt <= rs_starts_cnt + 1 WHEN rising_edge(clk) AND rs_sosi.valid = '1' AND prev_rs_valid = '0';
p_verify_bs_restart : PROCESS(clk)
p_verify_rs_restart : PROCESS(clk)
BEGIN
IF rising_edge(clk) THEN
IF bs_restart = '1' THEN
ASSERT bs_sosi.sync = '1' REPORT "Unexpected bs_start while bs_sosi.sync /= 1" SEVERITY ERROR;
ASSERT prev_bs_valid = '0' REPORT "Unexpected bs_start while prev_bs_valid /= 0" SEVERITY ERROR;
IF rs_restart = '1' THEN
ASSERT rs_sosi.sync = '1' REPORT "Unexpected rs_start while rs_sosi.sync /= 1" SEVERITY ERROR;
ASSERT prev_rs_valid = '0' REPORT "Unexpected rs_start while prev_rs_valid /= 0" SEVERITY ERROR;
END IF;
END IF;
END PROCESS;
p_verify_bs_new_interval : PROCESS(clk)
p_verify_rs_new_interval : PROCESS(clk)
BEGIN
IF rising_edge(clk) THEN
IF bs_restart = '1' THEN
ASSERT bs_new_interval = '1' REPORT "Wrong begin of bs_new_interval" SEVERITY ERROR;
IF rs_restart = '1' THEN
ASSERT rs_new_interval = '1' REPORT "Wrong begin of rs_new_interval" SEVERITY ERROR;
tb_new_interval <= '1';
ELSIF bs_sosi.sync = '1' THEN
ASSERT bs_new_interval = '0' REPORT "Wrong end of bs_new_interval" SEVERITY ERROR;
ELSIF rs_sosi.sync = '1' THEN
ASSERT rs_new_interval = '0' REPORT "Wrong end of rs_new_interval" SEVERITY ERROR;
tb_new_interval <= '0';
ELSIF tb_new_interval = '1' THEN
ASSERT bs_new_interval = '1' REPORT "Wrong level during bs_new_interval" SEVERITY ERROR;
ASSERT rs_new_interval = '1' REPORT "Wrong level during rs_new_interval" SEVERITY ERROR;
ELSE
ASSERT bs_new_interval = '0' REPORT "Unexpected bs_new_interval" SEVERITY ERROR;
ASSERT rs_new_interval = '0' REPORT "Unexpected rs_new_interval" SEVERITY ERROR;
END IF;
END IF;
END PROCESS;
-----------------------------------------------------------------------------
-- DUT: dp_bsn_source_v2
-- DUT: dp_bsn_source_v2 --> dp_rsn_source
-----------------------------------------------------------------------------
u_bsn : ENTITY work.dp_bsn_source_v2
......@@ -327,7 +405,7 @@ BEGIN
PORT MAP (
rst => rst,
clk => clk,
pps => ref_grid.pps,
pps => ref_grid_bs.pps,
-- MM control
dp_on => dp_on,
dp_on_pps => dp_on_pps,
......@@ -345,7 +423,8 @@ BEGIN
u_rsn : ENTITY work.dp_rsn_source
GENERIC MAP (
g_block_size => g_rs_block_size,
g_bs_block_size => g_bs_block_size,
g_rs_block_size => g_rs_block_size,
g_nof_clk_per_sync => g_pps_interval,
g_bsn_w => c_bsn_w
)
......
......@@ -52,6 +52,7 @@ BEGIN
-----------------------------------------------------------------------------
u_12_3_3 : ENTITY work.tb_dp_rsn_source GENERIC MAP (12, 3, 3); -- smallest block size
u_16_8_4 : ENTITY work.tb_dp_rsn_source GENERIC MAP (16, 8, 4); -- integer number of blocks per g_pps_interval
u_25_5 : ENTITY work.tb_dp_rsn_source GENERIC MAP (25, 5, 5);
u_29_17_23 : ENTITY work.tb_dp_rsn_source GENERIC MAP (29, 17, 23); -- fractional number of blocks per g_pps_interval
u_9_4_5 : ENTITY work.tb_dp_rsn_source GENERIC MAP (9, 4, 5); -- 2 g_bs_block_size < g_pps_interval < 2 g_rs_block_size
......@@ -60,8 +61,7 @@ BEGIN
u_9_9_5 : ENTITY work.tb_dp_rsn_source GENERIC MAP (9, 9, 5); -- 1 g_bs_block_size/g_pps_interval
-----------------------------------------------------------------------------
-- Same tests as with tb_dp_bsn_source_v2
-- . g_rs_block_size /= g_bs_block_size
-- Same tests as with tb_dp_bsn_source_v2 with g_rs_block_size = g_bs_block_size
-----------------------------------------------------------------------------
-- test integer case
u_20_10 : ENTITY work.tb_dp_rsn_source GENERIC MAP (20, 10, 10); -- 20 // 10 = 2, 20 MOD 10 = 0, 20/10 = 2 block/sync
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment