Newer
Older
-------------------------------------------------------------------------------
--
-- 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: E. Kooistra
-- Purpose: This package contains eth_tester specific constants and functions
-- Description:
--
LIBRARY IEEE, common_lib;
USE IEEE.std_logic_1164.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
USE common_lib.common_field_pkg.ALL;
USE common_lib.common_network_layers_pkg.ALL;
PACKAGE eth_tester_pkg is
CONSTANT c_eth_tester_bg_block_len_max : NATURAL := c_network_eth_payload_jumbo_max; -- 9000 octets
CONSTANT c_eth_tester_rx_block_len_max : NATURAL := c_network_eth_payload_jumbo_max + c_network_eth_crc_len; -- 9004 octets
CONSTANT c_eth_tester_eth_packet_len_max : NATURAL := c_network_eth_word_align_len + c_network_eth_frame_jumbo_max; -- 9020 octets = 2 word align + 14 header + 9000 + 4 crc
-- Support maximum (2**31-1)/200e6 = 10.7 s BG sync interval for sync timeout
-- in BSN monitors, assuming st_clk at 200 MHz and with maximum NATURAL value
-- of c_natural_high = 2**31 - 1.
CONSTANT c_eth_tester_sync_timeout : NATURAL := c_natural_high;
-- hdr_field_sel bit selects where the hdr_field value is set:
-- . 0 = data path controlled, value is set in data path, so field_default()
-- is not used.
-- . 1 = MM controlled, value is set via MM or by the field_default(), so any
-- data path setting in eth_tester.vhd is not used.
-- . For constant values it is convenient to use MM controlled, because then
-- the field_default() is used that can be set here in
-- c_eth_tester_hdr_field_arr.
-- . For reserved values it is convenient to use MM controlled, because then
-- in future they could still be changed via MM without having to recompile
-- the FW.
-- . Typically only use data path controlled if the value has to be set
-- dynamically, so dependent on the state of the FW.
-- . If a data path controlled field is not set in the FW, then it defaults
-- to 0 by declaring hdr_fields_in_arr with all 0. Hence e.g. udp_checksum
-- = 0 can be achieve via data path and default hdr_fields_in_arr = 0 or
-- via MM controlled and field_default(0).
CONSTANT c_eth_tester_nof_hdr_fields : NATURAL := 1+3+12+4+4;
CONSTANT c_eth_tester_hdr_field_sel : STD_LOGIC_VECTOR(c_eth_tester_nof_hdr_fields-1 DOWNTO 0) := "1"&"101"&"111011111001"&"0100"&"0100";
-- Default use destination MAC/IP/UDP = 0, so these have to be MM programmed
-- before eth_tester packets can be send.
CONSTANT c_eth_tester_hdr_field_arr : t_common_field_arr(c_eth_tester_nof_hdr_fields-1 DOWNTO 0) := (
( field_name_pad("word_align" ), "RW", 16, field_default(0) ), -- Tx TSE IP will strip these 2 padding bytes
( field_name_pad("eth_dst_mac" ), "RW", 48, field_default(0) ), -- c_eth_tester_eth_dst_mac
( 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) ), -- depends on BG block size, so set by data path
( 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) ), -- c_eth_tester_ip_dst_addr
( field_name_pad("udp_src_port" ), "RW", 16, field_default(0) ),
( field_name_pad("udp_dst_port" ), "RW", 16, field_default(0) ), -- c_eth_tester_udp_dst_port
( field_name_pad("udp_total_length" ), "RW", 16, field_default(0) ), -- depends on BG block size, so set by data path
( field_name_pad("udp_checksum" ), "RW", 16, field_default(0) ),
( field_name_pad("dp_length" ), "RW", 16, field_default(0) ),
( field_name_pad("dp_reserved" ), "RW", 15, field_default(0) ),
( field_name_pad("dp_sync" ), "RW", 1, field_default(0) ),
( field_name_pad("dp_bsn" ), "RW", 64, field_default(0) )
);
CONSTANT c_eth_tester_reg_hdr_dat_addr_w : NATURAL := ceil_log2(field_nof_words(c_eth_tester_hdr_field_arr, c_word_w)); -- = 5
CONSTANT c_eth_tester_reg_hdr_dat_addr_span : NATURAL := 2**c_eth_tester_reg_hdr_dat_addr_w; -- = 32
CONSTANT c_eth_tester_app_hdr_len : NATURAL := 12; -- octets
-- Source ETH MAC/IP/UDP:
-- . MAC address 00:22:86:08:pp:qq = UNB_ETH_SRC_MAC_BASE in
-- libraries/unb_osy/unbos_eth.h, pp = backplane ID, qq = node ID
-- . IP address 10.99.xx.yy = g_base_ip in ctrl_unb2#_board.vhd used in
-- libraries/unb_osy/unbos_eth.c, xx = backplane ID, yy = node ID + 1
-- . UDP port 15:8 = E0, 7:0 = gn_id (= ID[7:0] = backplane[5:0] & node[1:0])
CONSTANT c_eth_tester_eth_src_mac_47_16 : STD_LOGIC_VECTOR(31 DOWNTO 0) := x"00228608";
CONSTANT c_eth_tester_ip_src_addr_31_16 : STD_LOGIC_VECTOR(15 DOWNTO 0) := x"0A63";
CONSTANT c_eth_tester_udp_src_port_15_8 : STD_LOGIC_VECTOR( 7 DOWNTO 0) := x"E0";
-- Default eth_tester UDP port for first stream via 1GbE.
-- Do not use UDP port 0x1388 = 5000 for eth_tester, because port 5000 is
-- used for M&C via 1GbE-I.
CONSTANT c_eth_tester_udp_port : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(6001, 16); -- 0x1771 = 6001
dp_length : STD_LOGIC_VECTOR(15 DOWNTO 0);
dp_reserved : STD_LOGIC_VECTOR(14 DOWNTO 0);
dp_sync : STD_LOGIC;
dp_bsn : STD_LOGIC_VECTOR(63 DOWNTO 0);
END RECORD;
TYPE t_eth_tester_header IS RECORD
eth : t_network_eth_header;
ip : t_network_ip_header;
udp : t_network_udp_header;
app : t_eth_tester_app_header;
END RECORD;
-- Map global node index on UniBoard2 to node src MAC, IP and UDP port
FUNCTION func_eth_tester_gn_index_to_mac_15_0(gn_index : NATURAL; eth_port_index : NATURAL) RETURN STD_LOGIC_VECTOR;
FUNCTION func_eth_tester_gn_index_to_mac_15_0(gn_index : NATURAL) RETURN STD_LOGIC_VECTOR; -- default use 1GbE port I
FUNCTION func_eth_tester_gn_index_to_ip_15_0(gn_index : NATURAL; eth_port_index : NATURAL) RETURN STD_LOGIC_VECTOR;
FUNCTION func_eth_tester_gn_index_to_ip_15_0(gn_index : NATURAL) RETURN STD_LOGIC_VECTOR; -- default use 1GbE port I
FUNCTION func_eth_tester_gn_index_to_udp_7_0(gn_index : NATURAL; eth_port_index : NATURAL) RETURN STD_LOGIC_VECTOR;
FUNCTION func_eth_tester_gn_index_to_udp_7_0(gn_index : NATURAL) RETURN STD_LOGIC_VECTOR; -- default use 1GbE port I
-- Map packet header fields to t_eth_tester_header record
FUNCTION func_eth_tester_map_header(hdr_fields_raw : STD_LOGIC_VECTOR) RETURN t_eth_tester_header;
END eth_tester_pkg;
PACKAGE BODY eth_tester_pkg IS
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
FUNCTION func_eth_tester_gn_index_to_mac_15_0(gn_index : NATURAL; eth_port_index : NATURAL) RETURN STD_LOGIC_VECTOR IS
-- Assume gn_index < 256.
-- Use default address for 1GbE II (eth_port_index = 0) and
-- an address offset for 1GbE II (eth_port_index = 1)
CONSTANT c_unb_nr : NATURAL := gn_index / c_4; -- 4 PN per Uniboard2
CONSTANT c_node_nr : NATURAL := gn_index MOD c_4;
CONSTANT c_offset : NATURAL := eth_port_index * c_4;
CONSTANT c_mac_15_0 : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(c_unb_nr, 8) & TO_UVEC(c_node_nr + c_offset, 8);
BEGIN
RETURN c_mac_15_0;
END func_eth_tester_gn_index_to_mac_15_0;
FUNCTION func_eth_tester_gn_index_to_mac_15_0(gn_index : NATURAL) RETURN STD_LOGIC_VECTOR IS
BEGIN
RETURN func_eth_tester_gn_index_to_mac_15_0(gn_index, 0); -- default use 1GbE port I
END func_eth_tester_gn_index_to_mac_15_0;
FUNCTION func_eth_tester_gn_index_to_ip_15_0(gn_index : NATURAL; eth_port_index : NATURAL) RETURN STD_LOGIC_VECTOR IS
-- Assume gn_index < 256.
-- Use default address for 1GbE II (eth_port_index = 0) and
-- an address offset for 1GbE II (eth_port_index = 1)
CONSTANT c_unb_nr : NATURAL := gn_index / c_4; -- 4 PN per Uniboard2
CONSTANT c_node_nr : NATURAL := gn_index MOD c_4;
CONSTANT c_offset : NATURAL := eth_port_index * c_4;
CONSTANT c_ip_15_0 : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(c_unb_nr, 8) & TO_UVEC(c_node_nr + 1 + c_offset, 8); -- +1 to avoid IP = *.*.*.0
BEGIN
RETURN c_ip_15_0;
END func_eth_tester_gn_index_to_ip_15_0;
FUNCTION func_eth_tester_gn_index_to_ip_15_0(gn_index : NATURAL) RETURN STD_LOGIC_VECTOR IS
BEGIN
RETURN func_eth_tester_gn_index_to_ip_15_0(gn_index, 0); -- default use 1GbE port I
END func_eth_tester_gn_index_to_ip_15_0;
FUNCTION func_eth_tester_gn_index_to_udp_7_0(gn_index : NATURAL; eth_port_index : NATURAL) RETURN STD_LOGIC_VECTOR IS
-- Assume gn_index < 128.
-- Use default udp port for 1GbE I (eth_port_index = 0) and
-- an increment udp port for 1GbE II (eth_port_index = 1)
CONSTANT c_offset : NATURAL := eth_port_index * c_128; -- MSbit 7
CONSTANT c_udp_7_0 : STD_LOGIC_VECTOR(7 DOWNTO 0) := TO_UVEC(gn_index + c_offset, 8);
BEGIN
RETURN c_udp_7_0;
END func_eth_tester_gn_index_to_udp_7_0;
FUNCTION func_eth_tester_gn_index_to_udp_7_0(gn_index : NATURAL) RETURN STD_LOGIC_VECTOR IS
BEGIN
RETURN func_eth_tester_gn_index_to_udp_7_0(gn_index, 0); -- default use 1GbE port I
END func_eth_tester_gn_index_to_udp_7_0;
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
FUNCTION func_eth_tester_map_header(hdr_fields_raw : STD_LOGIC_VECTOR) RETURN t_eth_tester_header IS
VARIABLE v : t_eth_tester_header;
BEGIN
-- eth header
v.eth.dst_mac := hdr_fields_raw(field_hi(c_eth_tester_hdr_field_arr, "eth_dst_mac") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "eth_dst_mac"));
v.eth.src_mac := hdr_fields_raw(field_hi(c_eth_tester_hdr_field_arr, "eth_src_mac") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "eth_src_mac"));
v.eth.eth_type := hdr_fields_raw(field_hi(c_eth_tester_hdr_field_arr, "eth_type") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "eth_type"));
-- ip header
v.ip.version := hdr_fields_raw(field_hi(c_eth_tester_hdr_field_arr, "ip_version") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "ip_version"));
v.ip.header_length := hdr_fields_raw(field_hi(c_eth_tester_hdr_field_arr, "ip_header_length") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "ip_header_length"));
v.ip.services := hdr_fields_raw(field_hi(c_eth_tester_hdr_field_arr, "ip_services") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "ip_services"));
v.ip.total_length := hdr_fields_raw(field_hi(c_eth_tester_hdr_field_arr, "ip_total_length") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "ip_total_length"));
v.ip.identification := hdr_fields_raw(field_hi(c_eth_tester_hdr_field_arr, "ip_identification") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "ip_identification"));
v.ip.flags := hdr_fields_raw(field_hi(c_eth_tester_hdr_field_arr, "ip_flags") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "ip_flags"));
v.ip.fragment_offset := hdr_fields_raw(field_hi(c_eth_tester_hdr_field_arr, "ip_fragment_offset") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "ip_fragment_offset"));
v.ip.time_to_live := hdr_fields_raw(field_hi(c_eth_tester_hdr_field_arr, "ip_time_to_live") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "ip_time_to_live"));
v.ip.protocol := hdr_fields_raw(field_hi(c_eth_tester_hdr_field_arr, "ip_protocol") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "ip_protocol"));
v.ip.header_checksum := hdr_fields_raw(field_hi(c_eth_tester_hdr_field_arr, "ip_header_checksum") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "ip_header_checksum"));
v.ip.src_ip_addr := hdr_fields_raw(field_hi(c_eth_tester_hdr_field_arr, "ip_src_addr") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "ip_src_addr"));
v.ip.dst_ip_addr := hdr_fields_raw(field_hi(c_eth_tester_hdr_field_arr, "ip_dst_addr") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "ip_dst_addr"));
-- udp header
v.udp.src_port := hdr_fields_raw(field_hi(c_eth_tester_hdr_field_arr, "udp_src_port") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "udp_src_port"));
v.udp.dst_port := hdr_fields_raw(field_hi(c_eth_tester_hdr_field_arr, "udp_dst_port") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "udp_dst_port"));
v.udp.total_length := hdr_fields_raw(field_hi(c_eth_tester_hdr_field_arr, "udp_total_length") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "udp_total_length"));
v.udp.checksum := hdr_fields_raw(field_hi(c_eth_tester_hdr_field_arr, "udp_checksum") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "udp_checksum"));
-- app header
v.app.dp_length := hdr_fields_raw(field_hi(c_eth_tester_hdr_field_arr, "dp_length") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "dp_length"));
v.app.dp_reserved := hdr_fields_raw(field_hi(c_eth_tester_hdr_field_arr, "dp_reserved") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "dp_reserved"));
v.app.dp_sync := sl(hdr_fields_raw(field_hi(c_eth_tester_hdr_field_arr, "dp_sync") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "dp_sync")));
v.app.dp_bsn := hdr_fields_raw(field_hi(c_eth_tester_hdr_field_arr, "dp_bsn") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "dp_bsn"));
RETURN v;
END func_eth_tester_map_header;
END eth_tester_pkg;