diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_tbuf_one/tb_lofar2_unb2c_sdp_station_tbuf_one.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_tbuf_one/tb_lofar2_unb2c_sdp_station_tbuf_one.vhd index 338e89fe3f66208679f904ea46de9d3e151545f1..ee307df2892c11c3c85306fcdb082956f33fa785 100644 --- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_tbuf_one/tb_lofar2_unb2c_sdp_station_tbuf_one.vhd +++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_tbuf_one/tb_lofar2_unb2c_sdp_station_tbuf_one.vhd @@ -114,6 +114,11 @@ architecture tb of tb_lofar2_unb2c_sdp_station_tbuf_one is 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_verify_err : boolean := g_verify_crc_error or g_verify_rsn_error; + constant c_Gbps : real := 10.0**9; + + -- Optional try read input data_buffer, requires sync interval to be longer than the data_buffer size (= 1024 + -- samples) and to be sufficiently long so that it does not get rewritten while it is being read. + constant c_read_data_buffer_en : boolean := false; constant c_design_name : string := sel_a_b(g_use_bf, "lofar2_unb2c_sdp_station_lift", "lofar2_unb2c_sdp_station_tbuf_one"); @@ -146,7 +151,8 @@ architecture tb of tb_lofar2_unb2c_sdp_station_tbuf_one is constant c_rs_nof_clk_per_sync : natural := c_rs_nof_block_per_sync * g_rs_block_size; -- Buffer size - constant c_ddr_buffer_size : natural := sel_a_b(g_verify_crc_error, 4096, g_ddr_buffer_size); + constant c_ddr_buffer_size : natural := sel_a_b(g_verify_crc_error or g_rs_block_size > g_ddr_buffer_size, + 4096, g_rs_block_size); constant c_sim_sdp_tbuf : t_sdp_tbuf_sim := (c_rs_nof_clk_per_sync, c_bs_block_size, g_rs_block_size, @@ -164,9 +170,9 @@ architecture tb of tb_lofar2_unb2c_sdp_station_tbuf_one is constant c_record_min_nof_pages : natural := g_dump_page_offset + c_dump_nof_pages_rw; constant c_record_min_nof_clk : natural := c_bs_start_latency + g_rs_block_size * c_record_min_nof_pages; - constant c_exp_read_rate_Gbps : real := func_sdp_tbuf_dump_rate_bps(g_rs_block_size, g_dump_inter_packet_gap) / - 10.0**9; - constant c_exp_dump_rate_Gbps : real := sel_a_b(c_verify_err, 0.0, c_exp_read_rate_Gbps); + constant c_exp_read_rate_bps : real := func_sdp_tbuf_calculate_dump_rate_bps(g_rs_block_size, + g_dump_inter_packet_gap); + constant c_exp_dump_rate_bps : real := sel_a_b(c_verify_err, 0.0, c_exp_read_rate_bps); constant c_dump_rate_delta : real := 0.05; -- = 5 % constant c_dump_nof_ai : natural := vector_sum(g_dump_enables); @@ -259,10 +265,12 @@ architecture tb of tb_lofar2_unb2c_sdp_station_tbuf_one is constant c_mm_span_reg_diag_wg : natural := 2**c_addr_w_reg_diag_wg; constant c_addr_w_reg_aduh_monitor : natural := 2; constant c_mm_span_reg_aduh_monitor : natural := 2**c_addr_w_reg_aduh_monitor; + constant c_mm_span_ram_diag_data_buffer : natural := c_sdp_V_si_db; -- as used in sdp_station.vhd 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_ram_diag_data_buffer : string := c_mmf_prefix & "RAM_DIAG_DATA_BUFFER_BSN"; constant c_mm_file_reg_aduh_mon : string := c_mmf_prefix & "REG_ADUH_MONITOR"; 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"; @@ -313,6 +321,7 @@ architecture tb of tb_lofar2_unb2c_sdp_station_tbuf_one is signal rd_data_control : std_logic_vector(c_32 - 1 downto 0); signal rd_data_monitor : std_logic_vector(c_32 - 1 downto 0); signal rd_data_bsn : std_logic_vector(c_32 - 1 downto 0); + signal rd_data_data_buffer : std_logic_vector(c_32 - 1 downto 0); signal rd_data_record_busy : std_logic_vector(c_32 - 1 downto 0); signal rd_data_dump_done : std_logic_vector(c_32 - 1 downto 0); signal rd_data_strobe : std_logic_vector(c_32 - 1 downto 0); @@ -344,6 +353,9 @@ architecture tb of tb_lofar2_unb2c_sdp_station_tbuf_one is signal sp_power_sum : std_logic_vector(63 downto 0); signal current_bsn_wg : std_logic_vector(c_dp_stream_bsn_w - 1 downto 0); + -- Data buffer + signal data_buffer_arr : t_integer_arr(0 to c_sdp_V_si_db - 1) := (others => 0); + -- TBuf signal tbuf_registers_wr : t_sdp_tbuf_registers_rw; signal tbuf_registers_rd : t_sdp_tbuf_registers_rw; -- read (rd) of write (wr) @@ -354,10 +366,10 @@ architecture tb of tb_lofar2_unb2c_sdp_station_tbuf_one is signal dump_index : natural; signal time_index : natural; signal read_busy : std_logic := '0'; - signal dump_rate_Gbps : real := 0.0; + signal dump_rate_bps : real := 0.0; - signal dbg_c_exp_read_rate_Gbps : real := c_exp_read_rate_Gbps; - signal dbg_c_exp_dump_rate_Gbps : real := c_exp_dump_rate_Gbps; + signal dbg_c_exp_read_rate_bps : real := c_exp_read_rate_bps; + signal dbg_c_exp_dump_rate_bps : real := c_exp_dump_rate_bps; signal dbg_c_dump_nof_ai : natural := c_dump_nof_ai; signal dbg_c_dump_ai_indices : t_nat_integer_arr(g_dump_enables'range) := c_dump_ai_indices; signal dbg_c_read_nof_packets_per_ai : natural := c_read_nof_packets_per_ai; @@ -633,6 +645,7 @@ begin ------------------------------------------------------------------------------ p_mm_setup : process variable v_offset : natural; + variable v_addr : natural; variable v_norm_ampl : real; variable v_bsn : natural; variable v_sp_power_sum : real; @@ -860,8 +873,8 @@ begin --------------------------------------------------------------------------- -- Verify sp_power_sum --------------------------------------------------------------------------- - -- Read ADUH monitor power sum for SP = g_sp if g_sp < c_sdp_S_pn then + -- Read ADUH monitor power sum for SP = g_sp v_offset := g_sp * c_mm_span_reg_aduh_monitor; mmf_mm_bus_rd(c_mm_file_reg_aduh_mon, v_offset + 2, rd_data_setup, tb_clk); -- read low part sp_power_sum(31 downto 0) <= rd_data_setup; @@ -878,6 +891,18 @@ begin assert v_sp_power_sum < c_sp_power_hi_factor * c_exp_wg_power_sum report c_tb_str & "Wrong SP power for SP 0" severity ERROR; + + if c_read_data_buffer_en then + -- Read diag_ram_data_buffer rd_data_data_buffer + v_offset := g_sp * c_mm_span_ram_diag_data_buffer; + for I in 0 to c_sdp_V_si_db - 1 loop + v_addr := v_offset + I; + mmf_mm_bus_rd(c_mm_file_ram_diag_data_buffer, v_addr, rd_data_data_buffer, tb_clk); + data_buffer_arr(I) <= to_sint(rd_data_data_buffer(c_sdp_W_adc - 1 downto 0)); + --print_str(c_tb_str & "diag_data_buffer[" & int_to_str(v_addr) & "] = " & + -- int_to_str(to_sint(rd_data_data_buffer))); + end loop; + end if; end if; --------------------------------------------------------------------------- @@ -894,7 +919,7 @@ begin variable v_Begin : natural; variable v_End : natural; variable v_Period : real := 0.0; - variable v_dump_rate_Gbps : real := 0.0; + variable v_dump_rate_bps : real := 0.0; variable v_dump_start_page : natural; variable v_dump_start_rsn : std_logic_vector(c_sdp_W_rsn - 1 downto 0); begin @@ -909,6 +934,10 @@ 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(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)); ---------------------------------------------------------------------------- -- Read DDR4 FIFOs status @@ -1187,18 +1216,18 @@ begin read_busy <= '0'; v_End := NOW / c_1ns; v_Period := real(v_End - v_Begin); -- dump time in ns - v_dump_rate_Gbps := real(c_dump_total_nof_packets * c_sdp_W_ant * g_rs_block_size) / v_Period; - dump_rate_Gbps <= v_dump_rate_Gbps; + v_dump_rate_bps := real(c_dump_total_nof_packets * c_sdp_W_ant * g_rs_block_size) / v_Period; + dump_rate_bps <= v_dump_rate_bps; -- Verify dump rate over sufficient number of packets if c_dump_total_nof_packets > 5 and g_ddr_access_rate_pct = 100 then -- . use almost_equal(a/b, 1.0, max_ratio) to verify that a and b differ less than max_ratio/100 percent - assert almost_equal(v_dump_rate_Gbps / c_exp_dump_rate_Gbps, 1.0, c_dump_rate_delta) + assert almost_equal(v_dump_rate_bps / c_exp_dump_rate_bps, 1.0, c_dump_rate_delta) report c_tb_str & "Wrong dump rate" severity ERROR; end if; - print_str(c_tb_str & "Dump rate = " & real_to_str(v_dump_rate_Gbps, 4, 2) & " Gbps" & - " (Expected " & real_to_str(c_exp_dump_rate_Gbps, 4, 2) & " Gbps)"); + 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; -- Wait some time for latency in sdp_tbuf_output and 10GbE Tx - Rx network @@ -1304,6 +1333,60 @@ begin wait; end process; + ----------------------------------------------------------------------------- + -- Verify inter packet gap and bps + -- . verify func_sdp_tbuf_calculate_dump_rate_bps() --> func_sdp_tbuf_calculate_dump_inter_packet_gap() + -- . verify func_sdp_tbuf_calculate_dump_inter_packet_gap() --> func_sdp_tbuf_calculate_dump_rate_bps() + ----------------------------------------------------------------------------- + p_verify_gap_bps : process + constant c_repeat : natural := 100; + constant c_gap_step : natural := largest(1, g_rs_block_size / c_repeat); + constant c_bps_step : real := 10.0 * c_Gbps / real(c_repeat); + constant c_bps_margin : real := c_bps_step / 2.0; + constant c_bps_max : real := c_sdp_tbuf_reader_bps_max * + real(g_rs_block_size) / + real(g_rs_block_size + c_sdp_tbuf_gap_offset); + variable v_G : natural; + variable v_B : real; + variable v_bps : real; + variable v_gap : natural; + begin + wait for 1 ns; + -- Verify gap to bps to gap + for G in 0 to c_repeat loop + v_G := G * c_gap_step; + v_bps := func_sdp_tbuf_calculate_dump_rate_bps(g_rs_block_size, v_G); + v_gap := func_sdp_tbuf_calculate_dump_inter_packet_gap(g_rs_block_size, v_bps); + assert v_gap = v_G + report c_tb_str & "Wrong gap = " & int_to_str(v_G) & + " to Gbps = " & real_to_str(v_bps / c_Gbps, 5, 3) & + " to gap = " & int_to_str(v_gap) + severity ERROR; + end loop; + wait for 1 ns; + + -- Verify bps to gap to bps + for B in 1 to c_repeat loop + v_B := real(B) * c_bps_step; + v_gap := func_sdp_tbuf_calculate_dump_inter_packet_gap(g_rs_block_size, v_B); + v_bps := func_sdp_tbuf_calculate_dump_rate_bps(g_rs_block_size, v_gap); + if v_bps < c_bps_max then + assert almost_equal(v_B, v_bps, c_bps_margin) + report c_tb_str & "Wrong Gbps = " & real_to_str(v_B / c_Gbps, 5, 3) & + " to gap = " & int_to_str(v_gap) & + " to Gbps = " & real_to_str(v_bps / c_Gbps, 5, 3) + severity ERROR; + else + assert almost_equal(v_bps, c_bps_max, c_bps_margin) + report c_tb_str & "Wrong Gbps = " & real_to_str(v_B / c_Gbps, 5, 3) & + " to gap = " & int_to_str(v_gap) & + " to max Gbps = " & real_to_str(c_bps_max / c_Gbps, 5, 3) + severity ERROR; + end if; + end loop; + wait; + end process; + ----------------------------------------------------------------------------- -- Verify TBuf dump packet header ----------------------------------------------------------------------------- diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_tbuf_pkg.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_tbuf_pkg.vhd index 8a50fed7d6945bba5c6ca11997eeff18937c76d1..cf573ffab2ca4bda6349187e4130cc348682e506 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_tbuf_pkg.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_tbuf_pkg.vhd @@ -38,7 +38,7 @@ package sdp_tbuf_pkg is ----------------------------------------------------------------------------- -- SDP TBuf specific parameters ----------------------------------------------------------------------------- - constant c_sdp_tbuf_rs_block_size : natural := 2000; -- = N_blk, nof time samples per raw data block + constant c_sdp_tbuf_rs_block_size : natural := 2000; -- = N_rs, nof time samples per raw data block constant c_sdp_tbuf_W_word : natural := 512; -- nof bits per DDR4 memory word constant c_sdp_tbuf_all_data_w : natural := c_sdp_A_pn * c_sdp_W_ant; -- = 6 * 28 = 168 constant c_sdp_tbuf_all_meta_w : natural := c_sdp_tbuf_all_data_w + c_sdp_W_rsn; -- = 168 + 64 = 232 @@ -128,16 +128,16 @@ package sdp_tbuf_pkg is -- smallest block size of 400 samples when record_all = '0'. -- = ceil_log2(256MiB / 64) = ceil_log2(4MiB) - -- The sdp_tbuf_reader adds an interpacket gap of about c_sdp_tbuf_inter_packet_gap_offset = 25 dp_clk due to - -- latency in fsm and in ant_validate_sosi and due to clock domain crossing of the read burstbegin and latency in - -- io_ddr. The maximum rate is c_sdp_W_ant * c_sdp_f_adc_MHz = 28b * 200 = 5.6 Gbps. For a g_rs_block_size = 100 - -- this becomes 5.6G * 100 / (100 + 25) ~= 4.5 Gbps, for g_rs_block_size = 2000 as on HW this becomes 5.6G * 2000 / - -- (2000 + 25) ~= 5.5 Gbps. + -- The sdp_tbuf_reader adds an interpacket gap of about c_sdp_tbuf_gap_offset = 25 dp_clk due to latency in fsm and + -- in ant_validate_sosi and due to clock domain crossing of the read burstbegin and latency in io_ddr. The maximum + -- rate is c_sdp_tbuf_reader_bps_max = 5.6 Gbps. For a g_rs_block_size = 100 this becomes 5.6G * 100 / (100 + 25) + -- ~= 4.5 Gbps, for g_rs_block_size = 2000 as on HW this becomes 5.6G * 2000 / (2000 + 25) ~= 5.5 Gbps. -- Choose c_sdp_tbuf_gap_size_min = 0 for full link rate bps of almost 5.6 Gbps. Choose c_sdp_tbuf_gap_size_max = -- 200M = 1 s for dp_clk at 200 MHz, to ensure at least one dump packet per second. constant c_sdp_tbuf_gap_size_min : natural := 0; constant c_sdp_tbuf_gap_size_max : natural := c_sdp_N_clk_per_second; constant c_sdp_tbuf_gap_offset : natural := 25; + constant c_sdp_tbuf_reader_bps_max : real := real(c_sdp_W_ant * c_sdp_f_adc_MHz) * 10.0**6; -- = 5.6 Gbps -- 'to' order as in document [1] to ease view in wave window -- . RW control registers @@ -216,6 +216,8 @@ package sdp_tbuf_pkg is -- = 66 + 7000 = 7066 octets constant c_sdp_tbuf_packet_nof_longwords : natural := ceil_div(c_sdp_tbuf_packet_len, c_longword_sz); -- = 7066 / 8 = 883.25 = 884 + -- Account for the packet header length assuming c_longword_sz words in the dp_clk domain. + constant c_sdp_tbuf_dp_header_size : natural := ceil_div(c_sdp_tbuf_header_len, c_longword_sz); -- = 9 -- TBuf packet header constant c_sdp_tbuf_nof_hdr_fields : natural := 3 + 12 + 4 + 4 + 5 + 3 + 1; -- = 32 fields @@ -317,7 +319,6 @@ package sdp_tbuf_pkg is function func_sdp_tbuf_calculate_nof_pages(buffer_size, page_size : natural) return natural; function func_sdp_tbuf_increment_page_address(page_address, buffer_size, page_size : natural) return natural; function func_sdp_tbuf_limit_dump_inter_packet_gap(gap_size : natural) return natural; - function func_sdp_tbuf_dump_rate_bps(rs_block_size, gap_size : natural) return real; function func_sdp_tbuf_fsm_arbiter_to_slv(fsm : t_sdp_tbuf_fsm_arbiter) return std_logic_vector; function func_sdp_tbuf_fsm_writer_to_slv(fsm : t_sdp_tbuf_fsm_writer) return std_logic_vector; @@ -427,26 +428,19 @@ package body sdp_tbuf_pkg is begin -- Check maximum dump bit rate if gap_size < c_sdp_tbuf_gap_size_min then - report "Too high requested link_bps for internal clock rate" + report "Too small gap_size < c_sdp_tbuf_gap_size_min" severity warning; return c_sdp_tbuf_gap_size_min; end if; -- Check minimum dump bit rate if gap_size > c_sdp_tbuf_gap_size_max then - report "Too low requested link_bps" + report "Too large gap_size > c_sdp_tbuf_gap_size_max" severity warning; return c_sdp_tbuf_gap_size_max; end if; return gap_size; end func_sdp_tbuf_limit_dump_inter_packet_gap; - function func_sdp_tbuf_dump_rate_bps(rs_block_size, gap_size : natural) return real is - -- Purpose: Estimate dump rate in bps - begin - return real(c_sdp_W_ant * c_sdp_f_adc_MHz * rs_block_size) * 10.0**6 / - real(rs_block_size + c_sdp_tbuf_gap_offset + gap_size); - end func_sdp_tbuf_dump_rate_bps; - -- Map FSM state value independent of synthesis state value mapping function func_sdp_tbuf_fsm_arbiter_to_slv(fsm : t_sdp_tbuf_fsm_arbiter) return std_logic_vector is constant c_fsm_w : natural := 2; diff --git a/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_tbuf_pkg.vhd b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_tbuf_pkg.vhd index 7be2601fd9294a70e849e1eb1aae5ec0ae66ce0d..70b993c19bc54dfaef7dfbea79d03364b8926a2e 100644 --- a/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_tbuf_pkg.vhd +++ b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_tbuf_pkg.vhd @@ -37,7 +37,8 @@ library IEEE, common_lib, dp_lib; use work.sdp_tbuf_pkg.all; package tb_sdp_tbuf_pkg is - function func_sdp_tbuf_calculate_dump_inter_packet_gap(packet_len, link_bps : natural) return natural; + function func_sdp_tbuf_calculate_dump_inter_packet_gap(rs_block_size : natural; link_bps : real) return natural; + function func_sdp_tbuf_calculate_dump_rate_bps(rs_block_size, gap_size : natural) return real; function func_sdp_tbuf_fsm_arbiter_str(fsm_arbiter : natural) return string; function func_sdp_tbuf_fsm_writer_str(fsm_writer : natural) return string; @@ -60,31 +61,37 @@ package tb_sdp_tbuf_pkg is end package tb_sdp_tbuf_pkg; package body tb_sdp_tbuf_pkg is - function func_sdp_tbuf_calculate_dump_inter_packet_gap(packet_len, link_bps : natural) return natural is - -- Purpose: Use interpacket gap to set link data rate of the transient dump + function func_sdp_tbuf_calculate_dump_inter_packet_gap(rs_block_size : natural; link_bps : real) return natural is + -- Purpose: Use interpacket gap to set link data rate link_bps of the transient dump. -- Description: - -- Calculate the gap size in number of clk cycles between packets, to fit the packet rate within the available - -- link bit rate. - -- Input: - -- . app_packet_len : packet length in octets, c_sdp_tbuf_packet_len - -- . link_bps : available bit rate on the link, < 10 * 10**9 bit per second (bps) - -- Return: - -- . gap_size : number of clock cycles between packets to achieve link_bps. - -- - -- Packet period in nof clk - constant c_packet_nof_bits : natural := packet_len * c_octet_w; -- 7066 * 8 = 56528 - constant c_nof_packets_per_s : natural := link_bps / c_packet_nof_bits; -- 10**10 / 56528 = 176903 - constant c_nof_clk_per_period : natural := c_sdp_N_clk_per_second / c_nof_packets_per_s; - -- 200000000 / 176903 = 1130 - -- Packet duration in nof clk - constant c_packet_nof_words : natural := ceil_div(packet_len, c_longword_sz); -- 7066 / 8 = 884 - constant c_nof_clk_per_packet : natural := c_packet_nof_words; - -- Inter packet gap - constant c_gap_size : integer := c_nof_clk_per_period - c_nof_clk_per_packet; -- = 1130 - 884 = 246 + -- Estimate dump inter packet gap in sdp_tbuf_reader from requested link_bps. The maximum link_bps is limited + -- by the read access rate in the sdp_tbuf_reader and is maximum c_sdp_tbuf_reader_bps_max = 5.6 Gbps. Hence + -- the link_bps is not limited by the 10 Gbps of the 10GbE output link. + variable v_period : real; + variable v_gap : integer := 0; begin - return func_sdp_tbuf_limit_dump_inter_packet_gap(c_gap_size); + -- This func_sdp_tbuf_calculate_dump_inter_packet_gap() is inverse of func_sdp_tbuf_calculate_dump_rate_bps(). + v_period := (c_sdp_tbuf_reader_bps_max / link_bps - 1.0) * real(rs_block_size); + v_gap := integer(v_period) - c_sdp_tbuf_gap_offset; + if v_gap < 0 then + v_gap := 0; + elsif v_gap > c_sdp_tbuf_gap_size_max then + v_gap := c_sdp_tbuf_gap_size_max; + end if; + return v_gap; end func_sdp_tbuf_calculate_dump_inter_packet_gap; + function func_sdp_tbuf_calculate_dump_rate_bps(rs_block_size, gap_size : natural) return real is + -- Purpose: Estimate dump rate in bps from inter packet gap in sdp_tbuf_reader. + -- The link_bps is limited by the maximum read data rate from DDR4 memory in sdp_tbuf_reader.vhd. The read data + -- rate is W_ant = 28 bits per dp_clk cycle. There is a minimum delay of c_sdp_tbuf_gap_offset between page reads. + variable v_link_bps : real; + begin + v_link_bps := c_sdp_tbuf_reader_bps_max * real(rs_block_size) / + real(rs_block_size + c_sdp_tbuf_gap_offset + gap_size); + return v_link_bps; + end func_sdp_tbuf_calculate_dump_rate_bps; + function func_sdp_tbuf_fsm_arbiter_str(fsm_arbiter : natural) return string is begin case fsm_arbiter is