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

Merge branch 'L2SDP-176' into 'master'

Resolve L2SDP-176

Closes L2SDP-176

See merge request desp/hdl!226
parents 3cfd546e e11fe282
No related branches found
No related tags found
1 merge request!226Resolve L2SDP-176
Pipeline #26916 passed
hdl_lib_name = lofar2_unb2c_sdp_station_bf_ring
hdl_library_clause_name = lofar2_unb2c_sdp_station_bf_ring_lib
hdl_lib_uses_synth = common mm technology unb2c_board lofar2_unb2c_sdp_station
hdl_lib_uses_sim = eth
hdl_lib_technology = ip_arria10_e2sg
synth_files =
lofar2_unb2c_sdp_station_bf_ring.vhd
test_bench_files =
tb_lofar2_unb2c_sdp_station_bf_ring.vhd
regression_test_vhdl =
tb_lofar2_unb2c_sdp_station_bf_ring.vhd
[modelsim_project_file]
modelsim_copy_files =
../../src/data data
$RADIOHDL_WORK/libraries/dsp/filter/src/hex data # FIR filter coefficients
# Overwrite bf weights with sim data
../../tb/data data
[quartus_project_file]
synth_top_level_entity =
quartus_copy_files =
# Note: path $RADIOHDL_WORK is equivalent to relative path ../../../../../../
../../quartus .
../../src/data data
$RADIOHDL_WORK/libraries/dsp/filter/src/hex data # FIR filter coefficients
quartus_qsf_files =
$RADIOHDL_WORK/boards/uniboard2c/libraries/unb2c_board/quartus/unb2c_board.qsf
# use lofar2_unb2c_sdp_station.sdc instead because BCK_REF_CLK is 200MHz, not 644.33MHz.
quartus_sdc_files =
../../quartus/lofar2_unb2c_sdp_station.sdc
#$RADIOHDL_WORK/boards/uniboard2c/libraries/unb2c_board/quartus/unb2c_board.sdc
quartus_tcl_files =
lofar2_unb2c_sdp_station_bf_ring_pins.tcl
quartus_vhdl_files =
quartus_qip_files =
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station_bf_ring/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station.qip
quartus_ip_files =
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_avs_common_mm_0.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_avs_common_mm_1.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_avs_eth_0.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_clk_0.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_cpu_0.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_jesd204b.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_jtag_uart_0.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_onchip_memory2_0.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_pio_jesd_ctrl.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_pio_pps.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_pio_system_info.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_pio_wdi.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_ram_bf_weights.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_ram_diag_data_buffer_bsn.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_ram_equalizer_gains.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_ram_fil_coefs.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_ram_scrap.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_ram_ss_ss_wide.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_ram_st_bst.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_ram_st_histogram.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_ram_st_sst.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_ram_st_xsq.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_ram_wg.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_aduh_monitor.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_bf_scale.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_bsn_align_v2_bf.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_bsn_align_v2_xsub.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_bsn_monitor_input.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_bsn_monitor_v2_aligned_bf.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_bsn_monitor_v2_aligned_xsub.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_bsn_monitor_v2_beamlet_output.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_bsn_monitor_v2_bst_offload.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_bsn_monitor_v2_ring_rx_bf.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_bsn_monitor_v2_ring_rx_xst.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_bsn_monitor_v2_ring_tx_bf.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_bsn_monitor_v2_ring_tx_xst.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_bsn_monitor_v2_rx_align_bf.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_bsn_monitor_v2_rx_align_xsub.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_bsn_monitor_v2_sst_offload.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_bsn_monitor_v2_xst_offload.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_bsn_scheduler.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_bsn_source_v2.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_bsn_sync_scheduler_xsub.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_crosslets_info.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_diag_data_buffer_bsn.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_dp_block_validate_bsn_at_sync_bf.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_dp_block_validate_bsn_at_sync_xst.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_dp_block_validate_err_bf.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_dp_block_validate_err_xst.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_dpmm_ctrl.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_dpmm_data.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_dp_selector.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_dp_shiftram.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_dp_xonoff.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_epcs.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_fpga_temp_sens.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_fpga_voltage_sens.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_hdr_dat.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_mmdp_ctrl.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_mmdp_data.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_nof_crosslets.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_nw_10gbe_eth10g.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_nw_10gbe_mac.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_remu.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_ring_info.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_ring_lane_info_bf.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_ring_lane_info_xst.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_sdp_info.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_si.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_stat_enable_bst.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_stat_enable_sst.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_stat_enable_xst.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_stat_hdr_dat_bst.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_stat_hdr_dat_sst.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_stat_hdr_dat_xst.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_tr_10gbe_eth10g.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_tr_10gbe_mac.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_wdi.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_reg_wg.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_rom_system_info.ip
$RADIOHDL_BUILD_DIR/unb2c/quartus/lofar2_unb2c_sdp_station/ip/qsys_lofar2_unb2c_sdp_station/qsys_lofar2_unb2c_sdp_station_timer_0.ip
nios2_app_userflags = -DCOMPILE_FOR_GEN2_UNB2
-------------------------------------------------------------------------------
--
-- Copyright 2021
-- 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 : R. van der Walle
-- Purpose:
-- Wrapper for Lofar2 SDP Station beamformer design
-- Description:
-- Unb2c version for lab testing
-- Contains complete AIT input stage with 12 ADC streams, FSUB and BF
LIBRARY IEEE, common_lib, unb2c_board_lib, technology_lib, diag_lib, dp_lib, tech_jesd204b_lib, lofar2_unb2c_sdp_station_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 technology_lib.technology_pkg.ALL;
USE unb2c_board_lib.unb2c_board_pkg.ALL;
USE diag_lib.diag_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
ENTITY lofar2_unb2c_sdp_station_bf IS
GENERIC (
g_design_name : STRING := "lofar2_unb2c_sdp_station_bf";
g_design_note : STRING := "Lofar2 SDP station beamformer design";
g_sim : BOOLEAN := FALSE; --Overridden by TB
g_sim_unb_nr : NATURAL := 0;
g_sim_node_nr : NATURAL := 0;
g_stamp_date : NATURAL := 0; -- Date (YYYYMMDD) -- set by QSF
g_stamp_time : NATURAL := 0; -- Time (HHMMSS) -- set by QSF
g_revision_id : STRING := "" -- revision ID -- set by QSF
);
PORT (
-- GENERAL
CLK : IN STD_LOGIC; -- System Clock
PPS : IN STD_LOGIC; -- System Sync
WDI : OUT STD_LOGIC; -- Watchdog Clear
INTA : INOUT STD_LOGIC; -- FPGA interconnect line
INTB : INOUT STD_LOGIC; -- FPGA interconnect line
-- Others
VERSION : IN STD_LOGIC_VECTOR(c_unb2c_board_aux.version_w-1 DOWNTO 0);
ID : IN STD_LOGIC_VECTOR(c_unb2c_board_aux.id_w-1 DOWNTO 0);
TESTIO : INOUT STD_LOGIC_VECTOR(c_unb2c_board_aux.testio_w-1 DOWNTO 0);
-- 1GbE Control Interface
ETH_CLK : IN STD_LOGIC_VECTOR(c_unb2c_board_nof_eth-1 DOWNTO 0);
ETH_SGIN : IN STD_LOGIC_VECTOR(c_unb2c_board_nof_eth-1 DOWNTO 0);
ETH_SGOUT : OUT STD_LOGIC_VECTOR(c_unb2c_board_nof_eth-1 DOWNTO 0);
-- Transceiver clocks
SA_CLK : IN STD_LOGIC := '0'; -- Clock 10GbE front (qsfp) and ring lines
-- front transceivers QSFP0 for Ring.
QSFP_0_RX : IN STD_LOGIC_VECTOR(c_unb2c_board_tr_qsfp.bus_w-1 downto 0) := (OTHERS=>'0');
QSFP_0_TX : OUT STD_LOGIC_VECTOR(c_unb2c_board_tr_qsfp.bus_w-1 downto 0);
-- front transceivers
QSFP_1_RX : IN STD_LOGIC_VECTOR(c_unb2c_board_tr_qsfp.bus_w-1 DOWNTO 0) := (OTHERS=>'0');
QSFP_1_TX : OUT STD_LOGIC_VECTOR(c_unb2c_board_tr_qsfp.bus_w-1 DOWNTO 0);
-- LEDs
QSFP_LED : OUT STD_LOGIC_VECTOR(c_unb2c_board_tr_qsfp_nof_leds-1 DOWNTO 0);
-- ring transceivers
RING_0_RX : IN STD_LOGIC_VECTOR(c_unb2c_board_tr_qsfp.bus_w-1 DOWNTO 0) := (OTHERS => '0'); -- Using qsfp bus width also for ring interfaces
RING_0_TX : OUT STD_LOGIC_VECTOR(c_unb2c_board_tr_qsfp.bus_w-1 DOWNTO 0);
RING_1_RX : IN STD_LOGIC_VECTOR(c_unb2c_board_tr_qsfp.bus_w-1 DOWNTO 0) := (OTHERS=>'0');
RING_1_TX : OUT STD_LOGIC_VECTOR(c_unb2c_board_tr_qsfp.bus_w-1 DOWNTO 0);
-- back transceivers (note only 12 are used in unb2c)
BCK_RX : IN STD_LOGIC_VECTOR(c_unb2c_board_nof_tr_jesd204b-1 DOWNTO 0); -- c_unb2c_board_nof_tr_jesd204b = c_sdp_S_pn = 12
BCK_REF_CLK : IN STD_LOGIC; -- Use as JESD204B_REFCLK
-- jesd204b syncronization signals (4 syncs)
JESD204B_SYSREF : IN STD_LOGIC;
JESD204B_SYNC_N : OUT STD_LOGIC_VECTOR(c_unb2c_board_nof_sync_jesd204b-1 DOWNTO 0) -- c_unb2c_board_nof_sync_jesd204b = c_sdp_N_sync_jesd = 4
);
END lofar2_unb2c_sdp_station_bf;
ARCHITECTURE str OF lofar2_unb2c_sdp_station_bf IS
SIGNAL JESD204B_SERIAL_DATA : STD_LOGIC_VECTOR((c_unb2c_board_tr_jesd204b.bus_w*c_unb2c_board_tr_jesd204b.nof_bus)-1 DOWNTO 0);
SIGNAL jesd204b_sync_n_arr : STD_LOGIC_VECTOR(c_unb2c_board_nof_sync_jesd204b-1 DOWNTO 0);
SIGNAL JESD204B_REFCLK : STD_LOGIC;
BEGIN
-- Mapping between JESD signal names and UNB2B pin/schematic names
JESD204B_REFCLK <= BCK_REF_CLK;
JESD204B_SERIAL_DATA <= BCK_RX;
JESD204B_SYNC_N(c_unb2c_board_nof_sync_jesd204b-1 DOWNTO 0) <= jesd204b_sync_n_arr(c_unb2c_board_nof_sync_jesd204b-1 DOWNTO 0);
u_revision : ENTITY lofar2_unb2c_sdp_station_lib.lofar2_unb2c_sdp_station
GENERIC MAP (
g_design_name => g_design_name,
g_design_note => g_design_note,
g_sim => g_sim,
g_sim_unb_nr => g_sim_unb_nr,
g_sim_node_nr => g_sim_node_nr,
g_stamp_date => g_stamp_date,
g_stamp_time => g_stamp_time,
g_revision_id => g_revision_id
)
PORT MAP (
-- GENERAL
CLK => CLK,
PPS => PPS,
WDI => WDI,
INTA => INTA,
INTB => INTB,
-- Others
VERSION => VERSION,
ID => ID,
TESTIO => TESTIO,
-- 1GbE Control Interface
ETH_clk => ETH_clk,
ETH_SGIN => ETH_SGIN,
ETH_SGOUT => ETH_SGOUT,
-- Transceiver clocks
SA_CLK => SA_CLK,
-- front transceivers QSFP0 for Ring.
QSFP_0_RX => QSFP_0_RX,
QSFP_0_TX => QSFP_0_TX,
-- front transceivers QSFP1 for 10GbE output to CEP.
QSFP_1_RX => QSFP_1_RX,
QSFP_1_TX => QSFP_1_TX,
-- LEDs
QSFP_LED => QSFP_LED,
-- ring transceivers
RING_0_RX => RING_0_RX,
RING_0_TX => RING_0_TX,
RING_1_RX => RING_1_RX,
RING_1_TX => RING_1_TX,
-- back transceivers
JESD204B_SERIAL_DATA => JESD204B_SERIAL_DATA,
JESD204B_REFCLK => JESD204B_REFCLK,
-- jesd204b syncronization signals
JESD204B_SYSREF => JESD204B_SYSREF,
JESD204B_SYNC_N => jesd204b_sync_n_arr
);
END str;
###############################################################################
#
# Copyright (C) 2022
# 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/>.
#
###############################################################################
source $::env(RADIOHDL_WORK)/applications/lofar2/designs/lofar2_unb2c_sdp_station/quartus/lofar2_unb2c_sdp_station_pins.tcl
source $::env(RADIOHDL_WORK)/applications/lofar2/designs/lofar2_unb2c_sdp_station/quartus/lofar2_unb2c_sdp_station_beamlets_pins.tcl
source $::env(RADIOHDL_WORK)/applications/lofar2/designs/lofar2_unb2c_sdp_station/quartus/lofar2_unb2c_sdp_station_ring_pins.tcl
-------------------------------------------------------------------------------
--
-- Copyright 2020
-- 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: R. van der Walle (original), E. Kooistra (updates)
-- Purpose: Self-checking testbench for simulating lofar2_unb2c_sdp_station_bf_ring
-- using WG data.
--
-- Description:
-- This tb is a balance between verification coverage and keeping it simple:
-- - Use only one signal input (g_sp). Put same remnant WG signal on the
-- other signal inputs.
-- - Use different BF weight for the two beamlet polarizations (g_bf_x_gain,
-- g_bf_x_phase and g_bf_y_phase, g_bf_y_phase) of signal input g_sp.
-- Using different BF weights for the N_pol_bf = 2 BF polarizations allows
-- verification of the dual polarization beamlet.
-- - Use same remnant BF weight for the other S_pn - 1 = 11 signal inputs.
-- The remnant signal inputs and BF weights allow verifying the BF sum if
-- they are not 0. Using the same settings for all remnant SP simplyfies
-- the tb, while still testing the BF sum.
-- - Select one beamlet for the subband (g_beamlet). Selecting one beamlet
-- other than the default beamlet for the subband is sufficient to verify
-- the beamlet subband select.
-- - Use same stimuli for both beamsets.
--
-- MM control actions:
--
-- 1) Enable calc mode for WG on signal input (si) g_sp via reg_diag_wg with:
-- g_subband = 102 --> 102 * f_sub = 19.921875 MHz
-- g_sp_ampl = 1.0 --> 1.0 yield WG ampl = 2**13
-- g_sp_phase --> subband phase
-- Use g_sp_remnant_ampl = 0.1 and g_sp_remnant_phase = 0.0 for the other
-- S_pn-1 = 11 signal inputs, than g_sp, that are not used in the BF.
--
-- 2) Read current BSN from reg_bsn_scheduler_wg and write
-- reg_bsn_scheduler_wg to trigger start of WG at BSN.
--
-- 3) Read and verify subband statistics (SST) for g_sp. This also reads the
-- SST of the other signal input of the WPFB that processes g_sp.
--
-- 4) Select subband g_subband for beamlets in g_beamlet
--
-- 5) Apply BF weight to g_beamlet X beam and Y beam, so for example if g_sp
-- = 3, then w_x3 = g_bf_x_gain/phase and w_y3 = = g_bf_x_gain/phase. The
-- other BF weights are 0.
--
-- WG BF BF
-- si weight weight
-- X Y
-- 0 -----> * w_x0 ..+
-- \--------------|----> * w_y0 ..+
-- 1 -----> * w_x1 ..+ |
-- \--------------|----> * w_y1 ..+
-- 2 -----> * w_x2 ..+ |
-- \--------------|----> * w_y2 ..+
-- 3 -----> * w_x3 ..+ |
-- \--------------|----> * w_y3 ..+
-- 4 -----> * w_x4 ..+ |
-- \--------------|----> * w_y4 ..+
-- 5 -----> * w_x5 ..+ |
-- \--------------|----> * w_y5 ..+
-- 6 -----> * w_x6 ..+ |
-- \--------------|----> * w_y6 ..+
-- 7 -----> * w_x7 ..+ |
-- \--------------|----> * w_y7 ..+
-- 8 -----> * w_x8 ..+ |
-- \--------------|----> * w_y8 ..+
-- 9 -----> * w_x9 ..+ |
-- \--------------|----> * w_y9 ..+
-- 10 -----> * w_x10 ..+ |
-- \--------------|----> * w_y10 ..+
-- 11 -----> * w_x11 ..+ |
-- \--------------|----> * w_y11 ..+
-- | |
-- \----------------|---> beamlet_x
-- \--> beamlet_y
--
--
-- 6) Read and verify beamlet statistics (BST)
-- View sp_sst in Wave window
-- View bst_x_arr, bst_y_arr in Wave window
--
-- 7) Verify 10GbE output header and output payload for g_beamlet.
-- View rx_beamlet_sosi
-- View rx_beamlet_cnt (in analog format)
--
-- Remark:
-- . 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)
--
-- Usage:
-- > as 7 # default
-- > as 12 # for detailed debugging
-- # Manually add missing signal
-- > add wave -position insertpoint \
-- sim:/tb_lofar2_unb2c_sdp_station_bf_ring/sp_ssts_arr2 \
-- sim:/tb_lofar2_unb2c_sdp_station_bf_ring/bsts_arr2
-- > run -a
-- Takes about 40 m when g_read_all_* = FALSE
-- Takes about 1h 5 m when g_read_all_* = TRUE
--
-------------------------------------------------------------------------------
LIBRARY IEEE, common_lib, unb2c_board_lib, i2c_lib, mm_lib, dp_lib, diag_lib, lofar2_sdp_lib, wpfb_lib, tech_pll_lib, tr_10GbE_lib, lofar2_unb2c_sdp_station_lib;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
USE IEEE.math_real.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
USE common_lib.common_field_pkg.ALL;
USE common_lib.common_network_layers_pkg.ALL;
USE common_lib.tb_common_pkg.ALL;
USE common_lib.common_str_pkg.ALL;
USE mm_lib.mm_file_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
USE mm_lib.mm_file_unb_pkg.ALL;
USE diag_lib.diag_pkg.ALL;
USE wpfb_lib.wpfb_pkg.ALL;
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;
ENTITY tb_lofar2_unb2c_sdp_station_bf_ring IS
GENERIC (
g_sp : NATURAL := 3; -- WG signal path (SP) index in range(S_pn = 12)
g_sp_ampl : REAL := 0.5; -- WG normalized amplitude
g_sp_phase : REAL := -110.0; -- WG phase in degrees = subband phase
g_sp_remnant_ampl : REAL := 0.1; -- WG normalized amplitude for remnant sp
g_sp_remnant_phase : REAL := 15.0; -- WG phase in degrees for remnant sp
g_subband : NATURAL := 102; -- select g_subband at index 102 = 102/1024 * 200MHz = 19.921875 MHz
g_beamlet : NATURAL := 10; -- map g_subband to g_beamlet index in beamset in range(c_sdp_S_sub_bf = 488)
g_beamlet_scale : REAL := 1.0 / 2.0**9; -- g_beamlet output scale factor
g_bf_x_gain : REAL := 0.7; -- g_beamlet X BF weight normalized gain for g_sp
g_bf_y_gain : REAL := 0.6; -- g_beamlet Y BF weight normalized gain for g_sp
g_bf_x_phase : REAL := 30.0; -- g_beamlet X BF weight phase rotation in degrees for g_sp
g_bf_y_phase : REAL := 40.0; -- g_beamlet Y BF weight phase rotation in degrees for g_sp
g_bf_remnant_x_gain : REAL := 0.05; -- g_beamlet X BF weight normalized gain for remnant sp
g_bf_remnant_y_gain : REAL := 0.04; -- g_beamlet Y BF weight normalized gain for remnant sp
g_bf_remnant_x_phase : REAL := 170.0; -- g_beamlet X BF weight phase rotation in degrees for g_sp
g_bf_remnant_y_phase : REAL := -135.0; -- g_beamlet Y BF weight phase rotation in degrees for g_sp
g_read_all_SST : BOOLEAN := FALSE; -- when FALSE only read SST for g_subband, to save sim time
g_read_all_BST : BOOLEAN := FALSE -- when FALSE only read BST for g_beamlet, to save sim time
);
END tb_lofar2_unb2c_sdp_station_bf_ring;
ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf_ring IS
CONSTANT c_sim : BOOLEAN := TRUE;
CONSTANT c_unb_nr : NATURAL := 0; -- UniBoard 0
CONSTANT c_node_nr : NATURAL := 0;
CONSTANT c_nof_rn : NATURAL := 2;
CONSTANT c_gn_index : NATURAL := c_unb_nr * 4 + c_nof_rn-1; -- end node GN
CONSTANT c_init_bsn : NATURAL := 17; -- some recognizable value >= 0
CONSTANT c_nof_lanes : NATURAL := c_sdp_N_beamsets;
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 + ((c_nof_rn-1) / c_quad), 8) & TO_UVEC((c_nof_rn-1) MOD c_quad, 8);
CONSTANT c_ip_15_0 : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(c_unb_nr + ((c_nof_rn-1) / c_quad), 8) & TO_UVEC(((c_nof_rn-1) MOD c_quad) +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
CONSTANT c_bck_ref_clk_period : TIME := 5 ns;
CONSTANT c_sa_clk_period : TIME := tech_pll_clk_644_period; -- 644MHz
CONSTANT c_tb_clk_period : TIME := 100 ps; -- use fast tb_clk to speed up M&C
CONSTANT c_nof_block_per_sync : NATURAL := 16;
CONSTANT c_nof_clk_per_sync : NATURAL := c_nof_block_per_sync*c_sdp_N_fft;
CONSTANT c_pps_period : NATURAL := c_nof_clk_per_sync;
CONSTANT c_wpfb_sim : t_wpfb := func_wpfb_set_nof_block_per_sync(c_sdp_wpfb_subbands, c_nof_block_per_sync);
CONSTANT c_stat_data_sz : NATURAL := c_wpfb_sim.stat_data_sz; -- = 2
CONSTANT c_stat_percentage : REAL := 0.05; -- +-percentage margin that actual value may differ from expected value
CONSTANT c_stat_lo_factor : REAL := 1.0 - c_stat_percentage; -- lower boundary
CONSTANT c_stat_hi_factor : REAL := 1.0 + c_stat_percentage; -- higher boundary
CONSTANT c_nof_beamlets_per_data : NATURAL := 2; -- 2 dual pol beamlets (= XY, XY) per 64b data word
CONSTANT c_beamlet_output_delta : INTEGER := 2; -- +-delta margin
-- header fields
CONSTANT c_cep_eth_dst_mac : STD_LOGIC_VECTOR(47 DOWNTO 0) := c_sdp_cep_eth_dst_mac; -- 00074306C700 = DOP36-eth0
CONSTANT c_cep_ip_dst_addr : STD_LOGIC_VECTOR(31 DOWNTO 0) := c_sdp_cep_ip_dst_addr; -- C0A80001 = '192.168.0.1' = DOP36-eth0
CONSTANT c_cep_udp_dst_port : STD_LOGIC_VECTOR(15 DOWNTO 0) := c_sdp_cep_udp_dst_port; -- 5000
CONSTANT c_cep_eth_src_mac : STD_LOGIC_VECTOR(47 DOWNTO 0) := c_sdp_cep_eth_src_mac_47_16 & c_mac_15_0; -- x"00228608"; -- 47:16, 15:8 = backplane, 7:0 = node
CONSTANT c_cep_ip_src_addr : STD_LOGIC_VECTOR(31 DOWNTO 0) := c_sdp_cep_ip_src_addr_31_16 & c_ip_15_0; -- C0A80001 = '192.168.0.1' = DOP36-eth0
CONSTANT c_cep_udp_src_port : STD_LOGIC_VECTOR(15 DOWNTO 0) := c_sdp_cep_udp_src_port_15_8 & c_id; -- D0 & c_id
CONSTANT c_exp_ip_header_checksum : NATURAL := 16#5BDD#; -- value obtained from rx_sdp_cep_header.ip.header_checksum in wave window for c_nof_rn = 2.
CONSTANT c_exp_beamlet_scale : NATURAL := NATURAL(g_beamlet_scale * REAL(c_sdp_unit_beamlet_scale)); -- c_sdp_unit_beamlet_scale = 2**15;
CONSTANT c_exp_sdp_info : t_sdp_info := (
TO_UVEC(601, 16), -- station_id
'0', -- antenna_band_index
x"7FFFFFFF", -- observation_id, use > 0 to avoid Warning: (vsim-151) NUMERIC_STD.TO_INTEGER: Value -2 is not in bounds of subtype NATURAL.
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
);
-- WG
CONSTANT c_bsn_start_wg : NATURAL := c_init_bsn + 2; -- start WG at this BSN to instead of some BSN, to avoid mismatches in exact expected data values
-- .ampl
CONSTANT c_wg_ampl_full_scale : NATURAL := 2**(c_sdp_W_adc-1); -- full scale (FS) of WG, will just cause clipping of +FS to +FS-1
CONSTANT c_wg_ampl_lsb : REAL := c_diag_wg_ampl_unit / REAL(c_wg_ampl_full_scale); -- amplitude in number of LSbit resolution steps
CONSTANT c_wg_ampl : NATURAL := NATURAL(g_sp_ampl * REAL(c_wg_ampl_full_scale)); -- in number of lsb
CONSTANT c_wg_remnant_ampl : NATURAL := NATURAL(g_sp_remnant_ampl * REAL(c_wg_ampl_full_scale)); -- in number of lsb
CONSTANT c_exp_sp_power : REAL := REAL(c_wg_ampl**2) / 2.0;
CONSTANT c_exp_sp_ast : REAL := c_exp_sp_power * REAL(c_nof_clk_per_sync);
-- . phase
CONSTANT c_subband_freq : REAL := REAL(g_subband) / REAL(c_sdp_N_fft); -- normalized by fs = f_adc = 200 MHz = dp_clk rate
CONSTANT c_wg_latency : INTEGER := c_diag_wg_latency - 0; -- -0 to account for BSN scheduler start trigger latency
CONSTANT c_wg_phase_offset : REAL := 360.0 * REAL(c_wg_latency) * c_subband_freq; -- c_diag_wg_latency is in dp_clk cycles
CONSTANT c_wg_phase : REAL := g_sp_phase + c_wg_phase_offset; -- WG phase in degrees
CONSTANT c_wg_remnant_phase : REAL := g_sp_remnant_phase + c_wg_phase_offset; -- WG phase in degrees
-- . freq
CONSTANT c_wg_subband_freq_unit : REAL := c_diag_wg_freq_unit/REAL(c_sdp_N_fft); -- subband freq = Fs/1024 = 200 MSps/1024 = 195312.5 Hz sinus
-- WPFB
CONSTANT c_pol_index : NATURAL := g_sp MOD c_sdp_Q_fft;
CONSTANT c_pfb_index : NATURAL := g_sp / c_sdp_Q_fft; -- only read used WPFB unit out of range(c_sdp_P_pfb = 6)
CONSTANT c_subband_phase_offset : REAL := -90.0; -- WG with zero phase sinus yields subband with -90 degrees phase (negative Im, zero Re)
CONSTANT c_subband_weight_gain : REAL := 1.0; -- use default unit subband weights
CONSTANT c_subband_weight_phase : REAL := 0.0; -- use default unit subband weights
CONSTANT c_exp_subband_phase : REAL := g_sp_phase + c_subband_phase_offset + c_subband_weight_phase;
CONSTANT c_exp_subband_ampl : REAL := REAL(c_wg_ampl) * c_sdp_wpfb_subband_sp_ampl_ratio * c_subband_weight_gain;
CONSTANT c_exp_subband_power : REAL := c_exp_subband_ampl**2.0; -- complex signal ampl, so no divide by 2
CONSTANT c_exp_subband_sst : REAL := c_exp_subband_power * REAL(c_nof_block_per_sync);
CONSTANT c_exp_remnant_subband_phase : REAL := g_sp_remnant_phase + c_subband_phase_offset + c_subband_weight_phase;
CONSTANT c_exp_remnant_subband_ampl : REAL := REAL(c_wg_remnant_ampl) * c_sdp_wpfb_subband_sp_ampl_ratio * c_subband_weight_gain;
TYPE t_real_arr IS ARRAY (INTEGER RANGE <>) OF REAL;
TYPE t_slv_64_subbands_arr IS ARRAY (INTEGER RANGE <>) OF t_slv_64_arr(0 TO c_sdp_N_sub-1); -- 512
TYPE t_slv_64_beamlets_arr IS ARRAY (INTEGER RANGE <>) OF t_slv_64_arr(0 TO c_sdp_N_beamlets_sdp-1); -- 2*488 = 976
-- BF X-pol and Y-pol
-- . select
CONSTANT c_exp_beamlet_x_index : NATURAL := g_beamlet * c_sdp_N_pol_bf; -- X index in beamset 0
CONSTANT c_exp_beamlet_y_index : NATURAL := g_beamlet * c_sdp_N_pol_bf + 1; -- Y index in beamset 0
-- . Beamlet weights for selected g_sp
CONSTANT c_bf_x_weight_re : INTEGER := INTEGER(COMPLEX_RE(g_bf_x_gain * REAL(c_sdp_unit_bf_weight), g_bf_x_phase));
CONSTANT c_bf_x_weight_im : INTEGER := INTEGER(COMPLEX_IM(g_bf_x_gain * REAL(c_sdp_unit_bf_weight), g_bf_x_phase));
CONSTANT c_bf_y_weight_re : INTEGER := INTEGER(COMPLEX_RE(g_bf_y_gain * REAL(c_sdp_unit_bf_weight), g_bf_y_phase));
CONSTANT c_bf_y_weight_im : INTEGER := INTEGER(COMPLEX_IM(g_bf_y_gain * REAL(c_sdp_unit_bf_weight), g_bf_y_phase));
CONSTANT c_bf_remnant_x_weight_re : INTEGER := INTEGER(COMPLEX_RE(g_bf_remnant_x_gain * REAL(c_sdp_unit_bf_weight), g_bf_remnant_x_phase));
CONSTANT c_bf_remnant_x_weight_im : INTEGER := INTEGER(COMPLEX_IM(g_bf_remnant_x_gain * REAL(c_sdp_unit_bf_weight), g_bf_remnant_x_phase));
CONSTANT c_bf_remnant_y_weight_re : INTEGER := INTEGER(COMPLEX_RE(g_bf_remnant_y_gain * REAL(c_sdp_unit_bf_weight), g_bf_remnant_y_phase));
CONSTANT c_bf_remnant_y_weight_im : INTEGER := INTEGER(COMPLEX_IM(g_bf_remnant_y_gain * REAL(c_sdp_unit_bf_weight), g_bf_remnant_y_phase));
-- Model the SDP beamformer for one g_sp and S_pn-1 = 11 remnant signal inputs
FUNCTION bf_calculate_expected_beamlet(sp_subband_ampl, sp_subband_phase, sp_bf_gain, sp_bf_phase,
rem_subband_ampl, rem_subband_phase, rem_bf_gain, rem_bf_phase : REAL) RETURN t_real_arr IS -- 0:3 = ampl, phase, re, im
CONSTANT c_nof_rem : REAL := REAL(c_nof_rn * c_sdp_S_pn - 1); -- BF for one g_sp and N_rn * S_PN - 1 remnant signal inputs
VARIABLE v_sp_ampl, v_sp_phase, v_sp_re, v_sp_im : REAL;
VARIABLE v_rem_ampl, v_rem_phase, v_rem_re, v_rem_im : REAL;
VARIABLE v_sum_ampl, v_sum_phase, v_sum_re, v_sum_im : REAL;
VARIABLE v_tuple : t_real_arr(0 TO 3);
BEGIN
v_sp_ampl := sp_subband_ampl * sp_bf_gain;
v_sp_phase := sp_subband_phase + sp_bf_phase;
v_sp_re := COMPLEX_RE(v_sp_ampl, v_sp_phase);
v_sp_im := COMPLEX_IM(v_sp_ampl, v_sp_phase);
v_rem_ampl := rem_subband_ampl * rem_bf_gain;
v_rem_phase := rem_subband_phase + rem_bf_phase;
v_rem_re := COMPLEX_RE(v_rem_ampl, v_rem_phase);
v_rem_im := COMPLEX_IM(v_rem_ampl, v_rem_phase);
v_sum_re := v_sp_re + c_nof_rem * v_rem_re; -- BF sum re
v_sum_im := v_sp_im + c_nof_rem * v_rem_im; -- BF sum im
v_sum_ampl := COMPLEX_RADIUS(v_sum_re, v_sum_im);
v_sum_phase := COMPLEX_PHASE(v_sum_re, v_sum_im);
v_tuple := (0 => v_sum_ampl, 1 => v_sum_phase, 2 => v_sum_re, 3 => v_sum_im);
RETURN v_tuple;
END;
-- . Beamlet internal
CONSTANT c_exp_beamlet_x_tuple : t_real_arr(0 TO 3) := bf_calculate_expected_beamlet(
c_exp_subband_ampl, c_exp_subband_phase, g_bf_x_gain, g_bf_x_phase,
c_exp_remnant_subband_ampl, c_exp_remnant_subband_phase, g_bf_remnant_x_gain, g_bf_remnant_x_phase);
CONSTANT c_exp_beamlet_x_ampl : REAL := c_exp_beamlet_x_tuple(0);
CONSTANT c_exp_beamlet_x_phase : REAL := c_exp_beamlet_x_tuple(1);
CONSTANT c_exp_beamlet_x_re : REAL := c_exp_beamlet_x_tuple(2);
CONSTANT c_exp_beamlet_x_im : REAL := c_exp_beamlet_x_tuple(3);
CONSTANT c_exp_beamlet_y_tuple : t_real_arr(0 TO 3) := bf_calculate_expected_beamlet(
c_exp_subband_ampl, c_exp_subband_phase, g_bf_y_gain, g_bf_y_phase,
c_exp_remnant_subband_ampl, c_exp_remnant_subband_phase, g_bf_remnant_y_gain, g_bf_remnant_y_phase);
CONSTANT c_exp_beamlet_y_ampl : REAL := c_exp_beamlet_y_tuple(0);
CONSTANT c_exp_beamlet_y_phase : REAL := c_exp_beamlet_y_tuple(1);
CONSTANT c_exp_beamlet_y_re : REAL := c_exp_beamlet_y_tuple(2);
CONSTANT c_exp_beamlet_y_im : REAL := c_exp_beamlet_y_tuple(3);
-- . BST
CONSTANT c_exp_beamlet_x_power : REAL := c_exp_beamlet_x_ampl**2.0; -- complex signal ampl, so no divide by 2
CONSTANT c_exp_beamlet_x_bst : REAL := c_exp_beamlet_x_power * REAL(c_nof_block_per_sync);
CONSTANT c_exp_beamlet_y_power : REAL := c_exp_beamlet_y_ampl**2.0; -- complex signal ampl, so no divide by 2
CONSTANT c_exp_beamlet_y_bst : REAL := c_exp_beamlet_y_power * REAL(c_nof_block_per_sync);
-- . Beamlet output
CONSTANT c_exp_beamlet_x_output_ampl : REAL := c_exp_beamlet_x_ampl * g_beamlet_scale;
CONSTANT c_exp_beamlet_x_output_phase : REAL := c_exp_beamlet_x_phase;
CONSTANT c_exp_beamlet_x_output_re : REAL := c_exp_beamlet_x_re * g_beamlet_scale;
CONSTANT c_exp_beamlet_x_output_im : REAL := c_exp_beamlet_x_im * g_beamlet_scale;
CONSTANT c_exp_beamlet_y_output_ampl : REAL := c_exp_beamlet_y_ampl * g_beamlet_scale;
CONSTANT c_exp_beamlet_y_output_phase : REAL := c_exp_beamlet_y_phase;
CONSTANT c_exp_beamlet_y_output_re : REAL := c_exp_beamlet_y_re * g_beamlet_scale;
CONSTANT c_exp_beamlet_y_output_im : REAL := c_exp_beamlet_y_im * g_beamlet_scale;
-- MM
-- . Address widths of a single MM instance
-- . c_sdp_S_pn = 12 instances
CONSTANT c_addr_w_reg_diag_wg : NATURAL := 2;
-- . c_sdp_N_beamsets = 2 instances
CONSTANT c_addr_w_ram_ss_ss_wide : NATURAL := ceil_log2(c_sdp_P_pfb * c_sdp_S_sub_bf * c_sdp_Q_fft);
CONSTANT c_addr_w_ram_bf_weights : NATURAL := ceil_log2(c_sdp_N_pol_bf * c_sdp_P_pfb * c_sdp_S_sub_bf * c_sdp_Q_fft);
CONSTANT c_addr_w_reg_bf_scale : NATURAL := 1;
CONSTANT c_addr_w_reg_hdr_dat : NATURAL := ceil_log2(field_nof_words(c_sdp_cep_hdr_field_arr, c_word_w));
CONSTANT c_addr_w_reg_dp_xonoff : NATURAL := 1;
CONSTANT c_addr_w_ram_st_bst : NATURAL := ceil_log2(c_sdp_S_sub_bf*c_sdp_N_pol_bf*c_stat_data_sz);
-- . Address spans of a single MM instance
-- . c_sdp_S_pn = 12 instances
CONSTANT c_mm_span_reg_diag_wg : NATURAL := 2**c_addr_w_reg_diag_wg;
-- . c_sdp_N_beamsets = 2 instances
CONSTANT c_mm_span_ram_ss_ss_wide : NATURAL := 2**c_addr_w_ram_ss_ss_wide;
CONSTANT c_mm_span_ram_bf_weights : NATURAL := 2**c_addr_w_ram_bf_weights;
CONSTANT c_mm_span_reg_bf_scale : NATURAL := 2**c_addr_w_reg_bf_scale;
CONSTANT c_mm_span_reg_hdr_dat : NATURAL := 2**c_addr_w_reg_hdr_dat;
CONSTANT c_mm_span_reg_dp_xonoff : NATURAL := 2**c_addr_w_reg_dp_xonoff;
CONSTANT c_mm_span_ram_st_bst : NATURAL := 2**c_addr_w_ram_st_bst;
CONSTANT c_mm_file_reg_ppsh : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "PIO_PPS";
CONSTANT c_mm_file_reg_bsn_source_v2 : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BSN_SOURCE_V2";
CONSTANT c_mm_file_reg_bsn_scheduler_wg : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BSN_SCHEDULER";
CONSTANT c_mm_file_reg_diag_wg : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_WG";
CONSTANT c_mm_file_ram_equalizer_gains : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "RAM_EQUALIZER_GAINS";
CONSTANT c_mm_file_reg_dp_selector : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_DP_SELECTOR";
CONSTANT c_mm_file_ram_st_sst : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "RAM_ST_SST";
CONSTANT c_mm_file_ram_st_bst : STRING := mmf_unb_file_prefix(c_unb_nr + ((c_nof_rn-1) / c_quad), (c_nof_rn-1) MOD c_quad) & "RAM_ST_BST"; --end RN
CONSTANT c_mm_file_reg_dp_xonoff : STRING := mmf_unb_file_prefix(c_unb_nr + ((c_nof_rn-1) / c_quad), (c_nof_rn-1) MOD c_quad) & "REG_DP_XONOFF"; --end RN
CONSTANT c_mm_file_ram_ss_ss_wide : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "RAM_SS_SS_WIDE";
CONSTANT c_mm_file_ram_bf_weights : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "RAM_BF_WEIGHTS";
CONSTANT c_mm_file_reg_bf_scale : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BF_SCALE";
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
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 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
SIGNAL gen_pps : STD_LOGIC := '0';
SIGNAL in_sync : STD_LOGIC := '0';
SIGNAL in_sync_cnt : NATURAL := 0;
SIGNAL test_sync_cnt : INTEGER := 0;
-- MM
SIGNAL rd_sdp_info : t_sdp_info := c_sdp_info_rst;
SIGNAL rd_beamlet_scale : STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL rd_cep_eth_dst_mac : STD_LOGIC_VECTOR(47 DOWNTO 0);
SIGNAL rd_cep_ip_dst_addr : STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL rd_cep_udp_dst_port : STD_LOGIC_VECTOR(15 DOWNTO 0);
-- WG
SIGNAL current_bsn_wg : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0);
-- FSUB
-- . Read sp_ssts_arr2 = SST for one WPFB unit that processes g_sp
SIGNAL sp_ssts_arr2 : t_slv_64_subbands_arr(c_sdp_N_pol-1 DOWNTO 0); -- [pol][sub], for X,Y pair of A, B
SIGNAL sp_sst : REAL := 0.0;
SIGNAL stat_data : STD_LOGIC_VECTOR(c_longword_w-1 DOWNTO 0);
-- . Selector
SIGNAL sst_weighted_subbands_flag : STD_LOGIC;
-- . Subband equalizer
SIGNAL sp_subband_weight_re : INTEGER := 0;
SIGNAL sp_subband_weight_im : INTEGER := 0;
SIGNAL sp_subband_weight_gain : REAL := 0.0;
SIGNAL sp_subband_weight_phase : REAL := 0.0;
-- BF
-- . beamlet subband selection
SIGNAL sp_subband_select : NATURAL := 0;
SIGNAL sp_subband_select_arr : t_natural_arr(0 TO c_sdp_S_sub_bf * c_sdp_N_pol-1) := (OTHERS => 0); -- Q_fft = N_pol = 2
-- . beamlet X-pol
SIGNAL sp_bf_x_weights_re_arr : t_integer_arr(0 TO c_nof_rn * c_sdp_S_pn-1) := (OTHERS => 0);
SIGNAL sp_bf_x_weights_im_arr : t_integer_arr(0 TO c_nof_rn * c_sdp_S_pn-1) := (OTHERS => 0);
SIGNAL sp_bf_x_weights_gain_arr : t_real_arr(0 TO c_nof_rn * c_sdp_S_pn-1) := (OTHERS => 0.0);
SIGNAL sp_bf_x_weights_phase_arr : t_real_arr(0 TO c_nof_rn * c_sdp_S_pn-1) := (OTHERS => 0.0);
-- . beamlet Y-pol
SIGNAL sp_bf_y_weights_re_arr : t_integer_arr(0 TO c_nof_rn * c_sdp_S_pn-1) := (OTHERS => 0);
SIGNAL sp_bf_y_weights_im_arr : t_integer_arr(0 TO c_nof_rn * c_sdp_S_pn-1) := (OTHERS => 0);
SIGNAL sp_bf_y_weights_gain_arr : t_real_arr(0 TO c_nof_rn * c_sdp_S_pn-1) := (OTHERS => 0.0);
SIGNAL sp_bf_y_weights_phase_arr : t_real_arr(0 TO c_nof_rn * c_sdp_S_pn-1) := (OTHERS => 0.0);
-- . BST
SIGNAL bsts_arr2 : t_slv_64_beamlets_arr(c_sdp_N_pol_bf-1 DOWNTO 0); -- [pol_bf][blet]
SIGNAL bst_x_arr : t_real_arr(0 TO c_sdp_N_beamsets-1) := (OTHERS => 0.0); -- [bset] for BF X pol
SIGNAL bst_y_arr : t_real_arr(0 TO c_sdp_N_beamsets-1) := (OTHERS => 0.0); -- [bset] for BF Y pol
-- CEP model
-- . 10GbE
SIGNAL tr_10GbE_src_out : t_dp_sosi;
SIGNAL tr_10GbE_src_in : t_dp_siso;
SIGNAL tr_ref_clk_312 : STD_LOGIC := '0';
SIGNAL tr_ref_clk_156 : STD_LOGIC := '0';
SIGNAL tr_ref_rst_156 : STD_LOGIC := '0';
-- . dp_offload_rx
SIGNAL rx_hdr_dat_mosi : t_mem_mosi := c_mem_mosi_rst;
SIGNAL rx_hdr_dat_miso : t_mem_miso;
SIGNAL rx_hdr_fields_out : STD_LOGIC_VECTOR(1023 DOWNTO 0);
SIGNAL rx_hdr_fields_raw : STD_LOGIC_VECTOR(1023 DOWNTO 0) := (OTHERS => '0');
-- Beamlets packets header
SIGNAL rx_sdp_cep_header : t_sdp_cep_header;
SIGNAL exp_sdp_cep_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;
SIGNAL rx_beamlet_arr_re : t_slv_8_arr(c_sdp_cep_nof_blocks_per_packet-1 DOWNTO 0); -- [3:0]
SIGNAL rx_beamlet_arr_im : t_slv_8_arr(c_sdp_cep_nof_blocks_per_packet-1 DOWNTO 0); -- [3:0]
SIGNAL rx_beamlet_cnt : NATURAL;
SIGNAL rx_beamlet_valid : STD_LOGIC;
SIGNAL rx_beamlet_list_re : t_slv_8_arr(c_sdp_cep_nof_beamlets_per_block * c_sdp_N_pol_bf-1 DOWNTO 0); -- [488 * 2-1:0] = [975:0]
SIGNAL rx_beamlet_list_im : t_slv_8_arr(c_sdp_cep_nof_beamlets_per_block * c_sdp_N_pol_bf-1 DOWNTO 0); -- [488 * 2-1:0] = [975:0]
-- DUT
SIGNAL ext_clk : STD_LOGIC := '0';
SIGNAL ext_pps : STD_LOGIC := '0';
SIGNAL WDI : STD_LOGIC;
SIGNAL INTA : STD_LOGIC;
SIGNAL INTB : STD_LOGIC;
SIGNAL eth_clk : STD_LOGIC_VECTOR(c_unb2c_board_nof_eth-1 downto 0) := (OTHERS => '0');
SIGNAL eth_txp : STD_LOGIC_VECTOR(c_unb2c_board_nof_eth-1 downto 0);
SIGNAL eth_rxp : STD_LOGIC_VECTOR(c_unb2c_board_nof_eth-1 downto 0);
SIGNAL SA_CLK : STD_LOGIC := '1';
SIGNAL i_QSFP_0_TX : t_unb2c_board_qsfp_bus_2arr(c_nof_rn -1 DOWNTO 0) := (OTHERS => (OTHERS => '0'));
SIGNAL i_QSFP_0_RX : t_unb2c_board_qsfp_bus_2arr(c_nof_rn -1 DOWNTO 0) := (OTHERS => (OTHERS => '0'));
SIGNAL i_RING_0_TX : t_unb2c_board_qsfp_bus_2arr(c_nof_rn -1 DOWNTO 0) := (OTHERS => (OTHERS => '0'));
SIGNAL i_RING_0_RX : t_unb2c_board_qsfp_bus_2arr(c_nof_rn -1 DOWNTO 0) := (OTHERS => (OTHERS => '0'));
SIGNAL i_RING_1_TX : t_unb2c_board_qsfp_bus_2arr(c_nof_rn -1 DOWNTO 0) := (OTHERS => (OTHERS => '0'));
SIGNAL i_RING_1_RX : t_unb2c_board_qsfp_bus_2arr(c_nof_rn -1 DOWNTO 0) := (OTHERS => (OTHERS => '0'));
SIGNAL i_QSFP_1_lpbk : t_unb2c_board_qsfp_bus_2arr(c_nof_rn -1 DOWNTO 0) := (OTHERS => (OTHERS => '0'));
-- back transceivers
SIGNAL JESD204B_SERIAL_DATA : STD_LOGIC_VECTOR(c_sdp_S_pn-1 downto 0);
SIGNAL JESD204B_REFCLK : STD_LOGIC := '1';
-- jesd204b syncronization signals
SIGNAL jesd204b_sysref : STD_LOGIC;
SIGNAL jesd204b_sync_n : STD_LOGIC_VECTOR(c_sdp_N_sync_jesd-1 DOWNTO 0);
BEGIN
----------------------------------------------------------------------------
-- System setup
----------------------------------------------------------------------------
ext_clk <= NOT ext_clk AFTER c_ext_clk_period/2; -- External clock (200 MHz)
eth_clk(0) <= NOT eth_clk(0) AFTER c_eth_clk_period/2; -- Ethernet ref clock (125 MHz)
JESD204B_REFCLK <= NOT JESD204B_REFCLK AFTER c_bck_ref_clk_period/2; -- JESD sample clock (200MHz)
SA_CLK <= NOT SA_CLK AFTER c_sa_clk_period/2; -- Serial Gigabit IO sa clock (644 MHz)
dest_rst <= '0' AFTER c_ext_clk_period * 10;
INTA <= 'H'; -- pull up
INTB <= 'H'; -- pull up
------------------------------------------------------------------------------
-- External PPS
------------------------------------------------------------------------------
proc_common_gen_pulse(5, c_pps_period, '1', pps_rst, ext_clk, gen_pps);
jesd204b_sysref <= gen_pps;
ext_pps <= gen_pps;
------------------------------------------------------------------------------
-- DUT
------------------------------------------------------------------------------
gen_dut : FOR RN IN 0 TO c_nof_rn -1 GENERATE
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_ring",
g_design_note => "",
g_sim => c_sim,
g_sim_unb_nr => c_unb_nr + (RN / c_quad),
g_sim_node_nr => RN MOD c_quad,
g_wpfb => c_wpfb_sim,
g_bsn_nof_clk_per_sync => c_nof_clk_per_sync,
g_scope_selected_subband => g_subband
)
PORT MAP (
-- GENERAL
CLK => ext_clk,
PPS => ext_pps,
WDI => WDI,
INTA => INTA,
INTB => INTB,
-- Others
VERSION => c_version,
ID => ( TO_UVEC(RN / c_quad, c_unb2c_board_nof_uniboard_w) & TO_UVEC(RN MOD c_quad, c_unb2c_board_nof_chip_w) ),
TESTIO => open,
-- 1GbE Control Interface
ETH_CLK => eth_clk,
ETH_SGIN => eth_rxp,
ETH_SGOUT => eth_txp,
-- Transceiver clocks
SA_CLK => SA_CLK,
-- front transceivers for ring
QSFP_0_RX => i_QSFP_0_RX(RN),
QSFP_0_TX => i_QSFP_0_TX(RN),
-- ring transceivers
RING_0_RX => i_RING_0_RX(RN),
RING_0_TX => i_RING_0_TX(RN),
RING_1_RX => i_RING_1_RX(RN),
RING_1_TX => i_RING_1_TX(RN),
-- front transceivers for CEP
QSFP_1_RX => i_QSFP_1_lpbk(RN),
QSFP_1_TX => i_QSFP_1_lpbk(RN),
-- LEDs
QSFP_LED => open,
-- back transceivers
JESD204B_SERIAL_DATA => JESD204B_SERIAL_DATA,
JESD204B_REFCLK => JESD204B_REFCLK,
-- jesd204b syncronization signals
JESD204B_SYSREF => jesd204b_sysref,
JESD204B_SYNC_N => jesd204b_sync_n
);
END GENERATE;
-- Ring connections
gen_ring : FOR I IN 0 TO c_nof_rn -2 GENERATE
-- Connect consecutive nodes with RING interfaces (PCB)
i_RING_0_RX(I+1) <= i_RING_1_TX(I);
i_RING_1_RX(I) <= i_RING_0_TX(I+1);
END GENERATE;
-- Connect first and last nodes with QSFP interface.
i_QSFP_0_RX(0) <= i_QSFP_0_TX(c_nof_rn-1);
i_QSFP_0_RX(c_nof_rn-1) <= i_QSFP_0_TX(0);
------------------------------------------------------------------------------
-- CEP model
------------------------------------------------------------------------------
u_unb2_board_clk644_pll : ENTITY tech_pll_lib.tech_pll_xgmii_mac_clocks
PORT MAP (
refclk_644 => SA_CLK,
rst_in => dest_rst,
clk_156 => tr_ref_clk_156,
clk_312 => tr_ref_clk_312,
rst_156 => tr_ref_rst_156,
rst_312 => OPEN
);
u_tr_10GbE: ENTITY tr_10GbE_lib.tr_10GbE
GENERIC MAP (
g_sim => TRUE,
g_sim_level => 1,
g_nof_macs => 1,
g_use_mdio => FALSE
)
PORT MAP (
-- Transceiver PLL reference clock
tr_ref_clk_644 => SA_CLK,
tr_ref_clk_312 => tr_ref_clk_312, -- 312.5 MHz for 10GBASE-R
tr_ref_clk_156 => tr_ref_clk_156, -- 156.25 MHz for 10GBASE-R or for XAUI
tr_ref_rst_156 => tr_ref_rst_156, -- for 10GBASE-R or for XAUI
-- MM interface
mm_rst => dest_rst,
mm_clk => tb_clk,
-- DP interface
dp_rst => dest_rst,
dp_clk => ext_clk,
serial_rx_arr(0) => i_QSFP_1_lpbk(c_nof_rn-1)(0), -- Last RN must be used as end node.
src_out_arr(0) => tr_10GbE_src_out,
src_in_arr(0) => tr_10GbE_src_in
);
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 => dest_rst,
mm_clk => tb_clk,
dp_rst => dest_rst,
dp_clk => ext_clk,
reg_hdr_dat_mosi => rx_hdr_dat_mosi,
reg_hdr_dat_miso => rx_hdr_dat_miso,
snk_in_arr(0) => tr_10GbE_src_out,
snk_out_arr(0) => tr_10GbE_src_in,
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
);
------------------------------------------------------------------------------
-- MM slave accesses via file IO
------------------------------------------------------------------------------
tb_clk <= NOT tb_clk AFTER c_tb_clk_period/2; -- Testbench MM clock
p_mm_stimuli : PROCESS
VARIABLE v_bsn : NATURAL;
VARIABLE v_sp_sst : REAL := 0.0;
VARIABLE v_bst : REAL := 0.0;
VARIABLE v_data_lo, v_data_hi : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
VARIABLE v_stat_data : STD_LOGIC_VECTOR(c_longword_w-1 DOWNTO 0);
VARIABLE v_len, v_span, v_offset, v_addr, v_sel : NATURAL; -- address ranges, indices
VARIABLE v_W, v_P, v_PB, v_S, v_A, v_B, v_G : NATURAL; -- array indicies
VARIABLE v_re, v_im, v_weight : INTEGER;
VARIABLE v_re_exp, v_im_exp : REAL := 0.0;
BEGIN
-- Wait for DUT power up after reset
WAIT FOR 1 us;
print_str("");
print_str("WG:");
print_str(". c_wg_ampl = " & int_to_str(c_wg_ampl));
print_str(". c_exp_sp_power = " & real_to_str(c_exp_sp_power, 20, 1));
print_str(". c_exp_sp_ast = " & real_to_str(c_exp_sp_ast, 20, 1));
print_str("");
print_str("Subband weight:");
print_str(". sp_subband_weight_gain = " & real_to_str(sp_subband_weight_gain, 20, 6));
print_str(". sp_subband_weight_phase = " & real_to_str(sp_subband_weight_phase, 20, 6));
print_str("");
print_str("SST results:");
print_str(". sst_weighted_subbands_flag = " & sl_to_str(sst_weighted_subbands_flag));
print_str("");
print_str(". c_exp_subband_ampl = " & int_to_str(NATURAL(c_exp_subband_ampl)));
print_str(". c_exp_subband_power = " & real_to_str(c_exp_subband_power, 20, 1));
print_str(". c_exp_subband_sst = " & real_to_str(c_exp_subband_sst, 20, 1));
print_str("");
print_str(". sp_sst = " & real_to_str(sp_sst, 20, 1));
print_str(". sp_sst / c_exp_subband_sst = " & real_to_str(sp_sst / c_exp_subband_sst, 20, 6));
print_str("");
print_str("BST results:");
print_str(". c_exp_beamlet_x_ampl = " & int_to_str(NATURAL(c_exp_beamlet_x_ampl)));
print_str(". c_exp_beamlet_x_power = " & real_to_str(c_exp_beamlet_x_power, 20, 1));
print_str(". c_exp_beamlet_x_bst = " & real_to_str(c_exp_beamlet_x_bst, 20, 1));
print_str("");
print_str(". c_exp_beamlet_y_ampl = " & int_to_str(NATURAL(c_exp_beamlet_y_ampl)));
print_str(". c_exp_beamlet_y_power = " & real_to_str(c_exp_beamlet_y_power, 20, 1));
print_str(". c_exp_beamlet_y_bst = " & real_to_str(c_exp_beamlet_y_bst, 20, 1));
print_str("");
----------------------------------------------------------------------------
-- Set and check SDP info
----------------------------------------------------------------------------
-- TYPE t_sdp_info IS RECORD
-- 7 station_id : STD_LOGIC_VECTOR(15 DOWNTO 0);
-- 6 antenna_band_index : STD_LOGIC;
-- 5 observation_id : STD_LOGIC_VECTOR(31 DOWNTO 0);
-- 4 nyquist_zone_index : STD_LOGIC_VECTOR(1 DOWNTO 0);
-- 3 f_adc : STD_LOGIC;
-- 2 fsub_type : STD_LOGIC;
-- 1 beam_repositioning_flag : STD_LOGIC;
-- 0 block_period : STD_LOGIC_VECTOR(15 DOWNTO 0);
-- END RECORD;
-- . Write
FOR RN IN 0 TO c_nof_rn-1 LOOP
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_SDP_INFO", 7, TO_UINT(c_exp_sdp_info.station_id), tb_clk);
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_SDP_INFO", 6, TO_UINT(slv(c_exp_sdp_info.antenna_band_index)), tb_clk);
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_SDP_INFO", 5, TO_UINT(c_exp_sdp_info.observation_id), tb_clk);
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_SDP_INFO", 4, TO_UINT(c_exp_sdp_info.nyquist_zone_index), tb_clk);
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_SDP_INFO", 1, TO_UINT(slv(c_exp_sdp_info.beam_repositioning_flag)), tb_clk);
-- . Read
mmf_mm_bus_rd(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_SDP_INFO", 3, rd_data, tb_clk); rd_sdp_info.f_adc <= rd_data(0);
mmf_mm_bus_rd(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_SDP_INFO", 2, rd_data, tb_clk); rd_sdp_info.fsub_type <= rd_data(0);
mmf_mm_bus_rd(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_SDP_INFO", 0, rd_data, tb_clk); rd_sdp_info.block_period <= rd_data(15 DOWNTO 0);
END LOOP;
proc_common_wait_some_cycles(tb_clk, 1);
-- . Verify read
ASSERT c_exp_sdp_info.f_adc = rd_sdp_info.f_adc REPORT "Wrong MM read SDP info f_adc" SEVERITY ERROR;
ASSERT c_exp_sdp_info.fsub_type = rd_sdp_info.fsub_type REPORT "Wrong MM read SDP info fsub_type" SEVERITY ERROR;
ASSERT c_exp_sdp_info.block_period = rd_sdp_info.block_period REPORT "Wrong MM read SDP info block_period" SEVERITY ERROR;
------------------------------------------------------------------------------
---- 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;
FOR RN IN 0 TO c_nof_rn-1 LOOP
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_BF_SCALE", v_offset + 0, c_exp_beamlet_scale, tb_clk);
END LOOP;
proc_common_wait_cross_clock_domain_latency(c_mm_clk_period, c_ext_clk_period);
-- . readback
mmf_mm_bus_rd(c_mm_file_reg_bf_scale, v_offset + 0, rd_data, tb_clk);
rd_beamlet_scale <= rd_data(15 DOWNTO 0);
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;
-- 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) ),
-- 38 "eth_src_mac" ), "RW", 48, field_default(0) ),
-- 37 "eth_type" ), "RW", 16, field_default(x"0800") ),
--
-- 36 "ip_version" ), "RW", 4, field_default(4) ),
-- 35 "ip_header_length" ), "RW", 4, field_default(5) ),
-- 34 "ip_services" ), "RW", 8, field_default(0) ),
-- 33 "ip_total_length" ), "RW", 16, field_default(c_sdp_cep_ip_total_length) ),
-- 32 "ip_identification" ), "RW", 16, field_default(0) ),
-- 31 "ip_flags" ), "RW", 3, field_default(2) ),
-- 30 "ip_fragment_offset" ), "RW", 13, field_default(0) ),
-- 29 "ip_time_to_live" ), "RW", 8, field_default(127) ),
-- 28 "ip_protocol" ), "RW", 8, field_default(17) ),
-- 27 "ip_header_checksum" ), "RW", 16, field_default(0) ),
-- 26 "ip_src_addr" ), "RW", 32, field_default(0) ),
-- 25 "ip_dst_addr" ), "RW", 32, field_default(c_sdp_cep_ip_dst_addr) ),
--
-- 24 "udp_src_port" ), "RW", 16, field_default(0) ),
-- 23 "udp_dst_port" ), "RW", 16, field_default(c_sdp_cep_udp_dst_port) ),
-- 22 "udp_total_length" ), "RW", 16, field_default(c_sdp_cep_udp_total_length) ),
-- 21 "udp_checksum" ), "RW", 16, field_default(0) ),
--
-- 20 "sdp_marker" ), "RW", 8, field_default(c_sdp_marker_beamlets) ),
-- 19 "sdp_version_id" ), "RW", 8, field_default(c_sdp_cep_version_id) ),
-- 18 "sdp_observation_id" ), "RW", 32, field_default(0) ),
-- 17 "sdp_station_id" ), "RW", 16, field_default(0) ),
--
-- 16 "sdp_source_info_antenna_band_id" ), "RW", 1, field_default(0) ),
-- 15 "sdp_source_info_nyquist_zone_id" ), "RW", 2, field_default(0) ),
-- 14 "sdp_source_info_f_adc" ), "RW", 1, field_default(0) ),
-- 13 "sdp_source_info_fsub_type" ), "RW", 1, field_default(0) ),
-- 12 "sdp_source_info_payload_error" ), "RW", 1, field_default(0) ),
-- 11 "sdp_source_info_repositioning_flag" ), "RW", 1, field_default(0) ),
-- 10 "sdp_source_info_beamlet_width" ), "RW", 4, field_default(c_sdp_W_beamlet) ),
-- 9 "sdp_source_info_gn_id" ), "RW", 5, field_default(0) ),
--
-- 7 "sdp_reserved" ), "RW", 40, field_default(0) ),
-- 6 "sdp_beamlet_scale" ), "RW", 16, field_default(c_sdp_beamlet_scale_default) ),
-- 5 "sdp_beamlet_index" ), "RW", 16, field_default(0) ),
-- 4 "sdp_nof_blocks_per_packet" ), "RW", 8, field_default(c_sdp_cep_nof_blocks_per_packet) ),
-- 3 "sdp_nof_beamlets_per_block" ), "RW", 16, field_default(c_sdp_cep_nof_beamlets_per_block) ),
-- 2 "sdp_block_period" ), "RW", 16, field_default(c_sdp_block_period) ),
--
-- 0 "dp_bsn" ), "RW", 64, field_default(0) )
-- );
v_offset := bset * c_mm_span_reg_hdr_dat;
-- . Use defaults, so no need to write
-- . Read
mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 41, rd_data, tb_clk); rd_cep_eth_dst_mac(47 DOWNTO 32) <= rd_data(15 DOWNTO 0);
mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 40, rd_data, tb_clk); rd_cep_eth_dst_mac(31 DOWNTO 0) <= rd_data;
mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 25, rd_data, tb_clk); rd_cep_ip_dst_addr <= rd_data;
mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 23, rd_data, tb_clk); rd_cep_udp_dst_port <= rd_data(15 DOWNTO 0);
proc_common_wait_some_cycles(tb_clk, 1);
-- verify read
ASSERT rd_cep_eth_dst_mac = c_sdp_cep_eth_dst_mac REPORT "Wrong MM read rd_cep_eth_dst_mac for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; -- 00074306C700 = DOP36-eth0
ASSERT rd_cep_ip_dst_addr = c_sdp_cep_ip_dst_addr REPORT "Wrong MM read rd_cep_ip_dst_addr for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; -- C0A80001 = '192.168.0.1' = DOP36-eth0
ASSERT rd_cep_udp_dst_port = c_sdp_cep_udp_dst_port REPORT "Wrong MM read rd_cep_udp_dst_port for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; -- 5000
----------------------------------------------------------------------------
-- Enable beamlet UDP offload off end node (dp_xonoff)
----------------------------------------------------------------------------
v_offset := bset * c_mm_span_reg_dp_xonoff;
mmf_mm_bus_wr(c_mm_file_reg_dp_xonoff, v_offset + 0, 1, tb_clk);
END LOOP;
----------------------------------------------------------------------------
-- Enable BS
----------------------------------------------------------------------------
FOR RN IN 0 TO c_nof_rn-1 LOOP
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_BSN_SOURCE_V2", 2, c_init_bsn, tb_clk); -- Init BSN
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_BSN_SOURCE_V2", 3, 0, tb_clk); -- Write high part a
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_BSN_SOURCE_V2", 1, c_nof_clk_per_sync, tb_clk); -- nof_block_per_syn
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_BSN_SOURCE_V2", 0, 16#00000003#, tb_clk); -- Enable BS at PPS
END LOOP;
-- Release PPS pulser, to get first PPS now and to start BSN source
WAIT FOR 1 us;
pps_rst <= '0';
----------------------------------------------------------------------------
-- Ring config
----------------------------------------------------------------------------
-- Write ring configuration to all nodes.
FOR RN IN 0 TO c_nof_rn-1 LOOP
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_RING_INFO", 2, c_nof_rn, tb_clk); -- N_rn
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_RING_INFO", 3, 0, tb_clk); -- O_rn
END LOOP;
-- Start node specific settings
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr, 0) & "REG_RING_INFO", 0, 1, tb_clk); -- use_ring_to_previous_rn = 1
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr, 0) & "REG_RING_INFO", 1, 0, tb_clk); -- use_ring_to_next_rn = 0
-- End node specific settings
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + ((c_nof_rn-1) / c_quad), (c_nof_rn-1) MOD c_quad) & "REG_RING_INFO", 0, 0, tb_clk); -- use_ring_to_previous_rn = 0
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + ((c_nof_rn-1) / c_quad), (c_nof_rn-1) MOD c_quad) & "REG_RING_INFO", 1, 1, tb_clk); -- use_ring_to_next_rn = 1
-- Access scheme 1. Each RN uses and sends them along the ring.
FOR RN IN 0 TO c_nof_rn-1 LOOP
FOR I IN 0 TO c_nof_lanes-1 LOOP
IF RN = c_nof_rn-1 THEN
-- End RN, so set transport_nof_hops to 0.
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_RING_LANE_INFO_BF", I*2+1, 0, tb_clk);
ELSE
-- Set transport_nof_hops to 1 on all nodes.
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_RING_LANE_INFO_BF", I*2+1, 1, tb_clk);
END IF;
END LOOP;
END LOOP;
----------------------------------------------------------------------------
-- Enable and start WG
----------------------------------------------------------------------------
-- 0 : mode[7:0] --> off=0, calc=1, repeat=2, single=3)
-- nof_samples[31:16] --> <= c_ram_wg_size=1024
-- 1 : phase[15:0]
-- 2 : freq[30:0]
-- 3 : ampl[16:0]
-- . Put wanted signal on g_sp input and remnant signal on the other inputs
FOR RN IN 0 TO c_nof_rn-1 LOOP
FOR I IN 0 TO c_sdp_S_pn-1 LOOP
IF RN * c_sdp_S_pn + I = g_sp THEN
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_WG", I*4 + 0, 1024*2**16 + 1, tb_clk); -- nof_samples, mode calc
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_WG", I*4 + 1, INTEGER(c_wg_phase * c_diag_wg_phase_unit), tb_clk); -- phase offset in degrees
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_WG", I*4 + 2, INTEGER(REAL(g_subband) * c_wg_subband_freq_unit), tb_clk); -- freq
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_WG", I*4 + 3, INTEGER(REAL(c_wg_ampl) * c_wg_ampl_lsb), tb_clk); -- ampl
ELSE
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_WG", I*4 + 0, 1024*2**16 + 1, tb_clk); -- nof_samples, mode calc
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_WG", I*4 + 1, INTEGER(c_wg_remnant_phase * c_diag_wg_phase_unit), tb_clk); -- phase offset in degrees
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_WG", I*4 + 2, INTEGER(REAL(g_subband) * c_wg_subband_freq_unit), tb_clk); -- freq
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_WG", I*4 + 3, INTEGER(REAL(c_wg_remnant_ampl) * c_wg_ampl_lsb), tb_clk); -- ampl
END IF;
END LOOP;
END LOOP;
-- Read current BSN
mmf_mm_bus_rd(c_mm_file_reg_bsn_scheduler_wg, 0, current_bsn_wg(31 DOWNTO 0), tb_clk);
mmf_mm_bus_rd(c_mm_file_reg_bsn_scheduler_wg, 1, current_bsn_wg(63 DOWNTO 32), tb_clk);
proc_common_wait_some_cycles(tb_clk, 1);
-- Write scheduler BSN to trigger start of WG at next block
v_bsn := TO_UINT(current_bsn_wg) + 2;
ASSERT v_bsn <= c_bsn_start_wg REPORT "Too late to start WG: " & int_to_str(v_bsn) & " > " & int_to_str(c_bsn_start_wg) SEVERITY ERROR;
FOR RN IN 0 TO c_nof_rn-1 LOOP
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_BSN_SCHEDULER", 0, c_bsn_start_wg, tb_clk); -- first write low then high part
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_BSN_SCHEDULER", 1, 0, tb_clk); -- assume v_bsn < 2**31-1
END LOOP;
----------------------------------------------------------------------------
-- Read weighted subband selector
----------------------------------------------------------------------------
mmf_mm_bus_rd(c_mm_file_reg_dp_selector, 0, rd_data, tb_clk);
sst_weighted_subbands_flag <= NOT rd_data(0);
proc_common_wait_some_cycles(tb_clk, 1);
----------------------------------------------------------------------------
-- Subband weight
----------------------------------------------------------------------------
-- . MM format: (cint16)RAM_EQUALIZER_GAINS[S_pn/Q_fft]_[Q_fft][N_sub] = [S_pn][N_sub]
v_addr := g_sp * c_sdp_N_sub + g_subband;
-- . read
mmf_mm_bus_rd(c_mm_file_ram_equalizer_gains, v_addr, rd_data, tb_clk);
v_re := unpack_complex_re(rd_data, c_sdp_W_sub_weight);
v_im := unpack_complex_im(rd_data, c_sdp_W_sub_weight);
sp_subband_weight_re <= v_re;
sp_subband_weight_im <= v_im;
sp_subband_weight_gain <= COMPLEX_RADIUS(v_re, v_im) / REAL(c_sdp_unit_sub_weight);
sp_subband_weight_phase <= COMPLEX_PHASE(v_re, v_im);
-- No need to write subband weight, because default it is unit weight
----------------------------------------------------------------------------
-- Subband select to map subband to beamlet
----------------------------------------------------------------------------
-- . MM format: (uint16)RAM_SS_SS_WIDE[N_beamsets][A_pn]_[S_sub_bf][Q_fft], Q_fft = N_pol = 2
-- . write selection, only for g_beamlet to save sim time
v_span := true_log_pow2(c_sdp_N_pol * c_sdp_S_sub_bf); -- = 1024
FOR U IN 0 TO c_sdp_N_beamsets-1 LOOP
-- Same selection for both beamsets
-- Select beamlet g_beamlet to subband g_subband
FOR A IN 0 TO c_sdp_A_pn-1 LOOP
-- Same selection to all SP
FOR P IN 0 TO c_sdp_N_pol-1 LOOP
v_addr := P + g_beamlet * c_sdp_N_pol + A * v_span + U * c_mm_span_ram_ss_ss_wide;
v_sel := P + g_subband * c_sdp_N_pol;
FOR RN IN 0 TO c_nof_rn-1 LOOP
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "RAM_SS_SS_WIDE", v_addr, v_sel, tb_clk);
END LOOP;
END LOOP;
END LOOP;
END LOOP;
-- . read back selection for g_sp = c_pfb_index * c_sdp_N_pol + c_pol_index
v_P := c_pol_index;
v_A := c_pfb_index;
FOR U IN 0 TO c_sdp_N_beamsets-1 LOOP
-- Same selection for both beamsets, so fine to use only one sp_subband_select_arr()
FOR B IN 0 TO c_sdp_S_sub_bf-1 LOOP
-- Same selection for all SP, so fine to only read subband selection for g_sp
v_addr := v_P + B * c_sdp_N_pol + v_A * v_span + U * c_mm_span_ram_ss_ss_wide;
mmf_mm_bus_rd(c_mm_file_ram_ss_ss_wide, v_addr, rd_data, tb_clk);
v_sel := (TO_UINT(rd_data) - v_P) / c_sdp_N_pol;
sp_subband_select_arr(B) <= v_sel;
sp_subband_select <= v_sel; -- for time series view in Wave window
END LOOP;
END LOOP;
proc_common_wait_some_cycles(tb_clk, 1);
proc_common_wait_some_cycles(ext_clk, 100); -- delay for ease of view in Wave window
----------------------------------------------------------------------------
-- Write beamlet weight for g_beamlet in S_sub_bf
----------------------------------------------------------------------------
-- . MM format: (cint16)RAM_BF_WEIGHTS[N_beamsets][N_pol_bf][A_pn]_[N_pol][S_sub_bf]
-- . write BF weights, only for g_beamlet to save sim time
v_span := true_log_pow2(c_sdp_N_pol * c_sdp_S_sub_bf); -- = 1024
FOR RN IN 0 TO c_nof_rn-1 LOOP
FOR U IN 0 TO c_sdp_N_beamsets-1 LOOP
-- Same BF weights for both beamsets
FOR PB IN 0 TO c_sdp_N_pol_bf-1 LOOP
-- Same BF weights for both beamlet polarizations
FOR A IN 0 TO c_sdp_A_pn-1 LOOP
FOR P IN 0 TO c_sdp_N_pol-1 LOOP
v_S := RN * c_sdp_S_pn + A * c_sdp_N_pol + P;
IF v_S = g_sp THEN
-- use generic BF weight for g_sp in g_beamlet
IF PB = 0 THEN
v_weight := pack_complex(re => c_bf_x_weight_re, im => c_bf_x_weight_im, w => c_sdp_W_bf_weight);
ELSE
v_weight := pack_complex(re => c_bf_y_weight_re, im => c_bf_y_weight_im, w => c_sdp_W_bf_weight);
END IF;
ELSE
-- use the remnant BF weights for the other SP
IF PB = 0 THEN
v_weight := pack_complex(re => c_bf_remnant_x_weight_re, im => c_bf_remnant_x_weight_im, w => c_sdp_W_bf_weight);
ELSE
v_weight := pack_complex(re => c_bf_remnant_y_weight_re, im => c_bf_remnant_y_weight_im, w => c_sdp_W_bf_weight);
END IF;
END IF;
v_addr := g_beamlet; -- beamlet index
v_addr := v_addr + P * c_sdp_S_sub_bf; -- antenna input polarization address offset
v_addr := v_addr + A * v_span; -- antenna input address offset
v_addr := v_addr + PB * c_sdp_A_pn * v_span; -- beamlet polarization address offset
v_addr := v_addr + U * c_mm_span_ram_bf_weights; -- beamset address offset
mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "RAM_BF_WEIGHTS", v_addr, v_weight, tb_clk);
END LOOP;
END LOOP;
END LOOP;
END LOOP;
END LOOP;
-- . read back BF weights for g_beamlet in S_sub_bf
FOR U IN 0 TO c_sdp_N_beamsets-1 LOOP
FOR PB IN 0 TO c_sdp_N_pol_bf-1 LOOP
FOR A IN 0 TO c_sdp_A_pn-1 LOOP
FOR P IN 0 TO c_sdp_N_pol-1 LOOP
v_addr := g_beamlet; -- beamlet index
v_addr := v_addr + P * c_sdp_S_sub_bf; -- antenna input polarization address offset
v_addr := v_addr + A * v_span; -- antenna input address offset
v_addr := v_addr + PB * c_sdp_A_pn * v_span; -- beamlet polarization address offset
v_addr := v_addr + U * c_mm_span_ram_bf_weights; -- beamset address offset
mmf_mm_bus_rd(c_mm_file_ram_bf_weights, v_addr, rd_data, tb_clk);
v_re := unpack_complex_re(rd_data, c_sdp_W_bf_weight);
v_im := unpack_complex_im(rd_data, c_sdp_W_bf_weight);
-- same BF weights for both beamsets and both beamlet polarizations,
-- so fine to use only one sp_bf_x_weights_*_arr()
v_S := A * c_sdp_N_pol + P;
IF PB = 0 THEN
sp_bf_x_weights_re_arr(v_S) <= v_re;
sp_bf_x_weights_im_arr(v_S) <= v_im;
sp_bf_x_weights_gain_arr(v_S) <= COMPLEX_RADIUS(v_re, v_im) / REAL(c_sdp_unit_bf_weight);
sp_bf_x_weights_phase_arr(v_S) <= COMPLEX_PHASE(v_re, v_im);
ELSE
sp_bf_y_weights_re_arr(v_S) <= v_re;
sp_bf_y_weights_im_arr(v_S) <= v_im;
sp_bf_y_weights_gain_arr(v_S) <= COMPLEX_RADIUS(v_re, v_im) / REAL(c_sdp_unit_bf_weight);
sp_bf_y_weights_phase_arr(v_S) <= COMPLEX_PHASE(v_re, v_im);
END IF;
END LOOP;
END LOOP;
END LOOP;
END LOOP;
proc_common_wait_some_cycles(tb_clk, 1);
proc_common_wait_some_cycles(ext_clk, 100); -- delay for ease of view in Wave window
----------------------------------------------------------------------------
-- Wait for enough WG data and start of sync interval
----------------------------------------------------------------------------
mmf_mm_wait_until_value(c_mm_file_reg_bsn_scheduler_wg, 0, -- read BSN low
"UNSIGNED", rd_data, ">=", c_init_bsn + c_nof_block_per_sync*3, -- this is the wait until condition
c_sdp_T_sub, tb_clk);
-- Stimuli done, now verify results at end of test
stimuli_done <= '1';
---------------------------------------------------------------------------
-- Read subband statistics
---------------------------------------------------------------------------
-- . the subband statistics are c_stat_data_sz = 2 word power values.
-- . there are c_sdp_S_pn = 12 signal inputs A, B, C, D, E, F, G, H, I, J, K, L
-- . there are c_sdp_N_sub = 512 subbands per signal input (SI, = signal path, SP)
-- . one complex WPFB can process two real inputs A, B, so there are c_sdp_P_pfb = 6 WPFB units,
-- but only read for the 1 WPFB unit of the selected g_sp, to save sim time
-- . the outputs for A, B are time multiplexed, c_sdp_Q_fft = 2, assume that they
-- correspond to the c_sdp_N_pol = 2 signal polarizations
-- . the subbands are output alternately so A0 B0 A1 B1 ... A511 B511 for input A, B
-- . the subband statistics multiple WPFB units appear in order in the ram_st_sst address map
-- . the subband statistics are stored first lo word 0 then hi word 1
v_len := c_sdp_N_sub * c_sdp_N_pol * c_stat_data_sz; -- 2048 = 512 * 2 * 64/32
v_span := true_log_pow2(v_len); -- = 2048
FOR I IN 0 TO v_len-1 LOOP
v_W := I MOD c_stat_data_sz; -- 0, 1 per statistics word, word index
v_P := (I / c_stat_data_sz) MOD c_sdp_N_pol; -- 0, 1 per SP pol, polarization index
v_B := I / (c_sdp_N_pol * c_stat_data_sz); -- subband index, range(N_sub = 512) per dual pol
v_addr := I + c_pfb_index * v_span; -- MM address
-- Only read SST for g_subband for dual pol SP, to save sim time
IF g_read_all_SST = TRUE OR v_B = g_subband THEN
IF v_W=0 THEN
-- low part
mmf_mm_bus_rd(c_mm_file_ram_st_sst, v_addr, rd_data, tb_clk);
v_data_lo := rd_data;
ELSE
-- high part
mmf_mm_bus_rd(c_mm_file_ram_st_sst, v_addr, rd_data, tb_clk);
v_data_hi := rd_data;
v_stat_data := v_data_hi & v_data_lo;
sp_ssts_arr2(v_P)(v_B) <= v_stat_data;
stat_data <= v_stat_data; -- for time series view in Wave window
END IF;
END IF;
END LOOP;
proc_common_wait_some_cycles(tb_clk, 1);
-- Subband power of g_subband in g_sp
sp_sst <= TO_UREAL(sp_ssts_arr2(c_pol_index)(g_subband));
proc_common_wait_some_cycles(tb_clk, 1);
proc_common_wait_some_cycles(ext_clk, 100); -- delay for ease of view in Wave window
---------------------------------------------------------------------------
-- Read beamlet statistics from end node
---------------------------------------------------------------------------
-- . the beamlet statistics are c_stat_data_sz = 2 word power values.
-- . there are c_sdp_S_sub_bf = 488 dual pol beamlets per beamset
-- . the beamlets are output alternately so X0 Y0 X1 Y1 ... X487 Y487 for polarizations X, Y
-- . the beamlet statistics for multiple beamsets appear in order in the ram_st_bst address map
-- . the beamlet statistics are stored first lo word 0 then hi word 1
v_len := c_sdp_S_sub_bf * c_sdp_N_pol_bf * c_stat_data_sz; -- = 1952 = 488 * 2 * 64/32
v_span := true_log_pow2(v_len); -- = 2048
FOR U IN 0 TO c_sdp_N_beamsets-1 LOOP
FOR I IN 0 TO v_len-1 LOOP
v_W := I MOD c_stat_data_sz; -- 0, 1 per statistics word, word index
v_PB := (I / c_stat_data_sz) MOD c_sdp_N_pol_bf; -- 0, 1 per BF pol, polarization index
v_B := I / (c_sdp_N_pol_bf * c_stat_data_sz); -- beamlet index in beamset, range(S_sub_bf = 488) per dual pol
v_G := v_B + U * c_sdp_S_sub_bf; -- global beamlet index, range(c_sdp_N_beamlets_sdp)
v_addr := I + U * v_span; -- MM address
--Only read BST for g_beamlet and dual pol_bf 0 and 1 and for both beamsets, to save sim time
IF g_read_all_BST = TRUE OR v_B = g_beamlet THEN
IF v_W = 0 THEN
-- low part
mmf_mm_bus_rd(c_mm_file_ram_st_bst, v_addr, rd_data, tb_clk);
v_data_lo := rd_data;
ELSE
-- high part
mmf_mm_bus_rd(c_mm_file_ram_st_bst, v_addr, rd_data, tb_clk);
v_data_hi := rd_data;
v_stat_data := v_data_hi & v_data_lo;
bsts_arr2(v_PB)(v_G) <= v_stat_data;
stat_data <= v_stat_data; -- for time series view in Wave window
END IF;
END IF;
END LOOP;
END LOOP;
proc_common_wait_some_cycles(tb_clk, 1);
-- Beamlet power of g_beamlet X and Y, same for both beamsets
FOR U IN 0 TO c_sdp_N_beamsets-1 LOOP
v_G := g_beamlet + U * c_sdp_S_sub_bf; -- global beamlet index, range(c_sdp_N_beamlets_sdp)
bst_x_arr(U) <= TO_UREAL(bsts_arr2(0)(v_G)); -- X pol beamlet
bst_y_arr(U) <= TO_UREAL(bsts_arr2(1)(v_G)); -- Y pol beamlet
END LOOP;
proc_common_wait_some_cycles(tb_clk, 1);
proc_common_wait_some_cycles(ext_clk, 100); -- delay for ease of view in Wave window
---------------------------------------------------------------------------
-- Log WG, subband and beamlet statistics
---------------------------------------------------------------------------
print_str("");
print_str("WG:");
print_str(". c_wg_ampl = " & int_to_str(c_wg_ampl));
print_str(". c_exp_sp_power = " & real_to_str(c_exp_sp_power, 20, 1));
print_str(". c_exp_sp_ast = " & real_to_str(c_exp_sp_ast, 20, 1));
print_str("");
print_str("Subband weight:");
print_str(". sp_subband_weight_gain = " & real_to_str(sp_subband_weight_gain, 20, 6));
print_str(". sp_subband_weight_phase = " & real_to_str(sp_subband_weight_phase, 20, 6));
print_str("");
print_str("SST results:");
print_str(". sst_weighted_subbands_flag = " & sl_to_str(sst_weighted_subbands_flag));
print_str("");
print_str(". c_exp_subband_ampl = " & int_to_str(NATURAL(c_exp_subband_ampl)));
print_str(". c_exp_subband_power = " & real_to_str(c_exp_subband_power, 20, 1));
print_str(". c_exp_subband_sst = " & real_to_str(c_exp_subband_sst, 20, 1));
print_str("");
print_str(". sp_sst = " & real_to_str(sp_sst, 20, 1));
print_str(". sp_sst / c_exp_subband_sst = " & real_to_str(sp_sst / c_exp_subband_sst, 20, 6));
print_str("");
print_str("BST results:");
print_str(". c_exp_beamlet_x_ampl = " & int_to_str(NATURAL(c_exp_beamlet_x_ampl)));
print_str(". c_exp_beamlet_x_power = " & real_to_str(c_exp_beamlet_x_power, 20, 1));
print_str(". c_exp_beamlet_x_bst = " & real_to_str(c_exp_beamlet_x_bst, 20, 1));
print_str("");
print_str(". c_exp_beamlet_y_ampl = " & int_to_str(NATURAL(c_exp_beamlet_y_ampl)));
print_str(". c_exp_beamlet_y_power = " & real_to_str(c_exp_beamlet_y_power, 20, 1));
print_str(". c_exp_beamlet_y_bst = " & real_to_str(c_exp_beamlet_y_bst, 20, 1));
print_str("");
FOR U IN 0 TO c_sdp_N_beamsets-1 LOOP
v_G := g_beamlet + U * c_sdp_S_sub_bf; -- global beamlet index, range(c_sdp_N_beamlets_sdp)
print_str(". bst_x_arr(" & INTEGER'IMAGE(v_G) & ") = " & real_to_str(bst_x_arr(U), 20, 1));
print_str(". bst_y_arr(" & INTEGER'IMAGE(v_G) & ") = " & real_to_str(bst_y_arr(U), 20, 1));
END LOOP;
FOR U IN 0 TO c_sdp_N_beamsets-1 LOOP
v_G := g_beamlet + U * c_sdp_S_sub_bf; -- global beamlet index, range(c_sdp_N_beamlets_sdp)
print_str(". bst_x_arr(" & INTEGER'IMAGE(v_G) & ") / c_exp_beamlet_x_bst = " & real_to_str(bst_x_arr(U) / c_exp_beamlet_x_bst, 20, 6));
print_str(". bst_y_arr(" & INTEGER'IMAGE(v_G) & ") / c_exp_beamlet_y_bst = " & real_to_str(bst_y_arr(U) / c_exp_beamlet_y_bst, 20, 6));
END LOOP;
print_str("");
print_str("Beamlet output:");
print_str(". rd_beamlet_scale = " & int_to_str(TO_UINT(rd_beamlet_scale)));
print_str(". c_exp_beamlet_scale = " & int_to_str(c_exp_beamlet_scale));
print_str("");
print_str(". c_exp_beamlet_x_output_ampl = " & int_to_str(NATURAL(c_exp_beamlet_x_output_ampl)));
print_str(". c_exp_beamlet_x_output_phase = " & int_to_str(INTEGER(c_exp_beamlet_x_output_phase)));
print_str(". c_exp_beamlet_x_output_re = " & int_to_str(INTEGER(c_exp_beamlet_x_output_re)));
print_str(". c_exp_beamlet_x_output_im = " & int_to_str(INTEGER(c_exp_beamlet_x_output_im)));
print_str("");
print_str(". c_exp_beamlet_y_output_ampl = " & int_to_str(NATURAL(c_exp_beamlet_y_output_ampl)));
print_str(". c_exp_beamlet_y_output_phase = " & int_to_str(INTEGER(c_exp_beamlet_y_output_phase)));
print_str(". c_exp_beamlet_y_output_re = " & int_to_str(INTEGER(c_exp_beamlet_y_output_re)));
print_str(". c_exp_beamlet_y_output_im = " & int_to_str(INTEGER(c_exp_beamlet_y_output_im)));
---------------------------------------------------------------------------
-- Verify SST
---------------------------------------------------------------------------
-- verify expected subband power based on WG power
ASSERT sp_sst > c_stat_lo_factor * c_exp_subband_sst REPORT "Wrong subband power for SP " & NATURAL'IMAGE(g_sp) SEVERITY ERROR;
ASSERT sp_sst < c_stat_hi_factor * c_exp_subband_sst REPORT "Wrong subband power for SP " & NATURAL'IMAGE(g_sp) SEVERITY ERROR;
---------------------------------------------------------------------------
-- Verify BST
---------------------------------------------------------------------------
-- verify expected beamlet power based on WG power and BF weigths
FOR U IN 0 TO c_sdp_N_beamsets-1 LOOP
-- X-pol
ASSERT bst_x_arr(U) < c_stat_hi_factor * c_exp_beamlet_x_bst REPORT "Wrong beamlet X power in beamset " & NATURAL'IMAGE(U) SEVERITY ERROR;
ASSERT bst_x_arr(U) > c_stat_lo_factor * c_exp_beamlet_x_bst REPORT "Wrong beamlet X power in beamset " & NATURAL'IMAGE(U) SEVERITY ERROR;
-- Y-pol
ASSERT bst_y_arr(U) > c_stat_lo_factor * c_exp_beamlet_y_bst REPORT "Wrong beamlet Y power in beamset " & NATURAL'IMAGE(U) SEVERITY ERROR;
ASSERT bst_y_arr(U) < c_stat_hi_factor * c_exp_beamlet_y_bst REPORT "Wrong beamlet Y power in beamset " & NATURAL'IMAGE(U) SEVERITY ERROR;
END LOOP;
---------------------------------------------------------------------------
-- Verify beamlet output in 10GbE UDP offload
---------------------------------------------------------------------------
-- X-pol
v_re := TO_SINT(rx_beamlet_list_re(c_exp_beamlet_x_index)); v_re_exp := c_exp_beamlet_x_output_re;
v_im := TO_SINT(rx_beamlet_list_im(c_exp_beamlet_x_index)); v_im_exp := c_exp_beamlet_x_output_im;
ASSERT v_re > INTEGER(v_re_exp) - c_beamlet_output_delta REPORT "Wrong beamlet X output (re) " & INTEGER'IMAGE(v_re) & " != " & REAL'IMAGE(v_re_exp) SEVERITY ERROR;
ASSERT v_re < INTEGER(v_re_exp) + c_beamlet_output_delta REPORT "Wrong beamlet X output (re) " & INTEGER'IMAGE(v_re) & " != " & REAL'IMAGE(v_re_exp) SEVERITY ERROR;
ASSERT v_im > INTEGER(v_im_exp) - c_beamlet_output_delta REPORT "Wrong beamlet X output (im) " & INTEGER'IMAGE(v_im) & " != " & REAL'IMAGE(v_im_exp) SEVERITY ERROR;
ASSERT v_im < INTEGER(v_im_exp) + c_beamlet_output_delta REPORT "Wrong beamlet X output (im) " & INTEGER'IMAGE(v_im) & " != " & REAL'IMAGE(v_im_exp) SEVERITY ERROR;
-- Y-pol
v_re := TO_SINT(rx_beamlet_list_re(c_exp_beamlet_y_index)); v_re_exp := c_exp_beamlet_y_output_re;
v_im := TO_SINT(rx_beamlet_list_im(c_exp_beamlet_y_index)); v_im_exp := c_exp_beamlet_y_output_im;
ASSERT v_re > INTEGER(v_re_exp) - c_beamlet_output_delta REPORT "Wrong beamlet Y output (re) " & INTEGER'IMAGE(v_re) & " != " & REAL'IMAGE(v_re_exp) SEVERITY ERROR;
ASSERT v_re < INTEGER(v_re_exp) + c_beamlet_output_delta REPORT "Wrong beamlet Y output (re) " & INTEGER'IMAGE(v_re) & " != " & REAL'IMAGE(v_re_exp) SEVERITY ERROR;
ASSERT v_im > INTEGER(v_im_exp) - c_beamlet_output_delta REPORT "Wrong beamlet Y output (im) " & INTEGER'IMAGE(v_im) & " != " & REAL'IMAGE(v_im_exp) SEVERITY ERROR;
ASSERT v_im < INTEGER(v_im_exp) + c_beamlet_output_delta REPORT "Wrong beamlet Y output (im) " & INTEGER'IMAGE(v_im) & " != " & REAL'IMAGE(v_im_exp) SEVERITY ERROR;
---------------------------------------------------------------------------
-- End Simulation
---------------------------------------------------------------------------
tb_almost_end <= '1';
proc_common_wait_some_cycles(ext_clk, 100); -- delay for ease of view in Wave window
proc_common_stop_simulation(TRUE, ext_clk, tb_almost_end, tb_end);
WAIT;
END PROCESS;
-----------------------------------------------------------------------------
-- Verify beamlet offload packet header
-----------------------------------------------------------------------------
-- Counters to time expected exp_sdp_cep_header fields per offload packet
p_test_counters : PROCESS(ext_clk)
BEGIN
IF rising_edge(ext_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;
-- Count sync intervals using in_sosi.sync, because there is no rx_beamlet_sosi.sync
in_sync_cnt <= in_sync_cnt + 1 WHEN rising_edge(ext_clk) AND in_sync = '1';
test_sync_cnt <= in_sync_cnt - 1; -- optionally adjust to fit rx_beamlet_sosi
-- Prepare exp_sdp_cep_header before rx_beamlet_sosi.eop, so that
-- p_exp_sdp_cep_header can verify it at rx_beamlet_sosi.eop.
p_exp_sdp_cep_header : PROCESS(exp_dp_bsn)
BEGIN
-- eth header
exp_sdp_cep_header.eth.dst_mac <= c_cep_eth_dst_mac;
exp_sdp_cep_header.eth.src_mac <= c_cep_eth_src_mac;
exp_sdp_cep_header.eth.eth_type <= x"0800";
-- ip header
exp_sdp_cep_header.ip.version <= TO_UVEC( 4, c_network_ip_version_w);
exp_sdp_cep_header.ip.header_length <= TO_UVEC( 5, c_network_ip_header_length_w);
exp_sdp_cep_header.ip.services <= TO_UVEC( 0, c_network_ip_services_w);
exp_sdp_cep_header.ip.total_length <= c_sdp_cep_ip_total_length; -- 7868, see ICD STAT-CEP
exp_sdp_cep_header.ip.identification <= TO_UVEC( 0, c_network_ip_identification_w);
exp_sdp_cep_header.ip.flags <= TO_UVEC( 2, c_network_ip_flags_w);
exp_sdp_cep_header.ip.fragment_offset <= TO_UVEC( 0, c_network_ip_fragment_offset_w);
exp_sdp_cep_header.ip.time_to_live <= TO_UVEC( 127, c_network_ip_time_to_live_w);
exp_sdp_cep_header.ip.protocol <= TO_UVEC( 17, c_network_ip_protocol_w);
exp_sdp_cep_header.ip.header_checksum <= TO_UVEC( c_exp_ip_header_checksum, c_network_ip_header_checksum_w);
exp_sdp_cep_header.ip.src_ip_addr <= c_cep_ip_src_addr; -- c_network_ip_addr_w
exp_sdp_cep_header.ip.dst_ip_addr <= c_cep_ip_dst_addr; -- c_network_ip_addr_w
-- udp header
exp_sdp_cep_header.udp.src_port <= c_cep_udp_src_port;
exp_sdp_cep_header.udp.dst_port <= c_cep_udp_dst_port;
exp_sdp_cep_header.udp.total_length <= c_sdp_cep_udp_total_length; -- 7848, see ICD STAT-CEP
exp_sdp_cep_header.udp.checksum <= TO_UVEC( 0, c_network_udp_checksum_w);
-- app header
exp_sdp_cep_header.app.sdp_marker <= TO_UVEC(c_sdp_marker_beamlets, 8); -- 98 = x"62" = 'b'
exp_sdp_cep_header.app.sdp_version_id <= TO_UVEC(c_sdp_cep_version_id, 8); -- 5
exp_sdp_cep_header.app.sdp_observation_id <= c_exp_sdp_info.observation_id;
exp_sdp_cep_header.app.sdp_station_id <= c_exp_sdp_info.station_id;
exp_sdp_cep_header.app.sdp_source_info_antenna_band_id <= slv(c_exp_sdp_info.antenna_band_index);
exp_sdp_cep_header.app.sdp_source_info_nyquist_zone_id <= c_exp_sdp_info.nyquist_zone_index;
exp_sdp_cep_header.app.sdp_source_info_f_adc <= slv(c_exp_sdp_info.f_adc);
exp_sdp_cep_header.app.sdp_source_info_fsub_type <= slv(c_exp_sdp_info.fsub_type);
exp_sdp_cep_header.app.sdp_source_info_payload_error <= TO_UVEC(0, 1);
exp_sdp_cep_header.app.sdp_source_info_repositioning_flag <= slv(c_exp_sdp_info.beam_repositioning_flag);
exp_sdp_cep_header.app.sdp_source_info_beamlet_width <= TO_UVEC(c_sdp_W_beamlet, 4);
exp_sdp_cep_header.app.sdp_source_info_gn_id <= TO_UVEC(c_gn_index, 5);
exp_sdp_cep_header.app.sdp_reserved <= TO_UVEC( 0, 40);
exp_sdp_cep_header.app.sdp_beamlet_scale <= TO_UVEC( c_exp_beamlet_scale, 16);
exp_sdp_cep_header.app.sdp_beamlet_index <= TO_UVEC( 0, 16); -- depends on bset
exp_sdp_cep_header.app.sdp_nof_blocks_per_packet <= TO_UVEC( c_sdp_cep_nof_blocks_per_packet, 8);
exp_sdp_cep_header.app.sdp_nof_beamlets_per_block <= TO_UVEC(c_sdp_cep_nof_beamlets_per_block, 16);
exp_sdp_cep_header.app.sdp_block_period <= c_exp_sdp_info.block_period;
exp_sdp_cep_header.app.dp_bsn <= TO_UVEC(exp_dp_bsn, 64); -- depends on bset and time
END PROCESS;
rx_sdp_cep_header <= func_sdp_map_cep_header(rx_hdr_fields_raw);
p_verify_cep_header : PROCESS
VARIABLE v_bool : BOOLEAN;
BEGIN
WAIT UNTIL rising_edge(ext_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
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;
END IF;
END IF;
-- Verify header at eop
-- . The expected beamlet_index 0 or S_sub_bf = 488 depends on beamset 0
-- or 1, but the order in which the packets arrive is undetermined.
-- Therefore accept any beamlet_index MOD c_sdp_S_sub_bf = 0 as correct
-- in func_sdp_verify_cep_header().
IF rx_beamlet_sosi.eop = '1' THEN
v_bool := func_sdp_verify_cep_header(rx_sdp_cep_header, exp_sdp_cep_header);
END IF;
END PROCESS;
-----------------------------------------------------------------------------
-- CEP Read Rx 10GbE Stream
-----------------------------------------------------------------------------
-- Show received beamlets from 10GbE stream in Wave Window
-- . The packet header is 9.25 longwords wide. The dp_offload_rx has stripped
-- the header and has realigned the payload at a longword boundary.
-- . expect c_nof_block_per_sync / c_sdp_cep_nof_blocks_per_packet *
-- c_sdp_N_beamsets = 16 / 4 * 2 = 4 * 2 = 8 packets per sync interval
-- . expect c_sdp_cep_nof_beamlets_per_block = c_sdp_S_sub_bf = 488 dual pol
-- and complex beamlets per packet, so 2 dual pol beamlets/64b data word.
-- . Beamlets array is stored big endian in the data, so X index 0 first in
-- MSByte of rx_beamlet_sosi.data.
p_rx_cep_beamlets : PROCESS
BEGIN
rx_beamlet_cnt <= 0;
rx_beamlet_valid <= '0';
-- Wait until start of a beamlet packet, capture only first block in packet
proc_common_wait_until_high(ext_clk, rx_beamlet_sosi.sop);
-- c_nof_beamlets_per_data = 2 dual pol beamlets (= XY, XY) per 64b data word
FOR I IN 0 TO (c_sdp_cep_nof_blocks_per_packet * c_sdp_cep_nof_beamlets_per_block / c_nof_beamlets_per_data)-1 LOOP
proc_common_wait_until_high(ext_clk, rx_beamlet_sosi.valid);
rx_beamlet_valid <= '1';
-- Capture rx beamlets per longword in rx_beamlet_arr, for time series view in Wave window
rx_beamlet_arr_re(0) <= rx_beamlet_sosi.data(55 DOWNTO 48); -- X
rx_beamlet_arr_im(0) <= rx_beamlet_sosi.data(63 DOWNTO 56);
rx_beamlet_arr_re(1) <= rx_beamlet_sosi.data(39 DOWNTO 32); -- Y
rx_beamlet_arr_im(1) <= rx_beamlet_sosi.data(47 DOWNTO 40);
rx_beamlet_arr_re(2) <= rx_beamlet_sosi.data(23 DOWNTO 16); -- X
rx_beamlet_arr_im(2) <= rx_beamlet_sosi.data(31 DOWNTO 24);
rx_beamlet_arr_re(3) <= rx_beamlet_sosi.data( 7 DOWNTO 0); -- Y
rx_beamlet_arr_im(3) <= rx_beamlet_sosi.data(15 DOWNTO 8);
IF I < c_sdp_cep_nof_beamlets_per_block / c_nof_beamlets_per_data THEN
-- Only capture the first beamlets block of each packet in rx_beamlet_list
rx_beamlet_list_re(I*4 + 0) <= rx_beamlet_sosi.data(55 DOWNTO 48); -- X
rx_beamlet_list_im(I*4 + 0) <= rx_beamlet_sosi.data(63 DOWNTO 56);
rx_beamlet_list_re(I*4 + 1) <= rx_beamlet_sosi.data(39 DOWNTO 32); -- Y
rx_beamlet_list_im(I*4 + 1) <= rx_beamlet_sosi.data(47 DOWNTO 40);
rx_beamlet_list_re(I*4 + 2) <= rx_beamlet_sosi.data(23 DOWNTO 16); -- X
rx_beamlet_list_im(I*4 + 2) <= rx_beamlet_sosi.data(31 DOWNTO 24);
rx_beamlet_list_re(I*4 + 3) <= rx_beamlet_sosi.data( 7 DOWNTO 0); -- Y
rx_beamlet_list_im(I*4 + 3) <= rx_beamlet_sosi.data(15 DOWNTO 8);
END IF;
proc_common_wait_until_high(ext_clk, rx_beamlet_sosi.valid);
-- Use at least one WAIT instead of proc_common_wait_some_cycles() to
-- avoid Modelsim warning: (vcom-1090) Possible infinite loop: Process
-- contains no WAIT statement.
WAIT UNTIL rising_edge(ext_clk);
rx_beamlet_valid <= '0';
rx_beamlet_cnt <= (rx_beamlet_cnt + c_nof_beamlets_per_data) MOD c_sdp_cep_nof_beamlets_per_block; -- 4 blocks/packet
END LOOP;
END PROCESS;
-- 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);
END tb;
......@@ -43,6 +43,7 @@ PACKAGE lofar2_unb2c_sdp_station_pkg IS
CONSTANT c_ait : t_lofar2_unb2c_sdp_station_config := (FALSE, FALSE, FALSE, FALSE, FALSE, 0);
CONSTANT c_fsub : t_lofar2_unb2c_sdp_station_config := (FALSE, TRUE, FALSE, FALSE, FALSE, 0);
CONSTANT c_bf : t_lofar2_unb2c_sdp_station_config := (FALSE, TRUE, TRUE, FALSE, FALSE, 0);
CONSTANT c_bf_ring : t_lofar2_unb2c_sdp_station_config := (FALSE, TRUE, TRUE, FALSE, TRUE, 0);
CONSTANT c_xsub_one : t_lofar2_unb2c_sdp_station_config := (FALSE, TRUE, FALSE, TRUE, FALSE, 1);
CONSTANT c_xsub_ring : t_lofar2_unb2c_sdp_station_config := (FALSE, TRUE, FALSE, TRUE, TRUE, 9);
CONSTANT c_full : t_lofar2_unb2c_sdp_station_config := (FALSE, TRUE, TRUE, TRUE, TRUE, 9);
......@@ -61,6 +62,7 @@ PACKAGE BODY lofar2_unb2c_sdp_station_pkg IS
IF g_design_name = "lofar2_unb2c_sdp_station_adc" THEN RETURN c_ait;
ELSIF g_design_name = "lofar2_unb2c_sdp_station_fsub" THEN RETURN c_fsub;
ELSIF g_design_name = "lofar2_unb2c_sdp_station_bf" THEN RETURN c_bf;
ELSIF g_design_name = "lofar2_unb2c_sdp_station_bf_ring" THEN RETURN c_bf_ring;
ELSIF g_design_name = "lofar2_unb2c_sdp_station_xsub_one" THEN RETURN c_xsub_one;
ELSIF g_design_name = "lofar2_unb2c_sdp_station_xsub_ring" THEN RETURN c_xsub_ring;
ELSE RETURN c_full;
......
......@@ -383,7 +383,8 @@ ARCHITECTURE str OF sdp_station IS
CONSTANT c_addr_w_reg_bsn_monitor_v2_rx_align_bf : NATURAL := ceil_log2(c_dual) + c_sdp_reg_bsn_monitor_v2_addr_w;
CONSTANT c_addr_w_reg_bsn_monitor_v2_ring_rx_bf : NATURAL := ceil_log2(c_sdp_N_pn_max) + c_sdp_reg_bsn_monitor_v2_addr_w;
CONSTANT c_addr_w_reg_bsn_monitor_v2_ring_tx_bf : NATURAL := ceil_log2(c_sdp_N_pn_max) + c_sdp_reg_bsn_monitor_v2_addr_w;
CONSTANT c_addr_w_reg_ring_lane_info_bf : NATURAL := 1;
-- Read only sdp_info values
CONSTANT c_f_adc : STD_LOGIC := '1'; -- '0' => 160M, '1' => 200M
CONSTANT c_fsub_type : STD_LOGIC := '0'; -- '0' => critical sampled PFB, '1' => oversampled PFB
......@@ -1172,7 +1173,7 @@ BEGIN
u_mem_mux_reg_ring_lane_info_bf : ENTITY common_lib.common_mem_mux
GENERIC MAP (
g_nof_mosi => c_sdp_N_beamsets,
g_mult_addr_w => c_sdp_reg_ring_lane_info_addr_w
g_mult_addr_w => c_addr_w_reg_ring_lane_info_bf
)
PORT MAP (
mosi => reg_ring_lane_info_bf_copi,
......
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