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
Branches
No related tags found
1 merge request!358initial commit of rdma_packetiser library
Pipeline #59898 passed
...@@ -20,13 +20,35 @@ ...@@ -20,13 +20,35 @@
-- Author: R. van der Walle -- Author: R. van der Walle
-- Purpose: Assembles the RDMA header at snk_in.sop -- Purpose: Assembles the RDMA header at snk_in.sop
-- Description: -- 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 -- contain the RoCEv2 (RDMA over Converged Ethernet v2) header information for
-- the corresponding data frame. -- the corresponding data frame.
-- Remark -- . The virtual_address is set automatically by increasing it with dma_len every
-- . The incoming data frame on snk_in should consist of at least 2 clock cycles. -- new message. The virtual address is reset to "start_address" when the number
-- i.e. two consecutive 1 cycle frames (sop + eop on the same clock cycle) -- of messages has reached "nof_msg". Then the cycle repeats.
-- without a gap inbetween is not supported. -- . 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; library IEEE, common_lib, dp_lib, eth_lib;
use IEEE.std_logic_1164.all; use IEEE.std_logic_1164.all;
...@@ -61,7 +83,6 @@ entity rdma_packetiser_assemble_header is ...@@ -61,7 +83,6 @@ entity rdma_packetiser_assemble_header is
nof_msg : in std_logic_vector(c_word_w - 1 downto 0); 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 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) start_address : in std_logic_vector(c_longword_w - 1 downto 0)
); );
end rdma_packetiser_assemble_header; end rdma_packetiser_assemble_header;
...@@ -71,92 +92,82 @@ architecture str of rdma_packetiser_assemble_header is ...@@ -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_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; 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_state is (s_first, s_middle, s_last);
type t_reg is record type t_reg is record -- record to keep the registers organized.
state : t_state; state : t_state;
opcode : std_logic_vector(c_byte_w - 1 downto 0); 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); 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); psn : std_logic_vector(c_word_w - 1 downto 0);
virtual_address : unsigned(c_longword_w - 1 downto 0); virtual_address : unsigned(c_longword_w - 1 downto 0);
dma_len : unsigned(c_word_w - 1 downto 0); dma_len : unsigned(c_word_w - 1 downto 0);
p_cnt : natural; p_cnt : natural; -- Packet count (0 to nof_packets_in_msg).
msg_cnt : natural; msg_cnt : natural; -- message count (0 to nof_msg).
udp_total_length : natural; udp_total_length : natural;
ip_total_length : natural; ip_total_length : natural;
nof_packets_in_msg : natural; nof_packets_in_msg : natural;
end record; 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; signal d, q : t_reg;
begin begin
q <= d when rising_edge(st_clk); 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) 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; variable v : t_reg;
begin begin
v := q; 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.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.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 if;
case q.state is if v.nof_packets_in_msg = 1 then -- set opcode to write_only.
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; v.opcode := c_rdma_packetiser_opcode_uc_write_only;
if g_use_immediate then if g_use_immediate then -- set opcode to write_only with immediate data.
v.opcode := c_rdma_packetiser_opcode_uc_write_only_im; v.opcode := c_rdma_packetiser_opcode_uc_write_only_imm;
end if; 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; end if;
when s_first => when s_middle => -- wait unitl the first packet is done and set next opcode.
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.opcode := c_rdma_packetiser_opcode_uc_write_middle;
v.p_cnt := q.p_cnt + 1; if q.p_cnt >= v.nof_packets_in_msg - 2 then -- wait until last middle packet
elsif snk_in.sop = '1' and v.nof_packets_in_msg = 2 then
v.state := s_last; 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; end if;
when s_middle => when s_last => -- next packet must be last packet, set opcode.
if snk_in.sop = '1' and q.p_cnt >= v.nof_packets_in_msg - 1 then v.state := s_first;
v.state := s_last;
v.opcode := c_rdma_packetiser_opcode_uc_write_last; v.opcode := c_rdma_packetiser_opcode_uc_write_last;
v.p_cnt := q.p_cnt + 1; if g_use_immediate then -- set opcode to write_last with immediate data
if g_use_immediate then v.opcode := c_rdma_packetiser_opcode_uc_write_last_imm;
v.opcode := c_rdma_packetiser_opcode_uc_write_last_im;
end if; end if;
elsif snk_in.sop = '1' then end case;
v.p_cnt := q.p_cnt + 1;
end if; end if;
when s_last => if v.msg_cnt = 0 then -- set on new message
v.state := s_idle; v.virtual_address := unsigned(start_address);
v.p_cnt := 0; v.dma_len := unsigned(dma_len);
if q.msg_cnt >= to_uint(nof_msg) - 1 then v.udp_total_length := c_udp_app_hdr_length + to_uint(block_len) + c_rdma_packetiser_roce_icrc_len;
v.msg_cnt := 0; v.ip_total_length := c_ip_udp_app_hdr_length + to_uint(block_len) + c_rdma_packetiser_roce_icrc_len;
else v.nof_packets_in_msg := to_uint(nof_packets_in_msg);
v.msg_cnt := q.msg_cnt + 1; v.immediate_data := immediate_data;
v.virtual_address := q.virtual_address + q.dma_len;
end if; end if;
end case;
if st_rst = '1' then if st_rst = '1' then
v := c_reg_rst; v := c_reg_rst;
......
...@@ -17,11 +17,14 @@ ...@@ -17,11 +17,14 @@
-- limitations under the License. -- limitations under the License.
-- --
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
-- Author: R. vd Walle -- Author: R. vd Walle
-- Purpose: This package contains rdma_generator specific constants and/or functions -- Purpose: This package contains rdma_packetiser specific constants and/or functions
-- Description: -- Description: See [1] for RDMA explanation.
-- -- References:
-- . [1] https://support.astron.nl/confluence/x/3pKrB
-------------------------------------------------------------------------------
library IEEE, common_lib; library IEEE, common_lib;
use IEEE.std_logic_1164.all; use IEEE.std_logic_1164.all;
use common_lib.common_pkg.all; use common_lib.common_pkg.all;
...@@ -90,97 +93,97 @@ package rdma_packetiser_pkg is ...@@ -90,97 +93,97 @@ package rdma_packetiser_pkg is
constant c_rdma_packetiser_roce_hdr_field_arr : t_common_field_arr( constant c_rdma_packetiser_roce_hdr_field_arr : t_common_field_arr(
c_rdma_packetiser_roce_nof_hdr_fields - 1 downto 0) := ( 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_dst_mac" ), "RW", 48, field_default(0) ), -- set by M&C
( field_name_pad("eth_src_mac" ), "RW", 48, field_default(0) ), ( 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") ), ( 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_version" ), "RW", 4, field_default(4) ), -- fixed
( field_name_pad("ip_header_length" ), "RW", 4, field_default(5) ), ( field_name_pad("ip_header_length" ), "RW", 4, field_default(5) ), -- fixed
( field_name_pad("ip_services" ), "RW", 8, field_default(0) ), ( field_name_pad("ip_services" ), "RW", 8, field_default(0) ), -- fixed
( 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_total_length" ), "RW", 16, field_default(0) ), -- set by data path
( field_name_pad("ip_identification" ), "RW", 16, field_default(0) ), ( field_name_pad("ip_identification" ), "RW", 16, field_default(0) ), -- fixed
( field_name_pad("ip_flags" ), "RW", 3, field_default(2) ), ( field_name_pad("ip_flags" ), "RW", 3, field_default(2) ), -- fixed
( field_name_pad("ip_fragment_offset" ), "RW", 13, field_default(0) ), ( field_name_pad("ip_fragment_offset" ), "RW", 13, field_default(0) ), -- fixed
( field_name_pad("ip_time_to_live" ), "RW", 8, field_default(127) ), ( field_name_pad("ip_time_to_live" ), "RW", 8, field_default(127) ), -- fixed
( field_name_pad("ip_protocol" ), "RW", 8, field_default(17) ), ( field_name_pad("ip_protocol" ), "RW", 8, field_default(17) ), -- fixed
( field_name_pad("ip_header_checksum" ), "RW", 16, field_default(0) ), ( 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) ), ( 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) ), -- c_eth_tester_ip_dst_addr ( 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_src_port" ), "RW", 16, field_default(0) ), -- set by M&C
( field_name_pad("udp_dst_port" ), "RW", 16, field_default(0) ), -- c_eth_tester_udp_dst_port ( 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) ), -- depends on BG block size, so set by data path ( 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) ), ( 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_opcode" ), "RW", 8, field_default(x"FF") ), -- set by data path
( field_name_pad("bth_se" ), "RW", 1, field_default(0) ), ( field_name_pad("bth_se" ), "RW", 1, field_default(0) ), -- set by M&C
( field_name_pad("bth_m" ), "RW", 1, field_default(0) ), ( field_name_pad("bth_m" ), "RW", 1, field_default(0) ), -- set by M&C
( field_name_pad("bth_pad" ), "RW", 2, field_default(0) ), ( field_name_pad("bth_pad" ), "RW", 2, field_default(0) ), -- set by M&C
( field_name_pad("bth_tver" ), "RW", 4, field_default(0) ), ( 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) ), ( 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) ), ( field_name_pad("bth_fres" ), "RW", 1, field_default(0) ), -- set by M&C
( field_name_pad("bth_bres" ), "RW", 1, field_default(0) ), ( 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) ), ( field_name_pad("bth_reserved_a" ), "RW", 6, field_default(0) ), -- fixed
( field_name_pad("bth_dest_qp" ), "RW", 16, field_default(0) ), ( 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) ), ( 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) ), ( field_name_pad("bth_reserved_b" ), "RW", 7, field_default(0) ), -- fixed
( field_name_pad("bth_psn" ), "RW", 32, field_default(0) ), ( 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_virtual_address"), "RW", 64, field_default(0) ), -- set by data path
( field_name_pad("reth_r_key" ), "RW", 32, field_default(0) ), ( 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) ), ( 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_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; 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 -- 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_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_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( 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) := ( 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_dst_mac" ), "RW", 48, field_default(0) ), -- set by M&C
( field_name_pad("eth_src_mac" ), "RW", 48, field_default(0) ), ( 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") ), ( 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_version" ), "RW", 4, field_default(4) ), -- fixed
( field_name_pad("ip_header_length" ), "RW", 4, field_default(5) ), ( field_name_pad("ip_header_length" ), "RW", 4, field_default(5) ), -- fixed
( field_name_pad("ip_services" ), "RW", 8, field_default(0) ), ( field_name_pad("ip_services" ), "RW", 8, field_default(0) ), -- fixed
( 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_total_length" ), "RW", 16, field_default(0) ), -- set by data path
( field_name_pad("ip_identification" ), "RW", 16, field_default(0) ), ( field_name_pad("ip_identification" ), "RW", 16, field_default(0) ), -- fixed
( field_name_pad("ip_flags" ), "RW", 3, field_default(2) ), ( field_name_pad("ip_flags" ), "RW", 3, field_default(2) ), -- fixed
( field_name_pad("ip_fragment_offset" ), "RW", 13, field_default(0) ), ( field_name_pad("ip_fragment_offset" ), "RW", 13, field_default(0) ), -- fixed
( field_name_pad("ip_time_to_live" ), "RW", 8, field_default(127) ), ( field_name_pad("ip_time_to_live" ), "RW", 8, field_default(127) ), -- fixed
( field_name_pad("ip_protocol" ), "RW", 8, field_default(17) ), ( field_name_pad("ip_protocol" ), "RW", 8, field_default(17) ), -- fixed
( field_name_pad("ip_header_checksum" ), "RW", 16, field_default(0) ), ( 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) ), ( 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) ), -- c_eth_tester_ip_dst_addr ( 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_src_port" ), "RW", 16, field_default(0) ), -- set by M&C
( field_name_pad("udp_dst_port" ), "RW", 16, field_default(0) ), -- c_eth_tester_udp_dst_port ( 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) ), -- depends on BG block size, so set by data path ( 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) ), ( 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_opcode" ), "RW", 8, field_default(x"FF") ), -- set by data path
( field_name_pad("bth_se" ), "RW", 1, field_default(0) ), ( field_name_pad("bth_se" ), "RW", 1, field_default(0) ), -- set by M&C
( field_name_pad("bth_m" ), "RW", 1, field_default(0) ), ( field_name_pad("bth_m" ), "RW", 1, field_default(0) ), -- set by M&C
( field_name_pad("bth_pad" ), "RW", 2, field_default(0) ), ( field_name_pad("bth_pad" ), "RW", 2, field_default(0) ), -- set by M&C
( field_name_pad("bth_tver" ), "RW", 4, field_default(0) ), ( 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) ), ( 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) ), ( field_name_pad("bth_fres" ), "RW", 1, field_default(0) ), -- set by M&C
( field_name_pad("bth_bres" ), "RW", 1, field_default(0) ), ( 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) ), ( field_name_pad("bth_reserved_a" ), "RW", 6, field_default(0) ), -- fixed
( field_name_pad("bth_dest_qp" ), "RW", 16, field_default(0) ), ( 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) ), ( 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) ), ( field_name_pad("bth_reserved_b" ), "RW", 7, field_default(0) ), -- fixed
( field_name_pad("bth_psn" ), "RW", 32, field_default(0) ), ( 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_virtual_address"), "RW", 64, field_default(0) ), -- set by data path
( field_name_pad("reth_r_key" ), "RW", 32, field_default(0) ), ( 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) ) ( 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_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; 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 ...@@ -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_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_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 : std_logic_vector := "001" & "00010"; -- without immediate
constant c_rdma_packetiser_opcode_uc_send_last_im : std_logic_vector := "001" & "00011"; 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"; constant c_rdma_packetiser_opcode_uc_send_only : std_logic_vector := "001" & "00100"; -- without immediate
constant c_rdma_packetiser_opcode_uc_send_only_im : std_logic_vector := "001" & "00101"; 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_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_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 : std_logic_vector := "001" & "01000"; -- without immediate
constant c_rdma_packetiser_opcode_uc_write_last_im : std_logic_vector := "001" & "01001"; 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"; constant c_rdma_packetiser_opcode_uc_write_only : std_logic_vector := "001" & "01010"; -- without immediate
constant c_rdma_packetiser_opcode_uc_write_only_im : std_logic_vector := "001" & "01011"; 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; 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 @@ ...@@ -21,15 +21,24 @@
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- --
-- Author: R. vd Walle -- Author: R. vd Walle
-- Purpose: -- Purpose:
-- . test bench for rdma_packetiser_assemble_header -- . test bench for rdma_packetiser_assemble_header
-- Description: -- Description:
-- . Generates DP data using proc_dp_gen_block_data that streams into DUT. -- . Generates DP data using proc_dp_gen_block_data that streams into DUT.
-- . Verifies the resulting header field array comming from the DUT by -- . Verifies the resulting header field array comming from the DUT by
-- comparing to expected values. -- 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; library IEEE, common_lib, dp_lib;
...@@ -48,7 +57,7 @@ entity tb_rdma_packetiser_assemble_header is ...@@ -48,7 +57,7 @@ entity tb_rdma_packetiser_assemble_header is
generic ( generic (
g_use_immediate : boolean := true; g_use_immediate : boolean := true;
g_use_msg_cnt_as_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_frame_len : natural := 15;
g_start_address : unsigned(c_longword_w - 1 downto 0) := (others => '0'); g_start_address : unsigned(c_longword_w - 1 downto 0) := (others => '0');
g_nof_packets_in_msg : natural := 4; g_nof_packets_in_msg : natural := 4;
...@@ -80,7 +89,7 @@ architecture tb of tb_rdma_packetiser_assemble_header is ...@@ -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 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 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 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'; signal in_en : std_logic := '0';
...@@ -90,7 +99,7 @@ begin ...@@ -90,7 +99,7 @@ begin
dp_rst <= '1', '0' after c_dp_clk_period * 7; dp_rst <= '1', '0' after c_dp_clk_period * 7;
dp_clk <= (not dp_clk) or tb_end after c_dp_clk_period / 2; 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 p_dp_stimuli : process
begin begin
...@@ -107,7 +116,7 @@ begin ...@@ -107,7 +116,7 @@ begin
end process; end process;
-- check if values in rdma_packetiser_assemble_header match with expected values -- 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_ip_total_length : natural;
variable v_exp_udp_total_length : natural; variable v_exp_udp_total_length : natural;
variable v_exp_bth_opcode : std_logic_vector(c_byte_w - 1 downto 0); variable v_exp_bth_opcode : std_logic_vector(c_byte_w - 1 downto 0);
...@@ -132,14 +141,14 @@ begin ...@@ -132,14 +141,14 @@ begin
if v_p mod g_nof_packets_in_msg = 0 then if v_p mod g_nof_packets_in_msg = 0 then
v_exp_bth_opcode := c_rdma_packetiser_opcode_uc_write_first; v_exp_bth_opcode := c_rdma_packetiser_opcode_uc_write_first;
if g_nof_packets_in_msg = 1 and g_use_immediate then 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 elsif g_nof_packets_in_msg = 1 then
v_exp_bth_opcode := c_rdma_packetiser_opcode_uc_write_only; v_exp_bth_opcode := c_rdma_packetiser_opcode_uc_write_only;
end if; end if;
elsif v_p mod g_nof_packets_in_msg = g_nof_packets_in_msg - 1 then 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; v_exp_bth_opcode := c_rdma_packetiser_opcode_uc_write_last;
if g_use_immediate then 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; end if;
else else
v_exp_bth_opcode := c_rdma_packetiser_opcode_uc_write_middle; v_exp_bth_opcode := c_rdma_packetiser_opcode_uc_write_middle;
...@@ -160,13 +169,14 @@ begin ...@@ -160,13 +169,14 @@ begin
proc_common_wait_some_cycles(dp_clk, 1); proc_common_wait_some_cycles(dp_clk, 1);
-- assert when header is not as expected. -- 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 rx_rdma_header = exp_rdma_header report "Wrong rx_rdma_header" 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 rx_rdma_header.ip.total_length = exp_rdma_header.ip.total_length report "Wrong rx_rdma_header.ip.total_length value" severity error;
assert rdma_header.bth.opcode = v_exp_bth_opcode report "Wrong rdma_header.bth.opcode 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 TO_UINT(rdma_header.bth.psn) = v_exp_bth_psn report "Wrong rdma_header.bth.psn 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 unsigned(rdma_header.reth.virtual_address) = v_exp_reth_virtual_address report "Wrong rdma_header.reth.virtual_address 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 TO_UINT(rdma_header.reth.dma_length) = v_exp_reth_dma_length report "Wrong rdma_header.reth.dma_length 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 rdma_header.immediate_data = v_exp_immediate_data report "Wrong rdma_header.immediate_data 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; end loop;
proc_common_wait_some_cycles(dp_clk, 100); proc_common_wait_some_cycles(dp_clk, 100);
......
...@@ -53,9 +53,9 @@ begin ...@@ -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_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_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_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_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_no_imm : 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_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); u_many : entity work.tb_rdma_packetiser_assemble_header generic map( true, true, 6000, 3, c_low_start_addr, 5, 1000);
end tb; end tb;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment