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

Added tb for dp_concat_field_blk + dp_offload_rx.

parent 4f439b07
No related branches found
No related tags found
No related merge requests found
......@@ -203,6 +203,7 @@ test_bench_files =
tb/vhdl/tb_dp_mux.vhd
tb/vhdl/tb2_dp_mux.vhd
tb/vhdl/tb3_dp_mux.vhd
tb/vhdl/tb_dp_concat_field_blk.vhd
tb/vhdl/tb_dp_packet.vhd
tb/vhdl/tb_dp_packet_merge.vhd
tb/vhdl/tb_dp_packetizing.vhd
......
-------------------------------------------------------------------------------
--
-- 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_concat_field_blk and dp_offload_rx
-- Description:
-- u_tx u_rx
-- ___________________ ___________________
-- |dp_concat_field_blk| |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_concat_field_blk IS
GENERIC (
-- general
g_flow_control_stimuli : t_dp_flow_control_enum := e_active; -- 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 := 13;
g_pkt_len : NATURAL := 100;
g_pkt_gap : NATURAL := 30
);
END tb_dp_concat_field_blk;
ARCHITECTURE tb OF tb_dp_concat_field_blk 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 := 7;
-- 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;
-----------------------------------------------------------------------------
-- 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_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 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 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
)
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 <= '0'; -- in rx_hdr_fields_out_arr from dp_offload_rx output the bsn is only valid at sop
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
------------------------------------------------------------------------------
dp_offload_tx_snk_in_arr(0) <= stimuli_src_out;
stimuli_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_concat_field_blk
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
);
------------------------------------------------------------------------------
-- Link
------------------------------------------------------------------------------
p_link_offload : PROCESS(tx_offload_sosi_arr, link_offload_siso_arr)
BEGIN
link_offload_sosi_arr <= tx_offload_sosi_arr;
link_offload_sosi_arr(0).re <= (OTHERS=>'0');
link_offload_sosi_arr(0).im <= (OTHERS=>'0');
tx_offload_siso_arr <= link_offload_siso_arr;
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
);
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_out_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