From 74436c1155eb4b285b6fb86e52fe1fb62515b11b Mon Sep 17 00:00:00 2001
From: donker <donker@astron.nl>
Date: Thu, 28 Jan 2021 16:21:40 +0100
Subject: [PATCH] L2SDP-200, processed review coment.

---
 applications/lofar2/libraries/sdp/hdllib.cfg  |   3 +-
 .../lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd |   7 +-
 .../sdp/src/vhdl/sdp_statistics_offload.vhd   | 166 +++++++++---------
 .../sdp/tb/vhdl/tb_sdp_statistics_offload.vhd | 147 ++++++++--------
 4 files changed, 157 insertions(+), 166 deletions(-)

diff --git a/applications/lofar2/libraries/sdp/hdllib.cfg b/applications/lofar2/libraries/sdp/hdllib.cfg
index d82f2018d6..97a713a2e7 100644
--- a/applications/lofar2/libraries/sdp/hdllib.cfg
+++ b/applications/lofar2/libraries/sdp/hdllib.cfg
@@ -20,10 +20,11 @@ synth_files =
 
 test_bench_files =
     tb/vhdl/tb_sdp_info.vhd 
-    tb/vhdl/tb_sdp_statistics_offload.vhd 
+    tb/vhdl/tb_sdp_statistics_offload.vhd
 
 regression_test_vhdl = 
     tb/vhdl/tb_sdp_info.vhd
+    tb/vhdl/tb_sdp_statistics_offload.vhd 
 
 [modelsim_project_file]
 
diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd
index 15e3a26778..a1a5d34b4c 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd
@@ -96,6 +96,11 @@ PACKAGE sdp_pkg is
   CONSTANT c_sdp_W_gn_id         : NATURAL := 5;
   CONSTANT c_sdp_N_pn_lb         : NATURAL := 16;
 
+  -- 
+  CONSTANT c_sdp_marker_sst : NATURAL := 83;  -- = 0x53 = 'S'
+  CONSTANT c_sdp_marker_bst : NATURAL := 66;  -- = 0x42 = 'B'
+  CONSTANT c_sdp_marker_xst : NATURAL := 88;  -- = 0x58 = 'X'
+
   -- AIT constants
   CONSTANT c_sdp_ait_buf_nof_data_jesd : NATURAL := 1024; -- 1024 14 bit samples fit in one M20k BRAM 
   CONSTANT c_sdp_ait_buf_nof_data_bsn  : NATURAL := 1024; -- 1024 14 bit samples fit in one M20k BRAM
@@ -246,7 +251,7 @@ PACKAGE sdp_pkg is
       ( field_name_pad("sdp_data_id"                             ), "RW", 32, field_default(0) ),
       ( field_name_pad("sdp_nof_signal_inputs"                   ), "RW",  8, field_default(0) ),
       ( field_name_pad("sdp_nof_bytes_per_statistics"            ), "RW",  8, field_default(8) ),
-      ( field_name_pad("sdp_nof_statistics_per_package"          ), "RW", 16, field_default(0) ),
+      ( field_name_pad("sdp_nof_statistics_per_packet"           ), "RW", 16, field_default(0) ),
       ( field_name_pad("sdp_block_period"                        ), "RW", 16, field_default(0) ),
       
       ( field_name_pad("dp_bsn"                                  ), "RW", 64, field_default(0) )
diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd
index c02c5797be..5b6e55b792 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd
@@ -29,27 +29,6 @@
 -- https://support.astron.nl/confluence/pages/viewpage.action?spaceKey=L2M&title=L5+SDPFW+Design+Document%3A+Subband+filterbank
 -- https://plm.astron.nl/polarion/#/project/LOFAR2System/wiki/L2%20Interface%20Control%20Documents/SC%20to%20SDP%20ICD
 --
--- Remark:
--- . Offload SST, BST or XST data from the memory to a network interface
---   get data from mm bus and assemble header from from other input settings
---
---   A processing node (PN) in the ring ia called a ring node (RN).
--- 
---   g_statistics_type = "SST"   
---     data_id.signal_input_index = rn_id * S_pn
---     nof_signal_inputs = 1
---     nof_statistics_per_packet = N_sub
---
---   g_statistics_type = "BST"
---     data_id.beamlet_index = g_beamset_index * S_sub_bf
---     nof_signal_inputs = 0 (default not used)
---     nof_statistics_per_packet = S_sub_bf
---
---   g_statistics_type = "XST"
---     data_id.signal_input_A_index = rn_id * S_pn
---     data_id.signal_input_B_index = function of correlator cell instance and rn_id * S_pn
---     nof_signal_inputs = S_pn => 12 (fixed)
---     nof_statistics_per_packet = S_pn * S_pn => 12 * 12 = 144
 -------------------------------------------------------------------------------
 
 LIBRARY IEEE, common_lib, mm_lib, dp_lib;
@@ -75,20 +54,23 @@ ENTITY sdp_statistics_offload IS
     dp_clk : IN  STD_LOGIC;
     dp_rst : IN  STD_LOGIC;
 
-    -- from MM master multiplexer
+    -- Memory access to statistics values
     master_mosi : OUT  t_mem_mosi;  -- := c_mem_mosi_rst;
     master_miso : IN t_mem_miso;
 
+    -- Memory access to read/write settings
     reg_enable_mosi : IN  t_mem_mosi := c_mem_mosi_rst;
     reg_enable_miso : OUT t_mem_miso;
 
     reg_hdr_dat_mosi : IN  t_mem_mosi := c_mem_mosi_rst;
     reg_hdr_dat_miso : OUT t_mem_miso;
 
-    in_sosi     : IN t_dp_sosi;  -- from selector (sst_sosi_arr[0])
+    -- Input timing regarding the integration interval of the statistics
+    in_sosi     : IN t_dp_sosi;
     
-    out_sosi    : OUT t_dp_sosi;  -- output from SST UDP offload (sst_udp_sosi)
-    out_siso    : IN t_dp_siso;   -- input from SST UDP offload (sst_udp_siso)
+    -- Streaming output of offloaded statistics packets
+    out_sosi    : OUT t_dp_sosi;
+    out_siso    : IN t_dp_siso;
 
     -- inputs from other blocks
     eth_src_mac  : IN STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0);
@@ -103,15 +85,32 @@ END sdp_statistics_offload;
 
 ARCHITECTURE str OF sdp_statistics_offload IS
 
-  CONSTANT c_marker                     : NATURAL := sel_a_b((g_statistics_type="BST"), 66, sel_a_b((g_statistics_type="XST"), 88, 83));  -- based on g_statistics_type: 'S'=0x53="SST", 'B'=0x42="BST", 'X'=0x58="XST"
-  CONSTANT c_data_size                  : NATURAL := 2;
-  CONSTANT c_step_size                  : NATURAL := 4;
-  CONSTANT c_nof_data                   : NATURAL := 512;
-  CONSTANT c_block_size                 : NATURAL := c_nof_data * c_data_size * (c_step_size / c_data_size);
-  CONSTANT c_nof_streams                : NATURAL := 1;
-  CONSTANT c_nof_signal_inputs          : NATURAL := sel_a_b(g_statistics_type="BST", 0, sel_a_b(g_statistics_type="XST", c_sdp_S_pn, 1));
-  CONSTANT c_nof_statistics_per_package : NATURAL := sel_a_b(g_statistics_type="BST", c_sdp_S_sub_bf, sel_a_b(g_statistics_type="XST", (c_sdp_S_pn*c_sdp_S_pn*c_nof_complex), c_sdp_N_sub));
-  CONSTANT c_beamlet_id                 : NATURAL := g_beamset_id * c_sdp_S_sub_bf;
+  CONSTANT c_step_size                 : NATURAL := 4;
+  CONSTANT c_nof_data                  : NATURAL := 512;
+  CONSTANT c_block_size                : NATURAL := c_nof_data * c_step_size;
+  
+
+  CONSTANT c_nof_streams               : NATURAL := 1;
+  CONSTANT c_data_size                 : NATURAL := 2;
+  CONSTANT c_nof_data_per_step         : NATURAL := 2;
+  CONSTANT c_nof_packets               : NATURAL := sel_a_b(g_statistics_type="BST", 1,
+                                                    sel_a_b(g_statistics_type="XST", c_sdp_S_pn,
+                                                                                     c_sdp_S_pn));  -- SST
+  
+  CONSTANT c_marker                    : NATURAL := sel_a_b(g_statistics_type="BST", c_sdp_marker_bst,
+                                                    sel_a_b(g_statistics_type="XST", c_sdp_marker_xst,
+                                                                                     c_sdp_marker_sst));
+  
+  CONSTANT c_nof_signal_inputs         : NATURAL := sel_a_b(g_statistics_type="BST", 0,
+                                                    sel_a_b(g_statistics_type="XST", c_sdp_S_pn,
+                                                                                     1));  -- SST
+  
+  CONSTANT c_nof_statistics_per_packet : NATURAL := sel_a_b(g_statistics_type="BST",  c_sdp_S_sub_bf,
+                                                    sel_a_b(g_statistics_type="XST", (c_sdp_S_pn * c_sdp_S_pn * c_nof_complex), 
+                                                                                      c_sdp_N_sub));  -- SST
+  
+  
+  CONSTANT c_beamlet_id                : NATURAL := g_beamset_id * c_sdp_S_sub_bf;
 
   TYPE t_reg IS RECORD
     block_count    : NATURAL;
@@ -119,27 +118,26 @@ ARCHITECTURE str OF sdp_statistics_offload IS
     start_pulse    : STD_LOGIC;
     dp_header_info : STD_LOGIC_VECTOR(1023 DOWNTO 0);
     data_id        : STD_LOGIC_VECTOR(31 DOWNTO 0);
-    last_mm_done   : STD_LOGIC;
+    nof_cycles_dly : NATURAL;
+    payload_err    : STD_LOGIC;
+    interval_cnt   : NATURAL;
   END RECORD;
 
-  CONSTANT c_reg_rst : t_reg := (0, 0, '0', (OTHERS => '0'), (OTHERS => '0'), '0');
+  CONSTANT c_reg_rst : t_reg := (0, 0, '0', (OTHERS => '0'), (OTHERS => '0'), 0, '0', 0);
 
   SIGNAL r : t_reg;
   SIGNAL d : t_reg;
 
   SIGNAL trigger                  : STD_LOGIC := '0';
-  SIGNAL nof_cycles_dly           : NATURAL   := 0;
   SIGNAL mm_done                  : STD_LOGIC := '0';
   SIGNAL dp_block_from_mm_src_out : t_dp_sosi;
   SIGNAL dp_block_from_mm_src_in  : t_dp_siso;
   
   SIGNAL dp_header_info           : STD_LOGIC_VECTOR(1023 DOWNTO 0):= (OTHERS => '0');
-  SIGNAL payload_err              : STD_LOGIC := '0';
-  SIGNAL integration_interval_cnt : NATURAL   := 0;
-  SIGNAL integration_interval     : STD_LOGIC_VECTOR(23 DOWNTO 0) := (OTHERS => '0');
-  SIGNAL bsn_at_sync              : STD_LOGIC_VECTOR(63 DOWNTO 0) := x"f0f0f0f0f0f0f0f0"; -- (OTHERS => '0');
+  SIGNAL integration_interval     : NATURAL   := 0;
+  SIGNAL bsn_at_sync              : STD_LOGIC_VECTOR(63 DOWNTO 0) := (OTHERS => '0');
 
-  SIGNAL sdp_data_id : STD_LOGIC_VECTOR(31 DOWNTO 0);
+  --SIGNAL sdp_data_id : STD_LOGIC_VECTOR(31 DOWNTO 0);
   
 BEGIN
   p_bsn_at_sync : PROCESS(in_sosi)
@@ -149,31 +147,10 @@ BEGIN
     END IF;
   END PROCESS;
 
-  -- count number of sop's in a sync interval
-  p_integration_interval : PROCESS(in_sosi)
-    VARIABLE v_cnt : NATURAL;
-  BEGIN
-    v_cnt := integration_interval_cnt;
-    IF in_sosi.sync = '1' THEN
-      integration_interval <= TO_UVEC(v_cnt, integration_interval'LENGTH);
-      integration_interval_cnt <= 0;
-    ELSE
-      IF in_sosi.sop = '1' THEN
-        integration_interval_cnt <= v_cnt + 1;
-      END IF;
-    END IF;
-  END PROCESS;
-
   -- get payload errors and keep them till next sync
   p_payload_error : PROCESS(in_sosi)
-    VARIABLE v_err : STD_LOGIC;
   BEGIN
-    v_err := payload_err;
-    IF in_sosi.sync = '1' THEN
-      payload_err <= '0';
-    ELSE
-      payload_err <= v_err OR in_sosi.err(0);
-    END IF;
+    
   END PROCESS;
 
   -------------------------------------------------------------------------------
@@ -189,22 +166,19 @@ BEGIN
   dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "sdp_source_info_nyquist_zone_id"         ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr,  "sdp_source_info_nyquist_zone_id"         )) <= sdp_info.nyquist_zone_index;
   dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "sdp_source_info_f_adc"                   ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr,  "sdp_source_info_f_adc"                   )) <= SLV(sdp_info.f_adc);
   dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "sdp_source_info_fsub_type"               ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr,  "sdp_source_info_fsub_type"               )) <= SLV(sdp_info.fsub_type);
-  dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "sdp_source_info_payload_error"           ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr,  "sdp_source_info_payload_error"           )) <= SLV(payload_err);
+  dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "sdp_source_info_payload_error"           ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr,  "sdp_source_info_payload_error"           )) <= SLV(r.payload_err);
   dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "sdp_source_info_beam_repositioning_flag" ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr,  "sdp_source_info_beam_repositioning_flag" )) <= SLV(sdp_info.beam_repositioning_flag);
   dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "sdp_source_info_subband_calibrated_flag" ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr,  "sdp_source_info_subband_calibrated_flag" )) <= SLV(sdp_info.subband_calibrated_flag);
   dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "sdp_source_info_reserved"                ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr,  "sdp_source_info_reserved"                )) <= (OTHERS => '0');
   dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "sdp_source_info_gn_id"                   ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr,  "sdp_source_info_gn_id"                   )) <= TO_UVEC(gn_index, 5);
   dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "sdp_reserved"                            ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr,  "sdp_reserved"                            )) <= (OTHERS => '0');
-  dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "sdp_integration_interval"                ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr,  "sdp_integration_interval"                )) <= integration_interval;
-  dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "sdp_data_id"                             ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr,  "sdp_data_id"                             )) <= sdp_data_id;
+  dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "sdp_integration_interval"                ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr,  "sdp_integration_interval"                )) <= TO_UVEC(integration_interval, 24);
+  dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "sdp_data_id"                             ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr,  "sdp_data_id"                             )) <= r.data_id;
   dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "sdp_nof_signal_inputs"                   ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr,  "sdp_nof_signal_inputs"                   )) <= TO_UVEC(c_nof_signal_inputs, 8);
-  dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "sdp_nof_statistics_per_package"          ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr,  "sdp_nof_statistics_per_package"          )) <= TO_UVEC(c_nof_statistics_per_package, 16);
+  dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "sdp_nof_statistics_per_packet"           ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr,  "sdp_nof_statistics_per_packet"           )) <= TO_UVEC(c_nof_statistics_per_packet, 16);
   dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "sdp_block_period"                        ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr,  "sdp_block_period"                        )) <= sdp_info.block_period;
   dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "dp_bsn"                                  ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr,  "dp_bsn"                                  )) <= bsn_at_sync; 
 
-  nof_cycles_dly <= gn_index * g_offload_time;
-  sdp_data_id    <= r.data_id;
-
   p_reg : PROCESS(dp_rst, dp_clk)
   BEGIN
     IF dp_rst='1' THEN
@@ -214,12 +188,24 @@ BEGIN
     END IF;
   END PROCESS;
 
-  p_control_packet_offload : PROCESS(r, trigger, mm_done)
+  p_control_packet_offload : PROCESS(r, gn_index, in_sosi, trigger, mm_done, dp_header_info)
   BEGIN
     d <= r;
-    d.start_pulse   <= '0';
-    d.last_mm_done  <= mm_done;
+    d.start_pulse    <= '0';
+    d.nof_cycles_dly <= gn_index * g_offload_time;
     
+    -- Count number of sop's in a sync interval and get payload errors and keep them till next sync.
+    IF in_sosi.sync = '1' THEN
+      integration_interval <= r.interval_cnt;
+      d.interval_cnt <= 0;
+      d.payload_err  <= '0';
+    ELSE
+      d.payload_err <= r.payload_err OR in_sosi.err(0);
+      IF in_sosi.sop = '1' THEN
+        d.interval_cnt <= r.interval_cnt + 1;
+      END IF;
+    END IF;
+
     -- assign sdp_data_id for different statistic types
     IF g_statistics_type = "SST" THEN
       d.data_id <= x"000000" & TO_UVEC(r.block_count, 8);
@@ -231,26 +217,32 @@ BEGIN
       d.data_id <= x"00000000";
     END IF;
 
-    IF mm_done = '1' AND r.last_mm_done = '0' THEN
-      IF r.block_count + 1 < c_sdp_S_pn THEN
-        d.block_count <= r.block_count + 1;
-        IF r.block_count mod 2 = 0 THEN
-          d.start_address <= r.block_count / 2 * c_block_size;
+    -- Issue start_pulse per packet offload
+    IF trigger = '1' THEN
+      -- Use trigger to start first packet
+      d.start_pulse   <= '1';
+      d.start_address <= 0;
+      d.block_count   <= 1;
+    ELSIF mm_done = '1' THEN
+      -- Use mm_done to start next packets
+      IF r.block_count < c_nof_packets THEN
+        IF r.block_count MOD c_nof_data_per_step = 0 THEN
+          d.start_address <= r.start_address + c_data_size;  -- step to next packet within block
         ELSE 
-          d.start_address <= r.start_address + c_data_size; 
+          d.start_address <= r.block_count / c_nof_data_per_step * c_block_size;  -- jump to first packet in next block
         END IF;
         d.start_pulse <= '1';
+        d.block_count <= r.block_count + 1;
       ELSE
-        d.start_address <= 0; 
+        -- prepare for next trigger interval, this is in fact don't care, because trigger will start
+        -- next offload interval, but may ease interpretation in the wave window
+        d.start_address <= 0;
         d.block_count   <= 0;
       END IF;
     END IF;
 
-    IF trigger = '1' AND r.block_count = 0 THEN
-      d.start_pulse <= '1';
-    END IF;
-
-    IF mm_done = '1' THEN
+    -- Release header info per packet offload
+    IF trigger = '1' OR mm_done = '1' THEN
       d.dp_header_info <= dp_header_info;
     END IF;
   END PROCESS;
@@ -266,7 +258,7 @@ BEGIN
     reg_enable_mosi => reg_enable_mosi,
     reg_enable_miso => reg_enable_miso,
 
-    delay           => nof_cycles_dly,
+    delay           => r.nof_cycles_dly,
     trigger         => in_sosi.sync,
     trigger_dly     => trigger
   );
diff --git a/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_statistics_offload.vhd b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_statistics_offload.vhd
index 5d27c9cf57..5588d7978d 100644
--- a/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_statistics_offload.vhd
+++ b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_statistics_offload.vhd
@@ -23,11 +23,11 @@
 -- Author: P. Donker
 
 -- Purpose:
--- . test bench for sdp_info.vhd (and sdp_info_reg.vhd)
+-- . test bench for sdp_statistics_offload.vhd
 -- Description:
---
--- https://plm.astron.nl/polarion/#/project/LOFAR2System/workitem?id=LOFAR2-9258
--- https://plm.astron.nl/polarion/#/project/LOFAR2System/workitem?id=LOFAR2-8855
+-- 
+-- https://support.astron.nl/confluence/display/L2M/L5+SDPFW+Design+Document%3A+Subband+filterbank
+--    see Figure 4.8
 --
 -- Remark:
 -- .
@@ -65,14 +65,14 @@ ARCHITECTURE tb OF tb_sdp_statistics_offload IS
   CONSTANT c_udp_src_port : STD_LOGIC_VECTOR(c_network_udp_port_w-1 DOWNTO 0) := x"D001";
 
   -- used mm_adresses on mm bus "enable_mosi/miso"
-  CONSTANT c_mm_addr_enable   : NATURAL := 0;
+  CONSTANT c_reg_enable_mm_addr_enable : NATURAL := 0;
   -- used mm_adresses on mm bus "hdr_dat_mosi/miso"
-  CONSTANT c_mm_addr_eth_src_mac  : NATURAL := 1;
-  CONSTANT c_mm_addr_ip_src_addr  : NATURAL := 13;
-  CONSTANT c_mm_addr_udp_src_port : NATURAL := 15;
+  CONSTANT c_hdr_dat_mm_addr_eth_src_mac  : NATURAL := 1;
+  CONSTANT c_hdr_dat_mm_addr_ip_src_addr  : NATURAL := 13;
+  CONSTANT c_hdr_dat_mm_addr_udp_src_port : NATURAL := 15;
   
-  -- used test ram size: c_nof_clk_per_block = c_nof_data * c_data_size * (c_step_size / c_data_size) => 512 * 2 * (4 / 2) = 2048 words per pair of signal inputs;
-  -- with 12 signal input, 6 pairs (blocks) we will fill 2 blocks for testing 2 * 2048 = 4096 = 
+  -- SST RAM size and structure: c_nof_clk_per_block = c_nof_data * c_data_size * (c_step_size / c_data_size) => 512 * 2 * (4 / 2) = 2048 words per pair of signal inputs;
+  --    with 12 signal input, 6 pairs (blocks) we will fill 2 blocks for testing 2 * 2048 = 4096 words
   CONSTANT c_nof_data  : NATURAL := 512;
   CONSTANT c_data_size : NATURAL := 2;
   CONSTANT c_step_size : NATURAL := 4;
@@ -85,11 +85,22 @@ ARCHITECTURE tb OF tb_sdp_statistics_offload IS
   CONSTANT c_nof_clk_per_block : NATURAL := c_nof_data * c_data_size;
 
   -- based on g_statistics_type: 'S'=0x53="SST", 'B'=0x42="BST", 'X'=0x58="XST"
-  CONSTANT c_marker                     : NATURAL := sel_a_b((g_statistics_type="BST"), 66            , sel_a_b((g_statistics_type="XST"), 88, 83));  
-  CONSTANT c_nof_signal_inputs          : NATURAL := sel_a_b((g_statistics_type="BST"), 0             , sel_a_b((g_statistics_type="XST"), c_sdp_S_pn, 1));
-  CONSTANT c_nof_statistics_per_package : NATURAL := sel_a_b((g_statistics_type="BST"), c_sdp_S_sub_bf, sel_a_b((g_statistics_type="XST"), (c_sdp_S_pn*c_sdp_S_pn*c_nof_complex), c_sdp_N_sub));
+  CONSTANT c_marker                    : NATURAL := sel_a_b(g_statistics_type="BST", c_sdp_marker_bst,
+                                                    sel_a_b(g_statistics_type="XST", c_sdp_marker_xst, 
+                                                                                     c_sdp_marker_sst));  -- SST
+
+  CONSTANT c_nof_signal_inputs         : NATURAL := sel_a_b(g_statistics_type="BST", 0,
+                                                    sel_a_b(g_statistics_type="XST", c_sdp_S_pn,
+                                                                                     1));  -- SST
+
+  CONSTANT c_nof_statistics_per_packet : NATURAL := sel_a_b(g_statistics_type="BST",  c_sdp_S_sub_bf,
+                                                    sel_a_b(g_statistics_type="XST", (c_sdp_S_pn * c_sdp_S_pn * c_nof_complex),
+                                                                                      c_sdp_N_sub));  -- SST
 
-  CONSTANT c_nof_clk_in_valid : NATURAL := c_nof_data * c_data_size + 1;  -- +1 for cmem_ram_rd_latency
+  CONSTANT c_nof_valid_per_block : NATURAL := c_nof_data * c_data_size;
+
+  CONSTANT c_nof_sync         : NATURAL := 5;
+  CONSTANT c_nof_clk_per_sync : NATURAL := c_nof_block_per_sync * c_nof_clk_per_block;
 
   SIGNAL tb_end              : STD_LOGIC := '0';
 
@@ -115,9 +126,6 @@ ARCHITECTURE tb OF tb_sdp_statistics_offload IS
   SIGNAL offload_sosi        : t_dp_sosi;
   SIGNAL offload_siso        : t_dp_siso := c_dp_siso_rst;
 
-  SIGNAL link_offload_sosi           : t_dp_sosi := c_dp_sosi_rst;
-  SIGNAL link_offload_siso           : t_dp_siso;
-
   SIGNAL test_offload_sosi   : t_dp_sosi := c_dp_sosi_rst;
   SIGNAL test_offload_siso   : t_dp_siso;
 
@@ -162,7 +170,6 @@ BEGIN
   mm_rst <= '1', '0' AFTER c_mm_clk_period*7;
   mm_clk <= (NOT mm_clk) OR tb_end AFTER c_mm_clk_period/2;
 
-  
   -- fill ram with data, data is same as address number.
   p_mm_statistics_ram : PROCESS
   BEGIN
@@ -188,16 +195,16 @@ BEGIN
   BEGIN
     proc_common_wait_until_high(mm_clk, init_ram_done);
     -- enable common variabel delay
-    proc_mem_mm_bus_wr(c_mm_addr_enable, 1, mm_clk, enable_miso, enable_mosi);  
+    proc_mem_mm_bus_wr(c_reg_enable_mm_addr_enable, 1, mm_clk, enable_miso, enable_mosi);  
     proc_common_wait_some_cycles(mm_clk, c_cross_clock_domain_latency);
     WAIT;
   END PROCESS;
 
-  -- dp_offload_tx_v3.vhd can handle 32 data that is not alligned, dp_offload_rx can not.
-  -- this is the reason the firts 16bit of the header are always zero.
-  -- this process will start counting with bit16 high, the firt bit that wil be received
-  -- on each dp_clk bsn is incremented with 0xffff, if you look at B63..b16 it looks like normal counting
-  -- if dp_offload_rx.vhd is fixed this can be set normal again.
+  -- Module dp_offload_tx_v3.vhd can handle 32 data that is not aligned, dp_offload_rx can not.
+  -- This is the reason the first 16bit of the header are always zero.
+  -- This process will start counting with bit16 high, the first bit that wil be received,
+  -- on each dp_clk the bsn is incremented with 0x10000, if you look at b63..b16 it looks like normal counting.
+  -- If dp_offload_rx.vhd is fixed this can be set normal again.
   p_in_sosi : PROCESS
   BEGIN
     proc_common_wait_until_low(dp_clk, dp_rst);
@@ -216,7 +223,7 @@ BEGIN
           END IF;
           IF j = 0 THEN
             in_sosi.sop  <= '1';
-            in_sosi.bsn  <= INCR_UVEC(in_sosi.bsn, 65535);
+            in_sosi.bsn  <= INCR_UVEC(in_sosi.bsn, 65536);
           END IF;
           IF j = c_nof_clk_per_block-1 THEN
             in_sosi.eop  <= '1';
@@ -231,7 +238,7 @@ BEGIN
   p_verify_header : PROCESS
   BEGIN
     proc_common_wait_until_high(mm_clk, init_ram_done);
-    proc_common_wait_until_high(mm_clk, test_offload_sosi.eop);
+    proc_common_wait_until_high(mm_clk, test_offload_sosi.sop);
     -- bsn is not fully received (bit 0-15 is missing) because 32 bit allignment not working in dp_offload_rx.vhd.   
     -- check fixed settings
     ASSERT rx_hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "eth_dst_mac") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "eth_dst_mac")) = x"00074306C700"
@@ -278,8 +285,8 @@ BEGIN
       REPORT "wrong sdp_marker" SEVERITY ERROR;
     ASSERT rx_hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "sdp_nof_signal_inputs") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_nof_signal_inputs")) = TO_UVEC(c_nof_signal_inputs, 8)
       REPORT "wrong sdp_nof_signal_inputs" SEVERITY ERROR;
-    ASSERT rx_hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "sdp_nof_statistics_per_package") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_nof_statistics_per_package")) = TO_UVEC(c_nof_statistics_per_package, 8)
-      REPORT "wrong sdp_nof_statistics_per_package" SEVERITY ERROR;
+    ASSERT rx_hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "sdp_nof_statistics_per_packet") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_nof_statistics_per_packet")) = TO_UVEC(c_nof_statistics_per_packet, 16)
+      REPORT "wrong sdp_nof_statistics_per_packet: " SEVERITY ERROR;
     
     -- check some values from sdp_source_info
     ASSERT rx_hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "sdp_observation_id") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_observation_id")) = sdp_info.observation_id
@@ -303,53 +310,54 @@ BEGIN
     WAIT;
   END PROCESS;
 
- p_verify : PROCESS(in_sosi.sync, test_offload_sosi, rx_hdr_fields_raw)
+  -- verify number of blocks between 2 syncs and between 2 changed bsn numbers 
+  p_verify_nof_blocks : PROCESS(rx_bsn, rx_block_cnt, dp_clk, in_sosi.sync, test_offload_sosi, rx_hdr_fields_raw)
     VARIABLE v_bsn       : NATURAL;
     VARIABLE v_block_cnt : NATURAL;
   BEGIN
     v_bsn       := rx_bsn;
     v_block_cnt := rx_block_cnt;
-    
-    IF init_ram_done = '1' THEN
-      IF in_sosi.sync = '1' AND rx_block_cnt > 0 THEN
-        ASSERT rx_block_cnt = g_nof_signal_inputs_per_pn REPORT "wrong number of blocks between 2 sync" SEVERITY ERROR;
-      END IF;
-
-      IF test_offload_sosi.sop = '1' AND v_block_cnt = g_nof_signal_inputs_per_pn THEN
-        v_block_cnt := 0;
-      END IF;
-
-      IF test_offload_sosi.eop = '1' THEN
-        -- check info by p_in_sosi why +16 is used
+    IF rising_edge(dp_clk) THEN
+      IF init_ram_done = '1' THEN
+        
+        IF in_sosi.sync = '1' AND rx_block_cnt > 0 THEN
+          ASSERT rx_block_cnt = g_nof_signal_inputs_per_pn REPORT "wrong number of blocks between 2 sync" SEVERITY ERROR;
+        END IF;
+        
         v_bsn := TO_UINT(rx_hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "dp_bsn") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "dp_bsn")+16));
-        v_block_cnt := v_block_cnt + 1;
         IF rx_bsn > 0 AND v_bsn > rx_bsn THEN
           ASSERT (v_bsn - rx_bsn) = c_nof_block_per_sync REPORT "wrong number of blocks between 2 bsn numbers" SEVERITY ERROR;
         END IF;
-      END IF;
 
-      rx_data_id <= TO_UINT(rx_hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "sdp_data_id") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_data_id")));
+        rx_data_id <= TO_UINT(rx_hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "sdp_data_id") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_data_id")));
+        IF test_offload_sosi.eop = '1' THEN
+          ASSERT rx_data_id = rx_block_cnt REPORT "block count number in sdp_data_id not same as counted blocks" SEVERITY ERROR;
+        END IF;
+
+        IF test_offload_sosi.sop = '1' AND rx_block_cnt = g_nof_signal_inputs_per_pn THEN
+          v_block_cnt := 0;
+        ELSIF test_offload_sosi.eop = '1' THEN
+          v_block_cnt := v_block_cnt + 1;
+        END IF;
+
+      END IF;
+      test_offload_siso <= c_dp_siso_rdy;
+      rx_bsn            <= v_bsn;
+      rx_block_cnt      <= v_block_cnt;
     END IF;
-    test_offload_siso <= c_dp_siso_rdy;
-    rx_bsn            <= v_bsn;
-    rx_block_cnt      <= v_block_cnt;
   END PROCESS;
 
   p_verify_valid : PROCESS(dp_clk)
-    VARIABLE v_cnt : NATURAL;
   BEGIN
-    v_cnt := rx_valid_clk_cnt;
     IF rising_edge(dp_clk) THEN
-      IF test_offload_sosi.valid = '1' THEN
-        v_cnt := v_cnt + 1;
+      IF test_offload_sosi.sop = '1' THEN
+        rx_valid_clk_cnt <= 1;
+      ELSIF test_offload_sosi.eop = '1' THEN
+        ASSERT rx_valid_clk_cnt = c_nof_valid_per_block REPORT "wrong number of clock counts while valid" SEVERITY ERROR;
       ELSE
-        IF v_cnt > 0 THEN
-          ASSERT v_cnt = c_nof_clk_in_valid REPORT "wrong number of clock counts while valid" SEVERITY ERROR;
-          v_cnt := 0;
-        END IF;
+        rx_valid_clk_cnt <= rx_valid_clk_cnt + 1;
       END IF;
     END IF;
-    rx_valid_clk_cnt <= v_cnt; 
   END PROCESS; 
 
   p_mm_offload : PROCESS
@@ -357,36 +365,21 @@ BEGIN
     proc_common_wait_until_low(mm_clk, mm_rst);
     proc_common_wait_some_cycles(mm_clk, 10);
     -- write ethernet destinations via reg_hdr_dat_mosi
-    proc_mem_mm_bus_wr(c_mm_addr_udp_src_port, TO_UINT(c_udp_src_port), mm_clk, hdr_dat_miso, hdr_dat_mosi);  
+    proc_mem_mm_bus_wr(c_hdr_dat_mm_addr_udp_src_port, TO_UINT(c_udp_src_port), mm_clk, hdr_dat_miso, hdr_dat_mosi);  
     proc_common_wait_some_cycles(mm_clk, c_cross_clock_domain_latency);
     
-    proc_mem_mm_bus_wr(c_mm_addr_ip_src_addr, TO_UINT(c_ip_src_addr), mm_clk, hdr_dat_miso, hdr_dat_mosi);  
+    proc_mem_mm_bus_wr(c_hdr_dat_mm_addr_ip_src_addr, TO_UINT(c_ip_src_addr), mm_clk, hdr_dat_miso, hdr_dat_mosi);  
     proc_common_wait_some_cycles(mm_clk, c_cross_clock_domain_latency);
     
-    proc_mem_mm_bus_wr(c_mm_addr_eth_src_mac, TO_UINT(c_eth_src_mac), mm_clk, hdr_dat_miso, hdr_dat_mosi);  
+    proc_mem_mm_bus_wr(c_hdr_dat_mm_addr_eth_src_mac, TO_UINT(c_eth_src_mac), mm_clk, hdr_dat_miso, hdr_dat_mosi);  
     proc_common_wait_some_cycles(mm_clk, c_cross_clock_domain_latency);
     WAIT;
   END PROCESS;
 
-  p_link_offload : PROCESS(offload_sosi, in_sosi)
-  BEGIN
-    offload_siso <= c_dp_siso_rst;
-    IF init_ram_done = '1' THEN
-      link_offload_sosi       <= c_dp_sosi_rst;
-      link_offload_sosi.data  <= offload_sosi.data;
-      link_offload_sosi.empty <= offload_sosi.empty;
-      link_offload_sosi.valid <= offload_sosi.valid;
-      link_offload_sosi.sop   <= offload_sosi.sop;
-      link_offload_sosi.eop   <= offload_sosi.eop;
-      
-      offload_siso <= c_dp_siso_rdy;
-    END IF;
-  END PROCESS;
-  
   p_dp_end : PROCESS
   BEGIN
     proc_common_wait_until_high(mm_clk, init_ram_done);
-    proc_common_wait_some_cycles(dp_clk, 100000);  -- will show 4 sync periods
+    proc_common_wait_some_cycles(dp_clk, c_nof_sync * c_nof_clk_per_sync);  -- will show 4 sync periods
     tb_end <= '1';
     WAIT;
   END PROCESS;
@@ -430,8 +423,8 @@ BEGIN
     reg_hdr_dat_mosi      => offload_rx_hdr_dat_mosi,
     reg_hdr_dat_miso      => offload_rx_hdr_dat_miso,
   
-    snk_in_arr(0)         => link_offload_sosi,
-    snk_out_arr(0)        => link_offload_siso,
+    snk_in_arr(0)         => offload_sosi,
+    snk_out_arr(0)        => offload_siso,
                
     src_out_arr(0)        => test_offload_sosi,
     src_in_arr(0)         => test_offload_siso,
-- 
GitLab