Skip to content
Snippets Groups Projects

Move func_sdp_bdo_cep_hdr_field_sel_dest() from sdp_bdo_pkg to...

Merged Eric Kooistra requested to merge L2SDP-963 into master
1 file
+ 120
21
Compare changes
  • Side-by-side
  • Inline
-------------------------------------------------------------------------------
--
-- Copyright 2023
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-------------------------------------------------------------------------------
--
-- Author: E. Kooistra
-- Purpose:
-- . Test bench for sdp_beamformer_output.vhd
-- Description:
-- . https://support.astron.nl/confluence/pages/viewpage.action?spaceKey=L2M&title=L4+SDPFW+Decision%3A+Multiple+beamlet+output+destinations
--
-- Usage:
-- > as 8
-- > run -a
-------------------------------------------------------------------------------
library IEEE, common_lib, dp_lib;
use IEEE.std_logic_1164.all;
use common_lib.common_pkg.all;
use common_lib.common_mem_pkg.all;
use common_lib.tb_common_pkg.all;
use common_lib.tb_common_mem_pkg.all;
use common_lib.common_network_layers_pkg.all;
use dp_lib.dp_stream_pkg.all;
use work.sdp_pkg.all;
use work.tb_sdp_pkg.all;
entity tb_sdp_beamformer_output is
generic (
g_nof_repeat : natural := 50;
g_beamset_id : natural := 0;
g_use_transpose : boolean := true;
g_use_multiple_destinations : boolean := false
);
end tb_sdp_beamformer_output;
architecture tb of tb_sdp_beamformer_output is
constant c_dp_clk_period : time := 5 ns; -- 200 MHz
constant c_mm_clk_period : time := 1 ns; -- fast MM clk to speed up simulation
constant c_beamlet_mod : natural := 2**c_sdp_W_beamlet;
constant c_init_re : natural := 0;
constant c_init_im : natural := 1;
constant c_init_bsn : natural := 0;
constant c_bf_block_len : natural := c_sdp_N_pol_bf * c_sdp_S_sub_bf; -- = 2 * 488 = 976
constant c_bf_gap_size : natural := c_sdp_N_fft - c_bf_block_len; -- = 1024 - 976 = 48
constant c_exp_beamlet_scale : natural := natural(1.0 / 2.0**9 * real(c_sdp_unit_beamlet_scale));
constant c_exp_beamlet_scale_slv : std_logic_vector(c_sdp_W_beamlet_scale-1 downto 0) :=
to_uvec(c_exp_beamlet_scale, c_sdp_W_beamlet_scale);
constant c_gn_id : natural := 3;
constant c_gn_id_slv : std_logic_vector(c_sdp_W_gn_id - 1 downto 0) :=
to_uvec(c_gn_id, c_sdp_W_gn_id);
constant c_id : std_logic_vector(7 downto 0) := to_uvec(c_gn_id, 8);
constant c_cep_eth_src_mac : std_logic_vector(47 downto 0) := c_sdp_cep_eth_src_mac_47_16 & func_sdp_gn_index_to_mac_15_0(c_gn_id);
constant c_cep_ip_src_addr : std_logic_vector(31 downto 0) := c_sdp_cep_ip_src_addr_31_16 & func_sdp_gn_index_to_ip_15_0(c_gn_id);
constant c_cep_udp_src_port : std_logic_vector(15 downto 0) := c_sdp_cep_udp_src_port_15_8 & c_id;
-- Checksum value obtained from rx_sdp_cep_header.ip.header_checksum in wave window
constant c_exp_ip_header_checksum : natural := 16#5BDB#;
constant c_exp_payload_error : std_logic := '0';
constant c_exp_beamlet_index : natural := g_beamset_id * c_sdp_S_sub_bf;
constant c_exp_sdp_info : t_sdp_info := (to_uvec(7, 6), -- antenna_field_index
to_uvec(601, 10), -- station_id
'0', -- antenna_band_index
x"FFFFFFFF", -- observation_id
b"01", -- nyquist_zone_index, 0 = first, 1 = second, 2 = third
'1', -- f_adc, 0 = 160 MHz, 1 = 200 MHz
'0', -- fsub_type, 0 = critically sampled, 1 = oversampled
'0', -- beam_repositioning_flag
x"1400" -- block_period = 5120
);
signal tb_end : std_logic := '0';
signal dp_clk : std_logic := '1';
signal dp_rst : std_logic;
signal mm_clk : std_logic := '1';
signal mm_rst : std_logic;
-- beamlet data output
signal hdr_dat_copi : t_mem_copi := c_mem_copi_rst;
signal hdr_dat_cipo : t_mem_cipo;
signal reg_destinations_copi : t_mem_copi := c_mem_mosi_rst;
signal reg_destinations_cipo : t_mem_cipo;
signal reg_dp_xonoff_copi : t_mem_copi := c_mem_copi_rst;
signal reg_dp_xonoff_cipo : t_mem_cipo;
signal bdo_eth_src_mac : std_logic_vector(c_network_eth_mac_addr_w - 1 downto 0);
signal bdo_ip_src_addr : std_logic_vector(c_network_ip_addr_w - 1 downto 0);
signal bdo_udp_src_port : std_logic_vector(c_network_udp_port_w - 1 downto 0);
signal bf_sosi : t_dp_sosi;
signal bdo_sosi : t_dp_sosi;
signal bdo_siso : t_dp_siso;
-- dp_offload_rx
signal rx_hdr_dat_copi : t_mem_copi := c_mem_copi_rst;
signal rx_hdr_dat_cipo : t_mem_cipo;
signal rx_hdr_fields_out : std_logic_vector(1023 downto 0);
signal rx_hdr_fields_raw : std_logic_vector(1023 downto 0) := (others => '0');
signal rx_beamlet_header : t_sdp_cep_header;
signal exp_beamlet_header : t_sdp_cep_header;
signal exp_dp_bsn : natural;
-- Beamlets packets data
signal rx_beamlet_data : std_logic_vector(c_longword_w - 1 downto 0); -- 64 bit
signal rx_beamlet_sosi : t_dp_sosi := c_dp_sosi_rst;
signal rx_beamlet_sop_cnt : natural := 0;
signal rx_beamlet_eop_cnt : natural := 0;
-- [0 : 3] = X, Y, X, Y
signal rx_beamlet_arr_re : t_sdp_beamlet_part_arr;
signal rx_beamlet_arr_im : t_sdp_beamlet_part_arr;
signal rx_beamlet_cnt : natural;
signal rx_beamlet_valid : std_logic;
-- [0 : 4 * 488 * 2 - 1] = [0 : 3903]
signal rx_packet_list_re : t_sdp_beamlet_packet_list;
signal rx_packet_list_im : t_sdp_beamlet_packet_list;
signal rx_beamlet_list_re : t_sdp_beamlet_packet_list;
signal rx_beamlet_list_im : t_sdp_beamlet_packet_list;
signal rx_beamlet_list_val : std_logic := '0';
-- Use +c_beamlet_mod to ensure >= 0 to fit in natural, use mod c_beamlet_mod
-- to fit count in c_sdp_W_beamlet bits
signal prev_re : natural := (c_init_re - 1 + c_beamlet_mod) mod c_beamlet_mod;
signal prev_im : natural := (c_init_im - 1 + c_beamlet_mod) mod c_beamlet_mod;
begin
dp_rst <= '1', '0' after c_dp_clk_period * 7;
dp_clk <= (not dp_clk) or tb_end after c_dp_clk_period / 2;
mm_rst <= '1', '0' after c_mm_clk_period * 7;
mm_clk <= (not mm_clk) or tb_end after c_mm_clk_period / 2;
p_mm : process
begin
proc_common_wait_until_low(dp_clk, mm_rst);
proc_common_wait_some_cycles(mm_clk, 10);
----------------------------------------------------------------------------
-- BDO header fields
----------------------------------------------------------------------------
-- . Use sim default dst and src MAC, IP, UDP port from sdp_pkg.vhd and
-- based on c_gn_id
-- . use signed to fit 32 b in integer
proc_mem_mm_bus_wr(39, to_uint(c_cep_eth_src_mac(47 downto 32)), mm_clk, hdr_dat_cipo, hdr_dat_copi);
proc_mem_mm_bus_wr(38, to_sint(c_cep_eth_src_mac(31 downto 0)), mm_clk, hdr_dat_cipo, hdr_dat_copi);
proc_mem_mm_bus_wr(26, to_sint(c_cep_ip_src_addr), mm_clk, hdr_dat_cipo, hdr_dat_copi);
proc_mem_mm_bus_wr(24, to_uint(c_cep_udp_src_port), mm_clk, hdr_dat_cipo, hdr_dat_copi);
proc_mem_mm_bus_wr(41, to_uint(c_sdp_cep_eth_dst_mac(47 downto 32)), mm_clk, hdr_dat_cipo, hdr_dat_copi);
proc_mem_mm_bus_wr(40, to_sint(c_sdp_cep_eth_dst_mac(31 downto 0)), mm_clk, hdr_dat_cipo, hdr_dat_copi);
proc_mem_mm_bus_wr(25, to_sint(c_sdp_cep_ip_dst_addr), mm_clk, hdr_dat_cipo, hdr_dat_copi);
proc_mem_mm_bus_wr(23, to_uint(c_sdp_cep_udp_dst_port), mm_clk, hdr_dat_cipo, hdr_dat_copi);
----------------------------------------------------------------------------
-- Enable beamlet output (dp_xonoff)
----------------------------------------------------------------------------
proc_mem_mm_bus_wr(0, 1, mm_clk, reg_dp_xonoff_cipo, reg_dp_xonoff_copi);
wait;
end process;
u_bf_sosi : entity dp_lib.dp_stream_stimuli
generic map (
-- initializations
g_sync_period => 10,
g_sync_offset => 0,
g_use_complex => true,
g_re_init => c_init_re,
g_im_init => c_init_im,
g_bsn_init => TO_DP_BSN(c_init_bsn),
g_err_init => 0, -- not used
g_err_incr => 0, -- not used
g_channel_init => 0, -- not used
g_channel_incr => 0, -- not used
-- specific
g_in_dat_w => c_sdp_W_beamlet, -- = 8
g_nof_repeat => g_nof_repeat,
g_pkt_len => c_bf_block_len,
g_pkt_gap => c_bf_gap_size,
g_wait_last_evt => 100
)
port map (
rst => dp_rst,
clk => dp_clk,
-- Generate stimuli
src_out => bf_sosi,
-- End of stimuli
last_snk_in => open, -- expected verify_snk_in after end of stimuli
last_snk_in_evt => open, -- trigger verify to verify the last_snk_in
tb_end => tb_end
);
-- Beamlet Data Output (BDO)
u_dut: entity work.sdp_beamformer_output
generic map (
g_beamset_id => g_beamset_id,
g_use_transpose => g_use_transpose,
g_use_multiple_destinations => g_use_multiple_destinations,
g_sim_force_bsn_error => false
)
port map (
mm_clk => mm_clk,
mm_rst => mm_rst,
dp_clk => dp_clk,
dp_rst => dp_rst,
reg_hdr_dat_mosi => hdr_dat_copi,
reg_hdr_dat_miso => hdr_dat_cipo,
reg_destinations_copi => reg_destinations_copi,
reg_destinations_cipo => reg_destinations_cipo,
reg_dp_xonoff_mosi => reg_dp_xonoff_copi,
reg_dp_xonoff_miso => reg_dp_xonoff_cipo,
in_sosi => bf_sosi,
out_sosi => bdo_sosi,
out_siso => bdo_siso,
sdp_info => c_exp_sdp_info,
beamlet_scale => c_exp_beamlet_scale_slv,
gn_id => c_gn_id_slv,
-- Source MAC/IP/UDP are not used, c_sdp_cep_hdr_field_sel selects MM programmable instead
eth_src_mac => bdo_eth_src_mac,
ip_src_addr => bdo_ip_src_addr,
udp_src_port => bdo_udp_src_port,
hdr_fields_out => open
);
u_rx : entity dp_lib.dp_offload_rx
generic map (
g_nof_streams => 1,
g_data_w => c_longword_w,
g_symbol_w => c_octet_w,
g_hdr_field_arr => c_sdp_cep_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 => rx_hdr_dat_copi,
reg_hdr_dat_miso => rx_hdr_dat_cipo,
snk_in_arr(0) => bdo_sosi,
snk_out_arr(0) => bdo_siso,
src_out_arr(0) => rx_beamlet_sosi,
hdr_fields_out_arr(0) => rx_hdr_fields_out,
hdr_fields_raw_arr(0) => rx_hdr_fields_raw
);
-----------------------------------------------------------------------------
-- Beamlet offload packet header
-----------------------------------------------------------------------------
-- Counters to time expected cep_header fields per offload packet
p_test_counters : process(dp_clk)
begin
if rising_edge(dp_clk) then
-- Count rx_beamlet_sosi packets
if rx_beamlet_sosi.sop = '1' then
rx_beamlet_sop_cnt <= rx_beamlet_sop_cnt + 1; -- early count
end if;
if rx_beamlet_sosi.eop = '1' then
rx_beamlet_eop_cnt <= rx_beamlet_eop_cnt + 1; -- after count
end if;
end if;
end process;
-- Prepare exp_beamlet_header before rx_beamlet_sosi.eop, so that
-- p_verify_beamlet_header can verify it at rx_beamlet_sosi.eop.
exp_beamlet_header <= func_sdp_compose_cep_header(c_exp_ip_header_checksum,
c_exp_sdp_info,
c_gn_id,
c_exp_payload_error,
c_exp_beamlet_scale,
c_exp_beamlet_index,
exp_dp_bsn);
rx_beamlet_header <= func_sdp_map_cep_header(rx_hdr_fields_raw);
p_verify_beamlet_header : process
variable v_bool : boolean;
begin
wait until rising_edge(dp_clk);
-- 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
exp_dp_bsn <= c_init_bsn + rx_beamlet_sop_cnt * c_sdp_cep_nof_blocks_per_packet;
end if;
-- Verify header at eop
if rx_beamlet_sosi.eop = '1' then
v_bool := func_sdp_verify_cep_header(rx_beamlet_header, exp_beamlet_header);
end if;
end process;
-----------------------------------------------------------------------------
-- Beamlet offload packet data
-----------------------------------------------------------------------------
-- To view the 64 bit 10GbE offload data more easily in the Wave window
rx_beamlet_data <= rx_beamlet_sosi.data(c_longword_w - 1 downto 0);
proc_sdp_rx_beamlet_octets(dp_clk,
rx_beamlet_sosi,
rx_beamlet_cnt,
rx_beamlet_valid,
rx_beamlet_arr_re,
rx_beamlet_arr_im,
rx_packet_list_re,
rx_packet_list_im);
p_verify_rx_beamlet_list : process
-- Nof complex (= nof re = nof im = c_N) values in t_sdp_beamlet_packet_list
constant c_N : natural := c_sdp_cep_nof_beamlets_per_packet * c_sdp_N_pol_bf;
variable v_prev_re : natural := prev_re;
variable v_prev_im : natural := prev_im;
begin
-- Wait until end of a beamlet packet
-- . use at least one wait statement in process to avoid Modelsim warning: (vcom-1090)
wait until rising_edge(dp_clk);
proc_common_wait_until_hi_lo(dp_clk, rx_beamlet_sosi.eop);
if g_use_transpose then
-- Undo the beamlet output transpose, to have original beamlet order
rx_beamlet_list_re <= func_sdp_undo_transpose_beamlet_packet(rx_packet_list_re);
rx_beamlet_list_im <= func_sdp_undo_transpose_beamlet_packet(rx_packet_list_im);
else
-- Copy identity beamlet output order
rx_beamlet_list_re <= rx_packet_list_re;
rx_beamlet_list_im <= rx_packet_list_im;
end if;
rx_beamlet_list_val <= '1';
-- Wait until rx_beamlet_list is valid
wait until rising_edge(dp_clk);
rx_beamlet_list_val <= '0';
-- Verify rx_beamlet_list
for vI in 0 to c_N - 1 loop
-- Verify incrementing beamlets
v_prev_re := (v_prev_re + 1) mod c_beamlet_mod;
v_prev_im := (v_prev_im + 1) mod c_beamlet_mod;
assert to_uint(rx_beamlet_list_re(vI)) = v_prev_re report "Wrong re_beamlet." severity error;
assert to_uint(rx_beamlet_list_im(vI)) = v_prev_im report "Wrong im_beamlet." severity error;
end loop;
prev_re <= v_prev_re;
prev_im <= v_prev_im;
end process;
end tb;
Loading