diff --git a/applications/lofar2/libraries/sdp/hdllib.cfg b/applications/lofar2/libraries/sdp/hdllib.cfg index e09212959838fd74de68ece2c650788786094a3a..bfb5de62ba8bb338a5432ab13b1753df15541057 100644 --- a/applications/lofar2/libraries/sdp/hdllib.cfg +++ b/applications/lofar2/libraries/sdp/hdllib.cfg @@ -16,6 +16,8 @@ synth_files = src/vhdl/sdp_info.vhd src/vhdl/sdp_bdo_pkg.vhd src/vhdl/sdp_bdo_destinations_reg.vhd + src/vhdl/sdp_bdo_one_destination.vhd + src/vhdl/sdp_bdo_multiple_destinations.vhd src/vhdl/sdp_beamformer_output.vhd src/vhdl/sdp_statistics_offload.vhd src/vhdl/sdp_crosslets_subband_select.vhd 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 new file mode 100644 index 0000000000000000000000000000000000000000..9490efb8b0dee55a582acceef05f50a17bc198af --- /dev/null +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_bdo_multiple_destinations.vhd @@ -0,0 +1,205 @@ +------------------------------------------------------------------------------- +-- +-- Copyright 2023 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +------------------------------------------------------------------------------- +-- +-- Author: E. Kooistra +-- Purpose: +-- Construct beamformer data output (BDO) payloads for multiple destinations. +-- Description: +-- Merge, reorder and unmerge beamlet data for N_destinations > 1 from: +-- (int8) [t] [N_blocks_per_packet][S_sub_bf / N_destinations] [N_pol_bf][N_complex] +-- to: +-- (int8) [t] [S_sub_bf / N_destinations][N_blocks_per_packet] [N_pol_bf][N_complex] +-- +-- . where (int8) [N_pol_bf][N_complex] = c_sdp_W_dual_pol_beamlet = 32b +-- dual polarization beamlet word +-- . where N_destinations packets together transport the S_sub_bf beamlets. +-- References: +-- [1] https://support.astron.nl/confluence/display/L2M/L4+SDPFW+Decision%3A+Multiple+beamlet+output+destinations +-- +------------------------------------------------------------------------------- + +library IEEE, common_lib, dp_lib, reorder_lib; + use IEEE.std_logic_1164.all; + use IEEE.numeric_std.all; + use common_lib.common_pkg.all; + use common_lib.common_mem_pkg.all; + use dp_lib.dp_stream_pkg.all; + use reorder_lib.reorder_pkg.all; + use work.sdp_pkg.all; + use work.sdp_bdo_pkg.all; + +entity sdp_bdo_multiple_destinations is + generic ( + g_use_transpose : boolean := false + ); + port ( + dp_clk : in std_logic; + dp_rst : in std_logic; + + snk_in : in t_dp_sosi; + src_out : out t_dp_sosi + ); +end sdp_bdo_multiple_destinations; + +architecture str of sdp_bdo_multiple_destinations is + -- Reorder c_nof_ch = c_nof_ch_sel = c_nof_ch_in + constant c_nof_blocks_per_packet : natural := c_sdp_cep_nof_blocks_per_packet; -- = 4 + constant c_nof_beamlets_per_block : natural := c_sdp_S_sub_bf; -- = 488 dual pol beamlets + constant c_nof_words_per_beamlet : natural := 1; -- 1 dual pol beamlet data per 32b word + constant c_nof_ch : natural := c_nof_blocks_per_packet * c_nof_beamlets_per_block * c_nof_words_per_beamlet; -- = 1952 + + -- Use c_transpose_indices and c_transpose_indices_inv for debug view in Objects window. + -- Use c_transpose_indices for func_reorder_transpose() in this sdp_bdo_multiple_destinations, + -- a tb can then use c_transpose_indices_inv to undo the transpose. + constant c_transpose_indices : t_natural_arr(0 to c_nof_ch - 1) := + func_reorder_transpose_indices(c_nof_blocks_per_packet, + c_nof_beamlets_per_block, + c_nof_words_per_beamlet); + constant c_transpose_indices_inv : t_natural_arr(0 to c_nof_ch - 1) := + func_reorder_transpose_indices(c_nof_beamlets_per_block, + c_nof_blocks_per_packet, + c_nof_words_per_beamlet); + + -- Dynamic reorder block size control input + -- . The data consists of 1 word = 1 ch, because 1 word contains 1 dual pol beamlet. + -- . The input packet has nof_ch of data per packet. + -- . The transposed output packet will have blocks with nof_blocks_per_packet + -- data per block and nof_beamlets_per_block blocks per packet. + signal nof_ch : natural := c_nof_ch; + signal nof_blocks_per_packet : natural := c_nof_blocks_per_packet; + signal nof_beamlets_per_block : natural := c_nof_beamlets_per_block; + signal select_copi : t_mem_copi := c_mem_copi_rst; + signal select_cipo : t_mem_cipo := c_mem_cipo_rst; + signal r_identity : t_reorder_identity; + signal d_identity : t_reorder_identity; + signal r_transpose : t_reorder_transpose; + signal d_transpose : t_reorder_transpose; + + signal merge_src_out : t_dp_sosi; + signal merge_word : t_sdp_dual_pol_beamlet_in_word; + signal reorder_src_out : t_dp_sosi; + signal reorder_word : t_sdp_dual_pol_beamlet_in_word; + signal reorder_busy : std_logic; +begin + src_out <= reorder_src_out; + + ----------------------------------------------------------------------------- + -- dp_packet_merge + ----------------------------------------------------------------------------- + u_dp_packet_merge : entity dp_lib.dp_packet_merge + generic map( + g_use_ready => false, -- no flow control + g_nof_pkt => c_nof_blocks_per_packet, + g_bsn_increment => 1 + ) + port map( + rst => dp_rst, + clk => dp_clk, + snk_in => snk_in, + src_out => merge_src_out + ); + + -- Debug signals for view in Wave window + merge_word <= unpack_data(merge_src_out.data(c_sdp_W_dual_pol_beamlet - 1 downto 0)); + + ----------------------------------------------------------------------------- + -- reorder_col_select + -- . See tb_reorder_col_select_all.vhd for how to control col_select_copi / + -- cipo with p_reorder_identity or p_reorder_transpose. + ----------------------------------------------------------------------------- + u_reorder_col_select : entity reorder_lib.reorder_col_select + generic map ( + g_dsp_data_w => c_sdp_W_dual_pol_beamlet / c_nof_complex, -- = 32b / 2 + g_nof_ch_in => c_nof_ch, + g_nof_ch_sel => c_nof_ch, + g_use_complex => false + ) + port map ( + dp_rst => dp_rst, + dp_clk => dp_clk, + + reorder_busy => reorder_busy, + + -- Dynamic reorder block size control input + nof_ch_in => nof_ch, + nof_ch_sel => nof_ch, + + -- Captured reorder block size control used for output_sosi + output_nof_ch_in => open, + output_nof_ch_sel => open, + + -- Memory Mapped + col_select_mosi => select_copi, + col_select_miso => select_cipo, + + -- Streaming + input_sosi => merge_src_out, + output_sosi => reorder_src_out + ); + + -- Debug signals for view in Wave window + reorder_word <= unpack_data(reorder_src_out.data(c_sdp_W_dual_pol_beamlet - 1 downto 0)); + + -- Use synchronous reset in d signals + p_dp_clk : process(dp_clk) + begin + if rising_edge(dp_clk) then + r_identity <= d_identity; + r_transpose <= d_transpose; + end if; + end process; + + -- Pass on beamlet data in original order or in transposed order + select_copi <= r_transpose.select_copi when g_use_transpose else r_identity.select_copi; + + p_reorder_identity : process(dp_rst, select_cipo, nof_ch, r_identity) + variable v : t_reorder_identity; + begin + if select_cipo.waitrequest = '0' then + -- Read from reorder_col_select page + v := func_reorder_identity(nof_ch, r_identity); + else + -- No read, new reorder_col_select page not available yet + v := c_reorder_identity_rst; + end if; + -- Synchronous reset + if dp_rst = '1' then + v := c_reorder_identity_rst; + end if; + d_identity <= v; + end process; + + p_reorder_transpose : process(dp_rst, select_cipo, nof_blocks_per_packet, nof_beamlets_per_block, r_transpose) + variable v : t_reorder_transpose; + begin + if select_cipo.waitrequest = '0' then + -- Read from reorder_col_select page + v := func_reorder_transpose(nof_blocks_per_packet, nof_beamlets_per_block, r_transpose); + else + -- No read, new reorder_col_select page not available yet + v := c_reorder_transpose_rst; + end if; + -- Synchronous reset + if dp_rst = '1' then + v := c_reorder_transpose_rst; + end if; + d_transpose <= v; + end process; +end str; diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_bdo_one_destination.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_bdo_one_destination.vhd new file mode 100644 index 0000000000000000000000000000000000000000..989cfe606500eec2bce111870a7e13067d3a9def --- /dev/null +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_bdo_one_destination.vhd @@ -0,0 +1,193 @@ +------------------------------------------------------------------------------- +-- +-- Copyright 2023 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +------------------------------------------------------------------------------- +-- +-- Author: E. Kooistra +-- Purpose: +-- Construct beamformer data output (BDO) payload for one destination. +-- Description: +-- . Merge and reorder beamlet data for one destination from: +-- (int8) [t] [N_blocks_per_packet][S_sub_bf] [N_pol_bf][N_complex] +-- to: +-- (int8) [t] [S_sub_bf][N_blocks_per_packet] [N_pol_bf][N_complex] +-- +-- . where (int8) [N_pol_bf][N_complex] = c_sdp_W_dual_pol_beamlet = 32b +-- dual polarization beamlet word +-- References: +-- [1] https://support.astron.nl/confluence/display/L2M/L4+SDPFW+Decision%3A+Multiple+beamlet+output+destinations +-- +------------------------------------------------------------------------------- + +library IEEE, common_lib, dp_lib, reorder_lib; + use IEEE.std_logic_1164.all; + use IEEE.numeric_std.all; + use common_lib.common_pkg.all; + use common_lib.common_mem_pkg.all; + use dp_lib.dp_stream_pkg.all; + use reorder_lib.reorder_pkg.all; + use work.sdp_pkg.all; + use work.sdp_bdo_pkg.all; + +entity sdp_bdo_one_destination is + generic ( + g_use_transpose : boolean := false + ); + port ( + dp_clk : in std_logic; + dp_rst : in std_logic; + + snk_in : in t_dp_sosi; + src_out : out t_dp_sosi + ); +end sdp_bdo_one_destination; + +architecture str of sdp_bdo_one_destination is + -- Reorder c_nof_ch = c_nof_ch_sel = c_nof_ch_in + constant c_nof_blocks_per_packet : natural := c_sdp_cep_nof_blocks_per_packet; -- = 4 + constant c_nof_beamlets_per_block : natural := c_sdp_S_sub_bf; -- = 488 dual pol beamlets + constant c_nof_words_per_beamlet : natural := 1; -- 1 dual pol beamlet data per 32b word + constant c_nof_ch : natural := c_nof_blocks_per_packet * c_nof_beamlets_per_block * c_nof_words_per_beamlet; -- = 1952 + + -- Use c_transpose_indices and c_transpose_indices_inv for debug view in Objects window. + -- Use c_transpose_indices for func_reorder_transpose() in this sdp_bdo_one_destination, + -- a tb can then use c_transpose_indices_inv to undo the transpose. + constant c_transpose_indices : t_natural_arr(0 to c_nof_ch - 1) := + func_reorder_transpose_indices(c_nof_blocks_per_packet, + c_nof_beamlets_per_block, + c_nof_words_per_beamlet); + constant c_transpose_indices_inv : t_natural_arr(0 to c_nof_ch - 1) := + func_reorder_transpose_indices(c_nof_beamlets_per_block, + c_nof_blocks_per_packet, + c_nof_words_per_beamlet); + + -- Dynamic reorder block size control input + -- . The data consists of 1 word = 1 ch, because 1 word contains 1 dual pol beamlet. + -- . The input packet has c_nof_ch of data per packet. + -- . The transposed output packet will have blocks with c_nof_blocks_per_packet + -- data per block and c_nof_beamlets_per_block blocks per packet. + signal select_copi : t_mem_copi := c_mem_copi_rst; + signal select_cipo : t_mem_cipo := c_mem_cipo_rst; + signal r_identity : t_reorder_identity; + signal d_identity : t_reorder_identity; + signal r_transpose : t_reorder_transpose; + signal d_transpose : t_reorder_transpose; + + signal merge_src_out : t_dp_sosi; + signal merge_word : t_sdp_dual_pol_beamlet_in_word; + signal reorder_src_out : t_dp_sosi; + signal reorder_word : t_sdp_dual_pol_beamlet_in_word; + signal reorder_busy : std_logic; +begin + src_out <= reorder_src_out; + + ----------------------------------------------------------------------------- + -- dp_packet_merge + ----------------------------------------------------------------------------- + u_dp_packet_merge : entity dp_lib.dp_packet_merge + generic map( + g_use_ready => false, -- no flow control + g_nof_pkt => c_nof_blocks_per_packet, + g_bsn_increment => 1 + ) + port map( + rst => dp_rst, + clk => dp_clk, + snk_in => snk_in, + src_out => merge_src_out + ); + + -- Debug signals for view in Wave window + merge_word <= unpack_data(merge_src_out.data(c_sdp_W_dual_pol_beamlet - 1 downto 0)); + + ----------------------------------------------------------------------------- + -- reorder_col_select + -- . See tb_reorder_col_select_all.vhd for how to control col_select_copi / + -- cipo with p_reorder_identity or p_reorder_transpose. + ----------------------------------------------------------------------------- + u_reorder_col_select : entity reorder_lib.reorder_col_select + generic map ( + g_dsp_data_w => c_sdp_W_dual_pol_beamlet / c_nof_complex, -- = 32b / 2 + g_nof_ch_in => c_nof_ch, + g_nof_ch_sel => c_nof_ch, + g_use_complex => false + ) + port map ( + dp_rst => dp_rst, + dp_clk => dp_clk, + + reorder_busy => reorder_busy, + + -- Memory Mapped + col_select_mosi => select_copi, + col_select_miso => select_cipo, + + -- Streaming + input_sosi => merge_src_out, + output_sosi => reorder_src_out + ); + + -- Debug signals for view in Wave window + reorder_word <= unpack_data(reorder_src_out.data(c_sdp_W_dual_pol_beamlet - 1 downto 0)); + + -- Use synchronous reset in d signals + p_dp_clk : process(dp_clk) + begin + if rising_edge(dp_clk) then + r_identity <= d_identity; + r_transpose <= d_transpose; + end if; + end process; + + -- Pass on beamlet data in original order or in transposed order + select_copi <= r_transpose.select_copi when g_use_transpose else r_identity.select_copi; + + p_reorder_identity : process(dp_rst, select_cipo, r_identity) + variable v : t_reorder_identity; + begin + if select_cipo.waitrequest = '0' then + -- Read from reorder_col_select page + v := func_reorder_identity(c_nof_ch, r_identity); + else + -- No read, new reorder_col_select page not available yet + v := c_reorder_identity_rst; + end if; + -- Synchronous reset + if dp_rst = '1' then + v := c_reorder_identity_rst; + end if; + d_identity <= v; + end process; + + p_reorder_transpose : process(dp_rst, select_cipo, r_transpose) + variable v : t_reorder_transpose; + begin + if select_cipo.waitrequest = '0' then + -- Read from reorder_col_select page + v := func_reorder_transpose(c_nof_blocks_per_packet, c_nof_beamlets_per_block, r_transpose); + else + -- No read, new reorder_col_select page not available yet + v := c_reorder_transpose_rst; + end if; + -- Synchronous reset + if dp_rst = '1' then + v := c_reorder_transpose_rst; + end if; + d_transpose <= v; + end process; +end str;