From 037c4f79f96bc4f400b3e0b08e33c68f14f982e9 Mon Sep 17 00:00:00 2001
From: Eric Kooistra <kooistra@astron.nl>
Date: Mon, 14 Aug 2023 13:16:41 +0200
Subject: [PATCH] Add verification.

---
 .../tb/vhdl/tb_reorder_col_select_all.vhd     | 135 +++++++++++-------
 1 file changed, 81 insertions(+), 54 deletions(-)

diff --git a/libraries/base/reorder/tb/vhdl/tb_reorder_col_select_all.vhd b/libraries/base/reorder/tb/vhdl/tb_reorder_col_select_all.vhd
index 506795c4dc..b6aff9b06c 100644
--- a/libraries/base/reorder/tb/vhdl/tb_reorder_col_select_all.vhd
+++ b/libraries/base/reorder/tb/vhdl/tb_reorder_col_select_all.vhd
@@ -48,9 +48,10 @@ entity tb_reorder_col_select_all is
   generic(
     g_dsp_data_w            : natural := 16;  -- complex data width, = c_data_w / 2
     g_nof_sync              : natural := 1;
-    g_nof_packets_per_sync  : natural := 1;
-    g_nof_blocks_per_packet : natural := 4;
+    g_nof_packets_per_sync  : natural := 3;
+    g_nof_blocks_per_packet : natural := 5;
     g_nof_data_per_block    : natural := 3;
+    g_inter_packet_gap      : natural := 0;
     g_use_complex           : boolean := false
   );
 end tb_reorder_col_select_all;
@@ -61,51 +62,60 @@ architecture tb of tb_reorder_col_select_all is
   constant c_clk_period   : time := 10 ns;
   constant c_rl           : natural := 1;
 
-  constant c_use_data     : boolean := not g_use_complex;
-  constant c_data_w       : natural := c_nof_complex * g_dsp_data_w;
-  constant c_nof_ch       : natural := g_nof_blocks_per_packet * g_nof_data_per_block;
+  constant c_use_data       : boolean := not g_use_complex;
+  constant c_data_w         : natural := c_nof_complex * g_dsp_data_w;
+  constant c_nof_ch         : natural := g_nof_blocks_per_packet * g_nof_data_per_block;
+  constant c_nof_blocks_max : natural:= largest(g_nof_blocks_per_packet, g_nof_data_per_block) + 1;
+  constant c_addr_max       : natural := c_nof_ch + c_nof_blocks_max;
+  constant c_cnt_max        : natural := c_nof_blocks_max;
+
+  -- Total output latency for transpose and undo transpose
+  constant c_retrieve_lat   : natural := 2;  -- rd latency of reorder_col_select
+  constant c_output_lat     : natural := (c_nof_ch + c_retrieve_lat) * 2;
 
   type t_transpose is record
     select_copi  : t_mem_copi;
-    addr         : natural range 0 to c_nof_ch + g_nof_data_per_block;
-    blk_cnt      : natural range 0 to g_nof_blocks_per_packet;
-    data_cnt     : natural range 0 to g_nof_data_per_block;
+    addr         : natural range 0 to c_addr_max;
+    blk_cnt      : natural range 0 to c_cnt_max;
+    data_cnt     : natural range 0 to c_cnt_max;
   end record;
 
   constant c_transpose_rst : t_transpose := (c_mem_copi_rst, 0, 0, 0);
 
   -- The p_comb_transpose and p_comb_undo_transpose can both use
   -- func_transpose(), by swapping the transpose dimensions. For
-  -- example, with
-  -- . g_nof_blocks_per_packet = 4 and
-  -- . g_nof_data_per_block = 3
+  -- example, to get transposed output with:
+  -- . g_nof_blocks_per_packet = 3 and
+  -- . g_nof_data_per_block = 5
   -- the p_comb_transpose selects:
   --
-  --   v.blk_cnt:      0        1        2        3
-  --   v.data_cnt:     0  1  2  0  1  2  0  1  2  0  1  2
-  --   ch:             0  1  2  3  4  5  6  7  8  9 10 11
-  --   data_in         0  1  2  3  4  5  6  7  8  9 10 11  -- in_sosi
-  --   transpose:      0        3        6        9
-  --                      1        4        7       10
-  --                         2        5        8       11
-  --   v.addr          0  3  6  9  1  4  7 10  2  5  8 11
-  --   data_out        0  3  6  9  1  4  7 10  2  5  8 11  -- transposed_sosi
+  --   v.blk_cnt:      0              1              2
+  --   v.data_cnt:     0  1  2  3  4  0  1  2  3  4  0  1  2  3  4
+  --   ch:             0  1  2  3  4  5  6  7  8  9 10 11 12 13 14
+  --   data_in         0  1  2  3  4  5  6  7  8  9 10 11 12 13 14  -- in_sosi
+  --   transpose:      0        3        6        9       12
+  --                      1        4        7       10       13
+  --                         2        5        8       11       14
+  --   v.addr          0  3  6  9 12  1  4  7 10 13  2  5  8 11 14
+  --   data_out        0  3  6  9 12  1  4  7 10 13  2  5  8 11 14  -- transposed_sosi
   --
-  -- and then with swapped parameter values:
-  -- . g_nof_blocks_per_packet = 3 and
-  -- . g_nof_data_per_block = 4
+  -- and then with swapped parameter values, to get untransposed
+  -- output back (= original input order):
+  -- . g_nof_blocks_per_packet = 5 and
+  -- . g_nof_data_per_block = 3
   -- the p_comb_undo_transpose selects:
   --
-  --   v.blk_cnt:      0           1           2
-  --   v.data_cnt:     0  1  2  3  0  1  2  3  0  1  2  3
-  --   ch:             0  1  2  3  4  5  6  7  8  9 10 11
-  --   data_in         0  3  6  9  1  4  7 10  2  5  8 11  -- transposed_sosi
-  --   undo_transpose: 0           4           8
-  --                      1           5           9
-  --                         2           6           10
-  --                            3           7          11
-  --   v.addr:         0  4  8  1  5  9  2  6 10  3  7 11
-  --   data_out:       0  1  2  3  4  5  6  7  8  9 10 11  -- out_sosi
+  --   v.blk_cnt:      0        1        2        3        4
+  --   v.data_cnt:     0  1  2  0  1  2  0  1  2  0  1  2  0  1  2
+  --   ch:             0  1  2  3  4  5  6  7  8  9 10 11 12 13 14
+  --   data_in         0  3  6  9 12  1  4  7 10 13  2  5  8 11 14  -- transposed_sosi
+  --   undo_transpose: 0              1              2
+  --                      3              4              5
+  --                         6              7              8
+  --                            9             10             11
+  --                              12             13             14
+  --   v.addr:         0  5 10  1  6 11  2  7 12  3  8 13  4  9 14
+  --   data_out:       0  1  2  3  4  5  6  7  8  9 10 11 12 13 14  -- out_sosi
   --
   -- to restore the original order.
   function func_transpose(constant c_nof_blocks_per_packet : natural;
@@ -118,13 +128,16 @@ architecture tb of tb_reorder_col_select_all is
     v.select_copi.address := TO_MEM_ADDRESS(v.addr);
     v.select_copi.rd := '1';
     -- prepare next read address
-    if v.blk_cnt < c_nof_blocks_per_packet - 1 then
+    if v.blk_cnt <= c_nof_blocks_per_packet - 1 then
       if v.data_cnt < c_nof_data_per_block - 1 then
         v.data_cnt := v.data_cnt + 1;
-        v.addr := v.addr + c_nof_data_per_block;
+        v.addr := v.addr + c_nof_blocks_per_packet;
       else
         v.data_cnt := 0;
         v.blk_cnt := v.blk_cnt + 1;
+        if v.blk_cnt = c_nof_blocks_per_packet then
+          v.blk_cnt := 0;
+        end if;
         v.addr := v.blk_cnt;
       end if;
     else
@@ -145,7 +158,8 @@ architecture tb of tb_reorder_col_select_all is
   signal in_siso         : t_dp_siso := c_dp_siso_rdy;  -- used for proc_dp_gen_block_data
   signal transposed_sosi : t_dp_sosi;
   signal out_sosi        : t_dp_sosi;
-  signal expected_sosi   : t_dp_sosi;
+  signal in_sosi_dly     : t_dp_sosi := c_dp_sosi_rst;
+  signal expected_sosi   : t_dp_sosi := c_dp_sosi_rst;
 
   -- Reorder and undo reorder control
   signal nof_ch           : natural range 0 to c_nof_ch := c_nof_ch;
@@ -167,6 +181,7 @@ begin
     variable v_data : natural := 0;
   begin
     proc_common_wait_until_low(clk, rst);
+    proc_common_wait_some_cycles(clk, 5);
 
     -- Run some sync intervals with counter data in the packets
     -- proc_dp_gen_block_data(
@@ -186,49 +201,50 @@ begin
     --   signal   in_en            : in  std_logic;  -- when '0' then no valid output even when src_in is ready
     --   signal   src_in           : in  t_dp_siso;
     --   signal   src_out          : out t_dp_sosi);
-    wait until rising_edge(clk);
     for I in 0 to g_nof_sync - 1 loop
-      -- first block in sync interval
+      -- First packet in sync interval
       proc_dp_gen_block_data(c_rl,
                              c_use_data,
                              g_dsp_data_w,
                              g_dsp_data_w,
-                             v_data,
-                             v_data,
-                             v_data + 1,
+                             v_data,      -- data
+                             v_data,      -- re
+                             v_data + 1,  -- im
                              c_nof_ch,
-                             0,
-                             0,
+                             v_data + 2,  -- channel
+                             v_data + 3,  -- error
                              '1',  -- with sync
-                             v_bsn,
+                             v_bsn,  -- bsn
                              clk,
                              in_en,
                              in_siso,
                              in_sosi);
+      proc_common_wait_some_cycles(clk, g_inter_packet_gap);
       for J in 0 to g_nof_packets_per_sync - 2 loop
-        -- next blocks in sync interval
+        -- Next packets in sync interval
         v_bsn := INCR_UVEC(v_bsn, 1);
         v_data := v_data + c_nof_ch;
         proc_dp_gen_block_data(c_rl,
                                c_use_data,
                                g_dsp_data_w,
                                g_dsp_data_w,
-                               v_data,
-                               v_data,
-                               v_data + 1,
+                               v_data,      -- data
+                               v_data,      -- re
+                               v_data + 1,  -- im
                                c_nof_ch,
-                               0,
-                               0,
+                               v_data + 2,  -- channel
+                               v_data + 3,  -- error
                                '0',  -- no sync
-                               v_bsn,
+                               v_bsn,  -- bsn
                                clk,
                                in_en,
                                in_siso,
                                in_sosi);
+        proc_common_wait_some_cycles(clk, g_inter_packet_gap);
       end loop;
     end loop;
     in_sosi <= c_dp_sosi_rst;
-    proc_common_wait_some_cycles(clk, c_nof_ch);
+    proc_common_wait_some_cycles(clk, c_nof_ch * 2);
     proc_common_wait_some_cycles(clk, 10);
     tb_end <= '1';
     wait;
@@ -238,6 +254,17 @@ begin
   -- Verification
   ------------------------------------------------------------------------------
 
+  in_sosi_dly <= transport in_sosi after c_output_lat * c_clk_period;
+  expected_sosi <= in_sosi_dly when rising_edge(clk);
+
+  p_verify : process(rst, clk)
+  begin
+    if rst = '1' then
+    elsif rising_edge(clk) then
+      proc_dp_verify_sosi_equal(g_use_complex, out_sosi, expected_sosi);
+    end if;
+  end process;
+
   ------------------------------------------------------------------------------
   -- DUT
   ------------------------------------------------------------------------------
@@ -249,7 +276,7 @@ begin
   begin
     if select_cipo.waitrequest = '0' then
       -- Read from reorder_col_select page
-      v := func_transpose(g_nof_blocks_per_packet, g_nof_data_per_block, r_transpose);
+      v := func_transpose(g_nof_data_per_block, g_nof_blocks_per_packet, r_transpose);
     else
       -- No read, new reorder_col_select page not available yet
       v := c_transpose_rst;
@@ -266,7 +293,7 @@ begin
   begin
     if undo_select_cipo.waitrequest = '0' then
       -- Read from reorder_col_select page
-      v := func_transpose(g_nof_data_per_block, g_nof_blocks_per_packet, r_undo_transpose);
+      v := func_transpose(g_nof_blocks_per_packet, g_nof_data_per_block, r_undo_transpose);
     else
       -- No read, new reorder_col_select page not available yet
       v := c_transpose_rst;
-- 
GitLab