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

Merge branch 'HPR-130' into 'master'

HPR-130:

Closes HPR-130

See merge request !365
parents 5c6fa1f8 5971bb0a
No related branches found
No related tags found
1 merge request!365HPR-130:
Pipeline #63953 passed
...@@ -10,10 +10,8 @@ synth_files = ...@@ -10,10 +10,8 @@ synth_files =
test_bench_files = test_bench_files =
tb/vhdl/tb_rdma_packetiser_assemble_header.vhd tb/vhdl/tb_rdma_packetiser_assemble_header.vhd
tb/vhdl/tb_tb_rdma_packetiser_assemble_header.vhd
regression_test_vhdl = regression_test_vhdl =
tb/vhdl/tb_tb_rdma_packetiser_assemble_header.vhd
[modelsim_project_file] [modelsim_project_file]
......
...@@ -18,29 +18,28 @@ ...@@ -18,29 +18,28 @@
-- --
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- 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 and inserts it in front of
-- the incoming data stream
-- Description: -- Description:
-- Generates a RoCEv2 header (ETH + UDP + IP + RDMA). See [1]. -- Generates a RoCEv2 header (ETH + UDP + IP + RDMA). See [1]. Then it prepends
-- Generics: -- the generated header to the incoming sosi data stream.
-- . g_use_immediate: When true, the immediate data field will be added to the -- MM config:
-- . config_use_immediate: When true, the immediate data field will be added to the
-- header. -- header.
-- . g_use_msg_cnt_as_immediate: When true, the message counter going from 0 to -- . config_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" -- "nof_msg" is used as immediate data. When false, the "immediate_data"
-- input port is used. -- input port is used.
-- Signal inputs:
-- . immediate_data: Will be used as immediate data when -- . immediate_data: Will be used as immediate data when
-- g_use_msg_cnt_as_immediate = False. -- config_use_msg_cnt_as_immediate = False.
-- . block_len: Should be set to the length of the incoming data frame in octets. -- . config_nof_packets_in_msg: Should be set to the desired amount of packets in a message.
-- . nof_packets_in_msg: Should be set to the desired amount of packets in a message. -- . config_nof_msg: Should be set to the desired amount of messages, this determines the
-- . nof_msg: Should be set to the desired amount of messages, this determines the
-- address space aswell, see remarks. -- address space aswell, see remarks.
-- . dma_len: The amount with which the address should increase every message, -- . reth_dma_len: The amount with which the address should increase every message,
-- this should be set to >= nof_packets_in_msg * block_len. -- this should be set to >= nof_packets_in_msg * block_len.
-- . start_address: The start address for the virtual_address field. -- . config_start_address: The start address for the virtual_address field.
-- Signal inputs:
-- . block_len: Should be set to the length of the incoming data frame in octets.
-- Remarks -- 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 -- . 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 -- new message. The virtual address is reset to "start_address" when the number
-- of messages has reached "nof_msg". Then the cycle repeats. -- of messages has reached "nof_msg". Then the cycle repeats.
...@@ -65,38 +64,38 @@ library IEEE, common_lib, dp_lib, eth_lib; ...@@ -65,38 +64,38 @@ library IEEE, common_lib, dp_lib, eth_lib;
entity rdma_packetiser_assemble_header is entity rdma_packetiser_assemble_header is
generic ( generic (
g_use_immediate : boolean := true; g_data_w : natural := 512
g_use_msg_cnt_as_immediate : boolean := true
); );
port ( port (
-- Clocks and reset -- Clocks and reset
st_clk : in std_logic; st_clk : in std_logic;
st_rst : in std_logic; st_rst : in std_logic;
mm_clk : in std_logic;
mm_rst : in std_logic;
reg_hdr_dat_copi : in t_mem_copi := c_mem_copi_rst;
reg_hdr_dat_cipo : out t_mem_cipo;
snk_in : in t_dp_sosi := c_dp_sosi_rst; snk_in : in t_dp_sosi := c_dp_sosi_rst;
snk_out : out t_dp_siso := c_dp_siso_rdy;
hdr_fields_slv : out std_logic_vector(1023 downto 0) := (others => '0'); src_out : out t_dp_sosi := c_dp_sosi_rst;
src_in : in t_dp_siso := c_dp_siso_rdy;
immediate_data : in std_logic_vector(c_rdma_packetiser_roce_imm_len * c_octet_w - 1 downto 0) := (others => '0'); block_len : in std_logic_vector(c_halfword_w - 1 downto 0) -- in octets
block_len : in std_logic_vector(c_halfword_w - 1 downto 0); -- in octets
nof_packets_in_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
start_address : in std_logic_vector(c_longword_w - 1 downto 0)
); );
end rdma_packetiser_assemble_header; end rdma_packetiser_assemble_header;
architecture str of rdma_packetiser_assemble_header is architecture str of rdma_packetiser_assemble_header is
constant c_hdr_field_arr : t_common_field_arr := sel_a_b(g_use_immediate, c_rdma_packetiser_roce_hdr_field_arr, c_rdma_packetiser_roce_no_imm_hdr_field_arr); constant c_udp_app_hdr_length : natural := c_network_udp_header_len + c_rdma_packetiser_bth_len;
constant c_app_hdr_length : natural := sel_a_b(g_use_immediate, c_rdma_packetiser_roce_hdr_len, c_rdma_packetiser_roce_no_imm_hdr_len);
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;
constant c_nof_offload : natural := 4;
type t_state is (s_first, s_middle, s_last); type t_state is (s_first, s_middle, s_last);
type t_reg is record -- record to keep the registers organized. 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);
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);
...@@ -105,15 +104,61 @@ architecture str of rdma_packetiser_assemble_header is ...@@ -105,15 +104,61 @@ architecture str of rdma_packetiser_assemble_header is
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;
sel_ctrl : natural range 0 to c_nof_offload - 1;
end record; end record;
constant c_reg_rst : t_reg := (s_first, (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'), 0, 0, 0, 0, 0, 0);
signal d, q : t_reg; signal d, q : t_reg;
signal use_immediate : std_logic;
signal use_msg_cnt_as_immediate : std_logic;
signal immediate_data : std_logic_vector(c_rdma_packetiser_imm_len * c_octet_w - 1 downto 0) := (others => '0');
signal nof_packets_in_msg : std_logic_vector(c_word_w - 1 downto 0);
signal nof_msg : std_logic_vector(c_word_w - 1 downto 0);
signal dma_len : std_logic_vector(c_word_w - 1 downto 0); -- = block_len * nof_packets_in_msg
signal start_address : std_logic_vector(c_longword_w - 1 downto 0);
signal hdr_fields_slv_out_mm : std_logic_vector(1023 downto 0) := (others => '0');
signal hdr_fields_slv_in : std_logic_vector(1023 downto 0) := (others => '0');
signal hdr_fields_slv_in_first : std_logic_vector(1023 downto 0) := (others => '0');
signal hdr_fields_slv_in_mid : std_logic_vector(1023 downto 0) := (others => '0');
signal hdr_fields_slv_in_last : std_logic_vector(1023 downto 0) := (others => '0');
signal hdr_fields_slv_in_wo : std_logic_vector(1023 downto 0) := (others => '0');
signal dp_demux_src_out_arr : t_dp_sosi_arr(c_nof_offload - 1 downto 0) := (others => c_dp_sosi_rst);
signal dp_demux_src_in_arr : t_dp_siso_arr(c_nof_offload - 1 downto 0) := (others => c_dp_siso_rdy);
signal dp_mux_snk_in_arr : t_dp_sosi_arr(c_nof_offload - 1 downto 0) := (others => c_dp_sosi_rst);
signal dp_mux_snk_out_arr : t_dp_siso_arr(c_nof_offload - 1 downto 0) := (others => c_dp_siso_rdy);
signal dp_offload_first_snk_in : t_dp_sosi := c_dp_sosi_rst;
signal dp_offload_first_snk_out : t_dp_siso := c_dp_siso_rdy;
signal dp_offload_first_src_out : t_dp_sosi := c_dp_sosi_rst;
signal dp_offload_first_src_in : t_dp_siso := c_dp_siso_rdy;
signal dp_offload_mid_snk_in : t_dp_sosi := c_dp_sosi_rst;
signal dp_offload_mid_snk_out : t_dp_siso := c_dp_siso_rdy;
signal dp_offload_mid_src_out : t_dp_sosi := c_dp_sosi_rst;
signal dp_offload_mid_src_in : t_dp_siso := c_dp_siso_rdy;
signal dp_offload_last_snk_in : t_dp_sosi := c_dp_sosi_rst;
signal dp_offload_last_snk_out : t_dp_siso := c_dp_siso_rdy;
signal dp_offload_last_src_out : t_dp_sosi := c_dp_sosi_rst;
signal dp_offload_last_src_in : t_dp_siso := c_dp_siso_rdy;
signal dp_offload_wo_snk_in : t_dp_sosi := c_dp_sosi_rst;
signal dp_offload_wo_snk_out : t_dp_siso := c_dp_siso_rdy;
signal dp_offload_wo_src_out : t_dp_sosi := c_dp_sosi_rst;
signal dp_offload_wo_src_in : t_dp_siso := c_dp_siso_rdy;
signal dp_pipeline_src_out : t_dp_sosi := c_dp_sosi_rst;
begin begin
q <= d when rising_edge(st_clk); immediate_data <= hdr_fields_slv_out_mm(field_hi(c_rdma_packetiser_mm_field_arr, "immediate_data" ) downto field_lo(c_rdma_packetiser_mm_field_arr, "immediate_data" ));
use_immediate <= sl(hdr_fields_slv_out_mm(field_hi(c_rdma_packetiser_mm_field_arr, "config_use_immediate" ) downto field_lo(c_rdma_packetiser_mm_field_arr, "config_use_immediate" )));
use_msg_cnt_as_immediate <= sl(hdr_fields_slv_out_mm(field_hi(c_rdma_packetiser_mm_field_arr, "config_use_msg_cnt_as_immediate") downto field_lo(c_rdma_packetiser_mm_field_arr, "config_use_msg_cnt_as_immediate")));
nof_packets_in_msg <= hdr_fields_slv_out_mm(field_hi(c_rdma_packetiser_mm_field_arr, "config_nof_packets_in_msg" ) downto field_lo(c_rdma_packetiser_mm_field_arr, "config_nof_packets_in_msg" ));
nof_msg <= hdr_fields_slv_out_mm(field_hi(c_rdma_packetiser_mm_field_arr, "config_nof_msg" ) downto field_lo(c_rdma_packetiser_mm_field_arr, "config_nof_msg" ));
dma_len <= hdr_fields_slv_out_mm(field_hi(c_rdma_packetiser_mm_field_arr, "reth_dma_length" ) downto field_lo(c_rdma_packetiser_mm_field_arr, "reth_dma_length" ));
start_address <= hdr_fields_slv_out_mm(field_hi(c_rdma_packetiser_mm_field_arr, "config_start_address" ) downto field_lo(c_rdma_packetiser_mm_field_arr, "config_start_address" ));
-- State machine to derive RDMA header fields. -- 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) q <= d when rising_edge(st_clk);
p_comb : process(st_rst, q, snk_in, nof_packets_in_msg, start_address, nof_msg, immediate_data, dma_len, block_len, use_immediate)
variable v : t_reg; variable v : t_reg;
begin begin
v := q; v := q;
...@@ -134,19 +179,24 @@ begin ...@@ -134,19 +179,24 @@ begin
if v.nof_packets_in_msg = 1 then -- set opcode to write_only. if v.nof_packets_in_msg = 1 then -- set opcode to write_only.
v.opcode := c_rdma_packetiser_opcode_uc_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.sel_ctrl := 0;
if use_immediate = '1' then -- set opcode to write_only with immediate data.
v.opcode := c_rdma_packetiser_opcode_uc_write_only_imm; v.opcode := c_rdma_packetiser_opcode_uc_write_only_imm;
v.sel_ctrl := 3;
end if; end if;
elsif v.nof_packets_in_msg = 2 then -- set opcode to write_first. 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.state := s_last; -- next state is last as there are only 2 packets.
v.opcode := c_rdma_packetiser_opcode_uc_write_first; v.opcode := c_rdma_packetiser_opcode_uc_write_first;
v.sel_ctrl := 0;
elsif v.nof_packets_in_msg > 2 then elsif v.nof_packets_in_msg > 2 then
v.state := s_middle; v.state := s_middle;
v.opcode := c_rdma_packetiser_opcode_uc_write_first; v.opcode := c_rdma_packetiser_opcode_uc_write_first;
v.sel_ctrl := 0;
end if; end if;
when s_middle => -- wait unitl the first packet is done and set next opcode. when s_middle => -- wait unitl the first packet is done and set next opcode.
v.opcode := c_rdma_packetiser_opcode_uc_write_middle; v.opcode := c_rdma_packetiser_opcode_uc_write_middle;
v.sel_ctrl := 1;
if q.p_cnt >= v.nof_packets_in_msg - 2 then -- wait until last middle packet if q.p_cnt >= v.nof_packets_in_msg - 2 then -- wait until last middle packet
v.state := s_last; v.state := s_last;
end if; end if;
...@@ -154,8 +204,10 @@ begin ...@@ -154,8 +204,10 @@ begin
when s_last => -- next packet must be last packet, set opcode. when s_last => -- next packet must be last packet, set opcode.
v.state := s_first; v.state := s_first;
v.opcode := c_rdma_packetiser_opcode_uc_write_last; v.opcode := c_rdma_packetiser_opcode_uc_write_last;
if g_use_immediate then -- set opcode to write_last with immediate data v.sel_ctrl := 1;
if use_immediate = '1' then -- set opcode to write_last with immediate data
v.opcode := c_rdma_packetiser_opcode_uc_write_last_imm; v.opcode := c_rdma_packetiser_opcode_uc_write_last_imm;
v.sel_ctrl := 2;
end if; end if;
end case; end case;
end if; end if;
...@@ -163,10 +215,9 @@ begin ...@@ -163,10 +215,9 @@ begin
if v.msg_cnt = 0 then -- set on new message if v.msg_cnt = 0 then -- set on new message
v.virtual_address := unsigned(start_address); v.virtual_address := unsigned(start_address);
v.dma_len := unsigned(dma_len); 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.udp_total_length := c_udp_app_hdr_length + to_uint(block_len) + c_rdma_packetiser_icrc_len;
v.ip_total_length := c_ip_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_icrc_len;
v.nof_packets_in_msg := to_uint(nof_packets_in_msg); v.nof_packets_in_msg := to_uint(nof_packets_in_msg);
v.immediate_data := immediate_data;
end if; end if;
if st_rst = '1' then if st_rst = '1' then
...@@ -176,20 +227,228 @@ begin ...@@ -176,20 +227,228 @@ begin
d <= v; d <= v;
end process; end process;
hdr_fields_slv(field_hi(c_hdr_field_arr, "ip_total_length" ) downto field_lo(c_hdr_field_arr, "ip_total_length" )) <= TO_UVEC(q.ip_total_length, 16); -------------------------------------------------------------------------------
hdr_fields_slv(field_hi(c_hdr_field_arr, "udp_total_length" ) downto field_lo(c_hdr_field_arr, "udp_total_length" )) <= TO_UVEC(q.udp_total_length, 16); -- Wire the header fields
hdr_fields_slv(field_hi(c_hdr_field_arr, "bth_opcode" ) downto field_lo(c_hdr_field_arr, "bth_opcode" )) <= q.opcode; -------------------------------------------------------------------------------
hdr_fields_slv(field_hi(c_hdr_field_arr, "bth_psn" ) downto field_lo(c_hdr_field_arr, "bth_psn" )) <= q.psn; hdr_fields_slv_in(field_hi(c_rdma_packetiser_mm_field_arr, "ip_total_length" ) downto field_lo(c_rdma_packetiser_mm_field_arr, "ip_total_length" )) <= TO_UVEC(q.ip_total_length, 16);
hdr_fields_slv(field_hi(c_hdr_field_arr, "reth_virtual_address") downto field_lo(c_hdr_field_arr, "reth_virtual_address")) <= std_logic_vector(q.virtual_address); hdr_fields_slv_in(field_hi(c_rdma_packetiser_mm_field_arr, "udp_total_length" ) downto field_lo(c_rdma_packetiser_mm_field_arr, "udp_total_length" )) <= TO_UVEC(q.udp_total_length, 16);
hdr_fields_slv(field_hi(c_hdr_field_arr, "reth_dma_length" ) downto field_lo(c_hdr_field_arr, "reth_dma_length" )) <= std_logic_vector(q.dma_len); hdr_fields_slv_in(field_hi(c_rdma_packetiser_mm_field_arr, "bth_opcode" ) downto field_lo(c_rdma_packetiser_mm_field_arr, "bth_opcode" )) <= q.opcode;
hdr_fields_slv_in(field_hi(c_rdma_packetiser_mm_field_arr, "bth_psn" ) downto field_lo(c_rdma_packetiser_mm_field_arr, "bth_psn" )) <= q.psn;
gen_use_immediate : if g_use_immediate generate hdr_fields_slv_in(field_hi(c_rdma_packetiser_mm_field_arr, "reth_virtual_address") downto field_lo(c_rdma_packetiser_mm_field_arr, "reth_virtual_address")) <= std_logic_vector(q.virtual_address);
gen_use_msg_cnt : if g_use_msg_cnt_as_immediate generate hdr_fields_slv_in(field_hi(c_rdma_packetiser_mm_field_arr, "reth_dma_length" ) downto field_lo(c_rdma_packetiser_mm_field_arr, "reth_dma_length" )) <= std_logic_vector(q.dma_len);
hdr_fields_slv(field_hi(c_hdr_field_arr, "immediate_data") downto field_lo(c_hdr_field_arr, "immediate_data")) <= TO_UVEC(q.msg_cnt, 32);
end generate; -------------------------------------------------------------------------------
-- demux to guide the incoming stream to the correct dp_offload_tx_v3
gen_use_no_msg_cnt : if not g_use_msg_cnt_as_immediate generate -------------------------------------------------------------------------------
hdr_fields_slv(field_hi(c_hdr_field_arr, "immediate_data") downto field_lo(c_hdr_field_arr, "immediate_data")) <= q.immediate_data; u_dp_demux : entity dp_lib.dp_demux
end generate; generic map (
end generate; g_mode => 2,
g_nof_output => c_nof_offload,
g_combined => false,
g_sel_ctrl_invert => true,
g_sel_ctrl_pkt => true
)
port map (
rst => st_rst,
clk => st_clk,
sel_ctrl => q.sel_ctrl,
snk_in => snk_in,
snk_out => snk_out,
src_out_arr => dp_demux_src_out_arr,
src_in_arr => dp_demux_src_in_arr
);
-- Wire demux outputs to dp_offload inputs.
dp_offload_first_snk_in <= dp_demux_src_out_arr(0);
dp_offload_mid_snk_in <= dp_demux_src_out_arr(1);
dp_offload_last_snk_in <= dp_demux_src_out_arr(2);
dp_offload_wo_snk_in <= dp_demux_src_out_arr(3);
dp_demux_src_in_arr(0) <= dp_offload_first_snk_out;
dp_demux_src_in_arr(1) <= dp_offload_mid_snk_out;
dp_demux_src_in_arr(2) <= dp_offload_last_snk_out;
dp_demux_src_in_arr(3) <= dp_offload_wo_snk_out;
-- Wire header fields for every do_offload
p_wire_headers : process(hdr_fields_slv_out_mm, use_msg_cnt_as_immediate, q)
begin
-- set headers.
hdr_fields_slv_in_first <= field_select_subset(c_rdma_packetiser_first_hdr_field_arr,
c_rdma_packetiser_mm_field_arr,
hdr_fields_slv_out_mm);
hdr_fields_slv_in_mid <= field_select_subset(c_rdma_packetiser_last_hdr_field_arr,
c_rdma_packetiser_mm_field_arr,
hdr_fields_slv_out_mm);
hdr_fields_slv_in_last <= field_select_subset(c_rdma_packetiser_last_hdr_field_arr,
c_rdma_packetiser_mm_field_arr,
hdr_fields_slv_out_mm);
hdr_fields_slv_in_wo <= field_select_subset(c_rdma_packetiser_wo_hdr_field_arr,
c_rdma_packetiser_mm_field_arr,
hdr_fields_slv_out_mm);
if use_msg_cnt_as_immediate = '1' then -- set immediate data to msg_cnt when use_msg_cnt_as_immediate = '1'
hdr_fields_slv_in_last(field_hi(c_rdma_packetiser_last_hdr_field_arr, "immediate_data") downto
field_lo(c_rdma_packetiser_last_hdr_field_arr, "immediate_data")) <= TO_UVEC(q.msg_cnt, 32);
hdr_fields_slv_in_wo( field_hi(c_rdma_packetiser_wo_hdr_field_arr, "immediate_data") downto
field_lo(c_rdma_packetiser_wo_hdr_field_arr, "immediate_data")) <= TO_UVEC(q.msg_cnt, 32);
end if;
end process;
-------------------------------------------------------------------------------
-- Header for first packets or write only without immediate data
-------------------------------------------------------------------------------
u_dp_offload_first : entity dp_lib.dp_offload_tx_v3
generic map (
g_nof_streams => 1,
g_data_w => g_data_w,
g_symbol_w => c_octet_w,
g_hdr_field_arr => c_rdma_packetiser_first_hdr_field_arr,
g_hdr_field_sel => c_rdma_packetiser_first_hdr_field_sel,
g_pipeline_ready => true
)
port map (
dp_rst => st_rst,
dp_clk => st_clk,
snk_in_arr(0) => dp_offload_first_snk_in,
snk_out_arr(0) => dp_offload_first_snk_out,
src_out_arr(0) => dp_offload_first_src_out,
src_in_arr(0) => dp_offload_first_src_in,
hdr_fields_in_arr(0) => hdr_fields_slv_in_first
);
-------------------------------------------------------------------------------
-- Header for middle or last without immediate data (no RETH, no immediate data)
-------------------------------------------------------------------------------
u_dp_offload_mid : entity dp_lib.dp_offload_tx_v3
generic map (
g_nof_streams => 1,
g_data_w => g_data_w,
g_symbol_w => c_octet_w,
g_hdr_field_arr => c_rdma_packetiser_mid_hdr_field_arr,
g_hdr_field_sel => c_rdma_packetiser_mid_hdr_field_sel,
g_pipeline_ready => true
)
port map (
dp_rst => st_rst,
dp_clk => st_clk,
snk_in_arr(0) => dp_offload_mid_snk_in,
snk_out_arr(0) => dp_offload_mid_snk_out,
src_out_arr(0) => dp_offload_mid_src_out,
src_in_arr(0) => dp_offload_mid_src_in,
hdr_fields_in_arr(0) => hdr_fields_slv_in_mid
);
-------------------------------------------------------------------------------
-- Header for last packets with immediate data
-------------------------------------------------------------------------------
u_dp_offload_last : entity dp_lib.dp_offload_tx_v3
generic map (
g_nof_streams => 1,
g_data_w => g_data_w,
g_symbol_w => c_octet_w,
g_hdr_field_arr => c_rdma_packetiser_last_hdr_field_arr,
g_hdr_field_sel => c_rdma_packetiser_last_hdr_field_sel,
g_pipeline_ready => true
)
port map (
dp_rst => st_rst,
dp_clk => st_clk,
snk_in_arr(0) => dp_offload_last_snk_in,
snk_out_arr(0) => dp_offload_last_snk_out,
src_out_arr(0) => dp_offload_last_src_out,
src_in_arr(0) => dp_offload_last_src_in,
hdr_fields_in_arr(0) => hdr_fields_slv_in_last
);
-------------------------------------------------------------------------------
-- Header for write only packets with immediate data
-------------------------------------------------------------------------------
u_dp_offload_wo : entity dp_lib.dp_offload_tx_v3
generic map (
g_nof_streams => 1,
g_data_w => g_data_w,
g_symbol_w => c_octet_w,
g_hdr_field_arr => c_rdma_packetiser_wo_hdr_field_arr,
g_hdr_field_sel => c_rdma_packetiser_wo_hdr_field_sel,
g_pipeline_ready => true
)
port map (
dp_rst => st_rst,
dp_clk => st_clk,
snk_in_arr(0) => dp_offload_wo_snk_in,
snk_out_arr(0) => dp_offload_wo_snk_out,
src_out_arr(0) => dp_offload_wo_src_out,
src_in_arr(0) => dp_offload_wo_src_in,
hdr_fields_in_arr(0) => hdr_fields_slv_in_wo
);
-------------------------------------------------------------------------------
-- Using extra dp_offload_tx_v3 only for MM that contains all headers + config register
-------------------------------------------------------------------------------
-- DP pipeline to correct for state machine latency
u_dp_pipeline : entity dp_lib.dp_pipeline
port map (
rst => st_rst,
clk => st_clk,
snk_out => open,
snk_in => snk_in,
src_out => dp_pipeline_src_out
);
-- dp_offload_tx_v3
u_dp_offload_tx : entity dp_lib.dp_offload_tx_v3
generic map (
g_nof_streams => 1,
g_data_w => g_data_w,
g_symbol_w => c_octet_w,
g_hdr_field_arr => c_rdma_packetiser_mm_field_arr,
g_hdr_field_sel => c_rdma_packetiser_mm_field_sel,
g_pipeline_ready => true
)
port map (
mm_rst => mm_rst,
mm_clk => mm_clk,
dp_rst => st_rst,
dp_clk => st_clk,
reg_hdr_dat_mosi => reg_hdr_dat_copi,
reg_hdr_dat_miso => reg_hdr_dat_cipo,
snk_in_arr(0) => dp_pipeline_src_out,
hdr_fields_in_arr(0) => hdr_fields_slv_in,
hdr_fields_out_arr(0) => hdr_fields_slv_out_mm
);
-------------------------------------------------------------------------------
-- Mux to merge the packets from the different dp_offload_tx_v3
-------------------------------------------------------------------------------
-- Wire demux outputs to dp_offload inputs.
dp_mux_snk_in_arr(0) <= dp_offload_first_src_out;
dp_mux_snk_in_arr(1) <= dp_offload_mid_src_out;
dp_mux_snk_in_arr(2) <= dp_offload_last_src_out;
dp_mux_snk_in_arr(3) <= dp_offload_wo_src_out;
dp_offload_first_src_in <= dp_mux_snk_out_arr(0);
dp_offload_mid_src_in <= dp_mux_snk_out_arr(1);
dp_offload_last_src_in <= dp_mux_snk_out_arr(2);
dp_offload_wo_src_in <= dp_mux_snk_out_arr(3);
u_dp_mux : entity dp_lib.dp_mux
generic map (
g_mode => 2,
g_nof_input => c_nof_offload,
g_append_channel_lo => false,
g_sel_ctrl_invert => true,
g_use_fifo => false, -- fifo is not needed as the inputs cannot occur simultaneously.
g_fifo_size => array_init(0, c_nof_offload),
g_fifo_fill => array_init(0, c_nof_offload)
)
port map (
rst => st_rst,
clk => st_clk,
sel_ctrl => q.sel_ctrl,
snk_in_arr => dp_mux_snk_in_arr,
snk_out_arr => dp_mux_snk_out_arr,
src_out => src_out,
src_in => src_in
);
end str; end str;
...@@ -86,13 +86,14 @@ package rdma_packetiser_pkg is ...@@ -86,13 +86,14 @@ package rdma_packetiser_pkg is
-- = 0 can be achieve via data path and default hdr_fields_in_arr = 0 or -- = 0 can be achieve via data path and default hdr_fields_in_arr = 0 or
-- via MM controlled and field_default(0). -- via MM controlled and field_default(0).
-- RoCEv2 header for RDMA operation with immediate data -- RoCEv2 header for RDMA operation with all possible fields and user config fields
-- ETH + IP + UDP + Base Transport Header (BTH) + RDMA Extended Transport Header (RETH) + Immediate Data -- ETH + IP + UDP + Base Transport Header (BTH) + RDMA Extended Transport Header (RETH) + Immediate Data + user config
constant c_rdma_packetiser_roce_nof_hdr_fields : natural := 3 + 12 + 4 + 13 + 3 + 1; -- Primarly used as a MM register map to provide the data needed for all header variants.
constant c_rdma_packetiser_roce_hdr_field_sel : std_logic_vector(c_rdma_packetiser_roce_nof_hdr_fields - 1 downto 0) := "111" & "111011111001" & "0100" & "1111111111111" & "111" & "1"; constant c_rdma_packetiser_mm_nof_fields : natural := 3 + 12 + 4 + 13 + 3 + 1 + 6;
constant c_rdma_packetiser_mm_field_sel : std_logic_vector(c_rdma_packetiser_mm_nof_fields - 1 downto 0) := "111" & "111011111011" & "1100" & "0111111111110" & "010" & "1" & "011111";
constant c_rdma_packetiser_roce_hdr_field_arr : t_common_field_arr( constant c_rdma_packetiser_mm_field_arr : t_common_field_arr(
c_rdma_packetiser_roce_nof_hdr_fields - 1 downto 0) := ( c_rdma_packetiser_mm_nof_fields - 1 downto 0) := (
( field_name_pad("eth_dst_mac" ), "RW", 48, field_default(0) ), -- set by M&C ( 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_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("eth_type" ), "RW", 16, field_default(x"0800") ), -- fixed
...@@ -133,65 +134,213 @@ package rdma_packetiser_pkg is ...@@ -133,65 +134,213 @@ package rdma_packetiser_pkg is
( field_name_pad("reth_r_key" ), "RW", 32, field_default(0) ), -- set by M&C ( 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("reth_dma_length" ), "RW", 32, field_default(0) ), -- set by M&C
( field_name_pad("immediate_data" ), "RW", 32, field_default(0) ) -- set by data path or M&C ( field_name_pad("immediate_data" ), "RW", 32, field_default(0) ), -- set by M&C
( field_name_pad("config_reserved" ), "RW", 6, field_default(0) ), -- fixed
( field_name_pad("config_use_immediate" ), "RW", 1, field_default(0) ), -- set by M&C
( field_name_pad("config_use_msg_cnt_as_immediate"), "RW", 1, field_default(0) ), -- set by M&C
( field_name_pad("config_nof_packets_in_msg" ), "RW", 32, field_default(0) ), -- set by M&C
( field_name_pad("config_nof_msg" ), "RW", 32, field_default(0) ), -- set by M&C
( field_name_pad("config_start_address" ), "RW", 64, field_default(0) ) -- set by 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_reg_mm_dat_addr_w : natural := ceil_log2(field_nof_words(c_rdma_packetiser_mm_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_reg_mm_dat_addr_span : natural := 2**c_rdma_packetiser_reg_mm_dat_addr_w;
-- RoCEv2 header for RDMA operation without immediate data
-- 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) ), -- 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) ), -- fixed -- RoCEv2 header for first packets and write only packets without immediate data
( field_name_pad("ip_header_length" ), "RW", 4, field_default(5) ), -- fixed -- ETH + IP + UDP + Base Transport Header (BTH) + RDMA Extended Transport Header (RETH)
( field_name_pad("ip_services" ), "RW", 8, field_default(0) ), -- fixed constant c_rdma_packetiser_first_nof_hdr_fields : natural := 3 + 12 + 4 + 13 + 3;
( field_name_pad("ip_total_length" ), "RW", 16, field_default(0) ), -- set by data path constant c_rdma_packetiser_first_hdr_field_sel : std_logic_vector(c_rdma_packetiser_first_nof_hdr_fields - 1 downto 0) := (others => '0');
( 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) ), -- set by M&C constant c_rdma_packetiser_first_hdr_field_arr : t_common_field_arr(
( field_name_pad("udp_dst_port" ), "RW", 16, field_default(0) ), -- set by M&C c_rdma_packetiser_first_nof_hdr_fields - 1 downto 0) := (
( field_name_pad("udp_total_length" ), "RW", 16, field_default(0) ), -- set by data path ( field_name_pad("eth_dst_mac" ), "RW", 48, field_default(0) ),
( field_name_pad("udp_checksum" ), "RW", 16, field_default(0) ), -- fixed ( 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("bth_opcode" ), "RW", 8, field_default(x"FF") ), -- set by data path ( field_name_pad("ip_version" ), "RW", 4, field_default(4) ),
( field_name_pad("bth_se" ), "RW", 1, field_default(0) ), -- set by M&C ( field_name_pad("ip_header_length" ), "RW", 4, field_default(5) ),
( field_name_pad("bth_m" ), "RW", 1, field_default(0) ), -- set by M&C ( field_name_pad("ip_services" ), "RW", 8, field_default(0) ),
( field_name_pad("bth_pad" ), "RW", 2, field_default(0) ), -- set by M&C ( field_name_pad("ip_total_length" ), "RW", 16, field_default(0) ),
( field_name_pad("bth_tver" ), "RW", 4, field_default(0) ), -- set by M&C ( field_name_pad("ip_identification" ), "RW", 16, field_default(0) ),
( field_name_pad("bth_partition_key" ), "RW", 16, field_default(65535) ), -- set by M&C ( field_name_pad("ip_flags" ), "RW", 3, field_default(2) ),
( field_name_pad("bth_fres" ), "RW", 1, field_default(0) ), -- set by M&C ( field_name_pad("ip_fragment_offset" ), "RW", 13, field_default(0) ),
( field_name_pad("bth_bres" ), "RW", 1, field_default(0) ), -- set by M&C ( field_name_pad("ip_time_to_live" ), "RW", 8, field_default(127) ),
( field_name_pad("bth_reserved_a" ), "RW", 6, field_default(0) ), -- fixed ( field_name_pad("ip_protocol" ), "RW", 8, field_default(17) ),
( field_name_pad("bth_dest_qp" ), "RW", 16, field_default(0) ), -- set by M&C ( field_name_pad("ip_header_checksum" ), "RW", 16, field_default(0) ),
( field_name_pad("bth_ack_req" ), "RW", 1, field_default(0) ), -- set by M&C ( field_name_pad("ip_src_addr" ), "RW", 32, field_default(0) ),
( field_name_pad("bth_reserved_b" ), "RW", 7, field_default(0) ), -- fixed ( field_name_pad("ip_dst_addr" ), "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) ), -- set by data path ( field_name_pad("udp_src_port" ), "RW", 16, field_default(0) ),
( field_name_pad("reth_r_key" ), "RW", 32, field_default(0) ), -- set by M&C ( field_name_pad("udp_dst_port" ), "RW", 16, field_default(0) ),
( field_name_pad("reth_dma_length" ), "RW", 32, field_default(0) ) -- set by M&C ( field_name_pad("udp_total_length" ), "RW", 16, field_default(0) ),
( field_name_pad("udp_checksum" ), "RW", 16, field_default(0) ),
( 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("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) )
);
-- RoCEv2 header for middle packets and last packets without immediate data.
-- ETH + IP + UDP + Base Transport Header (BTH)
constant c_rdma_packetiser_mid_nof_hdr_fields : natural := 3 + 12 + 4 + 13;
constant c_rdma_packetiser_mid_hdr_field_sel : std_logic_vector(c_rdma_packetiser_mid_nof_hdr_fields - 1 downto 0) := (others => '0');
constant c_rdma_packetiser_mid_hdr_field_arr : t_common_field_arr(
c_rdma_packetiser_mid_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("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) ),
( 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) ),
( field_name_pad("udp_src_port" ), "RW", 16, field_default(0) ),
( field_name_pad("udp_dst_port" ), "RW", 16, field_default(0) ),
( field_name_pad("udp_total_length" ), "RW", 16, field_default(0) ),
( field_name_pad("udp_checksum" ), "RW", 16, field_default(0) ),
( 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) )
);
-- RoCEv2 header for last packets with immediate data
-- ETH + IP + UDP + Base Transport Header (BTH) + immediate data
constant c_rdma_packetiser_last_nof_hdr_fields : natural := 3 + 12 + 4 + 13 + 1;
constant c_rdma_packetiser_last_hdr_field_sel : std_logic_vector(c_rdma_packetiser_last_nof_hdr_fields - 1 downto 0) := (others => '0');
constant c_rdma_packetiser_last_hdr_field_arr : t_common_field_arr(
c_rdma_packetiser_last_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("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) ),
( 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) ),
( field_name_pad("udp_src_port" ), "RW", 16, field_default(0) ),
( field_name_pad("udp_dst_port" ), "RW", 16, field_default(0) ),
( field_name_pad("udp_total_length" ), "RW", 16, field_default(0) ),
( field_name_pad("udp_checksum" ), "RW", 16, field_default(0) ),
( 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("immediate_data" ), "RW", 32, field_default(0) )
); );
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_hdr_len : natural := 32; -- octets -- RoCEv2 header for write only packets with immediate data
constant c_rdma_packetiser_roce_imm_len : natural := 4; -- octets -- ETH + IP + UDP + Base Transport Header (BTH) + RDMA Extended Transport Header (RETH) + immediate data
constant c_rdma_packetiser_roce_icrc_len : natural := 4; -- octets constant c_rdma_packetiser_wo_nof_hdr_fields : natural := 3 + 12 + 4 + 13 + 3 + 1;
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_wo_hdr_field_sel : std_logic_vector(c_rdma_packetiser_wo_nof_hdr_fields - 1 downto 0) := (others => '0');
constant c_rdma_packetiser_wo_hdr_field_arr : t_common_field_arr(
c_rdma_packetiser_wo_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("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) ),
( 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) ),
( field_name_pad("udp_src_port" ), "RW", 16, field_default(0) ),
( field_name_pad("udp_dst_port" ), "RW", 16, field_default(0) ),
( field_name_pad("udp_total_length" ), "RW", 16, field_default(0) ),
( field_name_pad("udp_checksum" ), "RW", 16, field_default(0) ),
( 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("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("immediate_data" ), "RW", 32, field_default(0) )
);
constant c_rdma_packetiser_bth_len : natural := 12; -- octets
constant c_rdma_packetiser_reth_len : natural := 16; -- octets
constant c_rdma_packetiser_imm_len : natural := 4; -- octets
constant c_rdma_packetiser_icrc_len : natural := 4; -- octets
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";
...@@ -206,14 +355,13 @@ package rdma_packetiser_pkg is ...@@ -206,14 +355,13 @@ package rdma_packetiser_pkg is
constant c_rdma_packetiser_opcode_uc_write_only : std_logic_vector := "001" & "01010"; -- without 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 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; field_arr : t_common_field_arr) return t_rdma_packetiser_roce_header;
end rdma_packetiser_pkg; end rdma_packetiser_pkg;
package body rdma_packetiser_pkg is package body rdma_packetiser_pkg is
function func_rdma_packetiser_map_header(hdr_fields_raw : std_logic_vector; use_immediate : boolean) return t_rdma_packetiser_roce_header is function func_rdma_packetiser_map_header(hdr_fields_raw : std_logic_vector; field_arr : t_common_field_arr) return t_rdma_packetiser_roce_header is
variable v : t_rdma_packetiser_roce_header; variable v : t_rdma_packetiser_roce_header;
constant c_hdr_field_arr : t_common_field_arr := sel_a_b(use_immediate, c_rdma_packetiser_roce_hdr_field_arr, c_rdma_packetiser_roce_no_imm_hdr_field_arr); constant c_hdr_field_arr : t_common_field_arr := field_arr;
begin begin
-- eth header -- eth header
v.eth.dst_mac := hdr_fields_raw(field_hi(c_hdr_field_arr, "eth_dst_mac") downto field_lo(c_hdr_field_arr, "eth_dst_mac")); v.eth.dst_mac := hdr_fields_raw(field_hi(c_hdr_field_arr, "eth_dst_mac") downto field_lo(c_hdr_field_arr, "eth_dst_mac"));
...@@ -255,14 +403,17 @@ package body rdma_packetiser_pkg is ...@@ -255,14 +403,17 @@ package body rdma_packetiser_pkg is
v.bth.reserved_b := hdr_fields_raw(field_hi(c_hdr_field_arr, "bth_reserved_b") downto field_lo(c_hdr_field_arr, "bth_reserved_b")); v.bth.reserved_b := hdr_fields_raw(field_hi(c_hdr_field_arr, "bth_reserved_b") downto field_lo(c_hdr_field_arr, "bth_reserved_b"));
v.bth.psn := hdr_fields_raw(field_hi(c_hdr_field_arr, "bth_psn") downto field_lo(c_hdr_field_arr, "bth_psn")); v.bth.psn := hdr_fields_raw(field_hi(c_hdr_field_arr, "bth_psn") downto field_lo(c_hdr_field_arr, "bth_psn"));
-- reth header -- reth header (optional)
v.reth := ((others => '0'), (others => '0'),(others => '0'));
if field_exists(c_hdr_field_arr, "reth_virtual_address") then -- reth header exists
v.reth.virtual_address := hdr_fields_raw(field_hi(c_hdr_field_arr, "reth_virtual_address") downto field_lo(c_hdr_field_arr, "reth_virtual_address")); v.reth.virtual_address := hdr_fields_raw(field_hi(c_hdr_field_arr, "reth_virtual_address") downto field_lo(c_hdr_field_arr, "reth_virtual_address"));
v.reth.r_key := hdr_fields_raw(field_hi(c_hdr_field_arr, "reth_r_key") downto field_lo(c_hdr_field_arr, "reth_r_key")); v.reth.r_key := hdr_fields_raw(field_hi(c_hdr_field_arr, "reth_r_key") downto field_lo(c_hdr_field_arr, "reth_r_key"));
v.reth.dma_length := hdr_fields_raw(field_hi(c_hdr_field_arr, "reth_dma_length") downto field_lo(c_hdr_field_arr, "reth_dma_length")); v.reth.dma_length := hdr_fields_raw(field_hi(c_hdr_field_arr, "reth_dma_length") downto field_lo(c_hdr_field_arr, "reth_dma_length"));
end if;
--immediate data --immediate data (optional)
v.immediate_data := (others => '0'); v.immediate_data := (others => '0');
if use_immediate then if field_exists(c_hdr_field_arr, "immediate_data") then -- immediate data exists
v.immediate_data := hdr_fields_raw(field_hi(c_hdr_field_arr, "immediate_data") downto field_lo(c_hdr_field_arr, "immediate_data")); v.immediate_data := hdr_fields_raw(field_hi(c_hdr_field_arr, "immediate_data") downto field_lo(c_hdr_field_arr, "immediate_data"));
end if; end if;
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
-- limitations under the License. -- limitations under the License.
-- --
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- NOTE Work in progress, will be finished in HPR-131
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- --
-- Author: R. vd Walle -- Author: R. vd Walle
...@@ -67,12 +67,10 @@ end tb_rdma_packetiser_assemble_header; ...@@ -67,12 +67,10 @@ end tb_rdma_packetiser_assemble_header;
architecture tb of tb_rdma_packetiser_assemble_header is architecture tb of tb_rdma_packetiser_assemble_header is
constant c_dp_clk_period : time := 5 ns; -- 200 MHz constant c_dp_clk_period : time := 5 ns; -- 200 MHz
constant c_mm_clk_period : time := 1 ns; -- 1 GHz
constant c_data_w : natural := c_word_w; constant c_data_w : natural := c_word_w;
constant c_data_init : natural := 13; constant c_data_init : natural := 13;
constant c_hdr_fields_slv_rst : std_logic_vector(1023 downto 0) := (others => '0'); constant c_hdr_fields_slv_rst : std_logic_vector(1023 downto 0) := (others => '0');
constant c_rdma_hdr_len : natural := c_rdma_packetiser_roce_icrc_len + sel_a_b(
g_use_immediate,
c_rdma_packetiser_roce_hdr_len, c_rdma_packetiser_roce_no_imm_hdr_len);
constant c_block_len : natural := g_frame_len * (c_data_w / c_octet_w); constant c_block_len : natural := g_frame_len * (c_data_w / c_octet_w);
constant c_dma_len : natural := c_block_len * g_nof_packets_in_msg; constant c_dma_len : natural := c_block_len * g_nof_packets_in_msg;
...@@ -80,6 +78,8 @@ architecture tb of tb_rdma_packetiser_assemble_header is ...@@ -80,6 +78,8 @@ architecture tb of tb_rdma_packetiser_assemble_header is
signal dp_clk : std_logic := '1'; signal dp_clk : std_logic := '1';
signal dp_rst : std_logic; signal dp_rst : std_logic;
signal mm_clk : std_logic := '1';
signal mm_rst : std_logic;
signal immediate_data : std_logic_vector(c_word_w - 1 downto 0) := X"89ABCDEF"; signal immediate_data : std_logic_vector(c_word_w - 1 downto 0) := X"89ABCDEF";
signal block_len : std_logic_vector(c_halfword_w - 1 downto 0) := TO_UVEC(c_block_len, c_halfword_w); signal block_len : std_logic_vector(c_halfword_w - 1 downto 0) := TO_UVEC(c_block_len, c_halfword_w);
...@@ -90,16 +90,23 @@ architecture tb of tb_rdma_packetiser_assemble_header is ...@@ -90,16 +90,23 @@ architecture tb of tb_rdma_packetiser_assemble_header is
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 rx_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';
signal snk_in : t_dp_sosi := c_dp_sosi_rst; signal snk_in : t_dp_sosi := c_dp_sosi_rst;
signal snk_out : t_dp_siso := c_dp_siso_rdy; signal snk_out : t_dp_siso := c_dp_siso_rdy;
signal src_out : t_dp_sosi := c_dp_sosi_rst;
signal src_in : t_dp_siso := c_dp_siso_rdy;
signal reg_hdr_dat_copi : t_mem_copi := c_mem_copi_rst;
signal reg_hdr_dat_cipo : t_mem_cipo;
begin 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;
mm_rst <= '1', '0' after c_mm_clk_period * 7;
rx_rdma_header <= func_rdma_packetiser_map_header(hdr_fields_slv, g_use_immediate ); mm_clk <= (not mm_clk) or tb_end after c_mm_clk_period / 2;
--rx_rdma_header <= func_rdma_packetiser_map_header(hdr_fields_slv, g_use_immediate );
p_dp_stimuli : process p_dp_stimuli : process
begin begin
...@@ -115,92 +122,25 @@ begin ...@@ -115,92 +122,25 @@ begin
wait; wait;
end process; end process;
-- check if values in rdma_packetiser_assemble_header match with expected values
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);
variable v_exp_bth_psn : natural;
variable v_exp_reth_virtual_address : unsigned(c_longword_w - 1 downto 0);
variable v_exp_reth_dma_length : natural;
variable v_exp_immediate_data : std_logic_vector(c_word_w - 1 downto 0);
variable v_p, v_m : natural := 0;
begin
for rep in 0 to g_nof_rep - 1 loop
proc_common_wait_until_high(dp_clk, snk_in.sop); -- wait for sop
v_exp_ip_total_length := c_network_ip_header_len + c_network_udp_header_len + c_rdma_hdr_len + to_uint(block_len);
v_exp_udp_total_length := c_network_udp_header_len + c_rdma_hdr_len + to_uint(block_len);
v_exp_bth_psn := v_p;
v_exp_reth_virtual_address := g_start_address + to_unsigned((v_m mod g_nof_msg) * c_dma_len, c_longword_w);
v_exp_reth_dma_length := c_dma_len;
v_exp_immediate_data := sel_a_b(g_use_immediate,
sel_a_b(g_use_msg_cnt_as_immediate, to_uvec((v_m mod g_nof_msg), c_word_w), immediate_data), to_uvec(0, c_word_w));
-- determine expected opcode
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_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_imm;
end if;
else
v_exp_bth_opcode := c_rdma_packetiser_opcode_uc_write_middle;
end if;
-- increase counters
v_p := v_p + 1;
v_m := v_p / g_nof_packets_in_msg;
-- assign expected values to signal to view in wave window.
exp_rdma_header.ip.total_length <= to_uvec(v_exp_ip_total_length, c_halfword_w);
exp_rdma_header.udp.total_length <= to_uvec(v_exp_udp_total_length, c_halfword_w );
exp_rdma_header.bth.opcode <= v_exp_bth_opcode;
exp_rdma_header.bth.psn <= to_uvec(v_exp_bth_psn, c_word_w);
exp_rdma_header.reth.virtual_address <= std_logic_vector(v_exp_reth_virtual_address);
exp_rdma_header.reth.dma_length <= to_uvec(v_exp_reth_dma_length, c_word_w);
exp_rdma_header.immediate_data <= v_exp_immediate_data;
proc_common_wait_some_cycles(dp_clk, 1);
-- assert when header is not as expected.
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);
tb_end <= '1';
wait;
end process;
u_dut: entity work.rdma_packetiser_assemble_header u_dut: entity work.rdma_packetiser_assemble_header
generic map ( generic map (
g_use_immediate => g_use_immediate, g_data_w => 512
g_use_msg_cnt_as_immediate => g_use_msg_cnt_as_immediate
) )
port map ( port map (
st_clk => dp_clk, st_clk => dp_clk,
st_rst => dp_rst, st_rst => dp_rst,
mm_clk => mm_clk,
mm_rst => mm_rst,
reg_hdr_dat_copi => reg_hdr_dat_copi,
reg_hdr_dat_cipo => reg_hdr_dat_cipo,
snk_in => snk_in, snk_in => snk_in,
hdr_fields_slv => hdr_fields_slv, snk_out => snk_out,
immediate_data => immediate_data, src_out => src_out,
block_len => block_len, src_in => src_in,
nof_packets_in_msg => nof_packets_in_msg,
nof_msg => nof_msg, block_len => block_len
dma_len => dma_len,
start_address => start_address
); );
end tb; end tb;
...@@ -73,6 +73,8 @@ package common_field_pkg is ...@@ -73,6 +73,8 @@ package common_field_pkg is
function field_map_out (field_arr : t_common_field_arr; word_arr : std_logic_vector; word_w : natural ) return std_logic_vector; -- returns slv_out function field_map_out (field_arr : t_common_field_arr; word_arr : std_logic_vector; word_w : natural ) return std_logic_vector; -- returns slv_out
function field_map (field_arr : t_common_field_arr; word_arr_in: std_logic_vector; word_arr_out: std_logic_vector; word_w : natural) return std_logic_vector; -- returns word_arr function field_map (field_arr : t_common_field_arr; word_arr_in: std_logic_vector; word_arr_out: std_logic_vector; word_w : natural) return std_logic_vector; -- returns word_arr
function field_select_subset(subset_field_arr : t_common_field_arr; larger_field_arr : t_common_field_arr; larger_slv : std_logic_vector) return std_logic_vector; -- returns subset slv
function field_ovr_arr(field_arr : t_common_field_arr; ovr_init: std_logic_vector) return t_common_field_arr; function field_ovr_arr(field_arr : t_common_field_arr; ovr_init: std_logic_vector) return t_common_field_arr;
function field_exists(field_arr : t_common_field_arr; name: string) return boolean; function field_exists(field_arr : t_common_field_arr; name: string) return boolean;
...@@ -295,6 +297,25 @@ package body common_field_pkg is ...@@ -295,6 +297,25 @@ package body common_field_pkg is
return v_word_arr; return v_word_arr;
end field_map; end field_map;
function field_select_subset(subset_field_arr : t_common_field_arr; larger_field_arr : t_common_field_arr; larger_slv : std_logic_vector) return std_logic_vector is
-- Return SLV mapped to "subset_field_arr" extracted from a larger SLV mapped to "larger_field_arr".
variable v_hi_sub : natural;
variable v_lo_sub : natural;
variable v_hi_full : natural;
variable v_lo_full : natural;
variable out_slv : std_logic_vector(larger_slv'range) := (others => '0');
begin
for j in subset_field_arr'range loop
v_hi_sub := field_hi(subset_field_arr, j);
v_lo_sub := field_lo(subset_field_arr, j);
v_hi_full := field_hi(larger_field_arr, subset_field_arr(j).name);
v_lo_full := field_lo(larger_field_arr, subset_field_arr(j).name);
out_slv(v_hi_sub downto v_lo_sub) := larger_slv(v_hi_full downto v_lo_full);
end loop;
return out_slv;
end field_select_subset;
function field_ovr_arr(field_arr : t_common_field_arr; ovr_init: std_logic_vector) return t_common_field_arr is function field_ovr_arr(field_arr : t_common_field_arr; ovr_init: std_logic_vector) return t_common_field_arr is
-- Copy field_arr but change widths to 1 to create a 1-bit override field for each field in field_arr. -- Copy field_arr but change widths to 1 to create a 1-bit override field for each field in field_arr.
variable v_ovr_field_arr : t_common_field_arr(field_arr'range); variable v_ovr_field_arr : t_common_field_arr(field_arr'range);
......
...@@ -58,8 +58,8 @@ entity dp_offload_tx_v3 is ...@@ -58,8 +58,8 @@ entity dp_offload_tx_v3 is
g_pipeline_ready : boolean := false g_pipeline_ready : boolean := false
); );
port ( port (
mm_rst : in std_logic; mm_rst : in std_logic := '0';
mm_clk : in std_logic; mm_clk : in std_logic := '0';
dp_rst : in std_logic; dp_rst : in std_logic;
dp_clk : in std_logic; dp_clk : in std_logic;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment