diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_crosslets_subband_select.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_crosslets_subband_select.vhd index 94347aaca1aeccb0c0ed9efed5a10b24fbc668e3..2cc902a393ad0a179fe76657d4931681ca520549 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_crosslets_subband_select.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_crosslets_subband_select.vhd @@ -105,6 +105,13 @@ ARCHITECTURE str OF sdp_crosslets_subband_select IS SIGNAL crosslets_info_reg_in : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0'); SIGNAL active_crosslets_info : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0'); SIGNAL i_out_crosslets_info : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0'); + + -- Map crosslets_info slv to record for easier view in Wave window + SIGNAL crosslets_info_rec : t_sdp_crosslets_info; + SIGNAL crosslets_info_rec_inout : t_sdp_crosslets_info; + SIGNAL active_crosslets_info_rec : t_sdp_crosslets_info; + SIGNAL out_crosslets_info_rec : t_sdp_crosslets_info; + BEGIN --------------------------------------------------------------- @@ -303,7 +310,6 @@ BEGIN output_sosi_arr(0) => row_sosi ); - --------------------------------------------------------------- -- Out Crosslet info pipeline --------------------------------------------------------------- @@ -345,4 +351,10 @@ BEGIN src_out => out_sosi ); + -- Map crosslets_info slv to record for easier view in Wave window + crosslets_info_rec <= func_sdp_map_crosslets_info(crosslets_info_reg); + crosslets_info_rec_inout <= func_sdp_map_crosslets_info(crosslets_info_reg_in); + active_crosslets_info_rec <= func_sdp_map_crosslets_info(active_crosslets_info); + out_crosslets_info_rec <= func_sdp_map_crosslets_info(i_out_crosslets_info); + END str; 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 1e66291922993df2cb3bb30081db9d6e20e7fb1c..934dbb94caddf710fb87cdda18238fa359dc3b2b 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd @@ -25,10 +25,12 @@ -- Purpose: -- . SDP statistics offload -- Description: --- https://support.astron.nl/confluence/display/L2M/L5+SDPFW+Design+Document%3A+Subband+filterbank --- . See figure 4.3 --- https://plm.astron.nl/polarion/#/project/LOFAR2System/wiki/L2%20Interface%20Control%20Documents/SC%20to%20SDP%20ICD --- . See 2.9.4 Station Control (L3-SC) - SDP Firmware (L4-SDPFW) +-- [1] https://support.astron.nl/confluence/display/L2M/L5+SDPFW+Design+Document%3A+Subband+filterbank +-- . See figure 4.3 +-- [2] https://support.astron.nl/confluence/display/L2M/L5+SDPFW+Design+Document%3A+Subband+Correlator +-- . See Figure 3.7 +-- [3] https://plm.astron.nl/polarion/#/project/LOFAR2System/wiki/L2%20Interface%20Control%20Documents/SC%20to%20SDP%20ICD +-- . See 2.9.4 Station Control (L3-SC) - SDP Firmware (L4-SDPFW) -- -- . endianess -- Within a 32bit MM word the values are stored with LSByte at lowest byte @@ -225,6 +227,7 @@ ARCHITECTURE str OF sdp_statistics_offload IS SIGNAL trigger_en : STD_LOGIC := '0'; SIGNAL trigger_offload : STD_LOGIC := '0'; SIGNAL mm_done : STD_LOGIC := '0'; + SIGNAL dp_sop : STD_LOGIC := '0'; SIGNAL dp_block_from_mm_src_out : t_dp_sosi; SIGNAL dp_block_from_mm_src_in : t_dp_siso; @@ -349,7 +352,7 @@ BEGIN data_id_slv <= func_sdp_map_stat_data_id(g_statistics_type, data_id_rec); - p_control_packet_offload : PROCESS(r, in_sosi, local_si_offset, trigger_offload, nof_crosslets, crosslets_info, nof_packets, mm_done, dp_header_info) + p_control_packet_offload : PROCESS(r, in_sosi, local_si_offset, trigger_offload, nof_crosslets, crosslets_info, nof_packets, dp_sop, dp_header_info) VARIABLE v : t_reg; VARIABLE v_index : NATURAL; BEGIN @@ -372,18 +375,33 @@ BEGIN END IF; END IF; - -- Capture nof_crosslets and crosslets_info at in_sosi.sync, to make sure - -- they do not change during packets offload. The trigger_offload occurs - -- after the nof_cycles_dly and the offload will have finished before the - -- next in_sosi.sync + + -- For XST offload capture nof_crosslets and crosslets_info at in_sosi.sync, + -- to make sure they do not change during packets offload. + -- . The sdp_crosslets_subband_select.vhd takes in [2] takes care that + -- nof_crosslets and crosslets_info are valid at the xsel_sosi.sync. The + -- mmp_dp_bsn_align_v2 in [2] then aligns the local xsel_sosi with the + -- remote data and passes on the sync. After some latency the sync + -- arrives at the sdp_statistics_offload. This latency is very short + -- compared to the sync period, so the nof_crosslets and crosslet_info + -- are still valid at the in_sosi.sync. IF in_sosi.sync = '1' THEN v.nof_crosslets := TO_UINT(nof_crosslets); v.crosslets_info_rec := func_sdp_map_crosslets_info(crosslets_info); END IF; - -- Issue start_pulse per packet offload + -- The trigger_offload occurs 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 + -- and the integration interval (= sync interval) is 1 s for SST and BST + -- and minimal 0.1s (= c_sdp_xst_nof_clk_per_sync_min) for XST. + -- The trigger_offload initializes the control for the first packet offload + -- in every sync interval. + -- . Issue a start_pulse per packet offload. The start_pulse is used by + -- u_dp_block_from_mm_dc to read the packet from statistics memory. IF trigger_offload = '1' THEN - -- Use trigger_offload to start first packet offload, all g_statistics_type start from start address 0 + -- Use trigger_offload to start first packet offload, all + -- g_statistics_type start from start address 0 v.start_pulse := '1'; v.sync := '1'; v.start_address := 0; @@ -394,8 +412,20 @@ BEGIN v.instance_count := 0; -- only used for XST v.instance_address := 0; -- only used for XST - ELSIF mm_done = '1' THEN - -- Use mm_done to start next packets offloads. + -- The dp_sop = '1' when the packet has been read from statistics memory + -- and is about to get out of the dp_fifo_fill_eop in + -- u_dp_block_from_mm_dc. The difference between dp_sop and the mm_done + -- output of u_dp_block_from_mm_dc, is that dp_sop also includes any + -- dp_fifo_fill_eop latency. 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 + -- + ELSIF dp_sop = '1' THEN + -- Release dp_header_info for current packet offload + v.dp_header_info := dp_header_info; + + -- Start next packets offload. IF r.packet_count < nof_packets - 1 THEN IF g_statistics_type = "SST" THEN -- step step step step step step @@ -444,10 +474,6 @@ BEGIN END IF; END IF; - -- Release dp_header_info per packet offload - IF trigger_offload = '1' OR mm_done = '1' THEN - v.dp_header_info := dp_header_info; - END IF; nxt_r <= v; END PROCESS; @@ -487,13 +513,24 @@ BEGIN sync_in => r.sync, bsn_at_sync => bsn_at_sync, start_address => r.start_address, - done => mm_done, + done => mm_done, -- not used, use dp_sop instead mm_mosi => master_mosi, mm_miso => master_miso, out_sosi => dp_block_from_mm_src_out, out_siso => dp_block_from_mm_src_in ); + -- Use dp_block_from_mm_src_out.sop as dp_sop, to include the + -- dp_fifo_fill_eop that is in dp_block_from_mm_dc. The dp_sop thus is the + -- sop of the packet that is about to be offloaded by u_dp_offload_tx_v3. + -- The r.dp_header_info must be available at the dp_offload_snk_in.sop. + -- This is guaranteed because: + -- . r.dp_header_info is available one clock cycle after dp_sop in + -- p_control_packet_offload. + -- . The dp_offload_snk_in is delayed also by at least one clock cycle by + -- u_dp_pipeline_ready. + dp_sop <= dp_block_from_mm_src_out.sop; + u_dp_pipeline_ready : ENTITY dp_lib.dp_pipeline_ready PORT MAP( rst => dp_rst, 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 a10f7d020e1248f294300d48213b9058b921e575..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 @@ -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 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 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 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_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,7 +314,9 @@ 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); @@ -334,9 +339,7 @@ BEGIN END IF; END PROCESS; - -- Count sync intervals using in_sosi.sync, because there is no rx_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 rx_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 <= (rx_offload_eop_cnt / g_nof_crosslets) MOD c_nof_used_P_sq; @@ -351,14 +354,14 @@ BEGIN -- 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; @@ -443,13 +446,10 @@ BEGIN END PROCESS; -- Count number of packets in a sync interval. - -- There is no active rx_offload_sosi.sync to restart the count, therefore - -- use in_sosi.sync to reset the count for the next rx_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 rx_offload_sosi.eop = '1' THEN rx_packet_cnt <= rx_packet_cnt + 1; @@ -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; @@ -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; @@ -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 <= sdp_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; 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 0d3f42ce3fd8ebfd344e86d101ddc1a301d05b49..e017be43252f7e9fc1151b48ae864e896902c597 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 @@ -38,10 +38,13 @@ ARCHITECTURE tb OF tb_tb_sdp_statistics_offload IS 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_statistics_type : STRING := "SST"; -- g_offload_time : NATURAL := 500; -- 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_nof_sync : NATURAL := 3; -- -- BST -- g_beamset_id : NATURAL := 0; -- -- XST @@ -51,19 +54,21 @@ BEGIN -- 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, TRUE, 3, 0, 0); - u_sst_no_reverse : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("SST", 50, FALSE, 3, 0, 0); - u_bst_0 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("BST", 50, TRUE, 1, 0, 0); - u_bst_0_no_reverse : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("BST", 50, FALSE, 1, 0, 0); - u_bst_1 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("BST", 50, TRUE, 1, 1, 0); - u_xst_P1 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, TRUE, 1, 0, 0, 16, 1, 1, 1); - u_xst_P1_N3 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, TRUE, 1, 0, 0, 16, 1, 3, 1); - u_xst_P9 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, TRUE, 1, 0, 0, 16, 9, 1, 1); - u_xst_P9_N3 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, TRUE, 1, 0, 0, 16, 9, 3, 1); - u_xst_P9_N3_no_reverse : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, FALSE, 1, 0, 0, 16, 9, 3, 1); - u_xst_P9_N3_neg : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, TRUE, 1, 0, 0, 16, 9, 3, 0); - u_xst_P8_N7_RN1_15 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, TRUE, 1, 0, 1, 15, 8, 7, 0); - u_xst_P1_N7_RN0_7 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, TRUE, 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("XST", 50, TRUE, 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, TRUE, 3, 3); + u_sst_no_reverse : ENTITY work.tb_sdp_statistics_offload GENERIC MAP( TRUE, "SST", 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 END tb; diff --git a/libraries/base/dp/src/vhdl/dp_block_from_mm_dc.vhd b/libraries/base/dp/src/vhdl/dp_block_from_mm_dc.vhd index 71706eaeff9b0980e4c9e37e4de58433271695ef..86189e162cc1f7c9ccc80c94795eac7f32d9a7f4 100644 --- a/libraries/base/dp/src/vhdl/dp_block_from_mm_dc.vhd +++ b/libraries/base/dp/src/vhdl/dp_block_from_mm_dc.vhd @@ -65,8 +65,13 @@ END dp_block_from_mm_dc; ARCHITECTURE str OF dp_block_from_mm_dc IS - CONSTANT c_packet_size : NATURAL := g_nof_data * g_data_size; -- 512 * 2 = 1024 words. - CONSTANT c_fifo_size : NATURAL := c_packet_size * 2; + CONSTANT c_packet_size : NATURAL := g_nof_data * g_data_size; + + -- Fit one packet in FIFO, and less than two, to avoid filling the FIFO with + -- multiple packets in case writing FIFO (mm_clk) is faster than reading + -- FIFO (dp_clk). + CONSTANT c_fifo_fill : NATURAL := c_packet_size; + CONSTANT c_fifo_size : NATURAL := c_packet_size + c_packet_size/2; CONSTANT c_start_addr_w : NATURAL := c_natural_w; CONSTANT c_delay_len : NATURAL := c_meta_delay_len; @@ -152,7 +157,7 @@ BEGIN g_bsn_w => g_bsn_w, g_use_bsn => TRUE, g_use_sync => TRUE, - g_fifo_fill => c_packet_size, + g_fifo_fill => c_fifo_fill, g_fifo_size => c_fifo_size ) PORT MAP (