Skip to content
Snippets Groups Projects

Clarify g_nof_destinations_max design revision parameter and package constants...

Merged Eric Kooistra requested to merge L2SDP-964 into master
1 file
+ 43
31
Compare changes
  • Side-by-side
  • Inline
@@ -20,7 +20,7 @@
-------------------------------------------------------------------------------
--
-- Author: R. van der Walle, E. Kooistra (payload error support)
-- Author: R. van der Walle, E. Kooistra
-- Purpose:
-- The beamformer data output (BDO) packetizes the beamlet data into UDP/IP packets.
-- Description: see references
@@ -46,10 +46,13 @@ use work.sdp_bdo_pkg.all;
entity sdp_beamformer_output is
generic (
g_beamset_id : natural := 0;
g_use_transpose : boolean := false;
g_use_multiple_destinations : boolean := false;
g_sim_force_bsn_error : boolean := true
g_beamset_id : natural := 0;
-- For g_nof_destinations_max > 1 the transpose is always used
-- For g_nof_destinations_max = 1 then the transpose is only used
-- when g_use_transpose = true, else the identity is used
g_use_transpose : boolean := false;
g_nof_destinations_max : natural := 1;
g_sim_force_bsn_error : boolean := true
);
port (
dp_clk : in std_logic;
@@ -85,22 +88,35 @@ entity sdp_beamformer_output is
end sdp_beamformer_output;
architecture str of sdp_beamformer_output is
constant c_data_w : natural := c_nof_complex * c_sdp_W_beamlet; -- 16b
constant c_beamlet_index : natural := g_beamset_id * c_sdp_S_sub_bf; -- call beamset 'id' and beamlet 'index'
constant c_data_w : natural := c_nof_complex * c_sdp_W_beamlet; -- 16b
constant c_beamset_beamlet_index : natural := g_beamset_id * c_sdp_S_sub_bf; -- call beamset 'id' and beamlet 'index'
-- Use c_fifo_fill = c_fifo_size - margin so that FIFO does not get read out too soon.
-- The dp_fifo_fill_eop takes care that the FIFO gets read out whenever there is an
-- eop in the FIFO, so that no payload gets stuck in the FIFO. Thanks to the use of eop
-- it possible to pass on blocks of variable length.
-- Make fifo size large enough for adding header, muxing c_sdp_N_beamsets beamsets and
-- Make c_fifo_size large enough for adding header, muxing c_sdp_N_beamsets beamsets and
-- delaying output to be able to realign snk_in.err field from snk_in.eop to src_out.sop.
constant c_fifo_fill : natural := c_sdp_cep_payload_nof_longwords; -- 976
constant c_fifo_size : natural := true_log_pow2(c_sdp_cep_payload_nof_longwords) * c_sdp_N_beamsets; -- 2048
-- field_sel = '0' for DP (dynamic), '1' for MM (fixed or programmable via MM of dp_offload_tx_v3)
constant c_nof_words_multi : natural := largest(func_sdp_bdo_nof_ch_per_packet_first_destinations_look_up_table(g_nof_destinations_max));
constant c_nof_longwords_one : natural := c_sdp_cep_payload_nof_longwords; -- = 976
constant c_nof_longwords_multi : natural := c_nof_words_multi / 2;
constant c_fifo_size_one : natural := true_log_pow2(c_nof_longwords_one) * c_sdp_N_beamsets; -- = 2048
constant c_fifo_size_multi : natural := true_log_pow2(c_nof_longwords_multi) * c_sdp_N_beamsets; -- = 2048
constant c_fifo_size : natural := sel_a_b(g_nof_destinations_max = 1, c_fifo_size_one, c_fifo_size_multi);
-- Rely on input eop instead of FIFO fill level, therefore set c_fifo_fill =
-- g_fifo_size - (g_fifo_af_margin + 2) as explained in dp_fifo_fill_eop
constant c_fifo_fill : natural := c_fifo_size - 6;
-- Multi destination info (mdi)
constant c_nof_destinations_w : natural := ceil_log2(g_nof_destinations_max + 1);
constant c_beamlet_index_per_destination_mat : t_natural_matrix(1 to g_nof_destinations_max, 0 to g_nof_destinations_max - 1) :=
func_sdp_bdo_beamlet_index_per_destination_look_up_matrix(g_nof_destinations_max);
-- . field_sel = '0' for DP (dynamic), '1' for MM (fixed or programmable via MM of dp_offload_tx_v3)
constant c_cep_hdr_field_sel : std_logic_vector(c_sdp_cep_nof_hdr_fields - 1 downto 0) :=
sel_a_b(g_use_multiple_destinations, func_sdp_cep_hdr_field_sel_dst('0'),
func_sdp_cep_hdr_field_sel_dst('1'));
sel_a_b(g_nof_destinations_max = 1, func_sdp_cep_hdr_field_sel_dst('1'),
func_sdp_cep_hdr_field_sel_dst('0'));
-- BDO packet size control
-- . One 32b word contains 1 dual pol beamlet of 4 octets (Xre, Xim, Yre, Yim).
@@ -108,6 +124,7 @@ architecture str of sdp_beamformer_output is
-- per beamlet and nof_beamlets_per_block dual pol beamlets per time slot.
signal nof_blocks_per_packet : natural;
signal nof_beamlets_per_block : natural;
signal beamlet_index : natural;
signal snk_in_concat : t_dp_sosi;
signal snk_in_concat_data : std_logic_vector(c_data_w - 1 downto 0);
@@ -119,10 +136,10 @@ architecture str of sdp_beamformer_output is
signal dp_packet_reorder_word : t_sdp_dual_pol_beamlet_in_word;
signal dp_repack_longword_src_out : t_dp_sosi;
signal dp_repack_longword : t_sdp_dual_pol_beamlet_in_longword;
signal dp_fifo_fill_eop_src_out : t_dp_sosi;
signal dp_fifo_fill_eop_src_in : t_dp_siso;
signal dp_pipeline_src_out : t_dp_sosi;
signal dp_pipeline_src_in : t_dp_siso;
signal dp_fifo_data_src_out : t_dp_sosi;
signal dp_fifo_data_src_in : t_dp_siso;
signal dp_pipeline_data_src_out : t_dp_sosi;
signal dp_pipeline_data_src_in : t_dp_siso;
signal dp_offload_tx_src_out : t_dp_sosi;
signal dp_offload_tx_src_in : t_dp_siso;
signal ip_checksum_src_out : t_dp_sosi;
@@ -130,15 +147,23 @@ architecture str of sdp_beamformer_output is
signal dp_pipeline_ready_src_out : t_dp_sosi;
signal dp_pipeline_ready_src_in : t_dp_siso;
signal dbg_bsn_offset : std_logic;
signal payload_err : std_logic_vector(0 downto 0);
signal station_info : std_logic_vector(15 downto 0) := (others => '0');
signal dbg_force_bsn_error : std_logic := '0';
signal payload_err : std_logic_vector(0 downto 0);
signal station_info : std_logic_vector(15 downto 0) := (others => '0');
-- Multiple destinations info (mdi)
signal multi_destinations_info : t_sdp_bdo_destinations_info;
signal s_DN : natural := 1; -- number of destinations
signal s_DI : natural := 0; -- destination index
signal mdi_eth_dst_mac : std_logic_vector(c_network_eth_mac_addr_w - 1 downto 0);
signal mdi_ip_dst_addr : std_logic_vector(c_network_ip_addr_w - 1 downto 0);
signal mdi_udp_dst_port : std_logic_vector(c_network_udp_port_w - 1 downto 0);
-- Multiple destinations
signal destinations_info : t_sdp_bdo_destinations_info;
signal eth_dst_mac : std_logic_vector(c_network_eth_mac_addr_w - 1 downto 0);
signal ip_dst_addr : std_logic_vector(c_network_ip_addr_w - 1 downto 0);
signal udp_dst_port : std_logic_vector(c_network_udp_port_w - 1 downto 0);
signal mdi_nof_blocks_per_packet : natural;
signal mdi_nof_beamlets_per_block_first_destinations : natural;
signal mdi_nof_beamlets_per_block_last_destination : natural;
signal mdi_nof_beamlets_per_block_per_destination : natural;
signal mdi_beamlet_index_per_destination : natural;
-- Default set all data path driven header fields to 0
signal dp_offload_tx_hdr_fields : std_logic_vector(1023 downto 0) := (others => '0');
@@ -169,7 +194,7 @@ begin
-- tb_lofar2_unb2c_sdp_station_bf.vhd, this will cause two times payload
-- errors, one when BSN goes wrong and one when BSN goes ok again.
if g_sim_force_bsn_error = true then
dbg_bsn_offset <= '0';
dbg_force_bsn_error <= '0';
if v_ref_time = 0 ns then
if in_sosi.sop = '1' then
-- Use start of input as reference time, rather than e.g. fixed 50 us,
@@ -193,7 +218,7 @@ begin
-- because the bsn is restored after first block, so the
-- merged blocks do not have incrementing bsn
-- . index >= 5 : bsn ok and payload_error = '0'.
dbg_bsn_offset <= '1';
dbg_force_bsn_error <= '1';
snk_in_concat.bsn <= INCR_UVEC(in_sosi.bsn, 1);
end if;
end if;
@@ -229,7 +254,7 @@ begin
-- [0:3] = [Xre, Xim, Yre, Yim]
dp_repack_beamlet_word <= unpack_data(dp_repack_beamlet_src_out.data(c_sdp_W_dual_pol_beamlet - 1 downto 0));
gen_one_destination : if g_use_multiple_destinations = false generate
gen_one_destination : if g_nof_destinations_max = 1 generate
-----------------------------------------------------------------------------
-- Merge and reorder beamlet data for one destination from:
-- (int8) [t] [N_blocks_per_packet][S_sub_bf] [N_pol_bf][N_complex]
@@ -252,7 +277,7 @@ begin
);
end generate;
gen_multiple_destinations : if g_use_multiple_destinations = true generate
gen_multiple_destinations : if g_nof_destinations_max > 1 generate
-----------------------------------------------------------------------------
-- 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]
@@ -265,8 +290,8 @@ begin
-----------------------------------------------------------------------------
u_sdp_bdo_multiple_destinations : entity work.sdp_bdo_multiple_destinations
generic map (
g_beamset_id => g_beamset_id,
g_use_transpose => g_use_transpose
g_nof_destinations_max => g_nof_destinations_max,
g_beamset_id => g_beamset_id
)
port map (
mm_clk => mm_clk,
@@ -278,11 +303,55 @@ begin
reg_destinations_copi => reg_destinations_copi,
reg_destinations_cipo => reg_destinations_cipo,
destinations_info => destinations_info,
destinations_info => multi_destinations_info,
snk_in => dp_repack_beamlet_src_out,
src_out => dp_packet_reorder_src_out
src_out => dp_packet_reorder_src_out,
-- Streaming data output info dependent on DN = nof_destinations
nof_blocks_per_packet => mdi_nof_blocks_per_packet,
nof_beamlets_per_block_first_destinations => mdi_nof_beamlets_per_block_first_destinations,
nof_beamlets_per_block_last_destination => mdi_nof_beamlets_per_block_last_destination
);
-----------------------------------------------------------------------------
-- Look up table values and and output info dependent on DN and DI
-----------------------------------------------------------------------------
-- Register output info dependent on DN and DI to ease timing closure
p_reg : process(dp_clk)
variable v_DI : natural; -- destination index
begin
if rising_edge(dp_clk) then
-- Register number of destinations (DN)
s_DN <= multi_destinations_info.nof_destinations_act;
-- Capture destination index (DI) from channel field, valid at sop
if dp_fifo_data_src_out.sop = '1' then
v_DI := to_uint(dp_fifo_data_src_out.channel);
s_DI <= v_DI; -- for view in Wave window
-- Variable values that depend on DN set via MM and/or on current DI
-- from dp_packet_unmerged that is passed on via
-- dp_fifo_data_src_out.channel.
-- . Use s_DN to ease timing closure. Use v_DI to ensure that the mdi
-- values are valid at dp_pipeline_data_src_out.sop
mdi_eth_dst_mac <= multi_destinations_info.eth_destination_mac_arr(v_DI);
mdi_ip_dst_addr <= multi_destinations_info.ip_destination_address_arr(v_DI);
mdi_udp_dst_port <= multi_destinations_info.udp_destination_port_arr(v_DI);
-- . Account for beamset offset in beamlet index
mdi_beamlet_index_per_destination <= c_beamset_beamlet_index + c_beamlet_index_per_destination_mat(s_DN, v_DI);
-- . In total there are S_sub_bf = 488 beamlets for nof_destinations.
-- The packet for last destination contains the same number of
-- beamlets as the first destinations, or less beamlets.
if v_DI < s_DN - 1 then
mdi_nof_beamlets_per_block_per_destination <= mdi_nof_beamlets_per_block_first_destinations;
else
mdi_nof_beamlets_per_block_per_destination <= mdi_nof_beamlets_per_block_last_destination;
end if;
end if;
end if;
end process;
end generate;
-- Debug signals for view in Wave window
@@ -314,17 +383,19 @@ begin
dp_repack_longword <= unpack_data(dp_repack_longword_src_out.data(c_longword_w - 1 downto 0));
-----------------------------------------------------------------------------
-- FIFO
-- FIFO: to be able to insert header in u_dp_offload_tx_v3
-----------------------------------------------------------------------------
-- Pass on dp_repack_longword_src_out.err field not here, but via separate
-- u_common_fifo_sc_err.
u_dp_fifo_fill_eop_sc : entity dp_lib.dp_fifo_fill_eop_sc
-- u_common_fifo_err.
u_dp_fifo_data : entity dp_lib.dp_fifo_fill_eop_sc
generic map (
g_data_w => c_longword_w,
g_empty_w => c_byte_w,
g_use_empty => true,
g_use_bsn => true,
g_use_channel => true,
g_bsn_w => 64,
g_channel_w => c_nof_destinations_w,
g_use_sync => true,
g_fifo_size => c_fifo_size,
g_fifo_fill => c_fifo_fill,
@@ -334,16 +405,27 @@ begin
clk => dp_clk,
rst => dp_rst,
snk_in => dp_repack_longword_src_out,
src_out => dp_fifo_fill_eop_src_out,
src_in => dp_fifo_fill_eop_src_in
src_out => dp_fifo_data_src_out,
src_in => dp_fifo_data_src_in
);
-- Simple fifo to store the payload error bit at eop of FIFO input to be used
-- at sop of FIFO output, so that payload_err can then be used in the packet
-- header. Typically the u_dp_fifo_fill_eop will store between 0 and
-- c_sdp_N_beamsets = 2 packets. Choose g_nof_words > c_sdp_N_beamsets to
-- have some margin compared to c_fifo_size of the data FIFO.
u_common_fifo_sc_err : entity common_lib.common_fifo_sc
-- FIFO: to store and align payload error bit from eop to sop
-- . The payload error bit is set when dp_packet_merge detects an BSN
-- increment error. The dual page mechanism in reorder_col_select makes
-- that the sosi.err bit will be valid during the entire output packet,
-- so that it can be passed on at the sop via the application header.
-- For g_nof_destinations > 1 each destination packet will have its
-- payload error bit set as well, because dp_packet_unmerge applies the
-- input sosi.err at the sop to all unmerged output packets.
-- . Simple fifo to store the payload error bit at eop of FIFO input to be
-- used at sop of FIFO output, so that payload_err can then be used in
-- the packet header. Typically the u_dp_fifo_data will store between 0
-- and c_sdp_N_beamsets = 2 packets. Choose g_nof_words > c_sdp_N_beamsets
-- to have some margin compared to c_fifo_size of the data FIFO.
-- . No need to account for g_nof_destinations_max > 1 in FIFO g_nof_words,
-- because the BDO packets are multiplexed round-robin with fair chance
-- per beamset by the dp_mux in sdp_station.vhd
u_common_fifo_err : entity common_lib.common_fifo_sc
generic map (
g_dat_w => 1,
g_nof_words => c_sdp_N_beamsets + 2
@@ -354,11 +436,11 @@ begin
wr_dat => dp_repack_longword_src_out.err(0 downto 0),
wr_req => dp_repack_longword_src_out.eop,
rd_dat => payload_err,
rd_req => dp_fifo_fill_eop_src_out.sop
rd_req => dp_fifo_data_src_out.sop
);
-- Pipeline FIFO output to align payload_err at dp_pipeline_src_out.sop
u_pipeline : entity dp_lib.dp_pipeline
-- Pipeline dp_fifo_data_src_out to align payload_err at dp_pipeline_data_src_out.sop
u_pipeline_data : entity dp_lib.dp_pipeline
generic map (
g_pipeline => 1
)
@@ -366,11 +448,11 @@ begin
rst => dp_rst,
clk => dp_clk,
-- ST sink
snk_out => dp_fifo_fill_eop_src_in,
snk_in => dp_fifo_fill_eop_src_out,
snk_out => dp_fifo_data_src_in,
snk_in => dp_fifo_data_src_out,
-- ST source
src_in => dp_pipeline_src_in,
src_out => dp_pipeline_src_out
src_in => dp_pipeline_data_src_in,
src_out => dp_pipeline_data_src_out
);
-----------------------------------------------------------------------------
@@ -431,18 +513,20 @@ begin
--
-- DP dp_bsn
p_assemble_offload_info : process(destinations_info)
p_assemble_offload_info : process(mdi_nof_blocks_per_packet,
mdi_nof_beamlets_per_block_per_destination,
mdi_beamlet_index_per_destination)
begin
if g_use_multiple_destinations = false then
if g_nof_destinations_max = 1 then
-- Use constant defaults for beamlet data output to one destination.
nof_blocks_per_packet <= c_sdp_cep_nof_blocks_per_packet; -- = 4;
nof_beamlets_per_block <= c_sdp_S_sub_bf; -- = 488 dual pol beamlets;
beamlet_index <= c_beamset_beamlet_index;
else
-- Use dynamic sizes for beamlet data output to multiple destination.
nof_blocks_per_packet <= destinations_info.nof_blocks_per_packet_act;
nof_beamlets_per_block <= c_sdp_S_sub_bf; -- = 488 dual pol beamlets;
-- TODO check channel field to set destination addresses in dp_offload_tx_hdr_fields
nof_blocks_per_packet <= mdi_nof_blocks_per_packet;
nof_beamlets_per_block <= mdi_nof_beamlets_per_block_per_destination;
beamlet_index <= mdi_beamlet_index_per_destination;
end if;
end process;
@@ -460,9 +544,9 @@ begin
-- Use MM programmable destination MAC/IP/UDP from dp_offload_tx_v3 for one destination
-- Use DP programmable destination MAC/IP/UDP from sdp_bdo_destinations_reg for multiple destinations
dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "eth_dst_mac" ) downto field_lo(c_sdp_cep_hdr_field_arr, "eth_dst_mac" )) <= eth_dst_mac;
dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "ip_dst_addr" ) downto field_lo(c_sdp_cep_hdr_field_arr, "ip_dst_addr" )) <= ip_dst_addr;
dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "udp_dst_port") downto field_lo(c_sdp_cep_hdr_field_arr, "udp_dst_port")) <= udp_dst_port;
dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "eth_dst_mac" ) downto field_lo(c_sdp_cep_hdr_field_arr, "eth_dst_mac" )) <= mdi_eth_dst_mac;
dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "ip_dst_addr" ) downto field_lo(c_sdp_cep_hdr_field_arr, "ip_dst_addr" )) <= mdi_ip_dst_addr;
dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "udp_dst_port") downto field_lo(c_sdp_cep_hdr_field_arr, "udp_dst_port")) <= mdi_udp_dst_port;
dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_observation_id" ) downto field_lo(c_sdp_cep_hdr_field_arr, "sdp_observation_id" )) <= sdp_info.observation_id;
dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_station_info" ) downto field_lo(c_sdp_cep_hdr_field_arr, "sdp_station_info" )) <= station_info;
@@ -475,12 +559,12 @@ begin
dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_source_info_gn_id" ) downto field_lo(c_sdp_cep_hdr_field_arr, "sdp_source_info_gn_id" )) <= gn_id;
dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_beamlet_scale" ) downto field_lo(c_sdp_cep_hdr_field_arr, "sdp_beamlet_scale" )) <= beamlet_scale;
dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_beamlet_index" ) downto field_lo(c_sdp_cep_hdr_field_arr, "sdp_beamlet_index" )) <= TO_UVEC(c_beamlet_index, c_halfword_w);
dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_beamlet_index" ) downto field_lo(c_sdp_cep_hdr_field_arr, "sdp_beamlet_index" )) <= TO_UVEC(beamlet_index, c_halfword_w);
dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_nof_blocks_per_packet" ) downto field_lo(c_sdp_cep_hdr_field_arr, "sdp_nof_blocks_per_packet" )) <= TO_UVEC(nof_blocks_per_packet, c_octet_w);
dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_nof_beamlets_per_block") downto field_lo(c_sdp_cep_hdr_field_arr, "sdp_nof_beamlets_per_block")) <= TO_UVEC(nof_beamlets_per_block, c_halfword_w);
dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_block_period" ) downto field_lo(c_sdp_cep_hdr_field_arr, "sdp_block_period" )) <= sdp_info.block_period;
dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "dp_bsn" ) downto field_lo(c_sdp_cep_hdr_field_arr, "dp_bsn" )) <= dp_pipeline_src_out.bsn(63 downto 0);
dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "dp_bsn" ) downto field_lo(c_sdp_cep_hdr_field_arr, "dp_bsn" )) <= dp_pipeline_data_src_out.bsn(63 downto 0);
-- For viewing the header fields in wave window
dp_offload_tx_header <= func_sdp_map_cep_header(dp_offload_tx_hdr_fields);
@@ -507,8 +591,8 @@ begin
reg_hdr_dat_mosi => reg_hdr_dat_mosi,
reg_hdr_dat_miso => reg_hdr_dat_miso,
snk_in_arr(0) => dp_pipeline_src_out,
snk_out_arr(0) => dp_pipeline_src_in,
snk_in_arr(0) => dp_pipeline_data_src_out,
snk_out_arr(0) => dp_pipeline_data_src_in,
src_out_arr(0) => dp_offload_tx_src_out,
src_in_arr(0) => dp_offload_tx_src_in,
Loading