diff --git a/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_statistics_offload.vhd b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_statistics_offload.vhd index bfacace8b2242da2c5cd1473e67e4f6df1ea99ce..99ebd6f839aef1583d421cee33c40dfcca70927a 100644 --- a/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_statistics_offload.vhd +++ b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_statistics_offload.vhd @@ -32,7 +32,7 @@ -- Usage: -- > as 8 -- > run -a --- . for header: view test_offload_sosi and the rx_sdp_stat_header.app fields +-- . for header: view rx_offload_sosi and the rx_sdp_stat_header.app fields -- . for payload: view rx_val, rx_data and exp_data ------------------------------------------------------------------------------- @@ -54,17 +54,20 @@ USE work.tb_sdp_pkg.ALL; ENTITY tb_sdp_statistics_offload IS GENERIC ( -- All + g_fast_mm_clk : BOOLEAN := TRUE; -- When TRUE use 1 GHz mm_clk to speed up simulation, else use 100 MHz mm_clk + -- for real speed of u_dp_block_from_mm_dc in sdp_statistics_offload g_statistics_type : STRING := "XST"; g_offload_time : NATURAL := 50; g_reverse_word_order : BOOLEAN := TRUE; -- when TRUE then stream LSB word after MSB word. g_gn_index : NATURAL := 4; -- global node (GN) index, must be in range(O_rn, O_rn + N_rn), use > 0 to see effect of g_offload_time + g_nof_sync : NATURAL := 3; -- simulate some sync periods, choose >= 3 -- BST g_beamset_id : NATURAL := 0; -- < c_sdp_N_beamsets -- XST g_O_rn : NATURAL := 0; -- GN index of first ring node (RN) g_N_rn : NATURAL := 8; -- <= c_sdp_N_rn_max = 16, number of nodes in ring g_P_sq : NATURAL := 9; -- <= c_sdp_P_sq, nof available correlator cells - g_nof_crosslets : NATURAL := 1; -- <= c_sdp_N_crosslets_max + g_nof_crosslets : NATURAL := 4; -- <= c_sdp_N_crosslets_max g_crosslets_direction : NATURAL := 1 -- > 0 for crosslet transport in positive direction (incrementing RN), else 0 for negative direction ); END tb_sdp_statistics_offload; @@ -72,7 +75,8 @@ END tb_sdp_statistics_offload; ARCHITECTURE tb OF tb_sdp_statistics_offload IS CONSTANT c_dp_clk_period : TIME := 5 ns; -- 200 MHz - CONSTANT c_mm_clk_period : TIME := 1 ns; -- 1 GHz to speed up simulation + CONSTANT c_mm_clk_period : TIME := sel_a_b(g_fast_mm_clk, 1 , 10) * 1 ns; + CONSTANT c_mm_dp_clk_ratio : NATURAL := sel_a_b(c_mm_clk_period > c_dp_clk_period, c_mm_clk_period / c_dp_clk_period, 1); CONSTANT c_cross_clock_domain_latency : NATURAL := 20; @@ -112,7 +116,8 @@ ARCHITECTURE tb OF tb_sdp_statistics_offload IS CONSTANT c_beamlet_index : NATURAL := g_beamset_id * c_sdp_S_sub_bf; - CONSTANT c_crosslets_info_rec : t_sdp_crosslets_info := (offset_arr => (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), step => 16); + --CONSTANT c_crosslets_info_rec : t_sdp_crosslets_info := (offset_arr => (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), step => 16); + CONSTANT c_crosslets_info_rec : t_sdp_crosslets_info := (offset_arr => (0, 1, 2, 3, 4, 5, 6, 10, 11, 12, 13, 14, 15, 16, 17), step => 7); CONSTANT c_crosslets_info_slv : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := func_sdp_map_crosslets_info(c_crosslets_info_rec); -- Crosslets settings @@ -143,10 +148,9 @@ ARCHITECTURE tb OF tb_sdp_statistics_offload IS -- Define block timing. CONSTANT c_bsn_init : NATURAL := 0; -- Sufficient c_nof_block_per_sync to fit more than c_nof_packets_max offload packets per sync interval. - CONSTANT c_nof_block_per_sync : NATURAL := 3 + ceil_div(c_offload_time, c_packet_size) + c_nof_packets_max; + CONSTANT c_nof_block_per_sync : NATURAL := 3 + c_mm_dp_clk_ratio * (ceil_div(c_offload_time, c_packet_size) + c_nof_packets_max); CONSTANT c_nof_clk_per_block : NATURAL := c_packet_size; CONSTANT c_nof_clk_per_sync : NATURAL := c_nof_block_per_sync * c_nof_clk_per_block; - CONSTANT c_nof_sync : NATURAL := 3; SIGNAL tb_end : STD_LOGIC := '0'; @@ -172,15 +176,15 @@ ARCHITECTURE tb OF tb_sdp_statistics_offload IS SIGNAL in_crosslets_info_rec : t_sdp_crosslets_info; SIGNAL in_crosslets_info_slv : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0); - SIGNAL offload_data : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- 32 bit - SIGNAL offload_sosi : t_dp_sosi; - SIGNAL offload_siso : t_dp_siso := c_dp_siso_rst; + SIGNAL sdp_offload_data : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- 32 bit + SIGNAL sdp_offload_sosi : t_dp_sosi; + SIGNAL sdp_offload_siso : t_dp_siso := c_dp_siso_rst; - SIGNAL test_offload_en : STD_LOGIC := '0'; - SIGNAL test_offload_data : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- 32 bit - SIGNAL test_offload_sosi : t_dp_sosi := c_dp_sosi_rst; - SIGNAL test_offload_sop_cnt : NATURAL := 0; - SIGNAL test_offload_eop_cnt : NATURAL := 0; + SIGNAL rx_offload_en : STD_LOGIC := '0'; + SIGNAL rx_offload_data : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- 32 bit + SIGNAL rx_offload_sosi : t_dp_sosi := c_dp_sosi_rst; + SIGNAL rx_offload_sop_cnt : NATURAL := 0; + SIGNAL rx_offload_eop_cnt : NATURAL := 0; SIGNAL rx_hdr_fields_out : STD_LOGIC_VECTOR(1023 DOWNTO 0); SIGNAL rx_hdr_fields_raw : STD_LOGIC_VECTOR(1023 DOWNTO 0) := (OTHERS => '0'); @@ -213,13 +217,12 @@ ARCHITECTURE tb OF tb_sdp_statistics_offload IS SIGNAL ram_wr_en : STD_LOGIC; SIGNAL init_ram_done : STD_LOGIC := '0'; - SIGNAL in_sync_cnt : NATURAL := 0; - SIGNAL test_sync_cnt : INTEGER := 0; - + SIGNAL rx_sync_cnt : INTEGER := 0; SIGNAL rx_packet_cnt : NATURAL := 0; SIGNAL rx_valid_cnt : NATURAL := 0; -- Debug signals, to view in Wave window + SIGNAL dbg_c_mm_dp_clk_ratio : NATURAL := c_mm_dp_clk_ratio; SIGNAL dbg_c_nof_statistics_per_packet : NATURAL := c_nof_statistics_per_packet; SIGNAL dbg_c_udp_total_length : NATURAL := c_udp_total_length; SIGNAL dbg_c_ip_total_length : NATURAL := c_ip_total_length; @@ -251,7 +254,7 @@ BEGIN mm_rst <= '1', '0' AFTER c_mm_clk_period*7; mm_clk <= (NOT mm_clk) OR tb_end AFTER c_mm_clk_period/2; - -- Fill ram with data, data is same as address number. + -- Fill statistics RAM with data, data is same as address number. p_mm_statistics_ram : PROCESS BEGIN ram_wr_en <= '0'; @@ -271,10 +274,10 @@ BEGIN WAIT; END PROCESS; - -- Start the input + -- Start the input when statistics RAM is initialized p_in_sosi : PROCESS BEGIN - proc_common_wait_until_low(dp_clk, dp_rst); + proc_common_wait_until_high(mm_clk, init_ram_done); proc_common_wait_some_cycles(dp_clk, 10); in_sosi.bsn <= TO_DP_BSN(c_bsn_init); in_sosi.valid <= '1'; @@ -311,12 +314,14 @@ BEGIN -- Enable the statistics offload when input is running p_enable_trigger : PROCESS BEGIN - proc_common_wait_until_high(mm_clk, init_ram_done); + -- Wait at least one sync interval, so that DUT can have measured the integration_interval + proc_common_wait_until_hi_lo(dp_clk, in_sosi.sync); + proc_common_wait_some_cycles(mm_clk, 10); -- Enable common variable delay. proc_mem_mm_bus_wr(c_reg_enable_mm_addr_enable, 1, mm_clk, enable_miso, enable_mosi); proc_common_wait_some_cycles(mm_clk, c_cross_clock_domain_latency); proc_common_wait_some_cycles(dp_clk, 1); - test_offload_en <= '1'; + rx_offload_en <= '1'; WAIT; END PROCESS; @@ -324,41 +329,39 @@ BEGIN p_test_counters : PROCESS(dp_clk) BEGIN IF rising_edge(dp_clk) THEN - -- Count test_offload_sosi packets - IF test_offload_sosi.sop = '1' THEN - test_offload_sop_cnt <= test_offload_sop_cnt + 1; -- early count + -- Count rx_offload_sosi packets + IF rx_offload_sosi.sop = '1' THEN + rx_offload_sop_cnt <= rx_offload_sop_cnt + 1; -- early count END IF; - IF test_offload_sosi.eop = '1' THEN - test_offload_eop_cnt <= test_offload_eop_cnt + 1; -- after count + IF rx_offload_sosi.eop = '1' THEN + rx_offload_eop_cnt <= rx_offload_eop_cnt + 1; -- after count END IF; END IF; END PROCESS; - -- Count sync intervals using in_sosi.sync, because there is no test_offload_sosi.sync - in_sync_cnt <= in_sync_cnt + 1 WHEN rising_edge(dp_clk) AND in_sosi.sync = '1'; - test_sync_cnt <= in_sync_cnt - 1; -- optionally adjust to fit test_offload_sosi + rx_sync_cnt <= rx_sync_cnt + 1 WHEN rising_edge(dp_clk) AND rx_offload_sosi.sync = '1'; -- derive current X_sq correlator cell index - cur_X_sq_cell <= (test_offload_eop_cnt / g_nof_crosslets) MOD c_nof_used_P_sq; + cur_X_sq_cell <= (rx_offload_eop_cnt / g_nof_crosslets) MOD c_nof_used_P_sq; -- derive current N_crosslets index index - cur_crosslet <= test_offload_eop_cnt MOD g_nof_crosslets; + cur_crosslet <= rx_offload_eop_cnt MOD g_nof_crosslets; -- derive source RN index source_rn <= func_ring_nof_hops_to_source_rn(cur_X_sq_cell, rn_index, g_N_rn, g_crosslets_direction); source_gn <= g_O_rn + source_rn; - -- Prepare exp_sdp_stat_header before test_offload_sosi.eop, so that p_exp_sdp_stat_header can - -- verify it at test_offload_sosi.eop. + -- Prepare exp_sdp_stat_header before rx_offload_sosi.eop, so that p_exp_sdp_stat_header can + -- verify it at rx_offload_sosi.eop. -- For all statistics - exp_dp_bsn <= TO_SVEC(c_bsn_init + 1 + test_sync_cnt * c_nof_block_per_sync, 64); + exp_dp_bsn <= TO_SVEC(c_bsn_init + 1 + rx_sync_cnt * c_nof_block_per_sync, 64); -- SST exp_sst_signal_input <= rx_packet_cnt + c_sdp_S_pn * gn_index; -- BST exp_bst_beamlet_index <= c_beamlet_index; -- XST -- . prepare expected XST subband_index - exp_subband_index <= (c_crosslets_info_rec.offset_arr(cur_crosslet) + test_sync_cnt * c_crosslets_info_rec.step) MOD c_sdp_N_sub; + exp_subband_index <= (c_crosslets_info_rec.offset_arr(cur_crosslet) + rx_sync_cnt * c_crosslets_info_rec.step) MOD c_sdp_N_sub; -- . prepare expected XST signal_input_A index exp_xst_signal_input_A <= (gn_index MOD c_sdp_N_pn_max) * c_sdp_S_pn; @@ -433,25 +436,22 @@ BEGIN rx_sdp_stat_header <= func_sdp_map_stat_header(rx_hdr_fields_raw); - p_verify_header : PROCESS(test_offload_sosi) + p_verify_header : PROCESS(rx_offload_sosi) VARIABLE v_bool : BOOLEAN; BEGIN - -- Prepare exp_sdp_stat_header before test_offload_sosi.eop, so that it can be verified at test_offload_sosi.eop - IF test_offload_sosi.eop = '1' THEN + -- Prepare exp_sdp_stat_header before rx_offload_sosi.eop, so that it can be verified at rx_offload_sosi.eop + IF rx_offload_sosi.eop = '1' THEN v_bool := func_sdp_verify_stat_header(g_statistics_type, rx_sdp_stat_header, exp_sdp_stat_header); END IF; END PROCESS; -- Count number of packets in a sync interval. - -- There is no active test_offload_sosi.sync to restart the count, therefore - -- use in_sosi.sync to reset the count for the next test_offload_sosi.sync - -- interval p_rx_packet_cnt : PROCESS(dp_clk) BEGIN IF rising_edge(dp_clk) THEN - IF in_sosi.sync = '1' THEN + IF rx_offload_sosi.sync = '1' THEN rx_packet_cnt <= 0; - ELSIF test_offload_sosi.eop = '1' THEN + ELSIF rx_offload_sosi.eop = '1' THEN rx_packet_cnt <= rx_packet_cnt + 1; END IF; END IF; @@ -461,7 +461,7 @@ BEGIN p_verify_nof_packets : PROCESS(dp_clk) BEGIN IF rising_edge(dp_clk) THEN - IF in_sosi.sync = '1' AND in_sync_cnt > 1 THEN + IF rx_offload_sosi.sync = '1' AND rx_sync_cnt > 1 THEN ASSERT rx_packet_cnt = c_rx_nof_packets REPORT "Wrong number of packets per sync interval" SEVERITY ERROR; END IF; END IF; @@ -470,10 +470,10 @@ BEGIN p_verify_nof_valid_per_packet : PROCESS(dp_clk) BEGIN IF rising_edge(dp_clk) THEN - IF test_offload_sosi.eop = '1' THEN + IF rx_offload_sosi.eop = '1' THEN rx_valid_cnt <= 0; ASSERT rx_valid_cnt = c_packet_size - 1 REPORT "Wrong number of valid per packet" SEVERITY ERROR; - ELSIF test_offload_sosi.valid = '1' THEN + ELSIF rx_offload_sosi.valid = '1' THEN rx_valid_cnt <= rx_valid_cnt + 1; END IF; END IF; @@ -493,8 +493,8 @@ BEGIN BEGIN IF rising_edge(dp_clk) THEN rx_val <= '0'; - v_rx_data := TO_UINT(test_offload_sosi.data); - IF test_offload_sosi.valid = '1' THEN + v_rx_data := TO_UINT(rx_offload_sosi.data); + IF rx_offload_sosi.valid = '1' THEN IF g_statistics_type = "SST" THEN -- Indices: -- W: 0 1 2 3 4 5 ... 1022 1023 @@ -517,7 +517,7 @@ BEGIN -- c_mm_data_size / c_sdp_W_statistic_sz = 1 U := S; -- range c_sdp_N_sub = 512 SST values I := W MOD c_mm_user_size; -- range c_mm_user_size = c_sdp_W_statistic_sz = 2 words - P := rx_packet_cnt; -- range c_nof_packets_max = 12 = c_sdp_S_pn Packets + P := rx_packet_cnt MOD c_rx_nof_packets; -- range c_nof_packets_max = 12 = c_sdp_S_pn packets J := P MOD c_mm_nof_step; -- range c_mm_nof_step = 2 = c_sdp_Q_fft v_exp_data := S * 4; -- due to c_mm_step_size = 4 = c_sdp_W_statistic_sz * c_sdp_Q_fft; @@ -548,7 +548,7 @@ BEGIN -- c_mm_data_size / c_sdp_W_statistic_sz = 2 = c_sdp_N_pol_bf B := D; -- range c_sdp_S_sub_bf = 488 dual polarization BST values I := W MOD c_mm_user_size; -- range c_mm_user_size = c_sdp_W_statistic_sz = 2 words - P := rx_packet_cnt; -- range c_nof_packets_max = 1 + P := rx_packet_cnt MOD c_rx_nof_packets; -- range c_nof_packets_max = 1 packet v_exp_data := S * c_mm_user_size; -- c_mm_user_size = 2 IF g_reverse_word_order = FALSE THEN @@ -589,7 +589,7 @@ BEGIN -- c_mm_data_size / c_sdp_W_statistic_sz = 2 = c_nof_complex X := D; -- range c_sdp_X_sq = 144 complex XST values I := W MOD c_mm_user_size; -- range c_mm_user_size = c_sdp_W_statistic_sz = 2 words - P := rx_packet_cnt; -- range c_rx_nof_packets + P := rx_packet_cnt MOD c_rx_nof_packets; -- range c_nof_packets_max = c_nof_used_P_sq * g_nof_crosslets packets J := P MOD g_nof_crosslets; -- range g_nof_crosslets K := P / g_nof_crosslets; -- range c_nof_used_P_sq @@ -615,7 +615,7 @@ BEGIN p_dp_end : PROCESS BEGIN proc_common_wait_until_high(mm_clk, init_ram_done); - proc_common_wait_some_cycles(dp_clk, c_nof_sync * c_nof_clk_per_sync); -- will show some sync periods + proc_common_wait_some_cycles(dp_clk, g_nof_sync * c_nof_clk_per_sync); -- will show some sync periods tb_end <= '1'; WAIT; END PROCESS; @@ -659,10 +659,10 @@ BEGIN reg_hdr_dat_mosi => offload_rx_hdr_dat_mosi, reg_hdr_dat_miso => offload_rx_hdr_dat_miso, - snk_in_arr(0) => offload_sosi, - snk_out_arr(0) => offload_siso, + snk_in_arr(0) => sdp_offload_sosi, + snk_out_arr(0) => sdp_offload_siso, - src_out_arr(0) => test_offload_sosi, + src_out_arr(0) => rx_offload_sosi, hdr_fields_out_arr(0) => rx_hdr_fields_out, hdr_fields_raw_arr(0) => rx_hdr_fields_raw @@ -697,8 +697,8 @@ BEGIN -- ST in_sosi => in_sosi, - out_sosi => offload_sosi, - out_siso => offload_siso, + out_sosi => sdp_offload_sosi, + out_siso => sdp_offload_siso, -- Inputs from other blocks eth_src_mac => c_eth_src_mac, @@ -717,7 +717,7 @@ BEGIN ASSERT c_crosslets_info_rec = func_sdp_map_crosslets_info(c_crosslets_info_slv) REPORT "Error in func_sdp_map_crosslets_info()" SEVERITY FAILURE; -- To view the 32 bit 1GbE offload data more easily in the Wave window - offload_data <= offload_sosi.data(c_word_w-1 DOWNTO 0); - test_offload_data <= test_offload_sosi.data(c_word_w-1 DOWNTO 0); + sdp_offload_data <= sdp_offload_sosi.data(c_word_w-1 DOWNTO 0); + rx_offload_data <= rx_offload_sosi.data(c_word_w-1 DOWNTO 0); END tb;