From 7e5a2923761edf593145854b7484e077d108ae4e Mon Sep 17 00:00:00 2001
From: Eric Kooistra <kooistra@astron.nl>
Date: Mon, 25 Sep 2023 13:05:27 +0200
Subject: [PATCH] Verify c_unsigned_bsn_pkt_merge.

---
 .../dp/tb/vhdl/tb_dp_packet_merge_unmerge.vhd |  66 +++++----
 libraries/base/dp/tb/vhdl/tb_dp_pkg.vhd       | 130 ++++++++++++++++--
 2 files changed, 160 insertions(+), 36 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 e1038d56ab..275d85700b 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
@@ -23,8 +23,8 @@
 -- Description:
 -- . The p_stimuli_st uses proc_dp_gen_block_data to generate g_nof_repeat
 --   stimuli_src_out packets of length g_pkt_len_merge.
--- . The u_dp_packet_merge merges g_nof_pkt packets from stimuli_src_out into
---   dp_packet_merge_src_out.
+-- . The u_dp_packet_merge merges g_nof_pkt_merge packets from stimuli_src_out
+--   into dp_packet_merge_src_out.
 -- . The p_stimuli_unmerge provides stimuli for the .err and .empty fields of
 --   dp_packet_merge_src_out to get dp_packet_merge_sosi
 -- . The u_dp_packet_unmerge unmerges the dp_packet_merge_sosi into packets
@@ -33,7 +33,7 @@
 --   - the last unmerged packet may be shorter then g_pkt_len_unmerge, to
 --     contain the remaining data.
 --   - the number of unmerged packets c_nof_pkt_unmerge, may differ from
---     g_nof_pkt.
+--     g_nof_pkt_merge.
 --   - use c_bsn_increment_unmerge = 0 for u_dp_packet_unmerge and expect BSN
 --     increment of 0 for unmerged packets from same merged packet or
 --     c_nof_pkt_unmerge for unmerged packets from subsequent merged packets.
@@ -72,11 +72,11 @@ entity tb_dp_packet_merge_unmerge is
     g_pipeline_ready         : boolean := true;
     g_data_w                 : natural := 16;
     g_nof_repeat             : natural := 14;
-    g_nof_pkt                : natural := 3;
+    g_nof_pkt_merge          : natural := 4;
     g_pkt_len_merge          : natural := 7;
-    g_pkt_len_unmerge        : natural := 6;
+    g_pkt_len_unmerge        : natural := 7;
     g_pkt_gap                : natural := 0;
-    g_bsn_increment          : natural := 1
+    g_bsn_increment          : natural := 0
   );
 end tb_dp_packet_merge_unmerge;
 
@@ -87,20 +87,26 @@ architecture tb of tb_dp_packet_merge_unmerge is
   constant c_pulse_active             : natural := 1;
   constant c_pulse_period             : natural := 7;
 
+  constant c_nof_pkt_unmerge          : natural := ceil_div(g_nof_pkt_merge * g_pkt_len_merge, g_pkt_len_unmerge);
+  constant c_bsn_increment_unmerge    : natural := sel_a_b(g_nof_pkt_merge = c_nof_pkt_unmerge, g_bsn_increment, 0);
+
   constant c_sync_period              : natural := 10;
   constant c_sync_offset              : natural := 7;
 
   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_bsn_increment_w          : natural := ceil_log2(g_bsn_increment + 1);
-  constant c_unsigned_bsn_increment   : unsigned(c_bsn_increment_w - 1 downto 0) := to_unsigned(g_bsn_increment, c_bsn_increment_w);
-
-  constant c_nof_pkt_unmerge          : natural := ceil_div(g_nof_pkt * g_pkt_len_merge, g_pkt_len_unmerge);
-  constant c_bsn_increment_unmerge    : natural := sel_a_b(g_nof_pkt = c_nof_pkt_unmerge, g_bsn_increment, 0);
 
-  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_bsn_init                 : std_logic_vector(c_dp_stream_bsn_w - 1 downto 0) := X"0000000000000000";
+                                          -- X"0877665544332211"
+  constant c_bsn_increment_max        : natural := (g_bsn_increment + 1) * g_nof_pkt_merge;  -- +1 to ensure max > 0
+  constant c_bsn_increment_w          : natural := ceil_log2(c_bsn_increment_max + 1);
+  constant c_unsigned_bsn_increment   : unsigned(c_bsn_increment_w - 1 downto 0) :=
+                                          to_unsigned(g_bsn_increment, c_bsn_increment_w);
+  constant c_unsigned_bsn_pkt_merge : unsigned(c_bsn_increment_w - 1 downto 0) :=
+                                          to_unsigned(g_nof_pkt_merge, c_bsn_increment_w);
+
+  constant c_nof_pkt_not_zero         : natural := sel_a_b(g_nof_pkt_merge = 0, 1, g_nof_pkt_merge);
+  constant c_nof_merged_sop           : natural := sel_a_b(g_nof_pkt_merge = 0, 0, ceil_div(g_nof_repeat, c_nof_pkt_not_zero));
   -- 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);
 
@@ -144,7 +150,7 @@ architecture tb of tb_dp_packet_merge_unmerge is
   signal verify_en_sop              : std_logic := '0';
   signal verify_en_eop              : std_logic := '0';
   signal verify_done                : std_logic := '0';
-  signal verify_value_en            : std_logic := sel_a_b(g_nof_pkt = 0, '0', '1');
+  signal verify_value_en            : std_logic := sel_a_b(g_nof_pkt_merge = 0, '0', '1');
 
   signal expected_verify_snk_in     : t_dp_sosi;
 begin
@@ -207,9 +213,9 @@ begin
     end loop;
 
     -- Determine expected sosi field values after end of stimuli
-    -- . e_qual (account for merge size g_nof_pkt)
+    -- . e_qual (account for merge size g_nof_pkt_merge)
     -- . 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_merge);
 
     -- . account for g_pkt_len_merge
     v_sosi.data := INCR_UVEC(v_sosi.data, g_pkt_len_merge - 1);
@@ -251,8 +257,22 @@ begin
                       verify_snk_in.valid, verify_snk_in.data, prev_verify_snk_in.data);
 
   -- Verify that the output is incrementing BSN, like the input stimuli
-  gen_verify_bsn : if g_nof_pkt = c_nof_pkt_unmerge generate
-    proc_dp_verify_data("verify_snk_in.bsn", c_rl, c_unsigned_0, c_unsigned_bsn_increment,
+  gen_verify_bsn_increment : if g_nof_pkt_merge = c_nof_pkt_unmerge generate
+    -- If number of packets stays the same, then unmerge bsn will increment
+    -- as stimuli bsn by c_unsigned_bsn_increment = g_bsn_increment
+    proc_dp_verify_data("verify_snk_in.bsn increment", c_rl,
+                         c_unsigned_0, c_unsigned_bsn_increment,
+                         clk, verify_en_sop, verify_snk_out.ready,
+                         verify_snk_in.sop, verify_snk_in.bsn, prev_verify_snk_in.bsn);
+  end generate;
+  gen_verify_bsn_pkt_unmerge : if g_nof_pkt_merge /= c_nof_pkt_unmerge generate
+    -- If number of packets differs after unmerge, then use
+    -- c_bsn_increment_unmerge = 0 to not increment bsn during ummerge of
+    -- packets, this is covered by gap c_unsigned_0. The bsn of the merged
+    -- packets is passed on into each of the unmerged packets, this is
+    -- covered by c_unsigned_bsn_pkt_merge.
+    proc_dp_verify_data("verify_snk_in.bsn pkt_unmerge", c_rl,
+                         c_unsigned_0, c_unsigned_0, c_unsigned_bsn_pkt_merge,
                          clk, verify_en_sop, verify_snk_out.ready,
                          verify_snk_in.sop, verify_snk_in.bsn, prev_verify_snk_in.bsn);
   end generate;
@@ -276,12 +296,12 @@ begin
           report "Wrong unmerged verify_snk_in.channel"
           severity ERROR;
 
-        -- Verify that output error is same per g_nof_pkt unmerged packets
+        -- Verify that output error is same per c_nof_pkt_unmerge 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
+        -- Verify that output empty is same per c_nof_pkt_unmerge unmerged packets
         assert unsigned(verify_snk_in.empty) = exp_empty
           report "Wrong unmerged verify_snk_in.empty"
           severity ERROR;
@@ -293,10 +313,10 @@ begin
   -- DUT dp_packet_merge
   ------------------------------------------------------------------------------
 
-  -- Merge every g_nof_pkt incomming packets into output packets
+  -- Merge every g_nof_pkt_merge incomming packets into output packets
   u_dp_packet_merge : entity work.dp_packet_merge
   generic map (
-    g_nof_pkt       => g_nof_pkt,
+    g_nof_pkt       => g_nof_pkt_merge,
     g_align_at_sync => false,  -- not used in this tb
     g_bsn_increment => g_bsn_increment,
     g_bsn_err_bi    => 0  -- not used in this tb
diff --git a/libraries/base/dp/tb/vhdl/tb_dp_pkg.vhd b/libraries/base/dp/tb/vhdl/tb_dp_pkg.vhd
index 3cb638a976..6537c59535 100644
--- a/libraries/base/dp/tb/vhdl/tb_dp_pkg.vhd
+++ b/libraries/base/dp/tb/vhdl/tb_dp_pkg.vhd
@@ -339,6 +339,21 @@ package tb_dp_pkg is
   -- Verify incrementing data
   -- . wrap at c_out_data_max when >0, else no wrap when c_out_data_max=0
   -- . default increment by +1, but also allow an increment by +c_out_data_gap
+  --   or +c_out_data_gap2.
+  -- . by using sop or eop for out_val input, the proc_dp_verify_data() can
+  --   also be used to verify other SOSI fields like bsn, error, channel, empty
+  procedure proc_dp_verify_data(constant c_str           : in    string;
+                                constant c_ready_latency : in    natural;
+                                constant c_out_data_max  : in    unsigned;
+                                constant c_out_data_gap  : in    unsigned;
+                                constant c_out_data_gap2 : in    unsigned;
+                                signal   clk             : in    std_logic;
+                                signal   verify_en       : in    std_logic;
+                                signal   out_ready       : in    std_logic;
+                                signal   out_val         : in    std_logic;
+                                signal   out_data        : in    std_logic_vector;
+                                signal   prev_out_data   : inout std_logic_vector);
+
   procedure proc_dp_verify_data(constant c_str           : in    string;
                                 constant c_ready_latency : in    natural;
                                 constant c_out_data_max  : in    unsigned;
@@ -367,11 +382,21 @@ package tb_dp_pkg is
                                 signal   clk             : in    std_logic;
                                 signal   verify_en       : in    std_logic;
                                 signal   out_ready       : in    std_logic;
-                                signal   out_val         : in    std_logic;  -- by using sop or eop proc_dp_verify_data() can also be used to verify other SOSI fields like bsn, error, channel, empty
+                                signal   out_val         : in    std_logic;
                                 signal   out_data        : in    std_logic_vector;
                                 signal   prev_out_data   : inout std_logic_vector);
 
   -- Verify incrementing data with RL > 0 or no flow control, support wrap at maximum and increment gap
+  procedure proc_dp_verify_data(constant c_str           : in    string;
+                                constant c_out_data_max  : in    unsigned;
+                                constant c_out_data_gap  : in    unsigned;
+                                constant c_out_data_gap2 : in    unsigned;
+                                signal   clk             : in    std_logic;
+                                signal   verify_en       : in    std_logic;
+                                signal   out_val         : in    std_logic;
+                                signal   out_data        : in    std_logic_vector;
+                                signal   prev_out_data   : inout std_logic_vector);
+
   procedure proc_dp_verify_data(constant c_str           : in    string;
                                 constant c_out_data_max  : in    unsigned;
                                 constant c_out_data_gap  : in    unsigned;
@@ -381,6 +406,16 @@ package tb_dp_pkg is
                                 signal   out_data        : in    std_logic_vector;
                                 signal   prev_out_data   : inout std_logic_vector);
 
+  procedure proc_dp_verify_data(constant c_str           : in    string;
+                                constant c_out_data_max  : in    natural;
+                                constant c_out_data_gap  : in    natural;
+                                constant c_out_data_gap2 : in    natural;
+                                signal   clk             : in    std_logic;
+                                signal   verify_en       : in    std_logic;
+                                signal   out_val         : in    std_logic;
+                                signal   out_data        : in    std_logic_vector;
+                                signal   prev_out_data   : inout std_logic_vector);
+
   procedure proc_dp_verify_data(constant c_str           : in    string;
                                 constant c_out_data_max  : in    natural;
                                 constant c_out_data_gap  : in    natural;
@@ -1878,10 +1913,12 @@ package body tb_dp_pkg is
   -- Verify incrementing data
   -- . wrap at c_out_data_max when >0, else no wrap when c_out_data_max=0
   -- . default increment by 1, but also allow an increment by c_out_data_gap
+  -- . or c_out_data_gap2.
   procedure proc_dp_verify_data(constant c_str           : in    string;
                                 constant c_ready_latency : in    natural;
                                 constant c_out_data_max  : in    unsigned;
                                 constant c_out_data_gap  : in    unsigned;
+                                constant c_out_data_gap2 : in    unsigned;
                                 signal   clk             : in    std_logic;
                                 signal   verify_en       : in    std_logic;
                                 signal   out_ready       : in    std_logic;  -- only needed when c_ready_latency = 0
@@ -1903,10 +1940,17 @@ package body tb_dp_pkg is
             prev_out_data <= TO_SVEC(-1, prev_out_data'length);  -- do wrap
           end if;
           if verify_en = '1' then
-            if unsigned(out_data) /= unsigned(prev_out_data) + 1 and  -- check increment +1
-               unsigned(out_data) /= unsigned(prev_out_data) + c_out_data_gap and  -- increment +c_out_data_gap
-               unsigned(out_data) /= unsigned(prev_out_data) + c_out_data_gap - c_out_data_max then  -- increment +c_out_data_gap wrapped
-              report "DP : Wrong out_data " & c_str & " count" severity ERROR;
+            -- Default check increment +1.
+            -- also allow increment +c_out_data_gap or +c_out_data_gap2.
+            -- also allow increment +c_out_data_gap wrapped by c_out_data_max.
+            if unsigned(out_data) /= unsigned(prev_out_data) + 1 and
+               unsigned(out_data) /= unsigned(prev_out_data) + c_out_data_gap and
+               unsigned(out_data) /= unsigned(prev_out_data) + c_out_data_gap2 and
+               unsigned(out_data) /= unsigned(prev_out_data) + c_out_data_gap - c_out_data_max then
+              report "DP : Wrong out_data " & c_str & " count (" &
+                natural'image(to_uint(out_data)) & ", " &
+                natural'image(to_uint(prev_out_data)) & ")"
+                severity ERROR;
             end if;
           end if;
         end if;
@@ -1914,6 +1958,22 @@ package body tb_dp_pkg is
     end if;
   end proc_dp_verify_data;
 
+  procedure proc_dp_verify_data(constant c_str           : in    string;
+                                constant c_ready_latency : in    natural;
+                                constant c_out_data_max  : in    unsigned;
+                                constant c_out_data_gap  : in    unsigned;
+                                signal   clk             : in    std_logic;
+                                signal   verify_en       : in    std_logic;
+                                signal   out_ready       : in    std_logic;  -- only needed when c_ready_latency = 0
+                                signal   out_val         : in    std_logic;
+                                signal   out_data        : in    std_logic_vector;
+                                signal   prev_out_data   : inout std_logic_vector) is
+  begin
+    proc_dp_verify_data(c_str, c_ready_latency,
+                        c_out_data_max, c_out_data_gap, c_unsigned_1,
+                        clk, verify_en, out_ready, out_val, out_data, prev_out_data);
+  end proc_dp_verify_data;
+
   -- Verify incrementing data that wraps in range 0 ... c_out_data_max
   procedure proc_dp_verify_data(constant c_str           : in    string;
                                 constant c_ready_latency : in    natural;
@@ -1925,7 +1985,9 @@ package body tb_dp_pkg is
                                 signal   out_data        : in    std_logic_vector;
                                 signal   prev_out_data   : inout std_logic_vector) is
   begin
-    proc_dp_verify_data(c_str, c_ready_latency, c_out_data_max, to_unsigned(1,1), clk, verify_en, out_ready, out_val, out_data, prev_out_data);
+    proc_dp_verify_data(c_str, c_ready_latency,
+                        c_out_data_max, c_unsigned_1, c_unsigned_1,
+                        clk, verify_en, out_ready, out_val, out_data, prev_out_data);
   end proc_dp_verify_data;
 
   -- Verify incrementing data
@@ -1938,26 +2000,47 @@ package body tb_dp_pkg is
                                 signal   out_data        : in    std_logic_vector;
                                 signal   prev_out_data   : inout std_logic_vector) is
   begin
-    proc_dp_verify_data(c_str, c_ready_latency, to_unsigned(0,1), to_unsigned(1,1), clk, verify_en, out_ready, out_val, out_data, prev_out_data);
+    proc_dp_verify_data(c_str, c_ready_latency,
+                        c_unsigned_0, c_unsigned_1, c_unsigned_1,
+                        clk, verify_en, out_ready, out_val, out_data, prev_out_data);
   end proc_dp_verify_data;
 
   -- Verify incrementing data with RL > 0 or no flow control
   procedure proc_dp_verify_data(constant c_str           : in    string;
                                 constant c_out_data_max  : in    unsigned;
                                 constant c_out_data_gap  : in    unsigned;
+                                constant c_out_data_gap2 : in    unsigned;
                                 signal   clk             : in    std_logic;
                                 signal   verify_en       : in    std_logic;
                                 signal   out_val         : in    std_logic;
                                 signal   out_data        : in    std_logic_vector;
                                 signal   prev_out_data   : inout std_logic_vector) is
   begin
-    -- Use out_val as void signal to pass on to unused out_ready, because a signal input can not connect a constant or variable
-    proc_dp_verify_data(c_str, 1, c_out_data_max, c_out_data_gap, clk, verify_en, out_val, out_val, out_data, prev_out_data);
+    -- Use out_val as void signal to pass on to unused out_ready, because a
+    -- signal input can not connect a constant or variable.
+    proc_dp_verify_data(c_str, 1,
+                        c_out_data_max, c_out_data_gap, c_out_data_gap2,
+                        clk, verify_en, out_val, out_val, out_data, prev_out_data);
+  end proc_dp_verify_data;
+
+  procedure proc_dp_verify_data(constant c_str           : in    string;
+                                constant c_out_data_max  : in    unsigned;
+                                constant c_out_data_gap  : in    unsigned;
+                                signal   clk             : in    std_logic;
+                                signal   verify_en       : in    std_logic;
+                                signal   out_val         : in    std_logic;
+                                signal   out_data        : in    std_logic_vector;
+                                signal   prev_out_data   : inout std_logic_vector) is
+  begin
+    proc_dp_verify_data(c_str,
+                        c_out_data_max, c_out_data_gap, c_unsigned_1,
+                        clk, verify_en, out_val, out_data, prev_out_data);
   end proc_dp_verify_data;
 
   procedure proc_dp_verify_data(constant c_str           : in    string;
                                 constant c_out_data_max  : in    natural;
                                 constant c_out_data_gap  : in    natural;
+                                constant c_out_data_gap2 : in    natural;
                                 signal   clk             : in    std_logic;
                                 signal   verify_en       : in    std_logic;
                                 signal   out_val         : in    std_logic;
@@ -1965,11 +2048,16 @@ package body tb_dp_pkg is
                                 signal   prev_out_data   : inout std_logic_vector) is
     constant c_data_w : natural := out_data'length;
   begin
-    proc_dp_verify_data(c_str, to_unsigned(c_out_data_max, c_data_w), to_unsigned(c_out_data_gap, c_data_w), clk, verify_en, out_val, out_data, prev_out_data);
+    proc_dp_verify_data(c_str,
+                        to_unsigned(c_out_data_max, c_data_w),
+                        to_unsigned(c_out_data_gap, c_data_w),
+                        to_unsigned(c_out_data_gap2, c_data_w),
+                        clk, verify_en, out_val, out_data, prev_out_data);
   end proc_dp_verify_data;
 
   procedure proc_dp_verify_data(constant c_str           : in    string;
                                 constant c_out_data_max  : in    natural;
+                                constant c_out_data_gap  : in    natural;
                                 signal   clk             : in    std_logic;
                                 signal   verify_en       : in    std_logic;
                                 signal   out_val         : in    std_logic;
@@ -1977,18 +2065,34 @@ package body tb_dp_pkg is
                                 signal   prev_out_data   : inout std_logic_vector) is
     constant c_data_w : natural := out_data'length;
   begin
-    proc_dp_verify_data(c_str, to_unsigned(c_out_data_max, c_data_w), to_unsigned(1, 1), clk, verify_en, out_val, out_data, prev_out_data);
+    proc_dp_verify_data(c_str,
+                        c_out_data_max, c_out_data_gap, 1,
+                        clk, verify_en, out_val, out_data, prev_out_data);
   end proc_dp_verify_data;
 
   procedure proc_dp_verify_data(constant c_str           : in    string;
+                                constant c_out_data_max  : in    natural;
                                 signal   clk             : in    std_logic;
                                 signal   verify_en       : in    std_logic;
                                 signal   out_val         : in    std_logic;
                                 signal   out_data        : in    std_logic_vector;
                                 signal   prev_out_data   : inout std_logic_vector) is
+    constant c_data_w : natural := out_data'length;
   begin
-    -- Use out_val as void signal to pass on to unused out_ready, because a signal input can not connect a constant or variable
-    proc_dp_verify_data(c_str, 1, to_unsigned(0,1), to_unsigned(1,1), clk, verify_en, out_val, out_val, out_data, prev_out_data);
+    proc_dp_verify_data(c_str,
+                        c_out_data_max, 1,
+                        clk, verify_en, out_val, out_data, prev_out_data);
+  end proc_dp_verify_data;
+
+  procedure proc_dp_verify_data(constant c_str           : in    string;
+                                signal   clk             : in    std_logic;
+                                signal   verify_en       : in    std_logic;
+                                signal   out_val         : in    std_logic;
+                                signal   out_data        : in    std_logic_vector;
+                                signal   prev_out_data   : inout std_logic_vector) is
+  begin
+    proc_dp_verify_data(c_str, 0,
+                        clk, verify_en, out_val, out_data, prev_out_data);
   end proc_dp_verify_data;
 
   ------------------------------------------------------------------------------
-- 
GitLab