diff --git a/applications/rdma_demo/libraries/rdma_packetiser/src/vhdl/rdma_packetiser_assemble_header.vhd b/applications/rdma_demo/libraries/rdma_packetiser/src/vhdl/rdma_packetiser_assemble_header.vhd index 7dbf44536ae3c60faa6be94109636d2fc364180c..e51876b7d4d5972fcb4e5f70adbbe29595b0f768 100644 --- a/applications/rdma_demo/libraries/rdma_packetiser/src/vhdl/rdma_packetiser_assemble_header.vhd +++ b/applications/rdma_demo/libraries/rdma_packetiser/src/vhdl/rdma_packetiser_assemble_header.vhd @@ -20,13 +20,35 @@ -- Author: R. van der Walle -- Purpose: Assembles the RDMA header at snk_in.sop -- Description: --- The hdr_fields_slv output is set one st_clk cycle after snk_in.sop and will --- contain the RoCEv2 (RDMA over Converged Ethernet v2) header information for --- the corresponding data frame. --- Remark --- . The incoming data frame on snk_in should consist of at least 2 clock cycles. --- i.e. two consecutive 1 cycle frames (sop + eop on the same clock cycle) --- without a gap inbetween is not supported. +-- Generates a RoCEv2 header (ETH + UDP + IP + RDMA). See [1]. +-- Generics: +-- . g_use_immediate: When true, the immediate data field will be added to the +-- header. +-- . g_use_msg_cnt_as_immediate: When true, the message counter going from 0 to +-- "nof_msg" is used as immediate data. When false, the "immediate_data" +-- input port is used. +-- Signal inputs: +-- . immediate_data: Will be used as immediate data when +-- g_use_msg_cnt_as_immediate = False. +-- . block_len: Should be set to the length of the incoming data frame in octets. +-- . nof_packets_in_msg: Should be set to the desired amount of packets in a message. +-- . nof_msg: Should be set to the desired amount of messages, this determines the +-- address space aswell, see remarks. +-- . dma_len: The amount with which the address should increase every message, +-- this should be set to >= nof_packets_in_msg * block_len. +-- . start_address: The start address for the virtual_address field. +-- Remarks +-- . The hdr_fields_slv output is set one st_clk cycle after snk_in.sop and will +-- contain the RoCEv2 (RDMA over Converged Ethernet v2) header information for +-- the corresponding data frame. +-- . The virtual_address is set automatically by increasing it with dma_len every +-- new message. The virtual address is reset to "start_address" when the number +-- of messages has reached "nof_msg". Then the cycle repeats. +-- . The PSN field (= Packet Sequence Number) is set to LSBs of the incoming BSN. +-- This can be used to check the order or detect missing packets at the receiver. + +-- References: +-- . [1] https://support.astron.nl/confluence/x/3pKrB library IEEE, common_lib, dp_lib, eth_lib; use IEEE.std_logic_1164.all; @@ -61,7 +83,6 @@ entity rdma_packetiser_assemble_header is nof_msg : in std_logic_vector(c_word_w - 1 downto 0); dma_len : in std_logic_vector(c_word_w - 1 downto 0); -- = block_len * nof_packets_in_msg start_address : in std_logic_vector(c_longword_w - 1 downto 0) - ); end rdma_packetiser_assemble_header; @@ -71,33 +92,74 @@ architecture str of rdma_packetiser_assemble_header is constant c_udp_app_hdr_length : natural := c_network_udp_header_len + c_app_hdr_length; constant c_ip_udp_app_hdr_length : natural := c_network_ip_header_len + c_udp_app_hdr_length; - type t_state is (s_idle, s_first, s_middle, s_last); - type t_reg is record + type t_state is (s_first, s_middle, s_last); + type t_reg is record -- record to keep the registers organized. state : t_state; opcode : std_logic_vector(c_byte_w - 1 downto 0); immediate_data : std_logic_vector(c_rdma_packetiser_roce_imm_len * c_octet_w - 1 downto 0); psn : std_logic_vector(c_word_w - 1 downto 0); virtual_address : unsigned(c_longword_w - 1 downto 0); dma_len : unsigned(c_word_w - 1 downto 0); - p_cnt : natural; - msg_cnt : natural; + p_cnt : natural; -- Packet count (0 to nof_packets_in_msg). + msg_cnt : natural; -- message count (0 to nof_msg). udp_total_length : natural; ip_total_length : natural; nof_packets_in_msg : natural; end record; - constant c_reg_rst : t_reg := (s_idle, (others => '1'), (others => '0'), (others => '0'), (others => '0'), (others => '0'), 0, 0, 0, 0, 0); + constant c_reg_rst : t_reg := (s_first, (others => '1'), (others => '0'), (others => '0'), (others => '0'), (others => '0'), 0, 0, 0, 0, 0); signal d, q : t_reg; begin q <= d when rising_edge(st_clk); + -- State machine to derive RDMA header fields. p_comb : process(st_rst, q, snk_in, nof_packets_in_msg, start_address, nof_msg, immediate_data, dma_len, block_len) variable v : t_reg; begin v := q; - if snk_in.sop = '1' then -- set on sop + if snk_in.sop = '1' then v.psn := resize_uvec(snk_in.bsn, c_word_w); + v.p_cnt := q.p_cnt + 1; + case q.state is + when s_first => -- wait to start a new message and set the first opcode. + v.p_cnt := 1; + if q.p_cnt >= v.nof_packets_in_msg then -- (re)set message counter and virtual address. + if q.msg_cnt >= to_uint(nof_msg) - 1 then + v.msg_cnt := 0; + else + v.msg_cnt := q.msg_cnt + 1; + v.virtual_address := q.virtual_address + q.dma_len; + end if; + end if; + + if v.nof_packets_in_msg = 1 then -- set opcode to write_only. + v.opcode := c_rdma_packetiser_opcode_uc_write_only; + if g_use_immediate then -- set opcode to write_only with immediate data. + v.opcode := c_rdma_packetiser_opcode_uc_write_only_imm; + end if; + elsif v.nof_packets_in_msg = 2 then -- set opcode to write_first. + v.state := s_last; -- next state is last as there are only 2 packets. + v.opcode := c_rdma_packetiser_opcode_uc_write_first; + elsif v.nof_packets_in_msg > 2 then + v.state := s_middle; + v.opcode := c_rdma_packetiser_opcode_uc_write_first; + end if; + + when s_middle => -- wait unitl the first packet is done and set next opcode. + v.opcode := c_rdma_packetiser_opcode_uc_write_middle; + if q.p_cnt >= v.nof_packets_in_msg - 2 then -- wait until last middle packet + v.state := s_last; + end if; + + when s_last => -- next packet must be last packet, set opcode. + v.state := s_first; + v.opcode := c_rdma_packetiser_opcode_uc_write_last; + if g_use_immediate then -- set opcode to write_last with immediate data + v.opcode := c_rdma_packetiser_opcode_uc_write_last_imm; + end if; + end case; end if; + if v.msg_cnt = 0 then -- set on new message v.virtual_address := unsigned(start_address); v.dma_len := unsigned(dma_len); @@ -107,57 +169,6 @@ begin v.immediate_data := immediate_data; end if; - case q.state is - when s_idle => - if snk_in.sop = '1' and v.nof_packets_in_msg > 1 then - v.state := s_first; - v.opcode := c_rdma_packetiser_opcode_uc_write_first; - v.p_cnt := 1; - elsif snk_in.sop = '1' and v.nof_packets_in_msg = 1 then - v.state := s_last; - v.opcode := c_rdma_packetiser_opcode_uc_write_only; - if g_use_immediate then - v.opcode := c_rdma_packetiser_opcode_uc_write_only_im; - end if; - end if; - - when s_first => - if snk_in.sop = '1' and v.nof_packets_in_msg > 2 then - v.state := s_middle; - v.opcode := c_rdma_packetiser_opcode_uc_write_middle; - v.p_cnt := q.p_cnt + 1; - elsif snk_in.sop = '1' and v.nof_packets_in_msg = 2 then - v.state := s_last; - v.opcode := c_rdma_packetiser_opcode_uc_write_last; - v.p_cnt := q.p_cnt + 1; - if g_use_immediate then - v.opcode := c_rdma_packetiser_opcode_uc_write_last_im; - end if; - end if; - - when s_middle => - if snk_in.sop = '1' and q.p_cnt >= v.nof_packets_in_msg - 1 then - v.state := s_last; - v.opcode := c_rdma_packetiser_opcode_uc_write_last; - v.p_cnt := q.p_cnt + 1; - if g_use_immediate then - v.opcode := c_rdma_packetiser_opcode_uc_write_last_im; - end if; - elsif snk_in.sop = '1' then - v.p_cnt := q.p_cnt + 1; - end if; - - when s_last => - v.state := s_idle; - v.p_cnt := 0; - if q.msg_cnt >= to_uint(nof_msg) - 1 then - v.msg_cnt := 0; - else - v.msg_cnt := q.msg_cnt + 1; - v.virtual_address := q.virtual_address + q.dma_len; - end if; - end case; - if st_rst = '1' then v := c_reg_rst; end if; diff --git a/applications/rdma_demo/libraries/rdma_packetiser/src/vhdl/rdma_packetiser_pkg.vhd b/applications/rdma_demo/libraries/rdma_packetiser/src/vhdl/rdma_packetiser_pkg.vhd index c3f2a078aed2d799568c62bfba9dd952acde1438..bebc9205415d93fa2e33336d48b6a880852ae40c 100644 --- a/applications/rdma_demo/libraries/rdma_packetiser/src/vhdl/rdma_packetiser_pkg.vhd +++ b/applications/rdma_demo/libraries/rdma_packetiser/src/vhdl/rdma_packetiser_pkg.vhd @@ -17,11 +17,14 @@ -- limitations under the License. -- ------------------------------------------------------------------------------- --- + +------------------------------------------------------------------------------- -- Author: R. vd Walle --- Purpose: This package contains rdma_generator specific constants and/or functions --- Description: --- +-- Purpose: This package contains rdma_packetiser specific constants and/or functions +-- Description: See [1] for RDMA explanation. +-- References: +-- . [1] https://support.astron.nl/confluence/x/3pKrB +------------------------------------------------------------------------------- library IEEE, common_lib; use IEEE.std_logic_1164.all; use common_lib.common_pkg.all; @@ -90,97 +93,97 @@ package rdma_packetiser_pkg is constant c_rdma_packetiser_roce_hdr_field_arr : t_common_field_arr( c_rdma_packetiser_roce_nof_hdr_fields - 1 downto 0) := ( - ( field_name_pad("eth_dst_mac" ), "RW", 48, field_default(0) ), - ( field_name_pad("eth_src_mac" ), "RW", 48, field_default(0) ), - ( field_name_pad("eth_type" ), "RW", 16, field_default(x"0800") ), + ( field_name_pad("eth_dst_mac" ), "RW", 48, field_default(0) ), -- set by M&C + ( field_name_pad("eth_src_mac" ), "RW", 48, field_default(0) ), -- set by M&C + ( field_name_pad("eth_type" ), "RW", 16, field_default(x"0800") ), -- fixed - ( field_name_pad("ip_version" ), "RW", 4, field_default(4) ), - ( field_name_pad("ip_header_length" ), "RW", 4, field_default(5) ), - ( field_name_pad("ip_services" ), "RW", 8, field_default(0) ), - ( field_name_pad("ip_total_length" ), "RW", 16, field_default(0) ), -- depends on BG block size, so set by data path - ( field_name_pad("ip_identification" ), "RW", 16, field_default(0) ), - ( field_name_pad("ip_flags" ), "RW", 3, field_default(2) ), - ( field_name_pad("ip_fragment_offset" ), "RW", 13, field_default(0) ), - ( field_name_pad("ip_time_to_live" ), "RW", 8, field_default(127) ), - ( field_name_pad("ip_protocol" ), "RW", 8, field_default(17) ), - ( field_name_pad("ip_header_checksum" ), "RW", 16, field_default(0) ), - ( field_name_pad("ip_src_addr" ), "RW", 32, field_default(0) ), - ( field_name_pad("ip_dst_addr" ), "RW", 32, field_default(0) ), -- c_eth_tester_ip_dst_addr + ( field_name_pad("ip_version" ), "RW", 4, field_default(4) ), -- fixed + ( field_name_pad("ip_header_length" ), "RW", 4, field_default(5) ), -- fixed + ( field_name_pad("ip_services" ), "RW", 8, field_default(0) ), -- fixed + ( field_name_pad("ip_total_length" ), "RW", 16, field_default(0) ), -- set by data path + ( field_name_pad("ip_identification" ), "RW", 16, field_default(0) ), -- fixed + ( field_name_pad("ip_flags" ), "RW", 3, field_default(2) ), -- fixed + ( field_name_pad("ip_fragment_offset" ), "RW", 13, field_default(0) ), -- fixed + ( field_name_pad("ip_time_to_live" ), "RW", 8, field_default(127) ), -- fixed + ( field_name_pad("ip_protocol" ), "RW", 8, field_default(17) ), -- fixed + ( field_name_pad("ip_header_checksum" ), "RW", 16, field_default(0) ), -- set by data path + ( field_name_pad("ip_src_addr" ), "RW", 32, field_default(0) ), -- set by M&C + ( field_name_pad("ip_dst_addr" ), "RW", 32, field_default(0) ), -- set by M&C - ( field_name_pad("udp_src_port" ), "RW", 16, field_default(0) ), - ( field_name_pad("udp_dst_port" ), "RW", 16, field_default(0) ), -- c_eth_tester_udp_dst_port - ( 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("udp_src_port" ), "RW", 16, field_default(0) ), -- set by M&C + ( field_name_pad("udp_dst_port" ), "RW", 16, field_default(0) ), -- set by M&C + ( field_name_pad("udp_total_length" ), "RW", 16, field_default(0) ), -- set by data path + ( field_name_pad("udp_checksum" ), "RW", 16, field_default(0) ), -- fixed - ( field_name_pad("bth_opcode" ), "RW", 8, field_default(x"FF") ), - ( field_name_pad("bth_se" ), "RW", 1, field_default(0) ), - ( field_name_pad("bth_m" ), "RW", 1, field_default(0) ), - ( field_name_pad("bth_pad" ), "RW", 2, field_default(0) ), - ( field_name_pad("bth_tver" ), "RW", 4, field_default(0) ), - ( field_name_pad("bth_partition_key" ), "RW", 16, field_default(65535) ), - ( field_name_pad("bth_fres" ), "RW", 1, field_default(0) ), - ( field_name_pad("bth_bres" ), "RW", 1, field_default(0) ), - ( field_name_pad("bth_reserved_a" ), "RW", 6, field_default(0) ), - ( field_name_pad("bth_dest_qp" ), "RW", 16, field_default(0) ), - ( field_name_pad("bth_ack_req" ), "RW", 1, field_default(0) ), - ( field_name_pad("bth_reserved_b" ), "RW", 7, field_default(0) ), - ( field_name_pad("bth_psn" ), "RW", 32, field_default(0) ), + ( field_name_pad("bth_opcode" ), "RW", 8, field_default(x"FF") ), -- set by data path + ( field_name_pad("bth_se" ), "RW", 1, field_default(0) ), -- set by M&C + ( field_name_pad("bth_m" ), "RW", 1, field_default(0) ), -- set by M&C + ( field_name_pad("bth_pad" ), "RW", 2, field_default(0) ), -- set by M&C + ( field_name_pad("bth_tver" ), "RW", 4, field_default(0) ), -- set by M&C + ( field_name_pad("bth_partition_key" ), "RW", 16, field_default(65535) ), -- set by M&C + ( field_name_pad("bth_fres" ), "RW", 1, field_default(0) ), -- set by M&C + ( field_name_pad("bth_bres" ), "RW", 1, field_default(0) ), -- set by M&C + ( field_name_pad("bth_reserved_a" ), "RW", 6, field_default(0) ), -- fixed + ( field_name_pad("bth_dest_qp" ), "RW", 16, field_default(0) ), -- set by M&C + ( field_name_pad("bth_ack_req" ), "RW", 1, field_default(0) ), -- set by M&C + ( field_name_pad("bth_reserved_b" ), "RW", 7, field_default(0) ), -- fixed + ( field_name_pad("bth_psn" ), "RW", 32, field_default(0) ), -- set by data path - ( field_name_pad("reth_virtual_address"), "RW", 64, field_default(0) ), - ( field_name_pad("reth_r_key" ), "RW", 32, field_default(0) ), - ( field_name_pad("reth_dma_length" ), "RW", 32, field_default(0) ), + ( field_name_pad("reth_virtual_address"), "RW", 64, field_default(0) ), -- set by data path + ( field_name_pad("reth_r_key" ), "RW", 32, field_default(0) ), -- set by M&C + ( field_name_pad("reth_dma_length" ), "RW", 32, field_default(0) ), -- set by M&C - ( field_name_pad("immediate_data" ), "RW", 32, field_default(0) ) + ( field_name_pad("immediate_data" ), "RW", 32, field_default(0) ) -- set by data path or M&C ); constant c_rdma_packetiser_roce_reg_hdr_dat_addr_w : natural := ceil_log2(field_nof_words(c_rdma_packetiser_roce_hdr_field_arr, c_word_w)); constant c_rdma_packetiser_roce_reg_hdr_dat_addr_span : natural := 2**c_rdma_packetiser_roce_reg_hdr_dat_addr_w; -- RoCEv2 header for RDMA operation without immediate data - -- ETH + IP + UDP + Base Transport Header (BTH) + RDMA Extended Transport Header (RETH) + -- ETH + IP + UDP + Base Transport Header (BTH) + RDMA Extended Transport Header (RETH), so no immediate data ("no_imm"). constant c_rdma_packetiser_roce_no_imm_nof_hdr_fields : natural := 3 + 12 + 4 + 13 + 3; constant c_rdma_packetiser_roce_no_imm_hdr_field_sel : std_logic_vector(c_rdma_packetiser_roce_no_imm_nof_hdr_fields - 1 downto 0) := "111" & "111011111001" & "0100" & "1111111111111" & "111"; constant c_rdma_packetiser_roce_no_imm_hdr_field_arr : t_common_field_arr( c_rdma_packetiser_roce_no_imm_nof_hdr_fields - 1 downto 0) := ( - ( field_name_pad("eth_dst_mac" ), "RW", 48, field_default(0) ), - ( field_name_pad("eth_src_mac" ), "RW", 48, field_default(0) ), - ( field_name_pad("eth_type" ), "RW", 16, field_default(x"0800") ), + ( field_name_pad("eth_dst_mac" ), "RW", 48, field_default(0) ), -- set by M&C + ( field_name_pad("eth_src_mac" ), "RW", 48, field_default(0) ), -- set by M&C + ( field_name_pad("eth_type" ), "RW", 16, field_default(x"0800") ), -- fixed - ( field_name_pad("ip_version" ), "RW", 4, field_default(4) ), - ( field_name_pad("ip_header_length" ), "RW", 4, field_default(5) ), - ( field_name_pad("ip_services" ), "RW", 8, field_default(0) ), - ( field_name_pad("ip_total_length" ), "RW", 16, field_default(0) ), -- depends on BG block size, so set by data path - ( field_name_pad("ip_identification" ), "RW", 16, field_default(0) ), - ( field_name_pad("ip_flags" ), "RW", 3, field_default(2) ), - ( field_name_pad("ip_fragment_offset" ), "RW", 13, field_default(0) ), - ( field_name_pad("ip_time_to_live" ), "RW", 8, field_default(127) ), - ( field_name_pad("ip_protocol" ), "RW", 8, field_default(17) ), - ( field_name_pad("ip_header_checksum" ), "RW", 16, field_default(0) ), - ( field_name_pad("ip_src_addr" ), "RW", 32, field_default(0) ), - ( field_name_pad("ip_dst_addr" ), "RW", 32, field_default(0) ), -- c_eth_tester_ip_dst_addr + ( field_name_pad("ip_version" ), "RW", 4, field_default(4) ), -- fixed + ( field_name_pad("ip_header_length" ), "RW", 4, field_default(5) ), -- fixed + ( field_name_pad("ip_services" ), "RW", 8, field_default(0) ), -- fixed + ( field_name_pad("ip_total_length" ), "RW", 16, field_default(0) ), -- set by data path + ( field_name_pad("ip_identification" ), "RW", 16, field_default(0) ), -- fixed + ( field_name_pad("ip_flags" ), "RW", 3, field_default(2) ), -- fixed + ( field_name_pad("ip_fragment_offset" ), "RW", 13, field_default(0) ), -- fixed + ( field_name_pad("ip_time_to_live" ), "RW", 8, field_default(127) ), -- fixed + ( field_name_pad("ip_protocol" ), "RW", 8, field_default(17) ), -- fixed + ( field_name_pad("ip_header_checksum" ), "RW", 16, field_default(0) ), -- set by data path + ( field_name_pad("ip_src_addr" ), "RW", 32, field_default(0) ), -- set by M&C + ( field_name_pad("ip_dst_addr" ), "RW", 32, field_default(0) ), -- set by M&C - ( field_name_pad("udp_src_port" ), "RW", 16, field_default(0) ), - ( field_name_pad("udp_dst_port" ), "RW", 16, field_default(0) ), -- c_eth_tester_udp_dst_port - ( 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("udp_src_port" ), "RW", 16, field_default(0) ), -- set by M&C + ( field_name_pad("udp_dst_port" ), "RW", 16, field_default(0) ), -- set by M&C + ( field_name_pad("udp_total_length" ), "RW", 16, field_default(0) ), -- set by data path + ( field_name_pad("udp_checksum" ), "RW", 16, field_default(0) ), -- fixed - ( field_name_pad("bth_opcode" ), "RW", 8, field_default(x"FF") ), - ( field_name_pad("bth_se" ), "RW", 1, field_default(0) ), - ( field_name_pad("bth_m" ), "RW", 1, field_default(0) ), - ( field_name_pad("bth_pad" ), "RW", 2, field_default(0) ), - ( field_name_pad("bth_tver" ), "RW", 4, field_default(0) ), - ( field_name_pad("bth_partition_key" ), "RW", 16, field_default(65535) ), - ( field_name_pad("bth_fres" ), "RW", 1, field_default(0) ), - ( field_name_pad("bth_bres" ), "RW", 1, field_default(0) ), - ( field_name_pad("bth_reserved_a" ), "RW", 6, field_default(0) ), - ( field_name_pad("bth_dest_qp" ), "RW", 16, field_default(0) ), - ( field_name_pad("bth_ack_req" ), "RW", 1, field_default(0) ), - ( field_name_pad("bth_reserved_b" ), "RW", 7, field_default(0) ), - ( field_name_pad("bth_psn" ), "RW", 32, field_default(0) ), + ( field_name_pad("bth_opcode" ), "RW", 8, field_default(x"FF") ), -- set by data path + ( field_name_pad("bth_se" ), "RW", 1, field_default(0) ), -- set by M&C + ( field_name_pad("bth_m" ), "RW", 1, field_default(0) ), -- set by M&C + ( field_name_pad("bth_pad" ), "RW", 2, field_default(0) ), -- set by M&C + ( field_name_pad("bth_tver" ), "RW", 4, field_default(0) ), -- set by M&C + ( field_name_pad("bth_partition_key" ), "RW", 16, field_default(65535) ), -- set by M&C + ( field_name_pad("bth_fres" ), "RW", 1, field_default(0) ), -- set by M&C + ( field_name_pad("bth_bres" ), "RW", 1, field_default(0) ), -- set by M&C + ( field_name_pad("bth_reserved_a" ), "RW", 6, field_default(0) ), -- fixed + ( field_name_pad("bth_dest_qp" ), "RW", 16, field_default(0) ), -- set by M&C + ( field_name_pad("bth_ack_req" ), "RW", 1, field_default(0) ), -- set by M&C + ( field_name_pad("bth_reserved_b" ), "RW", 7, field_default(0) ), -- fixed + ( field_name_pad("bth_psn" ), "RW", 32, field_default(0) ), -- set by data path - ( field_name_pad("reth_virtual_address"), "RW", 64, field_default(0) ), - ( field_name_pad("reth_r_key" ), "RW", 32, field_default(0) ), - ( field_name_pad("reth_dma_length" ), "RW", 32, field_default(0) ) + ( field_name_pad("reth_virtual_address"), "RW", 64, field_default(0) ), -- set by data path + ( field_name_pad("reth_r_key" ), "RW", 32, field_default(0) ), -- set by M&C + ( field_name_pad("reth_dma_length" ), "RW", 32, field_default(0) ) -- set by M&C ); constant c_rdma_packetiser_roce_reg_no_imm_hdr_dat_addr_w : natural := ceil_log2(field_nof_words(c_rdma_packetiser_roce_no_imm_hdr_field_arr, c_word_w)); constant c_rdma_packetiser_roce_reg_no_imm_hdr_dat_addr_span : natural := 2**c_rdma_packetiser_roce_reg_no_imm_hdr_dat_addr_w; @@ -190,18 +193,18 @@ package rdma_packetiser_pkg is constant c_rdma_packetiser_roce_icrc_len : natural := 4; -- octets constant c_rdma_packetiser_roce_no_imm_hdr_len : natural := c_rdma_packetiser_roce_hdr_len - c_rdma_packetiser_roce_imm_len; - constant c_rdma_packetiser_opcode_uc_send_first : std_logic_vector := "001" & "00000"; - constant c_rdma_packetiser_opcode_uc_send_middle : std_logic_vector := "001" & "00001"; - constant c_rdma_packetiser_opcode_uc_send_last : std_logic_vector := "001" & "00010"; - constant c_rdma_packetiser_opcode_uc_send_last_im : std_logic_vector := "001" & "00011"; - constant c_rdma_packetiser_opcode_uc_send_only : std_logic_vector := "001" & "00100"; - constant c_rdma_packetiser_opcode_uc_send_only_im : std_logic_vector := "001" & "00101"; - constant c_rdma_packetiser_opcode_uc_write_first : std_logic_vector := "001" & "00110"; - constant c_rdma_packetiser_opcode_uc_write_middle : std_logic_vector := "001" & "00111"; - constant c_rdma_packetiser_opcode_uc_write_last : std_logic_vector := "001" & "01000"; - constant c_rdma_packetiser_opcode_uc_write_last_im : std_logic_vector := "001" & "01001"; - constant c_rdma_packetiser_opcode_uc_write_only : std_logic_vector := "001" & "01010"; - constant c_rdma_packetiser_opcode_uc_write_only_im : std_logic_vector := "001" & "01011"; + constant c_rdma_packetiser_opcode_uc_send_first : std_logic_vector := "001" & "00000"; + constant c_rdma_packetiser_opcode_uc_send_middle : std_logic_vector := "001" & "00001"; + constant c_rdma_packetiser_opcode_uc_send_last : std_logic_vector := "001" & "00010"; -- without immediate + constant c_rdma_packetiser_opcode_uc_send_last_imm : std_logic_vector := "001" & "00011"; -- with immediate + constant c_rdma_packetiser_opcode_uc_send_only : std_logic_vector := "001" & "00100"; -- without immediate + constant c_rdma_packetiser_opcode_uc_send_only_imm : std_logic_vector := "001" & "00101"; -- with immediate + constant c_rdma_packetiser_opcode_uc_write_first : std_logic_vector := "001" & "00110"; + constant c_rdma_packetiser_opcode_uc_write_middle : std_logic_vector := "001" & "00111"; + constant c_rdma_packetiser_opcode_uc_write_last : std_logic_vector := "001" & "01000"; -- without immediate + constant c_rdma_packetiser_opcode_uc_write_last_imm : std_logic_vector := "001" & "01001"; -- with immediate + constant c_rdma_packetiser_opcode_uc_write_only : std_logic_vector := "001" & "01010"; -- without immediate + constant c_rdma_packetiser_opcode_uc_write_only_imm : std_logic_vector := "001" & "01011"; -- with immediate function func_rdma_packetiser_map_header(hdr_fields_raw : std_logic_vector; use_immediate : boolean) return t_rdma_packetiser_roce_header; diff --git a/applications/rdma_demo/libraries/rdma_packetiser/tb/vhdl/tb_rdma_packetiser_assemble_header.vhd b/applications/rdma_demo/libraries/rdma_packetiser/tb/vhdl/tb_rdma_packetiser_assemble_header.vhd index 9644b24454b1803bf9820a447a8113a797d07ea6..b6a19a3744ecbbf954656b5f6af1b60f151dd18d 100644 --- a/applications/rdma_demo/libraries/rdma_packetiser/tb/vhdl/tb_rdma_packetiser_assemble_header.vhd +++ b/applications/rdma_demo/libraries/rdma_packetiser/tb/vhdl/tb_rdma_packetiser_assemble_header.vhd @@ -21,15 +21,24 @@ ------------------------------------------------------------------------------- -- -- Author: R. vd Walle - -- Purpose: -- . test bench for rdma_packetiser_assemble_header -- Description: -- . Generates DP data using proc_dp_gen_block_data that streams into DUT. -- . Verifies the resulting header field array comming from the DUT by -- comparing to expected values. --- Remark: --- . +-- . The generics can be used to test specific conditions. +-- . g_use_immediate: When true, the DUT will use the optional immediate data +-- field. +-- . g_use_msg_cnt_as_immediate: When true, the DUT will use the message count +-- value as immediate data. When false, the DUT sets the immediate data to +-- the value of the immediate_data input port. +-- . g_nof_rep: number of packets the TB should generate. +-- . g_frame_len: length of the data frames that the TB should generate. +-- . g_start_address: 64 bit value to use as a start address for the DUT +-- . g_nof_packets_in_msg: The number of packets the DUT should put in one +-- RDMA message. +-- . g_nof_msg: Number of RDMA messages the DUT should create. ------------------------------------------------------------------------------- library IEEE, common_lib, dp_lib; @@ -48,7 +57,7 @@ entity tb_rdma_packetiser_assemble_header is generic ( g_use_immediate : boolean := true; g_use_msg_cnt_as_immediate : boolean := true; - g_nof_rep : natural := 15; + g_nof_rep : natural := 60; g_frame_len : natural := 15; g_start_address : unsigned(c_longword_w - 1 downto 0) := (others => '0'); g_nof_packets_in_msg : natural := 4; @@ -80,7 +89,7 @@ architecture tb of tb_rdma_packetiser_assemble_header is signal start_address : std_logic_vector(c_longword_w - 1 downto 0) := std_logic_vector(g_start_address); signal hdr_fields_slv : std_logic_vector(1023 downto 0) := (others => '0'); - signal rdma_header : t_rdma_packetiser_roce_header; + signal rx_rdma_header : t_rdma_packetiser_roce_header; signal exp_rdma_header : t_rdma_packetiser_roce_header := func_rdma_packetiser_map_header(c_hdr_fields_slv_rst, g_use_immediate); signal in_en : std_logic := '0'; @@ -90,7 +99,7 @@ begin dp_rst <= '1', '0' after c_dp_clk_period * 7; dp_clk <= (not dp_clk) or tb_end after c_dp_clk_period / 2; - rdma_header <= func_rdma_packetiser_map_header(hdr_fields_slv, g_use_immediate ); + rx_rdma_header <= func_rdma_packetiser_map_header(hdr_fields_slv, g_use_immediate ); p_dp_stimuli : process begin @@ -107,7 +116,7 @@ begin end process; -- check if values in rdma_packetiser_assemble_header match with expected values - p_rdma_packetiser_assemble_header_stimuli : process + p_verify_rdma_header : process variable v_exp_ip_total_length : natural; variable v_exp_udp_total_length : natural; variable v_exp_bth_opcode : std_logic_vector(c_byte_w - 1 downto 0); @@ -132,14 +141,14 @@ begin if v_p mod g_nof_packets_in_msg = 0 then v_exp_bth_opcode := c_rdma_packetiser_opcode_uc_write_first; if g_nof_packets_in_msg = 1 and g_use_immediate then - v_exp_bth_opcode := c_rdma_packetiser_opcode_uc_write_only_im; + v_exp_bth_opcode := c_rdma_packetiser_opcode_uc_write_only_imm; elsif g_nof_packets_in_msg = 1 then v_exp_bth_opcode := c_rdma_packetiser_opcode_uc_write_only; end if; elsif v_p mod g_nof_packets_in_msg = g_nof_packets_in_msg - 1 then v_exp_bth_opcode := c_rdma_packetiser_opcode_uc_write_last; if g_use_immediate then - v_exp_bth_opcode := c_rdma_packetiser_opcode_uc_write_last_im; + v_exp_bth_opcode := c_rdma_packetiser_opcode_uc_write_last_imm; end if; else v_exp_bth_opcode := c_rdma_packetiser_opcode_uc_write_middle; @@ -160,13 +169,14 @@ begin proc_common_wait_some_cycles(dp_clk, 1); -- assert when header is not as expected. - assert TO_UINT(rdma_header.ip.total_length) = v_exp_ip_total_length report "Wrong rdma_header.ip.total_length value" severity error; - assert TO_UINT(rdma_header.udp.total_length) = v_exp_udp_total_length report "Wrong rdma_header.udp.total_length value" severity error; - assert rdma_header.bth.opcode = v_exp_bth_opcode report "Wrong rdma_header.bth.opcode value" severity error; - assert TO_UINT(rdma_header.bth.psn) = v_exp_bth_psn report "Wrong rdma_header.bth.psn value" severity error; - assert unsigned(rdma_header.reth.virtual_address) = v_exp_reth_virtual_address report "Wrong rdma_header.reth.virtual_address value" severity error; - assert TO_UINT(rdma_header.reth.dma_length) = v_exp_reth_dma_length report "Wrong rdma_header.reth.dma_length value" severity error; - assert rdma_header.immediate_data = v_exp_immediate_data report "Wrong rdma_header.immediate_data value" severity error; + assert rx_rdma_header = exp_rdma_header report "Wrong rx_rdma_header" severity error; + assert rx_rdma_header.ip.total_length = exp_rdma_header.ip.total_length report "Wrong rx_rdma_header.ip.total_length value" severity error; + assert rx_rdma_header.udp.total_length = exp_rdma_header.udp.total_length report "Wrong rx_rdma_header.udp.total_length value" severity error; + assert rx_rdma_header.bth.opcode = exp_rdma_header.bth.opcode report "Wrong rx_rdma_header.bth.opcode value" severity error; + assert rx_rdma_header.bth.psn = exp_rdma_header.bth.psn report "Wrong rx_rdma_header.bth.psn value" severity error; + assert rx_rdma_header.reth.virtual_address = exp_rdma_header.reth.virtual_address report "Wrong rx_rdma_header.reth.virtual_address value" severity error; + assert rx_rdma_header.reth.dma_length = exp_rdma_header.reth.dma_length report "Wrong rx_rdma_header.reth.dma_length value" severity error; + assert rx_rdma_header.immediate_data = exp_rdma_header.immediate_data report "Wrong rx_rdma_header.immediate_data value" severity error; end loop; proc_common_wait_some_cycles(dp_clk, 100); diff --git a/applications/rdma_demo/libraries/rdma_packetiser/tb/vhdl/tb_tb_rdma_packetiser_assemble_header.vhd b/applications/rdma_demo/libraries/rdma_packetiser/tb/vhdl/tb_tb_rdma_packetiser_assemble_header.vhd index 4bc4b5ebe94a6a037caa0fbb4291cb775306dba2..f660180caa85165c58e1994f55addcf8c66bdc66 100644 --- a/applications/rdma_demo/libraries/rdma_packetiser/tb/vhdl/tb_tb_rdma_packetiser_assemble_header.vhd +++ b/applications/rdma_demo/libraries/rdma_packetiser/tb/vhdl/tb_tb_rdma_packetiser_assemble_header.vhd @@ -48,14 +48,14 @@ begin -- g_nof_packets_in_msg : natural := 4; -- g_nof_msg : natural := 3 - u_lo_addr : entity work.tb_rdma_packetiser_assemble_header generic map( true, true, 20, 15, c_low_start_addr, 4, 5); - u_hi_addr : entity work.tb_rdma_packetiser_assemble_header generic map( true, true, 20, 15, c_high_start_addr, 4, 5); - u_no_mid : entity work.tb_rdma_packetiser_assemble_header generic map( true, true, 20, 15, c_high_start_addr, 2, 5); - u_wr_only : entity work.tb_rdma_packetiser_assemble_header generic map( true, true, 20, 15, c_high_start_addr, 1, 5); - u_large : entity work.tb_rdma_packetiser_assemble_header generic map( true, true, 10, 2000, c_low_start_addr, 3, 1); - u_no_im_cnt : entity work.tb_rdma_packetiser_assemble_header generic map( false, true, 100, 15, c_low_start_addr, 4, 10); - u_no_cnt : entity work.tb_rdma_packetiser_assemble_header generic map( true, false, 20, 15, c_low_start_addr, 4, 5); - u_no_im : entity work.tb_rdma_packetiser_assemble_header generic map( false, false, 30, 7, c_high_start_addr, 3, 2); - u_two : entity work.tb_rdma_packetiser_assemble_header generic map( true, true, 20, 2, c_low_start_addr, 1, 5); - u_many : entity work.tb_rdma_packetiser_assemble_header generic map( true, true, 6000, 3, c_low_start_addr, 5, 1000); + u_lo_addr : entity work.tb_rdma_packetiser_assemble_header generic map( true, true, 20, 15, c_low_start_addr, 4, 5); + u_hi_addr : entity work.tb_rdma_packetiser_assemble_header generic map( true, true, 20, 15, c_high_start_addr, 4, 5); + u_no_mid : entity work.tb_rdma_packetiser_assemble_header generic map( true, true, 20, 15, c_high_start_addr, 2, 5); + u_wr_only : entity work.tb_rdma_packetiser_assemble_header generic map( true, true, 20, 15, c_high_start_addr, 1, 5); + u_large : entity work.tb_rdma_packetiser_assemble_header generic map( true, true, 10, 2000, c_low_start_addr, 3, 1); + u_no_imm_cnt : entity work.tb_rdma_packetiser_assemble_header generic map( false, true, 100, 15, c_low_start_addr, 4, 10); + u_no_cnt : entity work.tb_rdma_packetiser_assemble_header generic map( true, false, 20, 15, c_low_start_addr, 4, 5); + u_no_imm : entity work.tb_rdma_packetiser_assemble_header generic map( false, false, 30, 7, c_high_start_addr, 3, 2); + u_one : entity work.tb_rdma_packetiser_assemble_header generic map( true, true, 20, 1, c_low_start_addr, 1, 5); + u_many : entity work.tb_rdma_packetiser_assemble_header generic map( true, true, 6000, 3, c_low_start_addr, 5, 1000); end tb;