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

Merge branch 'HPR-131' into 'master'

Resolve HPR-131

Closes HPR-131

See merge request !367
parents 04db780e 1ffbfef1
No related branches found
No related tags found
1 merge request!367Resolve HPR-131
Pipeline #65294 passed
...@@ -10,8 +10,10 @@ synth_files = ...@@ -10,8 +10,10 @@ 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]
......
...@@ -45,6 +45,10 @@ ...@@ -45,6 +45,10 @@
-- of messages has reached "nof_msg". Then the cycle repeats. -- of messages has reached "nof_msg". Then the cycle repeats.
-- . The PSN field (= Packet Sequence Number) is set to LSBs of the incoming BSN. -- . The PSN field (= Packet Sequence Number) is set to LSBs of the incoming BSN.
-- This can be used to check the order or detect missing packets at the receiver. -- This can be used to check the order or detect missing packets at the receiver.
-- . The incoming datastream has to be at least 6 valid cycles long and be able to handle
-- backpressure. Using less than 6 cycles seem to result in corrupted packets. It seems
-- that it has to do with dp_offload_tx_v3 not capable of processing fast enough, further
-- investigation is necessary in order to get rid of this limitation.
-- References: -- References:
-- . [1] https://support.astron.nl/confluence/x/3pKrB -- . [1] https://support.astron.nl/confluence/x/3pKrB
...@@ -88,8 +92,19 @@ entity rdma_packetiser_assemble_header is ...@@ -88,8 +92,19 @@ entity rdma_packetiser_assemble_header is
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_udp_app_hdr_length : natural := c_network_udp_header_len + c_rdma_packetiser_bth_len; -- Created constants for each header length variant, also included the icrc length here.
constant c_ip_udp_app_hdr_length : natural := c_network_ip_header_len + c_udp_app_hdr_length; -- first = rdma_write_first and rdma_write_only without immediate.
-- mid = rdma_write_middle and rdma_write_last without immediate.
-- last = rdma_write_last with immediate.
-- wo = rdma_write_only with immediate.
constant c_udp_app_first_hdr_len : natural := c_network_udp_header_len + c_rdma_packetiser_bth_len + c_rdma_packetiser_reth_len + c_rdma_packetiser_icrc_len;
constant c_udp_app_mid_hdr_len : natural := c_network_udp_header_len + c_rdma_packetiser_bth_len + c_rdma_packetiser_icrc_len;
constant c_udp_app_last_hdr_len : natural := c_network_udp_header_len + c_rdma_packetiser_bth_len + c_rdma_packetiser_imm_len + c_rdma_packetiser_icrc_len;
constant c_udp_app_wo_hdr_len : natural := c_network_udp_header_len + c_rdma_packetiser_bth_len + c_rdma_packetiser_reth_len + c_rdma_packetiser_imm_len + c_rdma_packetiser_icrc_len;
constant c_ip_udp_app_first_hdr_len : natural := c_network_ip_header_len + c_udp_app_first_hdr_len;
constant c_ip_udp_app_mid_hdr_len : natural := c_network_ip_header_len + c_udp_app_mid_hdr_len;
constant c_ip_udp_app_last_hdr_len : natural := c_network_ip_header_len + c_udp_app_last_hdr_len;
constant c_ip_udp_app_wo_hdr_len : natural := c_network_ip_header_len + c_udp_app_wo_hdr_len;
constant c_nof_offload : natural := 4; 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);
...@@ -179,24 +194,36 @@ begin ...@@ -179,24 +194,36 @@ 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;
v.udp_total_length := c_udp_app_first_hdr_len + to_uint(block_len);
v.ip_total_length := c_ip_udp_app_first_hdr_len + to_uint(block_len);
v.sel_ctrl := 0; v.sel_ctrl := 0;
if use_immediate = '1' then -- set opcode to write_only with immediate data. 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.udp_total_length := c_udp_app_wo_hdr_len + to_uint(block_len);
v.ip_total_length := c_ip_udp_app_wo_hdr_len + to_uint(block_len);
v.sel_ctrl := 3; 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.udp_total_length := c_udp_app_first_hdr_len + to_uint(block_len);
v.ip_total_length := c_ip_udp_app_first_hdr_len + to_uint(block_len);
v.sel_ctrl := 0; 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.udp_total_length := c_udp_app_first_hdr_len + to_uint(block_len);
v.ip_total_length := c_ip_udp_app_first_hdr_len + to_uint(block_len);
v.sel_ctrl := 0; 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; v.udp_total_length := c_udp_app_mid_hdr_len + to_uint(block_len);
v.ip_total_length := c_ip_udp_app_mid_hdr_len + to_uint(block_len);
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;
...@@ -204,9 +231,13 @@ begin ...@@ -204,9 +231,13 @@ 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;
v.sel_ctrl := 1; v.udp_total_length := c_udp_app_mid_hdr_len + to_uint(block_len);
v.ip_total_length := c_ip_udp_app_mid_hdr_len + to_uint(block_len);
v.sel_ctrl := 1;
if use_immediate = '1' then -- set opcode to write_last with immediate data 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.udp_total_length := c_udp_app_last_hdr_len + to_uint(block_len);
v.ip_total_length := c_ip_udp_app_last_hdr_len + to_uint(block_len);
v.sel_ctrl := 2; v.sel_ctrl := 2;
end if; end if;
end case; end case;
...@@ -215,8 +246,6 @@ begin ...@@ -215,8 +246,6 @@ 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_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);
end if; end if;
...@@ -278,7 +307,7 @@ begin ...@@ -278,7 +307,7 @@ begin
hdr_fields_slv_in_first <= field_select_subset(c_rdma_packetiser_first_hdr_field_arr, hdr_fields_slv_in_first <= field_select_subset(c_rdma_packetiser_first_hdr_field_arr,
c_rdma_packetiser_mm_field_arr, c_rdma_packetiser_mm_field_arr,
hdr_fields_slv_out_mm); hdr_fields_slv_out_mm);
hdr_fields_slv_in_mid <= field_select_subset(c_rdma_packetiser_last_hdr_field_arr, hdr_fields_slv_in_mid <= field_select_subset(c_rdma_packetiser_mid_hdr_field_arr,
c_rdma_packetiser_mm_field_arr, c_rdma_packetiser_mm_field_arr,
hdr_fields_slv_out_mm); hdr_fields_slv_out_mm);
hdr_fields_slv_in_last <= field_select_subset(c_rdma_packetiser_last_hdr_field_arr, hdr_fields_slv_in_last <= field_select_subset(c_rdma_packetiser_last_hdr_field_arr,
......
...@@ -90,7 +90,7 @@ package rdma_packetiser_pkg is ...@@ -90,7 +90,7 @@ package rdma_packetiser_pkg is
-- ETH + IP + UDP + Base Transport Header (BTH) + RDMA Extended Transport Header (RETH) + Immediate Data + user config -- 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. -- 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_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_mm_field_sel : std_logic_vector(c_rdma_packetiser_mm_nof_fields - 1 downto 0) := "111" & "111011111011" & "1100" & "0111111111110" & "011" & "1" & "011111";
constant c_rdma_packetiser_mm_field_arr : t_common_field_arr( constant c_rdma_packetiser_mm_field_arr : t_common_field_arr(
c_rdma_packetiser_mm_nof_fields - 1 downto 0) := ( c_rdma_packetiser_mm_nof_fields - 1 downto 0) := (
...@@ -342,18 +342,18 @@ package rdma_packetiser_pkg is ...@@ -342,18 +342,18 @@ package rdma_packetiser_pkg is
constant c_rdma_packetiser_imm_len : natural := 4; -- octets constant c_rdma_packetiser_imm_len : natural := 4; -- octets
constant c_rdma_packetiser_icrc_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(7 downto 0) := "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(7 downto 0) := "001" & "00001";
constant c_rdma_packetiser_opcode_uc_send_last : std_logic_vector := "001" & "00010"; -- without immediate constant c_rdma_packetiser_opcode_uc_send_last : std_logic_vector(7 downto 0) := "001" & "00010"; -- without immediate
constant c_rdma_packetiser_opcode_uc_send_last_imm : std_logic_vector := "001" & "00011"; -- with immediate constant c_rdma_packetiser_opcode_uc_send_last_imm : std_logic_vector(7 downto 0) := "001" & "00011"; -- with immediate
constant c_rdma_packetiser_opcode_uc_send_only : std_logic_vector := "001" & "00100"; -- without immediate constant c_rdma_packetiser_opcode_uc_send_only : std_logic_vector(7 downto 0) := "001" & "00100"; -- without immediate
constant c_rdma_packetiser_opcode_uc_send_only_imm : std_logic_vector := "001" & "00101"; -- with immediate constant c_rdma_packetiser_opcode_uc_send_only_imm : std_logic_vector(7 downto 0) := "001" & "00101"; -- with immediate
constant c_rdma_packetiser_opcode_uc_write_first : std_logic_vector := "001" & "00110"; constant c_rdma_packetiser_opcode_uc_write_first : std_logic_vector(7 downto 0) := "001" & "00110";
constant c_rdma_packetiser_opcode_uc_write_middle : std_logic_vector := "001" & "00111"; constant c_rdma_packetiser_opcode_uc_write_middle : std_logic_vector(7 downto 0) := "001" & "00111";
constant c_rdma_packetiser_opcode_uc_write_last : std_logic_vector := "001" & "01000"; -- without immediate constant c_rdma_packetiser_opcode_uc_write_last : std_logic_vector(7 downto 0) := "001" & "01000"; -- without immediate
constant c_rdma_packetiser_opcode_uc_write_last_imm : std_logic_vector := "001" & "01001"; -- with immediate constant c_rdma_packetiser_opcode_uc_write_last_imm : std_logic_vector(7 downto 0) := "001" & "01001"; -- with immediate
constant c_rdma_packetiser_opcode_uc_write_only : std_logic_vector := "001" & "01010"; -- without immediate constant c_rdma_packetiser_opcode_uc_write_only : std_logic_vector(7 downto 0) := "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(7 downto 0) := "001" & "01011"; -- with immediate
function func_rdma_packetiser_map_header(hdr_fields_raw : std_logic_vector; field_arr : t_common_field_arr) 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;
......
...@@ -55,6 +55,7 @@ library IEEE, common_lib, dp_lib; ...@@ -55,6 +55,7 @@ library IEEE, common_lib, dp_lib;
entity tb_rdma_packetiser_assemble_header is entity tb_rdma_packetiser_assemble_header is
generic ( generic (
g_data_w : natural := c_word_w;
g_use_immediate : boolean := true; g_use_immediate : boolean := true;
g_use_msg_cnt_as_immediate : boolean := true; g_use_msg_cnt_as_immediate : boolean := true;
g_nof_rep : natural := 60; g_nof_rep : natural := 60;
...@@ -68,35 +69,47 @@ end tb_rdma_packetiser_assemble_header; ...@@ -68,35 +69,47 @@ 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_mm_clk_period : time := 1 ns; -- 1 GHz
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_block_len : natural := g_frame_len * (c_data_w / c_octet_w); constant c_block_len : natural := g_frame_len * (g_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;
signal tb_end : std_logic := '0'; constant c_mm_addr_config_start_address : natural := 0;
constant c_mm_addr_config_nof_msg : natural := 2;
constant c_mm_addr_config_nof_packets_in_msg : natural := 3;
constant c_mm_addr_config_use_msg_cnt_as_immediate : natural := 4;
constant c_mm_addr_config_use_immediate : natural := 5;
constant c_mm_addr_immediate_data : natural := 7;
constant c_mm_addr_reth_dma_length : natural := 8;
signal dp_clk : std_logic := '1'; signal tb_end : std_logic := '0';
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 dp_clk : std_logic := '1';
signal block_len : std_logic_vector(c_halfword_w - 1 downto 0) := TO_UVEC(c_block_len, c_halfword_w); signal dp_rst : std_logic;
signal nof_packets_in_msg : std_logic_vector(c_word_w - 1 downto 0) := TO_UVEC(g_nof_packets_in_msg, c_word_w); signal mm_clk : std_logic := '1';
signal nof_msg : std_logic_vector(c_word_w - 1 downto 0) := TO_UVEC(g_nof_msg, c_word_w); signal mm_rst : std_logic;
signal dma_len : std_logic_vector(c_word_w - 1 downto 0) := TO_UVEC(c_dma_len, c_word_w);
signal start_address : std_logic_vector(c_longword_w - 1 downto 0) := std_logic_vector(g_start_address);
signal hdr_fields_slv : std_logic_vector(1023 downto 0) := (others => '0'); signal block_len : std_logic_vector(c_halfword_w - 1 downto 0) := TO_UVEC(c_block_len, c_halfword_w);
signal rx_rdma_header : t_rdma_packetiser_roce_header; signal nof_msg : std_logic_vector(c_word_w - 1 downto 0) := TO_UVEC(g_nof_msg, c_word_w);
--signal exp_rdma_header : t_rdma_packetiser_roce_header := func_rdma_packetiser_map_header(c_hdr_fields_slv_rst, g_use_immediate); signal dma_len : std_logic_vector(c_word_w - 1 downto 0) := TO_UVEC(c_dma_len, c_word_w);
signal in_en : std_logic := '0'; signal start_address : std_logic_vector(c_longword_w - 1 downto 0) := std_logic_vector(g_start_address);
signal immediate_data : std_logic_vector(c_word_w - 1 downto 0) := X"89ABCDEF";
signal snk_in : t_dp_sosi := c_dp_sosi_rst; signal first_hdr_fields_arr : std_logic_vector(1023 downto 0) := (others => '0');
signal snk_out : t_dp_siso := c_dp_siso_rdy; signal mid_hdr_fields_arr : std_logic_vector(1023 downto 0) := (others => '0');
signal src_out : t_dp_sosi := c_dp_sosi_rst; signal last_hdr_fields_arr : std_logic_vector(1023 downto 0) := (others => '0');
signal src_in : t_dp_siso := c_dp_siso_rdy; signal wo_hdr_fields_arr : 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, c_rdma_packetiser_wo_hdr_field_arr);
signal in_en : std_logic := '0';
signal mm_done : 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 sop_sosi : t_dp_sosi := c_dp_sosi_rst;
signal reg_hdr_dat_copi : t_mem_copi := c_mem_copi_rst; signal reg_hdr_dat_copi : t_mem_copi := c_mem_copi_rst;
signal reg_hdr_dat_cipo : t_mem_cipo; signal reg_hdr_dat_cipo : t_mem_cipo;
...@@ -106,25 +119,159 @@ begin ...@@ -106,25 +119,159 @@ begin
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; mm_rst <= '1', '0' after c_mm_clk_period * 7;
mm_clk <= (not mm_clk) or tb_end after c_mm_clk_period / 2; 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
-- dp stimuli -- dp stimuli
proc_common_wait_until_low(dp_clk, dp_rst); proc_common_wait_until_low(dp_clk, dp_rst);
proc_common_wait_until_high(dp_clk, mm_done); -- wait mm setup
proc_common_wait_some_cycles(dp_clk, 100); proc_common_wait_some_cycles(dp_clk, 100);
in_en <= '1'; in_en <= '1';
for rep in 0 to g_nof_rep - 1 loop for rep in 0 to g_nof_rep - 1 loop
proc_dp_gen_block_data(1, true, c_data_w, c_data_w, c_data_init, 0, 0, g_frame_len, 0, 0, '0', TO_DP_BSN(rep), dp_clk, in_en, snk_out, snk_in); proc_dp_gen_block_data(1, true, g_data_w, g_data_w, c_data_init, 0, 0, g_frame_len, 0, 0, '0', TO_DP_BSN(rep), dp_clk, in_en, snk_out, snk_in);
end loop; end loop;
proc_common_wait_some_cycles(dp_clk, 100); proc_common_wait_some_cycles(dp_clk, 100);
in_en <= '0'; in_en <= '0';
wait; wait;
end process; end process;
p_mm_setup : process
begin
proc_common_wait_until_low(dp_clk, mm_rst);
proc_common_wait_until_low(dp_clk, dp_rst);
proc_common_wait_some_cycles(mm_clk, 50);
proc_mem_mm_bus_wr(c_mm_addr_config_start_address, start_address(31 downto 0), mm_clk, reg_hdr_dat_cipo, reg_hdr_dat_copi);
proc_mem_mm_bus_wr(c_mm_addr_config_start_address + 1, start_address(63 downto 32), mm_clk, reg_hdr_dat_cipo, reg_hdr_dat_copi);
proc_mem_mm_bus_wr(c_mm_addr_config_nof_msg, g_nof_msg, mm_clk, reg_hdr_dat_cipo, reg_hdr_dat_copi);
proc_mem_mm_bus_wr(c_mm_addr_config_nof_packets_in_msg, g_nof_packets_in_msg, mm_clk, reg_hdr_dat_cipo, reg_hdr_dat_copi);
proc_mem_mm_bus_wr(c_mm_addr_config_use_msg_cnt_as_immediate, sel_a_b(g_use_msg_cnt_as_immediate, 1, 0), mm_clk, reg_hdr_dat_cipo, reg_hdr_dat_copi);
proc_mem_mm_bus_wr(c_mm_addr_config_use_immediate, sel_a_b(g_use_immediate, 1, 0), mm_clk, reg_hdr_dat_cipo, reg_hdr_dat_copi);
proc_mem_mm_bus_wr(c_mm_addr_immediate_data, immediate_data, mm_clk, reg_hdr_dat_cipo, reg_hdr_dat_copi);
proc_mem_mm_bus_wr(c_mm_addr_reth_dma_length, c_dma_len, mm_clk, reg_hdr_dat_cipo, reg_hdr_dat_copi);
mm_done <= '1';
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
proc_common_wait_until_high(dp_clk, mm_done); -- wait mm setup
for rep in 0 to g_nof_rep - 1 loop
proc_common_wait_until_high(dp_clk, sop_sosi.sop); -- wait for sop of dp_offload
v_exp_bth_psn := v_p;
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;
-- calculate expected lengths
v_exp_udp_total_length := c_network_udp_header_len + c_rdma_packetiser_bth_len + to_uint(block_len) + c_rdma_packetiser_icrc_len;
v_exp_reth_virtual_address := (others => '0');
v_exp_reth_dma_length := 0;
if v_exp_bth_opcode = c_rdma_packetiser_opcode_uc_write_first or
v_exp_bth_opcode = c_rdma_packetiser_opcode_uc_write_only or
v_exp_bth_opcode = c_rdma_packetiser_opcode_uc_write_only_imm then
v_exp_udp_total_length := v_exp_udp_total_length + c_rdma_packetiser_reth_len;
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;
end if;
if v_exp_bth_opcode = c_rdma_packetiser_opcode_uc_write_only_imm or
v_exp_bth_opcode = c_rdma_packetiser_opcode_uc_write_last_imm then
v_exp_udp_total_length := v_exp_udp_total_length + c_rdma_packetiser_imm_len;
end if;
v_exp_ip_total_length := c_network_ip_header_len + v_exp_udp_total_length;
-- select header based on expected opcode
if v_exp_bth_opcode = c_rdma_packetiser_opcode_uc_write_first or
v_exp_bth_opcode = c_rdma_packetiser_opcode_uc_write_only then
rx_rdma_header <= func_rdma_packetiser_map_header(first_hdr_fields_arr, c_rdma_packetiser_first_hdr_field_arr);
v_exp_immediate_data := (others => '0'); -- does not exist in this header
elsif v_exp_bth_opcode = c_rdma_packetiser_opcode_uc_write_middle or
v_exp_bth_opcode = c_rdma_packetiser_opcode_uc_write_last then
rx_rdma_header <= func_rdma_packetiser_map_header(mid_hdr_fields_arr, c_rdma_packetiser_mid_hdr_field_arr);
v_exp_immediate_data := (others => '0'); -- does not exist in this header
elsif v_exp_bth_opcode = c_rdma_packetiser_opcode_uc_write_last_imm then
rx_rdma_header <= func_rdma_packetiser_map_header(last_hdr_fields_arr, c_rdma_packetiser_last_hdr_field_arr);
elsif v_exp_bth_opcode = c_rdma_packetiser_opcode_uc_write_only_imm then
rx_rdma_header <= func_rdma_packetiser_map_header(wo_hdr_fields_arr, c_rdma_packetiser_wo_hdr_field_arr);
end if;
-- assign expected values to signal to view in wave window.
-- defaults
exp_rdma_header.eth.eth_type <= x"0800";
exp_rdma_header.ip.version <= to_uvec(4, 4);
exp_rdma_header.ip.header_length <= to_uvec(5, 4);
exp_rdma_header.ip.flags <= to_uvec(2, 3);
exp_rdma_header.ip.time_to_live <= to_uvec(127, 8);
exp_rdma_header.ip.protocol <= to_uvec(17, 8);
exp_rdma_header.bth.partition_key <= to_uvec(65535, 16);
-- changed by DUT
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;
-- increase counters
v_p := v_p + 1;
v_m := v_p / g_nof_packets_in_msg;
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_data_w => 512 g_data_w => g_data_w
) )
port map ( port map (
st_clk => dp_clk, st_clk => dp_clk,
...@@ -143,4 +290,81 @@ begin ...@@ -143,4 +290,81 @@ begin
block_len => block_len block_len => block_len
); );
-------------------------------------------------------------------------------
-- Header for first packets or write only without immediate data
-------------------------------------------------------------------------------
u_dp_offload_first: entity dp_lib.dp_offload_rx
generic map (
g_nof_streams => 1,
g_data_w => g_data_w,
g_symbol_w => c_byte_w,
g_hdr_field_arr => c_rdma_packetiser_first_hdr_field_arr
)
port map (
dp_clk => dp_clk,
dp_rst => dp_rst,
mm_clk => mm_clk,
mm_rst => mm_rst,
snk_in_arr(0) => src_out,
hdr_fields_raw_arr(0) => first_hdr_fields_arr
);
-------------------------------------------------------------------------------
-- Header for middle or last without immediate data (no RETH, no immediate data)
-------------------------------------------------------------------------------
u_dp_offload_mid: entity dp_lib.dp_offload_rx
generic map (
g_nof_streams => 1,
g_data_w => g_data_w,
g_symbol_w => c_byte_w,
g_hdr_field_arr => c_rdma_packetiser_mid_hdr_field_arr
)
port map (
dp_clk => dp_clk,
dp_rst => dp_rst,
mm_clk => mm_clk,
mm_rst => mm_rst,
snk_in_arr(0) => src_out,
hdr_fields_raw_arr(0) => mid_hdr_fields_arr
);
-------------------------------------------------------------------------------
-- Header for last packets with immediate data
-------------------------------------------------------------------------------
u_dp_offload_last: entity dp_lib.dp_offload_rx
generic map (
g_nof_streams => 1,
g_data_w => g_data_w,
g_symbol_w => c_byte_w,
g_hdr_field_arr => c_rdma_packetiser_last_hdr_field_arr
)
port map (
dp_clk => dp_clk,
dp_rst => dp_rst,
mm_clk => mm_clk,
mm_rst => mm_rst,
snk_in_arr(0) => src_out,
hdr_fields_raw_arr(0) => last_hdr_fields_arr
);
-------------------------------------------------------------------------------
-- Header for write only packets with immediate data
-------------------------------------------------------------------------------
u_dp_offload_wo: entity dp_lib.dp_offload_rx
generic map (
g_nof_streams => 1,
g_data_w => g_data_w,
g_symbol_w => c_byte_w,
g_hdr_field_arr => c_rdma_packetiser_wo_hdr_field_arr
)
port map (
dp_clk => dp_clk,
dp_rst => dp_rst,
mm_clk => mm_clk,
mm_rst => mm_rst,
snk_in_arr(0) => src_out,
src_out_arr(0) => sop_sosi,
hdr_fields_raw_arr(0) => wo_hdr_fields_arr
);
end tb; end tb;
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
-- Usage: -- Usage:
-- > as 3 -- > as 3
-- > run -all -- > run -all
-- Remark: testbench takes roughly 3 minutes without wave window.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
library IEEE; library IEEE;
...@@ -40,6 +41,7 @@ architecture tb of tb_tb_rdma_packetiser_assemble_header is ...@@ -40,6 +41,7 @@ architecture tb of tb_tb_rdma_packetiser_assemble_header is
signal tb_end : std_logic := '0'; -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end' signal tb_end : std_logic := '0'; -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end'
begin begin
-- All generics of TB -- All generics of TB
-- g_data_w : natural := c_word_w;
-- g_use_immediate : boolean := true; -- g_use_immediate : boolean := true;
-- g_use_msg_cnt_as_immediate : boolean := true; -- g_use_msg_cnt_as_immediate : boolean := true;
-- g_nof_rep : natural := 15; -- g_nof_rep : natural := 15;
...@@ -48,14 +50,14 @@ begin ...@@ -48,14 +50,14 @@ begin
-- g_nof_packets_in_msg : natural := 4; -- g_nof_packets_in_msg : natural := 4;
-- g_nof_msg : natural := 3 -- g_nof_msg : natural := 3
u_lo_addr : entity work.tb_rdma_packetiser_assemble_header generic map( true, true, 20, 15, c_low_start_addr, 4, 5); u_lo_addr : entity work.tb_rdma_packetiser_assemble_header generic map( 32, true, true, 50, 15, c_low_start_addr, 4, 5);
u_hi_addr : entity work.tb_rdma_packetiser_assemble_header generic map( true, true, 20, 15, c_high_start_addr, 4, 5); u_hi_addr : entity work.tb_rdma_packetiser_assemble_header generic map( 32, true, true, 50, 15, c_high_start_addr, 4, 5);
u_no_mid : entity work.tb_rdma_packetiser_assemble_header generic map( true, true, 20, 15, c_high_start_addr, 2, 5); u_no_mid : entity work.tb_rdma_packetiser_assemble_header generic map( 32, true, true, 50, 15, c_high_start_addr, 2, 5);
u_wr_only : entity work.tb_rdma_packetiser_assemble_header generic map( true, true, 20, 15, c_high_start_addr, 1, 5); u_wr_only : entity work.tb_rdma_packetiser_assemble_header generic map( 32, true, true, 50, 15, c_high_start_addr, 1, 5);
u_large : entity work.tb_rdma_packetiser_assemble_header generic map( true, true, 10, 2000, c_low_start_addr, 3, 1); u_large : entity work.tb_rdma_packetiser_assemble_header generic map( 32, true, true, 10, 2000, c_low_start_addr, 3, 1);
u_no_imm_cnt : entity work.tb_rdma_packetiser_assemble_header generic map( false, true, 100, 15, c_low_start_addr, 4, 10); u_no_imm_cnt : entity work.tb_rdma_packetiser_assemble_header generic map( 32, false, true, 50, 15, c_low_start_addr, 4, 5);
u_no_cnt : entity work.tb_rdma_packetiser_assemble_header generic map( true, false, 20, 15, c_low_start_addr, 4, 5); u_no_cnt : entity work.tb_rdma_packetiser_assemble_header generic map( 32, true, false, 50, 15, c_low_start_addr, 4, 5);
u_no_imm : entity work.tb_rdma_packetiser_assemble_header generic map( false, false, 30, 7, c_high_start_addr, 3, 2); u_no_imm : entity work.tb_rdma_packetiser_assemble_header generic map( 32, false, false, 50, 7, c_high_start_addr, 3, 5);
u_one : entity work.tb_rdma_packetiser_assemble_header generic map( true, true, 20, 1, c_low_start_addr, 1, 5); u_wide : entity work.tb_rdma_packetiser_assemble_header generic map( 1024, true, true, 50, 6, c_low_start_addr, 1, 5);
u_many : entity work.tb_rdma_packetiser_assemble_header generic map( true, true, 6000, 3, c_low_start_addr, 5, 1000); u_many : entity work.tb_rdma_packetiser_assemble_header generic map( 32, true, true, 600, 7, c_low_start_addr, 100, 5);
end tb; end tb;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment