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 =
test_bench_files =
tb/vhdl/tb_rdma_packetiser_assemble_header.vhd
tb/vhdl/tb_tb_rdma_packetiser_assemble_header.vhd
regression_test_vhdl =
tb/vhdl/tb_tb_rdma_packetiser_assemble_header.vhd
[modelsim_project_file]
......
......@@ -18,29 +18,28 @@
--
-------------------------------------------------------------------------------
-- 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:
-- 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
-- Generates a RoCEv2 header (ETH + UDP + IP + RDMA). See [1]. Then it prepends
-- the generated header to the incoming sosi data stream.
-- MM config:
-- . config_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
-- . 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"
-- 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
-- config_use_msg_cnt_as_immediate = False.
-- . config_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
-- 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.
-- . 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
-- . The hdr_fields_slv output is set one st_clk cycle after snk_in.sop and will
-- contain the RoCEv2 (RDMA over Converged Ethernet v2) header information for
-- the corresponding data frame.
-- . The virtual_address is set automatically by increasing it with dma_len every
-- new message. The virtual address is reset to "start_address" when the number
-- of messages has reached "nof_msg". Then the cycle repeats.
......@@ -65,38 +64,38 @@ library IEEE, common_lib, dp_lib, eth_lib;
entity rdma_packetiser_assemble_header is
generic (
g_use_immediate : boolean := true;
g_use_msg_cnt_as_immediate : boolean := true
g_data_w : natural := 512
);
port (
-- Clocks and reset
st_clk : 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_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
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)
block_len : in std_logic_vector(c_halfword_w - 1 downto 0) -- in octets
);
end rdma_packetiser_assemble_header;
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_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_udp_app_hdr_length : natural := c_network_udp_header_len + c_rdma_packetiser_bth_len;
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_reg is record -- record to keep the registers organized.
state : t_state;
opcode : std_logic_vector(c_byte_w - 1 downto 0);
immediate_data : std_logic_vector(c_rdma_packetiser_roce_imm_len * c_octet_w - 1 downto 0);
psn : std_logic_vector(c_word_w - 1 downto 0);
virtual_address : unsigned(c_longword_w - 1 downto 0);
dma_len : unsigned(c_word_w - 1 downto 0);
......@@ -105,15 +104,61 @@ architecture str of rdma_packetiser_assemble_header is
udp_total_length : natural;
ip_total_length : natural;
nof_packets_in_msg : natural;
sel_ctrl : natural range 0 to c_nof_offload - 1;
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 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
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.
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;
begin
v := q;
......@@ -134,19 +179,24 @@ begin
if v.nof_packets_in_msg = 1 then -- set opcode to write_only.
v.opcode := c_rdma_packetiser_opcode_uc_write_only;
if g_use_immediate then -- set opcode to write_only with immediate data.
v.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.sel_ctrl := 3;
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;
v.sel_ctrl := 0;
elsif v.nof_packets_in_msg > 2 then
v.state := s_middle;
v.opcode := c_rdma_packetiser_opcode_uc_write_first;
v.sel_ctrl := 0;
end if;
when s_middle => -- wait unitl the first packet is done and set next opcode.
v.opcode := c_rdma_packetiser_opcode_uc_write_middle;
v.sel_ctrl := 1;
if q.p_cnt >= v.nof_packets_in_msg - 2 then -- wait until last middle packet
v.state := s_last;
end if;
......@@ -154,8 +204,10 @@ begin
when s_last => -- next packet must be last packet, set opcode.
v.state := s_first;
v.opcode := c_rdma_packetiser_opcode_uc_write_last;
if g_use_immediate then -- set opcode to write_last with immediate data
v.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.sel_ctrl := 2;
end if;
end case;
end if;
......@@ -163,10 +215,9 @@ begin
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.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_icrc_len;
v.nof_packets_in_msg := to_uint(nof_packets_in_msg);
v.immediate_data := immediate_data;
end if;
if st_rst = '1' then
......@@ -176,20 +227,228 @@ begin
d <= v;
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);
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(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(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);
gen_use_immediate : if g_use_immediate generate
gen_use_msg_cnt : if 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")) <= TO_UVEC(q.msg_cnt, 32);
end generate;
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;
end generate;
end generate;
-------------------------------------------------------------------------------
-- Wire the header fields
-------------------------------------------------------------------------------
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_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_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;
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);
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);
-------------------------------------------------------------------------------
-- demux to guide the incoming stream to the correct dp_offload_tx_v3
-------------------------------------------------------------------------------
u_dp_demux : entity dp_lib.dp_demux
generic map (
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;
......@@ -86,13 +86,14 @@ package rdma_packetiser_pkg is
-- = 0 can be achieve via data path and default hdr_fields_in_arr = 0 or
-- via MM controlled and field_default(0).
-- RoCEv2 header for RDMA operation with immediate data
-- ETH + IP + UDP + Base Transport Header (BTH) + RDMA Extended Transport Header (RETH) + Immediate Data
constant c_rdma_packetiser_roce_nof_hdr_fields : natural := 3 + 12 + 4 + 13 + 3 + 1;
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";
-- 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 + user config
-- Primarly used as a MM register map to provide the data needed for all header variants.
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(
c_rdma_packetiser_roce_nof_hdr_fields - 1 downto 0) := (
constant c_rdma_packetiser_mm_field_arr : t_common_field_arr(
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_src_mac" ), "RW", 48, field_default(0) ), -- set by M&C
( field_name_pad("eth_type" ), "RW", 16, field_default(x"0800") ), -- fixed
......@@ -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_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_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_w : natural := ceil_log2(field_nof_words(c_rdma_packetiser_mm_field_arr, c_word_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
( field_name_pad("ip_header_length" ), "RW", 4, field_default(5) ), -- fixed
( field_name_pad("ip_services" ), "RW", 8, field_default(0) ), -- fixed
( field_name_pad("ip_total_length" ), "RW", 16, field_default(0) ), -- set by data path
( field_name_pad("ip_identification" ), "RW", 16, field_default(0) ), -- fixed
( field_name_pad("ip_flags" ), "RW", 3, field_default(2) ), -- fixed
( field_name_pad("ip_fragment_offset" ), "RW", 13, field_default(0) ), -- fixed
( field_name_pad("ip_time_to_live" ), "RW", 8, field_default(127) ), -- fixed
( field_name_pad("ip_protocol" ), "RW", 8, field_default(17) ), -- fixed
( field_name_pad("ip_header_checksum" ), "RW", 16, field_default(0) ), -- set by data path
( field_name_pad("ip_src_addr" ), "RW", 32, field_default(0) ), -- set by M&C
( field_name_pad("ip_dst_addr" ), "RW", 32, field_default(0) ), -- set by M&C
-- RoCEv2 header for first packets and write only packets without immediate data
-- ETH + IP + UDP + Base Transport Header (BTH) + RDMA Extended Transport Header (RETH)
constant c_rdma_packetiser_first_nof_hdr_fields : natural := 3 + 12 + 4 + 13 + 3;
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("udp_src_port" ), "RW", 16, field_default(0) ), -- set by M&C
( field_name_pad("udp_dst_port" ), "RW", 16, field_default(0) ), -- set by M&C
( field_name_pad("udp_total_length" ), "RW", 16, field_default(0) ), -- set by data path
( field_name_pad("udp_checksum" ), "RW", 16, field_default(0) ), -- fixed
constant c_rdma_packetiser_first_hdr_field_arr : t_common_field_arr(
c_rdma_packetiser_first_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("bth_opcode" ), "RW", 8, field_default(x"FF") ), -- set by data path
( field_name_pad("bth_se" ), "RW", 1, field_default(0) ), -- set by M&C
( field_name_pad("bth_m" ), "RW", 1, field_default(0) ), -- set by M&C
( field_name_pad("bth_pad" ), "RW", 2, field_default(0) ), -- set by M&C
( field_name_pad("bth_tver" ), "RW", 4, field_default(0) ), -- set by M&C
( field_name_pad("bth_partition_key" ), "RW", 16, field_default(65535) ), -- set by M&C
( field_name_pad("bth_fres" ), "RW", 1, field_default(0) ), -- set by M&C
( field_name_pad("bth_bres" ), "RW", 1, field_default(0) ), -- set by M&C
( field_name_pad("bth_reserved_a" ), "RW", 6, field_default(0) ), -- fixed
( field_name_pad("bth_dest_qp" ), "RW", 16, field_default(0) ), -- set by M&C
( field_name_pad("bth_ack_req" ), "RW", 1, field_default(0) ), -- set by M&C
( field_name_pad("bth_reserved_b" ), "RW", 7, field_default(0) ), -- fixed
( field_name_pad("bth_psn" ), "RW", 32, field_default(0) ), -- set by data path
( field_name_pad("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("reth_virtual_address"), "RW", 64, field_default(0) ), -- set by data path
( field_name_pad("reth_r_key" ), "RW", 32, field_default(0) ), -- set by M&C
( field_name_pad("reth_dma_length" ), "RW", 32, field_default(0) ) -- set by M&C
( field_name_pad("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) )
);
-- 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
constant c_rdma_packetiser_roce_imm_len : natural := 4; -- octets
constant c_rdma_packetiser_roce_icrc_len : natural := 4; -- octets
constant c_rdma_packetiser_roce_no_imm_hdr_len : natural := c_rdma_packetiser_roce_hdr_len - c_rdma_packetiser_roce_imm_len;
-- RoCEv2 header for write only packets with immediate data
-- ETH + IP + UDP + Base Transport Header (BTH) + RDMA Extended Transport Header (RETH) + immediate data
constant c_rdma_packetiser_wo_nof_hdr_fields : natural := 3 + 12 + 4 + 13 + 3 + 1;
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_middle : std_logic_vector := "001" & "00001";
......@@ -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_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;
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;
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
-- 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"));
......@@ -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.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.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"));
end if;
--immediate data
--immediate data (optional)
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"));
end if;
......
......@@ -17,7 +17,7 @@
-- limitations under the License.
--
-------------------------------------------------------------------------------
-- NOTE Work in progress, will be finished in HPR-131
-------------------------------------------------------------------------------
--
-- Author: R. vd Walle
......@@ -67,12 +67,10 @@ end tb_rdma_packetiser_assemble_header;
architecture tb of tb_rdma_packetiser_assemble_header is
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_init : natural := 13;
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_dma_len : natural := c_block_len * g_nof_packets_in_msg;
......@@ -80,6 +78,8 @@ architecture tb of tb_rdma_packetiser_assemble_header is
signal dp_clk : std_logic := '1';
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 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
signal hdr_fields_slv : std_logic_vector(1023 downto 0) := (others => '0');
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 snk_in : t_dp_sosi := c_dp_sosi_rst;
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
dp_rst <= '1', '0' after c_dp_clk_period * 7;
dp_clk <= (not dp_clk) or tb_end after c_dp_clk_period / 2;
rx_rdma_header <= func_rdma_packetiser_map_header(hdr_fields_slv, g_use_immediate );
mm_rst <= '1', '0' after c_mm_clk_period * 7;
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
begin
......@@ -115,92 +122,25 @@ begin
wait;
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
generic map (
g_use_immediate => g_use_immediate,
g_use_msg_cnt_as_immediate => g_use_msg_cnt_as_immediate
g_data_w => 512
)
port map (
st_clk => dp_clk,
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,
hdr_fields_slv => hdr_fields_slv,
immediate_data => immediate_data,
block_len => block_len,
nof_packets_in_msg => nof_packets_in_msg,
nof_msg => nof_msg,
dma_len => dma_len,
start_address => start_address
snk_out => snk_out,
src_out => src_out,
src_in => src_in,
block_len => block_len
);
end tb;
......@@ -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 (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_exists(field_arr : t_common_field_arr; name: string) return boolean;
......@@ -295,6 +297,25 @@ package body common_field_pkg is
return v_word_arr;
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
-- 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);
......
......@@ -58,8 +58,8 @@ entity dp_offload_tx_v3 is
g_pipeline_ready : boolean := false
);
port (
mm_rst : in std_logic;
mm_clk : in std_logic;
mm_rst : in std_logic := '0';
mm_clk : in std_logic := '0';
dp_rst : 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