diff --git a/libraries/io/eth/eth.peripheral.yaml b/libraries/io/eth/eth.peripheral.yaml index 083ec80cfba988b8619e5670e503529677c8e853..321706436eb9bc52210d67d1da407f3fb5c71fb5 100644 --- a/libraries/io/eth/eth.peripheral.yaml +++ b/libraries/io/eth/eth.peripheral.yaml @@ -251,30 +251,31 @@ peripherals: " fields: # eth field group - - - { field_name: word_align, mm_width: 16, access_mode: RW, address_offset: 0x64 } - - - { field_name: eth_destination_mac, mm_width: 32, user_width: 48, radix: uint64, access_mode: RW, address_offset: 0x5c } - - - { field_name: eth_source_mac, mm_width: 32, user_width: 48, radix: uint64, access_mode: RW, address_offset: 0x54 } - - - { field_name: eth_type, mm_width: 16, access_mode: RW, address_offset: 0x50 } + - - { field_name: word_align, mm_width: 16, access_mode: RW, address_offset: 0x68 } + - - { field_name: eth_destination_mac, mm_width: 32, user_width: 48, radix: uint64, access_mode: RW, address_offset: 0x60 } + - - { field_name: eth_source_mac, mm_width: 32, user_width: 48, radix: uint64, access_mode: RW, address_offset: 0x58 } + - - { field_name: eth_type, mm_width: 16, access_mode: RW, address_offset: 0x54 } # ip field group - - - { field_name: ip_version, mm_width: 4, access_mode: RW, address_offset: 0x4c } - - - { field_name: ip_header_length, mm_width: 4, access_mode: RW, address_offset: 0x48 } - - - { field_name: ip_services, mm_width: 8, access_mode: RW, address_offset: 0x44 } - - - { field_name: ip_total_length, mm_width: 16, access_mode: RW, address_offset: 0x40 } - - - { field_name: ip_identification, mm_width: 16, access_mode: RW, address_offset: 0x3c } - - - { field_name: ip_flags, mm_width: 3, access_mode: RW, address_offset: 0x38 } - - - { field_name: ip_fragment_offset, mm_width: 13, access_mode: RW, address_offset: 0x34 } - - - { field_name: ip_time_to_live, mm_width: 8, access_mode: RW, address_offset: 0x30 } - - - { field_name: ip_protocol, mm_width: 8, access_mode: RW, address_offset: 0x2c } - - - { field_name: ip_header_checksum, mm_width: 16, access_mode: RW, address_offset: 0x28 } - - - { field_name: ip_source_address, mm_width: 32, access_mode: RW, address_offset: 0x24 } - - - { field_name: ip_destination_address, mm_width: 32, access_mode: RW, address_offset: 0x20 } + - - { field_name: ip_version, mm_width: 4, access_mode: RW, address_offset: 0x50 } + - - { field_name: ip_header_length, mm_width: 4, access_mode: RW, address_offset: 0x4c } + - - { field_name: ip_services, mm_width: 8, access_mode: RW, address_offset: 0x48 } + - - { field_name: ip_total_length, mm_width: 16, access_mode: RW, address_offset: 0x44 } + - - { field_name: ip_identification, mm_width: 16, access_mode: RW, address_offset: 0x40 } + - - { field_name: ip_flags, mm_width: 3, access_mode: RW, address_offset: 0x3c } + - - { field_name: ip_fragment_offset, mm_width: 13, access_mode: RW, address_offset: 0x38 } + - - { field_name: ip_time_to_live, mm_width: 8, access_mode: RW, address_offset: 0x34 } + - - { field_name: ip_protocol, mm_width: 8, access_mode: RW, address_offset: 0x30 } + - - { field_name: ip_header_checksum, mm_width: 16, access_mode: RW, address_offset: 0x2c } + - - { field_name: ip_source_address, mm_width: 32, access_mode: RW, address_offset: 0x28 } + - - { field_name: ip_destination_address, mm_width: 32, access_mode: RW, address_offset: 0x24 } # udp field group - - - { field_name: udp_source_port, mm_width: 16, access_mode: RW, address_offset: 0x1c } - - - { field_name: udp_destination_port, mm_width: 16, access_mode: RW, address_offset: 0x18 } - - - { field_name: udp_length, mm_width: 16, access_mode: RW, address_offset: 0x14 } - - - { field_name: udp_checksum, mm_width: 16, access_mode: RW, address_offset: 0x10 } + - - { field_name: udp_source_port, mm_width: 16, access_mode: RW, address_offset: 0x20 } + - - { field_name: udp_destination_port, mm_width: 16, access_mode: RW, address_offset: 0x1c } + - - { field_name: udp_length, mm_width: 16, access_mode: RW, address_offset: 0x18 } + - - { field_name: udp_checksum, mm_width: 16, access_mode: RW, address_offset: 0x14 } # application field group - - - { field_name: dp_reserved, mm_width: 31, access_mode: RW, address_offset: 0xC } + - - { field_name: dp_length, mm_width: 16, access_mode: RW, address_offset: 0x10 } + - - { field_name: dp_reserved, mm_width: 15, access_mode: RW, address_offset: 0xC } - - { field_name: dp_sync, mm_width: 1, access_mode: RW, address_offset: 0x8 } - - { field_name: dp_bsn, mm_width: 32, user_width: 64, radix: uint64, access_mode: RW, address_offset: 0x0 } diff --git a/libraries/io/eth/src/vhdl/eth_tester.vhd b/libraries/io/eth/src/vhdl/eth_tester.vhd index f765e75a038d59cb58c006a2c1fd5c5c75085137..ccc63fb866d92cd1a8f313779ebce2babcff7cf2 100644 --- a/libraries/io/eth/src/vhdl/eth_tester.vhd +++ b/libraries/io/eth/src/vhdl/eth_tester.vhd @@ -82,7 +82,9 @@ END eth_tester; ARCHITECTURE str OF eth_tester IS - SIGNAL ref_sync_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); + SIGNAL ref_sync_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); + + SIGNAL dp_length_arr : t_natural_arr(g_nof_streams-1 DOWNTO 0); -- tx block length -- MM port multiplexers -- . Tx @@ -121,6 +123,7 @@ BEGIN ip_src_addr => ip_src_addr, udp_src_port => udp_src_port, + tx_length => dp_length_arr(I), tx_fifo_rd_emp => tx_fifo_rd_emp_arr(I), tx_udp_sosi => tx_udp_sosi_arr(I), @@ -149,6 +152,8 @@ BEGIN st_clk => st_clk, ref_sync => ref_sync_arr(I), + exp_length => dp_length_arr(I), + -- UDP transmit interface rx_udp_sosi => rx_udp_sosi_arr(I), diff --git a/libraries/io/eth/src/vhdl/eth_tester_pkg.vhd b/libraries/io/eth/src/vhdl/eth_tester_pkg.vhd index 64a0e4e8eca3571ecb703b6b638df2eb49d7b293..b55bd87250ba78766eda73ae384df2e26fe3602d 100644 --- a/libraries/io/eth/src/vhdl/eth_tester_pkg.vhd +++ b/libraries/io/eth/src/vhdl/eth_tester_pkg.vhd @@ -55,8 +55,8 @@ PACKAGE eth_tester_pkg is -- to 0 by declaring hdr_fields_in_arr with all 0. Hence e.g. udp_checksum -- = 0 can be achieve via data path and default hdr_fields_in_arr = 0 or -- via MM controlled and field_default(0). - CONSTANT c_eth_tester_nof_hdr_fields : NATURAL := 1+3+12+4+3; - CONSTANT c_eth_tester_hdr_field_sel : STD_LOGIC_VECTOR(c_eth_tester_nof_hdr_fields-1 DOWNTO 0) := "1"&"101"&"111011111001"&"0100"&"100"; + CONSTANT c_eth_tester_nof_hdr_fields : NATURAL := 1+3+12+4+4; + CONSTANT c_eth_tester_hdr_field_sel : STD_LOGIC_VECTOR(c_eth_tester_nof_hdr_fields-1 DOWNTO 0) := "1"&"101"&"111011111001"&"0100"&"0100"; -- Default use destination MAC/IP/UDP = 0, so these have to be MM programmed -- before eth_tester packets can be send. @@ -84,7 +84,8 @@ PACKAGE eth_tester_pkg is ( field_name_pad("udp_total_length" ), "RW", 16, field_default(0) ), -- depends on BG block size, so set by data path ( field_name_pad("udp_checksum" ), "RW", 16, field_default(0) ), - ( field_name_pad("dp_reserved" ), "RW", 31, field_default(0) ), + ( field_name_pad("dp_length" ), "RW", 16, field_default(0) ), + ( field_name_pad("dp_reserved" ), "RW", 15, field_default(0) ), ( field_name_pad("dp_sync" ), "RW", 1, field_default(0) ), ( field_name_pad("dp_bsn" ), "RW", 64, field_default(0) ) ); @@ -104,7 +105,8 @@ PACKAGE eth_tester_pkg is CONSTANT c_eth_tester_udp_src_port_15_8 : STD_LOGIC_VECTOR( 7 DOWNTO 0) := x"E0"; TYPE t_eth_tester_app_header IS RECORD - dp_reserved : STD_LOGIC_VECTOR(30 DOWNTO 0); + dp_length : STD_LOGIC_VECTOR(15 DOWNTO 0); + dp_reserved : STD_LOGIC_VECTOR(14 DOWNTO 0); dp_sync : STD_LOGIC; dp_bsn : STD_LOGIC_VECTOR(63 DOWNTO 0); END RECORD; @@ -152,6 +154,7 @@ PACKAGE BODY eth_tester_pkg IS v.udp.checksum := hdr_fields_raw(field_hi(c_eth_tester_hdr_field_arr, "udp_checksum") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "udp_checksum")); -- app header + v.app.dp_length := hdr_fields_raw(field_hi(c_eth_tester_hdr_field_arr, "dp_length") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "dp_length")); v.app.dp_reserved := hdr_fields_raw(field_hi(c_eth_tester_hdr_field_arr, "dp_reserved") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "dp_reserved")); v.app.dp_sync := sl(hdr_fields_raw(field_hi(c_eth_tester_hdr_field_arr, "dp_sync") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "dp_sync"))); v.app.dp_bsn := hdr_fields_raw(field_hi(c_eth_tester_hdr_field_arr, "dp_bsn") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "dp_bsn")); diff --git a/libraries/io/eth/src/vhdl/eth_tester_rx.vhd b/libraries/io/eth/src/vhdl/eth_tester_rx.vhd index 425f3f39f17fa73f62e02ddafa34300f53917efe..e4012c32f33201dea5808737ace2a779555d7483 100644 --- a/libraries/io/eth/src/vhdl/eth_tester_rx.vhd +++ b/libraries/io/eth/src/vhdl/eth_tester_rx.vhd @@ -46,6 +46,8 @@ ENTITY eth_tester_rx IS st_clk : IN STD_LOGIC; ref_sync : IN STD_LOGIC; + exp_length : IN NATURAL RANGE 0 TO 2**c_halfword_w - 1; -- 16 bit + -- UDP receive interface rx_udp_sosi : IN t_dp_sosi; @@ -75,6 +77,7 @@ ARCHITECTURE str OF eth_tester_rx IS SIGNAL rx_offload_data : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); SIGNAL decoded_sosi : t_dp_sosi; SIGNAL decoded_data : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); + SIGNAL decoded_length : NATURAL; SIGNAL rx_fifo_siso : t_dp_siso; SIGNAL rx_fifo_sosi : t_dp_sosi; SIGNAL rx_fifo_data : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); @@ -134,10 +137,22 @@ BEGIN p_set_meta: PROCESS(rx_offload_sosi, hdr_fields_out_slv, hdr_fields_raw_slv) BEGIN decoded_sosi <= rx_offload_sosi; + decoded_length <= TO_UINT(hdr_fields_raw_slv(field_hi(c_eth_tester_hdr_field_arr, "dp_length") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "dp_length"))); decoded_sosi.sync <= sl(hdr_fields_out_slv(field_hi(c_eth_tester_hdr_field_arr, "dp_sync") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "dp_sync"))); decoded_sosi.bsn <= RESIZE_DP_BSN(hdr_fields_raw_slv(field_hi(c_eth_tester_hdr_field_arr, "dp_bsn" ) DOWNTO field_lo(c_eth_tester_hdr_field_arr, "dp_bsn"))); END PROCESS; + -- synthesis translate_off + p_verify_length : PROCESS(st_clk) + BEGIN + IF rising_edge(st_clk) THEN + IF decoded_sosi.sop = '1' THEN + ASSERT decoded_length = exp_length REPORT "Unexpected Rx length" & NATURAL'IMAGE(decoded_length) & " /= " & NATURAL'IMAGE(exp_length) & " expected length from Tx" SEVERITY ERROR; + END IF; + END IF; + END PROCESS; + -- synthesis translate_on + u_rx_fifo : ENTITY dp_lib.dp_fifo_sc GENERIC MAP ( g_data_w => c_word_w, diff --git a/libraries/io/eth/src/vhdl/eth_tester_tx.vhd b/libraries/io/eth/src/vhdl/eth_tester_tx.vhd index 8d5dace234f77b58714d4b3d949c6de114f00d92..37008bab10974097d5d3a9f047d53060a1cfb81b 100644 --- a/libraries/io/eth/src/vhdl/eth_tester_tx.vhd +++ b/libraries/io/eth/src/vhdl/eth_tester_tx.vhd @@ -52,6 +52,7 @@ ENTITY eth_tester_tx IS ip_src_addr : IN STD_LOGIC_VECTOR(c_network_ip_addr_w-1 DOWNTO 0); udp_src_port : IN STD_LOGIC_VECTOR(c_network_udp_port_w-1 DOWNTO 0); + tx_length : OUT NATURAL RANGE 0 TO 2**c_halfword_w - 1; -- 16 bit tx_fifo_rd_emp : OUT STD_LOGIC; tx_udp_sosi : OUT t_dp_sosi; @@ -116,6 +117,7 @@ ARCHITECTURE str OF eth_tester_tx IS BEGIN ref_sync <= i_ref_sync; + tx_length <= app_total_length; tx_fifo_rd_emp <= i_tx_fifo_rd_emp; tx_udp_sosi <= i_tx_udp_sosi; @@ -246,6 +248,7 @@ BEGIN -- DP udp_checksum --> default fixed 0, so not used, not calculated -- here or in 1GbE eth component because would -- require store and forward + -- DP dp_length -- MM dp_reserved -- DP dp_sync -- DP dp_bsn @@ -263,6 +266,7 @@ BEGIN hdr_fields_slv_in(field_hi(c_eth_tester_hdr_field_arr, "ip_src_addr" ) DOWNTO field_lo(c_eth_tester_hdr_field_arr, "ip_src_addr" )) <= ip_src_addr; hdr_fields_slv_in(field_hi(c_eth_tester_hdr_field_arr, "udp_src_port" ) DOWNTO field_lo(c_eth_tester_hdr_field_arr, "udp_src_port" )) <= udp_src_port; hdr_fields_slv_in(field_hi(c_eth_tester_hdr_field_arr, "udp_total_length") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "udp_total_length")) <= TO_UVEC(udp_total_length, 16); + hdr_fields_slv_in(field_hi(c_eth_tester_hdr_field_arr, "dp_length" ) DOWNTO field_lo(c_eth_tester_hdr_field_arr, "dp_length" )) <= TO_UVEC(app_total_length, 16); hdr_fields_slv_in(field_hi(c_eth_tester_hdr_field_arr, "dp_sync" ) DOWNTO field_lo(c_eth_tester_hdr_field_arr, "dp_sync" )) <= slv(tx_fifo_sosi.sync); hdr_fields_slv_in(field_hi(c_eth_tester_hdr_field_arr, "dp_bsn" ) DOWNTO field_lo(c_eth_tester_hdr_field_arr, "dp_bsn" )) <= tx_fifo_sosi.bsn; diff --git a/libraries/io/eth/tb/vhdl/tb_eth_tester.vhd b/libraries/io/eth/tb/vhdl/tb_eth_tester.vhd index 08948c5d67f616ba11f685ca0394f2f799049dd9..0468da2e97b1c7044b6b589d621036255d4ce9c3 100644 --- a/libraries/io/eth/tb/vhdl/tb_eth_tester.vhd +++ b/libraries/io/eth/tb/vhdl/tb_eth_tester.vhd @@ -25,6 +25,9 @@ -- -- Usage: -- > as 8 +-- # Cannot use run -a when g_loopback_eth=TRUE and g_eth_sim_level=0, because +-- # the TSE IP model remains active internally after tb_end +-- > run 100 us # when g_loopback_eth=TRUE and g_eth_sim_level=0, else: -- > run -a -- -- References: @@ -54,10 +57,10 @@ USE tech_tse_lib.tb_tech_tse_pkg.ALL; ENTITY tb_eth_tester IS GENERIC ( g_tb_index : NATURAL := 0; -- use to incremental delay logging from tb instances in tb_tb - g_nof_sync : NATURAL := 93; -- number of BG sync intervals to set c_run_time + g_nof_sync : NATURAL := 3; -- number of BG sync intervals to set c_run_time g_nof_streams : NATURAL := 1; -- <= c_eth_nof_udp_ports = 4 when g_loopback_tx_rx = 1 - g_loopback_eth : BOOLEAN := FALSE; -- FALSE = sosi loopback, TRUE = eth loopback - g_eth_sim_level : NATURAL := 1; -- when g_loopback_eth = TRUE, then 0 = use tech_tse IP; 1 = use fast sim_tse model + g_loopback_eth : BOOLEAN := TRUE; -- FALSE = sosi loopback, TRUE = eth loopback + g_eth_sim_level : NATURAL := 0; -- when g_loopback_eth = TRUE, then 0 = use tech_tse IP; 1 = use fast sim_tse model -- t_diag_block_gen_integer = -- sl: enable @@ -70,7 +73,7 @@ ENTITY tb_eth_tester IS -- nat: bsn_init --g_bg_ctrl_first : t_diag_block_gen_integer := ('1', '1', 50, 8, 100, 0, c_diag_bg_mem_max_adr, 0); -- for first stream --g_bg_ctrl_others : t_diag_block_gen_integer := ('1', '1', 30, 8, 10, 0, c_diag_bg_mem_max_adr, 0) -- for other streams - g_bg_ctrl_first : t_diag_block_gen_integer := ('1', '1', 50, 8, 660, 0, c_diag_bg_mem_max_adr, 0); -- for first stream + g_bg_ctrl_first : t_diag_block_gen_integer := ('1', '1', 50, 8, 200, 0, c_diag_bg_mem_max_adr, 0); -- for first stream g_bg_ctrl_others : t_diag_block_gen_integer := ('1', '1', 30, 8, 10, 0, c_diag_bg_mem_max_adr, 0) -- for other streams ); PORT ( @@ -282,10 +285,10 @@ BEGIN v_offset := I * c_eth_tester_reg_hdr_dat_addr_span; -- Set destination MAC/IP/UDP port in tx header, increment udp_dst_port per stream -- The MM addresses follow from byte address_offset // 4 in eth.peripheral.yaml - proc_mem_mm_bus_wr(v_offset + 16#6#, v_udp_dst_port + I, mm_clk, reg_hdr_dat_cipo, reg_hdr_dat_copi); - proc_mem_mm_bus_wr(v_offset + 16#9#, TO_SINT(c_eth_tester_ip_dst_addr), mm_clk, reg_hdr_dat_cipo, reg_hdr_dat_copi); -- use signed to fit 32 b in INTEGER - proc_mem_mm_bus_wr(v_offset + 16#17#, TO_SINT(c_eth_tester_eth_dst_mac(31 DOWNTO 0)), mm_clk, reg_hdr_dat_cipo, reg_hdr_dat_copi); -- use signed to fit 32 b in INTEGER - proc_mem_mm_bus_wr(v_offset + 16#18#, TO_UINT(c_eth_tester_eth_dst_mac(47 DOWNTO 32)), mm_clk, reg_hdr_dat_cipo, reg_hdr_dat_copi); + proc_mem_mm_bus_wr(v_offset + 16#7#, v_udp_dst_port + I, mm_clk, reg_hdr_dat_cipo, reg_hdr_dat_copi); + proc_mem_mm_bus_wr(v_offset + 16#10#, TO_SINT(c_eth_tester_ip_dst_addr), mm_clk, reg_hdr_dat_cipo, reg_hdr_dat_copi); -- use signed to fit 32 b in INTEGER + proc_mem_mm_bus_wr(v_offset + 16#18#, TO_SINT(c_eth_tester_eth_dst_mac(31 DOWNTO 0)), mm_clk, reg_hdr_dat_cipo, reg_hdr_dat_copi); -- use signed to fit 32 b in INTEGER + proc_mem_mm_bus_wr(v_offset + 16#19#, TO_UINT(c_eth_tester_eth_dst_mac(47 DOWNTO 32)), mm_clk, reg_hdr_dat_cipo, reg_hdr_dat_copi); END LOOP; --------------------------------------------------------------------------- @@ -413,9 +416,9 @@ BEGIN -- BG experiences siso.xon block level flow control, to stay below -- 1 Gbps of the 1GbE link rate. ASSERT tx_total_count_nof_packet_arr(I) = rx_total_count_nof_packet_arr(I) REPORT c_tb_str & - "Wrong Tx total nof packets count(" & NATURAL'IMAGE(I) & + "Wrong Tx-Rx total nof packets count(" & NATURAL'IMAGE(I) & "), Tx count = " & NATURAL'IMAGE(tx_total_count_nof_packet_arr(I)) & - " /= " & NATURAL'IMAGE(tx_total_count_nof_packet_arr(I)) & + " /= " & NATURAL'IMAGE(rx_total_count_nof_packet_arr(I)) & " = Rx count" SEVERITY ERROR; END IF; END LOOP;