Skip to content
Snippets Groups Projects
Commit 0afa54fe authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Corrected dump_inter_packet_gap versus FPGA_tbuf_dump_nof_bps_RW.

parent 52822b0e
Branches
No related tags found
No related merge requests found
Pipeline #117769 passed
......@@ -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
-----------------------------------------------------------------------------
......
......@@ -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;
......
......@@ -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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment