Skip to content
Snippets Groups Projects
Commit f6b95cf0 authored by Reinier van der Walle's avatar Reinier van der Walle
Browse files

processed review comments

parent e1153b5f
No related branches found
No related tags found
1 merge request!358initial commit of rdma_packetiser library
Pipeline #59898 passed
......@@ -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
-- 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.
-- 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.
-- . 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,92 +92,82 @@ 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;
if v.msg_cnt = 0 then -- set on new message
v.virtual_address := unsigned(start_address);
v.dma_len := unsigned(dma_len);
v.udp_total_length := c_udp_app_hdr_length + to_uint(block_len) + c_rdma_packetiser_roce_icrc_len;
v.ip_total_length := c_ip_udp_app_hdr_length + to_uint(block_len) + c_rdma_packetiser_roce_icrc_len;
v.nof_packets_in_msg := to_uint(nof_packets_in_msg);
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;
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
v.opcode := c_rdma_packetiser_opcode_uc_write_only_im;
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_first =>
if snk_in.sop = '1' and v.nof_packets_in_msg > 2 then
v.state := s_middle;
when s_middle => -- wait unitl the first packet is done and set next opcode.
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
if q.p_cnt >= v.nof_packets_in_msg - 2 then -- wait until last middle packet
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;
when s_last => -- next packet must be last packet, set opcode.
v.state := s_first;
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;
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;
elsif snk_in.sop = '1' then
v.p_cnt := q.p_cnt + 1;
end case;
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;
if v.msg_cnt = 0 then -- set on new message
v.virtual_address := unsigned(start_address);
v.dma_len := unsigned(dma_len);
v.udp_total_length := c_udp_app_hdr_length + to_uint(block_len) + c_rdma_packetiser_roce_icrc_len;
v.ip_total_length := c_ip_udp_app_hdr_length + to_uint(block_len) + c_rdma_packetiser_roce_icrc_len;
v.nof_packets_in_msg := to_uint(nof_packets_in_msg);
v.immediate_data := immediate_data;
end if;
end case;
if st_rst = '1' then
v := c_reg_rst;
......
......@@ -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;
......@@ -192,16 +195,16 @@ package rdma_packetiser_pkg is
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_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";
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_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;
......
......@@ -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);
......
......@@ -53,9 +53,9 @@ begin
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_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_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_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;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment