Skip to content
Snippets Groups Projects
Commit 414dbd2f authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Add merged payload error bit support in design and in tb.

parent 74342d2f
Branches
No related tags found
1 merge request!336Resolve L2SDP-958
Pipeline #55466 passed
...@@ -111,6 +111,9 @@ ...@@ -111,6 +111,9 @@
-- are default 0, but in sim the BF weights in node_sdp_beamformer.vhd -- are default 0, but in sim the BF weights in node_sdp_beamformer.vhd
-- are default unit weights. Therefore also write the BF weight for default -- are default unit weights. Therefore also write the BF weight for default
-- beamlet 102 to define it value, in case g_beamlet /= 102. -- beamlet 102 to define it value, in case g_beamlet /= 102.
-- * A simulation only section in sdp_beamformer_output.vhd disturbs the BSN,
-- to cause a merged payload error, so that sdp_source_info_payload_error
-- can be verified here.
-- --
-- Usage: -- Usage:
-- > as 7 # default -- > as 7 # default
...@@ -436,6 +439,7 @@ architecture tb of tb_lofar2_unb2c_sdp_station_bf is ...@@ -436,6 +439,7 @@ architecture tb of tb_lofar2_unb2c_sdp_station_bf is
signal rx_sdp_cep_header : t_sdp_cep_header; signal rx_sdp_cep_header : t_sdp_cep_header;
signal exp_sdp_cep_header : t_sdp_cep_header; signal exp_sdp_cep_header : t_sdp_cep_header;
signal exp_dp_bsn : natural; signal exp_dp_bsn : natural;
signal exp_payload_error : std_logic := '0';
-- Beamlets packets data -- Beamlets packets data
signal rx_beamlet_data : std_logic_vector(c_longword_w - 1 downto 0); -- 64 bit signal rx_beamlet_data : std_logic_vector(c_longword_w - 1 downto 0); -- 64 bit
...@@ -1245,10 +1249,10 @@ begin ...@@ -1245,10 +1249,10 @@ begin
-- Prepare exp_sdp_cep_header before rx_beamlet_sosi.eop, so that -- Prepare exp_sdp_cep_header before rx_beamlet_sosi.eop, so that
-- p_verify_cep_header can verify it at rx_beamlet_sosi.eop. -- p_verify_cep_header can verify it at rx_beamlet_sosi.eop.
exp_sdp_cep_header <= func_sdp_compose_cep_header(c_exp_ip_header_checksum, exp_sdp_cep_header <= func_sdp_compose_cep_header(c_exp_ip_header_checksum,
c_exp_sdp_info, c_exp_sdp_info,
c_gn_index, c_gn_index,
exp_payload_error,
c_exp_beamlet_scale, c_exp_beamlet_scale,
c_exp_beamlet_index, c_exp_beamlet_index,
exp_dp_bsn); exp_dp_bsn);
...@@ -1256,15 +1260,39 @@ begin ...@@ -1256,15 +1260,39 @@ begin
rx_sdp_cep_header <= func_sdp_map_cep_header(rx_hdr_fields_raw); rx_sdp_cep_header <= func_sdp_map_cep_header(rx_hdr_fields_raw);
p_verify_cep_header : process p_verify_cep_header : process
variable v_pkt_cnt : natural;
variable v_new_pkt : boolean;
variable v_error : std_logic := '0';
variable v_bsn : natural := 0;
variable v_bool : boolean; variable v_bool : boolean;
begin begin
wait until rising_edge(ext_clk); wait until rising_edge(ext_clk);
-- Count packets per beamset
v_pkt_cnt := rx_beamlet_sop_cnt / c_sdp_N_beamsets;
v_new_pkt := rx_beamlet_sop_cnt mod c_sdp_N_beamsets = 0;
-- Prepare exp_sdp_cep_header at sop, so that it can be verified at eop -- Prepare exp_sdp_cep_header at sop, so that it can be verified at eop
if rx_beamlet_sosi.sop = '1' then if rx_beamlet_sosi.sop = '1' then
-- Expected BSN increments by c_sdp_cep_nof_blocks_per_packet = 4 blocks per packet -- Expected BSN increments by c_sdp_cep_nof_blocks_per_packet = 4 blocks per packet,
if rx_beamlet_sop_cnt mod c_sdp_N_beamsets = 0 then -- both beamsets are outputting packets.
exp_dp_bsn <= c_init_bsn + (rx_beamlet_sop_cnt / c_sdp_N_beamsets) * c_sdp_cep_nof_blocks_per_packet; if v_new_pkt then
-- Default expected
v_error := '0';
v_bsn := c_init_bsn + v_pkt_cnt * c_sdp_cep_nof_blocks_per_packet;
-- Expected due to bsn and payload_error stimuli in sdp_beamformer_output.vhd.
if v_pkt_cnt = 1 then
v_error := '1';
elsif v_pkt_cnt = 2 or v_pkt_cnt = 3 then
v_bsn := v_bsn + 1;
elsif v_pkt_cnt = 4 then
v_bsn := v_bsn + 1;
v_error := '1';
end if;
-- Apply expected values
exp_payload_error <= v_error;
exp_dp_bsn <= v_bsn;
end if; end if;
end if; end if;
......
...@@ -439,6 +439,7 @@ architecture tb of tb_lofar2_unb2c_sdp_station_bf_ring is ...@@ -439,6 +439,7 @@ architecture tb of tb_lofar2_unb2c_sdp_station_bf_ring is
signal rx_sdp_cep_header : t_sdp_cep_header; signal rx_sdp_cep_header : t_sdp_cep_header;
signal exp_sdp_cep_header : t_sdp_cep_header; signal exp_sdp_cep_header : t_sdp_cep_header;
signal exp_dp_bsn : natural; signal exp_dp_bsn : natural;
signal exp_payload_error : std_logic := '0';
-- Beamlets packets data -- Beamlets packets data
signal rx_beamlet_data : std_logic_vector(c_longword_w - 1 downto 0); -- 64 bit signal rx_beamlet_data : std_logic_vector(c_longword_w - 1 downto 0); -- 64 bit
...@@ -577,7 +578,6 @@ begin ...@@ -577,7 +578,6 @@ begin
i_QSFP_0_RX(0) <= i_QSFP_0_TX(c_last_rn); i_QSFP_0_RX(0) <= i_QSFP_0_TX(c_last_rn);
i_QSFP_0_RX(c_last_rn) <= i_QSFP_0_TX(0); i_QSFP_0_RX(c_last_rn) <= i_QSFP_0_TX(0);
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
-- CEP model -- CEP model
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
...@@ -721,7 +721,6 @@ begin ...@@ -721,7 +721,6 @@ begin
-- END RECORD; -- END RECORD;
-- . Write -- . Write
for RN in 0 to c_last_rn loop for RN in 0 to c_last_rn loop
v_gn := g_first_gn + RN; v_gn := g_first_gn + RN;
mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn mod c_quad) & "REG_SDP_INFO", 8, TO_UINT(c_exp_sdp_info.antenna_field_index), tb_clk); mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn mod c_quad) & "REG_SDP_INFO", 8, TO_UINT(c_exp_sdp_info.antenna_field_index), tb_clk);
...@@ -1361,11 +1360,11 @@ begin ...@@ -1361,11 +1360,11 @@ begin
-- Prepare exp_sdp_cep_header before rx_beamlet_sosi.eop, so that -- Prepare exp_sdp_cep_header before rx_beamlet_sosi.eop, so that
-- p_verify_cep_header can verify it at rx_beamlet_sosi.eop. -- p_verify_cep_header can verify it at rx_beamlet_sosi.eop.
exp_sdp_cep_header <= func_sdp_compose_cep_header(c_cep_ip_src_addr, exp_sdp_cep_header <= func_sdp_compose_cep_header(c_cep_ip_src_addr,
c_exp_ip_header_checksum, c_exp_ip_header_checksum,
c_exp_sdp_info, c_exp_sdp_info,
c_last_gn, c_last_gn,
exp_payload_error,
c_exp_beamlet_scale, c_exp_beamlet_scale,
c_exp_beamlet_index, c_exp_beamlet_index,
exp_dp_bsn); exp_dp_bsn);
......
...@@ -20,10 +20,12 @@ ...@@ -20,10 +20,12 @@
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- --
-- Author: R. van der Walle -- Author: R. van der Walle, E. Kooistra (payload error support)
-- Purpose: -- Purpose:
-- The beamformer output (BDO) packetizes the beamlet data into UDP/IP packets. -- The beamformer output (BDO) packetizes the beamlet data into UDP/IP packets.
-- Description: -- Description:
-- * https://support.astron.nl/confluence/display/L2M/L5+SDPFW+Design+Document%3A+Beamformer
-- * https://support.astron.nl/confluence/display/L2M/L4+SDPFW+Decision%3A+Multiple+beamlet+output+destinations
-- Remark: -- Remark:
-- --
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
...@@ -73,22 +75,27 @@ entity sdp_beamformer_output is ...@@ -73,22 +75,27 @@ entity sdp_beamformer_output is
); );
end sdp_beamformer_output; end sdp_beamformer_output;
architecture str of sdp_beamformer_output is architecture str of sdp_beamformer_output is
constant c_data_w : natural := c_nof_complex * c_sdp_W_beamlet; -- 16b 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_beamlet_index : natural := g_beamset_id * c_sdp_S_sub_bf; -- call beamset 'id' and beamlet 'index'
-- c_fifo_fill must be the exact size of a payload such that no payload gets stuck in the FIFO or the FIFO gets read out too soon. -- Use c_fifo_fill = c_fifo_size - margin so that FIFO does not get read out too soon.
-- For packets of variable length, dp_fifo_fill_eop must be used. In this case we can use the standard fill fifo. -- The dp_fifo_fill_eop takes care that the FIFO gets read out whenever there is an
constant c_fifo_fill : natural := c_sdp_cep_payload_nof_longwords; -- eop in the FIFO, so that no payload gets stuck in the FIFO. Thanks to the use of eop
constant c_fifo_size : natural := c_fifo_fill * 2; -- Make fifo size large enough for adding header and muxing beamsets. -- it possible to pass on blocks of variable length.
-- Make 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
signal snk_in_concat : t_dp_sosi; signal snk_in_concat : t_dp_sosi;
signal dp_packet_merge_src_out : t_dp_sosi;
signal dp_repack_data_src_out : t_dp_sosi; signal dp_repack_data_src_out : t_dp_sosi;
signal dp_fifo_sc_src_out : t_dp_sosi; signal dp_packet_merge_src_out : t_dp_sosi;
signal dp_fifo_sc_src_in : t_dp_siso; signal dp_fifo_merge_src_out : t_dp_sosi;
signal dp_fifo_merge_src_in : t_dp_siso;
signal dp_pipeline_src_out : t_dp_sosi;
signal dp_pipeline_src_in : t_dp_siso;
signal dp_offload_tx_src_out : t_dp_sosi; signal dp_offload_tx_src_out : t_dp_sosi;
signal dp_offload_tx_src_in : t_dp_siso; signal dp_offload_tx_src_in : t_dp_siso;
signal ip_checksum_src_out : t_dp_sosi; signal ip_checksum_src_out : t_dp_sosi;
...@@ -96,12 +103,12 @@ architecture str of sdp_beamformer_output is ...@@ -96,12 +103,12 @@ architecture str of sdp_beamformer_output is
signal dp_pipeline_ready_src_out : t_dp_sosi; signal dp_pipeline_ready_src_out : t_dp_sosi;
signal dp_pipeline_ready_src_in : t_dp_siso; signal dp_pipeline_ready_src_in : t_dp_siso;
signal common_fifo_rd_req : std_logic;
signal payload_err : std_logic_vector(0 downto 0); signal payload_err : std_logic_vector(0 downto 0);
signal station_info : std_logic_vector(15 downto 0) := (others => '0'); signal station_info : std_logic_vector(15 downto 0) := (others => '0');
-- Default set all data path driven header fields to 0 -- Default set all data path driven header fields to 0
signal dp_offload_tx_hdr_fields : std_logic_vector(1023 downto 0) := (others => '0'); signal dp_offload_tx_hdr_fields : std_logic_vector(1023 downto 0) := (others => '0');
signal dp_offload_tx_header : t_sdp_cep_header; -- to view dp_offload_tx_hdr_fields in Wave window
begin begin
...@@ -111,15 +118,43 @@ begin ...@@ -111,15 +118,43 @@ begin
-- . send beamlet data big endian with X.re part first, then X.im, Y.re, Y.im -- . send beamlet data big endian with X.re part first, then X.im, Y.re, Y.im
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
p_snk_in_arr : process(in_sosi) p_snk_in_arr : process(in_sosi)
variable v_ref_time : time := 0 ns;
begin begin
snk_in_concat <= in_sosi; snk_in_concat <= in_sosi;
snk_in_concat.data(c_data_w - 1 downto 0) <= in_sosi.re(c_sdp_W_beamlet - 1 downto 0) & in_sosi.im(c_sdp_W_beamlet - 1 downto 0); snk_in_concat.data(c_data_w - 1 downto 0) <= in_sosi.re(c_sdp_W_beamlet - 1 downto 0) & in_sosi.im(c_sdp_W_beamlet - 1 downto 0);
-- synthesis translate_off
-- Force BSN error in simulation to verify payload error in 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 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, to be
-- independent of how long it takes for the tb to deliver the first block.
v_ref_time := NOW;
-- Offset the v_ref_time to the second block of the c_sdp_cep_nof_blocks_per_packet
-- = 4 blocks that will be merged.
v_ref_time := v_ref_time + c_sdp_block_period * 1 ns;
end if;
elsif NOW > v_ref_time + 1 * c_sdp_cep_nof_blocks_per_packet * c_sdp_block_period * 1 ns and
NOW < v_ref_time + 4 * c_sdp_cep_nof_blocks_per_packet * c_sdp_block_period * 1 ns then
-- Disturb BSN to cause merged payload error. Expected results for the merged blocks:
-- . index 0 : First merged block bsn ok and payload_error = '0'.
-- . index 1 : bsn still ok, but payload error = '1', due to bsn++ after first block
-- . index 2,3 : bsn wrong due to bsn++, but payload error = '0', because all 4
-- merged blocks have incrementing bsn
-- . index 4 : bsn still wrong due to bsn++, and payload error = '1', 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'.
snk_in_concat.bsn <= INCR_UVEC(in_sosi.bsn, 1);
end if;
-- synthesis translate_on
end process; end process;
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- dp_repack_data -- dp_repack_data
-- . 16b -> 64b -- . 16b -> 64b
-- . We don't need to flow control the source beacause we're going from 16b->64b -- . We don't need to flow control the source because we're going from 16b->64b
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
u_dp_repack_data : entity dp_lib.dp_repack_data u_dp_repack_data : entity dp_lib.dp_repack_data
generic map ( generic map (
...@@ -144,7 +179,8 @@ begin ...@@ -144,7 +179,8 @@ begin
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
u_dp_packet_merge : entity dp_lib.dp_packet_merge u_dp_packet_merge : entity dp_lib.dp_packet_merge
generic map( generic map(
g_nof_pkt => c_sdp_cep_nof_blocks_per_packet g_nof_pkt => c_sdp_cep_nof_blocks_per_packet,
g_bsn_increment => 1
) )
port map( port map(
rst => dp_rst, rst => dp_rst,
...@@ -159,16 +195,9 @@ begin ...@@ -159,16 +195,9 @@ begin
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- FIFO -- FIFO
-- . We're inserting headers, so dp_offload_tx needs a flow controllable
-- source.
-- . Also, we need a fill FIFO here because 16b->64b will introduce gaps in our
-- TX stream (not allowed by 10G TX MAC).
-- . The fill fifo waits until c_fifo_fill words are received before enabling the
-- output. The total number of words in the fifo is determined by the
-- backpressure.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
u_dp_fifo_fill_sc : entity dp_lib.dp_fifo_fill_sc u_dp_fifo_fill_eop_sc : entity dp_lib.dp_fifo_fill_eop_sc
generic map ( generic map ( -- pass on dp_packet_merge_src_out.err via u_common_fifo_sc_err
g_data_w => c_longword_w, g_data_w => c_longword_w,
g_empty_w => c_byte_w, g_empty_w => c_byte_w,
g_use_empty => true, g_use_empty => true,
...@@ -182,20 +211,20 @@ begin ...@@ -182,20 +211,20 @@ begin
port map ( port map (
clk => dp_clk, clk => dp_clk,
rst => dp_rst, rst => dp_rst,
snk_in => dp_packet_merge_src_out, snk_in => dp_packet_merge_src_out,
src_out => dp_fifo_merge_src_out,
src_out => dp_fifo_sc_src_out, src_in => dp_fifo_merge_src_in
src_in => dp_fifo_sc_src_in
); );
-- Simple fifo to store the payload error at eop of FIFO input to be used at sop of FIFO output. -- Simple fifo to store the payload error bit at eop of FIFO input to be used at sop of FIFO
-- It can then be used in the packet header. -- output, so that payload_err can then be used in the packet header.
common_fifo_rd_req <= dp_fifo_sc_src_out.sop; -- Typically the u_dp_fifo_fill_eop will store between 0 and c_sdp_N_beamsets = 2 packets.
u_common_fifo_sc : entity common_lib.common_fifo_sc -- 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
generic map ( generic map (
g_dat_w => 1, g_dat_w => 1,
g_nof_words => 2 g_nof_words => c_sdp_N_beamsets + 2
) )
port map ( port map (
rst => dp_rst, rst => dp_rst,
...@@ -203,7 +232,23 @@ begin ...@@ -203,7 +232,23 @@ begin
wr_dat => dp_packet_merge_src_out.err(0 downto 0), wr_dat => dp_packet_merge_src_out.err(0 downto 0),
wr_req => dp_packet_merge_src_out.eop, wr_req => dp_packet_merge_src_out.eop,
rd_dat => payload_err, rd_dat => payload_err,
rd_req => common_fifo_rd_req rd_req => dp_fifo_merge_src_out.sop
);
-- Pipeline FIFO output to align payload_err at dp_pipeline_src_out.sop
u_pipeline : entity dp_lib.dp_pipeline
generic map (
g_pipeline => 1
)
port map (
rst => dp_rst,
clk => dp_clk,
-- ST sink
snk_out => dp_fifo_merge_src_in,
snk_in => dp_fifo_merge_src_out,
-- ST source
src_in => dp_pipeline_src_in,
src_out => dp_pipeline_src_out
); );
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
...@@ -287,8 +332,10 @@ begin ...@@ -287,8 +332,10 @@ begin
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(c_beamlet_index, 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, "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_fifo_sc_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_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);
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- dp_offload_tx_v3 -- dp_offload_tx_v3
...@@ -312,8 +359,8 @@ begin ...@@ -312,8 +359,8 @@ begin
reg_hdr_dat_mosi => reg_hdr_dat_mosi, reg_hdr_dat_mosi => reg_hdr_dat_mosi,
reg_hdr_dat_miso => reg_hdr_dat_miso, reg_hdr_dat_miso => reg_hdr_dat_miso,
snk_in_arr(0) => dp_fifo_sc_src_out, snk_in_arr(0) => dp_pipeline_src_out,
snk_out_arr(0) => dp_fifo_sc_src_in, snk_out_arr(0) => dp_pipeline_src_in,
src_out_arr(0) => dp_offload_tx_src_out, src_out_arr(0) => dp_offload_tx_src_out,
src_in_arr(0) => dp_offload_tx_src_in, src_in_arr(0) => dp_offload_tx_src_in,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment