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

Support header - data block boundary at symbol level (for g_symbol_w <= g_data_w) via g_symbol_w.

parent b45e5fb2
No related branches found
No related tags found
1 merge request!190Resolve L2SDP-210
Pipeline #23631 passed
......@@ -19,21 +19,25 @@
--
-------------------------------------------------------------------------------
-- Author: D. van der Schuur, E. Kooistra
-- Purpose:
-- . Concatenate a user-defined header to a DP frame e.g. to create an Ethernet frame
-- . Concatenate a user-defined header to a data block e.g. to create an Eth
-- frame
-- Description:
-- . The header contents can be controlled dynamically by data path or MM control (selected by g_hdr_field_sel)
-- . The header and data can be concatened at symbol level. The g_symbol_w defines the
-- resolution of the empty field. The g_data_w must be an integer multiple of the
-- g_symbol_w. If the empty field is not used or if the empty field is always 0 then
-- set g_symbol_w = g_data_w.
-- . For example to concat header and data for an Ethernet frame use:
-- . The dp_offload_tx_v3 --> dp_offload_rx form a pair.
-- . The header contents can be controlled dynamically by data path or MM
-- control (selected by g_hdr_field_sel)
-- . The header and data can be concatened at symbol level. The g_symbol_w
-- defines the resolution of the empty field. The g_data_w must be an
-- integer multiple of the g_symbol_w. If the empty field is not used or
-- if the empty field is always 0 then set g_symbol_w = g_data_w.
-- . For example to concat header and data block for an Ethernet frame use:
-- - g_data_w = 32 (1GbE) or 64 (10GbE)
-- - g_symbol_w = c_byte_w = 8 if either the header or the data can have an
-- non-zero empty field, so when they are not a multiple of 4 bytes
-- (= 32b) or 8 bytes (= 64b).
-- g_symbol_w = g_data_w if the empty field is always 0, so the number of bits in
-- the header and data are an integer number of g_data_w.
-- - g_symbol_w = c_byte_w = 8 if either the header or the data block can
-- have an non-zero empty field, so when they are not a multiple of
-- 4 bytes (= 32b) or 8 bytes (= 64b).
-- g_symbol_w = g_data_w if the empty field is always 0, so the number of
-- bits in the header and data are an integer number of g_data_w.
LIBRARY IEEE, common_lib, technology_lib, mm_lib;
......
......@@ -30,6 +30,23 @@
-- |___________________| | |___________________|
-- |
-- link_offload_sosi
--
-- The verification of the header - data block boundary is controlled via
-- g_symbol_w:
-- . g_symbol_w = g_data_w : boundary at g_data_w
-- . g_symbol_w < g_data_w : boundary at g_symbol_w, by reducing the number
-- of the header dp_bsn field by 1 symbol. If the c_bsn_w <= 32 then the
-- header MM interface only needs one MM word to read the header, so
-- therefore there are two sizes of c_expected_tx_hdr_word_arr_* and
-- c_expected_rx_hdr_word_arr_*.
--
-- Remarks:
-- . The g_flow_control_verify has to be e_active, otherwise the tb fails,
-- probably due to limitation in dp_offload_rx.vhd.
-- . It appears that the tx_hdr_word read values are the MM write values, so
-- read of value from logic fields (with MM override '0', e.g. dp_bsn,
-- eth_src_mac) is not supported.
--
-- Usage:
-- > as 10
-- > run -all
......@@ -54,8 +71,10 @@ ENTITY tb_dp_offload_tx_v3 IS
-- general
g_flow_control_stimuli : t_dp_flow_control_enum := e_pulse; -- always e_active, e_random or e_pulse flow control
g_flow_control_verify : t_dp_flow_control_enum := e_active; -- always e_active, e_random or e_pulse flow control
g_print_en : BOOLEAN := TRUE;
-- specific
g_data_w : NATURAL := 64;
g_symbol_w : NATURAL := 32;
g_pkt_len : NATURAL := 240;
g_pkt_gap : NATURAL := 16
);
......@@ -67,6 +86,18 @@ ARCHITECTURE tb OF tb_dp_offload_tx_v3 IS
CONSTANT c_mm_clk_period : TIME := 1 ns;
CONSTANT c_dp_clk_period : TIME := 5 ns;
-- Simulate header / payload boundary at g_data_w boundary or at g_symbol_w
-- boundary with one empty symbol, by adapting the size of the header dp_bsn
-- field:
-- . If g_symbol_w = g_data_w then boundary is at g_data_w, so empty is 0.
-- . If g_symbol_w < g_data_w then boundary is at last symbol, so empty is 1.
CONSTANT c_nof_symbols_per_data : NATURAL := g_data_w / g_symbol_w;
CONSTANT c_nof_symbols_per_bsn : NATURAL := c_dp_stream_bsn_w / g_symbol_w; -- = 64 / g_symbol_w
CONSTANT c_bsn_w : NATURAL := sel_a_b(c_nof_symbols_per_data = 1,
g_symbol_w * c_nof_symbols_per_bsn,
g_symbol_w * (c_nof_symbols_per_bsn - 1));
CONSTANT c_use_shortened_header : BOOLEAN := c_bsn_w <= c_word_w;
-- dp_stream_stimuli
CONSTANT c_stimuli_pulse_active : NATURAL := 3;
CONSTANT c_stimuli_pulse_period : NATURAL := 4;
......@@ -97,7 +128,10 @@ ARCHITECTURE tb OF tb_dp_offload_tx_v3 IS
-----------------------------------------------------------------------------
-- From apertif_udp_offload_pkg.vhd:
CONSTANT c_udp_offload_nof_hdr_fields : NATURAL := 3+12+4+3; -- 22, 448b; 7 64b words
CONSTANT c_udp_offload_nof_hdr_words : NATURAL := 26; -- 23 single word + 3 double word = 26 32b words
CONSTANT c_udp_offload_nof_hdr_words_default : NATURAL := 26; -- 23 single word + 3 double word = 26 32b words
CONSTANT c_udp_offload_nof_hdr_words_shortened : NATURAL := c_udp_offload_nof_hdr_words_default - 1;
CONSTANT c_udp_offload_nof_hdr_words : NATURAL := sel_a_b(c_use_shortened_header, c_udp_offload_nof_hdr_words_shortened, c_udp_offload_nof_hdr_words_default);
-- Notes:
-- . pre-calculated ip_header_checksum is valid only for UNB0, FN0 targeting IP 10.10.10.10
-- . udp_total_length = 176 beamlets * 64b / 8b = 1408B + 14 DP bytes + 8 UDP bytes = 1430B
......@@ -123,13 +157,13 @@ ARCHITECTURE tb OF tb_dp_offload_tx_v3 IS
( field_name_pad("udp_checksum" ), "RW", 16, field_default(0) ), -- 3
( field_name_pad("dp_reserved" ), "RW", 47, field_default(x"010203040506") ), -- 2
( field_name_pad("dp_sync" ), "RW", 1, field_default(0) ), -- 1
( field_name_pad("dp_bsn" ), "RW", 64, field_default(0) ) ); -- 0
( field_name_pad("dp_bsn" ), "RW", c_bsn_w, field_default(0) ) ); -- 0
-- TX: Corresponding storage of c_udp_offload_hdr_field_arr in MM register words
-- . Note: It appears that the tx_hdr_word read values are the MM write values, so read of value from logic fields (with MM override '0', e.g. dp_bsn, eth_src_mac) is not supported.
CONSTANT c_expected_tx_hdr_word_arr : t_slv_32_arr(0 TO c_udp_offload_nof_hdr_words-1) := ( -- word address
CONSTANT c_expected_tx_hdr_word_arr_default : t_slv_32_arr(0 TO c_udp_offload_nof_hdr_words_default-1) := ( -- word address
X"00000000", -- 0 = dp_bsn[31:0] -- readback is MM value, not the logic value
X"00000000", -- 1 = dp_bsn[63:32]
X"00000000", -- 1 = dp_bsn[c_bsn_w-1:32]
X"00000000", -- 2 = dp_sync
X"03040506", -- 3 = dp_reserved[31:0]
X"00000102", -- 4 = dp_reserved[47:32]
......@@ -155,10 +189,37 @@ ARCHITECTURE tb OF tb_dp_offload_tx_v3 IS
X"214368AC", -- 24 = eth_dst_mac[31:0]
X"0000001B"); -- 25 = eth_dst_mac[47:32]
CONSTANT c_expected_tx_hdr_word_arr_shortened : t_slv_32_arr(0 TO c_udp_offload_nof_hdr_words_shortened-1) := ( -- word address
X"00000000", -- 0 = dp_bsn[31:0] -- readback is MM value, not the logic value
X"00000000", -- 1 = dp_sync
X"03040506", -- 2 = dp_reserved[31:0]
X"00000102", -- 3 = dp_reserved[47:32]
X"00000000", -- 4 = udp_checksum
X"00000596", -- 5 = udp_total_length
X"00000000", -- 6 = udp_dst_port
X"00000000", -- 7 = udp_src_port -- readback is MM value, not the logic value
X"C0A80001", -- 8 = ip_dst_addr
X"C0A80009", -- 9 = ip_src_addr
X"000074E8", -- 10 = ip_header_checksum
X"00000011", -- 11 = ip_protocol
X"0000007F", -- 12 = ip_time_to_live
X"00000000", -- 13 = ip_fragment_offset
X"00000002", -- 14 = ip_flags
X"00000000", -- 15 = ip_identification
X"000005AA", -- 16 = ip_total_length
X"00000000", -- 17 = ip_services
X"00000005", -- 18 = ip_header_length
X"00000004", -- 19 = ip_version
X"00000800", -- 20 = eth_type[15:0]
X"456789AB", -- 21 = eth_src_mac[31:0] -- readback is MM value, not the logic value
X"00000123", -- 22 = eth_src_mac[47:32]
X"214368AC", -- 23 = eth_dst_mac[31:0]
X"0000001B"); -- 24 = eth_dst_mac[47:32]
-- RX: Corresponding storage of c_udp_offload_hdr_field_arr in MM register words
CONSTANT c_expected_rx_hdr_word_arr : t_slv_32_arr(0 TO c_udp_offload_nof_hdr_words-1) := ( -- word address
CONSTANT c_expected_rx_hdr_word_arr_default : t_slv_32_arr(0 TO c_udp_offload_nof_hdr_words_default-1) := ( -- word address
X"00000002", -- 0 = dp_bsn[31:0] -- dynamic value obtained from simulation
X"00000000", -- 1 = dp_bsn[63:32]
X"00000000", -- 1 = dp_bsn[c_bsn_w-1:32]
X"00000001", -- 2 = dp_sync -- dynamic value obtained from simulation
X"03040506", -- 3 = dp_reserved[31:0]
X"00000102", -- 4 = dp_reserved[47:32]
......@@ -184,6 +245,33 @@ ARCHITECTURE tb OF tb_dp_offload_tx_v3 IS
X"214368AC", -- 24 = eth_dst_mac[31:0]
X"0000001B"); -- 25 = eth_dst_mac[47:32]
CONSTANT c_expected_rx_hdr_word_arr_shortened : t_slv_32_arr(0 TO c_udp_offload_nof_hdr_words_shortened-1) := ( -- word address
X"00000002", -- 0 = dp_bsn[31:0] -- dynamic value obtained from simulation
X"00000001", -- 1 = dp_sync -- dynamic value obtained from simulation
X"03040506", -- 2 = dp_reserved[31:0]
X"00000102", -- 3 = dp_reserved[47:32]
X"00000000", -- 4 = udp_checksum
X"00000596", -- 5 = udp_total_length
X"00000000", -- 6 = udp_dst_port
X"00000000", -- 7 = udp_src_port
X"C0A80001", -- 8 = ip_dst_addr
X"C0A80009", -- 9 = ip_src_addr
X"000074E8", -- 10 = ip_header_checksum
X"00000011", -- 11 = ip_protocol
X"0000007F", -- 12 = ip_time_to_live
X"00000000", -- 13 = ip_fragment_offset
X"00000002", -- 14 = ip_flags
X"00000000", -- 15 = ip_identification
X"000005AA", -- 16 = ip_total_length
X"00000000", -- 17 = ip_services
X"00000005", -- 18 = ip_header_length
X"00000004", -- 19 = ip_version
X"00000800", -- 20 = eth_type[15:0]
X"86080000", -- 21 = eth_src_mac[31:0] -- readback is the logic value x"00228608" & id_backplane = 0 & id_chip = 0 (c_NODE_ID = 0)
X"00000022", -- 22 = eth_src_mac[47:32]
X"214368AC", -- 23 = eth_dst_mac[31:0]
X"0000001B"); -- 24 = eth_dst_mac[47:32]
-- From apertif_unb1_fn_beamformer_udp_offload.vhd: 221 111111111000 0000 000
-- Override ('1') only the Ethernet fields so we can use MM defaults there. 109 876543210987 6543 210
CONSTANT c_hdr_field_ovr_init : STD_LOGIC_VECTOR(c_udp_offload_nof_hdr_fields-1 DOWNTO 0) := "101"&"111111111111"&"1111"&"100";
......@@ -405,13 +493,13 @@ BEGIN
tx_hdr_fields_in_arr(0)(field_hi(c_udp_offload_hdr_field_arr, "ip_src_addr" ) DOWNTO field_lo(c_udp_offload_hdr_field_arr, "ip_src_addr" )) <= x"0A63" & id_backplane & INCR_UVEC(id_chip, 1);
tx_hdr_fields_in_arr(0)(field_hi(c_udp_offload_hdr_field_arr, "dp_sync" ) DOWNTO field_lo(c_udp_offload_hdr_field_arr, "dp_sync" )) <= slv(dp_offload_tx_snk_in_arr(0).sync);
tx_hdr_fields_in_arr(0)(field_hi(c_udp_offload_hdr_field_arr, "dp_bsn" ) DOWNTO field_lo(c_udp_offload_hdr_field_arr, "dp_bsn" )) <= dp_offload_tx_snk_in_arr(0).bsn(63 DOWNTO 0);
tx_hdr_fields_in_arr(0)(field_hi(c_udp_offload_hdr_field_arr, "dp_bsn" ) DOWNTO field_lo(c_udp_offload_hdr_field_arr, "dp_bsn" )) <= dp_offload_tx_snk_in_arr(0).bsn(c_bsn_w-1 DOWNTO 0);
u_tx : ENTITY work.dp_offload_tx_v3
GENERIC MAP (
g_nof_streams => 1,
g_data_w => g_data_w,
g_symbol_w => g_data_w,
g_symbol_w => g_symbol_w,
g_hdr_field_arr => c_udp_offload_hdr_field_arr,
g_hdr_field_sel => c_hdr_field_ovr_init
)
......@@ -440,19 +528,23 @@ BEGIN
VARIABLE v_word : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
BEGIN
proc_common_wait_until_hi_lo(dp_clk, tx_offload_sosi_arr(0).sync);
print_str("");
print_str("", g_print_en);
FOR I IN 0 TO c_udp_offload_nof_hdr_words-1 LOOP
proc_mem_mm_bus_rd(I, mm_clk, reg_dp_offload_tx_hdr_dat_mosi);
proc_mem_mm_bus_rd_latency(c_mem_reg_rd_latency, mm_clk);
v_word := reg_dp_offload_tx_hdr_dat_miso.rddata(31 DOWNTO 0);
-- Log word in transcript window
print_str("tx_hdr_word(" & int_to_str(I) & ") = " & slv_to_hex(v_word));
print_str("tx_hdr_word(" & int_to_str(I) & ") = " & slv_to_hex(v_word), g_print_en);
-- View word in wave window
tx_hdr_word <= v_word;
-- Verify expected word
ASSERT c_expected_tx_hdr_word_arr(I) = v_word REPORT "Unexpected tx_hdr_word at address " & int_to_str(I) & ", expected " & slv_to_hex(c_expected_tx_hdr_word_arr(I)) SEVERITY ERROR;
IF c_use_shortened_header THEN
ASSERT c_expected_tx_hdr_word_arr_shortened(I) = v_word REPORT "Unexpected tx_hdr_word at address " & int_to_str(I) & ", expected " & slv_to_hex(c_expected_tx_hdr_word_arr_shortened(I)) SEVERITY ERROR;
ELSE
ASSERT c_expected_tx_hdr_word_arr_default(I) = v_word REPORT "Unexpected tx_hdr_word at address " & int_to_str(I) & ", expected " & slv_to_hex(c_expected_tx_hdr_word_arr_default(I)) SEVERITY ERROR;
END IF;
END LOOP;
print_str("");
print_str("", g_print_en);
WAIT;
END PROCESS;
......@@ -482,6 +574,7 @@ BEGIN
GENERIC MAP (
g_nof_streams => 1,
g_data_w => g_data_w,
g_symbol_w => g_symbol_w,
g_hdr_field_arr => c_udp_offload_hdr_field_arr,
g_remove_crc => FALSE,
g_crc_nof_words => 0
......@@ -524,19 +617,23 @@ BEGIN
-- Check first packet after sync with dp_sync = 1
-- wait some latency until header fields of this sync packet are available via MM
proc_common_wait_some_cycles(dp_clk, 10);
print_str("");
print_str("", g_print_en);
FOR I IN 0 TO c_udp_offload_nof_hdr_words-1 LOOP
proc_mem_mm_bus_rd(I, mm_clk, reg_dp_offload_rx_hdr_dat_mosi);
proc_mem_mm_bus_rd_latency(c_mem_reg_rd_latency, mm_clk);
v_word := reg_dp_offload_rx_hdr_dat_miso.rddata(31 DOWNTO 0);
-- Log word in transcript window
print_str("rx_hdr_word(" & int_to_str(I) & ") : " & slv_to_hex(v_word));
print_str("rx_hdr_word(" & int_to_str(I) & ") : " & slv_to_hex(v_word), g_print_en);
-- View word in wave window
rx_hdr_word <= v_word;
-- Verify expected word
ASSERT v_word = c_expected_rx_hdr_word_arr(I) REPORT "Unexpected rx_hdr_word at address " & int_to_str(I) & ", expected " & slv_to_hex(c_expected_rx_hdr_word_arr(I)) SEVERITY ERROR;
IF c_use_shortened_header THEN
ASSERT v_word = c_expected_rx_hdr_word_arr_shortened(I) REPORT "Unexpected rx_hdr_word at address " & int_to_str(I) & ", expected " & slv_to_hex(c_expected_rx_hdr_word_arr_shortened(I)) SEVERITY ERROR;
ELSE
ASSERT v_word = c_expected_rx_hdr_word_arr_default(I) REPORT "Unexpected rx_hdr_word at address " & int_to_str(I) & ", expected " & slv_to_hex(c_expected_rx_hdr_word_arr_default(I)) SEVERITY ERROR;
END IF;
END LOOP;
print_str("");
print_str("", g_print_en);
-- Check dp_bsn and dp_sync of second packet after sync with dp_sync = 0
proc_common_wait_until_hi_lo(dp_clk, verify_snk_in.sop);
......@@ -547,9 +644,17 @@ BEGIN
proc_mem_mm_bus_rd_latency(c_mem_reg_rd_latency, mm_clk);
v_word := reg_dp_offload_rx_hdr_dat_miso.rddata(31 DOWNTO 0);
rx_hdr_word <= v_word; -- View word in wave window
ASSERT v_word = INCR_UVEC(c_expected_rx_hdr_word_arr(0), 1) REPORT "Unexpected dp_bsn from MM" SEVERITY ERROR;
IF c_use_shortened_header THEN
ASSERT v_word = INCR_UVEC(c_expected_rx_hdr_word_arr_shortened(0), 1) REPORT "Unexpected dp_bsn from MM" SEVERITY ERROR;
ELSE
ASSERT v_word = INCR_UVEC(c_expected_rx_hdr_word_arr_default(0), 1) REPORT "Unexpected dp_bsn from MM" SEVERITY ERROR;
END IF;
-- dp_sync
IF c_use_shortened_header THEN
proc_mem_mm_bus_rd(1, mm_clk, reg_dp_offload_rx_hdr_dat_mosi);
ELSE
proc_mem_mm_bus_rd(2, mm_clk, reg_dp_offload_rx_hdr_dat_mosi);
END IF;
proc_mem_mm_bus_rd_latency(c_mem_reg_rd_latency, mm_clk);
v_word := reg_dp_offload_rx_hdr_dat_miso.rddata(31 DOWNTO 0);
rx_hdr_word <= v_word; -- View word in wave window
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment