From c20362cf4cd5a3e48585c312fa707ea87770f491 Mon Sep 17 00:00:00 2001
From: Eric Kooistra <kooistra@astron.nl>
Date: Wed, 6 Sep 2023 13:26:43 +0200
Subject: [PATCH] Verify unmerged channel, empty and err fields.

---
 .../dp/tb/vhdl/tb_dp_packet_merge_unmerge.vhd | 95 ++++++++++++-------
 .../tb/vhdl/tb_tb_dp_packet_merge_unmerge.vhd | 42 ++++----
 2 files changed, 82 insertions(+), 55 deletions(-)

diff --git a/libraries/base/dp/tb/vhdl/tb_dp_packet_merge_unmerge.vhd b/libraries/base/dp/tb/vhdl/tb_dp_packet_merge_unmerge.vhd
index 6277b534f3..f94f237442 100644
--- a/libraries/base/dp/tb/vhdl/tb_dp_packet_merge_unmerge.vhd
+++ b/libraries/base/dp/tb/vhdl/tb_dp_packet_merge_unmerge.vhd
@@ -51,8 +51,6 @@ entity tb_dp_packet_merge_unmerge is
     g_nof_pkt                : natural := 3;
     g_pkt_len                : natural := 10;
     g_pkt_gap                : natural := 0;
-    g_align_at_sync          : boolean := false;
-    g_verify_bsn_err         : boolean := false;
     g_bsn_increment          : natural := 1
   );
 end tb_dp_packet_merge_unmerge;
@@ -69,23 +67,20 @@ architecture tb of tb_dp_packet_merge_unmerge is
   constant c_data_max                 : unsigned(g_data_w - 1 downto 0) := (others => '1');
   constant c_data_init                : integer := -1;
   constant c_bsn_init                 : std_logic_vector(c_dp_stream_bsn_w - 1 downto 0) := X"0000000000000000";  -- X"0877665544332211"
-  constant c_err_init                 : natural := 247;
-  constant c_bsn_err_bi               : natural := 31;  -- use sufficiently high bsn error bit index, that is outside counter range of c_err_init
-  constant c_channel_init             : integer := 5;  -- fixed
 
   constant c_nof_pkt_not_zero         : natural := sel_a_b(g_nof_pkt = 0, 1, g_nof_pkt);
   constant c_nof_merged_sop           : natural := sel_a_b(g_nof_pkt = 0, 0, ceil_div(g_nof_repeat, c_nof_pkt_not_zero));
-  constant c_verify_at_least          : natural := largest(1,c_nof_merged_sop / 2);  -- verify that at least some packets have been merged, not exact to allow variation by p_stimuli_mm
-  constant c_verify_data_gap          : natural := g_nof_pkt;
-  constant c_verify_bsn_gap           : natural := g_nof_pkt * g_bsn_increment;
+  -- verify that at least some packets have been merged, not exact to allow variation by p_stimuli_mm
+  constant c_verify_at_least          : natural := largest(1,c_nof_merged_sop / 2);
 
   signal tb_end                     : std_logic := '0';
   signal clk                        : std_logic := '1';
   signal rst                        : std_logic := '1';
   signal sl1                        : std_logic := '1';
 
-  signal random_0                   : std_logic_vector(14 downto 0) := (others => '0');  -- use different lengths to have different random sequences
-  signal random_1                   : std_logic_vector(15 downto 0) := (others => '0');  -- use different lengths to have different random sequences
+  -- use different slv lengths to have different random sequences
+  signal random_0                   : std_logic_vector(14 downto 0) := (others => '0');
+  signal random_1                   : std_logic_vector(15 downto 0) := (others => '0');
   signal pulse_0                    : std_logic;
   signal pulse_1                    : std_logic;
   signal pulse_en                   : std_logic := '1';
@@ -105,8 +100,12 @@ architecture tb of tb_dp_packet_merge_unmerge is
   signal verify_snk_in              : t_dp_sosi;
   signal verify_data                : std_logic_vector(g_data_w - 1 downto 0);
   signal prev_verify_snk_in         : t_dp_sosi;
+
+  signal input_pkt_cnt              : natural := 0;
   signal merged_pkt_cnt             : natural := 0;
   signal exp_channel                : natural := 0;
+  signal exp_error                  : natural := 0;
+  signal exp_empty                  : natural := 0;
 
   signal verify_hold_sop            : std_logic := '0';
   signal verify_en_valid            : std_logic := '0';
@@ -144,13 +143,14 @@ begin
 
   -- Generate data path input data
   p_stimuli_st : process
-    variable v_sosi : t_dp_sosi := c_dp_sosi_rst;
-    variable v_bsn  : std_logic_vector(c_dp_stream_bsn_w - 1 downto 0);
+    constant c_channel : natural := 0;
+    constant c_err     : natural := 0;
+    variable v_sosi    : t_dp_sosi := c_dp_sosi_rst;
+    variable v_bsn     : std_logic_vector(c_dp_stream_bsn_w - 1 downto 0);
   begin
     -- Adjust initial sosi field values by -1 to compensate for auto increment
     v_sosi.bsn  := INCR_UVEC(c_bsn_init, -1);
     v_sosi.data := INCR_UVEC(TO_DP_DATA(c_data_init), -1);
-    v_sosi.err  := INCR_UVEC(TO_DP_ERROR(c_err_init), -1);
 
     stimuli_src_out <= c_dp_sosi_rst;
     proc_common_wait_until_low(clk, rst);
@@ -159,14 +159,15 @@ begin
     -- Generate c_nof_repeat packets
     for I in 0 to g_nof_repeat - 1 loop
       -- Auto increment v_sosi field values for this packet
-      v_sosi.bsn     := INCR_UVEC(v_sosi.bsn, g_bsn_increment);
-      -- insert sync starting at BSN=c_sync_offset and with period c_sync_period
-      v_sosi.sync    := sel_a_b((unsigned(v_sosi.bsn) mod c_sync_period) = c_sync_offset, '1', '0');
-      v_sosi.data    := INCR_UVEC(v_sosi.data, g_pkt_len);
-      v_sosi.data    := RESIZE_DP_DATA(v_sosi.data(g_data_w - 1 downto 0));  -- wrap when >= 2**g_data_w
+      v_sosi.bsn  := INCR_UVEC(v_sosi.bsn, g_bsn_increment);
+      -- insert sync starting at BSN = c_sync_offset and with period c_sync_period
+      v_sosi.sync := sel_a_b((unsigned(v_sosi.bsn) mod c_sync_period) = c_sync_offset, '1', '0');
+      v_sosi.data := INCR_UVEC(v_sosi.data, g_pkt_len);
+      v_sosi.data := RESIZE_DP_DATA(v_sosi.data(g_data_w - 1 downto 0));  -- wrap when >= 2**g_data_w
 
       -- Send packet
-      proc_dp_gen_block_data(g_data_w, TO_UINT(v_sosi.data), g_pkt_len, TO_UINT(v_sosi.channel), TO_UINT(v_sosi.err), v_sosi.sync, v_sosi.bsn,
+      proc_dp_gen_block_data(g_data_w, TO_UINT(v_sosi.data), g_pkt_len,
+                             c_channel, c_err, v_sosi.sync, v_sosi.bsn,
                              clk, stimuli_en, stimuli_src_in, stimuli_src_out);
 
       -- Insert optional gap between the packets
@@ -176,11 +177,11 @@ begin
     -- Determine expected sosi field values after end of stimuli
     -- . e_qual (account for merge size g_nof_pkt)
     -- . e_at_least
-    v_sosi.bsn     := std_logic_vector(unsigned(c_bsn_init) + c_verify_at_least * g_nof_pkt);
+    v_sosi.bsn := std_logic_vector(unsigned(c_bsn_init) + c_verify_at_least * g_nof_pkt);
 
     -- . account for g_pkt_len
-    v_sosi.data    := INCR_UVEC(v_sosi.data, g_pkt_len - 1);
-    v_sosi.data    := RESIZE_DP_DATA(v_sosi.data(g_data_w - 1 downto 0));  -- wrap when >= 2**g_data_w
+    v_sosi.data := INCR_UVEC(v_sosi.data, g_pkt_len - 1);
+    v_sosi.data := RESIZE_DP_DATA(v_sosi.data(g_data_w - 1 downto 0));  -- wrap when >= 2**g_data_w
     expected_verify_snk_in <= v_sosi;
 
     -- Signal end of stimuli
@@ -216,7 +217,8 @@ begin
                       clk, verify_en_valid, verify_snk_out.ready,
                       verify_snk_in.valid, verify_snk_in.data, prev_verify_snk_in.data);
 
-  proc_dp_verify_data("verify_snk_in.bsn", c_rl, c_unsigned_0, to_unsigned(c_verify_bsn_gap, 32),
+  -- Verify that the output is incrementing BSN, like the input stimuli
+  proc_dp_verify_data("verify_snk_in.bsn", c_rl, c_unsigned_0, c_unsigned_0,
                        clk, verify_en_sop, verify_snk_out.ready,
                        verify_snk_in.sop, verify_snk_in.bsn, prev_verify_snk_in.bsn);
 
@@ -226,13 +228,27 @@ begin
   -- Verify output ready latency
   proc_dp_verify_valid(clk, verify_en_valid, verify_snk_out.ready, prev_verify_snk_out.ready, verify_snk_in.valid);
 
-  -- Verify output channel
-  p_verify_channel : process(clk)
+  -- Verify output verify_snk_in.sosi fields
+  p_verify_fields : process(clk)
   begin
     if rising_edge(clk) then
-      if verify_snk_in.sop = '1' then
+      -- Use verify_snk_in.valid, because the assumption with dp_packet_unmerge
+      -- is that the channel (at sop) and err, empty (at eop) are valid during
+      -- the entire unmerged packet.
+      if verify_snk_in.valid = '1' then
+        -- Verify that output channel yields index of unmerged packet, in range(g_nof_pkt)
         assert unsigned(verify_snk_in.channel) = exp_channel
-          report "wrong unmerged verify_snk_in.channel"
+          report "Wrong unmerged verify_snk_in.channel"
+          severity ERROR;
+
+        -- Verify that output error is same per g_nof_pkt unmerged packets
+        assert unsigned(verify_snk_in.err) = exp_error
+          report "Wrong unmerged verify_snk_in.err"
+          severity ERROR;
+
+        -- Verify that output empty is same per g_nof_pkt unmerged packets
+        assert unsigned(verify_snk_in.empty) = exp_empty
+          report "Wrong unmerged verify_snk_in.empty"
           severity ERROR;
       end if;
     end if;
@@ -246,9 +262,9 @@ begin
   u_dp_packet_merge : entity work.dp_packet_merge
   generic map (
     g_nof_pkt       => g_nof_pkt,
-    g_align_at_sync => g_align_at_sync,
+    g_align_at_sync => false,  -- not used in this tb
     g_bsn_increment => g_bsn_increment,
-    g_bsn_err_bi    => c_bsn_err_bi
+    g_bsn_err_bi    => 0  -- not used in this tb
   )
   port map (
     rst       => rst,
@@ -261,18 +277,31 @@ begin
     src_out   => dp_packet_merge_src_out
   );
 
-  merged_pkt_cnt <= merged_pkt_cnt + 1 when rising_edge(clk) and dp_packet_merge_src_out.eop = '1';
-
-  exp_channel <= merged_pkt_cnt mod g_nof_pkt;
-
   dp_packet_merge_snk_in <= dp_packet_merge_siso;
 
+  ------------------------------------------------------------------------------
+  -- TB stimuli for dp_packet_unmerge
+  ------------------------------------------------------------------------------
   p_stimuli_unmerge : process(dp_packet_merge_src_out)
   begin
     dp_packet_merge_sosi     <= dp_packet_merge_src_out;
+    -- Use counter as err field stimulus, per merged packet. Use
+    -- offset to distinguish err and empty values
     dp_packet_merge_sosi.err <= TO_DP_ERROR(merged_pkt_cnt);
+    dp_packet_merge_sosi.empty <= TO_DP_EMPTY(merged_pkt_cnt + 1);
   end process;
 
+  ------------------------------------------------------------------------------
+  -- TB signals for verification of dp_packet_unmerge
+  ------------------------------------------------------------------------------
+  input_pkt_cnt <= input_pkt_cnt + 1 when rising_edge(clk) and stimuli_src_out.eop = '1';
+  merged_pkt_cnt <= merged_pkt_cnt + 1 when rising_edge(clk) and dp_packet_merge_src_out.eop = '1';
+
+  -- get expected value, aligned with output packet boundaries
+  exp_channel <= input_pkt_cnt mod g_nof_pkt when rising_edge(clk) and verify_snk_in.eop = '1';
+  exp_error <= merged_pkt_cnt when rising_edge(clk) and verify_snk_in.eop = '1';
+  exp_empty <= exp_error + 1;
+
   ------------------------------------------------------------------------------
   -- Optional reverse DUT dp_packet_unmerge
   ------------------------------------------------------------------------------
diff --git a/libraries/base/dp/tb/vhdl/tb_tb_dp_packet_merge_unmerge.vhd b/libraries/base/dp/tb/vhdl/tb_tb_dp_packet_merge_unmerge.vhd
index daa8ab9db6..f0859b884a 100644
--- a/libraries/base/dp/tb/vhdl/tb_tb_dp_packet_merge_unmerge.vhd
+++ b/libraries/base/dp/tb/vhdl/tb_tb_dp_packet_merge_unmerge.vhd
@@ -44,31 +44,29 @@ begin
   --     g_nof_pkt                : natural := 3;
   --     g_pkt_len                : natural := 29;
   --     g_pkt_gap                : natural := 0;
-  --     g_align_at_sync          : boolean := false;
-  --     g_verify_bsn_err         : boolean := false;
   --     g_bsn_increment          : natural := 0;
 
-  u_act_act_8_nof_0      : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 0, 29, 0, false, false, 1);
-  u_act_act_8_nof_1      : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 1, 29, 0, false, false, 1);
-  u_act_act_8_nof_2      : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 2, 29, 0, false, false, 1);
-  u_act_act_8_nof_3      : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, false, false, 1);
-  u_act_act_8_nof_4      : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 4, 29, 0, false, false, 1);
-  u_act_act_8_nof_5      : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 5, 29, 0, false, false, 1);
-  u_act_act_8_nof_6      : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 6, 29, 0, false, false, 1);
-  u_act_act_8_nof_7      : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 7, 29, 0, false, false, 1);
+  u_act_act_8_nof_0      : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 0, 29, 0, 1);
+  u_act_act_8_nof_1      : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 1, 29, 0, 1);
+  u_act_act_8_nof_2      : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 2, 29, 0, 1);
+  u_act_act_8_nof_3      : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, 1);
+  u_act_act_8_nof_4      : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 4, 29, 0, 1);
+  u_act_act_8_nof_5      : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 5, 29, 0, 1);
+  u_act_act_8_nof_6      : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 6, 29, 0, 1);
+  u_act_act_8_nof_7      : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 7, 29, 0, 1);
 
-  u_rnd_act_8_nof_3      : entity work.tb_dp_packet_merge_unmerge generic map ( e_random, e_active, 8, c_nof_repeat, 3, 29, 0, false, false, 2);
-  u_rnd_rnd_8_nof_3      : entity work.tb_dp_packet_merge_unmerge generic map ( e_random, e_random, 8, c_nof_repeat, 3, 29, 0, false, false, 3);
-  u_pls_act_8_nof_3      : entity work.tb_dp_packet_merge_unmerge generic map ( e_pulse,  e_active, 8, c_nof_repeat, 3, 29, 0, false, false, 4);
-  u_pls_rnd_8_nof_3      : entity work.tb_dp_packet_merge_unmerge generic map ( e_pulse,  e_random, 8, c_nof_repeat, 3, 29, 0, false, false, 5);
-  u_pls_pls_8_nof_3      : entity work.tb_dp_packet_merge_unmerge generic map ( e_pulse,  e_pulse,  8, c_nof_repeat, 3, 29, 0, false, false, 6);
+  u_rnd_act_8_nof_3      : entity work.tb_dp_packet_merge_unmerge generic map ( e_random, e_active, 8, c_nof_repeat, 3, 29, 0, 2);
+  u_rnd_rnd_8_nof_3      : entity work.tb_dp_packet_merge_unmerge generic map ( e_random, e_random, 8, c_nof_repeat, 3, 29, 0, 3);
+  u_pls_act_8_nof_3      : entity work.tb_dp_packet_merge_unmerge generic map ( e_pulse,  e_active, 8, c_nof_repeat, 3, 29, 0, 4);
+  u_pls_rnd_8_nof_3      : entity work.tb_dp_packet_merge_unmerge generic map ( e_pulse,  e_random, 8, c_nof_repeat, 3, 29, 0, 5);
+  u_pls_pls_8_nof_3      : entity work.tb_dp_packet_merge_unmerge generic map ( e_pulse,  e_pulse,  8, c_nof_repeat, 3, 29, 0, 6);
 
-  u_rnd_act_8_nof_1      : entity work.tb_dp_packet_merge_unmerge generic map ( e_random, e_active, 8, c_nof_repeat, 1, 29,  0, false, false, 1);
-  u_rnd_act_8_nof_3_gap  : entity work.tb_dp_packet_merge_unmerge generic map ( e_random, e_active, 8, c_nof_repeat, 3, 29, 17, false, false, 1);
+  u_rnd_act_8_nof_1      : entity work.tb_dp_packet_merge_unmerge generic map ( e_random, e_active, 8, c_nof_repeat, 1, 29,  0, 1);
+  u_rnd_act_8_nof_3_gap  : entity work.tb_dp_packet_merge_unmerge generic map ( e_random, e_active, 8, c_nof_repeat, 3, 29, 17, 1);
 
-  u_act_act_8_nof_3_no_err : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, false, true, 0);
-  u_act_act_8_nof_3_err_10 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, false, true, 1);
-  u_act_act_8_nof_3_err_11 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, false, true, 1);
-  u_act_act_8_nof_3_err_12 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, false, true, 1);
-  u_act_act_8_nof_3_err_13 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, false, true, 1);
+  u_act_act_8_nof_3_no_err : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, 0);
+  u_act_act_8_nof_3_err_10 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, 1);
+  u_act_act_8_nof_3_err_11 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, 1);
+  u_act_act_8_nof_3_err_12 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, 1);
+  u_act_act_8_nof_3_err_13 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, 1);
 end tb;
-- 
GitLab