diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_tbuf_ring/tb_lofar2_unb2c_sdp_station_tbuf_ring.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_tbuf_ring/tb_lofar2_unb2c_sdp_station_tbuf_ring.vhd index 43237d9eac9bb89abaa23e5f12beffe81889c79c..f81e1df40a46955dae801868debc9ad840f282d1 100644 --- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_tbuf_ring/tb_lofar2_unb2c_sdp_station_tbuf_ring.vhd +++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_tbuf_ring/tb_lofar2_unb2c_sdp_station_tbuf_ring.vhd @@ -21,29 +21,30 @@ ------------------------------------------------------------------------------- -- -- Author: E. Kooistra --- Purpose: Self-checking testbench for lofar2_unb2c_sdp_station_tbuf_ring --- using WG data. --- +-- Purpose: Self-checking testbench for lofar2_unb2c_sdp_station_tbuf_ring using WG data. -- Description: --- MM control actions: +-- Record, freeze and dump TBuf [2] from multiple nodes in the ring [3]. Focus is on the ring. The TBuf functionality +-- itself is verified in tb_lofar2_unb2c_sdp_station_tbuf_one. +-- +-- E.g. for g_nof_rn = 4: +-- . the WG data is DC with level equal to RN +-- . ring lane in negative direction so from RN-3 to RN-0 via PCB connections and from RN-0 to RN-4 via cable +-- . dump output via 10GbE on last node RN-4 -- --- A) Set up WG and verify sp_power_sum as in tb_lofar2_unb2c_sdp_station_adc / bf.vhd --- . use DC level (= sp index) signal at the signal inputs, so all SP carry DC. --- B) Record, freeze and dump TBuf [2]: TODO --- . g_rs_block_size, g_ddr_buffer_size to verify recording beyond buffer full. --- . g_dump_page_offset, g_dump_nof_pages to verify dumping across begin and end of buffer --- . g_dump_enables to verify dumping one or more antenna inputs --- . g_dump_inter_packet_gap to vary dump rate. --- . log, verify: state, total counts +-- RN-3 --> PCB --> RN-2 --> PCB --> RN-1 --> PCB --> RN-0 --> cable --> RN-4 is last node +-- WG WG WG WG WG +-- DDR4 DDR4 DDR4 DDR4 DDR4 +-- 10GbE -- --- . g_ddr_buffer_size: --- Use Use g_ddr_buffer_size with e.g. 256 words to have smaller circular buffer independend of fixed --- c_tech_ddr4_sim_4k_64 with size 4096 words, to speed up simulation of wrap around of circular buffer full. +-- TODO: +-- . test parallel dump and serial dump +-- . read ring MP -- -- References: -- [1] https://support.astron.nl/confluence/pages/viewpage.action?spaceKey=L2M&title=L5+SDPFW+Design+Document%3A+Transient+buffer+raw+data -- [2] https://support.astron.nl/confluence/display/L2M/L2+STAT+Decision%3A+SC+-+SDP+OPC-UA+interface with dynamic -- behaviour recipe for record, freeze, dump +-- [3] https://support.astron.nl/confluence/display/L2M/L5+SDPFW+Design+Document%3A+Ring -- -- Usage: -- > as 12 # for detailed debugging @@ -88,6 +89,8 @@ entity tb_lofar2_unb2c_sdp_station_tbuf_ring is g_tb_end : boolean := true; -- when true then tb_end ends this simulation, else a higher -- multi-testbench will end the simulation g_tb_index : natural := 0; + g_first_gn : natural := 1; -- first global node (GN) in ring + g_nof_rn : natural := 2; -- nof ring nodes (RN) in ring g_ddr_buffer_size : natural := 256; -- <= 4096, because c_tech_ddr4_sim_4k_64 has 4k = 4096 words of -- c_sdp_tbuf_W_word = 512b g_rs_block_size : natural := 100; -- c_sdp_tbuf_rs_block_size = 2000, must be even see sdp_tbuf_output @@ -106,14 +109,21 @@ end tb_lofar2_unb2c_sdp_station_tbuf_ring; architecture tb of tb_lofar2_unb2c_sdp_station_tbuf_ring is constant c_sim : boolean := true; -- use true for sim_ddr, use false to simulate IP and external DDR4 - constant c_unb_nr : natural := 1; - constant c_node_nr : natural := 2; + constant c_first_unb_nr : natural := g_first_gn / c_quad; -- c_quad = 4 FPGAs per UniBoard2 + constant c_first_node_nr : natural := g_first_gn mod c_quad; -- first node_nr in range(c_quad) = [0:3] on + -- c_first_unb_nr + constant c_last_rn : natural := g_nof_rn - 1; -- first RN has index 0 by definition. + constant c_last_gn : natural := g_first_gn + c_last_rn; -- last global node (GN) in ring + constant c_last_unb_nr : natural := c_last_gn / c_quad; + constant c_last_node_nr : natural := c_last_gn mod c_quad; + constant c_first_sp : natural := g_first_gn * c_sdp_S_pn; + constant c_last_sp : natural := c_first_sp + g_nof_rn * c_sdp_S_pn - 1; + constant c_mmf_prefix_last : string := mmf_unb2_file_prefix(g_tb_index, c_last_unb_nr, c_last_node_nr); + constant c_tb_str : string := "TB-" & int_to_str(g_tb_index) & ": "; - constant c_mmf_prefix : string := mmf_unb2_file_prefix(g_tb_index, c_unb_nr, c_node_nr); constant c_Gbps : real := 10.0**9; constant c_design_name : string := "lofar2_unb2c_sdp_station_tbuf_ring"; - constant c_nof_dump : natural := 1; -- number of dumps, > 1 to repeat same dump constant c_gn_index : natural := c_unb_nr * 4 + c_node_nr; -- this node GN constant c_ai_offset : natural := c_gn_index * c_sdp_A_pn; @@ -217,9 +227,6 @@ architecture tb of tb_lofar2_unb2c_sdp_station_tbuf_ring is constant c_packed_empty_w : natural := 3; -- = ceil_log2(c_longword_sz - 1) constant c_rx_fifo_size : natural := g_rs_block_size; - -- DDR4 - constant c_exp_ddr_ctlr_nof_bytes_per_word : natural := c_sdp_tbuf_W_word / c_byte_w; - -- WG -- . Observe WG using rs_sosi.sop and rs_data_arr() in decimal format in Wave Window. constant c_bsn_start_wg : natural := c_init_bsn + 2; -- start WG at this BSN instead of some BSN, to avoid @@ -228,22 +235,20 @@ architecture tb of tb_lofar2_unb2c_sdp_station_tbuf_ring is -- MM constant c_addr_w_reg_diag_wg : natural := 2; constant c_mm_span_reg_diag_wg : natural := 2**c_addr_w_reg_diag_wg; - constant c_addr_w_reg_dp_xonoff : natural := 1; - constant c_mm_span_reg_dp_xonoff : natural := 2**c_addr_w_reg_dp_xonoff; - - constant c_mm_file_reg_bsn_source_v2 : string := c_mmf_prefix & "REG_BSN_SOURCE_V2"; - constant c_mm_file_reg_bsn_scheduler_wg : string := c_mmf_prefix & "REG_BSN_SCHEDULER"; - constant c_mm_file_reg_diag_wg : string := c_mmf_prefix & "REG_WG"; - constant c_mm_file_reg_sdp_info : string := c_mmf_prefix & "REG_SDP_INFO"; - constant c_mm_file_reg_io_ddr_mb_i : string := c_mmf_prefix & "REG_IO_DDR_MB_I"; - constant c_mm_file_reg_tbuf : string := c_mmf_prefix & "REG_TBUF"; - constant c_mm_file_reg_bsn_monitor_v2_tbuf : string := c_mmf_prefix & "REG_BSN_MONITOR_V2_TBUF"; - constant c_mm_file_reg_strobe_total_count_tbuf : string := c_mmf_prefix & "REG_STROBE_TOTAL_COUNT_TBUF"; - constant c_mm_file_reg_hdr_dat : string := c_mmf_prefix & "REG_HDR_DAT"; -- BF beamlets header - constant c_mm_file_reg_hdr_dat_tbuf : string := c_mmf_prefix & "REG_HDR_DAT_TBUF"; -- TBuf dump header - constant c_mm_file_reg_dp_xonoff : string := c_mmf_prefix & "REG_DP_XONOFF"; -- BF beamlet output enable - constant c_mm_file_reg_dp_xonoff_tbuf : string := c_mmf_prefix & "REG_DP_XONOFF_TBUF"; -- TBuf dump output enable - constant c_mm_file_reg_nw_10gbe_mac : string := c_mmf_prefix & "REG_NW_10GBE_MAC"; + + constant c_mm_file_reg_bsn_scheduler_wg : string := c_mmf_prefix_last & "REG_BSN_SCHEDULER"; + constant c_mm_file_reg_hdr_dat : string := c_mmf_prefix_last & "REG_HDR_DAT"; -- BF beamlets header + constant c_mm_file_reg_hdr_dat_tbuf : string := c_mmf_prefix_last & "REG_HDR_DAT_TBUF"; -- TBuf dump header + constant c_mm_file_reg_tbuf : string := c_mmf_prefix_last & "REG_TBUF"; + constant c_mm_file_reg_dp_xonoff_tbuf : string := c_mmf_prefix_last & "REG_DP_XONOFF_TBUF"; -- TBuf dump output + -- enable + -- Variable mmf_prefix dependent on gn, len('TB_0_UNB2_0_PN_0') = 16 + function mmf_prefix(gn : natural) return string is + constant c_unb2 : natural := gn / c_quad; + constant c_pn : natural := gn mod c_quad; + begin + return mmf_unb2_file_prefix(g_tb_index, c_unb2, c_pn); + end; signal wg_started : std_logic := '0'; signal rx_done : std_logic := '0'; @@ -272,14 +277,6 @@ architecture tb of tb_lofar2_unb2c_sdp_station_tbuf_ring is signal rd_cep_udp_src_port : std_logic_vector(15 downto 0); signal rd_cep_udp_dst_port : std_logic_vector(15 downto 0); - signal ddr_status : std_logic_vector(31 downto 0); - signal ddr_wr_fifo_used : natural; - signal ddr_rd_fifo_used : natural; - signal ddr_wr_fifo_full : std_logic; - signal ddr_rd_fifo_full : std_logic; - signal ddr_dvr_done : std_logic := '0'; - signal ddr_ctlr_nof_bytes_per_word : natural; - -- WG signal current_bsn_wg : std_logic_vector(c_dp_stream_bsn_w - 1 downto 0); @@ -292,7 +289,7 @@ architecture tb of tb_lofar2_unb2c_sdp_station_tbuf_ring is signal recording_nof_sop_per_sync : natural; signal dump_index : natural; signal time_index : natural; - signal read_busy : std_logic := '0'; + signal read_busy_arr : std_logic_vector(c_last_rn downto 0) := (others => '0'); signal dump_rate_bps : real := 0.0; signal dbg_c_exp_read_rate_bps : real := c_exp_read_rate_bps; @@ -331,7 +328,6 @@ architecture tb of tb_lofar2_unb2c_sdp_station_tbuf_ring is -- Dump packets data signal rx_dump_packet_cnt : natural := 0; - signal rx_stats_etherstatspkts : natural; signal rx_fifo_siso : t_dp_siso; signal rx_fifo_sosi : t_dp_sosi; signal rx_ant_sosi : t_dp_sosi := c_dp_sosi_rst; @@ -360,7 +356,13 @@ architecture tb of tb_lofar2_unb2c_sdp_station_tbuf_ring is signal eth_rxp : std_logic_vector(c_unb2c_board_nof_eth - 1 downto 0); signal SA_CLK : std_logic := '1'; - signal si_lpbk_0 : std_logic_vector(c_unb2c_board_tr_qsfp.bus_w - 1 downto 0); + signal i_QSFP_0_TX : t_unb2c_board_qsfp_bus_2arr(c_last_rn downto 0) := (others => (others => '0')); + signal i_QSFP_0_RX : t_unb2c_board_qsfp_bus_2arr(c_last_rn downto 0) := (others => (others => '0')); + signal i_RING_0_TX : t_unb2c_board_qsfp_bus_2arr(c_last_rn downto 0) := (others => (others => '0')); + signal i_RING_0_RX : t_unb2c_board_qsfp_bus_2arr(c_last_rn downto 0) := (others => (others => '0')); + signal i_RING_1_TX : t_unb2c_board_qsfp_bus_2arr(c_last_rn downto 0) := (others => (others => '0')); + signal i_RING_1_RX : t_unb2c_board_qsfp_bus_2arr(c_last_rn downto 0) := (others => (others => '0')); + signal i_QSFP_1_lpbk : t_unb2c_board_qsfp_bus_2arr(c_last_rn downto 0) := (others => (others => '0')); -- back transceivers signal JESD204B_SERIAL_DATA : std_logic_vector(c_sdp_S_pn - 1 downto 0); @@ -401,58 +403,82 @@ begin -- . Uses lofar2_unb2c_sdp_station instead of synthesis wrapper lofar2_unb2c_sdp_station_tbuf_ring, to be able to -- use the JESD204B signal names instead of the unb2c pin names and to have access to all generics. ------------------------------------------------------------------------------ - u_lofar_unb2c_sdp_station_tbuf_ring : entity lofar2_unb2c_sdp_station_lib.lofar2_unb2c_sdp_station - generic map ( - g_design_name => c_design_name, - g_design_note => "AIT + TBuf + Ring for dump from multiple nodes", - g_sim => c_sim, - g_sim_tb_index => g_tb_index, - g_sim_unb_nr => c_unb_nr, - g_sim_node_nr => c_node_nr, - g_sim_sdp_tbuf => c_sim_sdp_tbuf, - g_bsn_nof_clk_per_sync => c_bs_nof_clk_per_sync, - g_bs_block_size => c_bs_block_size - ) - port map ( - -- GENERAL - CLK => ext_clk, - PPS => ext_pps, - WDI => WDI, - INTA => INTA, - INTB => INTB, - - -- Others - VERSION => c_version, - ID => c_id, - 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 - QSFP_1_RX => si_lpbk_0, - QSFP_1_TX => si_lpbk_0, - - -- 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, - - -- DDR4 reference clock - MB_I_REF_CLK => MB_I_REF_CLK - -- DDR4 SO-DIMM Memory Bank I --> simulation use internal sim_ddr model in io_ddr - ); + gen_dut : for RN in 0 to c_last_rn generate + u_lofar_unb2c_sdp_station_tbuf_ring : entity lofar2_unb2c_sdp_station_lib.lofar2_unb2c_sdp_station + generic map ( + g_design_name => c_design_name, + g_design_note => "AIT + TBuf + Ring for dump from multiple nodes", + g_sim => c_sim, + g_sim_tb_index => g_tb_index, + g_sim_unb_nr => c_unb_nr, + g_sim_node_nr => c_node_nr, + g_sim_sdp_tbuf => c_sim_sdp_tbuf, + g_bsn_nof_clk_per_sync => c_bs_nof_clk_per_sync, + g_bs_block_size => c_bs_block_size + ) + port map ( + -- GENERAL + CLK => ext_clk, + PPS => ext_pps, + WDI => WDI, + INTA => INTA, + INTB => INTB, + + -- Others + VERSION => c_version, + ID => (TO_UVEC((g_first_gn + RN) / c_quad, c_unb2c_board_nof_uniboard_w) & + TO_UVEC((g_first_gn + 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, + + -- DDR4 reference clock + MB_I_REF_CLK => MB_I_REF_CLK + -- DDR4 SO-DIMM Memory Bank I --> simulation use internal sim_ddr model in io_ddr + ); + end generate; + + -- Ring connections + gen_ring : for RN in 0 to c_last_rn - 1 generate + -- Connect consecutive nodes in ring via their PCB RING interfaces + i_RING_0_RX(RN + 1) <= i_RING_1_TX(RN); + i_RING_1_RX(RN) <= i_RING_0_TX(RN + 1); + end generate; + + -- Connect first and last nodes in ring via their cable QSFP interface. + i_QSFP_0_RX(0) <= i_QSFP_0_TX(c_last_rn); + i_QSFP_0_RX(c_last_rn) <= i_QSFP_0_TX(0); ------------------------------------------------------------------------------ -- CEP model @@ -489,7 +515,7 @@ begin dp_rst => dest_rst, dp_clk => ext_clk, - serial_rx_arr(0) => si_lpbk_0(0), + serial_rx_arr(0) => i_QSFP_1_lpbk(c_last_rn)(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 @@ -580,11 +606,10 @@ begin -- MM slave accesses via file IO ------------------------------------------------------------------------------ p_mm_setup : process + variable v_gn : natural; variable v_offset : natural; - variable v_addr : natural; variable v_norm_ampl : real; variable v_bsn : natural; - variable v_sp_power_sum : real; begin -- Wait for DUT power up after reset wait for 200 ns; @@ -604,15 +629,18 @@ begin -- 0 block_period : STD_LOGIC_VECTOR(15 DOWNTO 0); -- END RECORD; -- . Write - mmf_mm_bus_wr(c_mm_file_reg_sdp_info, 8, TO_UINT(c_exp_sdp_info.antenna_field_index), tb_clk); - mmf_mm_bus_wr(c_mm_file_reg_sdp_info, 7, TO_UINT(c_exp_sdp_info.station_id), tb_clk); - mmf_mm_bus_wr(c_mm_file_reg_sdp_info, 6, TO_UINT(slv(c_exp_sdp_info.antenna_band_index)), tb_clk); - mmf_mm_bus_wr(c_mm_file_reg_sdp_info, 5, TO_UINT(c_exp_sdp_info.observation_id), tb_clk); - mmf_mm_bus_wr(c_mm_file_reg_sdp_info, 4, TO_UINT(c_exp_sdp_info.nyquist_zone_index), tb_clk); - mmf_mm_bus_wr(c_mm_file_reg_sdp_info, 1, TO_UINT(slv(c_exp_sdp_info.beam_repositioning_flag)), tb_clk); + for RN in 0 to c_last_rn loop + v_gn := g_first_gn + RN; + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_SDP_INFO", 8, TO_UINT(c_exp_sdp_info.antenna_field_index), tb_clk); + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_SDP_INFO", 7, TO_UINT(c_exp_sdp_info.station_id), tb_clk); + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_SDP_INFO", 6, TO_UINT(slv(c_exp_sdp_info.antenna_band_index)), tb_clk); + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_SDP_INFO", 5, TO_UINT(c_exp_sdp_info.observation_id), tb_clk); + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_SDP_INFO", 4, TO_UINT(c_exp_sdp_info.nyquist_zone_index), tb_clk); + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_SDP_INFO", 1, TO_UINT(slv(c_exp_sdp_info.beam_repositioning_flag)), tb_clk); + end loop; ---------------------------------------------------------------------------- - -- Set TBuf dump output MAC,IP,UDP port + -- Set TBuf dump output MAC,IP,UDP port on last node ---------------------------------------------------------------------------- -- TBuf dump header -- c_sdp_tbuf_hdr_field_arr : t_common_field_arr(c_sdp_tbuf_nof_hdr_fields - 1 downto 0) := ( @@ -714,39 +742,64 @@ begin report c_tb_str & "Wrong MM read rd_cep_udp_dst_port for dump" severity ERROR; - ---------------------------------------------------------------------------- - -- Read DDR4 memory status - ---------------------------------------------------------------------------- - mmf_mm_bus_rd(c_mm_file_reg_io_ddr_mb_i, 0, rd_data_setup, tb_clk); - ddr_status <= rd_data_setup; - proc_common_wait_some_cycles(tb_clk, 1); - - -- . verify dvr_done for calibration ok - ddr_dvr_done <= ddr_status(0); - proc_common_wait_some_cycles(tb_clk, 1); - assert ddr_dvr_done = '1' - report c_tb_str & "Wrong no DDR MB_I" - severity ERROR; - - -- . verify ddr_ctlr_nof_bytes_per_word - ddr_ctlr_nof_bytes_per_word <= TO_UINT(ddr_status(15 downto 8)); - proc_common_wait_some_cycles(tb_clk, 1); - assert ddr_ctlr_nof_bytes_per_word = c_exp_ddr_ctlr_nof_bytes_per_word - report c_tb_str & "Wrong read ddr_ctlr_nof_bytes_per_word" - severity ERROR; - ---------------------------------------------------------------------------- -- Enable BS ---------------------------------------------------------------------------- - mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 2, c_init_bsn, tb_clk); -- Init BSN - mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 3, 0, tb_clk); -- Write high part activates the init BSN - mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 1, c_bs_nof_clk_per_sync, tb_clk); - mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 0, 16#00000003#, tb_clk); -- Enable BS at PPS + for RN in 0 to c_last_rn loop + v_gn := g_first_gn + RN; + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_BSN_SOURCE_V2", 2, c_init_bsn, tb_clk); -- Init BSN + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_BSN_SOURCE_V2", 3, 0, tb_clk); -- Write high part activates the init BSN + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_BSN_SOURCE_V2", 1, c_bs_nof_clk_per_sync, tb_clk); + mmf_mm_bus_wr(mmf_prefix(v_gn) & "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 100 ns; pps_rst <= '0'; + ---------------------------------------------------------------------------- + -- Ring config + ---------------------------------------------------------------------------- + -- Write ring configuration to all nodes. + for RN in 0 to c_last_rn loop + v_gn := g_first_gn + RN; + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_RING_INFO", 2, g_nof_rn, tb_clk); -- N_rn + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_RING_INFO", 3, g_first_gn, tb_clk); -- O_rn + end loop; + + for RN in 0 to c_last_rn loop + v_gn := g_first_gn + RN; + if v_gn = g_first_gn then + -- Start node specific settings + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_RING_INFO", 0, 1, tb_clk); -- use_cable_to_previous_rn = 1 + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_RING_INFO", 1, 0, tb_clk); -- use_cable_to_next_rn = 0 + elsif v_gn = c_last_gn then + -- End node specific settings + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_RING_INFO", 0, 0, tb_clk); -- use_cable_to_previous_rn = 0 + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_RING_INFO", 1, 1, tb_clk); -- use_cable_to_next_rn = 1 + else + -- Use same settings for all nodes in between + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_RING_INFO", 0, 0, tb_clk); -- use_cable_to_previous_rn = 0 + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_RING_INFO", 1, 0, tb_clk); -- use_cable_to_next_rn = 0 + end if; + end loop; + + -- Access scheme 2 = End cast for TBuf dump. + -- Use transport_nof_hops = 0 on last node to stop remote input for first node. Use transport_nof_hops = g_nof_rn + -- on all other nodes, so that they pass on their remote rx packets. + for RN in 0 to c_last_rn loop + v_gn := g_first_gn + RN; + for I in 0 to c_nof_lanes - 1 loop + if RN = c_last_rn then + -- End RN, so set transport_nof_hops = 0. + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_RING_LANE_INFO_TBUF", I * 2 + 1, 0, tb_clk); + else + -- Set transport_nof_hops = g_nof_rn on all other nodes. + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_RING_LANE_INFO_TBUF", I * 2 + 1, g_nof_rn, tb_clk); + end if; + end loop; + end loop; + ---------------------------------------------------------------------------- -- Enable WG ---------------------------------------------------------------------------- @@ -756,14 +809,17 @@ begin -- 2 : freq[30:0] -- 3 : ampl[16:0] -- Put DC signal on all SP - for S in 0 to c_sdp_S_pn - 1 loop - v_offset := S * c_mm_span_reg_diag_wg; - -- use WG ampl = sp index, phase = 90 and freq = 0 to have DC level = sp index - v_norm_ampl := real(S) / real(c_sdp_FS_adc); - mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 0, 1024 * 2**16 + 1, tb_clk); -- nof_samples, mode calc - mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 1, integer(90.0 * c_diag_wg_phase_unit), tb_clk); - mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 2, 0, tb_clk); - mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 3, integer(v_norm_ampl * c_diag_wg_ampl_unit), tb_clk); + for RN in 0 to c_last_rn loop + v_gn := g_first_gn + RN; + for S in 0 to c_sdp_S_pn - 1 loop + v_offset := S * c_mm_span_reg_diag_wg; + -- use WG ampl = sp index, phase = 90 and freq = 0 to have DC level = sp index + v_norm_ampl := real(S) / real(c_sdp_FS_adc); + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_WG", v_offset + 0, 1024 * 2**16 + 1, tb_clk); -- nof_samples, mode calc + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_WG", v_offset + 1, integer(90.0 * c_diag_wg_phase_unit), tb_clk); + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_WG", v_offset + 2, 0, tb_clk); + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_WG", v_offset + 3, integer(v_norm_ampl * c_diag_wg_ampl_unit), tb_clk); + end loop; end loop; -- Read current BSN @@ -777,15 +833,19 @@ begin report c_tb_str & "Too late to start WG: " & int_to_str(v_bsn) & " > " & int_to_str(c_bsn_start_wg) severity ERROR; v_bsn := c_bsn_start_wg; - mmf_mm_bus_wr(c_mm_file_reg_bsn_scheduler_wg, 0, v_bsn, tb_clk); -- first write low then high part - mmf_mm_bus_wr(c_mm_file_reg_bsn_scheduler_wg, 1, 0, tb_clk); -- assume v_bsn < 2**31-1 + for RN in 0 to c_last_rn loop + v_gn := g_first_gn + RN; + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_BSN_SCHEDULER", 0, v_bsn, tb_clk); -- first write low then high part + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_BSN_SCHEDULER", 1, 0, tb_clk); -- assume v_bsn < 2**31-1 + end loop; ---------------------------------------------------------------------------- -- Wait until WG has started ---------------------------------------------------------------------------- + -- read BSN low part, this is the wait until condition mmf_mm_wait_until_value( - c_mm_file_reg_bsn_scheduler_wg, 0, -- read BSN low part - "UNSIGNED", rd_data_bsn, ">=", c_bsn_start_wg, -- this is the wait until condition + c_mm_file_reg_bsn_scheduler_wg, 0, + "UNSIGNED", rd_data_bsn, ">=", c_bsn_start_wg, c_T_bs_period, ext_clk); -- WG started @@ -805,6 +865,8 @@ begin end process; p_mm_tbuf_control : process + variable v_gn : natural; + variable v_rn_str : string(1 to 6); variable v_bool : boolean; variable v_offset : natural; variable v_recorded_nof_pages : natural; @@ -826,124 +888,59 @@ begin -- Wait for DUT power up after reset wait for 200 ns; - --v_bool := func_sdp_tbuf_print_state(c_tb_str, to_uvec(461603339, 32)); - --v_bool := func_sdp_tbuf_print_state(c_tb_str, to_uvec(461602827, 32)); - --v_bool := func_sdp_tbuf_print_state(c_tb_str, to_uvec(515, 32)); - --v_bool := func_sdp_tbuf_print_state(c_tb_str, to_uvec(741, 32)); - --v_bool := func_sdp_tbuf_print_state(c_tb_str, to_uvec(3, 32)); ---------------------------------------------------------------------------- - -- Record all antennas - ---------------------------------------------------------------------------- - mmf_mm_bus_wr(c_mm_file_reg_tbuf, 2, to_int(tbuf_registers_wr.record_all), tb_clk); - - ---------------------------------------------------------------------------- - -- Enable packet dump output + -- Enable packet dump output only on last node ---------------------------------------------------------------------------- mmf_mm_bus_wr(c_mm_file_reg_dp_xonoff_tbuf, 0, 1, tb_clk); mmf_mm_bus_wr(c_mm_file_reg_tbuf, 11, tbuf_registers_wr.dump_inter_packet_gap, tb_clk); - ---------------------------------------------------------------------------- - -- Report and verify sizes - ---------------------------------------------------------------------------- - mmf_mm_bus_rd(c_mm_file_reg_tbuf, 0, rd_data_control, tb_clk); - tbuf_registers_ro.nof_samples_per_block <= to_uint(rd_data_control); - mmf_mm_bus_rd(c_mm_file_reg_tbuf, 1, rd_data_control, tb_clk); - tbuf_registers_ro.nof_pages_in_buffer <= to_uint(rd_data_control); - proc_common_wait_some_cycles(tb_clk, 1); - assert tbuf_registers_ro.nof_samples_per_block = g_rs_block_size - report c_tb_str & "Wrong tbuf_registers_ro.nof_samples_per_block " - severity ERROR; - assert tbuf_registers_ro.nof_pages_in_buffer = c_nof_pages_in_buffer - report c_tb_str & "Wrong tbuf_registers_ro.nof_pages_in_buffer " - severity ERROR; - print_str(c_tb_str & "tbuf_registers_ro.nof_samples_per_block = " & - int_to_str(tbuf_registers_ro.nof_samples_per_block)); - print_str(c_tb_str & "tbuf_registers_ro.nof_pages_in_buffer = " & - int_to_str(tbuf_registers_ro.nof_pages_in_buffer)); - ---------------------------------------------------------------------------- -- RECORD ---------------------------------------------------------------------------- print_str(c_tb_str & "--------------------------------------------"); print_str(c_tb_str & "-- RECORD"); print_str(c_tb_str & "--------------------------------------------"); - -- Enable recording - proc_common_wait_until_high(ext_clk, wg_started); - mmf_mm_bus_wr(c_mm_file_reg_tbuf, 3, to_int(tbuf_registers_wr.record_enable), tb_clk); - proc_common_wait_cross_clock_domain_latency( - c_mm_clk_period, c_ext_clk_period, c_common_cross_clock_domain_latency * 2); - -- Read back record_enable - mmf_mm_bus_rd(c_mm_file_reg_tbuf, 3, rd_data_control, tb_clk); - tbuf_registers_rd.record_enable <= rd_data_control(0); - -- Read record_busy, wait one rs_block for record_enable to take effect - proc_common_wait_some_cycles(ext_clk, g_rs_block_size); - mmf_mm_bus_rd(c_mm_file_reg_tbuf, 18, rd_data_record_busy, tb_clk); - tbuf_registers_ro.record_busy <= rd_data_record_busy(0); - proc_common_wait_some_cycles(tb_clk, 1); - assert tbuf_registers_rd.record_enable = '1' - report c_tb_str & "Wrong tbuf_registers_rd.record_enable /= '1'" - severity ERROR; - assert tbuf_registers_ro.record_busy = '1' - report c_tb_str & "Wrong tbuf_registers_ro.record_busy /= '1'" - severity ERROR; - print_str(c_tb_str & "tbuf_registers_rd.record_enable = " & sl_to_str(tbuf_registers_rd.record_enable)); - print_str(c_tb_str & "tbuf_registers_ro.record_busy = " & sl_to_str(tbuf_registers_ro.record_busy)); - -- Read TBuf state - mmf_mm_bus_rd(c_mm_file_reg_tbuf, 19, rd_data_state, tb_clk); - proc_common_wait_some_cycles(tb_clk, 1); - v_bool := func_sdp_tbuf_print_state(c_tb_str, rd_data_state); + -- Wait until there is WG data to record + proc_common_wait_until_high(ext_clk, wg_started); + for RN in 0 to c_last_rn loop + v_gn := g_first_gn + RN; + -- Record all antennas on all nodes + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_TBUF", 2, to_int(tbuf_registers_wr.record_all), tb_clk); + -- Enable recording on all nodes + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_TBUF", 3, to_int(tbuf_registers_wr.record_enable), tb_clk); + end loop; -- Recording proc_common_wait_some_cycles(ext_clk, g_rs_block_size * g_rs_record_nof_block); - -- Read BSN monitor for recording data - mmf_mm_bus_rd(c_mm_file_reg_bsn_monitor_v2_tbuf, 1, rd_data_monitor, tb_clk); -- bsn at sync - recording_rsn_at_sync <= to_uint(rd_data_monitor); - mmf_mm_bus_rd(c_mm_file_reg_bsn_monitor_v2_tbuf, 3, rd_data_monitor, tb_clk); -- nof_sop - recording_nof_sop_per_sync <= to_uint(rd_data_monitor); - proc_common_wait_some_cycles(tb_clk, 1); - assert recording_nof_sop_per_sync = c_rs_nof_block_per_sync - report c_tb_str & "Wrong RSN monitor nof blocks per sync" - severity ERROR; - print_str(c_tb_str & "recording_rsn_at_sync = " & int_to_str(recording_rsn_at_sync)); - print_str(c_tb_str & "recording_nof_sop_per_sync = " & int_to_str(recording_nof_sop_per_sync)); - ---------------------------------------------------------------------------- -- FREEZE ---------------------------------------------------------------------------- print_str(c_tb_str & "--------------------------------------------"); print_str(c_tb_str & "-- FREEZE "); print_str(c_tb_str & "--------------------------------------------"); - -- Disable recording + + -- Disable recording on all nodes tbuf_registers_wr.record_enable <= '0'; proc_common_wait_some_cycles(tb_clk, 1); - mmf_mm_bus_wr(c_mm_file_reg_tbuf, 3, to_int(tbuf_registers_wr.record_enable), tb_clk); - proc_common_wait_cross_clock_domain_latency( - c_mm_clk_period, c_ext_clk_period, c_common_cross_clock_domain_latency * 2); - -- Read disabled recording - mmf_mm_bus_rd(c_mm_file_reg_tbuf, 3, rd_data_control, tb_clk); - tbuf_registers_rd.record_enable <= rd_data_control(0); - proc_common_wait_some_cycles(tb_clk, 1); - assert tbuf_registers_rd.record_enable = '0' - report c_tb_str & "Wrong tbuf_registers_rd.record_enable /= '0'" - severity ERROR; + for RN in 0 to c_last_rn loop + v_gn := g_first_gn + RN; + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_TBUF", 3, to_int(tbuf_registers_wr.record_enable), tb_clk); + end loop; + -- Wait until recording has finished, read record_busy to account for latency in record_enable disabled mmf_mm_wait_until_value( - c_mm_file_reg_tbuf, 18, -- read record_busy + c_mm_file_reg_tbuf, 18, -- read record_busy on last node "UNSIGNED", rd_data_record_busy, "=", 0, -- this is the wait until condition c_T_rd_interval, ext_clk); - tbuf_registers_ro.record_busy <= rd_data_record_busy(0); - proc_common_wait_some_cycles(tb_clk, 1); - print_str(c_tb_str & "tbuf_registers_rd.record_enable = " & sl_to_str(tbuf_registers_rd.record_enable)); - print_str(c_tb_str & "tbuf_registers_ro.record_busy = " & sl_to_str(tbuf_registers_ro.record_busy)); - -- Read number of recorded pages + -- Read number of recorded pages on last node mmf_mm_bus_rd(c_mm_file_reg_tbuf, 4, rd_data_control, tb_clk); tbuf_registers_ro.recorded_nof_pages <= to_uint(rd_data_control); - -- Read indices of first and last recorded page + -- Read indices of first and last recorded page on last node mmf_mm_bus_rd(c_mm_file_reg_tbuf, 5, rd_data_control, tb_clk); tbuf_registers_ro.recorded_first_page <= to_uint(rd_data_control); mmf_mm_bus_rd(c_mm_file_reg_tbuf, 6, rd_data_control, tb_clk); @@ -962,7 +959,7 @@ begin "Wrong tbuf_registers_ro.recorded_nof_pages does not match recorded_first_page and recorded_last_page" severity ERROR; - -- Read timestamps of first and last recorded page + -- Read timestamps of first and last recorded page on last node mmf_mm_bus_rd(c_mm_file_reg_tbuf, 7, rd_data_control, tb_clk); -- read low part tbuf_registers_ro.recorded_first_rsn(31 downto 0) <= rd_data_control; mmf_mm_bus_rd(c_mm_file_reg_tbuf, 8, rd_data_control, tb_clk); -- read high part @@ -1003,70 +1000,70 @@ begin ---------------------------------------------------------------------------- -- DUMP ---------------------------------------------------------------------------- + print_str(c_tb_str & "--------------------------------------------"); + print_str(c_tb_str & "-- DUMP"); + print_str(c_tb_str & "--------------------------------------------"); + -- Wait until nw_10GbE xon = '1' while NOW < 11 us loop wait for 100 ns; end loop; - for DUMP in 0 to c_nof_dump - 1 loop - tb_dump_cnt <= tb_dump_cnt + 1; - proc_common_wait_some_cycles(tb_clk, 1); - print_str(c_tb_str & "--------------------------------------------"); - print_str(c_tb_str & "-- DUMP : " & int_to_str(tb_dump_cnt)); - print_str(c_tb_str & "--------------------------------------------"); + -- Clear dump strobe_total_counts + for RN in 0 to c_last_rn loop + v_gn := g_first_gn + RN; + mmf_mm_bus_wr(mmf_prefix(v_gn) & + "REG_STROBE_TOTAL_COUNT_TBUF", c_sdp_tbuf_nof_strobe_total_counts_clear_id, 1, tb_clk); + end loop; + proc_common_wait_cross_clock_domain_latency( + c_mm_clk_period, c_ext_clk_period, c_common_cross_clock_domain_latency * 2); - -- Clear dump strobe_total_counts - mmf_mm_bus_wr(c_mm_file_reg_strobe_total_count_tbuf, c_sdp_tbuf_nof_strobe_total_counts_clear_id, 1, tb_clk); - proc_common_wait_cross_clock_domain_latency( - c_mm_clk_period, c_ext_clk_period, c_common_cross_clock_domain_latency * 2); + -- Set dump interval + v_dump_start_page := tbuf_registers_ro.recorded_first_page + g_dump_page_offset; + if v_dump_start_page >= c_nof_pages_in_buffer then + -- Wrap from begin of buffer when v_dump_start_page is just beyond the end of buffer. Do not use modulo + -- c_nof_pages_in_buffer to be able to simulate effect of a much too large v_dump_start_page due to + -- g_dump_page_offset >= c_nof_pages_in_buffer + v_dump_start_page := v_dump_start_page - c_nof_pages_in_buffer; + end if; + tbuf_registers_wr.dump_start_page <= v_dump_start_page; + v_dump_start_rsn := incr_uvec(tbuf_registers_ro.recorded_first_rsn, g_dump_page_offset * g_rs_block_size); + tbuf_registers_wr.dump_start_rsn <= v_dump_start_rsn; + tbuf_registers_wr.dump_enables <= g_dump_enables; + proc_common_wait_some_cycles(tb_clk, 1); - -- Set dump interval and antenna inputs - v_dump_start_page := tbuf_registers_ro.recorded_first_page + g_dump_page_offset; - if v_dump_start_page >= c_nof_pages_in_buffer then - -- Wrap from begin of buffer when v_dump_start_page is just beyond the end of buffer. Do not use modulo - -- c_nof_pages_in_buffer to be able to simulate effect of a much too large v_dump_start_page due to - -- g_dump_page_offset >= c_nof_pages_in_buffer - v_dump_start_page := v_dump_start_page - c_nof_pages_in_buffer; - end if; - tbuf_registers_wr.dump_start_page <= v_dump_start_page; - v_dump_start_rsn := incr_uvec(tbuf_registers_ro.recorded_first_rsn, g_dump_page_offset * g_rs_block_size); - tbuf_registers_wr.dump_start_rsn <= v_dump_start_rsn; - tbuf_registers_wr.dump_enables <= g_dump_enables; - proc_common_wait_some_cycles(tb_clk, 1); - mmf_mm_bus_wr(c_mm_file_reg_tbuf, 12, tbuf_registers_wr.dump_start_page, tb_clk); - mmf_mm_bus_wr(c_mm_file_reg_tbuf, 13, tbuf_registers_wr.dump_nof_pages, tb_clk); - mmf_mm_bus_wr(c_mm_file_reg_tbuf, 14, to_uint(tbuf_registers_wr.dump_start_rsn), tb_clk); - mmf_mm_bus_wr(c_mm_file_reg_tbuf, 16, to_uint(tbuf_registers_wr.dump_enables), tb_clk); - proc_common_wait_cross_clock_domain_latency( - c_mm_clk_period, c_ext_clk_period, c_common_cross_clock_domain_latency * 2); + for RN in 0 to c_last_rn loop + v_gn := g_first_gn + RN; + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_TBUF", 12, tbuf_registers_wr.dump_start_page, tb_clk); + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_TBUF", 13, tbuf_registers_wr.dump_nof_pages, tb_clk); + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_TBUF", 14, to_uint(tbuf_registers_wr.dump_start_rsn), tb_clk); + end loop; + proc_common_wait_cross_clock_domain_latency( + c_mm_clk_period, c_ext_clk_period, c_common_cross_clock_domain_latency * 2); + + -- Enable dump for antenna inputs + if g_dump_nof_pages > 0 then + for RN in 0 to c_last_rn loop + v_gn := g_first_gn + RN; + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_TBUF", 16, to_uint(tbuf_registers_wr.dump_enables), tb_clk); - if g_dump_nof_pages > 0 then -- Time dump begin - read_busy <= '1'; + read_busy_arr(RN) <= '1'; v_Begin := NOW / c_1ns; proc_common_wait_some_cycles(tb_clk, 1); - -- Read back enabled dump - mmf_mm_bus_rd(c_mm_file_reg_tbuf, 16, rd_data_control, tb_clk); - tbuf_registers_rd.dump_enables <= rd_data_control(c_sdp_A_pn - 1 downto 0); - proc_common_wait_some_cycles(tb_clk, 1); - assert to_uint(tbuf_registers_rd.dump_enables) = to_uint(tbuf_registers_wr.dump_enables) - report c_tb_str & "Wrong tbuf_registers_rd.dump_enables enabled" - severity ERROR; - print_str(c_tb_str & "tbuf_registers_rd.dump_enables = " & slv_to_str(tbuf_registers_rd.dump_enables)); - ---------------------------------------------------------------------------- -- Wait until dump is done ---------------------------------------------------------------------------- mmf_mm_wait_until_value( - c_mm_file_reg_tbuf, 17, -- read dump_done + mmf_prefix(v_gn) & "REG_TBUF", 17, -- read dump_done for this RN "UNSIGNED", rd_data_dump_done, "=", 1, -- this is the wait until condition c_T_rd_interval, ext_clk); tbuf_registers_ro.dump_done <= rd_data_dump_done(0); proc_common_wait_some_cycles(tb_clk, 1); -- Time dump end - read_busy <= '0'; + read_busy_arr(RN) <= '0'; v_End := NOW / c_1ns; v_Period := real(v_End - v_Begin) * 1.0e-9; -- dump time in s v_dump_rate_bps := real(c_dump_total_nof_packets * c_sdp_W_ant * g_rs_block_size) / v_Period; @@ -1081,100 +1078,91 @@ begin end if; print_str(c_tb_str & "Dump rate = " & real_to_str(v_dump_rate_bps / c_Gbps, 4, 2) & " Gbps" & " (Expected " & real_to_str(c_exp_dump_rate_bps / c_Gbps, 4, 2) & " Gbps)"); - end if; + end loop; + end if; - -- Wait some time for latency in sdp_tbuf_output and 10GbE Tx - Rx network - proc_common_wait_some_cycles(ext_clk, g_rs_block_size * 4); - rx_done <= '1'; + -- Wait some time for latency in sdp_tbuf_output and 10GbE Tx - Rx network + proc_common_wait_some_cycles(ext_clk, g_rs_block_size * 4); + rx_done <= '1'; + for RN in 0 to c_last_rn loop + v_gn := g_first_gn + RN; + v_rn_str := "RN-" & int_to_str(RN) & ": "; -- Read strobe_total_counts - mmf_mm_bus_rd(c_mm_file_reg_strobe_total_count_tbuf, 0, rd_data_strobe, tb_clk); + mmf_mm_bus_rd(mmf_prefix(v_gn) & "REG_STROBE_TOTAL_COUNT_TBUF", 0, rd_data_strobe, tb_clk); tbuf_strobe_total_counts.memory_read_nof_packets <= to_uint(rd_data_strobe); - mmf_mm_bus_rd(c_mm_file_reg_strobe_total_count_tbuf, 2, rd_data_strobe, tb_clk); + mmf_mm_bus_rd(mmf_prefix(v_gn) & "REG_STROBE_TOTAL_COUNT_TBUF", 2, rd_data_strobe, tb_clk); tbuf_strobe_total_counts.memory_read_nof_crc_errors <= to_uint(rd_data_strobe); - mmf_mm_bus_rd(c_mm_file_reg_strobe_total_count_tbuf, 4, rd_data_strobe, tb_clk); + mmf_mm_bus_rd(mmf_prefix(v_gn) & "REG_STROBE_TOTAL_COUNT_TBUF", 4, rd_data_strobe, tb_clk); tbuf_strobe_total_counts.memory_read_nof_rsn_errors <= to_uint(rd_data_strobe); - mmf_mm_bus_rd(c_mm_file_reg_strobe_total_count_tbuf, 6, rd_data_strobe, tb_clk); + mmf_mm_bus_rd(mmf_prefix(v_gn) & "REG_STROBE_TOTAL_COUNT_TBUF", 6, rd_data_strobe, tb_clk); tbuf_strobe_total_counts.memory_read_dumped_nof_packets <= to_uint(rd_data_strobe); - mmf_mm_bus_rd(c_mm_file_reg_strobe_total_count_tbuf, 8, rd_data_strobe, tb_clk); + mmf_mm_bus_rd(mmf_prefix(v_gn) & "REG_STROBE_TOTAL_COUNT_TBUF", 8, rd_data_strobe, tb_clk); tbuf_strobe_total_counts.memory_ring_rx_nof_packets <= to_uint(rd_data_strobe); - mmf_mm_bus_rd(c_mm_file_reg_strobe_total_count_tbuf, 10, rd_data_strobe, tb_clk); + mmf_mm_bus_rd(mmf_prefix(v_gn) & "REG_STROBE_TOTAL_COUNT_TBUF", 10, rd_data_strobe, tb_clk); tbuf_strobe_total_counts.memory_ring_tx_nof_packets <= to_uint(rd_data_strobe); - mmf_mm_bus_rd(c_mm_file_reg_strobe_total_count_tbuf, 12, rd_data_strobe, tb_clk); + mmf_mm_bus_rd(mmf_prefix(v_gn) & "REG_STROBE_TOTAL_COUNT_TBUF", 12, rd_data_strobe, tb_clk); tbuf_strobe_total_counts.memory_output_nof_packets <= to_uint(rd_data_strobe); proc_common_wait_some_cycles(tb_clk, 1); assert tbuf_strobe_total_counts.memory_read_nof_packets = c_read_total_nof_packets - report c_tb_str & "Wrong tbuf_strobe_total_counts.memory_read_nof_packets" + report c_tb_str & v_rn_str & "Wrong tbuf_strobe_total_counts.memory_read_nof_packets" severity ERROR; assert tbuf_strobe_total_counts.memory_read_nof_crc_errors = c_read_nof_crc_errors - report c_tb_str & "Wrong tbuf_strobe_total_counts.memory_read_nof_crc_errors" + report c_tb_str & v_rn_str & "Wrong tbuf_strobe_total_counts.memory_read_nof_crc_errors" severity ERROR; assert tbuf_strobe_total_counts.memory_read_nof_rsn_errors = c_read_nof_rsn_errors - report c_tb_str & "Wrong tbuf_strobe_total_counts.memory_read_nof_rsn_errors" + report c_tb_str & v_rn_str & "Wrong tbuf_strobe_total_counts.memory_read_nof_rsn_errors" severity ERROR; assert tbuf_strobe_total_counts.memory_read_dumped_nof_packets = c_dump_total_nof_packets - report c_tb_str & "Wrong tbuf_strobe_total_counts.memory_read_dumped_nof_packets" + report c_tb_str & v_rn_str & "Wrong tbuf_strobe_total_counts.memory_read_dumped_nof_packets" severity ERROR; assert tbuf_strobe_total_counts.memory_ring_rx_nof_packets = 0 - report c_tb_str & "Wrong tbuf_strobe_total_counts.memory_ring_rx_nof_packets" + report c_tb_str & v_rn_str & "Wrong tbuf_strobe_total_counts.memory_ring_rx_nof_packets" severity ERROR; assert tbuf_strobe_total_counts.memory_ring_tx_nof_packets = c_dump_total_nof_packets - report c_tb_str & "Wrong tbuf_strobe_total_counts.memory_ring_tx_nof_packets" + report c_tb_str & v_rn_str & "Wrong tbuf_strobe_total_counts.memory_ring_tx_nof_packets" severity ERROR; assert tbuf_strobe_total_counts.memory_output_nof_packets = c_dump_total_nof_packets - report c_tb_str & "Wrong tbuf_strobe_total_counts.memory_output_nof_packets" + report c_tb_str & v_rn_str & "Wrong tbuf_strobe_total_counts.memory_output_nof_packets" severity ERROR; - print_str(c_tb_str & "tbuf_strobe_total_counts.memory_read_nof_packets = " & + print_str(c_tb_str & v_rn_str & "tbuf_strobe_total_counts.memory_read_nof_packets = " & int_to_str(tbuf_strobe_total_counts.memory_read_nof_packets)); - print_str(c_tb_str & "tbuf_strobe_total_counts.memory_read_nof_crc_errors = " & + print_str(c_tb_str & v_rn_str & "tbuf_strobe_total_counts.memory_read_nof_crc_errors = " & int_to_str(tbuf_strobe_total_counts.memory_read_nof_crc_errors)); - print_str(c_tb_str & "tbuf_strobe_total_counts.memory_read_nof_rsn_errors = " & + print_str(c_tb_str & v_rn_str & "tbuf_strobe_total_counts.memory_read_nof_rsn_errors = " & int_to_str(tbuf_strobe_total_counts.memory_read_nof_rsn_errors)); - print_str(c_tb_str & "tbuf_strobe_total_counts.memory_read_dumped_nof_packets = " & + print_str(c_tb_str & v_rn_str & "tbuf_strobe_total_counts.memory_read_dumped_nof_packets = " & int_to_str(tbuf_strobe_total_counts.memory_read_dumped_nof_packets)); - print_str(c_tb_str & "tbuf_strobe_total_counts.memory_ring_rx_nof_packets = " & + print_str(c_tb_str & v_rn_str & "tbuf_strobe_total_counts.memory_ring_rx_nof_packets = " & int_to_str(tbuf_strobe_total_counts.memory_ring_rx_nof_packets)); - print_str(c_tb_str & "tbuf_strobe_total_counts.memory_ring_tx_nof_packets = " & + print_str(c_tb_str & v_rn_str & "tbuf_strobe_total_counts.memory_ring_tx_nof_packets = " & int_to_str(tbuf_strobe_total_counts.memory_ring_tx_nof_packets)); - print_str(c_tb_str & "tbuf_strobe_total_counts.memory_output_nof_packets = " & + print_str(c_tb_str & v_rn_str & "tbuf_strobe_total_counts.memory_output_nof_packets = " & int_to_str(tbuf_strobe_total_counts.memory_output_nof_packets)); - -- Read REG_NW_10GBE_MAC counts - -- . In sim via si_lpbk_0 loopback on own port, on HW using another node on unb2c as dump destination - -- . Only need to read low word part of rx_stats_etherstatspkts[35:0] - -- . Expect at least tbuf_strobe_total_counts.memory_output_nof_packets, there can be more when the nw_10gbe - -- does an ARP. - mmf_mm_bus_rd(c_mm_file_reg_nw_10gbe_mac, 16#C1C#, rd_data_nw_10gbe_mac, tb_clk); - rx_stats_etherstatspkts <= TO_UINT(rd_data_nw_10gbe_mac); - proc_common_wait_some_cycles(tb_clk, 1); - assert rx_stats_etherstatspkts >= tbuf_strobe_total_counts.memory_output_nof_packets - report c_tb_str & "Wrong rx_stats_etherstatspkts" - severity ERROR; - print_str(c_tb_str & "rx_stats_etherstatspkts = " & int_to_str(rx_stats_etherstatspkts)); - -- Disable dump proc_common_wait_some_cycles(ext_clk, 100); -- delay for ease of view in Wave window tbuf_registers_wr.dump_enables <= (others => '0'); proc_common_wait_some_cycles(tb_clk, 1); - mmf_mm_bus_wr(c_mm_file_reg_tbuf, 16, to_uint(tbuf_registers_wr.dump_enables), tb_clk); + mmf_mm_bus_wr(mmf_prefix(v_gn) & "REG_TBUF", 16, to_uint(tbuf_registers_wr.dump_enables), tb_clk); proc_common_wait_cross_clock_domain_latency( c_mm_clk_period, c_ext_clk_period, c_common_cross_clock_domain_latency * 2); -- Read back disabled dump - mmf_mm_bus_rd(c_mm_file_reg_tbuf, 16, rd_data_control, tb_clk); + mmf_mm_bus_rd(mmf_prefix(v_gn) & "REG_TBUF", 16, rd_data_control, tb_clk); tbuf_registers_rd.dump_enables <= rd_data_control(c_sdp_A_pn - 1 downto 0); proc_common_wait_some_cycles(tb_clk, 1); assert to_uint(tbuf_registers_rd.dump_enables) = to_uint(tbuf_registers_wr.dump_enables) - report c_tb_str & "Wrong tbuf_registers_rd.dump_enables disabled" + report c_tb_str & v_rn_str & "Wrong tbuf_registers_rd.dump_enables disabled" severity ERROR; -- Read dump_done to check that it is '0' - mmf_mm_bus_rd(c_mm_file_reg_tbuf, 17, rd_data_dump_done, tb_clk); + mmf_mm_bus_rd(mmf_prefix(v_gn) & "REG_TBUF", 17, rd_data_dump_done, tb_clk); tbuf_registers_ro.dump_done <= rd_data_dump_done(0); proc_common_wait_some_cycles(tb_clk, 1); assert tbuf_registers_ro.dump_done = '0' - report c_tb_str & "Wrong tbuf_registers_ro.dump_done" + report c_tb_str & v_rn_str & "Wrong tbuf_registers_ro.dump_done" severity ERROR; - print_str(c_tb_str & "tbuf_registers_rd.dump_enables = " & slv_to_str(tbuf_registers_rd.dump_enables)); - print_str(c_tb_str & "tbuf_registers_ro.dump_done = " & sl_to_str(tbuf_registers_ro.dump_done)); + print_str(c_tb_str & v_rn_str & "tbuf_registers_rd.dump_enables = " & slv_to_str(tbuf_registers_rd.dump_enables)); + print_str(c_tb_str & v_rn_str & "tbuf_registers_ro.dump_done = " & sl_to_str(tbuf_registers_ro.dump_done)); end loop; ---------------------------------------------------------------------------