From 75f505c4d8fbda23e68871dc17dd1faacd61aaaa Mon Sep 17 00:00:00 2001 From: Eric Kooistra <kooistra@astron.nl> Date: Thu, 28 Sep 2023 17:22:42 +0200 Subject: [PATCH] Connect streaming data output info per destination index. --- .../vhdl/sdp_bdo_multiple_destinations.vhd | 121 +++++++++++------- 1 file changed, 75 insertions(+), 46 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 1e2b7c0e3d..dc6683df3b 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 @@ -23,11 +23,11 @@ -- Construct beamformer data output (BDO) payloads for multiple destinations. -- Description: -- * The nof_destinations_max determines how to MM control the beamlet packet --- destination(s) MAC/IP/UDP port: +-- destination(s) MAC/IP/UDP: -- . nof_destinations_max = 1 then use sdp_bdo_one_destination.vhd and --- MM program the one destination MAC/IP/UDP port from dp_offload_tx_v3. +-- MM program the one destination MAC/IP/UDP from dp_offload_tx_v3. -- . nof_destinations_max > 1 then use sdp_bdo_multiple_destinations.vhd and --- MM program the one or more destination MAC/IP/UDP port via +-- 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. @@ -72,52 +72,61 @@ entity sdp_bdo_multiple_destinations is dp_clk : in std_logic; dp_rst : in std_logic; + -- MM register reg_destinations_copi : in t_mem_copi; reg_destinations_cipo : out t_mem_cipo; destinations_info : out t_sdp_bdo_destinations_info; + -- Streaming data snk_in : in t_dp_sosi; - src_out : out 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 ); end sdp_bdo_multiple_destinations; architecture str of sdp_bdo_multiple_destinations is - constant c_beamlet_index : natural := g_beamset_id * c_sdp_S_sub_bf; + constant c_beamset_beamlet_index : natural := g_beamset_id * c_sdp_S_sub_bf; -- 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_destination_arr : t_natural_arr(1 to c_m) := func_sdp_bdo_nof_beamlets_per_block_first_destination_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_destination_arr : t_natural_arr(1 to c_m) := func_sdp_bdo_nof_ch_per_packet_first_destination_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_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_nof_ch_per_packet_max : natural := largest(c_nof_ch_per_packet_first_destination_arr); + 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); + -- Reorder all c_sdp_nof_beamlets_per_block = c_sdp_S_sub_bf = 488 beamlets + -- in buffer, such that they appear with first all blocks (= time samples) + -- 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 + -- Dynamic merge, reorder, unmerge packet sizes - -- . default use values for nof_destinations = 1 - signal reorder_nof_blocks : natural := c_reorder_nof_blocks_arr(1); - signal reorder_nof_blocks_slv : std_logic_vector(c_sdp_bdo_reorder_nof_blocks_w - 1 downto 0); - signal reorder_nof_ch : natural := c_reorder_nof_ch_arr(1); - signal nof_beamlets_per_block_first_destination : natural := c_nof_beamlets_per_block_first_destination_arr(1); - signal nof_beamlets_per_block_last_destination : natural := c_nof_beamlets_per_block_last_destination_arr(1); - signal nof_beamlets_per_block : natural; - signal nof_ch_per_packet_first_destination : natural := c_nof_ch_per_packet_first_destination_arr(1); - signal nof_ch_per_packet_last_destination : natural := c_nof_ch_per_packet_last_destination_arr(1); - signal nof_ch_per_packet : natural; - signal nof_ch_per_packet_slv : std_logic_vector(c_nof_ch_per_packet_w - 1 downto 0); - - -- . default use values for nof_destinations = 1 and destination index = 0 - signal beamlet_index_per_destination_bset_0 : natural := c_beamlet_index_per_destination_mat(1, 0); - signal beamlet_index_per_destination : natural := c_beamlet_index + c_beamlet_index_per_destination_mat(1, 0); + 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); + signal nof_ch_per_packet_last_destination : natural; signal select_copi : t_mem_copi := c_mem_copi_rst; signal select_cipo : t_mem_cipo := c_mem_cipo_rst; @@ -132,7 +141,6 @@ architecture str of sdp_bdo_multiple_destinations is signal unmerge_src_out : t_dp_sosi; signal unmerge_word : t_sdp_dual_pol_beamlet_in_word; begin - src_out <= unmerge_src_out; destinations_info <= i_destinations_info; ----------------------------------------------------------------------------- @@ -159,28 +167,45 @@ begin ); ----------------------------------------------------------------------------- - -- Multiple destinations info look up values + -- Look up table values and and output info dependent on DN and DI ----------------------------------------------------------------------------- - -- Pipeline values from look up tables to ease timing closure - p_pipeline : process(dp_clk) + -- 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; - reorder_nof_blocks <= c_reorder_nof_blocks_arr(v_DN); - reorder_nof_ch <= c_reorder_nof_ch_arr(v_DN); - nof_beamlets_per_block_first_destination <= c_nof_beamlets_per_block_first_destination_arr(v_DN); - nof_beamlets_per_block_last_destination <= c_nof_beamlets_per_block_last_destination_arr(v_DN); - v_DI := 0; - beamlet_index_per_destination_bset_0 <= c_beamlet_index_per_destination_mat(v_DN, v_DI); - beamlet_index_per_destination <= c_beamlet_index + beamlet_index_per_destination_bset_0; + v_DI := to_uint(unmerge_src_out.channel); + + -- 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); + nof_beamlets_per_block_first_destinations <= c_nof_beamlets_per_block_first_destinations_arr(s_DN); + 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; - nof_beamlets_per_block <= nof_beamlets_per_block_first_destination; - nof_ch_per_packet <= nof_ch_per_packet_first_destination; - ----------------------------------------------------------------------------- -- dp_packet_merge ----------------------------------------------------------------------------- @@ -259,12 +284,12 @@ begin -- Pass on beamlet data in transposed order select_copi <= r_transpose.select_copi; - p_reorder_transpose : process(dp_rst, select_cipo, reorder_nof_blocks, nof_beamlets_per_block, r_transpose) + p_reorder_transpose : process(dp_rst, select_cipo, reorder_nof_blocks, r_transpose) variable v : t_reorder_transpose; begin if select_cipo.waitrequest = '0' then -- Read from reorder_col_select page - v := func_reorder_transpose(reorder_nof_blocks, nof_beamlets_per_block, r_transpose); + v := func_reorder_transpose(reorder_nof_blocks, c_reorder_nof_beamlets_per_block, r_transpose); else -- No read, new reorder_col_select page not available yet v := c_reorder_transpose_rst; @@ -279,7 +304,11 @@ begin ----------------------------------------------------------------------------- -- dp_packet_unmerge for nof_destinations ----------------------------------------------------------------------------- - nof_ch_per_packet_slv <= to_uvec(nof_ch_per_packet, c_nof_ch_per_packet_w); + 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 ( @@ -292,7 +321,7 @@ begin rst => dp_rst, clk => dp_clk, - pkt_len => nof_ch_per_packet_slv, + pkt_len => nof_ch_per_packet_first_destinations_slv, pkt_len_out => open, -- Valid at src_out.sop snk_in => reorder_src_out, -- GitLab