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 0031f7d1593008eadc92c9a16e8f6236321d4b56..9e02d441423fc2b0ee15eabc79ef19ea21c5f21c 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 @@ -33,7 +33,7 @@ -- . ------------------------------------------------------------------------------- -LIBRARY IEEE, common_lib, dp_lib; +LIBRARY IEEE, common_lib, dp_lib, ring_lib; USE IEEE.STD_LOGIC_1164.ALL; USE common_lib.common_pkg.ALL; USE common_lib.common_mem_pkg.ALL; @@ -43,6 +43,7 @@ USE common_lib.common_network_layers_pkg.ALL; USE common_lib.common_field_pkg.ALL; USE common_lib.common_str_pkg.ALL; USE dp_lib.dp_stream_pkg.ALL; +USE ring_lib.ring_pkg.ALL; USE work.sdp_pkg.ALL; USE work.tb_sdp_pkg.ALL; @@ -50,19 +51,27 @@ USE work.tb_sdp_pkg.ALL; ENTITY tb_sdp_statistics_offload IS GENERIC ( g_statistics_type : STRING := "XST"; - g_offload_time : NATURAL := 500; - g_beamset_id : NATURAL := 0; - g_P_sq : NATURAL := 1 --c_sdp_P_sq + g_offload_time : NATURAL := 50; + g_beamset_id : NATURAL := 1; -- < c_sdp_N_beamsets + g_gn_index : NATURAL := 5; -- global node (GN) index, must be in range(O_rn, O_rn + N_rn), use > 0 to see effect of g_offload_time + g_O_rn : NATURAL := 4; -- 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 + g_nof_crosslets : NATURAL := 1; -- <= c_sdp_N_crosslets_max + g_crosslets_direction : INTEGER := 1 -- +1 or -1 ); 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 := 20 ns; -- 50 MHz + CONSTANT c_mm_clk_period : TIME := 1 ns; -- 1 GHz to speed up simulation CONSTANT c_cross_clock_domain_latency : NATURAL := 20; - -- In this tb simply use fixed src addresses + CONSTANT c_offload_time : NATURAL := g_offload_time * g_gn_index; + + -- In this tb simply use fixed network src addresses CONSTANT c_eth_src_mac : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0) := x"123456789ABC"; CONSTANT c_ip_src_addr : STD_LOGIC_VECTOR(c_network_ip_addr_w-1 DOWNTO 0) := x"0A090807"; CONSTANT c_udp_src_port : STD_LOGIC_VECTOR(c_network_udp_port_w-1 DOWNTO 0) := x"D001"; @@ -76,23 +85,26 @@ ARCHITECTURE tb OF tb_sdp_statistics_offload IS CONSTANT c_ip_total_length : NATURAL := func_sdp_get_stat_ip_total_length(g_statistics_type); CONSTANT c_marker : NATURAL := func_sdp_get_stat_marker(g_statistics_type); CONSTANT c_nof_signal_inputs : NATURAL := func_sdp_get_stat_nof_signal_inputs(g_statistics_type); - CONSTANT c_nof_packets : NATURAL := func_sdp_get_stat_nof_packets(g_statistics_type, c_sdp_S_pn, g_P_sq); + CONSTANT c_nof_packets_max : NATURAL := func_sdp_get_stat_nof_packets(g_statistics_type, c_sdp_S_pn, g_P_sq, c_sdp_N_crosslets_max); - CONSTANT c_beamlet_id : NATURAL := g_beamset_id * c_sdp_S_sub_bf; + 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_slv : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := func_construct_crosslets_info(c_crosslets_info_rec); -- payload data - CONSTANT c_data_size : NATURAL := 2; + CONSTANT c_data_size : NATURAL := c_sdp_W_statistic_sz; CONSTANT c_nof_data : NATURAL := c_nof_statistics_per_packet; - -- Define SST RAM size for c_nof_packets. - CONSTANT c_ram_size : NATURAL := c_nof_data * c_data_size * c_nof_packets; + -- Define SST RAM size for c_nof_packets_max. + CONSTANT c_ram_size : NATURAL := c_nof_data * c_data_size * c_nof_packets_max; CONSTANT c_ram_w : NATURAL := ceil_log2(c_ram_size); --CONSTANT c_ram_buf : t_c_mem := (c_mem_ram_rd_latency, c_ram_w, 32, 2**c_ram_w, 'X'); CONSTANT c_ram_buf : t_c_mem := (1, c_ram_w, 32, 2**c_ram_w, 'X'); -- Define block timing. CONSTANT c_bsn_init : NATURAL := 0; - CONSTANT c_nof_block_per_sync : NATURAL := 80; -- Sufficient to fit more than c_nof_packets offload packets per sync interval. + CONSTANT c_nof_block_per_sync : NATURAL := 3 + ceil_div(c_offload_time, c_nof_data) + c_nof_packets_max; -- Sufficient to fit more than c_nof_packets_max offload packets per sync interval. CONSTANT c_nof_clk_per_block : NATURAL := c_nof_data * c_data_size; CONSTANT c_nof_valid_per_block : NATURAL := c_nof_data * c_data_size; CONSTANT c_nof_sync : NATURAL := 5; @@ -118,52 +130,85 @@ ARCHITECTURE tb OF tb_sdp_statistics_offload IS SIGNAL offload_rx_hdr_dat_mosi : t_mem_mosi := c_mem_mosi_rst; SIGNAL offload_rx_hdr_dat_miso : t_mem_miso; - SIGNAL in_sosi : t_dp_sosi := c_dp_sosi_rst; + SIGNAL in_sosi : t_dp_sosi := c_dp_sosi_rst; + + SIGNAL offload_data : STD_LOGIC_VECTOR(31 DOWNTO 0); + SIGNAL offload_sosi : t_dp_sosi; + SIGNAL offload_siso : t_dp_siso := c_dp_siso_rst; - SIGNAL offload_data : STD_LOGIC_VECTOR(31 DOWNTO 0); - SIGNAL offload_sosi : t_dp_sosi; - SIGNAL offload_siso : t_dp_siso := c_dp_siso_rst; + SIGNAL test_offload_sosi : t_dp_sosi := c_dp_sosi_rst; + SIGNAL test_offload_en : STD_LOGIC := '0'; + SIGNAL test_offload_sop_cnt : NATURAL; + SIGNAL test_offload_eop_cnt : NATURAL; - SIGNAL test_offload_sosi : t_dp_sosi := c_dp_sosi_rst; + SIGNAL rx_hdr_fields_out : STD_LOGIC_VECTOR(1023 DOWNTO 0); + SIGNAL rx_hdr_fields_raw : STD_LOGIC_VECTOR(1023 DOWNTO 0) := (OTHERS => '0'); + SIGNAL rx_sdp_stat_header : t_sdp_stat_header; + SIGNAL exp_sdp_stat_header : t_sdp_stat_header; - SIGNAL rx_hdr_fields_out : STD_LOGIC_VECTOR(1023 DOWNTO 0); - SIGNAL rx_hdr_fields_raw : STD_LOGIC_VECTOR(1023 DOWNTO 0) := (OTHERS => '0'); - SIGNAL rx_sdp_stat_header : t_sdp_stat_header; - SIGNAL exp_sdp_stat_header : t_sdp_stat_header; - SIGNAL exp_bsn : STD_LOGIC_VECTOR(63 DOWNTO 0); + SIGNAL exp_dp_bsn : STD_LOGIC_VECTOR(63 DOWNTO 0); + SIGNAL exp_sst_signal_input : NATURAL; + SIGNAL exp_bst_beamlet_index : NATURAL; + SIGNAL cur_X_sq_cell : NATURAL; + SIGNAL cur_crosslet : NATURAL; + SIGNAL exp_subband_index : NATURAL; + SIGNAL exp_xst_signal_input_A : NATURAL; + SIGNAL exp_xst_signal_input_B : NATURAL; -- Signals used to change settings of sdp_info. - SIGNAL gn_index : NATURAL := 1; -- select > 0 to see effect of g_offload_time - SIGNAL sdp_info : t_sdp_info := ( TO_UVEC(601, 16), -- station_id '0', -- antenna_band_index - x"00001111", -- observation_id - b"01", -- nyquist_zone_index - '0', -- f_adc - '1', -- fsub_type + x"FFFFFFFF", -- observation_id + b"01", -- nyquist_zone_index, 0 = first, 1 = second, 2 = third + '1', -- f_adc, 0 = 160 MHz, 1 = 200 MHz + '0', -- fsub_type, 0 = critically sampled, 1 = oversampled '0', -- beam_repositioning_flag - x"01", -- O_si - x"02", -- N_si - x"04", -- O_rn - x"08", -- N_rn + x"01", -- O_si, not used + x"02", -- N_si, not used + TO_UVEC(g_O_rn, 8), -- O_rn + TO_UVEC(g_N_rn, 8), -- N_rn x"1400" -- block_period = 5120 ); + SIGNAL gn_index : NATURAL := g_gn_index; -- this node GN + SIGNAL rn_index : NATURAL := g_gn_index - g_O_rn; -- this node RN + SIGNAL source_rn : NATURAL; -- source node RN + SIGNAL source_gn : NATURAL; -- source node GN + SIGNAL subband_calibrated_flag : STD_LOGIC := '0'; + SIGNAL nof_crosslets : STD_LOGIC_VECTOR(c_sdp_nof_crosslets_reg_w-1 DOWNTO 0) := (OTHERS => '0'); + SIGNAL nof_packets : NATURAL; -- Signals used for starting processes. - SIGNAL ram_wr_data : STD_LOGIC_VECTOR(c_ram_buf.dat_w-1 DOWNTO 0); - SIGNAL ram_wr_addr : STD_LOGIC_VECTOR(c_ram_buf.adr_w-1 DOWNTO 0); - SIGNAL ram_wr_en : STD_LOGIC; - SIGNAL init_ram_done : STD_LOGIC := '0'; + SIGNAL ram_wr_data : STD_LOGIC_VECTOR(c_ram_buf.dat_w-1 DOWNTO 0); + SIGNAL ram_wr_addr : STD_LOGIC_VECTOR(c_ram_buf.adr_w-1 DOWNTO 0); + SIGNAL ram_wr_en : STD_LOGIC; + SIGNAL init_ram_done : STD_LOGIC := '0'; - SIGNAL in_sync_cnt : NATURAL := 0; SIGNAL in_sync_hold : STD_LOGIC := '0'; - SIGNAL rx_block_cnt : NATURAL := 0; - SIGNAL rx_valid_clk_cnt : NATURAL := 0; + SIGNAL in_sync_cnt : NATURAL := 0; + SIGNAL test_sync_cnt : INTEGER; + + SIGNAL rx_packet_cnt : NATURAL := 0; + SIGNAL rx_valid_cnt : NATURAL := 0; + + -- Debug signals, to view in Wave window + 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; + SIGNAL dbg_c_marker : NATURAL := c_marker; + SIGNAL dbg_c_nof_signal_inputs : NATURAL := c_nof_signal_inputs; + SIGNAL dbg_c_nof_packets_max : NATURAL := c_nof_packets_max; + SIGNAL dbg_c_beamlet_index : NATURAL := c_beamlet_index; + SIGNAL dbg_c_data_size : NATURAL := c_data_size; + SIGNAL dbg_c_nof_data : NATURAL := c_nof_data; + SIGNAL dbg_c_ram_size : NATURAL := c_ram_size; + SIGNAL dbg_c_crosslets_info_rec : t_sdp_crosslets_info := c_crosslets_info_rec; + SIGNAL dbg_c_crosslets_info_slv : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := c_crosslets_info_slv; BEGIN + dp_rst <= '1', '0' AFTER c_dp_clk_period*7; dp_clk <= (NOT dp_clk) OR tb_end AFTER c_dp_clk_period/2; @@ -186,24 +231,15 @@ BEGIN END LOOP; ram_wr_en <= '0'; - proc_common_wait_until_high(dp_clk, in_sosi.sync); init_ram_done <= '1'; WAIT; END PROCESS; - p_enable_trigger : PROCESS - BEGIN - proc_common_wait_until_high(mm_clk, init_ram_done); - -- Enable common variabel 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); - WAIT; - END PROCESS; - + -- Start the input p_in_sosi : PROCESS BEGIN proc_common_wait_until_low(dp_clk, dp_rst); - proc_common_wait_some_cycles(dp_clk, 12); + proc_common_wait_some_cycles(dp_clk, 10); in_sosi.bsn <= TO_DP_BSN(c_bsn_init); in_sosi.valid <= '1'; WHILE TRUE LOOP @@ -229,7 +265,79 @@ BEGIN WAIT; END PROCESS; - p_exp_sdp_stat_header : PROCESS(sdp_info, subband_calibrated_flag, gn_index, rx_block_cnt, exp_bsn) + -- Enable the statistics offload when input is running + p_enable_trigger : PROCESS + BEGIN + proc_common_wait_until_high(mm_clk, init_ram_done); + proc_common_wait_until_high(dp_clk, in_sosi.sync); + -- Enable common variabel 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'; + WAIT; + END PROCESS; + + -- Crosslets settings + nof_crosslets <= TO_UVEC(g_nof_crosslets, c_sdp_nof_crosslets_reg_w); + nof_packets <= func_sdp_get_stat_nof_packets(g_statistics_type, c_sdp_S_pn, g_P_sq, g_nof_crosslets); + + -- Counters to time expected exp_sdp_stat_header fields per offload packet + p_exp_counters : PROCESS(dp_clk) + BEGIN + IF rising_edge(dp_clk) THEN + -- Count sync intervals using in_sosi.sync, because there is no test_offload_sosi.sync + IF test_offload_en = '0' THEN + in_sync_cnt <= 0; + test_offload_sop_cnt <= 0; + test_offload_eop_cnt <= 0; + ELSE + -- Count test_offload_sosi sync integration intervals + IF in_sosi.sync = '1' THEN + in_sync_cnt <= in_sync_cnt + 1; + END IF; + + -- Count test_offload_sosi packets + IF test_offload_sosi.sop = '1' THEN + test_offload_sop_cnt <= test_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 + END IF; + END IF; + END IF; + END PROCESS; + test_sync_cnt <= in_sync_cnt + 1; -- optionally adjust to fit test_offload_sosi + + -- derive current X_sq correlator cell index + cur_X_sq_cell <= (test_offload_eop_cnt / g_nof_crosslets) MOD g_P_sq; + -- derive current N_crosslets index index + cur_crosslet <= test_offload_eop_cnt MOD g_nof_crosslets; + + -- derive source RN index + source_rn <= func_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. + + -- For all statistics + exp_dp_bsn <= TO_SVEC(c_bsn_init + 1 + test_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; + + -- . prepare expected XST signal_input_A index + exp_xst_signal_input_A <= (gn_index MOD c_sdp_N_pn_max) * c_sdp_S_pn; + + -- . prepare expected XST signal_input_B index, assume crosslet transport in positive direction + exp_xst_signal_input_B <= (source_gn MOD c_sdp_N_pn_max) * c_sdp_S_pn; + + p_exp_sdp_stat_header : PROCESS(sdp_info, subband_calibrated_flag, gn_index, exp_dp_bsn, exp_sst_signal_input, exp_subband_index, exp_xst_signal_input_A, exp_xst_signal_input_B) BEGIN -- eth header exp_sdp_stat_header.eth.dst_mac <= c_sdp_stat_eth_dst_mac; @@ -275,23 +383,23 @@ BEGIN exp_sdp_stat_header.app.sdp_reserved <= TO_UVEC( 0, 8); exp_sdp_stat_header.app.sdp_integration_interval <= TO_UVEC(c_nof_block_per_sync, 24); IF g_statistics_type = "SST" THEN - exp_sdp_stat_header.app.sdp_data_id <= TO_UVEC(rx_block_cnt + c_sdp_S_pn * gn_index, 32); - exp_sdp_stat_header.app.sdp_data_id_sst_signal_input_index <= TO_UVEC(rx_block_cnt + c_sdp_S_pn * gn_index, 8); + exp_sdp_stat_header.app.sdp_data_id <= TO_UVEC(exp_sst_signal_input, 32); + exp_sdp_stat_header.app.sdp_data_id_sst_signal_input_index <= TO_UVEC(exp_sst_signal_input, 8); ELSIF g_statistics_type = "BST" THEN - exp_sdp_stat_header.app.sdp_data_id <= TO_UVEC(c_beamlet_id, 32); - exp_sdp_stat_header.app.sdp_data_id_bst_beamlet_index <= TO_UVEC(c_beamlet_id, 16); + exp_sdp_stat_header.app.sdp_data_id <= TO_UVEC(c_beamlet_index, 32); + exp_sdp_stat_header.app.sdp_data_id_bst_beamlet_index <= TO_UVEC(c_beamlet_index, 16); ELSIF g_statistics_type = "XST" THEN - exp_sdp_stat_header.app.sdp_data_id <= TO_UVEC(0, 7) & TO_UVEC(0, 9) & TO_UVEC(0, 8) & TO_UVEC(0, 8); -- TODO - exp_sdp_stat_header.app.sdp_data_id_xst_subband_index <= TO_UVEC(0, 9); -- TODO - exp_sdp_stat_header.app.sdp_data_id_xst_signal_input_A_index <= TO_UVEC(0, 8); -- TODO - exp_sdp_stat_header.app.sdp_data_id_xst_signal_input_B_index <= TO_UVEC(0, 8); -- TODO + exp_sdp_stat_header.app.sdp_data_id <= TO_UVEC(0, 7) & TO_UVEC(exp_subband_index, 9) & TO_UVEC(exp_xst_signal_input_A, 8) & TO_UVEC(exp_xst_signal_input_B, 8); + exp_sdp_stat_header.app.sdp_data_id_xst_subband_index <= TO_UVEC(exp_subband_index, 9); + exp_sdp_stat_header.app.sdp_data_id_xst_signal_input_A_index <= TO_UVEC(exp_xst_signal_input_A, 8); + exp_sdp_stat_header.app.sdp_data_id_xst_signal_input_B_index <= TO_UVEC(exp_xst_signal_input_B, 8); END IF; - exp_sdp_stat_header.app.sdp_nof_signal_inputs <= TO_UVEC( c_nof_signal_inputs, 8); - exp_sdp_stat_header.app.sdp_nof_bytes_per_statistics <= TO_UVEC( 8, 8); - exp_sdp_stat_header.app.sdp_nof_statistics_per_packet <= TO_UVEC(c_nof_statistics_per_packet, 16); + exp_sdp_stat_header.app.sdp_nof_signal_inputs <= TO_UVEC( c_nof_signal_inputs, 8); + exp_sdp_stat_header.app.sdp_nof_bytes_per_statistic <= TO_UVEC(c_sdp_nof_bytes_per_statistic, 8); + exp_sdp_stat_header.app.sdp_nof_statistics_per_packet <= TO_UVEC( c_nof_statistics_per_packet, 16); exp_sdp_stat_header.app.sdp_block_period <= sdp_info.block_period; - exp_sdp_stat_header.app.dp_bsn <= exp_bsn; + exp_sdp_stat_header.app.dp_bsn <= exp_dp_bsn; END PROCESS; rx_sdp_stat_header <= func_sdp_extract_stat_header(rx_hdr_fields_raw); @@ -299,26 +407,24 @@ BEGIN p_verify_header : PROCESS(test_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 - -- bsn is not fully received (bit 0-15 is missing) because 32 bit allignment not working in dp_offload_rx.vhd. - v_bool := func_sdp_verify_stat_header(g_statistics_type, rx_sdp_stat_header, exp_sdp_stat_header, sdp_info); - END IF; END PROCESS; - -- Count number of blocks in a sync interval. + -- Count number of packets in a sync interval. -- There is no active test_offload_sosi.sync to restart the count. Therefore capture the in_sosi.sync in in_sync_hold, and - -- use in_sync_hold with test_offload_sosi.sop to start counting blocks (packets) from 0, at the start of every sync interval. - p_rx_block_cnt : PROCESS(dp_clk) + -- use in_sync_hold with test_offload_sosi.sop to start counting packets from 0, at the start of every sync interval. + p_rx_packet_cnt : PROCESS(dp_clk) BEGIN IF rising_edge(dp_clk) THEN IF test_offload_sosi.sop = '1' THEN IF in_sync_hold = '1' THEN - rx_block_cnt <= 0; in_sync_hold <= '0'; + rx_packet_cnt <= 0; ELSE - rx_block_cnt <= rx_block_cnt + 1; + rx_packet_cnt <= rx_packet_cnt + 1; END IF; END IF; IF in_sosi.sync = '1' THEN @@ -327,40 +433,29 @@ BEGIN END IF; END PROCESS; - -- Count number of sync intervals, to determine expected statistics bsn - p_rx_sync_cnt : PROCESS(dp_clk) - BEGIN - IF rising_edge(dp_clk) THEN - IF in_sosi.sync = '1' THEN - in_sync_cnt <= in_sync_cnt + 1; - END IF; - END IF; - END PROCESS; - exp_bsn <= TO_SVEC(c_bsn_init + 1 + (in_sync_cnt - 1) * c_nof_block_per_sync, 64); - - -- Verify number of blocks between 2 syncs and between 2 changed bsn numbers. - p_verify_nof_blocks : PROCESS(dp_clk) + -- Verify number of packets per sync interval + p_verify_nof_packets : PROCESS(dp_clk) BEGIN IF rising_edge(dp_clk) THEN IF init_ram_done = '1' THEN - IF in_sosi.sync = '1' AND rx_block_cnt > 0 THEN - ASSERT rx_block_cnt = c_nof_packets-1 REPORT "wrong number of blocks between 2 sync" SEVERITY ERROR; + IF in_sosi.sync = '1' AND rx_packet_cnt > 0 THEN + ASSERT rx_packet_cnt = nof_packets-1 REPORT "Wrong number of packets per sync interval" SEVERITY ERROR; END IF; END IF; END IF; END PROCESS; - p_verify_nof_valid : PROCESS(dp_clk) + p_verify_nof_valid_per_packet : PROCESS(dp_clk) BEGIN IF rising_edge(dp_clk) THEN IF test_offload_sosi.sop = '1' THEN - rx_valid_clk_cnt <= 1; + rx_valid_cnt <= 1; ELSIF test_offload_sosi.eop = '1' THEN - ASSERT rx_valid_clk_cnt+1 = c_nof_valid_per_block REPORT "wrong number of clock counts while valid" SEVERITY ERROR; + ASSERT rx_valid_cnt+1 = c_nof_valid_per_block REPORT "Wrong number of valid per packet" SEVERITY ERROR; ELSE - rx_valid_clk_cnt <= rx_valid_clk_cnt + 1; + rx_valid_cnt <= rx_valid_cnt + 1; -- test_offload_sosi.valid has no gaps END IF; END IF; END PROCESS; @@ -430,34 +525,43 @@ BEGIN g_P_sq => g_P_sq ) PORT MAP ( - mm_clk => mm_clk, - mm_rst => mm_rst, + mm_clk => mm_clk, + mm_rst => mm_rst, - dp_clk => dp_clk, - dp_rst => dp_rst, + dp_clk => dp_clk, + dp_rst => dp_rst, - master_mosi => master_mosi, - master_miso => master_miso, + -- MM + master_mosi => master_mosi, + master_miso => master_miso, reg_enable_mosi => enable_mosi, reg_enable_miso => enable_miso, - reg_hdr_dat_mosi => hdr_dat_mosi, - reg_hdr_dat_miso => hdr_dat_miso, + reg_hdr_dat_mosi => hdr_dat_mosi, + reg_hdr_dat_miso => hdr_dat_miso, - sdp_info => sdp_info, - subband_calibrated_flag => subband_calibrated_flag, - gn_index => gn_index, + -- ST + in_sosi => in_sosi, + out_sosi => offload_sosi, + out_siso => offload_siso, + + -- Inputs from other blocks + eth_src_mac => c_eth_src_mac, + udp_src_port => c_udp_src_port, + ip_src_addr => c_ip_src_addr, - in_sosi => in_sosi, - out_sosi => offload_sosi, - out_siso => offload_siso, + gn_index => gn_index, - eth_src_mac => c_eth_src_mac, - udp_src_port => c_udp_src_port, - ip_src_addr => c_ip_src_addr + sdp_info => sdp_info, + subband_calibrated_flag => subband_calibrated_flag, + nof_crosslets => nof_crosslets, + crosslets_info => c_crosslets_info_slv ); + -- Check crosslet_info functions + ASSERT c_crosslets_info_rec = func_extract_crosslets_info(c_crosslets_info_slv) REPORT "Error in func_extract_crosslets_info() or func_construct_crosslets_info()" SEVERITY FAILURE; + -- To view the 32 bit 1GbE offload data more easily in the Wave window offload_data <= offload_sosi.data(31 DOWNTO 0); diff --git a/applications/lofar2/libraries/sdp/tb/vhdl/tb_tb_sdp_statistics_offload.vhd b/applications/lofar2/libraries/sdp/tb/vhdl/tb_tb_sdp_statistics_offload.vhd index e0506591d517a9df01f03904a3c1bec1c98a1c28..c7e03d9ef4b5972d91a444d63918abe5d3a675e3 100644 --- a/applications/lofar2/libraries/sdp/tb/vhdl/tb_tb_sdp_statistics_offload.vhd +++ b/applications/lofar2/libraries/sdp/tb/vhdl/tb_tb_sdp_statistics_offload.vhd @@ -40,12 +40,19 @@ BEGIN -- g_statistics_type : STRING := "SST"; -- g_offload_time : NATURAL := 500; -- g_beamset_id : NATURAL := 0; +-- g_gn_index : NATURAL := 1; -- global node (GN) index, use > 0 to see effect of g_offload_time +-- g_O_rn : NATURAL := 0; -- GN index of first ring node (RN) +-- g_N_rn : NATURAL := 16; -- <= c_sdp_N_rn_max = 16, number of nodes in ring -- g_P_sq : NATURAL := c_sdp_P_sq +-- g_nof_crosslets : NATURAL := 1; +-- g_crosslets_direction : INTEGER := 1; -- +1 or -1 + + u_sst : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("SST", 50); + u_bst_0 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("BST", 50, 0); + u_bst_1 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("BST", 50, 1); + u_xst_P1 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, 0, 1, 0, 16, 1, 1, 1); + u_xst_P1_nof3 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, 0, 1, 0, 16, 1, 3, 1); + u_xst_P9 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, 0, 1, 0, 16, 9, 1, 1); + u_xst_P9_nof3 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, 0, 1, 0, 16, 9, 3, 1); - u_sst : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("SST"); - u_bst_0 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("BST"); - u_bst_1 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("BST", 500, 1); - u_xst_1 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 500, 0, 1); - u_xst_P_sq : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST"); - END tb;