From 78640739928a40013501b189e84acc33b81f48c2 Mon Sep 17 00:00:00 2001
From: Eric Kooistra <kooistra@astron.nl>
Date: Mon, 4 Oct 2021 11:32:38 +0200
Subject: [PATCH] Simplified tb verification by using delayed input sosi.

---
 .../base/dp/tb/vhdl/tb_dp_bsn_align_v2.vhd    | 74 +++++++------------
 1 file changed, 25 insertions(+), 49 deletions(-)

diff --git a/libraries/base/dp/tb/vhdl/tb_dp_bsn_align_v2.vhd b/libraries/base/dp/tb/vhdl/tb_dp_bsn_align_v2.vhd
index 030019880a..4e62f1ceba 100644
--- a/libraries/base/dp/tb/vhdl/tb_dp_bsn_align_v2.vhd
+++ b/libraries/base/dp/tb/vhdl/tb_dp_bsn_align_v2.vhd
@@ -72,12 +72,13 @@ ARCHITECTURE tb OF tb_dp_bsn_align_v2 IS
   
   CONSTANT c_gap_size                 : NATURAL := g_block_period - g_block_size;
   CONSTANT c_dut_latency              : NATURAL := g_pipeline_input + g_rd_latency + 2;
-  CONSTANT c_align_latency_nof_valid  : NATURAL := g_bsn_latency_max * g_block_size;
-  CONSTANT c_align_latency_nof_clk    : NATURAL := g_bsn_latency_max * g_block_period;
+  CONSTANT c_align_latency_nof_blocks : NATURAL := g_bsn_latency_max;  -- DUT buffer latency in number blocks
+  CONSTANT c_align_latency_nof_valid  : NATURAL := g_bsn_latency_max * g_block_size;  -- DUT buffer latency in number of data samples
+  CONSTANT c_align_latency_nof_clk    : NATURAL := g_bsn_latency_max * g_block_period;  -- DUT buffer latency in number clk cycles
   CONSTANT c_total_latency            : NATURAL := c_dut_latency + c_align_latency_nof_clk;
-  CONSTANT c_verify_nof_blocks        : NATURAL := g_tb_nof_blocks - g_bsn_latency_max;  -- skip last blocks
+  CONSTANT c_verify_nof_blocks        : NATURAL := g_tb_nof_blocks - c_align_latency_nof_blocks;  -- skip last blocks that are still in the DUT buffer
 
-  TYPE t_tb_state IS (s_idle, s_start, s_restart, s_disable, s_lost);
+  TYPE t_tb_state IS (s_idle, s_start, s_restart);
 
   TYPE t_data_arr    IS ARRAY (g_nof_streams-1 DOWNTO 0) OF STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0);
   TYPE t_bsn_arr     IS ARRAY (g_nof_streams-1 DOWNTO 0) OF STD_LOGIC_VECTOR(c_bsn_w-1 DOWNTO 0);
@@ -133,6 +134,7 @@ ARCHITECTURE tb OF tb_dp_bsn_align_v2 IS
   SIGNAL out_eop_arr           : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
   SIGNAL out_val_arr           : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
   SIGNAL out_data_arr          : t_data_arr;
+  SIGNAL hold_data_arr         : t_data_arr;
   SIGNAL out_bsn_arr           : t_bsn_arr;
   SIGNAL out_channel_arr       : t_channel_arr;
   SIGNAL out_err_arr           : t_err_arr;
@@ -145,13 +147,10 @@ ARCHITECTURE tb OF tb_dp_bsn_align_v2 IS
   SIGNAL out_sosi_arr_exp      : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
   SIGNAL out_sosi_exp          : t_dp_sosi;
   SIGNAL verify_done_arr       : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS => '0');
-  SIGNAL verify_en_prev_arr    : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS => '0');
-  SIGNAL verify_en_delayed_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS => '0');
+  SIGNAL verify_sosi_en_arr    : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS => '0');
 
   SIGNAL hold_out_sop_arr      : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS => '0');
-  SIGNAL prev_out_bsn_arr      : t_bsn_arr;
   SIGNAL expected_out_bsn_arr  : t_bsn_arr;
-  SIGNAL prev_out_data_arr     : t_data_arr;
   SIGNAL expected_out_data_arr : t_data_arr;
 
   -- Return input delay as function of inputs stream index I
@@ -205,7 +204,7 @@ BEGIN
       END LOOP;
 
       -- End of stimuli, g_bsn_latency_max blocks remain in DUT buffer
-      expected_out_bsn_arr(I) <= TO_UVEC(v_bsn-1 - g_bsn_latency_max, c_bsn_w);
+      expected_out_bsn_arr(I) <= TO_UVEC(v_bsn-1 - c_align_latency_nof_blocks, c_bsn_w);
       expected_out_data_arr(I) <= TO_UVEC(v_data-1 - c_align_latency_nof_valid, c_data_w);
       
       proc_common_wait_some_cycles(clk, 100);
@@ -226,8 +225,7 @@ BEGIN
     tb_state <= s_idle;
     IF restart_cnt = 0 THEN tb_state <= s_start; END IF;
     IF restart_cnt = 1 THEN tb_state <= s_restart; END IF;
-    IF restart_cnt = 3 THEN tb_state <= s_disable; END IF;
-    IF restart_cnt = 4 THEN tb_state <= s_lost; END IF;
+    IF restart_cnt > 1 THEN tb_state <= s_restart; END IF;
   END PROCESS;
 
   -- Create latency misalignment between the input streams
@@ -274,58 +272,36 @@ BEGIN
   out_sosi_arr_exp <= ref_sosi_arr_dly WHEN rising_edge(clk);
   out_sosi_exp <= out_sosi_arr_exp(0);  -- take out_sosi_exp control and info from out_sosi_arr_exp(0)
 
-  ------------------------------------------------------------------------------
-  -- a) Use proc_dp_verify_()
-  ------------------------------------------------------------------------------
-  p_verify_en_prev_arr : PROCESS
-  BEGIN
-    WAIT UNTIL rising_edge(clk);
-    IF g_tb_diff_delay_max <= c_align_latency_nof_clk THEN
-      -- Can only verify incrementing sosi data when no blocks get lost
-      -- Use sop to skip sample of first block from verification, because then there is no prev_out_bsn_arr, prev_out_data_arr yet
-      IF out_sosi_exp.sop = '1' THEN
-        verify_en_prev_arr <= (OTHERS => '0');
-        IF TO_UINT(out_sosi_exp.bsn) - c_bsn_init < c_verify_nof_blocks THEN
-          verify_en_prev_arr <= (OTHERS => '1');
-        END IF;
-      END IF;
-    END IF;
-  END PROCESS;
-  
-  gen_verify_prev_sosi : FOR I IN g_nof_streams-1 DOWNTO 0 GENERATE
-    -- Actual verification of the output streams
+  gen_verify_ctrl : FOR I IN g_nof_streams-1 DOWNTO 0 GENERATE
     -- . Verify that sop and eop come in pairs
     proc_dp_verify_sop_and_eop(clk, out_val_arr(I), out_sop_arr(I), out_eop_arr(I), hold_out_sop_arr(I));
-    
-    -- . Verify that the output is incrementing, like the input stimuli
-    proc_dp_verify_data("out_sosi_arr().data", c_rl, clk, verify_en_prev_arr(I), out_siso_arr(I).ready, out_val_arr(I), out_data_arr(I), prev_out_data_arr(I));
-    proc_dp_verify_data("out_sosi_arr().bsn", c_rl, clk, verify_en_prev_arr(I), out_siso_arr(I).ready, out_sop_arr(I), out_bsn_arr(I), prev_out_bsn_arr(I));
-    
+
+    -- . No data verification here, using p_verify_sosi is easier than using proc_dp_verify_data().
+
     -- . Verify that the stimuli have been applied at all
-    proc_dp_verify_value("out_data_arr", e_equal, clk, verify_done_arr(I), expected_out_data_arr(I), prev_out_data_arr(I));
-    proc_dp_verify_value("out_bsn_arr", e_equal, clk, verify_done_arr(I), expected_out_bsn_arr(I),  prev_out_bsn_arr(I));
+    hold_data_arr(I) <= out_data_arr(I) WHEN out_val_arr(I) = '1';  -- hold last valid data
+
+    proc_dp_verify_value("out_data_arr", e_equal, clk, verify_done_arr(I), expected_out_data_arr(I), hold_data_arr(I));
+    proc_dp_verify_value("out_bsn_arr", e_equal, clk, verify_done_arr(I), expected_out_bsn_arr(I), out_bsn_arr(I));
   END GENERATE;
   
-  ------------------------------------------------------------------------------
-  -- b) Use delayed in_sosi_arr as expected out_sosi_arr
-  ------------------------------------------------------------------------------
-  p_verify_en_delayed_arr : PROCESS(out_sosi_exp)
+  -- . Use delayed in_sosi_arr as expected out_sosi_arr, this is possible
+  --   because the DUT has no flow control and has a fixed latency.
+  p_verify_sosi_en_arr : PROCESS(out_sosi_exp)
   BEGIN
     IF g_tb_diff_delay_max <= c_align_latency_nof_clk THEN
-      -- Can only verify incrementing sosi data when no blocks get lost
-      -- Skip sample of first block from verification, because then there is no prev_out_bsn_arr, prev_out_data_arr yet
-      verify_en_delayed_arr <= (OTHERS => '1');
+      verify_sosi_en_arr <= (OTHERS => '1');
       IF TO_UINT(out_sosi_exp.bsn) - c_bsn_init >= c_verify_nof_blocks THEN
-          verify_en_delayed_arr <= (OTHERS => '0');
+        verify_sosi_en_arr <= (OTHERS => '0');
       END IF;
     END IF;
   END PROCESS;
 
-  gen_verify_delayed_sosi : FOR I IN g_nof_streams-1 DOWNTO 0 GENERATE
-    p_verify_data : PROCESS(clk)
+  gen_verify_streams : FOR I IN g_nof_streams-1 DOWNTO 0 GENERATE
+    p_verify_sosi : PROCESS(clk)
     BEGIN
       IF rising_edge(clk) THEN
-        IF verify_en_delayed_arr(I) = '1' AND out_sosi_arr_exp(I).valid = '1' THEN
+        IF verify_sosi_en_arr(I) = '1' AND out_sosi_arr_exp(I).valid = '1' THEN
            ASSERT out_sosi_arr(I).sync = out_sosi_arr_exp(I).sync REPORT "Wrong sync for output " & int_to_str(I) SEVERITY ERROR;
            ASSERT out_sosi_arr(I).sop = out_sosi_arr_exp(I).sop REPORT "Wrong sop for output " & int_to_str(I) SEVERITY ERROR;
            ASSERT out_sosi_arr(I).eop = out_sosi_arr_exp(I).eop REPORT "Wrong eop for output " & int_to_str(I) SEVERITY ERROR;
-- 
GitLab