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
1 merge request!317Resolve L2SDP-7
Pipeline #46461 passed
...@@ -308,6 +308,7 @@ test_bench_files = ...@@ -308,6 +308,7 @@ test_bench_files =
tb/vhdl/tb_tb_dp_bsn_align.vhd tb/vhdl/tb_tb_dp_bsn_align.vhd
tb/vhdl/tb_tb_dp_bsn_align_v2.vhd tb/vhdl/tb_tb_dp_bsn_align_v2.vhd
tb/vhdl/tb_tb_mmp_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_source_v2.vhd
tb/vhdl/tb_tb_dp_bsn_sync_scheduler.vhd tb/vhdl/tb_tb_dp_bsn_sync_scheduler.vhd
tb/vhdl/tb_tb_dp_concat.vhd tb/vhdl/tb_tb_dp_concat.vhd
...@@ -382,6 +383,7 @@ regression_test_vhdl = ...@@ -382,6 +383,7 @@ regression_test_vhdl =
tb/vhdl/tb_tb_dp_block_validate_channel.vhd tb/vhdl/tb_tb_dp_block_validate_channel.vhd
tb/vhdl/tb_tb_dp_bsn_align_v2.vhd tb/vhdl/tb_tb_dp_bsn_align_v2.vhd
tb/vhdl/tb_tb_mmp_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_source_v2.vhd
tb/vhdl/tb_tb_dp_bsn_sync_scheduler.vhd tb/vhdl/tb_tb_dp_bsn_sync_scheduler.vhd
tb/vhdl/tb_tb_dp_concat.vhd tb/vhdl/tb_tb_dp_concat.vhd
......
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- --
-- Copyright 2022 -- Copyright 2023
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> -- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands -- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
-- --
...@@ -32,11 +32,12 @@ ...@@ -32,11 +32,12 @@
-- The bs_sosi can stop and restart. It (re)starts with bs_sosi.sync and -- 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.sop when bs_sosi.valid becomes '1' and it stops when
-- bs_sosi.valid becomes '0' immediately after a bs_sosi.eop. -- 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 -- 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 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' -- The rs_sosi starts when the bs_sosi starts, so when bs_sosi.sync = '1'
-- and bs_sosi.valid becomes '1'. -- and bs_sosi.valid becomes '1'.
-- The rs_sosi ends after the rs_sosi.eop, when the bs_sosi ends. There -- 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; ...@@ -56,7 +57,8 @@ USE work.dp_stream_pkg.ALL;
ENTITY dp_rsn_source IS ENTITY dp_rsn_source IS
GENERIC ( 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_nof_clk_per_sync : NATURAL := 200 * 10**6;
g_bsn_w : NATURAL := 64 g_bsn_w : NATURAL := 64
); );
...@@ -69,7 +71,7 @@ ENTITY dp_rsn_source IS ...@@ -69,7 +71,7 @@ ENTITY dp_rsn_source IS
-- Output stream sosi control using RSN -- 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); 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_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 rs_new_interval : OUT STD_LOGIC -- = active during first rs_sosi.sync interval
); );
...@@ -78,8 +80,9 @@ END dp_rsn_source; ...@@ -78,8 +80,9 @@ END dp_rsn_source;
ARCHITECTURE rtl OF dp_rsn_source IS ARCHITECTURE rtl OF dp_rsn_source IS
CONSTANT c_block_size_cnt_w : NATURAL := ceil_log2(g_block_size); 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_rsn_product_w : NATURAL := g_bsn_w + c_block_size_cnt_w; 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); 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 ...@@ -91,11 +94,11 @@ ARCHITECTURE rtl OF dp_rsn_source IS
SIGNAL nxt_sync : STD_LOGIC; SIGNAL nxt_sync : STD_LOGIC;
SIGNAL 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 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 rs_block_size_cnt : STD_LOGIC_VECTOR(c_rs_block_size_cnt_w-1 DOWNTO 0);
SIGNAL nxt_block_size_cnt : STD_LOGIC_VECTOR(c_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 i_rs_sosi : t_dp_sosi := c_dp_sosi_init;
SIGNAL nxt_rs_sosi : t_dp_sosi; SIGNAL nxt_rs_sosi : t_dp_sosi;
...@@ -111,11 +114,11 @@ BEGIN ...@@ -111,11 +114,11 @@ BEGIN
rs_restart <= i_rs_restart; rs_restart <= i_rs_restart;
rs_new_interval <= i_rs_new_interval; 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, state, prev_state,
i_rs_sosi, block_size_cnt, rsn) i_rs_sosi, rs_block_size_cnt, rsn)
BEGIN BEGIN
-- Maintain sync_size_cnt for nof_clk_per_sync -- Maintain sync_size_cnt for nof_clk_per_sync
-- . nof_clk_per_sync is the number of clk per sync interval and the -- . nof_clk_per_sync is the number of clk per sync interval and the
...@@ -131,6 +134,9 @@ BEGIN ...@@ -131,6 +134,9 @@ BEGIN
nxt_sync <= '1'; -- will set rs_sosi.sync on next rs_sosi.sop nxt_sync <= '1'; -- will set rs_sosi.sync on next rs_sosi.sop
nxt_sync_size_cnt <= (OTHERS=>'0'); nxt_sync_size_cnt <= (OTHERS=>'0');
END IF; 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 -- State machine for rs_sosi
nxt_state <= state; nxt_state <= state;
...@@ -139,7 +145,7 @@ BEGIN ...@@ -139,7 +145,7 @@ BEGIN
nxt_rs_sosi.valid <= '0'; nxt_rs_sosi.valid <= '0';
nxt_rs_sosi.sop <= '0'; nxt_rs_sosi.sop <= '0';
nxt_rs_sosi.eop <= '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 CASE state IS
WHEN s_off => WHEN s_off =>
...@@ -147,7 +153,7 @@ BEGIN ...@@ -147,7 +153,7 @@ BEGIN
nxt_rs_sosi.bsn <= RESIZE_DP_BSN(rsn); -- RSN fits in g_bsn_w nxt_rs_sosi.bsn <= RESIZE_DP_BSN(rsn); -- RSN fits in g_bsn_w
nxt_sync <= '0'; nxt_sync <= '0';
nxt_sync_size_cnt <= (OTHERS=>'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 IF bs_sosi.sync = '1' THEN
nxt_rs_sosi.sync <= '1'; nxt_rs_sosi.sync <= '1';
nxt_rs_sosi.sop <= '1'; nxt_rs_sosi.sop <= '1';
...@@ -156,31 +162,30 @@ BEGIN ...@@ -156,31 +162,30 @@ BEGIN
END IF; END IF;
-- using separate states s_on_sop and s_on_eop instead of only -- 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. -- >= 3, but that is fine.
WHEN s_on_sop => WHEN s_on_sop =>
-- Start of block -- Start of block
nxt_rs_sosi.sop <= '1'; nxt_rs_sosi.sop <= '1';
nxt_rs_sosi.valid <= '1'; nxt_rs_sosi.valid <= '1';
nxt_state <= s_on; nxt_state <= s_on;
-- block_size_cnt = 0 at rs_sosi.sop -- rs_block_size_cnt = 0 at rs_sosi.sop
nxt_block_size_cnt <= (OTHERS=>'0'); nxt_rs_block_size_cnt <= (OTHERS=>'0');
-- after first block, increment bsn per block -- after first block, increment bsn per block
IF prev_state = s_on_eop THEN 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; END IF;
-- check for pending sync -- check for pending sync
IF sync = '1' THEN IF nxt_sync = '1' THEN
nxt_rs_sosi.sync <= '1'; nxt_rs_sosi.sync <= '1';
nxt_sync <= '0';
END IF; END IF;
WHEN s_on => WHEN s_on =>
-- During block -- During block
nxt_rs_sosi.valid <= '1'; nxt_rs_sosi.valid <= '1';
-- block_size_cnt increments to determine end of block -- rs_block_size_cnt increments to determine end of block
nxt_block_size_cnt <= INCR_UVEC(block_size_cnt, 1); nxt_rs_block_size_cnt <= INCR_UVEC(rs_block_size_cnt, 1);
IF UNSIGNED(block_size_cnt) >= g_block_size - 3 THEN IF UNSIGNED(rs_block_size_cnt) >= g_rs_block_size - 3 THEN
nxt_state <= s_on_eop; nxt_state <= s_on_eop;
END IF; END IF;
...@@ -189,7 +194,8 @@ BEGIN ...@@ -189,7 +194,8 @@ BEGIN
nxt_rs_sosi.eop <= '1'; nxt_rs_sosi.eop <= '1';
nxt_rs_sosi.valid <= '1'; nxt_rs_sosi.valid <= '1';
nxt_state <= s_on_sop; 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 -- accept dp_off after eop, to avoid fractional blocks
IF bs_sosi.valid = '0' THEN IF bs_sosi.valid = '0' THEN
nxt_state <= s_off; nxt_state <= s_off;
...@@ -216,7 +222,7 @@ BEGIN ...@@ -216,7 +222,7 @@ BEGIN
i_rs_sosi <= c_dp_sosi_rst; i_rs_sosi <= c_dp_sosi_rst;
sync_size_cnt <= (OTHERS=>'0'); sync_size_cnt <= (OTHERS=>'0');
sync <= '0'; sync <= '0';
block_size_cnt <= (OTHERS=>'0'); rs_block_size_cnt <= (OTHERS=>'0');
i_rs_restart <= '0'; i_rs_restart <= '0';
reg_rs_new_interval <= '0'; reg_rs_new_interval <= '0';
ELSIF rising_edge(clk) THEN ELSIF rising_edge(clk) THEN
...@@ -225,7 +231,7 @@ BEGIN ...@@ -225,7 +231,7 @@ BEGIN
i_rs_sosi <= nxt_rs_sosi; i_rs_sosi <= nxt_rs_sosi;
sync_size_cnt <= nxt_sync_size_cnt; sync_size_cnt <= nxt_sync_size_cnt;
sync <= nxt_sync; 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; i_rs_restart <= nxt_rs_restart;
reg_rs_new_interval <= i_rs_new_interval; reg_rs_new_interval <= i_rs_new_interval;
END IF; END IF;
......
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- --
-- Copyright 2022 -- Copyright 2023
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> -- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands -- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
-- --
...@@ -24,7 +24,10 @@ ...@@ -24,7 +24,10 @@
-- Use dp_bsn_source_v2 to create bs_sosi and extending it with dut = -- Use dp_bsn_source_v2 to create bs_sosi and extending it with dut =
-- dp_rsn_source to create and verify rs_sosi. -- dp_rsn_source to create and verify rs_sosi.
-- Remark: -- 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; LIBRARY IEEE, common_lib, dp_lib;
USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_1164.ALL;
...@@ -36,9 +39,9 @@ USE dp_lib.tb_dp_pkg.ALL; ...@@ -36,9 +39,9 @@ USE dp_lib.tb_dp_pkg.ALL;
ENTITY tb_dp_rsn_source IS ENTITY tb_dp_rsn_source IS
GENERIC ( GENERIC (
g_pps_interval : NATURAL := 16; --101; g_pps_interval : NATURAL := 40; --101;
g_bs_block_size : NATURAL := 5; --23 g_bs_block_size : NATURAL := 10; --23, input BSN block size <= g_pps_interval
g_rs_block_size : NATURAL := 5 --23 g_rs_block_size : NATURAL := 10 --23, output RSN block size <= g_pps_interval
); );
END tb_dp_rsn_source; END tb_dp_rsn_source;
...@@ -62,7 +65,7 @@ ARCHITECTURE tb OF tb_dp_rsn_source IS ...@@ -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 -- 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 -- fractional sync pattern will repeat every c_min_nof_pps_interval number
-- of g_pps_intervals. -- 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_pps : NATURAL := c_min_nof_pps_interval * c_factor;
CONSTANT c_nof_repeat : 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 ...@@ -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); CONSTANT c_bsn_time_offset_w : NATURAL := ceil_log2(g_bs_block_size);
-- Minimum latency between sync and PPS, due to logic in DUT -- 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 -- The state name tells what kind of test is being done
TYPE t_state_enum IS ( TYPE t_state_enum IS (
...@@ -93,7 +98,7 @@ ARCHITECTURE tb OF tb_dp_rsn_source IS ...@@ -93,7 +98,7 @@ ARCHITECTURE tb OF tb_dp_rsn_source IS
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 -- Reference grid
SIGNAL ref_grid : t_time_grid := c_time_grid_rst; SIGNAL ref_grid_bs : t_time_grid := c_time_grid_rst;
SIGNAL ssn_eop : STD_LOGIC := '0'; SIGNAL ssn_eop : STD_LOGIC := '0';
SIGNAL hold_pps : STD_LOGIC := '0'; SIGNAL hold_pps : STD_LOGIC := '0';
SIGNAL nxt_hold_pps : STD_LOGIC := '0'; SIGNAL nxt_hold_pps : STD_LOGIC := '0';
...@@ -114,21 +119,27 @@ ARCHITECTURE tb OF tb_dp_rsn_source IS ...@@ -114,21 +119,27 @@ ARCHITECTURE tb OF tb_dp_rsn_source IS
SIGNAL bsn_init : STD_LOGIC_VECTOR(c_bsn_w-1 DOWNTO 0) := (OTHERS=>'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 bsn_time_offset : STD_LOGIC_VECTOR(c_bsn_time_offset_w-1 DOWNTO 0) := (OTHERS=>'0');
SIGNAL bs_sosi : t_dp_sosi; SIGNAL bs_sosi : t_dp_sosi;
SIGNAL exp_grid_bs : t_time_grid; -- to check with bs_sosi.bsn, sync, sop, eop
-- RSN source -- RSN source
SIGNAL rs_restart : STD_LOGIC; SIGNAL rs_restart : STD_LOGIC;
SIGNAL rs_new_interval : STD_LOGIC; SIGNAL rs_new_interval : STD_LOGIC;
SIGNAL rs_sosi : t_dp_sosi; SIGNAL rs_sosi : t_dp_sosi;
SIGNAL exp_grid_rs : t_time_grid; -- to verify rs_sosi.bsn, sync, sop, eop
-- Verify -- Verify
SIGNAL exp_grid : t_time_grid; SIGNAL exp_rs_start_bsn : NATURAL;
SIGNAL unexpected_bs_sync : STD_LOGIC; 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 sl0 : STD_LOGIC := '0';
SIGNAL verify_en : STD_LOGIC := '0'; SIGNAL verify_en : STD_LOGIC := '0';
SIGNAL verify_sync : STD_LOGIC := '0'; SIGNAL verify_sync : STD_LOGIC := '0';
SIGNAL hold_bs_sop : STD_LOGIC; SIGNAL hold_rs_sop : STD_LOGIC := '0';
SIGNAL prev_bs_valid : STD_LOGIC; SIGNAL prev_rs_valid : STD_LOGIC;
SIGNAL bs_starts_cnt : NATURAL := 0; SIGNAL rs_starts_cnt : NATURAL := 0;
SIGNAL dbg_c_nof_pps : NATURAL := c_nof_pps; SIGNAL dbg_c_nof_pps : NATURAL := c_nof_pps;
SIGNAL dbg_c_nof_repeat : NATURAL := c_nof_repeat; SIGNAL dbg_c_nof_repeat : NATURAL := c_nof_repeat;
...@@ -143,32 +154,32 @@ BEGIN ...@@ -143,32 +154,32 @@ BEGIN
clk <= (NOT clk) OR tb_end AFTER c_clk_period/2; 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_pps_interval, '1', sl0, clk, ref_grid_bs.pps);
proc_common_gen_pulse(1, g_bs_block_size, '1', sl0, clk, ref_grid.sop); proc_common_gen_pulse(1, g_bs_block_size, '1', sl0, clk, ref_grid_bs.sop);
ref_grid.eop <= ref_grid.sop'DELAYED((g_bs_block_size - 1) * c_clk_period); ref_grid_bs.eop <= ref_grid_bs.sop'DELAYED((g_bs_block_size - 1) * c_clk_period);
ssn_eop <= ref_grid.pps'DELAYED((g_pps_interval - 1) * c_clk_period); ssn_eop <= ref_grid_bs.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_bs.ssn <= ref_grid_bs.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'; 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 -- 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 BEGIN
ref_grid.sync <= '0'; ref_grid_bs.sync <= '0';
nxt_hold_pps <= hold_pps; nxt_hold_pps <= hold_pps;
IF ref_grid.pps = '1' THEN IF ref_grid_bs.pps = '1' THEN
IF ref_grid.sop = '1' THEN IF ref_grid_bs.sop = '1' THEN
ref_grid.sync <= '1'; -- immediately issue sync ref_grid_bs.sync <= '1'; -- immediately issue sync
ELSE ELSE
nxt_hold_pps <= '1'; -- wait until next block nxt_hold_pps <= '1'; -- wait until next block
END IF; END IF;
END IF; END IF;
IF hold_pps = '1' THEN IF hold_pps = '1' THEN
IF ref_grid.sop = '1' THEN IF ref_grid_bs.sop = '1' THEN
ref_grid.sync <= '1'; -- issue pending sync ref_grid_bs.sync <= '1'; -- issue pending sync
nxt_hold_pps <= '0'; nxt_hold_pps <= '0';
END IF; END IF;
END IF; END IF;
...@@ -176,7 +187,71 @@ BEGIN ...@@ -176,7 +187,71 @@ BEGIN
hold_pps <= nxt_hold_pps WHEN rising_edge(clk); 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 -- Stimuli
...@@ -199,7 +274,9 @@ BEGIN ...@@ -199,7 +274,9 @@ BEGIN
tb_state <= s_disable; tb_state <= s_disable;
dp_on <= '0'; dp_on <= '0';
dp_on_pps <= '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 -- Start synchronously by making dp_on and dp_on_pps high
verify_en <= '1'; -- verify automatically in test bench verify_en <= '1'; -- verify automatically in test bench
...@@ -207,17 +284,17 @@ BEGIN ...@@ -207,17 +284,17 @@ BEGIN
FOR I IN 0 TO c_nof_repeat-1 LOOP FOR I IN 0 TO c_nof_repeat-1 LOOP
-- Wait some variable time between tests, to enforce testing different -- Wait some variable time between tests, to enforce testing different
-- bsn_time_offset values -- 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); proc_common_wait_some_cycles(clk, I*g_pps_interval);
-- Wait until in the beginning of PPS interval -- Wait until in the beginning of PPS interval
proc_common_wait_until_hi_lo(clk, ref_grid.pps); proc_common_wait_until_hi_lo(clk, ref_grid_bs.pps);
proc_common_wait_some_cycles(clk, c_dut_latency); proc_common_wait_some_cycles(clk, c_dp_bsn_latency);
-- Determine bsn_init and bsn_time_offset for BSN source start -- Determine bsn_init and bsn_time_offset for BSN source start
-- . bsn_init = BSN at sync -- . bsn_init = BSN at sync
-- . bsn_time_offset = number of clk that sync occurs after PPS -- . 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_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] 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); -- bsn_init <= TO_UVEC(v_bsn_init, c_bsn_w); --
...@@ -233,7 +310,7 @@ BEGIN ...@@ -233,7 +310,7 @@ BEGIN
END LOOP; END LOOP;
proc_common_wait_some_cycles(clk, 10); 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'; tb_end <= '1';
WAIT; WAIT;
...@@ -242,79 +319,80 @@ BEGIN ...@@ -242,79 +319,80 @@ BEGIN
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Verification -- 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 -- this overlap is fine, because the tb and DUT are rather complicated, so
-- using different approaches also helpt to verify the tb itself. -- 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_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, bs_sosi.sync, exp_grid.sop, exp_grid.sync); -- Verify sync at sop and at expected_sync --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 -- 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_pps_interval,
g_bs_block_size, g_rs_block_size,
TRUE, -- use BSN as RSN
clk, clk,
verify_en, verify_en,
bs_sosi.sync, rs_sosi.sync,
bs_sosi.sop, rs_sosi.sop,
bs_sosi.bsn, rs_sosi.bsn,
dbg_nof_blk, dbg_nof_blk,
dbg_accumulate, dbg_accumulate,
dbg_expected_bsn); dbg_expected_bsn);
-- Verify bs_sosi by comparing with exp_grid, this again verifies bs_sosi.sync, sop and bsn -- Verify rs_sosi by comparing with exp_grid_rs, this again verifies rs_sosi.sync, sop and bsn
p_verify_bs_sosi_grid : PROCESS(clk) p_verify_rs_sosi_grid : PROCESS(clk)
BEGIN BEGIN
IF rising_edge(clk) THEN IF rising_edge(clk) THEN
unexpected_bs_sync <= '0'; unexpected_rs_sync <= '0';
IF verify_en = '1' AND bs_sosi.valid = '1' THEN IF verify_en = '1' AND rs_sosi.valid = '1' THEN
ASSERT TO_UINT(bs_sosi.bsn) = exp_grid.bsn REPORT "Wrong bs_sosi.bsn /= exp_grid.bsn" SEVERITY ERROR; ASSERT TO_UINT(rs_sosi.bsn) = exp_grid_rs.bsn REPORT "Wrong rs_sosi.bsn /= exp_grid_rs.bsn" SEVERITY ERROR;
ASSERT bs_sosi.sync = exp_grid.sync REPORT "Wrong bs_sosi.sync /= exp_grid.sync" SEVERITY ERROR; ASSERT rs_sosi.sync = exp_grid_rs.sync REPORT "Wrong rs_sosi.sync /= exp_grid_rs.sync" SEVERITY ERROR;
ASSERT bs_sosi.sop = exp_grid.sop REPORT "Wrong bs_sosi.sop /= exp_grid.sop" SEVERITY ERROR; ASSERT rs_sosi.sop = exp_grid_rs.sop REPORT "Wrong rs_sosi.sop /= exp_grid_rs.sop" SEVERITY ERROR;
ASSERT bs_sosi.eop = exp_grid.eop REPORT "Wrong bs_sosi.eop /= exp_grid.eop" 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 -- Mark error in Wave window
IF bs_sosi.sync = '1' AND bs_sosi.sync /= exp_grid.sync THEN IF rs_sosi.sync = '1' AND rs_sosi.sync /= exp_grid_rs.sync THEN
unexpected_bs_sync <= '1'; unexpected_rs_sync <= '1';
END IF; END IF;
END IF; END IF;
END IF; END IF;
END PROCESS; END PROCESS;
-- Verify that bs_sosi.valid = '1' did happen after dp_on by verifying bs_start -- Verify that rs_sosi.valid = '1' did happen after dp_on by verifying rs_start
prev_bs_valid <= bs_sosi.valid WHEN rising_edge(clk); prev_rs_valid <= rs_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'; 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 BEGIN
IF rising_edge(clk) THEN IF rising_edge(clk) THEN
IF bs_restart = '1' THEN IF rs_restart = '1' THEN
ASSERT bs_sosi.sync = '1' REPORT "Unexpected bs_start while bs_sosi.sync /= 1" SEVERITY ERROR; ASSERT rs_sosi.sync = '1' REPORT "Unexpected rs_start while rs_sosi.sync /= 1" SEVERITY ERROR;
ASSERT prev_bs_valid = '0' REPORT "Unexpected bs_start while prev_bs_valid /= 0" SEVERITY ERROR; ASSERT prev_rs_valid = '0' REPORT "Unexpected rs_start while prev_rs_valid /= 0" SEVERITY ERROR;
END IF; END IF;
END IF; END IF;
END PROCESS; END PROCESS;
p_verify_bs_new_interval : PROCESS(clk) p_verify_rs_new_interval : PROCESS(clk)
BEGIN BEGIN
IF rising_edge(clk) THEN IF rising_edge(clk) THEN
IF bs_restart = '1' THEN IF rs_restart = '1' THEN
ASSERT bs_new_interval = '1' REPORT "Wrong begin of bs_new_interval" SEVERITY ERROR; ASSERT rs_new_interval = '1' REPORT "Wrong begin of rs_new_interval" SEVERITY ERROR;
tb_new_interval <= '1'; tb_new_interval <= '1';
ELSIF bs_sosi.sync = '1' THEN ELSIF rs_sosi.sync = '1' THEN
ASSERT bs_new_interval = '0' REPORT "Wrong end of bs_new_interval" SEVERITY ERROR; ASSERT rs_new_interval = '0' REPORT "Wrong end of rs_new_interval" SEVERITY ERROR;
tb_new_interval <= '0'; tb_new_interval <= '0';
ELSIF tb_new_interval = '1' THEN 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 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 IF; END IF;
END PROCESS; END PROCESS;
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- DUT: dp_bsn_source_v2 -- DUT: dp_bsn_source_v2 --> dp_rsn_source
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
u_bsn : ENTITY work.dp_bsn_source_v2 u_bsn : ENTITY work.dp_bsn_source_v2
...@@ -327,7 +405,7 @@ BEGIN ...@@ -327,7 +405,7 @@ BEGIN
PORT MAP ( PORT MAP (
rst => rst, rst => rst,
clk => clk, clk => clk,
pps => ref_grid.pps, pps => ref_grid_bs.pps,
-- MM control -- MM control
dp_on => dp_on, dp_on => dp_on,
dp_on_pps => dp_on_pps, dp_on_pps => dp_on_pps,
...@@ -345,7 +423,8 @@ BEGIN ...@@ -345,7 +423,8 @@ BEGIN
u_rsn : ENTITY work.dp_rsn_source u_rsn : ENTITY work.dp_rsn_source
GENERIC MAP ( 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_nof_clk_per_sync => g_pps_interval,
g_bsn_w => c_bsn_w g_bsn_w => c_bsn_w
) )
......
...@@ -52,6 +52,7 @@ BEGIN ...@@ -52,6 +52,7 @@ BEGIN
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
u_12_3_3 : ENTITY work.tb_dp_rsn_source GENERIC MAP (12, 3, 3); -- smallest block size 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_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_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 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 ...@@ -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 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 -- Same tests as with tb_dp_bsn_source_v2 with g_rs_block_size = g_bs_block_size
-- . g_rs_block_size /= g_bs_block_size
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- test integer case -- 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 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.
Please register or to comment