From eba962b7001f2884d3f28128eaea0ad09ed96682 Mon Sep 17 00:00:00 2001 From: Eric Kooistra <kooistra@astron.nl> Date: Tue, 29 Apr 2025 14:32:42 +0200 Subject: [PATCH] Verify g_dump_nof_pages = 0. --- .../tb_lofar2_unb2c_sdp_station_tbuf_one.vhd | 133 ++++++++++-------- ...b_tb_lofar2_unb2c_sdp_station_tbuf_one.vhd | 6 +- .../sdp/src/vhdl/sdp_tbuf_reader.vhd | 10 +- 3 files changed, 81 insertions(+), 68 deletions(-) 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 1ea793cfff..338e89fe3f 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 @@ -98,9 +98,9 @@ entity tb_lofar2_unb2c_sdp_station_tbuf_one is g_rs_nof_periods_per_block : real := 1.17; -- number of WG periods per rs_block for WG in g_sp g_dump_inter_packet_gap : natural := 0; g_dump_page_offset : natural := 1; -- offset relative to recorded_first_page - g_dump_nof_pages : natural := 2; -- g_dump_page_offset + g_dump_nof_pages <= c_nof_pages_in_buffer, else + g_dump_nof_pages : natural := 1; -- g_dump_page_offset + g_dump_nof_pages <= c_nof_pages_in_buffer, else -- there will occur read RSN errors for pages that are not available - g_dump_enables : std_logic_vector(c_sdp_A_pn - 1 downto 0) := "000010" + g_dump_enables : std_logic_vector(c_sdp_A_pn - 1 downto 0) := "100010" ); port ( tb_end : out std_logic @@ -1154,50 +1154,52 @@ begin proc_common_wait_cross_clock_domain_latency( c_mm_clk_period, c_ext_clk_period, c_common_cross_clock_domain_latency * 2); - -- Time dump begin - read_busy <= '1'; - v_Begin := NOW / c_1ns; - proc_common_wait_some_cycles(tb_clk, 1); - - -- Read back enabled dump - mmf_mm_bus_rd(c_mm_file_reg_tbuf, 16, rd_data_control, tb_clk); - tbuf_registers_rd.dump_enables <= rd_data_control(c_sdp_A_pn - 1 downto 0); - proc_common_wait_some_cycles(tb_clk, 1); - assert to_uint(tbuf_registers_rd.dump_enables) = to_uint(tbuf_registers_wr.dump_enables) - report c_tb_str & "Wrong tbuf_registers_rd.dump_enables enabled" - severity ERROR; - print_str(c_tb_str & "tbuf_registers_rd.dump_enables = " & slv_to_str(tbuf_registers_rd.dump_enables)); - - -- Read DDR4 read FIFO status - proc_common_wait_some_cycles(ext_clk, 10); - proc_read_ddr4_rd_fifo_status(tb_clk, rd_data_fifo, ddr_rd_fifo_used, ddr_rd_fifo_full); - - ---------------------------------------------------------------------------- - -- Wait until dump is done - ---------------------------------------------------------------------------- - mmf_mm_wait_until_value( - c_mm_file_reg_tbuf, 17, -- read dump_done - "UNSIGNED", rd_data_dump_done, "=", 1, -- this is the wait until condition - c_T_rd_interval, ext_clk); - tbuf_registers_ro.dump_done <= rd_data_dump_done(0); - proc_common_wait_some_cycles(tb_clk, 1); + if g_dump_nof_pages > 0 then + -- Time dump begin + read_busy <= '1'; + v_Begin := NOW / c_1ns; + proc_common_wait_some_cycles(tb_clk, 1); - -- Time dump end - 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; - - -- 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) - report c_tb_str & "Wrong dump rate" + -- Read back enabled dump + mmf_mm_bus_rd(c_mm_file_reg_tbuf, 16, rd_data_control, tb_clk); + tbuf_registers_rd.dump_enables <= rd_data_control(c_sdp_A_pn - 1 downto 0); + proc_common_wait_some_cycles(tb_clk, 1); + assert to_uint(tbuf_registers_rd.dump_enables) = to_uint(tbuf_registers_wr.dump_enables) + report c_tb_str & "Wrong tbuf_registers_rd.dump_enables enabled" severity ERROR; + print_str(c_tb_str & "tbuf_registers_rd.dump_enables = " & slv_to_str(tbuf_registers_rd.dump_enables)); + + -- Read DDR4 read FIFO status + proc_common_wait_some_cycles(ext_clk, 10); + proc_read_ddr4_rd_fifo_status(tb_clk, rd_data_fifo, ddr_rd_fifo_used, ddr_rd_fifo_full); + + ---------------------------------------------------------------------------- + -- Wait until dump is done + ---------------------------------------------------------------------------- + mmf_mm_wait_until_value( + c_mm_file_reg_tbuf, 17, -- read dump_done + "UNSIGNED", rd_data_dump_done, "=", 1, -- this is the wait until condition + c_T_rd_interval, ext_clk); + tbuf_registers_ro.dump_done <= rd_data_dump_done(0); + proc_common_wait_some_cycles(tb_clk, 1); + + -- Time dump end + 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; + + -- 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) + 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)"); 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)"); -- Wait some time for latency in sdp_tbuf_output and 10GbE Tx - Rx network proc_common_wait_some_cycles(ext_clk, g_rs_block_size * 4); @@ -1327,26 +1329,33 @@ begin variable v_bool : boolean; begin wait until rising_edge(ext_clk); - -- Count rx_dump_sosi packets at sop - if rx_dump_sosi.sop = '1' then - rx_dump_packet_cnt <= rx_dump_packet_cnt + 1; - - -- Determine expected antenna_input_index assuming c_dump_nof_packets_per_ai per ai - v_dump_index := rx_dump_packet_cnt / c_dump_nof_packets_per_ai; - v_ai_local := c_dump_ai_indices(v_dump_index); - exp_dump_ai <= c_ai_offset + v_ai_local; - - -- Determine expected RSN assuming c_dump_nof_packets_per_ai per ai - v_time_index := rx_dump_packet_cnt mod c_dump_nof_packets_per_ai; - exp_dp_rsn <= to_uint(tbuf_registers_wr.dump_start_rsn) + v_time_index * g_rs_block_size; - end if; - -- Verify header at eop - if rx_dump_sosi.eop = '1' then - v_bool := func_sdp_tbuf_verify_cep_header(rx_dump_header, exp_dump_header); + if c_dump_nof_packets_per_ai > 0 then + -- Count rx_dump_sosi packets at sop + if rx_dump_sosi.sop = '1' then + rx_dump_packet_cnt <= rx_dump_packet_cnt + 1; + + -- Determine expected antenna_input_index assuming c_dump_nof_packets_per_ai per ai + v_dump_index := rx_dump_packet_cnt / c_dump_nof_packets_per_ai; + v_ai_local := c_dump_ai_indices(v_dump_index); + exp_dump_ai <= c_ai_offset + v_ai_local; + + -- Determine expected RSN assuming c_dump_nof_packets_per_ai per ai + v_time_index := rx_dump_packet_cnt mod c_dump_nof_packets_per_ai; + exp_dp_rsn <= to_uint(tbuf_registers_wr.dump_start_rsn) + v_time_index * g_rs_block_size; + end if; + -- Verify header at eop + if rx_dump_sosi.eop = '1' then + v_bool := func_sdp_tbuf_verify_cep_header(rx_dump_header, exp_dump_header); + end if; + -- View variables in Wave Window + dump_index <= v_dump_index; + time_index <= v_time_index; + else + -- Expect no dump packets when g_dump_nof_pages = 0 + assert rx_dump_sosi.sop = '0' + report c_tb_str & "Wrong unexpected rx_dump_sosi packet for g_dump_nof_pages = 0" + severity ERROR; end if; - -- View variables in Wave Window - dump_index <= v_dump_index; - time_index <= v_time_index; end process; ----------------------------------------------------------------------------- diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_tbuf_one/tb_tb_lofar2_unb2c_sdp_station_tbuf_one.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_tbuf_one/tb_tb_lofar2_unb2c_sdp_station_tbuf_one.vhd index 842467a3f5..6d65f8569b 100644 --- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_tbuf_one/tb_tb_lofar2_unb2c_sdp_station_tbuf_one.vhd +++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_tbuf_one/tb_tb_lofar2_unb2c_sdp_station_tbuf_one.vhd @@ -35,7 +35,7 @@ end tb_tb_lofar2_unb2c_sdp_station_tbuf_one; architecture tb of tb_tb_lofar2_unb2c_sdp_station_tbuf_one is -- Multi tb - constant c_tb_w : natural := 10; -- sufficiently long to fit all tb instances + constant c_tb_w : natural := 11; -- sufficiently long to fit all tb instances constant c_tb_end_vec : std_logic_vector(c_tb_w - 1 downto 0) := (others => '1'); signal tb_end_vec : std_logic_vector(c_tb_w - 1 downto 0) := c_tb_end_vec; -- best view as hex in Wave Window @@ -109,6 +109,10 @@ begin generic map(false, 9, false, false, false, false, 3, 100, 256, 100, 10, 1.17, 0, 6, 1, "000010") port map (tb_end_vec(9)); + u_dump_zero_pages : entity work.tb_lofar2_unb2c_sdp_station_tbuf_one + generic map(false, 10, false, false, false, false, 3, 100, 256, 102, 10, 1.0, 0, 1, 0, "100010") + port map (tb_end_vec(10)); + tb_end <= '1' after 1 us when tb_end_vec = c_tb_end_vec else '0'; proc_common_stop_simulation(tb_end); end tb; diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_tbuf_reader.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_tbuf_reader.vhd index df2f73a7d7..5bc156427f 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_tbuf_reader.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_tbuf_reader.vhd @@ -336,17 +336,17 @@ begin v.dump_done := '0'; v.dump_start_rsn := reg_dump_start_rsn_rw; v.dump_start_page := reg_dump_start_page_rw; + v.dump_nof_pages := reg_dump_nof_pages_rw; if v.dump_start_page >= c_nof_pages_in_buffer then - -- Force to recovery value within buffer range, this will lead to read RSN errors due to mismatch with - -- dump_start_rsn. + -- Start page not in buffer range, cannot do dump. v.dump_start_page := 0; + v.dump_nof_pages := 0; end if; - v.dump_nof_pages := reg_dump_nof_pages_rw; if v.dump_nof_pages >= c_nof_pages_in_buffer then - -- Limit to buffer size + -- Limit nof pages to buffer size v.dump_nof_pages := c_nof_pages_in_buffer; end if; - if dump_en = '1' then + if dump_en = '1' and r.dump_nof_pages > 0 then v.latency_cnt := c_start_latency; v.fsm := s_dump_start; end if; -- GitLab