diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd index fec9c157176011fa2f05ce1d136712b9d2d713d2..1b819a9a7d1559a8573d573ed0ecad078e7c9247 100644 --- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd +++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd @@ -121,7 +121,11 @@ -- # Manually add missing signals and constants using objects in GUI -- > add wave -position insertpoint \ -- sim:/tb_lofar2_unb2c_sdp_station_bf/sp_ssts_arr2 \ --- sim:/tb_lofar2_unb2c_sdp_station_bf/bsts_arr2 +-- sim:/tb_lofar2_unb2c_sdp_station_bf/bsts_arr2 \ +-- sim:/tb_lofar2_unb2c_sdp_station_bf/rx_packet_list_re \ +-- sim:/tb_lofar2_unb2c_sdp_station_bf/rx_packet_list_im \ +-- sim:/tb_lofar2_unb2c_sdp_station_bf/rx_reordered_list_re \ +-- sim:/tb_lofar2_unb2c_sdp_station_bf/rx_reordered_list_im -- > run -a -- View beamlet output as radix-decimal -- Takes about 1h 1 m when g_read_all_* = FALSE @@ -151,6 +155,7 @@ use unb2c_board_lib.unb2c_board_pkg.all; use lofar2_sdp_lib.sdp_pkg.all; use lofar2_sdp_lib.tb_sdp_pkg.all; use tech_pll_lib.tech_pll_component_pkg.all; +use lofar2_unb2c_sdp_station_lib.lofar2_unb2c_sdp_station_pkg.all; entity tb_lofar2_unb2c_sdp_station_bf is generic ( @@ -178,21 +183,22 @@ end tb_lofar2_unb2c_sdp_station_bf; architecture tb of tb_lofar2_unb2c_sdp_station_bf is + -- Revision parameters + constant c_design_name : string := "lofar2_unb2c_sdp_station_bf"; + constant c_revision_select : t_lofar2_unb2c_sdp_station_config := func_sel_revision_rec(c_design_name); + constant c_sim : boolean := true; constant c_unb_nr : natural := 0; -- UniBoard 0 constant c_node_nr : natural := 0; constant c_gn_index : natural := c_unb_nr * 4 + c_node_nr; -- this node GN constant c_init_bsn : natural := 17; -- some recognizable value >= 0 constant c_bsn_latency : natural := 5; -- used to time stimuli_done - constant c_use_transpose : boolean := false; + constant c_use_bdo_transpose : boolean := c_revision_select.use_bdo_transpose; constant c_id : std_logic_vector(7 downto 0) := TO_UVEC(c_gn_index, 8); constant c_version : std_logic_vector(1 downto 0) := "00"; constant c_fw_version : t_unb2c_board_fw_version := (1, 0); - constant c_mac_15_0 : std_logic_vector(15 downto 0) := TO_UVEC(c_unb_nr, 8) & TO_UVEC(c_node_nr, 8); - constant c_ip_15_0 : std_logic_vector(15 downto 0) := TO_UVEC(c_unb_nr, 8) & TO_UVEC(c_node_nr + 1, 8); -- +1 to avoid IP = *.*.*.0 - constant c_eth_clk_period : time := 8 ns; -- 125 MHz XO on UniBoard constant c_ext_clk_period : time := 5 ns; constant c_mm_clk_period : time := 10 ns; -- 100 MHz internal mm_clk @@ -355,12 +361,17 @@ architecture tb of tb_lofar2_unb2c_sdp_station_bf is constant c_mm_file_reg_sdp_info : string := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_SDP_INFO"; constant c_mm_file_reg_hdr_dat : string := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_HDR_DAT"; -- c_sdp_N_beamsets = 2 beamsets + -- Tb BSN moments + constant c_stimuli_done_bsn : natural := c_init_bsn + c_bsn_latency + c_nof_block_per_sync * 3; + constant c_verify_rx_beamlet_list_bsn : natural := c_stimuli_done_bsn - c_nof_block_per_sync; + -- Tb signal stimuli_done : std_logic := '0'; signal tb_almost_end : std_logic := '0'; signal tb_end : std_logic := '0'; signal tb_clk : std_logic := '0'; signal rd_data : std_logic_vector(c_32 - 1 downto 0); + signal rd_data_bsn : std_logic_vector(c_32 - 1 downto 0); signal dest_rst : std_logic := '1'; -- use separate destination rst for Rx 10GbE in tb signal pps_rst : std_logic := '1'; -- use separate reset to release the PPS generator @@ -447,8 +458,8 @@ architecture tb of tb_lofar2_unb2c_sdp_station_bf is signal rx_beamlet_eop_cnt : natural := 0; -- [0 : 3] = X, Y, X, Y - signal rx_beamlet_arr_re : t_sdp_beamlet_longword_list; - signal rx_beamlet_arr_im : t_sdp_beamlet_longword_list; + 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; @@ -458,9 +469,17 @@ architecture tb of tb_lofar2_unb2c_sdp_station_bf is signal rx_reordered_list_re : t_sdp_beamlet_packet_list; signal rx_reordered_list_im : t_sdp_beamlet_packet_list; - -- [0 : 488 * 2 - 1] = [0 : 975] - signal rx_beamlet_list_re : t_sdp_beamlet_block_list; - signal rx_beamlet_list_im : t_sdp_beamlet_block_list; + -- Recover original beamlet order per block, either by using c_use_bdo_transpose + -- = false or by using c_use_bdo_transpose and func_sdp_bdo_transpose_packet(). + -- List: [0 : 488 * 2 - 1] = [0 : 975] + -- . X part at even indices + -- . Y part at odd indices + signal prev_rx_beamlet_list_re : t_sdp_beamlet_block_list; + signal prev_rx_beamlet_list_im : t_sdp_beamlet_block_list; + signal rx_beamlet_list_re : t_sdp_beamlet_block_list; + signal rx_beamlet_list_im : t_sdp_beamlet_block_list; + signal rx_beamlet_list_val : std_logic; + signal verify_rx_beamlet_list : std_logic := '0'; signal rx_beamlet_x_output_re : integer; signal rx_beamlet_x_output_im : integer; @@ -516,7 +535,7 @@ begin ------------------------------------------------------------------------------ u_lofar_unb2c_sdp_station_bf : entity lofar2_unb2c_sdp_station_lib.lofar2_unb2c_sdp_station generic map ( - g_design_name => "lofar2_unb2c_sdp_station_bf", + g_design_name => c_design_name, g_design_note => "", g_sim => c_sim, g_sim_unb_nr => c_unb_nr, @@ -683,7 +702,9 @@ begin ---- Set and check BF per beamset ------------------------------------------------------------------------------ for bset in 0 to c_sdp_N_beamsets - 1 loop + ---------------------------------------------------------------------------- -- MM beamlet_scale + ---------------------------------------------------------------------------- -- . write v_offset := bset * c_mm_span_reg_bf_scale; mmf_mm_bus_wr(c_mm_file_reg_bf_scale, v_offset + 0, c_exp_beamlet_scale, tb_clk); @@ -695,6 +716,9 @@ begin proc_common_wait_some_cycles(tb_clk, 1); assert TO_UINT(rd_beamlet_scale) = c_exp_beamlet_scale report "Wrong MM read beamlet_scale for beamset " & natural'image(bset) severity ERROR; + ---------------------------------------------------------------------------- + -- Set CEP beamlets output MAC,IP,UDP port + ---------------------------------------------------------------------------- -- CEP beamlet output header -- c_sdp_cep_hdr_field_arr : t_common_field_arr(c_sdp_cep_nof_hdr_fields-1 DOWNTO 0) := ( -- 40 "eth_dst_mac" ), "RW", 48, field_default(c_sdp_cep_eth_dst_mac) ), @@ -1018,7 +1042,7 @@ begin ---------------------------------------------------------------------------- -- read BSN low, this is the wait until condition mmf_mm_wait_until_value(c_mm_file_reg_bsn_scheduler_wg, 0, - "UNSIGNED", rd_data, ">=", c_init_bsn + c_bsn_latency + c_nof_block_per_sync * 3, + "UNSIGNED", rd_data_bsn, ">=", c_stimuli_done_bsn, c_sdp_T_sub, tb_clk); -- Stimuli done, now verify results at end of test @@ -1369,41 +1393,61 @@ begin -- Wait until end of a beamlet packet wait until rising_edge(ext_clk); -- to avoid Modelsim warning: (vcom-1090) proc_common_wait_until_hi_lo(ext_clk, rx_beamlet_sosi.eop); -- to reduce simulation effort - rx_reordered_list_re <= func_sdp_transpose_packet(c_sdp_cep_nof_blocks_per_packet, - c_sdp_cep_nof_beamlets_per_block, - rx_packet_list_re); - rx_reordered_list_im <= func_sdp_transpose_packet(c_sdp_cep_nof_blocks_per_packet, - c_sdp_cep_nof_beamlets_per_block, - rx_packet_list_im); + rx_reordered_list_re <= func_sdp_bdo_transpose_packet(c_sdp_cep_nof_blocks_per_packet, + c_sdp_cep_nof_beamlets_per_block, + rx_packet_list_re); + rx_reordered_list_im <= func_sdp_bdo_transpose_packet(c_sdp_cep_nof_blocks_per_packet, + c_sdp_cep_nof_beamlets_per_block, + rx_packet_list_im); end process; p_rx_beamlet_list : process + constant c_N : natural := c_sdp_cep_nof_beamlets_per_block * c_sdp_N_pol_bf; begin - -- Wait until p_rx_reordered_list has updated + rx_beamlet_list_val <= '0'; + + -- Wait until after p_rx_reordered_list has updated proc_common_wait_until_hi_lo(ext_clk, rx_beamlet_sosi.eop); wait until rising_edge(ext_clk); - -- Copy first block from rx_packet_list into rx_beamlet_list of one block. - if c_use_transpose then - -- transposed beamlet output order - rx_beamlet_list_re <= rx_reordered_list_re(0 to c_sdp_cep_nof_beamlets_per_block * c_sdp_N_pol_bf - 1); - rx_beamlet_list_im <= rx_reordered_list_im(0 to c_sdp_cep_nof_beamlets_per_block * c_sdp_N_pol_bf - 1); - else - -- identity beamlet output order - -- . X at even indices - -- . Y at odd indices - rx_beamlet_list_re <= rx_packet_list_re(0 to c_sdp_cep_nof_beamlets_per_block * c_sdp_N_pol_bf - 1); - rx_beamlet_list_im <= rx_packet_list_im(0 to c_sdp_cep_nof_beamlets_per_block * c_sdp_N_pol_bf - 1); - end if; + -- Use same rx_beamlet_list to show all 4 blocks of a packet in time, to + -- ease viewing the blocks in the wave window. + for blk in 0 to c_sdp_cep_nof_blocks_per_packet - 1 loop + -- Copy block blk from rx_packet_list into rx_beamlet_list of one block. + if c_use_bdo_transpose then + -- undone transposed beamlet output order + rx_beamlet_list_re <= rx_reordered_list_re(blk * c_N to (blk + 1) * c_N - 1); + rx_beamlet_list_im <= rx_reordered_list_im(blk * c_N to (blk + 1) * c_N - 1); + else + -- identity beamlet output order + rx_beamlet_list_re <= rx_packet_list_re(blk * c_N to (blk + 1) * c_N - 1); + rx_beamlet_list_im <= rx_packet_list_im(blk * c_N to (blk + 1) * c_N - 1); + end if; + rx_beamlet_list_val <= '1'; + wait until rising_edge(ext_clk); + end loop; end process; - -- Verify that beamlet values remain stable in time - p_verify_rx_beamlet_list : process + -- Verify that beamlet values remain stable in time, so same beamlet value in each time block + verify_rx_beamlet_list <= '1' when unsigned(rd_data_bsn) > c_verify_rx_beamlet_list_bsn else '0'; + + p_verify_rx_beamlet_list : process(ext_clk) begin - -- . After some time all rx blocks should have same beamlet values, so - -- then rx_beamlet_list then does not change in time and the other - -- blocks should be the same as the first block. - -- TODO + if rising_edge(ext_clk) then + -- Wait until p_rx_beamlet_list is valid + if rx_beamlet_list_val = '1' then + -- Maintain previous x_beamlet_list for comparision + prev_rx_beamlet_list_re <= rx_beamlet_list_re; + prev_rx_beamlet_list_im <= rx_beamlet_list_im; + -- After some time all rx blocks should have same beamlet values, so + -- then rx_beamlet_list then does not change in time and the other + -- blocks should be the same as the first block. + if verify_rx_beamlet_list = '1' then + assert rx_beamlet_list_re = prev_rx_beamlet_list_re report "Wrong: rx_beamlet_list_re differs from previous block" severity ERROR; + assert rx_beamlet_list_im = prev_rx_beamlet_list_im report "Wrong: rx_beamlet_list_im differs from previous block" severity ERROR; + end if; + end if; + end if; end process; -- get rx_beamlet for comparision with c_exp_beamlet