1213 lines
70 KiB
VHDL
1213 lines
70 KiB
VHDL
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
|
|
library osvvm; -- Utility Library
|
|
context osvvm.OsvvmContext;
|
|
|
|
use work.math_pkg.all;
|
|
use work.rtps_package.all;
|
|
use work.user_config.all;
|
|
use work.rtps_config_package.all;
|
|
|
|
package rtps_test_package is
|
|
|
|
constant DEFAULT_GUIDPREFIX : GUIDPREFIX_TYPE; -- Deferred to Package Body
|
|
constant DEFAULT_ENTITYID : std_logic_vector(ENTITYID_WIDTH-1 downto 0); -- Deferred to Package Body
|
|
|
|
type TEST_PACKET_TYPE is record
|
|
-- Limit Packet Size to 2^16 (IPv4 size limit)
|
|
data : WORD_ARRAY_TYPE(0 to (2**16)/4);
|
|
length : natural;
|
|
end record;
|
|
|
|
constant LOCATOR_PORT_WIDTH : natural := CDR_LONG_WIDTH;
|
|
constant LOCATOR_ADDR_WIDTH : natural := 4*CDR_LONG_WIDTH;
|
|
|
|
type LOCATOR_TYPE is record
|
|
kind : std_logic_vector(LOCATOR_KIND_WIDTH-1 downto 0);
|
|
portn : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
|
|
addr : std_logic_vector(LOCATOR_ADDR_WIDTH-1 downto 0);
|
|
end record;
|
|
|
|
constant EMPTY_LOCATOR : LOCATOR_TYPE; -- Deferred to Package Body
|
|
|
|
-- Limit Number of Locators to maximum number that fits in a maximum length RTPS Submessage
|
|
type LOCATOR_TYPE_ARRAY is array (0 to ((2**16)/4)/6) of LOCATOR_TYPE;
|
|
|
|
type LOCATOR_LIST_TYPE is record
|
|
numLocators : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
|
|
locator : LOCATOR_TYPE_ARRAY;
|
|
end record;
|
|
|
|
constant EMPTY_LOCATOR_LIST : LOCATOR_LIST_TYPE; -- Deferred to Package Body
|
|
|
|
type SEQUENCENUMBER_SET_TYPE is record
|
|
base : SEQUENCENUMBER_TYPE;
|
|
numBits : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
|
|
bitmap : std_logic_vector(0 to 255);
|
|
end record;
|
|
|
|
constant DEFAULT_SEQUENCENUMBER_SET : SEQUENCENUMBER_SET_TYPE; -- Deferred to package Body
|
|
|
|
type FRAGMENTNUMBER_SET_TYPE is record
|
|
base : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
|
|
numBits : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
|
|
bitmap : std_logic_vector(0 to 255);
|
|
end record;
|
|
|
|
constant DEFAULT_FRAGMENTNUMBER_SET : FRAGMENTNUMBER_SET_TYPE; -- Deferred to Package Body
|
|
|
|
-- Valid Destination Locators
|
|
type DEST_LOCATOR_LIST_TYPE is record
|
|
meta : LOCATOR_LIST_TYPE;
|
|
user : LOCATOR_LIST_TYPE;
|
|
end record;
|
|
|
|
constant DEST_LOC : DEST_LOCATOR_LIST_TYPE; -- Deferred to Package Body
|
|
|
|
-- *UDP HEADER*
|
|
type UDP_HEADER_TYPE is record
|
|
src : LOCATOR_TYPE;
|
|
dest : LOCATOR_TYPE;
|
|
end record;
|
|
|
|
constant DEFAULT_UDP_HEADER : UDP_HEADER_TYPE; -- Deferred to Package Body
|
|
|
|
procedure gen_udp_header(ref : in UDP_HEADER_TYPE; output : inout TEST_PACKET_TYPE);
|
|
procedure fix_udp_packet(output : inout TEST_PACKET_TYPE);
|
|
|
|
-- *RTPS HEADER*
|
|
type RTPS_HEADER_TYPE is record
|
|
protocol : std_logic_vector(PROTOCOL_WIDTH-1 downto 0);
|
|
version : std_logic_vector(PROTOCOLVERSION_WIDTH-1 downto 0);
|
|
vendorId : std_logic_vector(VENDORID_WIDTH-1 downto 0);
|
|
guidPrefix : GUIDPREFIX_TYPE;
|
|
end record;
|
|
|
|
constant DEFAULT_RTPS_HEADER : RTPS_HEADER_TYPE; -- Deferred to Package Body
|
|
|
|
procedure gen_rtps_header( ref : in RTPS_HEADER_TYPE; output : inout TEST_PACKET_TYPE);
|
|
|
|
-- *GENERIC RTPS SUBMESSAGE HEADER*
|
|
type RTPS_SUBMESSAGE_TYPE is record
|
|
submessageID : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0);
|
|
flags : std_logic_vector(SUBMESSAGE_FLAGS_WIDTH-1 downto 0);
|
|
submessageLength : std_logic_vector(SUBMESSAGE_LENGTH_WIDTH-1 downto 0);
|
|
readerId : std_logic_vector(ENTITYID_WIDTH-1 downto 0);
|
|
writerId : std_logic_vector(ENTITYID_WIDTH-1 downto 0);
|
|
extraFlags : std_logic_vector(SUBMESSAGE_DATA_EXTRA_FLAGS_WIDTH-1 downto 0);
|
|
octetsToInlineQos : std_logic_vector(SUBMESSAGE_LENGTH_WIDTH-1 downto 0);
|
|
readerSNState : SEQUENCENUMBER_SET_TYPE;
|
|
count : std_logic_vector(COUNT_WIDTH-1 downto 0);
|
|
writerSN : SEQUENCENUMBER_TYPE;
|
|
fragmentNumberState : FRAGMENTNUMBER_SET_TYPE;
|
|
data : TEST_PACKET_TYPE;
|
|
fragmentStartingNumber : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
|
|
fragmentsInSubmessage : std_logic_vector(CDR_SHORT_WIDTH-1 downto 0);
|
|
fragmentSize : std_logic_vector(CDR_SHORT_WIDTH-1 downto 0);
|
|
sampleSize : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
|
|
gapStart : SEQUENCENUMBER_TYPE;
|
|
gapList : SEQUENCENUMBER_SET_TYPE;
|
|
firstSN : SEQUENCENUMBER_TYPE;
|
|
lastSN : SEQUENCENUMBER_TYPE;
|
|
lastFragmentNum : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
|
|
guidPrefix : GUIDPREFIX_TYPE;
|
|
unicastLocatorList : LOCATOR_LIST_TYPE;
|
|
multicastLocatorList : LOCATOR_LIST_TYPE;
|
|
unicastLocator : LOCATOR_TYPE;
|
|
multicastLocator : LOCATOR_TYPE;
|
|
unused : std_logic_vector(31 downto 0);
|
|
version : std_logic_vector(PROTOCOLVERSION_WIDTH-1 downto 0);
|
|
vendorId : std_logic_vector(VENDORID_WIDTH-1 downto 0);
|
|
timestamp : TIME_TYPE;
|
|
end record;
|
|
|
|
constant DEFAULT_RTPS_SUBMESSAGE : RTPS_SUBMESSAGE_TYPE; -- Deferred to Package Body
|
|
|
|
procedure gen_rtps_submessage( ref : in RTPS_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE);
|
|
procedure gen_rtps_handler_out(ref : in RTPS_SUBMESSAGE_TYPE; loc : in LOCATOR_TYPE; is_meta : in boolean; ts : in TIME_TYPE; src_guid : in GUIDPREFIX_TYPE; output : inout TEST_PACKET_TYPE);
|
|
|
|
type PARTICIPANT_DATA_TYPE is record
|
|
littleEndian : std_logic;
|
|
domainId : std_logic_vector(DOMAIN_ID_WIDTH-1 downto 0);
|
|
domainTag : STRING_WORD_ARRAY_TYPE;
|
|
protocolVersion : std_logic_vector(PROTOCOLVERSION_WIDTH-1 downto 0);
|
|
vendorId : std_logic_vector(VENDORID_WIDTH-1 downto 0);
|
|
guidPrefix : GUIDPREFIX_TYPE;
|
|
entityId : std_logic_vector(ENTITYID_WIDTH-1 downto 0);
|
|
expectsInlineQoS : std_logic_vector(CDR_BOOLEAN_WIDTH-1 downto 0);
|
|
metatrafficUnicastLocatorList : LOCATOR_LIST_TYPE;
|
|
metatrafficMulticastLocatorList : LOCATOR_LIST_TYPE;
|
|
defaultUnicastLocatorList : LOCATOR_LIST_TYPE;
|
|
defaultMulticastLocatorList : LOCATOR_LIST_TYPE;
|
|
leaseDuration : DURATION_TYPE;
|
|
manualLivelinessCount : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
|
|
builtinEndpointQoS : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
|
|
availableBuiltinEndpoints : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
|
|
end record;
|
|
|
|
constant DEFAULT_PARTICIPANT_DATA : PARTICIPANT_DATA_TYPE; -- Deferred to Pckage Body
|
|
|
|
procedure gen_participant_announcement( ref : in PARTICIPANT_DATA_TYPE; output : inout TEST_PACKET_TYPE);
|
|
|
|
type ENDPOINT_DATA_TYPE is record
|
|
littleEndian : std_logic;
|
|
participant : PARTICIPANT_DATA_TYPE;
|
|
entityId : std_logic_vector(ENTITYID_WIDTH-1 downto 0);
|
|
topic_name : STRING_WORD_ARRAY_TYPE;
|
|
type_name : STRING_WORD_ARRAY_TYPE;
|
|
durability : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0);
|
|
durability_service_cleanup_delay : DURATION_TYPE;
|
|
durability_service_history : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0);
|
|
durability_service_history_depth : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
|
|
durability_service_max_samples : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
|
|
durability_service_max_instances : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
|
|
durability_service_max_samples_per_instances : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
|
|
presentation : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0);
|
|
coherent_access : std_logic_vector(CDR_BOOLEAN_WIDTH-1 downto 0);
|
|
ordered_access : std_logic_vector(CDR_BOOLEAN_WIDTH-1 downto 0);
|
|
deadline : DURATION_TYPE;
|
|
latency_budget : DURATION_TYPE;
|
|
ownership : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0);
|
|
ownership_strength : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
|
|
liveliness : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0);
|
|
leaseDuration : DURATION_TYPE;
|
|
time_based_filter : DURATION_TYPE;
|
|
reliability : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0);
|
|
max_blocking_time : DURATION_TYPE;
|
|
transportnpriority : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
|
|
lifespan : DURATION_TYPE;
|
|
destination_order : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0);
|
|
-- Represent Data as Strings (Ease of Use)
|
|
user_data : STRING_WORD_ARRAY_TYPE;
|
|
topic_data : STRING_WORD_ARRAY_TYPE;
|
|
group_data : STRING_WORD_ARRAY_TYPE;
|
|
expectsInlineQoS : std_logic_vector(CDR_BOOLEAN_WIDTH-1 downto 0);
|
|
unicastLocatorList : LOCATOR_LIST_TYPE;
|
|
multicastLocatorList : LOCATOR_LIST_TYPE;
|
|
max_size_serialized : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
|
|
end record;
|
|
|
|
constant DEFAULT_ENDPOINT_DATA : ENDPOINT_DATA_TYPE; -- Deferred to Package Body
|
|
|
|
procedure gen_endpoint_data( ref : in ENDPOINT_DATA_TYPE; output : inout TEST_PACKET_TYPE);
|
|
|
|
procedure gen_rand_loc(RV : inout RandomPType; ret : out LOCATOR_TYPE);
|
|
function int(n : integer; width : natural) return std_logic_vector;
|
|
|
|
end package;
|
|
|
|
package body rtps_test_package is
|
|
|
|
-- *UTILITY FUNCTIONS*
|
|
procedure gen_rand_loc(RV : inout RandomPType; ret : out LOCATOR_TYPE) is
|
|
begin
|
|
ret := EMPTY_LOCATOR;
|
|
ret.kind := LOCATOR_KIND_UDPv4;
|
|
ret.portn(UDP_PORT_WIDTH-1 downto 0) := RV.RandSlv(UDP_PORT_WIDTH);
|
|
ret.addr(IPv4_ADDRESS_WIDTH-1 downto 0) := RV.RandSlv(IPv4_ADDRESS_WIDTH);
|
|
end procedure;
|
|
|
|
function int(n : integer; width : natural) return std_logic_vector is
|
|
begin
|
|
return std_logic_vector(to_signed(n, width));
|
|
end function;
|
|
|
|
-- *DEFERRED DEFINITIONS*
|
|
|
|
constant DEFAULT_GUIDPREFIX : GUIDPREFIX_TYPE := (0 => x"da27cc3c", 1 => x"687ddcde", 2 => x"88bce3d1");
|
|
|
|
constant DEFAULT_ENTITYID : std_logic_vector(ENTITYID_WIDTH-1 downto 0) := x"b9cbad8d";
|
|
|
|
constant EMPTY_LOCATOR : LOCATOR_TYPE := (
|
|
kind => LOCATOR_KIND_INVALID,
|
|
portn => (others => '0'),
|
|
addr => (others => '0')
|
|
);
|
|
|
|
constant EMPTY_LOCATOR_LIST : LOCATOR_LIST_TYPE := (
|
|
numLocators => (others => '0'),
|
|
locator => (others => EMPTY_LOCATOR)
|
|
);
|
|
|
|
constant DEFAULT_SEQUENCENUMBER_SET : SEQUENCENUMBER_SET_TYPE := (
|
|
base => FIRST_SEQUENCENUMBER,
|
|
numBits => (others => '0'),
|
|
bitmap => (others => '0')
|
|
);
|
|
|
|
constant DEFAULT_FRAGMENTNUMBER_SET : FRAGMENTNUMBER_SET_TYPE := (
|
|
base => int(1,CDR_LONG_WIDTH),
|
|
numBits => (others => '0'),
|
|
bitmap => (others => '0')
|
|
);
|
|
|
|
constant DEST_LOC : DEST_LOCATOR_LIST_TYPE := (
|
|
meta => (
|
|
numLocators => int(4,CDR_LONG_WIDTH),
|
|
locator => (
|
|
0 => (
|
|
kind => LOCATOR_KIND_UDPv4,
|
|
portn => (LOCATOR_PORT_WIDTH-1 downto UDP_PORT_WIDTH => '0') & META_IPv4_MULTICAST_PORT,
|
|
addr => (LOCATOR_ADDR_WIDTH-1 downto IPv4_ADDRESS_WIDTH => '0') & DEFAULT_IPv4_META_ADDRESS
|
|
),
|
|
1 => (
|
|
kind => LOCATOR_KIND_UDPv4,
|
|
portn => (LOCATOR_PORT_WIDTH-1 downto UDP_PORT_WIDTH => '0') & META_IPv4_UNICAST_PORT,
|
|
addr => (LOCATOR_ADDR_WIDTH-1 downto IPv4_ADDRESS_WIDTH => '0') & DEFAULT_IPv4_META_ADDRESS
|
|
),
|
|
2 => (
|
|
kind => LOCATOR_KIND_UDPv4,
|
|
portn => (LOCATOR_PORT_WIDTH-1 downto UDP_PORT_WIDTH => '0') & META_IPv4_MULTICAST_PORT,
|
|
addr => (LOCATOR_ADDR_WIDTH-1 downto IPv4_ADDRESS_WIDTH => '0') & DEFAULT_IPv4_ADDRESS
|
|
),
|
|
3 => (
|
|
kind => LOCATOR_KIND_UDPv4,
|
|
portn => (LOCATOR_PORT_WIDTH-1 downto UDP_PORT_WIDTH => '0') & META_IPv4_UNICAST_PORT,
|
|
addr => (LOCATOR_ADDR_WIDTH-1 downto IPv4_ADDRESS_WIDTH => '0') & DEFAULT_IPv4_ADDRESS
|
|
),
|
|
others => EMPTY_LOCATOR
|
|
)
|
|
),
|
|
user => (
|
|
numLocators => int(2,CDR_LONG_WIDTH),
|
|
locator => (
|
|
0 => (
|
|
kind => LOCATOR_KIND_UDPv4,
|
|
portn => (LOCATOR_PORT_WIDTH-1 downto UDP_PORT_WIDTH => '0') & USER_IPv4_MULTICAST_PORT,
|
|
addr => (LOCATOR_ADDR_WIDTH-1 downto IPv4_ADDRESS_WIDTH => '0') & DEFAULT_IPv4_ADDRESS
|
|
),
|
|
1 => (
|
|
kind => LOCATOR_KIND_UDPv4,
|
|
portn => (LOCATOR_PORT_WIDTH-1 downto UDP_PORT_WIDTH => '0') & USER_IPv4_UNICAST_PORT,
|
|
addr => (LOCATOR_ADDR_WIDTH-1 downto IPv4_ADDRESS_WIDTH => '0') & DEFAULT_IPv4_ADDRESS
|
|
),
|
|
others => EMPTY_LOCATOR
|
|
)
|
|
)
|
|
);
|
|
|
|
constant DEFAULT_UDP_HEADER : UDP_HEADER_TYPE := (
|
|
src => EMPTY_LOCATOR,
|
|
dest => EMPTY_LOCATOR
|
|
);
|
|
|
|
constant DEFAULT_RTPS_HEADER : RTPS_HEADER_TYPE := (
|
|
protocol => PROTOCOL_RTPS,
|
|
version => PROTOCOLVERSION_2_4,
|
|
vendorId => VENDORID_UNKNOWN,
|
|
guidPrefix => DEFAULT_GUIDPREFIX
|
|
);
|
|
|
|
constant DEFAULT_RTPS_SUBMESSAGE : RTPS_SUBMESSAGE_TYPE := (
|
|
submessageID => (others => '0'),
|
|
flags => (others => '0'),
|
|
submessageLength => (others => '1'),
|
|
readerId => ENTITYID_UNKNOWN,
|
|
writerId => ENTITYID_UNKNOWN,
|
|
readerSNState => DEFAULT_SEQUENCENUMBER_SET,
|
|
count => int(1,COUNT_WIDTH),
|
|
extraFlags => (others => '0'),
|
|
octetsToInlineQos => int(16, SUBMESSAGE_LENGTH_WIDTH),
|
|
writerSN => FIRST_SEQUENCENUMBER,
|
|
fragmentNumberState => DEFAULT_FRAGMENTNUMBER_SET,
|
|
data => (length => 0, data => (others => (others => '0'))),
|
|
fragmentStartingNumber => int(1,CDR_LONG_WIDTH),
|
|
fragmentsInSubmessage => int(1,CDR_SHORT_WIDTH),
|
|
fragmentSize => (others => '0'),
|
|
sampleSize => (others => '0'),
|
|
gapStart => FIRST_SEQUENCENUMBER,
|
|
gapList => DEFAULT_SEQUENCENUMBER_SET,
|
|
firstSN => FIRST_SEQUENCENUMBER,
|
|
lastSN => (others => (others => '0')),
|
|
lastFragmentNum => int(1,CDR_LONG_WIDTH),
|
|
guidPrefix => DEFAULT_GUIDPREFIX,
|
|
unicastLocatorList => EMPTY_LOCATOR_LIST,
|
|
multicastLocatorList => EMPTY_LOCATOR_LIST,
|
|
unicastLocator => EMPTY_LOCATOR,
|
|
multicastLocator => EMPTY_LOCATOR,
|
|
unused => (others => '0'),
|
|
version => PROTOCOLVERSION_2_4,
|
|
vendorId => VENDORID_UNKNOWN,
|
|
timestamp => TIME_ZERO
|
|
);
|
|
|
|
constant DEFAULT_PARTICIPANT_DATA : PARTICIPANT_DATA_TYPE := (
|
|
littleEndian => '0',
|
|
domainId => (others => '0'),
|
|
domainTag => (others => (others => '0')),
|
|
protocolVersion => PROTOCOLVERSION_2_4,
|
|
vendorId => VENDORID_UNKNOWN,
|
|
guidPrefix => GUIDPREFIX_UNKNOWN,
|
|
entityId => ENTITYID_PARTICIPANT,
|
|
expectsInlineQoS => (others => '0'),
|
|
metatrafficUnicastLocatorList => EMPTY_LOCATOR_LIST,
|
|
metatrafficMulticastLocatorList => EMPTY_LOCATOR_LIST,
|
|
defaultUnicastLocatorList => EMPTY_LOCATOR_LIST, -- NOTE: Has to be initialized
|
|
defaultMulticastLocatorList => EMPTY_LOCATOR_LIST,
|
|
leaseDuration => DEFAULT_PARTICIPANT_LEASE_DURATION,
|
|
manualLivelinessCount => (others => '0'),
|
|
builtinEndpointQoS => (others => '0'),
|
|
availableBuiltinEndpoints => (DISC_BUILTIN_ENDPOINT_PARTICIPANT_ANNOUNCER => '1', DISC_BUILTIN_ENDPOINT_PARTICIPANT_DETECTOR => '1', BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_WRITER => '1', BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_READER => '1', others => '0')
|
|
);
|
|
|
|
constant DEFAULT_ENDPOINT_DATA : ENDPOINT_DATA_TYPE := (
|
|
littleEndian => '0',
|
|
participant => DEFAULT_PARTICIPANT_DATA,
|
|
entityId => DEFAULT_ENTITYID,
|
|
topic_name => EMPTY_STRING,
|
|
type_name => EMPTY_STRING,
|
|
durability => DEFAULT_DURABILITY_QOS,
|
|
durability_service_cleanup_delay => DEFAULT_DURABILITY_SERVICE_CLEANUP_DELAY,
|
|
durability_service_history => DEFAULT_DURABILITY_SERVICE_HISTORY,
|
|
durability_service_history_depth => DEFAULT_DURABILITY_SERVICE_HISTORY_DEPTH,
|
|
durability_service_max_samples => DEFAULT_DURABILITY_SERVICE_MAX_SAMPLES,
|
|
durability_service_max_instances => DEFAULT_DURABILITY_SERVICE_MAX_INSTANCES,
|
|
durability_service_max_samples_per_instances => DEFAULT_DURABILITY_SERVICE_MAX_SAMPLES_PER_INSTANCE,
|
|
presentation => DEFAULT_PRESENTATION_QOS,
|
|
coherent_access => (0 => boolean_to_std_logic(DEFAULT_COHERENT_ACCESS), others => '0'),
|
|
ordered_access => (0 => boolean_to_std_logic(DEFAULT_ORDERED_ACCESS), others => '0'),
|
|
deadline => DEFAULT_DEADLINE_QOS,
|
|
latency_budget => DEFAULT_LATENCY_BUDGET_QOS,
|
|
ownership => DEFAULT_OWNERSHIP_QOS,
|
|
ownership_strength => DEFAULT_OWNERSHIP_STRENGTH_QOS,
|
|
liveliness => DEFAULT_LIVELINESS_QOS,
|
|
leaseDuration => DEFAULT_LEASE_DURATION,
|
|
time_based_filter => DEFAULT_TIME_BASED_FILTER_QOS,
|
|
reliability => DEFAULT_RELIABILTY_QOS,
|
|
max_blocking_time => DEFAULT_MAX_BLOCKING_TIME,
|
|
transportnpriority => DEFAULT_TRANSPORT_PRIORITY_QOS,
|
|
lifespan => DEFAULT_LIFESPAN_QOS,
|
|
destination_order => DEFAULT_DESTINATION_ORDER_QOS,
|
|
user_data => EMPTY_STRING,
|
|
topic_data => EMPTY_STRING,
|
|
group_data => EMPTY_STRING,
|
|
expectsInlineQoS => (others => '0'),
|
|
unicastLocatorList => EMPTY_LOCATOR_LIST,
|
|
multicastLocatorList => EMPTY_LOCATOR_LIST,
|
|
max_size_serialized => (others => '0')
|
|
);
|
|
|
|
-- *PACKAGE INTERNAL HELPER FUNCTIONS*
|
|
|
|
procedure store_byte(in_off : in natural range 0 to 3; input : in std_logic_vector(WORD_WIDTH-1 downto 0); out_off : in natural range 0 to 3; output : inout TEST_PACKET_TYPE) is
|
|
begin
|
|
output.data(output.length)((BYTE_WIDTH*out_off)+BYTE_WIDTH-1 downto (BYTE_WIDTH*out_off)) := input((BYTE_WIDTH*in_off)+BYTE_WIDTH-1 downto (BYTE_WIDTH*in_off));
|
|
end procedure;
|
|
|
|
procedure gen_udp_header(ref : in UDP_HEADER_TYPE; output : inout TEST_PACKET_TYPE) is
|
|
begin
|
|
-- IPv4 Source Address
|
|
output.data(output.length) := ref.src.addr(IPv4_ADDRESS_WIDTH-1 downto 0);
|
|
output.length := output.length + 1;
|
|
-- IPv4 Destination Address
|
|
output.data(output.length) := ref.dest.addr(IPv4_ADDRESS_WIDTH-1 downto 0);
|
|
output.length := output.length + 1;
|
|
-- Packet Length
|
|
output.data(output.length) := (others => '0');
|
|
output.length := output.length + 1;
|
|
-- Source Port & Destination Port
|
|
output.data(output.length) := ref.src.portn(UDP_PORT_WIDTH-1 downto 0) & ref.dest.portn(UDP_PORT_WIDTH-1 downto 0);
|
|
output.length := output.length + 1;
|
|
-- Length & Checksum
|
|
output.data(output.length) := (others => '0');
|
|
output.length := output.length + 1;
|
|
end procedure;
|
|
|
|
procedure fix_udp_packet(output : inout TEST_PACKET_TYPE) is
|
|
begin
|
|
assert (output.length < 2**UDP_PORT_WIDTH) report "Exceeded maximum UDP Packet Size" severity error;
|
|
-- Fix Packet Length
|
|
output.data(2) := int(output.length-3, WORD_WIDTH);
|
|
-- Fix UDP Length
|
|
output.data(4)(31 downto 16) := int((output.length-3)*4, UDP_HEADER_LENGTH_WIDTH);
|
|
-- TODO: Calculate Checksum
|
|
end procedure;
|
|
|
|
procedure gen_rtps_header( ref : in RTPS_HEADER_TYPE; output : inout TEST_PACKET_TYPE) is
|
|
begin
|
|
-- Protocol
|
|
output.data(output.length) := ref.protocol;
|
|
output.length := output.length + 1;
|
|
-- Protocol Version & Vendor ID
|
|
output.data(output.length) := ref.version & ref.vendorId;
|
|
output.length := output.length + 1;
|
|
-- GUID Prefix
|
|
output.data(output.length) := ref.guidPrefix(0);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.guidPrefix(1);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.guidPrefix(2);
|
|
output.length := output.length + 1;
|
|
end procedure;
|
|
|
|
procedure write_sequence_ns(input : in SEQUENCENUMBER_SET_TYPE; littleEndian : in std_logic; output : inout TEST_PACKET_TYPE) is
|
|
begin
|
|
-- Sequence Number State (Base)
|
|
output.data(output.length) := endian_swap(littleEndian, std_logic_vector(input.base(0)));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(littleEndian, std_logic_vector(input.base(1)));
|
|
output.length := output.length + 1;
|
|
-- Sequence Number State (NumBits)
|
|
assert (unsigned(input.numBits) <= 256) report "SequenceNS.numbits is higher than 256." severity warning;
|
|
output.data(output.length) := endian_swap(littleEndian, input.numBits);
|
|
output.length := output.length + 1;
|
|
-- Sequence Number State (Bitmap)
|
|
for i in 0 to round_div(to_integer(unsigned(input.numBits)),WORD_WIDTH)-1 loop
|
|
if (i < MAX_BITMAP_WIDTH/WORD_WIDTH) then
|
|
output.data(output.length) := endian_swap(littleEndian, input.bitmap(i*32 to i*32+31));
|
|
output.length := output.length + 1;
|
|
end if;
|
|
end loop;
|
|
end procedure;
|
|
|
|
procedure write_fragment_ns(input : in FRAGMENTNUMBER_SET_TYPE; littleEndian : in std_logic; output : inout TEST_PACKET_TYPE) is
|
|
begin
|
|
-- Sequence Number State (Base)
|
|
output.data(output.length) := endian_swap(littleEndian, input.base);
|
|
output.length := output.length + 1;
|
|
-- Sequence Number State (NumBits)
|
|
assert (unsigned(input.numBits) <= 256) report "SequenceNS.numbits is higher than 256." severity warning;
|
|
output.data(output.length) := endian_swap(littleEndian, input.numBits);
|
|
output.length := output.length + 1;
|
|
-- Sequence Number State (Bitmap)
|
|
for i in 0 to round_div(to_integer(unsigned(input.numBits)),WORD_WIDTH)-1 loop
|
|
if (i < MAX_BITMAP_WIDTH/WORD_WIDTH) then
|
|
output.data(output.length) := endian_swap(littleEndian, input.bitmap(i*32 to i*32+31));
|
|
output.length := output.length + 1;
|
|
end if;
|
|
end loop;
|
|
end procedure;
|
|
|
|
procedure write_locator_list(input : in LOCATOR_LIST_TYPE; littleEndian : in std_logic; output : inout TEST_PACKET_TYPE) is
|
|
begin
|
|
-- NumLocators
|
|
output.data(output.length) := endian_swap(littleEndian, input.numLocators);
|
|
output.length := output.length + 1;
|
|
for i in 0 to to_integer(unsigned(input.numLocators))-1 loop
|
|
-- Kind
|
|
output.data(output.length) := endian_swap(littleEndian, input.locator(i).kind);
|
|
output.length := output.length + 1;
|
|
-- Port
|
|
output.data(output.length) := endian_swap(littleEndian, input.locator(i).portn);
|
|
output.length := output.length + 1;
|
|
-- Address
|
|
output.data(output.length) := input.locator(i).addr(127 downto 96);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := input.locator(i).addr(95 downto 64);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := input.locator(i).addr(63 downto 32);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := input.locator(i).addr(31 downto 0);
|
|
output.length := output.length + 1;
|
|
end loop;
|
|
end procedure;
|
|
|
|
procedure gen_rtps_submessage( ref : in RTPS_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE) is
|
|
variable start : natural := 0;
|
|
variable tmp : natural := 0;
|
|
begin
|
|
-- *GENERAL*
|
|
start := output.length;
|
|
-- Submessage ID & Submessage Flags & Submessage Length
|
|
output.data(output.length) := ref.submessageID & ref.flags & endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.submessageLength);
|
|
output.length := output.length + 1;
|
|
|
|
-- *DATA/DATA_FRAG*
|
|
if (ref.submessageID = SID_DATA or ref.submessageID = SID_DATA_FRAG) then
|
|
-- Extra Flags & octetsToInlineQos
|
|
output.data(output.length) := ref.extraFlags & endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.octetsToInlineQos);
|
|
output.length := output.length + 1;
|
|
end if;
|
|
|
|
-- *ACKNACK/NACK_FRAG/HEARTBEAT/HEARTBEAT_FRAG/GAP/DATA/DATA_FRAG*
|
|
if (ref.submessageID = SID_ACKNACK or ref.submessageID = SID_NACK_FRAG or ref.submessageID = SID_HEARTBEAT or ref.submessageID = SID_HEARTBEAT_FRAG or ref.submessageID = SID_GAP or ref.submessageID = SID_DATA or ref.submessageID = SID_DATA_FRAG) then
|
|
-- Reader ID
|
|
output.data(output.length) := ref.readerId;
|
|
output.length := output.length + 1;
|
|
-- Writer ID
|
|
output.data(output.length) := ref.writerId;
|
|
output.length := output.length + 1;
|
|
end if;
|
|
|
|
-- *NACK_FRAG/DATA/DATA_FRAG/HEARTBEAT_FRAG*
|
|
if (ref.submessageID = SID_NACK_FRAG or ref.submessageID = SID_DATA or ref.submessageID = SID_DATA_FRAG or ref.submessageID = SID_HEARTBEAT_FRAG) then
|
|
output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.writerSN(0)));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.writerSN(1)));
|
|
output.length := output.length + 1;
|
|
end if;
|
|
|
|
-- *ACKNACK*
|
|
if (ref.submessageID = SID_ACKNACK) then
|
|
-- Reader State
|
|
write_sequence_ns(ref.readerSNState, ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), output);
|
|
-- *NACK_FRAG*
|
|
elsif (ref.submessageID = SID_NACK_FRAG) then
|
|
-- Fragment Number State
|
|
write_fragment_ns(ref.fragmentNumberState, ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), output);
|
|
-- *HEARTBEAT*
|
|
elsif (ref.submessageID = SID_HEARTBEAT) then
|
|
-- First Sequence Number
|
|
output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.firstSN(0)));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.firstSN(1)));
|
|
output.length := output.length + 1;
|
|
-- Last Sequence Number
|
|
output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.lastSN(0)));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.lastSN(1)));
|
|
output.length := output.length + 1;
|
|
-- *HEARTBEAT_FRAG*
|
|
elsif (ref.submessageID = SID_HEARTBEAT_FRAG) then
|
|
-- Last Fargment Number
|
|
output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.lastFragmentNum);
|
|
output.length := output.length + 1;
|
|
end if;
|
|
|
|
-- *ACKNACK/NACK_FRAG/HEARTBEAT/HEARTBEAT_FRAG*
|
|
if (ref.submessageID = SID_ACKNACK or ref.submessageID = SID_HEARTBEAT or ref.submessageID = SID_NACK_FRAG or ref.submessageID = SID_HEARTBEAT_FRAG) then
|
|
output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.count);
|
|
output.length := output.length + 1;
|
|
end if;
|
|
|
|
-- *GAP*
|
|
if (ref.submessageID = SID_GAP) then
|
|
-- Gap Start
|
|
output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.gapStart(0)));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.gapStart(1)));
|
|
output.length := output.length + 1;
|
|
-- Gap List
|
|
write_sequence_ns(ref.gapList, ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), output);
|
|
end if;
|
|
|
|
-- *DATA_FRAG*
|
|
if (ref.submessageID = SID_DATA_FRAG) then
|
|
-- Fragment Number
|
|
output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.fragmentStartingNumber);
|
|
output.length := output.length + 1;
|
|
-- FragmentsinSubmessage & FragmentSize
|
|
output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.fragmentsInSubmessage) & endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.fragmentSize);
|
|
output.length := output.length + 1;
|
|
-- Sample Size
|
|
output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.sampleSize);
|
|
output.length := output.length + 1;
|
|
end if;
|
|
|
|
-- *DATA/DATA_FRAG*
|
|
if (ref.submessageID = SID_DATA or ref.submessageID = SID_DATA_FRAG) then
|
|
-- EXTRA HEADER
|
|
tmp := to_integer(unsigned(ref.octetsToInlineQos)) - 16;
|
|
if (tmp > 0) then
|
|
for i in 0 to tmp-1 loop
|
|
store_byte((i+1) mod 4, x"DEADBEEF", (i+1) mod 4, output);
|
|
if (i mod 4 = 3) then
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := (others => '0');
|
|
end if;
|
|
end loop;
|
|
end if;
|
|
-- DATA
|
|
if (ref.data.length > 0) then
|
|
for i in 0 to (ref.data.length*4)-1 loop
|
|
store_byte((i+tmp) mod 4, ref.data.data(i/4), i mod 4, output);
|
|
if ((i+tmp) mod 4 = 3) then
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := (others => '0');
|
|
end if;
|
|
end loop;
|
|
end if;
|
|
-- Fix Alignement
|
|
if ((tmp + (ref.data.length*4)) mod 4 /= 0) then
|
|
output.length := output.length + 1;
|
|
end if;
|
|
end if;
|
|
|
|
-- *INFO_SRC*
|
|
if (ref.submessageID = SID_INFO_SRC) then
|
|
-- UNUSED
|
|
output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.unused);
|
|
output.length := output.length + 1;
|
|
-- Protocol Version & Vendor ID
|
|
output.data(output.length) := ref.version & ref.vendorId;
|
|
output.length := output.length + 1;
|
|
-- *INFO_REPLY*
|
|
elsif (ref.submessageID = SID_INFO_REPLY) then
|
|
write_locator_list(ref.unicastLocatorList, ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), output);
|
|
if (ref.flags(SUBMESSAGE_MULTICAST_FLAG_POS) = '1') then
|
|
write_locator_list(ref.multicastLocatorList, ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), output);
|
|
end if;
|
|
-- *INFO_REPLY_IP4*
|
|
elsif (ref.submessageID = SID_INFO_REPLY_IP4) then
|
|
-- Unicast Locator (Address)
|
|
output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.unicastLocator.addr(CDR_LONG_WIDTH-1 downto 0));
|
|
output.length := output.length + 1;
|
|
-- Unicast Locator (Port)
|
|
output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.unicastLocator.portn);
|
|
output.length := output.length + 1;
|
|
if (ref.flags(SUBMESSAGE_MULTICAST_FLAG_POS) = '1') then
|
|
-- Multicast Locator (Address)
|
|
output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.multicastLocator.addr(CDR_LONG_WIDTH-1 downto 0));
|
|
output.length := output.length + 1;
|
|
-- Multicast Locator (Port)
|
|
output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.multicastLocator.portn);
|
|
output.length := output.length + 1;
|
|
end if;
|
|
-- *INFO_TS*
|
|
elsif (ref.submessageID = SID_INFO_TS) then
|
|
-- Timestamp
|
|
if (ref.flags(SUBMESSAGE_INVALIDATE_FLAG_POS) = '0') then
|
|
output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.timestamp(0)));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.timestamp(1)));
|
|
output.length := output.length + 1;
|
|
end if;
|
|
end if;
|
|
|
|
-- *INFO_DEST/INFO_SRC*
|
|
if (ref.submessageID = SID_INFO_DST or ref.submessageID = SID_INFO_SRC) then
|
|
-- GUID Prefix
|
|
output.data(output.length) := ref.guidPrefix(0);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.guidPrefix(1);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.guidPrefix(2);
|
|
output.length := output.length + 1;
|
|
end if;
|
|
|
|
-- *ACKNACK/NACK_FRAG/HEARTBEAT/HEARTBEAT_FRAG/GAP/DATA/DATA_FRAG*
|
|
if (ref.submessageID = SID_ACKNACK or ref.submessageID = SID_NACK_FRAG or ref.submessageID = SID_HEARTBEAT or ref.submessageID = SID_HEARTBEAT_FRAG or ref.submessageID = SID_GAP or ref.submessageID = SID_DATA or ref.submessageID = SID_DATA_FRAG or ref.submessageID = SID_INFO_TS or ref.submessageID = SID_INFO_SRC or ref.submessageID = SID_INFO_DST or ref.submessageID = SID_INFO_REPLY or ref.submessageID =SID_INFO_REPLY_IP4) then
|
|
-- Fix Submessage Length
|
|
if (ref.submessageLength = (ref.submessageLength'range => '1')) then
|
|
output.data(start)(SUBMESSAGE_LENGTH_WIDTH-1 downto 0) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), int((output.length-start-1)*4,SUBMESSAGE_LENGTH_WIDTH));
|
|
-- Fix Packet Length
|
|
else
|
|
output.length := start + to_integer(unsigned(ref.submessageLength));
|
|
end if;
|
|
-- *PAD/UKNOWN*
|
|
else
|
|
-- Padding
|
|
tmp := to_integer(unsigned(ref.submessageLength));
|
|
assert (tmp mod 4 = 0) report "Padding Length has to be multiple of four" severity FAILURE;
|
|
for i in 0 to (tmp/4)-1 loop
|
|
output.data(output.length) := (others => '0');
|
|
output.length := output.length + 1;
|
|
end loop;
|
|
end if;
|
|
end procedure;
|
|
|
|
procedure gen_rtps_handler_out(ref : in RTPS_SUBMESSAGE_TYPE; loc : in LOCATOR_TYPE; is_meta : in boolean; ts : in TIME_TYPE; src_guid : in GUIDPREFIX_TYPE; output : inout TEST_PACKET_TYPE) is
|
|
begin
|
|
-- Opcode & Flags & Source Port
|
|
output.data(output.length) := ref.submessageID & ref.flags & loc.portn(UDP_PORT_WIDTH-1 downto 0);
|
|
output.length := output.length + 1;
|
|
-- Source Address
|
|
output.data(output.length) := loc.addr(IPv4_ADDRESS_WIDTH-1 downto 0);
|
|
output.length := output.length + 1;
|
|
-- Source Entity ID
|
|
if (ref.submessageID = SID_ACKNACK or ref.submessageID = SID_NACK_FRAG) then
|
|
output.data(output.length) := ref.readerId;
|
|
output.length := output.length + 1;
|
|
else
|
|
output.data(output.length) := ref.writerId;
|
|
output.length := output.length + 1;
|
|
end if;
|
|
-- Source GUID Prefix
|
|
output.data(output.length) := src_guid(0);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := src_guid(1);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := src_guid(2);
|
|
output.length := output.length + 1;
|
|
-- Destination Enity ID
|
|
if (is_meta) then
|
|
if (ref.submessageID = SID_ACKNACK or ref.submessageID = SID_NACK_FRAG) then
|
|
output.data(output.length) := ref.writerId;
|
|
output.length := output.length + 1;
|
|
else
|
|
output.data(output.length) := ref.readerId;
|
|
output.length := output.length + 1;
|
|
end if;
|
|
end if;
|
|
|
|
-- *DATA*
|
|
if (ref.submessageID = SID_DATA) then
|
|
-- Sequence Number
|
|
output.data(output.length) := std_logic_vector(ref.writerSN(0));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := std_logic_vector(ref.writerSN(1));
|
|
output.length := output.length + 1;
|
|
-- Timestamp
|
|
if (not is_meta) then
|
|
output.data(output.length) := std_logic_vector(ts(0));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := std_logic_vector(ts(1));
|
|
output.length := output.length + 1;
|
|
end if;
|
|
-- DATA PAYLOAD
|
|
if (ref.data.length > 0) then
|
|
for i in 0 to ref.data.length-1 loop
|
|
output.data(output.length) := ref.data.data(i);
|
|
output.length := output.length + 1;
|
|
end loop;
|
|
end if;
|
|
end if;
|
|
|
|
-- *ACKNACK*
|
|
if (ref.submessageID = SID_ACKNACK) then
|
|
-- Reader State
|
|
write_sequence_ns(ref.readerSNState, '0', output);
|
|
-- *HEARTBEAT*
|
|
elsif (ref.submessageID = SID_HEARTBEAT) then
|
|
-- First Sequence Number
|
|
output.data(output.length) := std_logic_vector(ref.firstSN(0));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := std_logic_vector(ref.firstSN(1));
|
|
output.length := output.length + 1;
|
|
-- Last Sequence Number
|
|
output.data(output.length) := std_logic_vector(ref.lastSN(0));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := std_logic_vector(ref.lastSN(1));
|
|
output.length := output.length + 1;
|
|
end if;
|
|
|
|
-- *ACKNACK/HEARTBEAT*
|
|
if (ref.submessageID = SID_ACKNACK or ref.submessageID = SID_HEARTBEAT) then
|
|
output.data(output.length) := ref.count;
|
|
output.length := output.length + 1;
|
|
end if;
|
|
|
|
-- *GAP*
|
|
if (ref.submessageID = SID_GAP) then
|
|
-- Gap Start
|
|
output.data(output.length) := std_logic_vector(ref.gapStart(0));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := std_logic_vector(ref.gapStart(1));
|
|
output.length := output.length + 1;
|
|
-- Gap List
|
|
write_sequence_ns(ref.gapList, '0', output);
|
|
end if;
|
|
end procedure;
|
|
|
|
procedure gen_participant_announcement( ref : in PARTICIPANT_DATA_TYPE; output : inout TEST_PACKET_TYPE) is
|
|
variable tmp : natural := 0;
|
|
begin
|
|
-- Representation Identifier & Representation Options
|
|
if (ref.littleEndian = '0') then
|
|
output.data(output.length) := PL_CDR_BE & x"0000";
|
|
else
|
|
output.data(output.length) := PL_CDR_LE & x"0000";
|
|
end if;
|
|
output.length := output.length + 1;
|
|
-- GUID
|
|
output.data(output.length) := PID_PARTICIPANT_GUID & endian_swap(ref.littleEndian, int(16, PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.guidPrefix(0);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.guidPrefix(1);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.guidPrefix(2);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.entityId;
|
|
output.length := output.length + 1;
|
|
-- DOMAIN ID
|
|
output.data(output.length) := PID_DOMAIN_ID & endian_swap(ref.littleEndian, int(4, PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.domainId);
|
|
output.length := output.length + 1;
|
|
-- DOMAIN TAG
|
|
if (ref.domainTag /= EMPTY_STRING) then
|
|
tmp := string_len(ref.domainTag);
|
|
output.data(output.length) := PID_DOMAIN_TAG & endian_swap(ref.littleEndian, int((round_div(tmp,4)+1)*4, PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, int(tmp, CDR_LONG_WIDTH));
|
|
output.length := output.length + 1;
|
|
for i in 0 to round_div(tmp,4)-1 loop
|
|
output.data(output.length) := ref.domainTag(i);
|
|
output.length := output.length + 1;
|
|
end loop;
|
|
end if;
|
|
-- PROTOCOL VERSION
|
|
output.data(output.length) := PID_PROTOCOL_VERSION & endian_swap(ref.littleEndian, int(4, PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := (others => '0');
|
|
output.data(output.length)(31 downto 16) := ref.protocolVersion;
|
|
output.length := output.length + 1;
|
|
-- VENDORID
|
|
output.data(output.length) := PID_VENDORID & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := (others => '0');
|
|
output.data(output.length)(31 downto 16) := ref.vendorId;
|
|
output.length := output.length + 1;
|
|
-- EXPECTS IN-LINE QOS
|
|
if (ref.expectsInlineQoS(0) /= '0') then
|
|
output.data(output.length) := PID_EXPECTS_INLINE_QOS & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := (others => '0');
|
|
output.data(output.length)(31 downto 24) := ref.expectsInlineQoS; -- 1 Byte, No endian swap
|
|
output.length := output.length + 1;
|
|
end if;
|
|
-- METATRAFFIC UNICAST LOCATOR
|
|
if (ref.metatrafficUnicastLocatorList.numLocators /= (ref.metatrafficUnicastLocatorList.numLocators'range => '0')) then
|
|
tmp := to_integer(unsigned(ref.metatrafficUnicastLocatorList.numLocators));
|
|
output.data(output.length) := PID_METATRAFFIC_UNICAST_LOCATOR & endian_swap(ref.littleEndian, int(((tmp*6)+1)*4,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.metatrafficUnicastLocatorList.numLocators);
|
|
output.length := output.length + 1;
|
|
for i in 0 to tmp-1 loop
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.metatrafficUnicastLocatorList.locator(i).kind);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.metatrafficUnicastLocatorList.locator(i).portn);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.metatrafficUnicastLocatorList.locator(i).addr(127 downto 96);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.metatrafficUnicastLocatorList.locator(i).addr(95 downto 64);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.metatrafficUnicastLocatorList.locator(i).addr(63 downto 32);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.metatrafficUnicastLocatorList.locator(i).addr(31 downto 0);
|
|
output.length := output.length + 1;
|
|
end loop;
|
|
end if;
|
|
-- METATRAFFIC MULTICAST LOCATOR
|
|
if (ref.metatrafficMulticastLocatorList.numLocators /= (ref.metatrafficMulticastLocatorList.numLocators'range => '0')) then
|
|
tmp := to_integer(unsigned(ref.metatrafficMulticastLocatorList.numLocators));
|
|
output.data(output.length) := PID_METATRAFFIC_MULTICAST_LOCATOR & endian_swap(ref.littleEndian, int(((tmp*6)+1)*4,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.metatrafficMulticastLocatorList.numLocators);
|
|
output.length := output.length + 1;
|
|
for i in 0 to tmp-1 loop
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.metatrafficMulticastLocatorList.locator(i).kind);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.metatrafficMulticastLocatorList.locator(i).portn);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.metatrafficMulticastLocatorList.locator(i).addr(127 downto 96);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.metatrafficMulticastLocatorList.locator(i).addr(95 downto 64);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.metatrafficMulticastLocatorList.locator(i).addr(63 downto 32);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.metatrafficMulticastLocatorList.locator(i).addr(31 downto 0);
|
|
output.length := output.length + 1;
|
|
end loop;
|
|
end if;
|
|
-- DEFAULT UNICAST LOCATOR
|
|
assert (unsigned(ref.defaultUnicastLocatorList.numLocators) > 0) report "PARTICIPANT_DATA: Participant needs to have at least one Default Unicast Locator." severity error;
|
|
if (ref.defaultUnicastLocatorList.numLocators /= (ref.defaultUnicastLocatorList.numLocators'range => '0')) then
|
|
tmp := to_integer(unsigned(ref.defaultUnicastLocatorList.numLocators));
|
|
output.data(output.length) := PID_METATRAFFIC_MULTICAST_LOCATOR & endian_swap(ref.littleEndian, int(((tmp*6)+1)*4,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.defaultUnicastLocatorList.numLocators);
|
|
output.length := output.length + 1;
|
|
for i in 0 to tmp-1 loop
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.defaultUnicastLocatorList.locator(i).kind);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.defaultUnicastLocatorList.locator(i).portn);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.defaultUnicastLocatorList.locator(i).addr(127 downto 96);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.defaultUnicastLocatorList.locator(i).addr(95 downto 64);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.defaultUnicastLocatorList.locator(i).addr(63 downto 32);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.defaultUnicastLocatorList.locator(i).addr(31 downto 0);
|
|
output.length := output.length + 1;
|
|
end loop;
|
|
end if;
|
|
-- DEFAULT MULTICAST LOCATOR
|
|
if (ref.defaultMulticastLocatorList.numLocators /= (ref.defaultMulticastLocatorList.numLocators'range => '0')) then
|
|
tmp := to_integer(unsigned(ref.defaultMulticastLocatorList.numLocators));
|
|
output.data(output.length) := PID_METATRAFFIC_MULTICAST_LOCATOR & endian_swap(ref.littleEndian, int(((tmp*6)+1)*4,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.defaultMulticastLocatorList.numLocators);
|
|
output.length := output.length + 1;
|
|
for i in 0 to tmp-1 loop
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.defaultMulticastLocatorList.locator(i).kind);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.defaultMulticastLocatorList.locator(i).portn);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.defaultMulticastLocatorList.locator(i).addr(127 downto 96);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.defaultMulticastLocatorList.locator(i).addr(95 downto 64);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.defaultMulticastLocatorList.locator(i).addr(63 downto 32);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.defaultMulticastLocatorList.locator(i).addr(31 downto 0);
|
|
output.length := output.length + 1;
|
|
end loop;
|
|
end if;
|
|
-- LEASE DURATION
|
|
if (ref.leaseDuration /= DEFAULT_PARTICIPANT_LEASE_DURATION) then
|
|
output.data(output.length) := PID_PARTICIPANT_LEASE_DURATION & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.leaseDuration(0)));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.leaseDuration(1)));
|
|
output.length := output.length + 1;
|
|
end if;
|
|
-- AVAILABLE ENDPOINTS
|
|
output.data(output.length) := PID_BUILTIN_ENDPOINT_SET & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.availableBuiltinEndpoints);
|
|
output.length := output.length + 1;
|
|
-- MANUAL LIVELINESS COUNT
|
|
output.data(output.length) := PID_PARTICIPANT_MANUAL_LIVELINESS_COUNT & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.manualLivelinessCount);
|
|
output.length := output.length + 1;
|
|
end procedure;
|
|
|
|
procedure gen_endpoint_data( ref : in ENDPOINT_DATA_TYPE; output : inout TEST_PACKET_TYPE) is
|
|
variable tmp : natural := 0;
|
|
begin
|
|
-- GUID
|
|
output.data(output.length) := PID_ENDPOINT_GUID & endian_swap(ref.littleEndian, int(16,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.participant.guidPrefix(0);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.participant.guidPrefix(1);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.participant.guidPrefix(2);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.entityId;
|
|
output.length := output.length + 1;
|
|
-- EXPECTS IN-LINE QOS
|
|
if (ref.expectsInlineQoS(0) /= '0') then
|
|
output.data(output.length) := PID_EXPECTS_INLINE_QOS & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := (others => '0');
|
|
output.data(output.length)(31 downto 24) := ref.expectsInlineQoS; -- 1 Byte, No endian swap
|
|
output.length := output.length + 1;
|
|
end if;
|
|
-- TOPIC NAME
|
|
tmp := string_len(ref.topic_name);
|
|
output.data(output.length) := PID_TOPIC_NAME & endian_swap(ref.littleEndian, int((round_div(tmp,4)+1)*4,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, int(tmp, CDR_LONG_WIDTH));
|
|
output.length := output.length + 1;
|
|
for i in 0 to round_div(tmp,4)-1 loop
|
|
output.data(output.length) := ref.topic_name(i);
|
|
output.length := output.length + 1;
|
|
end loop;
|
|
-- TYPE NAME
|
|
tmp := string_len(ref.type_name);
|
|
output.data(output.length) := PID_TOPIC_NAME & endian_swap(ref.littleEndian, int((round_div(tmp,4)+1)*4,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, int(tmp,CDR_LONG_WIDTH));
|
|
output.length := output.length + 1;
|
|
for i in 0 to round_div(tmp,4)-1 loop
|
|
output.data(output.length) := ref.type_name(i);
|
|
output.length := output.length + 1;
|
|
end loop;
|
|
-- DURABILITY
|
|
if (ref.durability /= DEFAULT_DURABILITY_QOS) then
|
|
output.data(output.length) := PID_DURABILITY & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.durability);
|
|
output.length := output.length + 1;
|
|
end if;
|
|
-- DURABILITY SERVICE
|
|
if (ref.durability_service_cleanup_delay /= DEFAULT_DURABILITY_SERVICE_CLEANUP_DELAY or ref.durability_service_history /= DEFAULT_DURABILITY_SERVICE_HISTORY or
|
|
ref.durability_service_history_depth /= DEFAULT_DURABILITY_SERVICE_HISTORY_DEPTH or ref.durability_service_max_samples /= DEFAULT_DURABILITY_SERVICE_MAX_SAMPLES or
|
|
ref.durability_service_max_instances /= DEFAULT_DURABILITY_SERVICE_MAX_INSTANCES or ref.durability_service_max_samples_per_instances /= DEFAULT_DURABILITY_SERVICE_MAX_SAMPLES_PER_INSTANCE) then
|
|
|
|
output.data(output.length) := PID_DURABILITY_SERVICE & endian_swap(ref.littleEndian, int(28,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.durability_service_cleanup_delay(0)));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.durability_service_cleanup_delay(1)));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.durability_service_history);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.durability_service_history_depth);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.durability_service_max_samples);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.durability_service_max_instances);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.durability_service_max_samples_per_instances);
|
|
output.length := output.length + 1;
|
|
end if;
|
|
-- PRESENTATION
|
|
if (ref.presentation /= DEFAULT_PRESENTATION_QOS or ref.coherent_access(0) /= boolean_to_std_logic(DEFAULT_COHERENT_ACCESS) or ref.ordered_access(0) /= boolean_to_std_logic(DEFAULT_ORDERED_ACCESS)) then
|
|
output.data(output.length) := PID_PRESENTATION & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.presentation);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.coherent_access) & endian_swap(ref.littleEndian, ref.ordered_access);
|
|
output.length := output.length + 1;
|
|
end if;
|
|
-- DEADLINE
|
|
if (ref.deadline /= DEFAULT_DEADLINE_QOS) then
|
|
output.data(output.length) := PID_DEADLINE & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.deadline(0)));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.deadline(1)));
|
|
output.length := output.length + 1;
|
|
end if;
|
|
-- LATENCY BUDGET
|
|
if (ref.latency_budget /= DEFAULT_LATENCY_BUDGET_QOS) then
|
|
output.data(output.length) := PID_LATENCY_BUDGET & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.deadline(0)));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.deadline(1)));
|
|
output.length := output.length + 1;
|
|
end if;
|
|
-- OWNERSHIP
|
|
if (ref.ownership /= DEFAULT_OWNERSHIP_QOS) then
|
|
output.data(output.length) := PID_OWNERSHIP & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.ownership);
|
|
output.length := output.length + 1;
|
|
end if;
|
|
-- OWNERSHIP STRENGTH
|
|
if (ref.ownership /= DEFAULT_OWNERSHIP_STRENGTH_QOS) then
|
|
output.data(output.length) := PID_OWNERSHIP_STRENGTH & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.ownership_strength);
|
|
output.length := output.length + 1;
|
|
end if;
|
|
-- LIVELINESS
|
|
if (ref.liveliness /= DEFAULT_LIVELINESS_QOS or ref.leaseDuration /= DEFAULT_LEASE_DURATION) then
|
|
output.data(output.length) := PID_LIVELINESS & endian_swap(ref.littleEndian, int(12,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.liveliness);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.leaseDuration(0)));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.leaseDuration(1)));
|
|
output.length := output.length + 1;
|
|
end if;
|
|
-- TIME BASED FILTER
|
|
if (ref.time_based_filter /= DEFAULT_TIME_BASED_FILTER_QOS) then
|
|
output.data(output.length) := PID_TIME_BASED_FILTER & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.time_based_filter(0)));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.time_based_filter(1)));
|
|
output.length := output.length + 1;
|
|
end if;
|
|
-- RELIABILITY
|
|
if (ref.reliability /= DEFAULT_RELIABILTY_QOS or ref.max_blocking_time /= DEFAULT_MAX_BLOCKING_TIME) then
|
|
output.data(output.length) := PID_RELIABILITY & endian_swap(ref.littleEndian, int(12,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.reliability);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.max_blocking_time(0)));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.max_blocking_time(1)));
|
|
output.length := output.length + 1;
|
|
end if;
|
|
-- TRANSPORT PRIORITY
|
|
if (ref.transportnpriority /= DEFAULT_TRANSPORT_PRIORITY_QOS) then
|
|
output.data(output.length) := PID_TRANSPORT_PRIORITY & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.transportnpriority);
|
|
output.length := output.length + 1;
|
|
end if;
|
|
-- LIFESPAN
|
|
if (ref.lifespan /= DEFAULT_LIFESPAN_QOS) then
|
|
output.data(output.length) := PID_LIFESPAN & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.lifespan(0)));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.lifespan(1)));
|
|
output.length := output.length + 1;
|
|
end if;
|
|
-- DESTINATION ORDER
|
|
if (ref.destination_order /= DEFAULT_DESTINATION_ORDER_QOS) then
|
|
output.data(output.length) := PID_DESTINATION_ORDER & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.destination_order);
|
|
output.length := output.length + 1;
|
|
end if;
|
|
-- UNICAST LOCATORS
|
|
if (unsigned(ref.unicastLocatorList.numLocators) > 0) then
|
|
tmp := to_integer(unsigned(ref.unicastLocatorList.numLocators));
|
|
for i in 0 to tmp-1 loop
|
|
output.data(output.length) := PID_UNICAST_LOCATOR & endian_swap(ref.littleEndian, int(24,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.unicastLocatorList.locator(i).kind);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.unicastLocatorList.locator(i).portn);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.unicastLocatorList.locator(i).addr(127 downto 96);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.unicastLocatorList.locator(i).addr(95 downto 64);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.unicastLocatorList.locator(i).addr(63 downto 32);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.unicastLocatorList.locator(i).addr(31 downto 0);
|
|
output.length := output.length + 1;
|
|
end loop;
|
|
end if;
|
|
-- MULTICAST LOCATORS
|
|
if (unsigned(ref.multicastLocatorList.numLocators) > 0) then
|
|
tmp := to_integer(unsigned(ref.multicastLocatorList.numLocators));
|
|
for i in 0 to tmp-1 loop
|
|
output.data(output.length) := PID_MULTICAST_LOCATOR & endian_swap(ref.littleEndian, int(24,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.multicastLocatorList.locator(i).kind);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.multicastLocatorList.locator(i).portn);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.multicastLocatorList.locator(i).addr(127 downto 96);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.multicastLocatorList.locator(i).addr(95 downto 64);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.multicastLocatorList.locator(i).addr(63 downto 32);
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := ref.multicastLocatorList.locator(i).addr(31 downto 0);
|
|
output.length := output.length + 1;
|
|
end loop;
|
|
end if;
|
|
-- USER DATA
|
|
tmp := string_len(ref.user_data);
|
|
if (tmp > 1) then
|
|
output.data(output.length) := PID_USER_DATA & endian_swap(ref.littleEndian, int((round_div(tmp,4)+1)*4,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, int(tmp, 32));
|
|
output.length := output.length + 1;
|
|
for i in 0 to round_div(tmp,4)-1 loop
|
|
output.data(output.length) := ref.user_data(i);
|
|
output.length := output.length + 1;
|
|
end loop;
|
|
end if;
|
|
-- TOPIC DATA
|
|
tmp := string_len(ref.topic_data);
|
|
if (tmp > 1) then
|
|
output.data(output.length) := PID_TOPIC_DATA & endian_swap(ref.littleEndian, int((round_div(tmp,4)+1)*4,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, int(tmp,32));
|
|
output.length := output.length + 1;
|
|
for i in 0 to round_div(tmp,4)-1 loop
|
|
output.data(output.length) := ref.topic_data(i);
|
|
output.length := output.length + 1;
|
|
end loop;
|
|
end if;
|
|
-- GROUP DATA
|
|
tmp := string_len(ref.group_data);
|
|
if (tmp > 1) then
|
|
output.data(output.length) := PID_GROUP_DATA & endian_swap(ref.littleEndian, int((round_div(tmp,4)+1)*4,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, int(tmp,32));
|
|
output.length := output.length + 1;
|
|
for i in 0 to round_div(tmp,4)-1 loop
|
|
output.data(output.length) := ref.group_data(i);
|
|
output.length := output.length + 1;
|
|
end loop;
|
|
end if;
|
|
-- MAX SIZE SERIALIZED
|
|
if (unsigned(ref.max_size_serialized) /= 0) then
|
|
output.data(output.length) := PID_DATA_MAX_SIZE_SERIALIZED & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH));
|
|
output.length := output.length + 1;
|
|
output.data(output.length) := endian_swap(ref.littleEndian, ref.max_size_serialized);
|
|
output.length := output.length + 1;
|
|
end if;
|
|
end procedure;
|
|
|
|
end package body; |