From 656425661d40e30489f8830a96eace85e74870d2 Mon Sep 17 00:00:00 2001 From: Eric Kooistra <kooistra@astron.nl> Date: Tue, 12 Mar 2024 13:24:22 +0100 Subject: [PATCH] Add and use sdp_crosslets_remote_v2.vhd. --- applications/lofar2/libraries/sdp/hdllib.cfg | 1 + .../sdp/src/vhdl/node_sdp_correlator.vhd | 2 +- .../sdp/src/vhdl/sdp_crosslets_remote_v2.vhd | 273 ++++++++++++++++++ 3 files changed, 275 insertions(+), 1 deletion(-) create mode 100644 applications/lofar2/libraries/sdp/src/vhdl/sdp_crosslets_remote_v2.vhd diff --git a/applications/lofar2/libraries/sdp/hdllib.cfg b/applications/lofar2/libraries/sdp/hdllib.cfg index 73c93d93c0..8369aee4be 100644 --- a/applications/lofar2/libraries/sdp/hdllib.cfg +++ b/applications/lofar2/libraries/sdp/hdllib.cfg @@ -23,6 +23,7 @@ synth_files = src/vhdl/sdp_statistics_offload.vhd src/vhdl/sdp_crosslets_subband_select.vhd src/vhdl/sdp_crosslets_remote.vhd + src/vhdl/sdp_crosslets_remote_v2.vhd src/vhdl/node_sdp_adc_input_and_timing.vhd src/vhdl/node_sdp_filterbank.vhd src/vhdl/node_sdp_oversampled_filterbank.vhd diff --git a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_correlator.vhd b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_correlator.vhd index 9a1d0fe6f2..fa97a9f7d7 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_correlator.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_correlator.vhd @@ -181,7 +181,7 @@ begin --------------------------------------------------------------- -- Local and remote crosslets --------------------------------------------------------------- - u_sdp_crosslets_remote : entity work.sdp_crosslets_remote + u_sdp_crosslets_remote : entity work.sdp_crosslets_remote_v2 generic map ( g_P_sq => g_P_sq ) diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_crosslets_remote_v2.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_crosslets_remote_v2.vhd new file mode 100644 index 0000000000..2f283a3803 --- /dev/null +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_crosslets_remote_v2.vhd @@ -0,0 +1,273 @@ +------------------------------------------------------------------------------- +-- +-- Copyright 2021 +-- 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: R. van der Walle, E. Kooistra +-- Purpose: +-- . Implements the functionality for remote crosslets IO and aligning the +-- local and remote crosslets in the node_sdp_correlator of the LOFAR2 +-- SDPFW design. +-- Description: +-- . Improvement compared to v1 is that in v2 the local crosslets are passed +-- on directly to input 0 of the dp_bsn_align_v2, instead of via the +-- ring_mux and dp_demux. In this way the block period of the reference +-- input 0 remains constant and therefore also of crosslets_sosi.sop. This +-- ensure that there is always constant, and thus enough, time to read the +-- aligned output. via crosslets_copi. +------------------------------------------------------------------------------- + +library IEEE, common_lib, dp_lib, reorder_lib, st_lib, mm_lib, ring_lib; +use IEEE.std_logic_1164.all; +use common_lib.common_pkg.all; +use common_lib.common_mem_pkg.all; +use common_lib.common_network_layers_pkg.all; +use dp_lib.dp_stream_pkg.all; +use ring_lib.ring_pkg.all; +use work.sdp_pkg.all; + +entity sdp_crosslets_remote_v2 is + generic ( + g_P_sq : natural := c_sdp_P_sq + ); + port ( + dp_clk : in std_logic; + dp_rst : in std_logic; + + xsel_sosi : in t_dp_sosi; + from_ri_sosi : in t_dp_sosi := c_dp_sosi_rst; + to_ri_sosi : out t_dp_sosi; + + crosslets_sosi : out t_dp_sosi; + crosslets_copi : in t_mem_copi := c_mem_copi_rst; + crosslets_cipo_arr : out t_mem_cipo_arr(g_P_sq - 1 downto 0); + + mm_rst : in std_logic; + mm_clk : in std_logic; + + reg_bsn_align_copi : in t_mem_copi := c_mem_copi_rst; + reg_bsn_align_cipo : out t_mem_cipo; + reg_bsn_monitor_v2_bsn_align_input_copi : in t_mem_copi := c_mem_copi_rst; + reg_bsn_monitor_v2_bsn_align_input_cipo : out t_mem_cipo; + reg_bsn_monitor_v2_bsn_align_output_copi : in t_mem_copi := c_mem_copi_rst; + reg_bsn_monitor_v2_bsn_align_output_cipo : out t_mem_cipo + ); +end sdp_crosslets_remote_v2; + +architecture str of sdp_crosslets_remote_v2 is + constant c_block_size : natural := c_sdp_N_crosslets_max * c_sdp_S_pn; + constant c_block_size_longwords : natural := ceil_div(c_block_size, 2); -- 32b -> 64b + constant c_data_w : natural := c_sdp_W_crosslet * c_nof_complex; + -- The channel field carries the index of time multiplexed crosslet packets + constant c_use_channel : boolean := true; + constant c_channel_w : natural := ceil_log2(g_P_sq); + -- With 32b data repacked in 64b one empty bit is enough. For crosslets the number + -- of 32b words is c_block_size is even, so empty will be 0 always. However do + -- support odd sizes, to be save. + constant c_use_empty : boolean := true; + constant c_empty_w : natural := 1; + -- The from_ri_sosi only carries correct packets, so error field is not used. + constant c_use_error : boolean := false; + + -- The size for 1 block is probably already enough as the number of blocks received + -- on the remote input of the mux probably have enough gap time in between. Just + -- to be sure to not run into issues in the future, the fifo size is increased to + -- buffer the maximum nof blocks per block period. + constant c_mux_fifo_size : natural := 2**ceil_log2(g_P_sq * c_block_size_longwords); + -- c_repack_fifo_size should be at least c_block_size_longwords / 2, as dp_repack_data + -- unpacks by factor 2 from 64bit to 32bit. Choose 1x to have some room. + constant c_repack_fifo_size : natural := 2**ceil_log2(1 * c_block_size_longwords); + + signal xsel_data_sosi : t_dp_sosi := c_dp_sosi_rst; + signal local_sosi : t_dp_sosi := c_dp_sosi_rst; + signal ring_mux_sosi : t_dp_sosi := c_dp_sosi_rst; + signal ring_mux_siso : t_dp_siso := c_dp_siso_rdy; + signal repack_fifo_sosi : t_dp_sosi := c_dp_sosi_rst; + signal repack_fifo_siso : t_dp_siso := c_dp_siso_rdy; + signal rx_sosi : t_dp_sosi := c_dp_sosi_rst; + signal dispatch_invert_sosi_arr : t_dp_sosi_arr(0 to g_P_sq - 1) := (others => c_dp_sosi_rst); + signal dispatch_sosi_arr : t_dp_sosi_arr(g_P_sq - 1 downto 0) := (others => c_dp_sosi_rst); + signal to_aligner_sosi_arr : t_dp_sosi_arr(g_P_sq - 1 downto 0) := (others => c_dp_sosi_rst); +begin + --------------------------------------------------------------- + -- Repack 32b to 64b + --------------------------------------------------------------- + -- repacking xsel re/im to data field. + p_wire_xsel_sosi : process(xsel_sosi) + begin + xsel_data_sosi <= xsel_sosi; + xsel_data_sosi.data( c_sdp_W_crosslet - 1 downto 0) <= xsel_sosi.re(c_sdp_W_crosslet - 1 downto 0); + xsel_data_sosi.data(c_nof_complex * c_sdp_W_crosslet - 1 downto c_sdp_W_crosslet) <= xsel_sosi.im(c_sdp_W_crosslet - 1 downto 0); + end process; + + u_dp_repack_data_local : entity dp_lib.dp_repack_data + generic map ( + g_in_dat_w => c_data_w, + g_in_nof_words => c_longword_w / c_data_w, + g_out_dat_w => c_longword_w, + g_out_nof_words => 1, + g_pipeline_ready => true -- Needed for src_in.ready to snk_out.ready. + ) + port map ( + rst => dp_rst, + clk => dp_clk, + + snk_in => xsel_data_sosi, + src_out => local_sosi + ); + + --------------------------------------------------------------- + -- ring_mux + --------------------------------------------------------------- + u_ring_mux : entity ring_lib.ring_mux + generic map ( + g_bsn_w => c_dp_stream_bsn_w, + g_data_w => c_longword_w, + g_channel_w => c_word_w, + g_use_error => c_use_error, + g_fifo_size => array_init(c_mux_fifo_size, 2) + ) + port map ( + dp_clk => dp_clk, + dp_rst => dp_rst, + + remote_sosi => from_ri_sosi, + local_sosi => local_sosi, + mux_sosi => ring_mux_sosi, + mux_siso => ring_mux_siso + ); + + to_ri_sosi <= ring_mux_sosi; + + --------------------------------------------------------------- + -- Repack 64b to 32b + --------------------------------------------------------------- + -- FIFO to take backpressure from u_dp_repack_data_rx + u_dp_fifo_sc : entity dp_lib.dp_fifo_sc + generic map ( + g_data_w => c_longword_w, + g_bsn_w => c_dp_stream_bsn_w, + g_empty_w => c_empty_w, + g_channel_w => c_channel_w, + g_use_bsn => true, + g_use_empty => c_use_empty, + g_use_channel => c_use_channel, + g_use_error => c_use_error, + g_use_sync => true, + g_fifo_size => c_repack_fifo_size + ) + port map ( + rst => dp_rst, + clk => dp_clk, + + snk_out => open, + snk_in => from_ri_sosi, + + src_in => repack_fifo_siso, + src_out => repack_fifo_sosi + ); + + u_dp_repack_data_rx : entity dp_lib.dp_repack_data + generic map ( + g_in_dat_w => c_longword_w, + g_in_nof_words => 1, + g_out_dat_w => c_data_w, + g_out_nof_words => c_longword_w / c_data_w, + g_pipeline_ready => true -- Needed for src_in.ready to snk_out.ready. + ) + port map ( + rst => dp_rst, + clk => dp_clk, + + snk_in => repack_fifo_sosi, + snk_out => repack_fifo_siso, + src_out => rx_sosi + ); + + --------------------------------------------------------------- + -- dp_demux + --------------------------------------------------------------- + u_dp_demux : entity dp_lib.dp_demux + generic map ( + g_mode => 0, + g_nof_output => g_P_sq, + g_remove_channel_lo => false, + g_sel_ctrl_invert => true -- TRUE when indexed (g_nof_input-1 DOWNTO 0) + ) + port map ( + rst => dp_rst, + clk => dp_clk, + + snk_in => rx_sosi, + src_out_arr => dispatch_invert_sosi_arr + ); + + dispatch_sosi_arr <= func_dp_stream_arr_reverse_range(dispatch_invert_sosi_arr); + + -- Group local input stream with and remote input streams + to_aligner_sosi_arr(g_P_sq - 1 downto 1) <= dispatch_sosi_arr(g_P_sq - 1 downto 1); + to_aligner_sosi_arr(0) <= xsel_data_sosi; + + --------------------------------------------------------------- + -- dp_bsn_aligner_v2 + --------------------------------------------------------------- + u_mmp_dp_bsn_align_v2 : entity dp_lib.mmp_dp_bsn_align_v2 + generic map( + -- for dp_bsn_align_v2 + g_nof_streams => g_P_sq, + g_bsn_latency_max => 2, + g_nof_aligners_max => 1, -- 1 for Access scheme 3. + g_block_size => c_block_size, + g_data_w => c_data_w, + g_use_mm_output => true, + g_rd_latency => 1, -- Required for st_xst + -- for mms_dp_bsn_monitor_v2 + -- Using c_sdp_N_clk_sync_timeout_xsub as g_nof_clk_per_sync is used for BSN monitor timeout. + g_nof_clk_per_sync => c_sdp_N_clk_sync_timeout_xsub, + g_nof_input_bsn_monitors => g_P_sq, + g_use_bsn_output_monitor => true + ) + port map ( + -- Memory-mapped clock domain + mm_rst => mm_rst, + mm_clk => mm_clk, + + reg_bsn_align_copi => reg_bsn_align_copi, + reg_bsn_align_cipo => reg_bsn_align_cipo, + + reg_input_monitor_copi => reg_bsn_monitor_v2_bsn_align_input_copi, + reg_input_monitor_cipo => reg_bsn_monitor_v2_bsn_align_input_cipo, + + reg_output_monitor_copi => reg_bsn_monitor_v2_bsn_align_output_copi, + reg_output_monitor_cipo => reg_bsn_monitor_v2_bsn_align_output_cipo, + + -- Streaming clock domain + dp_rst => dp_rst, + dp_clk => dp_clk, + + -- Streaming input + in_sosi_arr => to_aligner_sosi_arr, + + -- Output via local MM interface in dp_clk domain, when g_use_mm_output = TRUE. + mm_sosi => crosslets_sosi, + mm_copi => crosslets_copi, + mm_cipo_arr => crosslets_cipo_arr + ); +end str; -- GitLab