Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
H
HDL
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Jira
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
RTSD
HDL
Merge requests
!358
initial commit of rdma_packetiser library
Code
Review changes
Check out branch
Download
Patches
Plain diff
Merged
initial commit of rdma_packetiser library
HPR-129
into
master
Overview
18
Commits
3
Pipelines
3
Changes
5
All threads resolved!
Show all comments
Merged
Reinier van der Walle
requested to merge
HPR-129
into
master
1 year ago
Overview
18
Commits
3
Pipelines
3
Changes
5
All threads resolved!
Show all comments
Expand
Closes
HPR-129
0
0
Merge request reports
Compare
master
version 2
e1153b5f
1 year ago
version 1
5f5878fc
1 year ago
master (base)
and
latest version
latest version
f6b95cf0
3 commits,
1 year ago
version 2
e1153b5f
2 commits,
1 year ago
version 1
5f5878fc
1 commit,
1 year ago
5 files
+
756
−
0
Inline
Compare changes
Side-by-side
Inline
Show whitespace changes
Show one file at a time
Files
5
Search (e.g. *.vue) (Ctrl+P)
applications/rdma_demo/libraries/rdma_packetiser/src/vhdl/rdma_packetiser_assemble_header.vhd
0 → 100644
+
195
−
0
Options
-------------------------------------------------------------------------------
--
-- Copyright 2023
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-------------------------------------------------------------------------------
-- Author: R. van der Walle
-- Purpose: Assembles the RDMA header at snk_in.sop
-- 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
-- header.
-- . g_use_msg_cnt_as_immediate: When true, the message counter going from 0 to
-- "nof_msg" is used as immediate data. When false, the "immediate_data"
-- input port is used.
-- Signal inputs:
-- . immediate_data: Will be used as immediate data when
-- g_use_msg_cnt_as_immediate = False.
-- . block_len: Should be set to the length of the incoming data frame in octets.
-- . nof_packets_in_msg: Should be set to the desired amount of packets in a message.
-- . nof_msg: Should be set to the desired amount of messages, this determines the
-- address space aswell, see remarks.
-- . dma_len: The amount with which the address should increase every message,
-- this should be set to >= nof_packets_in_msg * block_len.
-- . start_address: The start address for the virtual_address field.
-- Remarks
-- . The hdr_fields_slv output is set one st_clk cycle after snk_in.sop and will
-- contain the RoCEv2 (RDMA over Converged Ethernet v2) header information for
-- the corresponding data frame.
-- . The virtual_address is set automatically by increasing it with dma_len every
-- new message. The virtual address is reset to "start_address" when the number
-- of messages has reached "nof_msg". Then the cycle repeats.
-- . The PSN field (= Packet Sequence Number) is set to LSBs of the incoming BSN.
-- This can be used to check the order or detect missing packets at the receiver.
-- References:
-- . [1] https://support.astron.nl/confluence/x/3pKrB
library
IEEE
,
common_lib
,
dp_lib
,
eth_lib
;
use
IEEE
.
std_logic_1164
.
all
;
use
IEEE
.
numeric_std
.
all
;
use
common_lib
.
common_pkg
.
all
;
use
common_lib
.
common_mem_pkg
.
all
;
use
common_lib
.
common_network_layers_pkg
.
all
;
use
common_lib
.
common_field_pkg
.
all
;
use
dp_lib
.
dp_stream_pkg
.
all
;
use
dp_lib
.
dp_components_pkg
.
all
;
use
eth_lib
.
eth_pkg
.
all
;
use
eth_lib
.
eth_tester_pkg
.
all
;
use
work
.
rdma_packetiser_pkg
.
all
;
entity
rdma_packetiser_assemble_header
is
generic
(
g_use_immediate
:
boolean
:
=
true
;
g_use_msg_cnt_as_immediate
:
boolean
:
=
true
);
port
(
-- Clocks and reset
st_clk
:
in
std_logic
;
st_rst
:
in
std_logic
;
snk_in
:
in
t_dp_sosi
:
=
c_dp_sosi_rst
;
hdr_fields_slv
:
out
std_logic_vector
(
1023
downto
0
)
:
=
(
others
=>
'0'
);
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
)
);
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_ip_udp_app_hdr_length
:
natural
:
=
c_network_ip_header_len
+
c_udp_app_hdr_length
;
type
t_state
is
(
s_first
,
s_middle
,
s_last
);
type
t_reg
is
record
-- record to keep the registers organized.
state
:
t_state
;
opcode
:
std_logic_vector
(
c_byte_w
-
1
downto
0
);
immediate_data
:
std_logic_vector
(
c_rdma_packetiser_roce_imm_len
*
c_octet_w
-
1
downto
0
);
psn
:
std_logic_vector
(
c_word_w
-
1
downto
0
);
virtual_address
:
unsigned
(
c_longword_w
-
1
downto
0
);
dma_len
:
unsigned
(
c_word_w
-
1
downto
0
);
p_cnt
:
natural
;
-- Packet count (0 to nof_packets_in_msg).
msg_cnt
:
natural
;
-- message count (0 to nof_msg).
udp_total_length
:
natural
;
ip_total_length
:
natural
;
nof_packets_in_msg
:
natural
;
end
record
;
constant
c_reg_rst
:
t_reg
:
=
(
s_first
,
(
others
=>
'1'
),
(
others
=>
'0'
),
(
others
=>
'0'
),
(
others
=>
'0'
),
(
others
=>
'0'
),
0
,
0
,
0
,
0
,
0
);
signal
d
,
q
:
t_reg
;
begin
q
<=
d
when
rising_edge
(
st_clk
);
-- State machine to derive RDMA header fields.
p_comb
:
process
(
st_rst
,
q
,
snk_in
,
nof_packets_in_msg
,
start_address
,
nof_msg
,
immediate_data
,
dma_len
,
block_len
)
variable
v
:
t_reg
;
begin
v
:
=
q
;
if
snk_in
.
sop
=
'1'
then
v
.
psn
:
=
resize_uvec
(
snk_in
.
bsn
,
c_word_w
);
v
.
p_cnt
:
=
q
.
p_cnt
+
1
;
case
q
.
state
is
when
s_first
=>
-- wait to start a new message and set the first opcode.
v
.
p_cnt
:
=
1
;
if
q
.
p_cnt
>=
v
.
nof_packets_in_msg
then
-- (re)set message counter and virtual address.
if
q
.
msg_cnt
>=
to_uint
(
nof_msg
)
-
1
then
v
.
msg_cnt
:
=
0
;
else
v
.
msg_cnt
:
=
q
.
msg_cnt
+
1
;
v
.
virtual_address
:
=
q
.
virtual_address
+
q
.
dma_len
;
end
if
;
end
if
;
if
v
.
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
.
opcode
:
=
c_rdma_packetiser_opcode_uc_write_only_imm
;
end
if
;
elsif
v
.
nof_packets_in_msg
=
2
then
-- set opcode to write_first.
v
.
state
:
=
s_last
;
-- next state is last as there are only 2 packets.
v
.
opcode
:
=
c_rdma_packetiser_opcode_uc_write_first
;
elsif
v
.
nof_packets_in_msg
>
2
then
v
.
state
:
=
s_middle
;
v
.
opcode
:
=
c_rdma_packetiser_opcode_uc_write_first
;
end
if
;
when
s_middle
=>
-- wait unitl the first packet is done and set next opcode.
v
.
opcode
:
=
c_rdma_packetiser_opcode_uc_write_middle
;
if
q
.
p_cnt
>=
v
.
nof_packets_in_msg
-
2
then
-- wait until last middle packet
v
.
state
:
=
s_last
;
end
if
;
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
.
opcode
:
=
c_rdma_packetiser_opcode_uc_write_last_imm
;
end
if
;
end
case
;
end
if
;
if
v
.
msg_cnt
=
0
then
-- set on new message
v
.
virtual_address
:
=
unsigned
(
start_address
);
v
.
dma_len
:
=
unsigned
(
dma_len
);
v
.
udp_total_length
:
=
c_udp_app_hdr_length
+
to_uint
(
block_len
)
+
c_rdma_packetiser_roce_icrc_len
;
v
.
ip_total_length
:
=
c_ip_udp_app_hdr_length
+
to_uint
(
block_len
)
+
c_rdma_packetiser_roce_icrc_len
;
v
.
nof_packets_in_msg
:
=
to_uint
(
nof_packets_in_msg
);
v
.
immediate_data
:
=
immediate_data
;
end
if
;
if
st_rst
=
'1'
then
v
:
=
c_reg_rst
;
end
if
;
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
;
end
str
;
Loading