From 200a14a99ed09fa868cd3b17c025436fe037bd74 Mon Sep 17 00:00:00 2001
From: Eric Kooistra <kooistra@astron.nl>
Date: Tue, 29 Apr 2025 11:04:22 +0200
Subject: [PATCH] Verify requested dump page range.

---
 .../tb_lofar2_unb2c_sdp_station_tbuf_one.vhd  | 40 ++++++++++++-------
 ...b_tb_lofar2_unb2c_sdp_station_tbuf_one.vhd | 17 +++++++-
 2 files changed, 41 insertions(+), 16 deletions(-)

diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_tbuf_one/tb_lofar2_unb2c_sdp_station_tbuf_one.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_tbuf_one/tb_lofar2_unb2c_sdp_station_tbuf_one.vhd
index 404004d009..1ea793cfff 100644
--- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_tbuf_one/tb_lofar2_unb2c_sdp_station_tbuf_one.vhd
+++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_tbuf_one/tb_lofar2_unb2c_sdp_station_tbuf_one.vhd
@@ -97,9 +97,10 @@ entity tb_lofar2_unb2c_sdp_station_tbuf_one is
     g_rs_record_nof_block      : natural := 10;
     g_rs_nof_periods_per_block : real := 1.17;  -- number of WG periods per rs_block for WG in g_sp
     g_dump_inter_packet_gap    : natural := 0;
-    g_dump_page_offset         : natural := 0;  -- offset relative to recorded_first_page
-    g_dump_nof_pages           : natural := 2;  -- <= c_nof_pages_in_buffer
-    g_dump_enables             : std_logic_vector(c_sdp_A_pn - 1 downto 0) := "000001"
+    g_dump_page_offset         : natural := 1;  -- offset relative to recorded_first_page
+    g_dump_nof_pages           : natural := 2;  -- g_dump_page_offset + g_dump_nof_pages <= c_nof_pages_in_buffer, else
+                                                -- there will occur read RSN errors for pages that are not available
+    g_dump_enables             : std_logic_vector(c_sdp_A_pn - 1 downto 0) := "000010"
   );
   port (
     tb_end : out std_logic
@@ -157,9 +158,10 @@ architecture tb of tb_lofar2_unb2c_sdp_station_tbuf_one is
   constant c_page_meta_size         : natural := func_sdp_tbuf_calculate_page_meta_size(g_rs_block_size);
   constant c_page_size              : natural := c_page_data_size + c_page_meta_size;
   constant c_nof_pages_in_buffer    : natural := func_sdp_tbuf_calculate_nof_pages(c_ddr_buffer_size, c_page_size);
-  constant c_dump_nof_pages         : natural := smallest(g_dump_nof_pages, c_nof_pages_in_buffer);
+  constant c_dump_nof_pages_rw      : natural := g_dump_nof_pages;
+  constant c_dump_nof_pages_actual  : natural := smallest(g_dump_nof_pages, c_nof_pages_in_buffer);
   constant c_bs_start_latency       : natural := c_bs_block_size * 2;
-  constant c_record_min_nof_pages   : natural := g_dump_page_offset + c_dump_nof_pages;
+  constant c_record_min_nof_pages   : natural := g_dump_page_offset + c_dump_nof_pages_rw;
   constant c_record_min_nof_clk     : natural := c_bs_start_latency + g_rs_block_size * c_record_min_nof_pages;
 
   constant c_exp_read_rate_Gbps     : real := func_sdp_tbuf_dump_rate_bps(g_rs_block_size, g_dump_inter_packet_gap) /
@@ -169,8 +171,8 @@ architecture tb of tb_lofar2_unb2c_sdp_station_tbuf_one is
 
   constant c_dump_nof_ai             : natural := vector_sum(g_dump_enables);
   constant c_dump_ai_indices         : t_nat_integer_arr(g_dump_enables'range) := vector_one_indices(g_dump_enables);
-  constant c_read_nof_packets_per_ai : natural := c_dump_nof_pages;
-  constant c_read_total_nof_packets  : natural := c_dump_nof_ai * c_dump_nof_pages;
+  constant c_read_nof_packets_per_ai : natural := c_dump_nof_pages_actual;
+  constant c_read_total_nof_packets  : natural := c_dump_nof_ai * c_dump_nof_pages_actual;
   constant c_read_nof_crc_errors     : natural := sel_a_b(g_verify_crc_error, c_read_total_nof_packets, 0);
   constant c_read_nof_rsn_errors     : natural := sel_a_b(c_verify_err, c_read_total_nof_packets, 0);
   constant c_dump_nof_packets_per_ai : natural := sel_a_b(c_verify_err, 0, c_read_nof_packets_per_ai);
@@ -893,13 +895,15 @@ begin
     variable v_End                : natural;
     variable v_Period             : real := 0.0;
     variable v_dump_rate_Gbps     : real := 0.0;
+    variable v_dump_start_page    : natural;
+    variable v_dump_start_rsn     : std_logic_vector(c_sdp_W_rsn - 1 downto 0);
   begin
     -- Init tbuf_registers_wr record
     tbuf_registers_wr.record_all            <= '1';                      -- 2
     tbuf_registers_wr.record_enable         <= '1';                      -- 3
     tbuf_registers_wr.dump_inter_packet_gap <= g_dump_inter_packet_gap;  -- 11
     tbuf_registers_wr.dump_start_page       <= 0;                        -- 12
-    tbuf_registers_wr.dump_nof_pages        <= c_dump_nof_pages;         -- 13
+    tbuf_registers_wr.dump_nof_pages        <= c_dump_nof_pages_rw;      -- 13
     tbuf_registers_wr.dump_start_rsn        <= (others => 'X');          -- 14
     tbuf_registers_wr.dump_enables          <= (others => '0');          -- 16
 
@@ -970,7 +974,7 @@ begin
     -- Read TBuf state
     mmf_mm_bus_rd(c_mm_file_reg_tbuf, 19, rd_data_state, tb_clk);
     proc_common_wait_some_cycles(tb_clk, 1);
-    v_bool := func_sdp_tbuf_print_state(rd_data_state);
+    v_bool := func_sdp_tbuf_print_state(c_tb_str, rd_data_state);
 
     -- Recording
     proc_common_wait_some_cycles(ext_clk, g_rs_block_size * g_rs_record_nof_block);
@@ -1125,14 +1129,22 @@ begin
         c_mm_clk_period, c_ext_clk_period, c_common_cross_clock_domain_latency * 2);
 
     -- Set dump interval and antenna inputs
-    -- . when g_verify_crc_error then read from last g_dump_nof_pages in the buffer. These pages still contain 0
+    -- . when g_verify_crc_error then read from last c_dump_nof_pages_rw in the buffer. These pages still contain 0,
     --   because they have not been recorded, so these will yield a CRC error (and also a RSN error) for each page.
+    v_dump_start_page := tbuf_registers_ro.recorded_first_page + g_dump_page_offset;
+    if v_dump_start_page >= c_nof_pages_in_buffer then
+      -- Wrap from begin of buffer when v_dump_start_page is just beyond the end of buffer. Do not use modulo
+      -- c_nof_pages_in_buffer to be able to simulate effect of a much to large v_dump_start_page due to
+      -- g_dump_page_offset >= c_nof_pages_in_buffer
+      v_dump_start_page := v_dump_start_page - c_nof_pages_in_buffer;
+    end if;
     tbuf_registers_wr.dump_start_page <= sel_a_b(g_verify_crc_error,
-                                                 c_nof_pages_in_buffer - g_dump_nof_pages,
-                                                 tbuf_registers_ro.recorded_first_page + g_dump_page_offset);
+                                                 c_nof_pages_in_buffer - c_dump_nof_pages_rw,
+                                                 v_dump_start_page);
     -- . when g_verify_rsn_error then write a wrong dump_start_rsn.
-    tbuf_registers_wr.dump_start_rsn <= incr_uvec(tbuf_registers_ro.recorded_first_rsn,
-                                                  g_dump_page_offset * g_rs_block_size + to_int(g_verify_rsn_error));
+    v_dump_start_rsn := incr_uvec(tbuf_registers_ro.recorded_first_rsn, g_dump_page_offset * g_rs_block_size);
+    v_dump_start_rsn := incr_uvec(v_dump_start_rsn, to_int(g_verify_rsn_error));
+    tbuf_registers_wr.dump_start_rsn <= v_dump_start_rsn;
     tbuf_registers_wr.dump_enables <= g_dump_enables;
     proc_common_wait_some_cycles(tb_clk, 1);
     mmf_mm_bus_wr(c_mm_file_reg_tbuf, 12, tbuf_registers_wr.dump_start_page, tb_clk);
diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_tbuf_one/tb_tb_lofar2_unb2c_sdp_station_tbuf_one.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_tbuf_one/tb_tb_lofar2_unb2c_sdp_station_tbuf_one.vhd
index 3b95d29fea..842467a3f5 100644
--- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_tbuf_one/tb_tb_lofar2_unb2c_sdp_station_tbuf_one.vhd
+++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_tbuf_one/tb_tb_lofar2_unb2c_sdp_station_tbuf_one.vhd
@@ -20,8 +20,11 @@
 -- Purpose: Regression multi tb for tb_lofar2_unb2c_sdp_station_tbuf_one
 -- Description:
 -- Usage:
--- > as 4
--- > run -all
+-- . Modelsim:
+--   > as 4
+--   > run -all
+-- . Terminal:
+--   > cat transcript | grep Error:
 
 library IEEE, common_lib;
 use IEEE.std_logic_1164.all;
@@ -96,6 +99,16 @@ begin
       generic map(false, 7, false, false, false, false, 3, 100, 4096, 2000, 3, 1.17, 50, 0, 1, "000011")
       port map (tb_end_vec(7));
 
+  -- g_dump_nof_pages = 10 > c_nof_pages_in_buffer = 7
+  u_dump_nof_pages_limit : entity work.tb_lofar2_unb2c_sdp_station_tbuf_one
+      generic map(false, 8, false, false, false, false, 3, 100, 256, 100, 10, 1.17, 0, 0, 10, "000010")
+      port map (tb_end_vec(8));
+
+  -- g_dump_page_offset + g_dump_nof_pages = 6 + 1 = c_nof_pages_in_buffer = 7
+  u_dump_page_offset_limit : entity work.tb_lofar2_unb2c_sdp_station_tbuf_one
+      generic map(false, 9, false, false, false, false, 3, 100, 256, 100, 10, 1.17, 0, 6, 1, "000010")
+      port map (tb_end_vec(9));
+
   tb_end <= '1' after 1 us when tb_end_vec = c_tb_end_vec else '0';
   proc_common_stop_simulation(tb_end);
 end tb;
-- 
GitLab