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