diff --git a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_correlator.vhd b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_correlator.vhd index 79d79f21e74c5ff072def085f016c642b2bc857d..d40d86596a5303cd8dc945d9a65a026c5e33e4e2 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_correlator.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_correlator.vhd @@ -293,7 +293,8 @@ begin u_sdp_xst_udp_offload: entity work.sdp_statistics_offload generic map ( g_statistics_type => "XST", - g_offload_time => sel_a_b(g_sim, g_sim_sdp.offload_time, c_sdp_offload_time), + g_offload_node_time => sel_a_b(g_sim, g_sim_sdp.offload_node_time, c_sdp_offload_node_time), + g_offload_packet_time => sel_a_b(g_sim, g_sim_sdp.offload_packet_time, c_sdp_offload_packet_time), g_offload_scale_w => sel_a_b(g_sim, g_sim_sdp.offload_scale_w, c_sdp_offload_scale_w), g_ctrl_interval_size_min => sel_a_b(g_sim, g_sim_sdp.N_clk_per_sync_min, c_sdp_N_clk_per_sync_min), g_P_sq => g_P_sq, diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd index 32171fd7965d87b9dd17a6014eaac9f8361bc659..676a983e1b620d223d0024f168e275e54dd9a5a1 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd @@ -121,6 +121,7 @@ package sdp_pkg is constant c_sdp_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 constant c_sdp_N_clk_per_second : natural := c_sdp_f_adc_MHz * 10**6; -- Default 200M clock cycles per second constant c_sdp_N_clk_per_sync : natural := c_sdp_N_clk_per_second; -- Default 200M clock cycles per sync interval of 1 second + constant c_sdp_N_clk_per_sync_max : natural := c_sdp_N_clk_per_second * 10; -- 10 seconds constant c_sdp_N_clk_per_sync_min : natural := c_sdp_N_clk_per_second / 10; -- 0.1 second constant c_sdp_N_clk_sync_timeout : natural := c_sdp_N_clk_per_second + c_sdp_N_clk_per_second / 10; -- 10% margin. constant c_sdp_N_clk_sync_timeout_xsub : natural := 2147483647; -- = 2**31 - 1 = largest value for NATURAL for 10.7 seconds. Do not use 2*31 to avoid Modelsim NATURAL overflow warning. @@ -274,11 +275,15 @@ package sdp_pkg is -- Can use same offload time for all statistics, because 1GbE mux will combine them -- see https://support.astron.nl/confluence/display/L2M/L3+SDP+Testing+Notebook%3A+Statistics+offload - --CONSTANT c_sdp_offload_time : NATURAL := 13000; -- from wave window 62855nS / 5nS = 12571 cycles. - constant c_sdp_offload_time : natural := 600000; -- 600000 * 5 ns = 3 ms, so gn 31 starts after 93 ms + -- Intra node time of 600000 * 5 ns = 3 ms, so gn 31 starts after 31 * 3 = 93 ms + constant c_sdp_offload_node_time : natural := 600000; + -- Inter packet time of 3100 * 5 ns = 15.5 us, so maximum 9 * 7 = 63 XST packets will yield total gap time of + -- about 63 * 15.5 us = 0.98 ms. The 63 XST packets take about 63 * 2344 octets * 8 bits / 1GbE = 1.2 ms. + -- Hence in total the XST offload takes about 0.98 + 1.2 = 2.2 ms, which fits in the budgetted 3 ms per node. + constant c_sdp_offload_packet_time : natural := 3100; -- Scale factor to implement offload time dependent on ctrl_interval_size, see sdp_statistics_offload.vhd -- for more description. - constant c_sdp_offload_scale_w : natural := 14; + constant c_sdp_offload_scale_w : natural := 15; -- packet lengths, see ICD SC-SDP constant c_sdp_nof_bytes_per_statistic : natural := 8; -- c_sdp_W_statistic_sz * c_word_sz = 2 * 4 = 8 @@ -664,14 +669,15 @@ package sdp_pkg is ------------------------------------------------- type t_sdp_sim is record N_clk_per_sync_min : natural; - offload_time : natural; -- select > 0 and gn_index > 0 to see effect of offload_time on statistics offload + offload_node_time : natural; -- select > 0 and gn_index > 0 to see effect on statistics offload + offload_packet_time : natural; -- select > 0 to see effect on statistics offload offload_scale_w : natural; sync_timeout : natural; unb_nr : natural; node_nr : natural; end record; - constant c_sdp_sim : t_sdp_sim := (1, 10, 1, 3 * 1024, 0, 0); + constant c_sdp_sim : t_sdp_sim := (1, 10, 5, 1, 3 * 1024, 0, 0); ------------------------------------------------- -- SDP functions diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd index 6b149387b8082d5f75a328be320c6baca6d132dc..dda2950705dbbf50d872bb9bb60f81f17cefb37d 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd @@ -110,9 +110,10 @@ use work.sdp_pkg.all; entity sdp_statistics_offload is generic ( g_statistics_type : string := "SST"; - g_offload_time : natural := c_sdp_offload_time; - g_offload_scale_w : natural := 0; -- default for p.offload_time = g_offload_time - g_ctrl_interval_size_min : natural := 1; -- default for p.offload_time = g_offload_time + g_offload_node_time : natural := c_sdp_offload_node_time; + g_offload_packet_time : natural := c_sdp_offload_packet_time; + g_offload_scale_w : natural := 0; -- 0 = default + g_ctrl_interval_size_min : natural := 1; -- 1 = default g_beamset_id : natural := 0; g_P_sq : natural := c_sdp_P_sq; -- number of available correlator cells, g_crosslets_direction : natural := 1; -- > 0 for crosslet transport in positive direction (incrementing RN), else 0 for negative direction @@ -143,9 +144,9 @@ entity sdp_statistics_offload is reg_bsn_monitor_v2_offload_cipo : out t_mem_cipo; -- Input timing regarding the integration interval of the statistics - in_sosi : in t_dp_sosi; - new_interval : in std_logic; - ctrl_interval_size : in natural := 1; -- default for p.offload_time = g_offload_time + in_sosi : in t_dp_sosi; + new_interval : in std_logic; + ctrl_interval_size : in natural := 1; -- 1 = default -- Streaming output of offloaded statistics packets out_sosi : out t_dp_sosi; @@ -169,6 +170,15 @@ end sdp_statistics_offload; architecture str of sdp_statistics_offload is constant c_nof_streams : natural := 1; + -- Offload timing + constant c_offload_node_time_scaled : natural := (g_offload_node_time * 2**g_offload_scale_w) / + g_ctrl_interval_size_min; + constant c_offload_packet_time_scaled : natural := (g_offload_packet_time * 2**g_offload_scale_w) / + g_ctrl_interval_size_min; + constant c_offload_packet_time_max : natural := g_offload_packet_time * + (c_sdp_N_clk_per_sync_max / c_sdp_N_clk_per_sync_min + 1) + 1; + -- +1 for margin and to ensure > 0 + -- header fields 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); @@ -196,7 +206,8 @@ architecture str of sdp_statistics_offload is remote_gn : natural; -- index of remote global node remote_pn : natural; -- index of remote node in antenna band remote_si_offset : natural; -- index of first signal input on remote node - offload_time : natural; -- unit offload delay for nof_cycles_dly per node + offload_node_time : natural; -- unit offload delay between nodes + offload_packet_time : natural; -- unit offload delay between packets per node base_dly : natural; -- same base offload delay for nof_cycles_dly per node nodes_dly : natural; -- incremental offload delay for nof_cycles_dly per node nof_cycles_dly : natural; -- trigger_offload delay for this node @@ -222,6 +233,7 @@ architecture str of sdp_statistics_offload is type t_reg is record packet_count : natural range 0 to c_nof_packets_max; start_address : natural range 0 to c_mm_ram_size; + start_timer : natural range 0 to c_offload_packet_time_max; start_pulse : std_logic; start_sync : std_logic; dp_header_info : std_logic_vector(1023 downto 0); @@ -232,7 +244,7 @@ architecture str of sdp_statistics_offload is instance_address : natural range 0 to c_mm_ram_size; end record; - constant c_reg_rst : t_reg := (0, 0, '0', '0', (others => '0'), 0, 0, 0, 0, 0); + constant c_reg_rst : t_reg := (0, 0, 0, '0', '0', (others => '0'), 0, 0, 0, 0, 0); signal p : t_parameters; signal p_gn_id : std_logic_vector(c_byte_w - 1 downto 0); @@ -271,6 +283,8 @@ architecture str of sdp_statistics_offload is signal station_info : std_logic_vector(15 downto 0) := (others => '0'); -- Debug signals for view in Wave window + signal dbg_g_offload_node_time : natural := g_offload_node_time; + signal dbg_g_offload_packet_time : natural := g_offload_packet_time; signal dbg_c_marker : natural := c_marker; signal dbg_c_nof_signal_inputs : natural := c_nof_signal_inputs; signal dbg_c_nof_statistics_per_packet : natural := c_nof_statistics_per_packet; @@ -379,55 +393,73 @@ begin -- . gn_index and ring_info.O_rn are in full GN = ID = 0:255 range defined by c_sdp_W_gn_id = 8 -- . pn_index = gn_index MOD c_sdp_N_pn_max = gn_index[3:0] = 0:15, with c_sdp_N_pn_max = 16 -- . O_rn is first GN index in ring, so O_rn <= gn_index - -- . nof_cycles_dly for statistics offload start per node: - -- - nof_cycles_dly avoids burst between nodes, but per node the statistics packets are still - -- offloaded a full rate, for SST these are nof_packets = S_pn = 12, for BST nof_packets = 1 - -- and for XST maximum nof_packets = P_sq * c_sdp_N_crosslets_max = 9 * 7 - 63. + -- . Avoid offload bursts between nodes via g_offload_node_time: + -- - The nof_cycles_dly delays the start of statistics offload per node. The nof_cycles_dly + -- increases as function of the GN index, so that the multiple nodes do their offload after + -- eachother, to avoid bursts from multiple nodes. -- - c_sdp_N_band * c_sdp_N_pn_max = 32 nodes is maximum for a LOFAR2 Station. - -- - p.nodes_dly: g_offload_time = c_sdp_offload_time = 600000 * 5 ns = 3 ms, so for max + -- - p.nodes_dly: g_offload_node_time = c_sdp_offload_node_time = 600000 * 5 ns = 3 ms, so for max -- gn_index[4:0] = 31 the offload starts after 93 ms, to just fit within XST T_int min is 100 ms. - -- - p.base_dly: use gn_index[7:5] to add a small extra dly g_offload_time / 8 of per group of - -- 32 nodes, so 0:g_offload_time in 8 steps of g_offload_time/8, to remain within 32 * 3 = 96 ms - -- < 100 ms for any set of 32 nodes within full GN range. + -- - p.base_dly: use gn_index[7:5] to add a small extra dly g_offload_node_time / 8 of per group of + -- 32 nodes, so 0:g_offload_node_time in 8 steps of g_offload_node_time / 8, to remain within + -- 32 * 3 = 96 ms < 100 ms for any set of 32 nodes within full GN range. -- - use +1 for nof_cycles_dly to ensure that hdr_input.integration_interval gets the correct -- value also for node 0 with zero delay. Otherwise node 0 will read an integration_interval -- value that depends on when the remaining sop_cnt of the last interval in case of a XST -- processing restart. - -- - g_offload_time = c_sdp_offload_time = 600000 suits g_ctrl_interval_size_min. For larger - -- ctrl_interval_size the p.offload_time can be > g_offload_time by factor ctrl_interval_size / - -- g_ctrl_interval_size_min. Use g_offload_scale_w to be able to implement this scaling by - -- using right shift instead of integer divide: - -- p.offload_time = (g_offload_time * 2**g_offload_scale_w / g_ctrl_interval_size_min) * - -- (ctrl_interval_size / 2**g_offload_scale_w) - -- ~= g_offload_time * ctrl_interval_size / g_ctrl_interval_size_min - -- For c_sdp_offload_time / g_ctrl_interval_size_min = 600000 / 20000000 = 0.03 choose - -- g_offload_scale_w = 15 to have c_offload_time_scaled = 0.03 * 2**15 = 983.04 --> 983 and + -- - g_offload_node_time = c_sdp_offload_node_time = 600000 suits g_ctrl_interval_size_min. For + -- larger ctrl_interval_size the p.offload_node_time can be > g_offload_node_time by factor + -- ctrl_interval_size / g_ctrl_interval_size_min. Use g_offload_scale_w to be able to implement + -- this scaling by using right shift instead of integer divide: + -- p.offload_node_time = (g_offload_node_time * 2**g_offload_scale_w / g_ctrl_interval_size_min) * + -- (ctrl_interval_size / 2**g_offload_scale_w) + -- ~= g_offload_node_time * ctrl_interval_size / g_ctrl_interval_size_min + -- . Avoid offload bursts per node via g_offload_packet_time: + -- - Each node offloads multiple packets per integration interval. For SST nof_packets = S_pn = 12, + -- for BST nof_packets = 1 (per beamset), and for XST maximum nof_packets = P_sq * + -- c_sdp_N_crosslets_max = 9 * 7 = 63. + -- - g_offload_packet_time = c_sdp_offload_packet_time = 3100 suits g_ctrl_interval_size_min. For + -- larger ctrl_interval_size the p.offload_packet_time can be > g_offload_packet_time by factor + -- ctrl_interval_size / g_ctrl_interval_size_min. Use g_offload_scale_w to be able to implement + -- this scaling by using right shift instead of integer divide: + -- p.offload_packet_time = (g_offload_packet_time * 2**g_offload_scale_w / g_ctrl_interval_size_min) * + -- (ctrl_interval_size / 2**g_offload_scale_w) + -- ~= g_offload_packet_time * ctrl_interval_size / g_ctrl_interval_size_min + -- . Fit g_offload_scale_w for offload_node_time and offload_packet_time. + -- - For c_sdp_offload_node_time / g_ctrl_interval_size_min = 600000 / 20000000 = 0.03 choose + -- g_offload_scale_w = 15 to have c_offload_node_time_scaled = 0.03 * 2**15 = 983.04 --> 983 and -- ctrl_interval_scaled = 20000000 / 2**15 = 610.35 --> 610, and 983 * 610 = 599630, which is - -- close enough to c_sdp_offload_time == 600000. - -- - default use g_offload_scale_w = 0, ctrl_interval_size = g_ctrl_interval_size_min = 1 to have - -- p.offload_time = g_offload_time + -- close enough to c_sdp_offload_node_time = 600000. + -- - For c_sdp_offload_packet_time / g_ctrl_interval_size_min = 3100 / 20000000 = 0.000155 choose + -- g_offload_scale_w = 15 to have c_offload_node_time_scaled = 0.000155 * 2**15 = 5.08 --> 5 and + -- ctrl_interval_scaled = 20000000 / 2**15 = 610.35 --> 610, and 5 * 610 = 3050, which is close + -- enough to c_sdp_offload_packet_time = 3100. + -- - Default use g_offload_scale_w = 0, ctrl_interval_size = g_ctrl_interval_size_min = 1 to have + -- p.offload_node_time = g_offload_node_time + -- p.offload_packet_time = g_offload_packet_time ctrl_interval_scaled <= SHIFT_UINT(ctrl_interval_size, g_offload_scale_w); p_reg_parameters : process(dp_clk) - constant c_offload_time_scaled : natural := (g_offload_time * 2**g_offload_scale_w) / g_ctrl_interval_size_min; begin if rising_edge(dp_clk) then - p.gn_index <= gn_index; -- gn_index[7:0] full GN range - p.pn_index <= func_sdp_gn_index_to_pn_index(p.gn_index); -- pn_index = 0:15 - p.offset_rn <= TO_UINT(ring_info.O_rn); - p.rn_index <= p.gn_index - p.offset_rn; - p.local_si_offset <= p.pn_index * c_sdp_S_pn; - p.offload_time <= c_offload_time_scaled * ctrl_interval_scaled; - p.base_dly <= TO_UINT(p_gn_id(7 downto 5)) * SHIFT_UINT(p.offload_time, 3); -- divide by 2**3 = 8 - p.nodes_dly <= TO_UINT(p_gn_id(4 downto 0)) * p.offload_time; - p.nof_cycles_dly <= p.base_dly + p.nodes_dly + 1; -- + 1 to ensure proper hdr_input.integration_interval also on node 0 - p.nof_rn <= TO_UINT(ring_info.N_rn); - p.nof_used_P_sq <= smallest(p.nof_rn / 2 + 1, g_P_sq); - p.remote_rn <= func_ring_nof_hops_to_source_rn(r.instance_count, p.rn_index, p.nof_rn, g_crosslets_direction); - p.remote_gn <= p.offset_rn + p.remote_rn; - p.remote_pn <= func_sdp_gn_index_to_pn_index(p.remote_gn); - p.remote_si_offset <= p.remote_pn * c_sdp_S_pn; + p.gn_index <= gn_index; -- gn_index[7:0] full GN range + p.pn_index <= func_sdp_gn_index_to_pn_index(p.gn_index); -- pn_index = 0:15 + p.offset_rn <= TO_UINT(ring_info.O_rn); + p.rn_index <= p.gn_index - p.offset_rn; + p.local_si_offset <= p.pn_index * c_sdp_S_pn; + p.offload_node_time <= c_offload_node_time_scaled * ctrl_interval_scaled; + p.offload_packet_time <= c_offload_packet_time_scaled * ctrl_interval_scaled + 1; -- + 1 to ensure > 0 + p.base_dly <= TO_UINT(p_gn_id(7 downto 5)) * SHIFT_UINT(p.offload_node_time, 3); -- divide by 2**3 = 8 + p.nodes_dly <= TO_UINT(p_gn_id(4 downto 0)) * p.offload_node_time; + p.nof_cycles_dly <= p.base_dly + p.nodes_dly + 1; -- + 1 to ensure > 0, to have proper + -- hdr_input.integration_interval also on node 0 + p.nof_rn <= TO_UINT(ring_info.N_rn); + p.nof_used_P_sq <= smallest(p.nof_rn / 2 + 1, g_P_sq); + p.remote_rn <= func_ring_nof_hops_to_source_rn(r.instance_count, p.rn_index, p.nof_rn, g_crosslets_direction); + p.remote_gn <= p.offset_rn + p.remote_rn; + p.remote_pn <= func_sdp_gn_index_to_pn_index(p.remote_gn); + p.remote_si_offset <= p.remote_pn * c_sdp_S_pn; end if; end process; @@ -523,7 +555,7 @@ begin -- The trigger_offload occurs p.nof_cycles_dly after the in_sosi.sync and -- the offload will have finished before the next in_sosi.sync, because - -- c_sdp_offload_time is such that all offload will finish within 100 ms + -- c_sdp_offload_node_time is such that all offload will finish within 100 ms -- and the integration interval (= sync interval) is 1 s for SST and BST -- and minimal 0.1s (= c_sdp_N_clk_per_sync_min) for XST. -- The trigger_offload initializes the control for the first packet offload @@ -548,8 +580,7 @@ begin -- u_dp_block_from_mm_dc. This ensures that the dp_sop identifies the -- sop of the offload packet. At the dp_sop: -- . the dp_header_info per packet offload can be released - -- . the next packet offload can be prepared - -- + -- . the next packet offload with inter packet gap can be prepared elsif dp_sop = '1' then -- Release dp_header_info for current packet offload v.dp_header_info := dp_header_info; @@ -567,7 +598,7 @@ begin v.interleave_count := 0; v.interleave_address := v.start_address; end if; - v.start_pulse := '1'; + v.start_timer := p.offload_packet_time; v.packet_count := r.packet_count + 1; elsif g_statistics_type = "BST" then @@ -595,13 +626,21 @@ begin v.instance_count := r.instance_count + 1; v.instance_address := v.start_address; -- use v.start_address to avoid multipier needed in (r.instance_count + 1) * 2**c_sdp_ram_st_xsq_addr_w end if; - v.start_pulse := '1'; + v.start_timer := p.offload_packet_time; v.packet_count := r.packet_count + 1; else null; -- do nothing in case of unknown g_statistics_type end if; end if; + + -- Use start_timer to have p.offload_packet_time gap between packets, and issue start_pulse when + -- the start_timer expires + elsif r.start_timer > 0 then + v.start_timer := r.start_timer - 1; + if v.start_timer = 0 then + v.start_pulse := '1'; + end if; end if; nxt_r <= v; 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 5b2da154df7b5384886e388f7446c58a361cecf3..f10e1a83b477577e362304edb7f287124dc87ac4 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 @@ -53,12 +53,18 @@ 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_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_offload_node_time : natural := 50; + g_offload_packet_time : natural := 5; + g_offload_scale_w : natural := 0; -- 0 = default + g_ctrl_interval_size : natural := 1; -- 1 = default + g_ctrl_interval_size_min : natural := 1; -- 1 = default 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_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_node_time g_nof_sync : natural := 3; -- simulate some sync periods, choose >= 3 -- BST g_beamset_id : natural := 0; -- < c_sdp_N_beamsets @@ -66,8 +72,9 @@ entity tb_sdp_statistics_offload is 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 := 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 + g_nof_crosslets : natural := 7; -- <= 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; @@ -78,7 +85,7 @@ architecture tb of tb_sdp_statistics_offload is constant c_cross_clock_domain_latency : natural := 20; - constant c_offload_time : natural := g_offload_time * g_gn_index; + constant c_offload_node_time : natural := g_offload_node_time * g_gn_index; -- Use sim default dst and src MAC, IP, UDP port from sdp_pkg.vhd and based on g_gn_index constant c_node_eth_src_mac : std_logic_vector(47 downto 0) := c_sdp_stat_eth_src_mac_47_16 & func_sdp_gn_index_to_mac_15_0(g_gn_index); @@ -149,7 +156,7 @@ 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 + c_mm_dp_clk_ratio * (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_node_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; @@ -655,12 +662,15 @@ begin -- SDP info u_dut: entity work.sdp_statistics_offload generic map ( - g_statistics_type => g_statistics_type, - g_offload_time => g_offload_time, - g_reverse_word_order => g_reverse_word_order, - g_beamset_id => g_beamset_id, - g_P_sq => g_P_sq, - g_crosslets_direction => g_crosslets_direction + g_statistics_type => g_statistics_type, + g_offload_node_time => g_offload_node_time, + g_offload_packet_time => g_offload_packet_time, + g_offload_scale_w => g_offload_scale_w, + g_ctrl_interval_size_min => g_ctrl_interval_size_min, + g_reverse_word_order => g_reverse_word_order, + g_beamset_id => g_beamset_id, + g_P_sq => g_P_sq, + g_crosslets_direction => g_crosslets_direction ) port map ( mm_clk => mm_clk, @@ -680,8 +690,9 @@ begin reg_hdr_dat_miso => hdr_dat_miso, -- ST - in_sosi => in_sosi, - new_interval => new_interval, + in_sosi => in_sosi, + new_interval => new_interval, + ctrl_interval_size => g_ctrl_interval_size, out_sosi => sdp_offload_sosi, out_siso => sdp_offload_siso, 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 c325ba9be21b0f986b274e1060af40f0e48548b3..9851c36b6fa80cc7818689151fc2f44d7ae1a959 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 @@ -37,12 +37,18 @@ architecture tb of tb_tb_sdp_statistics_offload is signal tb_end : std_logic := '0'; -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end' begin -- -- 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_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 := "SST"; --- g_offload_time : NATURAL := 500; +-- g_offload_node_time : NATURAL := 50; +-- g_offload_packet_time : natural := 5; +-- g_offload_scale_w : natural := 0; -- 0 = default +-- g_ctrl_interval_size : natural := 1; -- 1 = default +-- g_ctrl_interval_size_min : natural := 1; -- 1 = default -- g_reverse_word_order : BOOLEAN := TRUE -- when TRUE then stream LSB word after MSB word. --- g_gn_index : NATURAL := 1; -- global node (GN) index, use > 0 to see effect of g_offload_time +-- g_gn_index : NATURAL := 1; -- global node (GN) index, use > 0 to see effect of +-- -- g_offload_node_time -- g_nof_sync : NATURAL := 3; -- -- BST -- g_beamset_id : NATURAL := 0; @@ -53,22 +59,24 @@ begin -- g_nof_crosslets : NATURAL := 1; -- g_crosslets_direction : INTEGER := 1; -- +1 or -1 - u_sst : entity work.tb_sdp_statistics_offload generic map( true, "SST", 50, true, 3, 3); - u_sst_no_reverse : entity work.tb_sdp_statistics_offload generic map( true, "SST", 50, false, 3, 3); - u_sst_os : entity work.tb_sdp_statistics_offload generic map( true, "SST_OS", 50, true, 3, 3); - u_sst_os_no_reverse : entity work.tb_sdp_statistics_offload generic map( true, "SST_OS", 50, false, 3, 3); - u_bst_0 : entity work.tb_sdp_statistics_offload generic map( true, "BST", 50, true, 1, 3); - u_bst_0_no_reverse : entity work.tb_sdp_statistics_offload generic map( true, "BST", 50, false, 1, 3, 0); - u_bst_1 : entity work.tb_sdp_statistics_offload generic map( true, "BST", 50, true, 1, 3, 1); - u_xst_P1 : entity work.tb_sdp_statistics_offload generic map( true, "XST", 50, true, 1, 3, 0, 0, 16, 1, 1, 1); - u_xst_P1_N3 : entity work.tb_sdp_statistics_offload generic map( true, "XST", 50, true, 1, 3, 0, 0, 16, 1, 3, 1); - u_xst_P9 : entity work.tb_sdp_statistics_offload generic map( true, "XST", 50, true, 1, 3, 0, 0, 16, 9, 1, 1); - u_xst_P9_N3 : entity work.tb_sdp_statistics_offload generic map( true, "XST", 50, true, 1, 3, 0, 0, 16, 9, 3, 1); - u_xst_P9_N3_no_reverse : entity work.tb_sdp_statistics_offload generic map( true, "XST", 50, false, 1, 3, 0, 0, 16, 9, 3, 1); - u_xst_P9_N3_neg_dir : entity work.tb_sdp_statistics_offload generic map( true, "XST", 50, true, 1, 3, 0, 0, 16, 9, 3, 0); - u_xst_P8_N7_RN1_15 : entity work.tb_sdp_statistics_offload generic map( true, "XST", 50, true, 1, 3, 0, 1, 15, 8, 7, 0); - u_xst_P1_N7_RN0_7 : entity work.tb_sdp_statistics_offload generic map( true, "XST", 50, true, 3, 3, 0, 0, 8, 1, 7, 1); -- P_sq = 1 < N_rn/2+1 = 5 - u_xst_P9_N7_RN0_7 : entity work.tb_sdp_statistics_offload generic map( true, "XST", 50, true, 3, 3, 0, 0, 8, 9, 7, 1); -- P_sq = 9 > N_rn/2+1 = 5 - u_xst_P9_N4_RN0_7_slow_mm : entity work.tb_sdp_statistics_offload generic map(false, "XST", 50, true, 3, 3, 0, 0, 8, 9, 4, 1); -- P_sq = 9 > N_rn/2+1 = 5 - u_xst_P9_N7_RN0_7_slow_mm : entity work.tb_sdp_statistics_offload generic map(false, "XST", 50, true, 3, 3, 0, 0, 8, 9, 7, 1); -- P_sq = 9 > N_rn/2+1 = 5 + u_sst : entity work.tb_sdp_statistics_offload generic map( true, "SST", 50, 5, 0, 1, 1, true, 3, 3); + u_sst_time : entity work.tb_sdp_statistics_offload generic map( true, "SST", 50, 8, 1, 6, 2, true, 3, 3); + u_sst_no_reverse : entity work.tb_sdp_statistics_offload generic map( true, "SST", 50, 5, 0, 1, 1, false, 3, 3); + u_sst_os : entity work.tb_sdp_statistics_offload generic map( true, "SST_OS", 50, 5, 0, 1, 1, true, 3, 3); + u_sst_os_no_reverse : entity work.tb_sdp_statistics_offload generic map( true, "SST_OS", 50, 5, 0, 1, 1, false, 3, 3); + u_bst_0 : entity work.tb_sdp_statistics_offload generic map( true, "BST", 50, 5, 0, 1, 1, true, 1, 3); + u_bst_0_no_reverse : entity work.tb_sdp_statistics_offload generic map( true, "BST", 50, 5, 0, 1, 1, false, 1, 3, 0); + u_bst_1 : entity work.tb_sdp_statistics_offload generic map( true, "BST", 50, 5, 0, 1, 1, true, 1, 3, 1); + u_xst_P1 : entity work.tb_sdp_statistics_offload generic map( true, "XST", 50, 5, 0, 1, 1, true, 1, 3, 0, 0, 16, 1, 1, 1); + u_xst_P1_N3 : entity work.tb_sdp_statistics_offload generic map( true, "XST", 50, 5, 0, 1, 1, true, 1, 3, 0, 0, 16, 1, 3, 1); + u_xst_P9 : entity work.tb_sdp_statistics_offload generic map( true, "XST", 50, 5, 0, 1, 1, true, 1, 3, 0, 0, 16, 9, 1, 1); + u_xst_P9_N3 : entity work.tb_sdp_statistics_offload generic map( true, "XST", 50, 5, 0, 1, 1, true, 1, 3, 0, 0, 16, 9, 3, 1); + u_xst_P9_N3_no_reverse : entity work.tb_sdp_statistics_offload generic map( true, "XST", 50, 5, 0, 1, 1, false, 1, 3, 0, 0, 16, 9, 3, 1); + u_xst_P9_N3_neg_dir : entity work.tb_sdp_statistics_offload generic map( true, "XST", 50, 5, 0, 1, 1, true, 1, 3, 0, 0, 16, 9, 3, 0); + u_xst_P8_N7_RN1_15 : entity work.tb_sdp_statistics_offload generic map( true, "XST", 50, 5, 0, 1, 1, true, 1, 3, 0, 1, 15, 8, 7, 0); + u_xst_P1_N7_RN0_7 : entity work.tb_sdp_statistics_offload generic map( true, "XST", 50, 5, 0, 1, 1, true, 3, 3, 0, 0, 8, 1, 7, 1); -- P_sq = 1 < N_rn/2+1 = 5 + u_xst_P9_N7_RN0_7 : entity work.tb_sdp_statistics_offload generic map( true, "XST", 50, 5, 0, 1, 1, true, 3, 3, 0, 0, 8, 9, 7, 1); -- P_sq = 9 > N_rn/2+1 = 5 + u_xst_P9_N7_RN0_7_time : entity work.tb_sdp_statistics_offload generic map( true, "XST", 50, 5, 1, 3, 2, true, 3, 3, 0, 0, 8, 9, 7, 1); -- P_sq = 9 > N_rn/2+1 = 5 + u_xst_P9_N4_RN0_7_slow_mm : entity work.tb_sdp_statistics_offload generic map(false, "XST", 50, 5, 0, 1, 1, true, 3, 3, 0, 0, 8, 9, 4, 1); -- P_sq = 9 > N_rn/2+1 = 5 + u_xst_P9_N7_RN0_7_slow_mm : entity work.tb_sdp_statistics_offload generic map(false, "XST", 50, 5, 0, 1, 1, true, 3, 3, 0, 0, 8, 9, 7, 1); -- P_sq = 9 > N_rn/2+1 = 5 end tb;