From b4b66ef9f5de819b03aa271ab463b37d2f6eaeee Mon Sep 17 00:00:00 2001
From: Eric Kooistra <kooistra@astron.nl>
Date: Tue, 3 Oct 2023 17:10:41 +0200
Subject: [PATCH] Correct unmerge BSN increment = 0. Capture look up values for
 DN.

---
 .../vhdl/sdp_bdo_multiple_destinations.vhd    | 74 +++++++------------
 1 file changed, 25 insertions(+), 49 deletions(-)

diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_bdo_multiple_destinations.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_bdo_multiple_destinations.vhd
index dc6683df3b..9beecbdf2d 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_bdo_multiple_destinations.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_bdo_multiple_destinations.vhd
@@ -30,8 +30,11 @@
 --     MM program the one or more destination MAC/IP/UDP via
 --     sdp_bdo_destinations_reg.
 -- * Get nof_destinations from sdp_bdo_destinations_reg. The nof_destinations
---   is MM programmable between 1 and nof_destinations_max.
--- * The nof_blocks_per_packet is not MM programmable, but based on
+--   is MM programmable between 1 and nof_destinations_max. The
+--   nof_destinations must be in range 1:g_nof_destinations_max, then
+--   nof_destinations_act = nof_destinations, as defined in
+--   sdp_bdo_destinations_reg.
+-- * The nof_blocks_per_packet is not MM programmable, but based on DN =
 --   nof_destinations to ensure that the packet fits in a jumbo frame or
 --   equal to c_sdp_bdo_reorder_nof_blocks_max to make maximum use of the
 --   available reorder buffer size.
@@ -82,11 +85,10 @@ entity sdp_bdo_multiple_destinations is
     snk_in   : in  t_dp_sosi;
     src_out  : out t_dp_sosi;
 
-    -- Streaming data output info per destination index
-    destination_index                      : out natural;
-    nof_blocks_per_packet                  : out natural;
-    nof_beamlets_per_block_per_destination : out natural;
-    beamlet_index_per_destination          : out natural
+    -- Streaming data output info dependent on DN = nof_destinations
+    nof_blocks_per_packet                     : out natural;
+    nof_beamlets_per_block_first_destinations : out natural;
+    nof_beamlets_per_block_last_destination   : out natural
   );
 end sdp_bdo_multiple_destinations;
 
@@ -95,15 +97,12 @@ architecture str of sdp_bdo_multiple_destinations is
 
   -- Look up table constants as function of nof_destinations in range(g_nof_destinations_max)
   constant c_m                                             : natural := g_nof_destinations_max;
-  constant c_reorder_nof_blocks_arr                        : t_natural_arr(1 to c_m) := func_sdp_bdo_reorder_nof_blocks_look_up_table(g_nof_destinations_max);
-  constant c_reorder_nof_ch_arr                            : t_natural_arr(1 to c_m) := func_sdp_bdo_reorder_nof_ch_look_up_table(g_nof_destinations_max);
-  constant c_nof_beamlets_per_block_first_destinations_arr : t_natural_arr(1 to c_m) := func_sdp_bdo_nof_beamlets_per_block_first_destinations_look_up_table(g_nof_destinations_max);
-  constant c_nof_beamlets_per_block_last_destination_arr   : t_natural_arr(1 to c_m) := func_sdp_bdo_nof_beamlets_per_block_last_destination_look_up_table(g_nof_destinations_max);
-  constant c_nof_ch_per_packet_first_destinations_arr      : t_natural_arr(1 to c_m) := func_sdp_bdo_nof_ch_per_packet_first_destinations_look_up_table(g_nof_destinations_max);
-  constant c_nof_ch_per_packet_last_destination_arr        : t_natural_arr(1 to c_m) := func_sdp_bdo_nof_ch_per_packet_last_destination_look_up_table(g_nof_destinations_max);
-
-  constant c_beamlet_index_per_destination_mat : t_natural_matrix(1 to c_m, 0 to c_m - 1) :=
-                                                   func_sdp_bdo_beamlet_index_per_destination_look_up_matrix(g_nof_destinations_max);
+  constant c_reorder_nof_blocks_arr                        : t_natural_arr(1 to c_m) := func_sdp_bdo_reorder_nof_blocks_look_up_table(c_m);
+  constant c_reorder_nof_ch_arr                            : t_natural_arr(1 to c_m) := func_sdp_bdo_reorder_nof_ch_look_up_table(c_m);
+  constant c_nof_beamlets_per_block_first_destinations_arr : t_natural_arr(1 to c_m) := func_sdp_bdo_nof_beamlets_per_block_first_destinations_look_up_table(c_m);
+  constant c_nof_beamlets_per_block_last_destination_arr   : t_natural_arr(1 to c_m) := func_sdp_bdo_nof_beamlets_per_block_last_destination_look_up_table(c_m);
+  constant c_nof_ch_per_packet_first_destinations_arr      : t_natural_arr(1 to c_m) := func_sdp_bdo_nof_ch_per_packet_first_destinations_look_up_table(c_m);
+  constant c_nof_ch_per_packet_last_destination_arr        : t_natural_arr(1 to c_m) := func_sdp_bdo_nof_ch_per_packet_last_destination_look_up_table(c_m);
 
   constant c_nof_ch_per_packet_max  : natural := largest(c_nof_ch_per_packet_first_destinations_arr);
   constant c_nof_ch_per_packet_w    : natural := ceil_log2(c_nof_ch_per_packet_max + 1);
@@ -113,19 +112,18 @@ architecture str of sdp_bdo_multiple_destinations is
   -- for beamlet index 0 and last all blocks for beamlet index 477.
   constant c_reorder_nof_beamlets_per_block       : natural := c_sdp_nof_beamlets_per_block;
 
-  signal i_destinations_info     : t_sdp_bdo_destinations_info;
-
-  signal s_DN  : natural range 1 to g_nof_destinations_max;      -- number of destinations
-  signal s_DI  : natural range 0 to g_nof_destinations_max - 1;  -- destination index
+  signal i_destinations_info : t_sdp_bdo_destinations_info;
+  signal s_DN                : natural range 1 to g_nof_destinations_max;  -- number of destinations
 
   -- Dynamic merge, reorder, unmerge packet sizes
   signal reorder_nof_blocks                        : natural;
   signal reorder_nof_blocks_slv                    : std_logic_vector(c_sdp_bdo_reorder_nof_blocks_w - 1 downto 0);
   signal reorder_nof_ch                            : natural;
-  signal nof_beamlets_per_block_first_destinations : natural;
-  signal nof_beamlets_per_block_last_destination   : natural;
   signal nof_ch_per_packet_first_destinations      : natural;
   signal nof_ch_per_packet_first_destinations_slv  : std_logic_vector(c_nof_ch_per_packet_w - 1 downto 0);
+  -- The nof_ch_per_packet_last_destination is used only for view in Wave
+  -- window, because dp_packet_unmerge automatically will output that number
+  -- of remaining number of ch for the last block.
   signal nof_ch_per_packet_last_destination        : natural;
 
   signal select_copi            : t_mem_copi := c_mem_copi_rst;
@@ -142,6 +140,8 @@ architecture str of sdp_bdo_multiple_destinations is
   signal unmerge_word           : t_sdp_dual_pol_beamlet_in_word;
 begin
   destinations_info <= i_destinations_info;
+  nof_blocks_per_packet <= reorder_nof_blocks;
+  src_out <= unmerge_src_out;
 
   -----------------------------------------------------------------------------
   -- Multiple destinations info register
@@ -167,18 +167,15 @@ begin
     );
 
   -----------------------------------------------------------------------------
-  -- Look up table values and and output info dependent on DN and DI
+  -- Register look up table values dependent on DN to ease timing closure
   -----------------------------------------------------------------------------
-  -- Register values to ease timing closure
   p_reg : process(dp_clk)
     variable v_DN : natural;  -- number of destinations
-    variable v_DI : natural;  -- destination index
   begin
     if rising_edge(dp_clk) then
       v_DN := i_destinations_info.nof_destinations_act;
-      v_DI := to_uint(unmerge_src_out.channel);
 
-      -- Constant values that depend on DN = nof_destinations_act set via MM
+      -- Semi constant values that depend on DN = nof_destinations_act set via MM
       s_DN <= v_DN;
       reorder_nof_blocks                        <= c_reorder_nof_blocks_arr(s_DN);
       reorder_nof_ch                            <= c_reorder_nof_ch_arr(s_DN);
@@ -186,23 +183,6 @@ begin
       nof_beamlets_per_block_last_destination   <= c_nof_beamlets_per_block_last_destination_arr(s_DN);
       nof_ch_per_packet_first_destinations      <= c_nof_ch_per_packet_first_destinations_arr(s_DN);
       nof_ch_per_packet_last_destination        <= c_nof_ch_per_packet_last_destination_arr(s_DN);
-      -- . output info
-      nof_blocks_per_packet <= reorder_nof_blocks;
-
-      -- Variable values that depend on DN set via MM and on current DI of
-      -- dp_packet_unmerge output destination channel
-      s_DI <= v_DI;
-      -- . output info
-      destination_index <= v_DI;
-      beamlet_index_per_destination <= c_beamset_beamlet_index + c_beamlet_index_per_destination_mat(s_DN, v_DI);
-      if v_DI < s_DN - 1 then
-        nof_beamlets_per_block_per_destination <= nof_beamlets_per_block_first_destinations;
-      else
-        nof_beamlets_per_block_per_destination <= nof_beamlets_per_block_last_destination;
-      end if;
-
-      -- Register src_out to time align output info with src_out.sop
-      src_out <= unmerge_src_out;
     end if;
   end process;
 
@@ -306,16 +286,12 @@ begin
   -----------------------------------------------------------------------------
   nof_ch_per_packet_first_destinations_slv <= to_uvec(nof_ch_per_packet_first_destinations, c_nof_ch_per_packet_w);
 
-  -- The nof_ch_per_packet_last_destination is used only for view in Wave
-  -- window, because dp_packet_unmerge automatically will output that number
-  -- of remaining number of ch for the last block.
-
   u_dp_packet_unmerge : entity dp_lib.dp_packet_unmerge
     generic map (
       g_use_ready     => false,  -- no flow control
       g_nof_pkt       => g_nof_destinations_max,
       g_pkt_len       => c_nof_ch_per_packet_max,
-      g_bsn_increment => 1
+      g_bsn_increment => 0
     )
     port map (
       rst     => dp_rst,
-- 
GitLab