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

Added dp_offload_tx_v3

parent ab96e44a
No related branches found
No related tags found
2 merge requests!10Update branch to latest revision,!9Resolve L2SDP-23
...@@ -128,6 +128,7 @@ synth_files = ...@@ -128,6 +128,7 @@ synth_files =
src/vhdl/dp_field_blk.vhd src/vhdl/dp_field_blk.vhd
src/vhdl/dp_concat_field_blk.vhd src/vhdl/dp_concat_field_blk.vhd
src/vhdl/dp_offload_tx.vhd src/vhdl/dp_offload_tx.vhd
src/vhdl/dp_offload_tx_v3.vhd
src/vhdl/dp_offload_rx_filter.vhd src/vhdl/dp_offload_rx_filter.vhd
src/vhdl/dp_offload_rx_filter_mm.vhd src/vhdl/dp_offload_rx_filter_mm.vhd
src/vhdl/dp_offload_rx.vhd src/vhdl/dp_offload_rx.vhd
...@@ -289,6 +290,7 @@ test_bench_files = ...@@ -289,6 +290,7 @@ test_bench_files =
tb/vhdl/tb_tb_dp_xonoff.vhd tb/vhdl/tb_tb_dp_xonoff.vhd
tb/vhdl/tb_tb_tb_dp_backpressure.vhd tb/vhdl/tb_tb_tb_dp_backpressure.vhd
tb/vhdl/tb_dp_offload_tx_v3.vhd
tb/vhdl/tb_dp_offload_rx_filter.vhd tb/vhdl/tb_dp_offload_rx_filter.vhd
regression_test_vhdl = regression_test_vhdl =
......
-------------------------------------------------------------------------------
--
-- Copyright (C) 2017
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-------------------------------------------------------------------------------
-- Purpose:
-- . Concatenate a user-defined header to a DP frame e.g. to create an Ethernet frame
-- Description:
-- . The header contents can be controlled dynamically by data path or MM control (selected by g_hdr_field_sel)
-- . The header and data can be concatened at symbol level. The g_symbol_w defines the
-- resolution of the empty field. The g_data_w must be an integer multiple of the
-- g_symbol_w. If the empty field is not used or if the empty field is always 0 then
-- set g_symbol_w = g_data_w.
-- . For example to concat header and data for an Ethernet frame use:
-- - g_data_w = 32 (1GbE) or 64 (10GbE)
-- - g_symbol_w = c_byte_w = 8 if either the header or the data can have an
-- non-zero empty field, so when they are not a multiple of 4 bytes
-- (= 32b) or 8 bytes (= 64b).
-- g_symbol_w = g_data_w if the empty field is always 0, so the number of bits in
-- the header and data are an integer number of g_data_w.
LIBRARY IEEE, common_lib, technology_lib, mm_lib;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
USE work.dp_stream_pkg.ALL;
USE common_lib.common_field_pkg.ALL;
USE technology_lib.technology_select_pkg.ALL;
ENTITY dp_offload_tx_v3 IS
GENERIC (
g_nof_streams : NATURAL;
g_data_w : NATURAL;
g_symbol_w : NATURAL;
g_hdr_field_arr : t_common_field_arr; -- User defined header fields
g_hdr_field_sel : STD_LOGIC_VECTOR; -- For each header field, select the source: 0=data path, 1=MM controlled
g_pipeline_ready : BOOLEAN := FALSE
);
PORT (
mm_rst : IN STD_LOGIC;
mm_clk : IN STD_LOGIC;
dp_rst : IN STD_LOGIC;
dp_clk : IN STD_LOGIC;
reg_hdr_dat_mosi : IN t_mem_mosi := c_mem_mosi_rst;
reg_hdr_dat_miso : OUT t_mem_miso;
snk_in_arr : IN t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
snk_out_arr : OUT t_dp_siso_arr(g_nof_streams-1 DOWNTO 0);
src_out_arr : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
src_in_arr : IN t_dp_siso_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>c_dp_siso_rdy);
hdr_fields_in_arr : IN t_slv_1024_arr(g_nof_streams-1 DOWNTO 0); -- hdr_fields_in_arr(i) is considered valid @ snk_in_arr(i).sop
hdr_fields_out_arr : OUT t_slv_1024_arr(g_nof_streams-1 DOWNTO 0)
);
END dp_offload_tx_v3;
ARCHITECTURE str OF dp_offload_tx_v3 IS
CONSTANT c_dp_field_blk_snk_data_w : NATURAL := field_slv_out_len(field_arr_set_mode(g_hdr_field_arr , "RW"));
CONSTANT c_dp_field_blk_src_data_w : NATURAL := g_data_w;
SIGNAL dbg_c_dp_field_blk_snk_data_w : NATURAL := c_dp_field_blk_snk_data_w;
SIGNAL dbg_c_dp_field_blk_src_data_w : NATURAL := c_dp_field_blk_src_data_w;
SIGNAL dp_field_blk_snk_in_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL dp_field_blk_snk_out_arr : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL dp_field_blk_src_out_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL dp_field_blk_src_in_arr : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL dp_concat_snk_in_2arr : t_dp_sosi_2arr_2(g_nof_streams-1 DOWNTO 0);
SIGNAL dp_concat_snk_out_2arr : t_dp_siso_2arr_2(g_nof_streams-1 DOWNTO 0);
SIGNAL reg_hdr_dat_mosi_arr : t_mem_mosi_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL reg_hdr_dat_miso_arr : t_mem_miso_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL mm_fields_slv_out_arr : t_slv_1024_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL field_override_arr : STD_LOGIC_VECTOR(g_hdr_field_arr'RANGE) := g_hdr_field_sel; --1 override bit per field
BEGIN
ASSERT c_dp_field_blk_snk_data_w <= c_dp_stream_data_w REPORT "Number of header bits must fit in t_dp_sosi data field." SEVERITY FAILURE;
---------------------------------------------------------------------------------------
-- Create header block & concatenate header to offload stream.
---------------------------------------------------------------------------------------
p_wire_valid : PROCESS(snk_in_arr, hdr_fields_in_arr)
BEGIN
FOR i IN 0 TO g_nof_streams-1 LOOP
-- default pass on the other snk_in_arr fields as well, especially the sync, bsn and channel can
-- be useful to preserve for the packetized output, even though only the sosi.data of the
-- packetized output will get transmitted.
dp_field_blk_snk_in_arr(i) <= snk_in_arr(i);
-- Prepare packet header as a data block with only one data word, so valid = sop = eop. If
-- c_dp_field_blk_snk_data_w > c_dp_field_blk_src_data_w then dp_repack_data in dp_field_blk will
-- repack this data word into a multi word header block, else dp_field_blk will pass on the
-- dp_field_blk_snk_in_arr as a single word header block.
dp_field_blk_snk_in_arr(i).data <= RESIZE_DP_DATA(hdr_fields_in_arr(i)(field_slv_len(g_hdr_field_arr)-1 DOWNTO 0));
dp_field_blk_snk_in_arr(i).valid <= snk_in_arr(i).sop;
dp_field_blk_snk_in_arr(i).sop <= snk_in_arr(i).sop; -- necessary for single word header block
dp_field_blk_snk_in_arr(i).eop <= snk_in_arr(i).sop; -- necessary for single word header block
END LOOP;
END PROCESS;
gen_dp_field_blk : FOR i IN 0 TO g_nof_streams-1 GENERATE
-- Both dp_concat inputs must be ready. One of the inputs toggles ready via dp_field_blk.
snk_out_arr(i).ready <= dp_field_blk_snk_out_arr(i).ready AND dp_concat_snk_out_2arr(i)(0).ready;
snk_out_arr(i).xon <= src_in_arr(i).xon;
-- Wire hdr_fields_out_arr
-- MM override bits determine source for each field
gen_field_wires: FOR j IN g_hdr_field_arr'RANGE GENERATE
hdr_fields_out_arr(i)(field_hi(g_hdr_field_arr, j) DOWNTO field_lo(g_hdr_field_arr, j)) <= mm_fields_slv_out_arr(i)(field_hi(g_hdr_field_arr, j) DOWNTO field_lo(g_hdr_field_arr, j))
WHEN field_override_arr(j) = '1' ELSE
hdr_fields_in_arr(i)(field_hi(g_hdr_field_arr, j) DOWNTO field_lo(g_hdr_field_arr, j));
END GENERATE;
---------------------------------------------------------------------------------------
-- mm_fields for MM access to each field
---------------------------------------------------------------------------------------
u_mm_fields_slv: ENTITY mm_lib.mm_fields
GENERIC MAP(
g_field_arr => field_arr_set_mode(g_hdr_field_arr , "RW")
)
PORT MAP (
mm_clk => mm_clk,
mm_rst => mm_rst,
mm_mosi => reg_hdr_dat_mosi_arr(i),
mm_miso => OPEN, -- Not used
slv_clk => dp_clk,
slv_rst => dp_rst,
slv_out => mm_fields_slv_out_arr(i)(field_slv_len(g_hdr_field_arr)-1 DOWNTO 0)
);
-- Create multi-cycle header block from single-cycle wide header SLV
u_dp_field_blk : ENTITY work.dp_field_blk
GENERIC MAP (
g_field_arr => field_arr_set_mode(g_hdr_field_arr , "RW"),
g_field_sel => g_hdr_field_sel,
g_snk_data_w => c_dp_field_blk_snk_data_w,
g_src_data_w => c_dp_field_blk_src_data_w,
g_in_symbol_w => g_symbol_w,
g_out_symbol_w => g_symbol_w,
g_pipeline_ready => g_pipeline_ready
)
PORT MAP (
dp_clk => dp_clk,
dp_rst => dp_rst,
mm_clk => mm_clk,
mm_rst => mm_rst,
snk_in => dp_field_blk_snk_in_arr(i),
snk_out => dp_field_blk_snk_out_arr(i),
src_out => dp_field_blk_src_out_arr(i),
src_in => dp_field_blk_src_in_arr(i),
reg_slv_mosi => reg_hdr_dat_mosi_arr(i),
reg_slv_miso => reg_hdr_dat_miso_arr(i)
);
dp_field_blk_src_in_arr(i) <= dp_concat_snk_out_2arr(i)(1);
END GENERATE;
-- Prepend the header block to the input block
gen_dp_concat : FOR i IN 0 TO g_nof_streams-1 GENERATE
dp_concat_snk_in_2arr(i)(0) <= snk_in_arr(i);
dp_concat_snk_in_2arr(i)(1) <= dp_field_blk_src_out_arr(i);
u_dp_concat : ENTITY work.dp_concat
GENERIC MAP (
g_data_w => g_data_w,
g_symbol_w => g_symbol_w
)
PORT MAP (
rst => dp_rst,
clk => dp_clk,
snk_out_arr => dp_concat_snk_out_2arr(i),
snk_in_arr => dp_concat_snk_in_2arr(i),
src_in => src_in_arr(i),
src_out => src_out_arr(i)
);
END GENERATE;
---------------------------------------------------------------------------------------
-- MM control & monitoring
---------------------------------------------------------------------------------------
u_common_mem_mux_hdr_dat : ENTITY common_lib.common_mem_mux
GENERIC MAP (
g_nof_mosi => g_nof_streams,
g_mult_addr_w => ceil_log2(field_nof_words(g_hdr_field_arr, c_word_w))
)
PORT MAP (
mosi => reg_hdr_dat_mosi,
miso => reg_hdr_dat_miso,
mosi_arr => reg_hdr_dat_mosi_arr,
miso_arr => reg_hdr_dat_miso_arr
);
END str;
-------------------------------------------------------------------------------
--
-- Copyright (C) 2015
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-------------------------------------------------------------------------------
-- Purpose:
-- . Test bench for dp_offload_tx_v3 and dp_offload_rx
-- Description:
-- u_tx u_rx
-- ___________________ ___________________
-- |dp_offload_tx_v3| |dp_offload_rx |
-- stimuli_src -->| |--->| |--> verify_snk
-- | in out | | | in out |
-- |___________________| | |___________________|
-- |
-- link_offload_sosi
-- Usage:
-- > as 10
-- > run -all
--
LIBRARY IEEE, common_lib;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_lfsr_sequences_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
USE common_lib.common_field_pkg.ALL;
USE common_lib.tb_common_pkg.ALL;
USE work.dp_stream_pkg.ALL;
USE work.tb_dp_pkg.ALL;
ENTITY tb_dp_offload_tx_v3 IS
GENERIC (
-- general
g_flow_control_stimuli : t_dp_flow_control_enum := e_pulse; -- always e_active, e_random or e_pulse flow control
g_flow_control_verify : t_dp_flow_control_enum := e_active; -- always e_active, e_random or e_pulse flow control
-- specific
g_data_w : NATURAL := 64;
g_nof_repeat : NATURAL := 100;
g_pkt_len : NATURAL := 240;
g_pkt_gap : NATURAL := 16
);
END tb_dp_offload_tx_v3;
ARCHITECTURE tb OF tb_dp_offload_tx_v3 IS
CONSTANT c_mm_clk_period : TIME := 1 ns;
CONSTANT c_dp_clk_period : TIME := 5 ns;
-- dp_stream_stimuli
CONSTANT c_stimuli_pulse_active : NATURAL := 3;
CONSTANT c_stimuli_pulse_period : NATURAL := 4;
-- dp_stream_verify
CONSTANT c_verify_pulse_active : NATURAL := 1;
CONSTANT c_verify_pulse_period : NATURAL := 5;
CONSTANT c_data_max : UNSIGNED(g_data_w-1 DOWNTO 0) := (OTHERS=>'1');
CONSTANT c_dsp_max : UNSIGNED(g_data_w-1 DOWNTO 0) := (OTHERS=>'1');
--CONSTANT c_verify_snk_in_cnt_max : t_dp_sosi_unsigned := c_dp_sosi_unsigned_rst; -- default 0 is no wrap
CONSTANT c_verify_snk_in_cnt_max : t_dp_sosi_unsigned := TO_DP_SOSI_UNSIGNED('0', '0', '0', '0', c_data_max, c_dsp_max, c_dsp_max, c_unsigned_0, c_unsigned_0, c_unsigned_0, c_unsigned_0);
CONSTANT c_verify_snk_in_cnt_gap : t_dp_sosi_unsigned := c_dp_sosi_unsigned_ones; -- default only accept increment +1
CONSTANT c_expected_pkt_len : NATURAL := g_pkt_len;
CONSTANT c_sync_period : NATURAL := 5;
CONSTANT c_sync_offset : NATURAL := 2;
CONSTANT c_hdr_len : NATURAL := 7;
CONSTANT c_wait_last_evt : NATURAL := 100 + g_nof_repeat * c_hdr_len;
-----------------------------------------------------------------------------
-- Tx offload
-----------------------------------------------------------------------------
-- From apertif_udp_offload_pkg.vhd:
CONSTANT c_udp_offload_nof_hdr_fields : NATURAL := 3+12+4+3; -- 448b; 7 64b words
-- Notes:
-- . pre-calculated ip_header_checksum is valid only for UNB0, FN0 targeting IP 10.10.10.10
-- . udp_total_length = 176 beamlets * 64b / 8b = 1408B + 14 DP bytes + 8 UDP bytes = 1430B
CONSTANT c_udp_offload_hdr_field_arr : t_common_field_arr(c_udp_offload_nof_hdr_fields-1 DOWNTO 0) := (
( field_name_pad("eth_dst_mac" ), "RW", 48, field_default(x"001B214368AC") ),
( field_name_pad("eth_src_mac" ), "RW", 48, field_default(0) ),
( field_name_pad("eth_type" ), "RW", 16, field_default(x"0800") ),
( field_name_pad("ip_version" ), "RW", 4, field_default(4) ),
( field_name_pad("ip_header_length" ), "RW", 4, field_default(5) ),
( field_name_pad("ip_services" ), "RW", 8, field_default(0) ),
( field_name_pad("ip_total_length" ), "RW", 16, field_default(1450) ),
( field_name_pad("ip_identification" ), "RW", 16, field_default(0) ),
( field_name_pad("ip_flags" ), "RW", 3, field_default(2) ),
( field_name_pad("ip_fragment_offset" ), "RW", 13, field_default(0) ),
( field_name_pad("ip_time_to_live" ), "RW", 8, field_default(127) ),
( field_name_pad("ip_protocol" ), "RW", 8, field_default(17) ),
( field_name_pad("ip_header_checksum" ), "RW", 16, field_default(29928) ),
( field_name_pad("ip_src_addr" ), "RW", 32, field_default(x"C0A80009") ),
( field_name_pad("ip_dst_addr" ), "RW", 32, field_default(x"C0A80001") ),
( field_name_pad("udp_src_port" ), "RW", 16, field_default(0) ),
( field_name_pad("udp_dst_port" ), "RW", 16, field_default(0) ),
( field_name_pad("udp_total_length" ), "RW", 16, field_default(1430) ),
( field_name_pad("udp_checksum" ), "RW", 16, field_default(0) ),
( field_name_pad("dp_reserved" ), "RW", 47, field_default(0) ),
( field_name_pad("dp_sync" ), "RW", 1, field_default(0) ),
( field_name_pad("dp_bsn" ), "RW", 64, field_default(0) ) );
-- From apertif_unb1_fn_beamformer_udp_offload.vhd:
-- Override ('1') only the Ethernet fields so we can use MM defaults there.
CONSTANT c_hdr_field_ovr_init : STD_LOGIC_VECTOR(c_udp_offload_nof_hdr_fields-1 DOWNTO 0) := "101"&"111111111111"&"1111"&"100";
CONSTANT c_NODE_ID : STD_LOGIC_VECTOR(7 DOWNTO 0) := TO_UVEC(0, 8);
SIGNAL id_backplane : STD_LOGIC_VECTOR(c_byte_w-1 DOWNTO 0);
SIGNAL id_chip : STD_LOGIC_VECTOR(c_byte_w-1 DOWNTO 0);
SIGNAL dp_fifo_sc_src_in : t_dp_siso := c_dp_siso_rdy;
SIGNAL dp_fifo_sc_src_out : t_dp_sosi;
SIGNAL dp_offload_tx_snk_in_arr : t_dp_sosi_arr(0 DOWNTO 0);
SIGNAL dp_offload_tx_snk_out_arr : t_dp_siso_arr(0 DOWNTO 0);
SIGNAL tx_hdr_fields_in_arr : t_slv_1024_arr(0 DOWNTO 0);
SIGNAL tx_hdr_fields_out_arr : t_slv_1024_arr(0 DOWNTO 0);
SIGNAL reg_dp_offload_tx_hdr_dat_mosi : t_mem_mosi := c_mem_mosi_rst;
SIGNAL reg_dp_offload_tx_hdr_dat_miso : t_mem_miso;
-----------------------------------------------------------------------------
-- Link
-----------------------------------------------------------------------------
SIGNAL tx_offload_sosi_arr : t_dp_sosi_arr(0 DOWNTO 0);
SIGNAL tx_offload_siso_arr : t_dp_siso_arr(0 DOWNTO 0);
SIGNAL link_offload_sosi_arr : t_dp_sosi_arr(0 DOWNTO 0);
SIGNAL link_offload_siso_arr : t_dp_siso_arr(0 DOWNTO 0);
-----------------------------------------------------------------------------
-- Rx offload
-----------------------------------------------------------------------------
SIGNAL dp_offload_rx_src_out_arr : t_dp_sosi_arr(0 DOWNTO 0);
SIGNAL dp_offload_rx_src_in_arr : t_dp_siso_arr(0 DOWNTO 0);
SIGNAL rx_hdr_fields_out_arr : t_slv_1024_arr(0 DOWNTO 0);
SIGNAL rx_hdr_fields_raw_arr : t_slv_1024_arr(0 DOWNTO 0);
SIGNAL reg_dp_offload_rx_hdr_dat_mosi : t_mem_mosi := c_mem_mosi_rst;
SIGNAL reg_dp_offload_rx_hdr_dat_miso : t_mem_miso;
-----------------------------------------------------------------------------
-- Test
-----------------------------------------------------------------------------
SIGNAL mm_clk : STD_LOGIC := '1';
SIGNAL mm_rst : STD_LOGIC := '1';
SIGNAL dp_clk : STD_LOGIC := '1';
SIGNAL dp_rst : STD_LOGIC := '1';
SIGNAL tb_end : STD_LOGIC := '0';
SIGNAL stimuli_src_in : t_dp_siso := c_dp_siso_rdy;
SIGNAL stimuli_src_out : t_dp_sosi;
SIGNAL stimuli_src_out_data : STD_LOGIC_VECTOR(g_data_w-1 DOWNTO 0);
SIGNAL verify_snk_in_enable : t_dp_sosi_sl := c_dp_sosi_sl_rst;
SIGNAL last_snk_in : t_dp_sosi;
SIGNAL last_snk_in_evt : STD_LOGIC;
SIGNAL verify_last_snk_in_evt : t_dp_sosi_sl := c_dp_sosi_sl_rst;
SIGNAL verify_snk_out : t_dp_siso := c_dp_siso_rdy;
SIGNAL verify_snk_in : t_dp_sosi;
SIGNAL verify_snk_in_data : STD_LOGIC_VECTOR(g_data_w-1 DOWNTO 0);
BEGIN
------------------------------------------------------------------------------
-- Clock & reset
------------------------------------------------------------------------------
mm_clk <= (NOT mm_clk) OR tb_end AFTER c_mm_clk_period/2;
mm_rst <= '1', '0' AFTER c_mm_clk_period*7;
dp_clk <= (NOT dp_clk) OR tb_end AFTER c_dp_clk_period/2;
dp_rst <= '1', '0' AFTER c_dp_clk_period*7;
------------------------------------------------------------------------------
-- DATA GENERATION
------------------------------------------------------------------------------
u_dp_stream_stimuli : ENTITY work.dp_stream_stimuli
GENERIC MAP (
g_instance_nr => 0, -- only one stream so choose index 0
-- flow control
g_random_w => 15, -- use different random width for stimuli and for verify to have different random sequences
g_pulse_active => c_stimuli_pulse_active,
g_pulse_period => c_stimuli_pulse_period,
g_flow_control => g_flow_control_stimuli, -- always active, random or pulse flow control
-- initializations
g_sync_period => c_sync_period,
g_sync_offset => c_sync_offset,
-- specific
g_in_dat_w => g_data_w,
g_nof_repeat => g_nof_repeat,
g_pkt_len => g_pkt_len,
g_pkt_gap => g_pkt_gap,
g_wait_last_evt => c_wait_last_evt
)
PORT MAP (
rst => dp_rst,
clk => dp_clk,
-- Generate stimuli
src_in => stimuli_src_in,
src_out => stimuli_src_out,
-- End of stimuli
last_snk_in => last_snk_in, -- expected verify_snk_in after end of stimuli
last_snk_in_evt => last_snk_in_evt, -- trigger verify to verify the last_snk_in
tb_end => tb_end -- signal end of tb as far as this dp_stream_stimuli is concerned
);
------------------------------------------------------------------------------
-- DATA VERIFICATION
------------------------------------------------------------------------------
-- Select fields that need to be verified
-- . during the test
verify_snk_in_enable.sync <= '1';
verify_snk_in_enable.bsn <= '1';
verify_snk_in_enable.data <= '1';
verify_snk_in_enable.re <= '0';
verify_snk_in_enable.im <= '0';
verify_snk_in_enable.valid <= '1';
verify_snk_in_enable.sop <= '1';
verify_snk_in_enable.eop <= '1';
verify_snk_in_enable.empty <= '0';
verify_snk_in_enable.channel <= '0';
verify_snk_in_enable.err <= '0';
-- . after the test
verify_last_snk_in_evt.sync <= last_snk_in_evt;
verify_last_snk_in_evt.bsn <= last_snk_in_evt; -- thanks to using rx_hdr_fields_raw_arr for bsn field
verify_last_snk_in_evt.data <= last_snk_in_evt;
verify_last_snk_in_evt.re <= '0';
verify_last_snk_in_evt.im <= '0';
verify_last_snk_in_evt.valid <= last_snk_in_evt;
verify_last_snk_in_evt.sop <= last_snk_in_evt;
verify_last_snk_in_evt.eop <= last_snk_in_evt;
verify_last_snk_in_evt.empty <= '0';
verify_last_snk_in_evt.channel <= '0';
verify_last_snk_in_evt.err <= '0';
u_dp_stream_verify : ENTITY work.dp_stream_verify
GENERIC MAP (
g_instance_nr => 0, -- only one stream so choose index 0
-- flow control
g_random_w => 14, -- use different random width for stimuli and for verify to have different random sequences
g_pulse_active => c_verify_pulse_active,
g_pulse_period => c_verify_pulse_period,
g_flow_control => g_flow_control_verify, -- always active, random or pulse flow control
-- initializations
g_sync_period => c_sync_period,
g_sync_offset => c_sync_offset,
g_snk_in_cnt_max => c_verify_snk_in_cnt_max,
g_snk_in_cnt_gap => c_verify_snk_in_cnt_gap,
-- specific
g_in_dat_w => g_data_w,
g_pkt_len => c_expected_pkt_len
)
PORT MAP (
rst => dp_rst,
clk => dp_clk,
-- Verify data
snk_out => verify_snk_out,
snk_in => verify_snk_in,
-- During stimuli
verify_snk_in_enable => verify_snk_in_enable, -- enable verify to verify that the verify_snk_in fields are incrementing
-- End of stimuli
expected_snk_in => last_snk_in, -- expected verify_snk_in after end of stimuli
verify_expected_snk_in_evt => verify_last_snk_in_evt -- trigger verify to verify the last_snk_in
);
------------------------------------------------------------------------------
-- DUT offload Tx
------------------------------------------------------------------------------
stimuli_src_in <= c_dp_siso_rdy;
-- Use FIFO to mimic apertif_unb1_fn_beamformer_udp_offload.vhd, without FIFO dp_stream_stimuli
-- would handle the back pressure
u_dp_fifo_sc : ENTITY work.dp_fifo_sc
GENERIC MAP (
g_data_w => g_data_w,
g_bsn_w => 64,
g_use_sync => TRUE,
g_use_bsn => TRUE,
g_fifo_size => 1024
)
PORT MAP (
rst => dp_rst,
clk => dp_clk,
snk_out => OPEN, -- stimuli_src_in
snk_in => stimuli_src_out,
src_in => dp_fifo_sc_src_in,
src_out => dp_fifo_sc_src_out
);
dp_offload_tx_snk_in_arr(0) <= dp_fifo_sc_src_out;
dp_fifo_sc_src_in <= dp_offload_tx_snk_out_arr(0);
-- Extract the chip and backplane numbers from c_NODE_ID
id_backplane <= RESIZE_UVEC(c_NODE_ID(7 DOWNTO 3), c_byte_w);
id_chip <= RESIZE_UVEC(c_NODE_ID(2 DOWNTO 0), c_byte_w);
-- Wire the hardwired header fields to DP signals and c_NODE_ID
tx_hdr_fields_in_arr(0)(field_hi(c_udp_offload_hdr_field_arr, "eth_src_mac" ) DOWNTO field_lo(c_udp_offload_hdr_field_arr, "eth_src_mac" )) <= x"00228608" & id_backplane & id_chip;
tx_hdr_fields_in_arr(0)(field_hi(c_udp_offload_hdr_field_arr, "udp_src_port") DOWNTO field_lo(c_udp_offload_hdr_field_arr, "udp_src_port" )) <= x"D0" & c_NODE_ID;
tx_hdr_fields_in_arr(0)(field_hi(c_udp_offload_hdr_field_arr, "udp_dst_port") DOWNTO field_lo(c_udp_offload_hdr_field_arr, "udp_dst_port" )) <= x"D0" & c_NODE_ID;
tx_hdr_fields_in_arr(0)(field_hi(c_udp_offload_hdr_field_arr, "ip_src_addr" ) DOWNTO field_lo(c_udp_offload_hdr_field_arr, "ip_src_addr" )) <= x"0A63" & id_backplane & INCR_UVEC(id_chip, 1);
tx_hdr_fields_in_arr(0)(field_hi(c_udp_offload_hdr_field_arr, "dp_sync" ) DOWNTO field_lo(c_udp_offload_hdr_field_arr, "dp_sync" )) <= slv(dp_offload_tx_snk_in_arr(0).sync);
tx_hdr_fields_in_arr(0)(field_hi(c_udp_offload_hdr_field_arr, "dp_bsn" ) DOWNTO field_lo(c_udp_offload_hdr_field_arr, "dp_bsn" )) <= dp_offload_tx_snk_in_arr(0).bsn(63 DOWNTO 0);
u_tx : ENTITY work.dp_offload_tx_v3
GENERIC MAP (
g_nof_streams => 1,
g_data_w => g_data_w,
g_symbol_w => g_data_w,
g_hdr_field_arr => c_udp_offload_hdr_field_arr,
g_hdr_field_sel => c_hdr_field_ovr_init
)
PORT MAP (
mm_rst => mm_rst,
mm_clk => mm_clk,
dp_rst => dp_rst,
dp_clk => dp_clk,
reg_hdr_dat_mosi => reg_dp_offload_tx_hdr_dat_mosi,
reg_hdr_dat_miso => reg_dp_offload_tx_hdr_dat_miso,
snk_in_arr => dp_offload_tx_snk_in_arr,
snk_out_arr => dp_offload_tx_snk_out_arr,
src_out_arr => tx_offload_sosi_arr,
src_in_arr => tx_offload_siso_arr,
hdr_fields_in_arr => tx_hdr_fields_in_arr,
hdr_fields_out_arr => tx_hdr_fields_out_arr
);
------------------------------------------------------------------------------
-- Link
------------------------------------------------------------------------------
p_link_offload : PROCESS(tx_offload_sosi_arr, link_offload_siso_arr)
BEGIN
-- Model active packet fields of tr_10GbE Rx sosi output interface
link_offload_sosi_arr(0) <= c_dp_sosi_rst;
link_offload_sosi_arr(0).data <= tx_offload_sosi_arr(0).data;
link_offload_sosi_arr(0).empty <= tx_offload_sosi_arr(0).empty;
link_offload_sosi_arr(0).valid <= tx_offload_sosi_arr(0).valid;
link_offload_sosi_arr(0).sop <= tx_offload_sosi_arr(0).sop;
link_offload_sosi_arr(0).eop <= tx_offload_sosi_arr(0).eop;
tx_offload_siso_arr <= (OTHERS=>c_dp_siso_rdy);
END PROCESS;
------------------------------------------------------------------------------
-- DUT offload Rx
------------------------------------------------------------------------------
u_rx : ENTITY work.dp_offload_rx
GENERIC MAP (
g_nof_streams => 1,
g_data_w => g_data_w,
g_hdr_field_arr => c_udp_offload_hdr_field_arr,
g_remove_crc => FALSE,
g_crc_nof_words => 0
)
PORT MAP (
mm_rst => mm_rst,
mm_clk => mm_clk,
dp_rst => dp_rst,
dp_clk => dp_clk,
reg_hdr_dat_mosi => reg_dp_offload_rx_hdr_dat_mosi,
reg_hdr_dat_miso => reg_dp_offload_rx_hdr_dat_miso,
snk_in_arr => link_offload_sosi_arr,
snk_out_arr => link_offload_siso_arr,
src_out_arr => dp_offload_rx_src_out_arr,
src_in_arr => dp_offload_rx_src_in_arr,
hdr_fields_out_arr => rx_hdr_fields_out_arr,
hdr_fields_raw_arr => rx_hdr_fields_raw_arr
);
p_restore_sync_bsn : PROCESS(dp_offload_rx_src_out_arr, rx_hdr_fields_out_arr)
BEGIN
verify_snk_in <= dp_offload_rx_src_out_arr(0);
verify_snk_in.sync <= sl(rx_hdr_fields_out_arr(0)(field_hi(c_udp_offload_hdr_field_arr, "dp_sync") DOWNTO field_lo(c_udp_offload_hdr_field_arr, "dp_sync" )));
verify_snk_in.bsn <= RESIZE_UVEC(rx_hdr_fields_raw_arr(0)(field_hi(c_udp_offload_hdr_field_arr, "dp_bsn" ) DOWNTO field_lo(c_udp_offload_hdr_field_arr, "dp_bsn" )), c_dp_stream_bsn_w);
END PROCESS;
dp_offload_rx_src_in_arr <= (OTHERS=>c_dp_siso_rdy);
dp_offload_rx_src_in_arr(0) <= verify_snk_out;
------------------------------------------------------------------------------
-- Auxiliary
------------------------------------------------------------------------------
-- Map to slv to ease monitoring in wave window
stimuli_src_out_data <= stimuli_src_out.data(g_data_w-1 DOWNTO 0);
verify_snk_in_data <= verify_snk_in.data(g_data_w-1 DOWNTO 0);
END tb;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment