From e158fc6c293e8ab4ebc16b647c5a68c8cb04acd8 Mon Sep 17 00:00:00 2001
From: Eric Kooistra <kooistra@astron.nl>
Date: Thu, 21 Sep 2023 09:34:04 +0200
Subject: [PATCH] Correct use of v_busy and rst value.

---
 .../base/dp/src/vhdl/dp_packet_merge.vhd      | 74 +++++++++----------
 1 file changed, 37 insertions(+), 37 deletions(-)

diff --git a/libraries/base/dp/src/vhdl/dp_packet_merge.vhd b/libraries/base/dp/src/vhdl/dp_packet_merge.vhd
index 14dfd8a984..2de0853cc9 100644
--- a/libraries/base/dp/src/vhdl/dp_packet_merge.vhd
+++ b/libraries/base/dp/src/vhdl/dp_packet_merge.vhd
@@ -46,6 +46,8 @@
 -- . with g_align_at_sync=true the merge can be forced to restart at a snk_in.sync.
 -- . Optional flow control dependent on g_use_ready and g_pipeline_ready, see
 --   description of dp_add_flow_control.
+-- . The input packets do not have to have equal length, because they are
+--   merged based on counting their eop.
 
 
 library IEEE,common_lib;
@@ -67,7 +69,7 @@ entity dp_packet_merge is
     rst         : in  std_logic;
     clk         : in  std_logic;
 
-    nof_pkt     : in  std_logic_vector(ceil_log2(g_nof_pkt + 1) - 1 downto 0) := TO_UVEC(g_nof_pkt, ceil_log2(g_nof_pkt + 1));
+    nof_pkt     : in  std_logic_vector(ceil_log2(g_nof_pkt + 1) - 1 downto 0) := to_uvec(g_nof_pkt, ceil_log2(g_nof_pkt + 1));
     nof_pkt_out : out std_logic_vector(ceil_log2(g_nof_pkt + 1) - 1 downto 0);  -- Valid at src_out.sop
 
     snk_out     : out t_dp_siso;
@@ -79,10 +81,13 @@ entity dp_packet_merge is
 end dp_packet_merge;
 
 architecture rtl of dp_packet_merge is
+  constant c_nof_pkt_max : natural := g_nof_pkt + 1;
+  constant c_nof_pkt_w   : natural := ceil_log2(c_nof_pkt_max);
+
   type t_reg is record
-    nof_pkt     : natural range 0 to g_nof_pkt + 1;
-    pkt_cnt     : natural range 0 to g_nof_pkt + 1;
-    align_cnt   : natural range 0 to g_nof_pkt + 1;
+    nof_pkt     : natural range 0 to c_nof_pkt_max;
+    pkt_cnt     : natural range 0 to c_nof_pkt_max;
+    align_cnt   : natural range 0 to c_nof_pkt_max;
     busy        : std_logic;
     sync        : std_logic;
     next_bsn    : std_logic_vector(c_dp_stream_bsn_w - 1 downto 0);
@@ -90,10 +95,12 @@ architecture rtl of dp_packet_merge is
     src_out     : t_dp_sosi;
   end record;
 
+  constant c_reg_rst : t_reg := (0, 0, 0, '0', '0', (others =>'0'), '0', c_dp_sosi_rst);
+
   signal r, nxt_r : t_reg;
 begin
   -- Map logic function outputs to entity outputs
-  nof_pkt_out <= TO_UVEC(r.nof_pkt, ceil_log2(g_nof_pkt + 1));
+  nof_pkt_out <= to_uvec(r.nof_pkt, c_nof_pkt_w);
 
   u_dp_add_flow_control : entity work.dp_add_flow_control
     generic map (
@@ -124,7 +131,7 @@ begin
     v := r;
 
     ----------------------------------------------------------------------------
-    -- Function
+    -- Function: merge input packets into one output packet
     --                       _         _         _         _         _         _            _         _         _
     --   snk_in.sop    _____|0|_______|1|_______|2|_______|0|_______|1|_______|2|__________|0|_______|1|_______|2|_______
     --                               _         _         _         _         _         _            _         _         _
@@ -150,29 +157,6 @@ begin
       end if;
     end if;
 
-    -- capture nof_pkt between output packets when there is no merge busy
-    if snk_in.sop = '1' then
-      v.busy := '1';
-    end if;
-    if snk_in.eop = '1' then
-      if r.pkt_cnt = r.nof_pkt - 1 then
-        v.busy := '0';
-      end if;
-    end if;
-
-    if g_align_at_sync then
-      if snk_in.sync = '1' then
-        if r.pkt_cnt > 0 then
-          v.align_cnt := r.nof_pkt - r.pkt_cnt;  -- = 0 when sync occurs at integer number of merged blocks, > 0 when (re)align to sync is needed
-        end if;
-      end if;
-    end if;
-
-    if v.busy = '0' and v.src_out.eop = '1' then
-      v.nof_pkt := TO_UINT(nof_pkt) - r.align_cnt;  -- use shorter next merge to (re)align to sync (when g_align_at_sync=false then r.align_cnt=0)
-      v.align_cnt := 0;
-    end if;
-
     -- output packet bsn, sync, sop and eop
     v.src_out         := snk_in;
     v.src_out.bsn     := r.src_out.bsn;
@@ -222,6 +206,29 @@ begin
       end if;
     end if;
 
+    -- capture nof_pkt between output packets when there is no merge busy
+    -- . For determining busy, using snk_in.sop is functionally equivalent to
+    --   using v.src_out.sop, but using snk_in.sop may ease timing closure.
+    if snk_in.sop = '1' then
+      v.busy := '1';
+    end if;
+    if v.src_out.eop = '1' then
+      v.busy := '0';
+    end if;
+
+    if g_align_at_sync then
+      if snk_in.sync = '1' then
+        if r.pkt_cnt > 0 then
+          v.align_cnt := r.nof_pkt - r.pkt_cnt;  -- = 0 when sync occurs at integer number of merged blocks, > 0 when (re)align to sync is needed
+        end if;
+      end if;
+    end if;
+
+    if v.busy = '0' then
+      v.nof_pkt := TO_UINT(nof_pkt) - r.align_cnt;  -- use shorter next merge to (re)align to sync (when g_align_at_sync=false then r.align_cnt=0)
+      v.align_cnt := 0;
+    end if;
+
     -- force sosi control to inactive for no output when nof_pkt=0
     if r.nof_pkt = 0 then
       v.src_out.valid := '0';
@@ -234,14 +241,7 @@ begin
     ----------------------------------------------------------------------------
     -- Reset and nxt_r
     if rst = '1' then
-      v.nof_pkt     := TO_UINT(nof_pkt);
-      v.pkt_cnt     := 0;
-      v.align_cnt   := 0;
-      v.busy        := '0';
-      v.sync        := '0';
-      v.next_bsn    := (others => '0');
-      v.bsn_err     := '0';
-      v.src_out     := c_dp_sosi_rst;
+      v := c_reg_rst;
     end if;
 
     nxt_r <= v;
-- 
GitLab