Skip to content
Snippets Groups Projects
Commit 09aeaf9d authored by Reinier van der Walle's avatar Reinier van der Walle
Browse files

Merge branch 'L2SDP-958' into 'master'

Resolve L2SDP-958

Closes L2SDP-958

See merge request desp/hdl!336
parents faf9cd58 1716d488
No related branches found
No related tags found
1 merge request!336Resolve L2SDP-958
Pipeline #55474 passed
Showing
with 328 additions and 107 deletions
......@@ -111,6 +111,9 @@
-- 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
-- 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:
-- > as 7 # default
......@@ -436,6 +439,7 @@ architecture tb of tb_lofar2_unb2c_sdp_station_bf is
signal rx_sdp_cep_header : t_sdp_cep_header;
signal exp_sdp_cep_header : t_sdp_cep_header;
signal exp_dp_bsn : natural;
signal exp_payload_error : std_logic := '0';
-- Beamlets packets data
signal rx_beamlet_data : std_logic_vector(c_longword_w - 1 downto 0); -- 64 bit
......@@ -1245,10 +1249,10 @@ begin
-- Prepare exp_sdp_cep_header before rx_beamlet_sosi.eop, so that
-- 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,
c_exp_sdp_info,
c_gn_index,
exp_payload_error,
c_exp_beamlet_scale,
c_exp_beamlet_index,
exp_dp_bsn);
......@@ -1256,15 +1260,39 @@ begin
rx_sdp_cep_header <= func_sdp_map_cep_header(rx_hdr_fields_raw);
p_verify_cep_header : process
variable v_bool : boolean;
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;
begin
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
if rx_beamlet_sosi.sop = '1' then
-- 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
exp_dp_bsn <= c_init_bsn + (rx_beamlet_sop_cnt / c_sdp_N_beamsets) * c_sdp_cep_nof_blocks_per_packet;
-- Expected BSN increments by c_sdp_cep_nof_blocks_per_packet = 4 blocks per packet,
-- both beamsets are outputting packets.
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;
......
......@@ -105,6 +105,9 @@
-- * The c_wg_phase_offset and c_subband_phase_offset are used to tune the WG
-- phase reference to 0.0 degrees at the start (sop)
-- * Use g_beamlet_scale = 2**10, for full scale WG and N_ant = 1, see [1]
-- * 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:
-- > as 7 # default
......@@ -439,6 +442,7 @@ architecture tb of tb_lofar2_unb2c_sdp_station_bf_ring is
signal rx_sdp_cep_header : t_sdp_cep_header;
signal exp_sdp_cep_header : t_sdp_cep_header;
signal exp_dp_bsn : natural;
signal exp_payload_error : std_logic := '0';
-- Beamlets packets data
signal rx_beamlet_data : std_logic_vector(c_longword_w - 1 downto 0); -- 64 bit
......@@ -577,7 +581,6 @@ begin
i_QSFP_0_RX(0) <= i_QSFP_0_TX(c_last_rn);
i_QSFP_0_RX(c_last_rn) <= i_QSFP_0_TX(0);
------------------------------------------------------------------------------
-- CEP model
------------------------------------------------------------------------------
......@@ -721,7 +724,6 @@ begin
-- END RECORD;
-- . Write
for RN in 0 to c_last_rn loop
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);
......@@ -1361,11 +1363,11 @@ begin
-- Prepare exp_sdp_cep_header before rx_beamlet_sosi.eop, so that
-- 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,
c_exp_ip_header_checksum,
c_exp_sdp_info,
c_last_gn,
exp_payload_error,
c_exp_beamlet_scale,
c_exp_beamlet_index,
exp_dp_bsn);
......@@ -1373,15 +1375,39 @@ begin
rx_sdp_cep_header <= func_sdp_map_cep_header(rx_hdr_fields_raw);
p_verify_cep_header : process
variable v_bool : boolean;
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;
begin
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
if rx_beamlet_sosi.sop = '1' then
-- 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
exp_dp_bsn <= c_init_bsn + (rx_beamlet_sop_cnt / c_sdp_N_beamsets) * c_sdp_cep_nof_blocks_per_packet;
-- Expected BSN increments by c_sdp_cep_nof_blocks_per_packet = 4 blocks per packet,
-- both beamsets are outputting packets.
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;
......
......@@ -20,10 +20,12 @@
-------------------------------------------------------------------------------
--
-- Author: R. van der Walle
-- Author: R. van der Walle, E. Kooistra (payload error support)
-- Purpose:
-- The beamformer output (BDO) packetizes the beamlet data into UDP/IP packets.
-- 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:
--
-------------------------------------------------------------------------------
......@@ -73,22 +75,27 @@ 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_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.
-- For packets of variable length, dp_fifo_fill_eop must be used. In this case we can use the standard fill fifo.
constant c_fifo_fill : natural := c_sdp_cep_payload_nof_longwords;
constant c_fifo_size : natural := c_fifo_fill * 2; -- Make fifo size large enough for adding header and muxing beamsets.
-- 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
-- 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 dp_packet_merge_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_fifo_sc_src_in : t_dp_siso;
signal dp_packet_merge_src_out : t_dp_sosi;
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_in : t_dp_siso;
signal ip_checksum_src_out : t_dp_sosi;
......@@ -96,12 +103,13 @@ 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 common_fifo_rd_req : std_logic;
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');
-- 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_header : t_sdp_cep_header; -- to view dp_offload_tx_hdr_fields in Wave window
begin
......@@ -111,15 +119,45 @@ begin
-- . send beamlet data big endian with X.re part first, then X.im, Y.re, Y.im
-------------------------------------------------------------------------------
p_snk_in_arr : process(in_sosi)
variable v_ref_time : time := 0 ns;
begin
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);
-- 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.
dbg_bsn_offset <= '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, 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'.
dbg_bsn_offset <= '1';
snk_in_concat.bsn <= INCR_UVEC(in_sosi.bsn, 1);
end if;
-- synthesis translate_on
end process;
-------------------------------------------------------------------------------
-- dp_repack_data
-- . 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
generic map (
......@@ -144,7 +182,8 @@ begin
-------------------------------------------------------------------------------
u_dp_packet_merge : entity dp_lib.dp_packet_merge
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(
rst => dp_rst,
......@@ -159,16 +198,9 @@ begin
-------------------------------------------------------------------------------
-- 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
generic map (
u_dp_fifo_fill_eop_sc : entity dp_lib.dp_fifo_fill_eop_sc
generic map ( -- pass on dp_packet_merge_src_out.err via u_common_fifo_sc_err
g_data_w => c_longword_w,
g_empty_w => c_byte_w,
g_use_empty => true,
......@@ -182,28 +214,44 @@ begin
port map (
clk => dp_clk,
rst => dp_rst,
snk_in => dp_packet_merge_src_out,
src_out => dp_fifo_sc_src_out,
src_in => dp_fifo_sc_src_in
src_out => dp_fifo_merge_src_out,
src_in => dp_fifo_merge_src_in
);
-- Simple fifo to store the payload error at eop of FIFO input to be used at sop of FIFO output.
-- It can then be used in the packet header.
common_fifo_rd_req <= dp_fifo_sc_src_out.sop;
u_common_fifo_sc : entity common_lib.common_fifo_sc
-- 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
generic map (
g_dat_w => 1,
g_nof_words => 2
g_nof_words => c_sdp_N_beamsets + 2
)
port map (
rst => dp_rst,
clk => dp_clk,
rst => dp_rst,
clk => dp_clk,
wr_dat => dp_packet_merge_src_out.err(0 downto 0),
wr_req => dp_packet_merge_src_out.eop,
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 +335,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_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
......@@ -312,8 +362,8 @@ begin
reg_hdr_dat_mosi => reg_hdr_dat_mosi,
reg_hdr_dat_miso => reg_hdr_dat_miso,
snk_in_arr(0) => dp_fifo_sc_src_out,
snk_out_arr(0) => dp_fifo_sc_src_in,
snk_in_arr(0) => dp_pipeline_src_out,
snk_out_arr(0) => dp_pipeline_src_in,
src_out_arr(0) => dp_offload_tx_src_out,
src_in_arr(0) => dp_offload_tx_src_in,
......
......@@ -64,6 +64,7 @@ package tb_sdp_pkg is
ip_header_checksum : natural;
sdp_info : t_sdp_info; -- app header
gn_index : natural;
payload_error : std_logic;
beamlet_scale : natural;
beamlet_index : natural;
dp_bsn : natural) return t_sdp_cep_header;
......@@ -71,6 +72,7 @@ package tb_sdp_pkg is
function func_sdp_compose_cep_header(ip_header_checksum : natural;
sdp_info : t_sdp_info; -- app header
gn_index : natural;
payload_error : std_logic;
beamlet_scale : natural;
beamlet_index : natural;
dp_bsn : natural) return t_sdp_cep_header;
......@@ -283,6 +285,7 @@ package body tb_sdp_pkg is
ip_header_checksum : natural;
sdp_info : t_sdp_info; -- app header
gn_index : natural;
payload_error : std_logic;
beamlet_scale : natural;
beamlet_index : natural;
dp_bsn : natural) return t_sdp_cep_header is
......@@ -326,7 +329,7 @@ package body tb_sdp_pkg is
v_hdr.app.sdp_source_info_nyquist_zone_id := sdp_info.nyquist_zone_index;
v_hdr.app.sdp_source_info_f_adc := slv(sdp_info.f_adc);
v_hdr.app.sdp_source_info_fsub_type := slv(sdp_info.fsub_type);
v_hdr.app.sdp_source_info_payload_error := TO_UVEC(0, 1);
v_hdr.app.sdp_source_info_payload_error := slv(payload_error);
v_hdr.app.sdp_source_info_beam_repositioning_flag := slv(sdp_info.beam_repositioning_flag);
v_hdr.app.sdp_source_info_beamlet_width := TO_UVEC(c_sdp_W_beamlet, 4);
v_hdr.app.sdp_source_info_gn_id := TO_UVEC(gn_index, 8);
......@@ -345,6 +348,7 @@ package body tb_sdp_pkg is
function func_sdp_compose_cep_header(ip_header_checksum : natural;
sdp_info : t_sdp_info; -- app header
gn_index : natural;
payload_error : std_logic;
beamlet_scale : natural;
beamlet_index : natural;
dp_bsn : natural) return t_sdp_cep_header is
......@@ -356,6 +360,7 @@ package body tb_sdp_pkg is
ip_header_checksum,
sdp_info,
gn_index,
payload_error,
beamlet_scale,
beamlet_index,
dp_bsn);
......
......@@ -45,8 +45,10 @@
-- that is a power of 2, so g_fifo_size = true_log_pow2(largest block size +
-- c_fifo_tx_fill_margin).
-- Remark:
-- * The dp_fifo_fill_eop cannot handle continues stream of blocks without a
-- gap between blocks it needs 1 cycle to process a block.
-- * The dp_fifo_fill_eop can handle continues stream of blocks without a
-- gap between blocks, as shown by tb_dp_fifo_fill_eop.vhd, because
-- snk_out.ready remains active and the FIFO does not run full. This was
-- fixed by Reinier in Nov 2021 as part of L2SDP-505.
--
-------------------------------------------------------------------------------
......
......@@ -20,11 +20,22 @@
--------------------------------------------------------------------------------
-- Purpose:
-- . Merge g_nof_pkt input packets into one output packet
-- . Merge nof_pkt input packets into one output packet.
-- Description:
-- . Merge nof_pkt snk_in blocks per src_out block. If nof_pkt = 0 then there
-- is no output. If nof_pkt = 1 then the output is the same as the input.
-- . The output is the same as the registered input, except for the SOP and EOP
-- signal; these are overridden to create output packets as long as multiple (g_nof_pkt)
-- input packets.
-- signal; these are overridden to create output packets as long as multiple
-- (g_nof_pkt) input packets.
-- . Uses bsn of first snk_in block as bsn for merged output src_out block.
-- . The snk_in.err fields of the input blocks are OR-ed to reflect combined
-- error status of the merged blocks in src_out.err of the output block.
-- . When g_bsn_increment = 0 then the snk_in.bsn is not checked.
-- . When g_bsn_increment > 0 then the src_out.err[g_bsn_err_bi] = '1', if
-- the snk_in.bsn did not increment by g_bsn_increment for the merged snk_in
-- blocks in the src_out block. If the bsn increment for the merged blocks is
-- correct, then src_out.err[g_bsn_err_bi] = '0' to indicate that the
-- merged blocks are consecutive, so no input block got lost for this merge.
--
-- Remarks:
-- . g_nof_pkt statically sets the number of packets to merge into one in absence of
......@@ -165,7 +176,6 @@
-- . The advantage of this scheme it that it allows designing the function without flow
-- control according to scheme A). Then make nxt_r available instead of r and lead nxt_r
-- through dp_pipeline to register it and to add the flow control.
--
library IEEE,common_lib;
use IEEE.std_logic_1164.all;
......@@ -176,7 +186,9 @@ use work.dp_stream_pkg.all;
entity dp_packet_merge is
generic (
g_nof_pkt : natural;
g_align_at_sync : boolean := false
g_align_at_sync : boolean := false;
g_bsn_increment : natural := 0;
g_bsn_err_bi : natural := 0 -- bit index (bi) in scr_out.err for snk_in.bsn error
);
port (
rst : in std_logic;
......@@ -202,6 +214,8 @@ architecture rtl of dp_packet_merge is
align_cnt : natural range 0 to g_nof_pkt + 1;
busy : std_logic;
sync : std_logic;
next_bsn : std_logic_vector(c_dp_stream_bsn_w - 1 downto 0);
bsn_err : std_logic;
src_out : t_dp_sosi;
end record;
......@@ -224,7 +238,6 @@ begin
src_out <= r.src_out;
-- can put dp_hold_input here --
end generate;
gen_dp_latency_adapter : if c_use_dp_latency_adapter = true generate
......@@ -332,18 +345,27 @@ begin
if snk_in.sync = '1' then
v.src_out.sync := '1'; -- set out sync to '1' if this first block contains the sync.
end if;
v.next_bsn := INCR_UVEC(snk_in.bsn, g_bsn_increment); -- expected bsn for next snk_in block
v.bsn_err := '0'; -- bsn of first block is correct by default
else
if snk_in.sync = '1' then
v.sync := '1'; -- Capture sync if it occurs on a pkt_cnt /= 0 so we can use it in the next merged packet
end if;
v.next_bsn := INCR_UVEC(r.next_bsn, g_bsn_increment); -- expected bsn for next snk_in block
if unsigned(snk_in.bsn) /= unsigned(r.next_bsn) then
v.bsn_err := '1';
end if;
end if;
end if;
if snk_in.eop = '1' then
if r.pkt_cnt = 0 then
v.src_out.err := snk_in.err;
v.src_out.err := snk_in.err;
else
v.src_out.err := r.src_out.err or snk_in.err; -- OR the err fields of the packets to reflect combined error status.
v.src_out.err := r.src_out.err or snk_in.err; -- OR the err fields of the packets to reflect combined error status.
end if;
if g_bsn_increment > 0 then
v.src_out.err(g_bsn_err_bi) := r.bsn_err; -- report bsn error bit in case of missing snk_in block
end if;
if r.pkt_cnt = r.nof_pkt - 1 then
......@@ -369,6 +391,8 @@ begin
v.align_cnt := 0;
v.busy := '0';
v.sync := '0';
v.next_bsn := (others => '0');
v.bsn_err := '0';
v.src_out := c_dp_sosi_rst;
end if;
......
......@@ -47,7 +47,7 @@ use work.tb_dp_pkg.all;
entity tb_dp_fifo_fill_eop is
generic (
-- Try FIFO settings
g_dut_use_dual_clock : boolean := true;
g_dut_use_dual_clock : boolean := false;
g_dut_use_bsn : boolean := false;
g_dut_use_empty : boolean := false;
g_dut_use_channel : boolean := false;
......@@ -55,9 +55,10 @@ entity tb_dp_fifo_fill_eop is
g_dut_fifo_rl : natural := 1; -- internal RL, use 0 for look ahead FIFO, default 1 for normal FIFO
g_dut_fifo_size : natural := 128;
g_dut_fifo_fill : natural := 100; -- selectable >= 0 for dp_fifo_fill
g_block_size : natural := 14; -- to verify g_block_size > or < g_dut_fifo_fill
g_dut_use_rd_fill_32b : boolean := false;
g_dut_use_gap : boolean := true;
g_dut_use_random_ctrl : boolean := true
g_dut_use_gap : boolean := false;
g_dut_use_random_ctrl : boolean := false
);
end tb_dp_fifo_fill_eop;
......@@ -75,7 +76,7 @@ architecture tb of tb_dp_fifo_fill_eop is
constant c_tx_latency : natural := c_dut_in_latency; -- TX ready latency of TB
constant c_tx_void : natural := sel_a_b(c_tx_latency, 1, 0); -- used to avoid empty range VHDL warnings when c_tx_latency=0
constant c_tx_offset_sop : natural := 3;
constant c_tx_period_sop : natural := 14; -- sop in data valid cycle 3, 17, 31, ...
constant c_tx_period_sop : natural := g_block_size; -- sop in data valid cycle 3, 17, 31, ...
constant c_tx_offset_eop : natural := sel_a_b(g_dut_use_gap, 12, 16); -- eop in data valid cycle 12, 26, 40, ...
constant c_tx_period_eop : natural := c_tx_period_sop;
constant c_tx_offset_sync : natural := 3; -- sync in data valid cycle 3, 20, 37, ...
......@@ -115,6 +116,7 @@ architecture tb of tb_dp_fifo_fill_eop is
signal in_val : std_logic;
signal in_sop : std_logic;
signal in_eop : std_logic;
signal in_en : std_logic := '0';
signal wr_ful : std_logic;
signal rd_usedw : std_logic_vector(ceil_log2(largest(g_dut_fifo_size, g_dut_fifo_fill + c_dut_fifo_af_margin + 2)) - 1 downto 0);
......@@ -148,8 +150,6 @@ architecture tb of tb_dp_fifo_fill_eop is
begin
clk <= not clk or tb_end after clk_period / 2;
rst <= '1', '0' after clk_period * 7;
......@@ -159,7 +159,6 @@ begin
-- Input data
cnt_val <= in_ready and cnt_en and not gap_en when g_dut_use_random_ctrl else in_ready and not gap_en;
proc_dp_cnt_dat(rst, clk, cnt_val, cnt_dat);
proc_dp_tx_data(c_tx_latency, rst, clk, cnt_val, cnt_dat, tx_data, tx_val, in_data, in_val);
proc_dp_tx_ctrl(c_tx_offset_sync, c_tx_period_sync, in_data, in_val, in_sync);
......@@ -169,6 +168,23 @@ begin
proc_dp_tx_ctrl(c_tx_offset_gap, c_tx_period_gap, in_data, in_val, gap_en);
end generate;
-- Use in_en to ensure that in_sosi starts with in_sop, so no spurious
-- in_eop or in_val without an in_sop. The FIFO will ignore these
-- spurious in_eop or in_val, but for testing the fill_eop mechanism
-- it is more clear to test with only complete input blocks. The
-- general assumption is that only complete blocks are allowed to enter
-- the application code, so incomplete blocks are already avoided at the
-- external interface code of the FPGA and by making sure that FIFOs
-- will stop accepting new blocks before they would overflow.
p_in_en : process
begin
wait until in_sop = '1';
wait until in_eop = '1';
wait until in_sop = '1';
in_en <= '1';
wait;
end process;
in_bsn <= INCR_UVEC(in_data, c_bsn_offset);
in_empty <= INCR_UVEC(in_data, c_empty_offset);
in_channel <= INCR_UVEC(in_data, c_channel_offset);
......@@ -236,10 +252,10 @@ begin
in_sosi.bsn(c_dp_bsn_w - 1 downto 0) <= in_bsn(c_dp_bsn_w - 1 downto 0);
in_sosi.empty <= in_empty(c_dp_empty_w - 1 downto 0);
in_sosi.channel <= in_channel(c_dp_channel_w - 1 downto 0);
in_sosi.sync <= in_sync;
in_sosi.valid <= (in_val and not gap_en);
in_sosi.sop <= in_sop;
in_sosi.eop <= in_eop;
in_sosi.sync <= in_en and in_sync;
in_sosi.valid <= in_en and (in_val and not gap_en);
in_sosi.sop <= in_en and in_sop;
in_sosi.eop <= in_en and in_eop;
out_siso.ready <= out_ready; -- SISO
out_siso.xon <= '1';
......
......@@ -66,6 +66,9 @@ entity tb_dp_packet_merge is
g_pkt_len : natural := 10;
g_pkt_gap : natural := 0;
g_align_at_sync : boolean := false;
g_verify_bsn_err : boolean := false;
g_bsn_increment : natural := 2;
g_bsn_err_at_pkt_index : natural := 6; -- force wrong snk_in.bsn for packet with this index, in range(g_nof_repeat)
g_use_dp_packet_unmerge : boolean := false
);
end tb_dp_packet_merge;
......@@ -84,13 +87,17 @@ architecture tb of tb_dp_packet_merge is
constant c_data_max : unsigned(g_data_w - 1 downto 0) := (others => '1');
constant c_data_init : integer := -1;
constant c_bsn_init : std_logic_vector(c_dp_stream_bsn_w - 1 downto 0) := X"0000000000000000"; -- X"0877665544332211"
constant c_bsn_error : std_logic_vector(c_dp_stream_bsn_w - 1 downto 0) := (others => '1'); -- use -1 as bsn error value
constant c_err_init : natural := 247;
constant c_bsn_err_bi : natural := 31; -- use sufficiently high bsn error bit index, that is outside counter range of c_err_init
constant c_channel_init : integer := 5; -- fixed
constant c_nof_pkt_not_zero : natural := sel_a_b(g_nof_pkt = 0, 1, g_nof_pkt);
constant c_nof_merged_sop : natural := sel_a_b(g_nof_pkt = 0, 0, ceil_div(g_nof_repeat, c_nof_pkt_not_zero));
constant c_verify_at_least : natural := largest(1,c_nof_merged_sop / 2); -- verify that at least some packets have been merged, not exact to allow variation by p_stimuli_mm
constant c_verify_data_gap : natural := g_nof_pkt;
constant c_verify_bsn_gap : natural := g_nof_pkt * g_bsn_increment;
constant c_exp_err_at_pkt_index : natural := g_bsn_err_at_pkt_index / sel_a_b(g_nof_pkt = 0, 1, g_nof_pkt);
signal tb_end : std_logic := '0';
signal clk : std_logic := '1';
......@@ -123,6 +130,8 @@ architecture tb of tb_dp_packet_merge is
signal verify_snk_in : t_dp_sosi;
signal verify_data : std_logic_vector(g_data_w - 1 downto 0);
signal prev_verify_snk_in : t_dp_sosi;
signal merged_pkt_cnt : natural := 0;
signal merged_pkt_err : std_logic;
signal verify_hold_sop : std_logic := '0';
signal verify_en_valid : std_logic := '0';
......@@ -164,9 +173,10 @@ begin
-- Generate data path input data
p_stimuli_st : process
variable v_sosi : t_dp_sosi := c_dp_sosi_rst;
variable v_bsn : std_logic_vector(c_dp_stream_bsn_w - 1 downto 0);
begin
-- Adjust initial sosi field values by -1 to compensate for auto increment
v_sosi.bsn := INCR_UVEC(c_bsn_init, -1);
v_bsn := INCR_UVEC(c_bsn_init, -1);
v_sosi.channel := INCR_UVEC(TO_DP_CHANNEL(c_channel_init), -1);
v_sosi.data := INCR_UVEC(TO_DP_DATA(c_data_init), -1);
v_sosi.err := INCR_UVEC(TO_DP_ERROR(c_err_init), -1);
......@@ -178,13 +188,21 @@ begin
-- Generate c_nof_repeat packets
for I in 0 to g_nof_repeat - 1 loop
-- Auto increment v_sosi field values for this packet
v_sosi.bsn := INCR_UVEC(v_sosi.bsn, 1);
v_bsn := INCR_UVEC(v_bsn, g_bsn_increment);
v_sosi.bsn := v_bsn;
v_sosi.sync := sel_a_b((unsigned(v_sosi.bsn) mod c_sync_period) = c_sync_offset, '1', '0'); -- insert sync starting at BSN=c_sync_offset and with period c_sync_period
v_sosi.channel := INCR_UVEC(v_sosi.channel, 1);
v_sosi.data := INCR_UVEC(v_sosi.data, g_pkt_len);
v_sosi.data := RESIZE_DP_DATA(v_sosi.data(g_data_w - 1 downto 0)); -- wrap when >= 2**g_data_w
v_sosi.err := INCR_UVEC(v_sosi.err, 1);
-- Force bsn error in one snk_in block, to verify src_out.err(g_bsn_err_bi) bit
if g_verify_bsn_err = true then
if I = g_bsn_err_at_pkt_index then
v_sosi.bsn := c_bsn_error;
end if;
end if;
-- Send packet
proc_dp_gen_block_data(g_data_w, TO_UINT(v_sosi.data), g_pkt_len, TO_UINT(v_sosi.channel), TO_UINT(v_sosi.err), v_sosi.sync, v_sosi.bsn, clk, stimuli_en, stimuli_src_in, stimuli_src_out);
......@@ -235,9 +253,39 @@ begin
-- Verify that the output is incrementing data, like the input stimuli
proc_dp_verify_data("verify_snk_in.data", c_rl, c_data_max, c_unsigned_1, clk, verify_en_valid, verify_snk_out.ready, verify_snk_in.valid, verify_snk_in.data, prev_verify_snk_in.data);
proc_dp_verify_data("verify_snk_in.bsn", c_rl, c_unsigned_0, to_unsigned(c_verify_data_gap,32), clk, verify_en_sop, verify_snk_out.ready, verify_snk_in.sop, verify_snk_in.bsn, prev_verify_snk_in.bsn);
gen_verify_bsn_increment : if g_verify_bsn_err = false generate
proc_dp_verify_data("verify_snk_in.bsn", c_rl, c_unsigned_0, to_unsigned(c_verify_bsn_gap, 32), clk, verify_en_sop, verify_snk_out.ready, verify_snk_in.sop, verify_snk_in.bsn, prev_verify_snk_in.bsn);
gen_verify_err : if g_nof_pkt = 1 generate
-- Assume verifying g_nof_pkt = 1 is sufficient. Verifing g_nof_pkt > 1 is more difficult,
-- because the merged output error field is the bitwise OR of the input error fields
proc_dp_verify_data("verify_snk_in.err", c_rl, c_unsigned_0, to_unsigned(c_verify_data_gap,32), clk, verify_en_eop, verify_snk_out.ready, verify_snk_in.eop, verify_snk_in.err, prev_verify_snk_in.err);
end generate;
end generate;
proc_dp_verify_data("verify_snk_in.channel", c_rl, c_unsigned_0, to_unsigned(c_verify_data_gap,32), clk, verify_en_sop, verify_snk_out.ready, verify_snk_in.sop, verify_snk_in.channel, prev_verify_snk_in.channel);
-- Verify that the output bsn error bit is set if an input block was missed in a merge
merged_pkt_err <= verify_snk_in.err(c_bsn_err_bi);
gen_verify_bsn_err : if g_verify_bsn_err = true generate
p_verify_bsn_err : process(clk)
begin
if rising_edge(clk) then
-- count number of merged packets
if verify_snk_in.sop = '1' then
merged_pkt_cnt <= merged_pkt_cnt + 1;
end if;
-- verify err field for merged packet with input bsn error
if verify_snk_in.sop = '1' then
if merged_pkt_cnt = c_exp_err_at_pkt_index + 1 and g_bsn_increment > 0 then
assert merged_pkt_err = '1' report "Unexpected sosi.err = 0" severity ERROR;
else
assert merged_pkt_err = '0' report "Unexpected sosi.err = 1" severity ERROR;
end if;
end if;
end if;
end process;
end generate;
-- Verify output packet ctrl
proc_dp_verify_sop_and_eop(clk, verify_snk_in.valid, verify_snk_in.sop, verify_snk_in.eop, verify_hold_sop);
......@@ -256,7 +304,9 @@ begin
u_dp_packet_merge : entity work.dp_packet_merge
generic map (
g_nof_pkt => g_nof_pkt,
g_align_at_sync => g_align_at_sync
g_align_at_sync => g_align_at_sync,
g_bsn_increment => g_bsn_increment,
g_bsn_err_bi => c_bsn_err_bi
)
port map (
rst => rst,
......
......@@ -45,7 +45,19 @@ end tb_tb_dp_fifo_fill_eop;
architecture tb of tb_tb_dp_fifo_fill_eop is
signal tb_end : std_logic := '0'; -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end'
begin
-- Try FIFO settings : GENERIC MAP (g_dut_use_dual_clock, g_dut_use_bsn, g_dut_use_empty, g_dut_use_channel, g_dut_use_sync, g_dut_fifo_rl, g_dut_fifo_size, g_dut_fifo_fill, g_dut_use_rd_fill_32b, g_dut_use_gap, g_dut_use_random_ctrl)
-- Try FIFO settings
-- g_dut_use_dual_clock : boolean := true;
-- g_dut_use_bsn : boolean := false;
-- g_dut_use_empty : boolean := false;
-- g_dut_use_channel : boolean := false;
-- g_dut_use_sync : boolean := false;
-- g_dut_fifo_rl : natural := 1; -- internal RL, use 0 for look ahead FIFO, default 1 for normal FIFO
-- g_dut_fifo_size : natural := 128;
-- g_dut_fifo_fill : natural := 100; -- selectable >= 0 for dp_fifo_fill
-- g_block_size : natural := 14;
-- g_dut_use_rd_fill_32b : boolean := false;
-- g_dut_use_gap : boolean := true;
-- g_dut_use_random_ctrl : boolean := true
u_dut_sc_1 : entity work.tb_dp_fifo_fill_eop generic map (g_dut_use_dual_clock => false, g_dut_fifo_rl => 1, g_dut_use_random_ctrl => false);
u_dut_sc_1_no_gap : entity work.tb_dp_fifo_fill_eop generic map (g_dut_use_dual_clock => false, g_dut_fifo_rl => 1, g_dut_use_random_ctrl => false, g_dut_use_gap => false);
......@@ -59,4 +71,8 @@ begin
u_dut_dc_1_rand_no_gap : entity work.tb_dp_fifo_fill_eop generic map (g_dut_use_dual_clock => true, g_dut_fifo_rl => 1, g_dut_use_random_ctrl => true, g_dut_use_gap => false);
u_dut_sc_0_rand_no_gap : entity work.tb_dp_fifo_fill_eop generic map (g_dut_use_dual_clock => false, g_dut_fifo_rl => 0, g_dut_use_random_ctrl => true, g_dut_use_gap => false);
u_dut_dc_0_rand_no_gap : entity work.tb_dp_fifo_fill_eop generic map (g_dut_use_dual_clock => true, g_dut_fifo_rl => 0, g_dut_use_random_ctrl => true, g_dut_use_gap => false);
u_dut_sc_1_blk_gt_fill : entity work.tb_dp_fifo_fill_eop generic map (g_dut_use_dual_clock => false, g_dut_fifo_rl => 1, g_dut_use_random_ctrl => false, g_dut_use_gap => false,
g_dut_fifo_fill => 10, g_block_size => 20);
end tb;
......@@ -45,30 +45,39 @@ begin
-- g_flow_control_stimuli : t_dp_flow_control_enum := e_active; -- always active, random or pulse flow control
-- g_flow_control_verify : t_dp_flow_control_enum := e_active; -- always active, random or pulse flow control
-- -- specific
-- g_data_w : NATURAL := 4;
-- g_nof_repeat : NATURAL := 20;
-- g_nof_pkt : NATURAL := 3;
-- g_pkt_len : NATURAL := 29;
-- g_pkt_gap : NATURAL := 0;
-- g_align_at_sync : BOOLEAN := FALSE;
-- g_use_dp_packet_unmerge : BOOLEAN := FALSE
-- g_data_w : natural := 4;
-- g_nof_repeat : natural := 20;
-- g_nof_pkt : natural := 3;
-- g_pkt_len : natural := 29;
-- g_pkt_gap : natural := 0;
-- g_align_at_sync : boolean := false;
-- g_verify_bsn_err : boolean := false;
-- g_bsn_increment : natural := 0;
-- g_bsn_err_at_pkt_index : natural := 3;
-- g_use_dp_packet_unmerge : boolean := false
u_act_act_8_nof_0 : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 0, 29, 0, false, false);
u_act_act_8_nof_1 : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 1, 29, 0, false, false);
u_act_act_8_nof_2 : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 2, 29, 0, false, false);
u_act_act_8_nof_3 : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, false, false);
u_act_act_8_nof_4 : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 4, 29, 0, false, false);
u_act_act_8_nof_5 : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 5, 29, 0, false, false);
u_act_act_8_nof_6 : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 6, 29, 0, false, false);
u_act_act_8_nof_7 : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 7, 29, 0, false, false);
u_act_act_8_nof_0 : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 0, 29, 0, false, false, 1, 0, false);
u_act_act_8_nof_1 : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 1, 29, 0, false, false, 1, 0, false);
u_act_act_8_nof_2 : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 2, 29, 0, false, false, 1, 0, false);
u_act_act_8_nof_3 : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, false, false, 1, 0, false);
u_act_act_8_nof_4 : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 4, 29, 0, false, false, 1, 0, false);
u_act_act_8_nof_5 : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 5, 29, 0, false, false, 1, 0, false);
u_act_act_8_nof_6 : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 6, 29, 0, false, false, 1, 0, false);
u_act_act_8_nof_7 : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 7, 29, 0, false, false, 1, 0, false);
u_rnd_act_8_nof_3 : entity work.tb_dp_packet_merge generic map ( e_random, e_active, 8, c_nof_repeat, 3, 29, 0, false, false);
u_rnd_rnd_8_nof_3 : entity work.tb_dp_packet_merge generic map ( e_random, e_random, 8, c_nof_repeat, 3, 29, 0, false, false);
u_pls_act_8_nof_3 : entity work.tb_dp_packet_merge generic map ( e_pulse, e_active, 8, c_nof_repeat, 3, 29, 0, false, false);
u_pls_rnd_8_nof_3 : entity work.tb_dp_packet_merge generic map ( e_pulse, e_random, 8, c_nof_repeat, 3, 29, 0, false, false);
u_pls_pls_8_nof_3 : entity work.tb_dp_packet_merge generic map ( e_pulse, e_pulse, 8, c_nof_repeat, 3, 29, 0, false, false);
u_rnd_act_8_nof_3 : entity work.tb_dp_packet_merge generic map ( e_random, e_active, 8, c_nof_repeat, 3, 29, 0, false, false, 2, 0, false);
u_rnd_rnd_8_nof_3 : entity work.tb_dp_packet_merge generic map ( e_random, e_random, 8, c_nof_repeat, 3, 29, 0, false, false, 3, 0, false);
u_pls_act_8_nof_3 : entity work.tb_dp_packet_merge generic map ( e_pulse, e_active, 8, c_nof_repeat, 3, 29, 0, false, false, 4, 0, false);
u_pls_rnd_8_nof_3 : entity work.tb_dp_packet_merge generic map ( e_pulse, e_random, 8, c_nof_repeat, 3, 29, 0, false, false, 5, 0, false);
u_pls_pls_8_nof_3 : entity work.tb_dp_packet_merge generic map ( e_pulse, e_pulse, 8, c_nof_repeat, 3, 29, 0, false, false, 6, 0, false);
u_rnd_act_8_nof_1 : entity work.tb_dp_packet_merge generic map ( e_random, e_active, 8, c_nof_repeat, 1, 29, 0, false, false);
u_rnd_act_8_nof_3_gap : entity work.tb_dp_packet_merge generic map ( e_random, e_active, 8, c_nof_repeat, 3, 29, 17, false, false);
u_rnd_act_8_nof_1 : entity work.tb_dp_packet_merge generic map ( e_random, e_active, 8, c_nof_repeat, 1, 29, 0, false, false, 1, 0, false);
u_rnd_act_8_nof_3_gap : entity work.tb_dp_packet_merge generic map ( e_random, e_active, 8, c_nof_repeat, 3, 29, 17, false, false, 1, 0, false);
u_act_act_8_nof_3_no_err : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, false, true, 0, 10, false);
u_act_act_8_nof_3_err_10 : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, false, true, 1, 10, false);
u_act_act_8_nof_3_err_11 : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, false, true, 1, 11, false);
u_act_act_8_nof_3_err_12 : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, false, true, 1, 12, false);
u_act_act_8_nof_3_err_13 : entity work.tb_dp_packet_merge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, false, true, 1, 13, false);
end tb;
......@@ -21,16 +21,11 @@
-------------------------------------------------------------------------------
--
-- Author: R. van der Walle
--
-- Purpose: Implement the function of a complete ring lane by combining ring_lane/tx.
-- Description: See https://support.astron.nl/confluence/x/jyu7Ag
-- Description:
-- . See "L5 SDPFW Design Document: Ring" at https://support.astron.nl/confluence/x/jyu7Ag
-- Remark:
-- . Note that the dp_fifo_fill_eop in dp_block_validate_err cannot handle
-- continues stream of blocks without a gap between blocks the dp_fifo_fill_eop
-- needs 1 cycle to process a block. Streaming without gaps may cause the fifo
-- to overflow. Bursts of blocks can be handled by increasing gvalidate_err_fifo_size.
-------------------------------------------------------------------------------
library IEEE, common_lib, mm_lib, dp_lib;
use IEEE.std_logic_1164.all;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment