-- altera vhdl_input_version vhdl_2008 -- XXX: QSYS Fix (https://www.intel.com/content/www/us/en/support/programmable/articles/000079458.html) 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 TEST_CLOCK_PERIOD : time := 50 ns; -- File were the Test Results are stored constant RESULTS_FILE : string := "./Test_Results.txt"; -- Frame Sizes have to be specified, so that direct memory probing is possible -- rtps_builtin_endpoint Participant Frame Size constant PARTICIPANT_FRAME_SIZE : natural := 24; -- rtps_reader Endpoint Frame Size (RELIABLE=TRUE) constant WRITER_ENDPOINT_FRAME_SIZE_A : natural := 14; -- rtps_reader Endpoint Frame Size (RELIABLE=FALSE) constant WRITER_ENDPOINT_FRAME_SIZE_B : natural := 10; -- rtps_writer Endpoint Frame Size (RELIABLE=TRUE) constant READER_ENDPOINT_FRAME_SIZE_A : natural := 15; -- rtps_writer Endpoint Frame Size (RELIABLE=FALSE) constant READER_ENDPOINT_FRAME_SIZE_B : natural := 6; constant DEFAULT_GUIDPREFIX : GUIDPREFIX_TYPE; -- Deferred to Package Body constant DEFAULT_READER_ENTITYID : std_logic_vector(ENTITYID_WIDTH-1 downto 0); -- Deferred to Package Body constant DEFAULT_WRITER_ENTITYID : std_logic_vector(ENTITYID_WIDTH-1 downto 0); -- Deferred to Package Body type MATCH_TYPE is (MATCH, UNMATCH); -- General Purpose 32-bit wide data container type TEST_PACKET_TYPE is record -- Limit Packet Size to 2^16 (IPv4 size limit) data : WORD_ARRAY_TYPE(0 to (2**16)/4); -- Last Word Indicator last : std_logic_vector(0 to (2**16)/4); -- Length of Packet length : natural; end record; constant EMPTY_TEST_PACKET : TEST_PACKET_TYPE; -- Deferred to Package Body -- Memory Element Representation type TEST_MEMORY_ELEMENT_TYPE is record addr : natural; data : std_logic_vector(WORD_WIDTH-1 downto 0); end record; type TEST_MEMORY_TYPE is array (natural range <>) of TEST_MEMORY_ELEMENT_TYPE; subtype TEST_PARTICIPANT_MEMORY_FRAME_TYPE is TEST_MEMORY_TYPE(0 to PARTICIPANT_FRAME_SIZE-1); subtype TEST_WRITER_ENDPOINT_MEMORY_FRAME_TYPE_A is TEST_MEMORY_TYPE(0 to WRITER_ENDPOINT_FRAME_SIZE_A-1); subtype TEST_WRITER_ENDPOINT_MEMORY_FRAME_TYPE_B is TEST_MEMORY_TYPE(0 to WRITER_ENDPOINT_FRAME_SIZE_B-1); subtype TEST_READER_ENDPOINT_MEMORY_FRAME_TYPE_A is TEST_MEMORY_TYPE(0 to READER_ENDPOINT_FRAME_SIZE_A-1); subtype TEST_READER_ENDPOINT_MEMORY_FRAME_TYPE_B is TEST_MEMORY_TYPE(0 to READER_ENDPOINT_FRAME_SIZE_B-1); 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 type OUTPUT_HEADER_TYPE is record src : LOCATOR_TYPE; dest : LOCATOR_TYPE; end record; constant DEFAULT_OUTPUT_HEADER : OUTPUT_HEADER_TYPE; -- Deferred to Package Body 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 -- Generic RTPS Submessage Container type RTPS_SUBMESSAGE_TYPE is record -- ALL 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); -- ACKNACK/DATA/GAP/HEARTBEAT/DATAFRAG/NACKFRAG readerId : std_logic_vector(ENTITYID_WIDTH-1 downto 0); writerId : std_logic_vector(ENTITYID_WIDTH-1 downto 0); -- DATA/DATAFRAG/HEARTBEATFRAG/NACKFRAG writerSN : SEQUENCENUMBER_TYPE; -- DATA/DATAFRAG inlineQos : TEST_PACKET_TYPE; data : TEST_PACKET_TYPE; -- DATA extraFlags : std_logic_vector(SUBMESSAGE_DATA_EXTRA_FLAGS_WIDTH-1 downto 0); octetsToInlineQos : std_logic_vector(SUBMESSAGE_LENGTH_WIDTH-1 downto 0); -- DATAFRAG 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); -- HEARTBEAT/HEARTBEATFRAG/NACKFRAG/ACKNACK count : std_logic_vector(COUNT_WIDTH-1 downto 0); -- HEARTBEAT firstSN : SEQUENCENUMBER_TYPE; lastSN : SEQUENCENUMBER_TYPE; -- HEARTBEATFRAG lastFragmentNum : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); -- NACKFRAG fragmentNumberState : FRAGMENTNUMBER_SET_TYPE; -- ACKNACK readerSNState : SEQUENCENUMBER_SET_TYPE; -- GAP gapStart : SEQUENCENUMBER_TYPE; gapList : SEQUENCENUMBER_SET_TYPE; -- INFO_REPLY unicastLocatorList : LOCATOR_LIST_TYPE; multicastLocatorList : LOCATOR_LIST_TYPE; -- INFO_DEST/INFO_SRC guidPrefix : GUIDPREFIX_TYPE; -- INFO_SRC 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); -- INFO_TS timestamp : TIME_TYPE; -- INFO_REPLY_IP4 unicastLocator : LOCATOR_TYPE; multicastLocator : LOCATOR_TYPE; end record; constant DEFAULT_RTPS_SUBMESSAGE : RTPS_SUBMESSAGE_TYPE; -- Deferred to Package Body type PARTICIPANT_DATA_TYPE is record -- Signifies if the Data should be written in Little Endian 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); -- Signifies if the Participant represented by this Record is a match match : MATCH_TYPE; -- Denotes the Position in the Memory of this Participant Data nr : natural; -- Denotes which locator is to be used (Same as PREFER_MULTICAST generic of rtps_builtin_endpoint) PREFER_MULTICAST : boolean; end record; constant DEFAULT_PARTICIPANT_DATA : PARTICIPANT_DATA_TYPE; -- Deferred to Package Body constant THIS_PARTICIPANT_DATA : PARTICIPANT_DATA_TYPE; -- Deferred to Package Body -- Generic RTPS Endpoint Container type ENDPOINT_DATA_TYPE is record -- Signifies if the Endoint Data represented by this Record is a Reader Endpoint reader : boolean; -- Signifies if the Data should be written in Little Endian 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; lifespan : DURATION_TYPE; destination_order : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0); 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); -- 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; -- Signifies if the Endpoint represented by this Record is a match match : MATCH_TYPE; -- Denotes the Position in the Memory of this Participant Data nr : natural; end record; constant DEFAULT_ENDPOINT_DATA : ENDPOINT_DATA_TYPE; -- Deferred to Package Body type ENDPOINT_DATA_ARRAY_TYPE is array (natural range <>) of ENDPOINT_DATA_TYPE; -- Cache Change Representation type CACHE_CHANGE_TYPE is record -- Denotes if the CC contains the Serialized Key serialized_key : boolean; kind : CACHE_CHANGE_KIND_TYPE; writer_guid : GUID_TYPE; instance : INSTANCE_HANDLE_TYPE; seq_nr : SEQUENCENUMBER_TYPE; src_timestamp : TIME_TYPE; payload : TEST_PACKET_TYPE; end record; constant DEFAULT_CACHE_CHANGE : CACHE_CHANGE_TYPE; -- Deferred to Package Body -- DDS Sample Representation type SAMPLE_TYPE is record -- Instance (KEY_HASH) inst : INSTANCE_HANDLE_TYPE; data : TEST_PACKET_TYPE; -- Sample State sstate : std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0); -- Instance State istate : std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); -- View State vstate : std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0); -- Disposed Generation Count dis_gen_cnt : natural; -- No Writers Generation Count no_w_gen_cnt : natural; -- Sample Rank srank : natural; -- Generation Rank grank : natural; -- Absolut Generation Rank agrank : natural; -- Source Timestamp ts : TIME_TYPE; end record; constant DEFAULT_SAMPLE : SAMPLE_TYPE; -- Deferred to Package Body -- NOTE: The array is currently limited to 15 Samples to limit memory allocation type SAMPLE_ARRAY_TYPE is array (0 to 15) of SAMPLE_TYPE; -- Representation of a DDS Reader Sample Collection type COLLECTION_TYPE is record s : SAMPLE_ARRAY_TYPE; len : natural; end record; constant DEFAULT_COLLECTION : COLLECTION_TYPE; -- Deferred to Package Body -- Representation of DDS Reader Instance State type INSTANCE_CACHE_TYPE is record -- Instance (KEY_HASH) inst : INSTANCE_HANDLE_TYPE; -- Instance State istate : std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); -- Vies State vstate : std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0); -- Disposed Generation Count dis_gen_cnt : natural; -- No Writers Geneation Count no_w_gen_cnt : natural; end record; constant DEFAULT_INSTANCE_CACHE_TYPE : INSTANCE_CACHE_TYPE; -- Deferred to Package Body type INSTANCE_CACHE_ARRAY_TYPE is array (0 to 15) of INSTANCE_CACHE_TYPE; -- Representation of DDS Reader internal Memory type DDS_READER_MEM_TYPE is record -- Sample Memory s : SAMPLE_ARRAY_TYPE; slen : natural; -- Instance Memory inst : INSTANCE_CACHE_ARRAY_TYPE; ilen : natural; end record; constant DEFAULT_DDS_READER_MEM : DDS_READER_MEM_TYPE; -- Deferred to Package Body -- Representation of DDS Reader Operations type DDS_READER_TEST_TYPE is record -- OPERATION & ARGUMENTS opcode : DDS_READER_OPCODE_TYPE; sstate : std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0); istate : std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); vstate : std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0); max_samples : natural; -- NOTE: Instance is used as Operation Arguments & Expected Return (Last Rejected Instance) inst : INSTANCE_HANDLE_TYPE; -- EXPECTED RETURN ret_code : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0); -- STATUS Operation Count count : natural; -- STATUS Operation Count Change change : natural; -- STATUS Operation Last Rejected Reason last_reason : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0); end record; constant DEFAULT_DDS_READER_TEST : DDS_READER_TEST_TYPE; -- Deferred to Package Body -- Represntation of RTPS Writer Operations type RTPS_WRITER_TEST_TYPE is record opcode : HISTORY_CACHE_OPCODE_TYPE; cc : CACHE_CHANGE_TYPE; ret_code : HISTORY_CACHE_RESPONSE_TYPE; end record; constant DEFAULT_RTPS_WRITER_TEST : RTPS_WRITER_TEST_TYPE; -- Deferred to Package Body -- Representation of RTPS Reader Operations type RTPS_READER_TEST_TYPE is record opcode : HISTORY_CACHE_OPCODE_TYPE; cc : CACHE_CHANGE_TYPE; lifespan : DURATION_TYPE; writer_pos : natural; ret_code : HISTORY_CACHE_RESPONSE_TYPE; end record; constant DEFAULT_RTPS_READER_TEST : RTPS_READER_TEST_TYPE; -- Deferred to Package Body -- Representation of DDS Writer Operation type DDS_WRITER_TEST_TYPE is record -- OPERATION & ARGUMENTS opcode : DDS_WRITER_OPCODE_TYPE; cc : CACHE_CHANGE_TYPE; -- NOTE: Instance is used as Operation Arguments & Expected Return (Deadline Missed Instance) inst : INSTANCE_HANDLE_TYPE; -- Liveliness Assertion assertion : std_logic; -- EXPECTED RETURN ret_code : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0); -- STATUS Operation Count count : natural; -- STATUS Operation Count Change change : natural; end record; constant DEFAULT_DDS_WRITER_TEST : DDS_WRITER_TEST_TYPE; -- Deferred to Package Body -- *RTPS SPECIFICATION* -- Writes RTPS Output Header based on "ref" to "output" procedure gen_output_header(ref : in OUTPUT_HEADER_TYPE; output : inout TEST_PACKET_TYPE); -- Fixes the "Packet Length" Field of the RTPS Output Reader with the current Packet Length -- This function should be called to fnalize the RTPS packet procedure fix_output_packet(output : inout TEST_PACKET_TYPE); -- Writes RTPS Header based on "ref" to "output" procedure gen_rtps_header( ref : in RTPS_HEADER_TYPE; output : inout TEST_PACKET_TYPE); -- Write RTPS Submessage based on "ref" to "output" procedure gen_rtps_submessage( ref : in RTPS_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE); -- Writes Participant Data based on "ref" to "output" procedure gen_participant_data( ref : in PARTICIPANT_DATA_TYPE; output : inout TEST_PACKET_TYPE); -- Like previous procedure, but allows modification of the generated output. -- The Parameter Field represented by "pid" is always written, not depending on if it has Default value. "Offset" modifies the Parameter Length of the "pid" and represents how -- many 4-Byte Words to add/subtract from the original value. -- This allows to generate invalid parameter lists procedure gen_participant_data( ref : in PARTICIPANT_DATA_TYPE; output : inout TEST_PACKET_TYPE; pid : in std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0); offset : in integer); -- Writes Endpoint Data based on "ref" to "output" procedure gen_endpoint_data( ref : in ENDPOINT_DATA_TYPE; output : inout TEST_PACKET_TYPE); -- Like previous procedure, but allows modification of the generated output. -- The Parameter Field represented by "pid" is always written, not depending on if it has Default value. "Offset" modifies the Parameter Length of the "pid" and represents how -- many 4-Byte Words to add/subtract from the original value. -- This allows to generate invalid parameter lists procedure gen_endpoint_data( ref : in ENDPOINT_DATA_TYPE; output : inout TEST_PACKET_TYPE; pid : in std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0); offset : in integer); -- Generate Participant Message Data -- participant participant to assert Liveliness -- manual TRUE if MANUAL_LIVELINESS_UPDATE, FALSE if AUTOMATIC_LIVELINESS_UPDATE -- extra_data Extra Data in Participant Message -- output Destination of generated ouput procedure gen_liveliness_assertion(participant : in PARTICIPANT_DATA_TYPE; manual : in boolean; extra_data : in TEST_PACKET_TYPE; output : inout TEST_PACKET_TYPE); -- Same as previous procedure, but extra_data is EMPTY procedure gen_liveliness_assertion(participant : in PARTICIPANT_DATA_TYPE; manual : in boolean; output : inout TEST_PACKET_TYPE); -- Generate DATA Submessage InLine QoS -- ref Cache Change (Used for PID_KEY_HASH, PID_STATUS_INFO) -- endpoint Endpoint Data -- expectsInlineQoS The Endpoint Data related PIDs are only generated if this is TRUE -- littleEndian If TRUE the generated Data is in little Endian, else in Big Endian -- output Destination of generated output procedure gen_inline_qos(ref : in CACHE_CHANGE_TYPE; endpoint : in ENDPOINT_DATA_TYPE; expectsInlineQoS : in boolean; littleEndian : in std_logic; output : inout TEST_PACKET_TYPE); -- Like previous procedure, but allows modification of the generated output. -- The Parameter Field represented by "pid" is always written, not depending on if it has Default value. "Offset" modifies the Parameter Length of the "pid" and represents how -- many 4-Byte Words to add/subtract from the original value. -- This allows to generate invalid parameter lists -- NOTE: "expectsInlineQoS" takes precedence over "pid" (I.e. if expectsInlineQoS=FALSE and pid is Endpoint related, the PID Element will not be generated) procedure gen_inline_qos(ref : in CACHE_CHANGE_TYPE; endpoint : in ENDPOINT_DATA_TYPE; expectsInlineQoS : in boolean; littleEndian : in std_logic; output : inout TEST_PACKET_TYPE; pid : in std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0); offset : in integer); -- Like previous procedure, but no Endpoint Data related PIDs are generated (only PID_KEY_HASH, PID_STATUS_INFO) procedure gen_inline_qos(ref : in CACHE_CHANGE_TYPE; output : inout TEST_PACKET_TYPE); -- Like previous procedure, but the data for PID_STATUS_INFO andf PID_KEY_HASH are given directly. procedure gen_inline_qos(status : in CACHE_CHANGE_KIND_TYPE; key : in INSTANCE_HANDLE_TYPE; output : inout TEST_PACKET_TYPE); -- Like previous procedure but with "pid" and "offset" parameters. procedure gen_inline_qos(status : in CACHE_CHANGE_KIND_TYPE; key : in INSTANCE_HANDLE_TYPE; output : inout TEST_PACKET_TYPE; pid : in std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0); offset : in integer); -- Generate Parameter List Element [NOTE: Dat has to be in the correct endianness] -- pid Parameter ID of element -- data Parameter Data of element -- littleEndian If TRUE the generated Data is in little Endian, else in Big Endian -- output Destination of generated output procedure gen_parameter(pid : in std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0); data : in TEST_PACKET_TYPE; littleEndian : in std_logic; output : inout TEST_PACKET_TYPE); -- Generate Parameter List Sentinel. This procedure should be used to finalize Parameter Lists -- littleEndian If TRUE the generated Data is in little Endian, else in Big Endian -- output Destination of generated output procedure gen_sentinel(littleEndian : in std_logic; output : inout TEST_PACKET_TYPE); -- Shortcut of previous procedure in Big Endian procedure gen_sentinel(output : inout TEST_PACKET_TYPE); -- *RTPS_READER* -- Generates RTPS Reader ADD_CACHE_CHANGE output (DDS Reader Input) -- ref Cache Change -- lifespan_deadline Lifespan Deadline of Sample -- pos ID (Memory Position) of Source Remote Writer -- output Destination of generated output procedure gen_add_cache_change_dds(ref : in CACHE_CHANGE_TYPE; lifespan_deadline : in TIME_TYPE; pos : in natural; output : inout TEST_PACKET_TYPE); -- Generate a rtps_writer memory Participant Frame based on "ref". (A Version) function gen_writer_endpoint_mem_frame_a (ref : ENDPOINT_DATA_TYPE) return TEST_WRITER_ENDPOINT_MEMORY_FRAME_TYPE_A; -- Generate a rtps_writer memory Participant Frame based on "ref". (B Version) function gen_writer_endpoint_mem_frame_b (ref : ENDPOINT_DATA_TYPE) return TEST_WRITER_ENDPOINT_MEMORY_FRAME_TYPE_B; -- *RTPS WRITER* -- Generate a rtps_reader memory Participant Frame based on "ref". (A Version) function gen_reader_endpoint_mem_frame_a (ref : ENDPOINT_DATA_TYPE) return TEST_READER_ENDPOINT_MEMORY_FRAME_TYPE_A; -- Generate a rtps_reader memory Participant Frame based on "ref". (B Version) function gen_reader_endpoint_mem_frame_b (ref : ENDPOINT_DATA_TYPE) return TEST_READER_ENDPOINT_MEMORY_FRAME_TYPE_B; -- *RTPS_HANDLER* -- Generates RTPS_HANDLER output -- ref RTPS Submessage -- loc Source Locator of RTPS Submessage -- is_meta Indicates if the RTPS Submessage is metatraffic (Destined for Built-in Endpoints) -- ts Source Timestamp of RTPS Submessage -- src_guid Source GUID of RTPS Submessage -- output Destination of generated output 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); -- Like the previous procedure, but the source locator & GUID is extracted from the "participant". Timestamp is INVALID and is_meta is set to TRUE. procedure gen_rtps_handler_out(ref : in RTPS_SUBMESSAGE_TYPE; participant : PARTICIPANT_DATA_TYPE; output : inout TEST_PACKET_TYPE); -- Like the previous procedure, but the source locator & GUID is extracted from the "endpoint". Timestamp is INVALID and is_meta is set to TRUE. procedure gen_rtps_handler_out(ref : in RTPS_SUBMESSAGE_TYPE; endpoint : ENDPOINT_DATA_TYPE; output : inout TEST_PACKET_TYPE); -- *RTPS_BUILTIN_ENDPOINT* -- Generate a rtps_builtin_endpoint memory Participant Frame based on "ref". function gen_participant_mem_frame (ref : PARTICIPANT_DATA_TYPE) return TEST_PARTICIPANT_MEMORY_FRAME_TYPE; -- Writes a rtps_builtin_endpoint Endpoint Match Frame based on "ref" to "output" procedure gen_endpoint_match_frame( ref : in ENDPOINT_DATA_TYPE; output : inout TEST_PACKET_TYPE); -- Writes a rtps_builtin_endpoint Participant Match Frame based on "ref" to "output" procedure gen_participant_match_frame( ref : in PARTICIPANT_DATA_TYPE; output : inout TEST_PACKET_TYPE); -- Writes a rtps_builtin_endpoint Endpoint Liveliness Update Frame based on "ref" to "output" procedure gen_liveliness_update_frame( ref : in PARTICIPANT_DATA_TYPE; output : inout TEST_PACKET_TYPE); -- *DDS_READER* -- Add Instance to Memory -- inst Instance (KEY_HASH) -- istate Instance State -- mem Target Memory procedure add_instance(inst : in INSTANCE_HANDLE_TYPE; istate : in std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); mem : inout DDS_READER_MEM_TYPE); -- Change Instance State of Instance in Memory -- inst Instance to be modified (KEY_HASH) -- istate New instance State -- mem Target Memory procedure change_istate(inst : INSTANCE_HANDLE_TYPE; istate : in std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); mem : inout DDS_READER_MEM_TYPE); -- Add Sample to Memory -- sample Sample to be added -- mem Target Memory -- DESTINATION_ORDER_QOS Determines the position where the Sample is added to the memory. If BY_RECEPTION_TIMESTAMP_DESTINATION_ORDER_QOS the Sample is added -- to the end of the memory. If BY_SOURCE_TIMESTAMP_DESTINATION_ORDER_QOS the Sample is positioned according to the source timestamp -- of the Sample (Earliest first). -- NOTE: This function sets the View State, Disposed Generation Count, and No Writers Generation Count of the added Sample procedure add_sample(sample : inout SAMPLE_TYPE; mem : inout DDS_READER_MEM_TYPE; DESTINATION_ORDER_QOS : in std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0)); -- Remove Sample from Memory -- ind Index position of Sample to be removed -- mem Target Memory procedure remove_sample(ind : in natural; mem : inout DDS_READER_MEM_TYPE); -- Remove Instance from Memory -- inst Instance to be removed (KEY_HASH) -- mem Target Memory procedure remove_inst(inst : in INSTANCE_HANDLE_TYPE; mem : inout DDS_READER_MEM_TYPE); -- Check Instance State. returns TRUE if "istate" and "vstate" are equal to the instance State and View State of "inst" in "mem" function check_instance(istate : std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); vstate : std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0); mem : DDS_READER_MEM_TYPE; inst : INSTANCE_HANDLE_TYPE) return boolean; -- Return index position of Instance "inst" in "mem" function find_instance(mem : DDS_READER_MEM_TYPE; inst : INSTANCE_HANDLE_TYPE) return natural; -- Generate DDS Reader Sample Collection -- mem Source Memory -- col Generated Collection -- inst Target Instance of samples in collection (Use HANDLE_NIL for all Instances) -- sstate Target Sample State of samples in collection -- istate Target Instance State of samples in collection -- vstate Target View State of samples in collection -- max_samples Maximum number of Samples in collection -- remove If TRUE the selected samples are removed from the source memory "mem" -- sort If TRUE the collection is sorted by Instance (Samples of the same Instance are consecutive, not depending on their in-memory order) procedure gen_collection (mem : inout DDS_READER_MEM_TYPE; col : inout COLLECTION_TYPE; inst : INSTANCE_HANDLE_TYPE; sstate : in std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0); istate : in std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); vstate : in std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0); max_samples : in natural; remove : in boolean; sort : in boolean); -- Wrapper of previous procedure. Extracts arguments from DDS Operation -- mem Source Memory -- col Generate Collection -- opcode DDS Reader Operation -- PRESENTATION_QOS Target PRESENTATION_QOS -- ordered Ordered Value of PRESENTATION_QOS procedure gen_collection (mem : inout DDS_READER_MEM_TYPE; col : inout COLLECTION_TYPE; opcode : in DDS_READER_TEST_TYPE; PRESENTATION_QOS : in std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0); ordered : in boolean); -- *HELPER FUNCTIONS* -- Generate Random Locator -- RV OSVVM Random Variable -- ret Generated Random Locator procedure gen_rand_loc(RV : inout RandomPType; ret : out LOCATOR_TYPE); -- Generate Random EntityID -- RV OSVVM Random Variable -- reader If TRUE the generated ID has the prefix for Reader EntityIDs, else for Writer -- ret Generated Random EntityID procedure gen_rand_entityid(RV : inout RandomPType; reader : boolean; ret : out std_logic_vector(ENTITYID_WIDTH-1 downto 0)); -- Generate SLV from Integer -- n Unsigned Value of generated SLV -- width Width of generated SLV function int(n : integer; width : natural) return std_logic_vector; -- to_string Function for ScoreBoardPkg_builtin_endpoint function to_string1 (input : std_logic_vector) return string; -- Find first valid Locator of Particiapnt Data -- ref Participant Data to extract Locator from -- meta If TRUE extracts metatraffic Locator -- NOTE: This assumes a specific sending order (Multicast before Unicast)! function get_loc (ref : PARTICIPANT_DATA_TYPE; meta : boolean) return LOCATOR_TYPE; -- Find first valid Locator of Endpoint Data -- ref Endpoint Data to extract Locator from function get_loc (ref : ENDPOINT_DATA_TYPE) return LOCATOR_TYPE; -- Extract Data from Cache Change "cc" to generate a Sample. -- cc Cache Change -- istate Instance State of Sample function to_sample(cc : CACHE_CHANGE_TYPE; istate : std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0)) return SAMPLE_TYPE; -- Return TRUE if both memory segments are equal, else FALSE function test_memory_match (A,B : TEST_MEMORY_TYPE) return boolean; -- Returns String with Length, Start Address, and End Address of the memory Segment function to_string (input : TEST_MEMORY_TYPE) return string; -- Generate Endpoint Data based on "id" of the test_config Package function gen_endpoint(id : natural) return ENDPOINT_DATA_TYPE; -- Generate all Reader (or Writer if "reader" is FALSE) Endpoints of the test_config Package function gen_endpoint_array(readers : boolean) return ENDPOINT_DATA_ARRAY_TYPE; -- Extract Data from RTPS Submessage (Sequence Number, Payload, Serialized_Key) and generate Cache Change function gen_cache_change(ref : RTPS_SUBMESSAGE_TYPE) return CACHE_CHANGE_TYPE; procedure gen_CDR(input : std_logic_vector; target_align : ALIGN_TYPE; align_offset : inout unsigned; output : inout TEST_PACKET_TYPE); 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; procedure gen_rand_entityid(RV : inout RandomPType; reader : boolean; ret : out std_logic_vector(ENTITYID_WIDTH-1 downto 0)) is begin ret := RV.RandSlv(ENTITYID_WIDTH); ret(ENTITY_KIND_H_RANGE):= USER_DEFINED_ENTITY; if (reader) then ret(ENTITY_KIND_L_RANGE):= READER_NO_KEY; else ret(ENTITY_KIND_L_RANGE):= WRITER_NO_KEY; end if; 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_READER_ENTITYID : std_logic_vector(ENTITYID_WIDTH-1 downto 0) := x"b9cbad04"; constant DEFAULT_WRITER_ENTITYID : std_logic_vector(ENTITYID_WIDTH-1 downto 0) := x"b9cbad03"; constant EMPTY_TEST_PACKET : TEST_PACKET_TYPE := (length => 0, data => (others => (others => '0')), last => (others => '0')); 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 => (UDP_PORT_WIDTH to LOCATOR_PORT_WIDTH-1 => '0') & META_IPv4_MULTICAST_PORT, addr => (IPv4_ADDRESS_WIDTH to LOCATOR_ADDR_WIDTH-1 => '0') & DEFAULT_IPv4_META_ADDRESS ), 1 => ( kind => LOCATOR_KIND_UDPv4, portn => (UDP_PORT_WIDTH to LOCATOR_PORT_WIDTH-1 => '0') & META_IPv4_UNICAST_PORT, addr => (IPv4_ADDRESS_WIDTH to LOCATOR_ADDR_WIDTH-1 => '0') & DEFAULT_IPv4_META_ADDRESS ), 2 => ( kind => LOCATOR_KIND_UDPv4, portn => (UDP_PORT_WIDTH to LOCATOR_PORT_WIDTH-1 => '0') & META_IPv4_MULTICAST_PORT, addr => (IPv4_ADDRESS_WIDTH to LOCATOR_ADDR_WIDTH-1 => '0') & DEFAULT_IPv4_ADDRESS ), 3 => ( kind => LOCATOR_KIND_UDPv4, portn => (UDP_PORT_WIDTH to LOCATOR_PORT_WIDTH-1 => '0') & META_IPv4_UNICAST_PORT, addr => (IPv4_ADDRESS_WIDTH to LOCATOR_ADDR_WIDTH-1 => '0') & DEFAULT_IPv4_ADDRESS ), others => EMPTY_LOCATOR ) ), user => ( numLocators => int(2,CDR_LONG_WIDTH), locator => ( 0 => ( kind => LOCATOR_KIND_UDPv4, portn => (UDP_PORT_WIDTH to LOCATOR_PORT_WIDTH-1 => '0') & USER_IPv4_MULTICAST_PORT, addr => (IPv4_ADDRESS_WIDTH to LOCATOR_ADDR_WIDTH-1 => '0') & DEFAULT_IPv4_ADDRESS ), 1 => ( kind => LOCATOR_KIND_UDPv4, portn => (UDP_PORT_WIDTH to LOCATOR_PORT_WIDTH-1 => '0') & USER_IPv4_UNICAST_PORT, addr => (IPv4_ADDRESS_WIDTH to LOCATOR_ADDR_WIDTH-1 => '0') & DEFAULT_IPv4_ADDRESS ), others => EMPTY_LOCATOR ) ) ); constant DEFAULT_OUTPUT_HEADER : OUTPUT_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, inlineQos => EMPTY_TEST_PACKET, data => EMPTY_TEST_PACKET, 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 => DOMAIN_ID, domainTag => DOMAIN_TAG, 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 => 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'), match => MATCH, nr => 0, PREFER_MULTICAST => FALSE ); constant THIS_PARTICIPANT_DATA : PARTICIPANT_DATA_TYPE := ( littleEndian => '0', domainId => DOMAIN_ID, domainTag => DOMAIN_TAG, protocolVersion => PROTOCOLVERSION_2_4, vendorId => VENDORID_UNKNOWN, guidPrefix => GUIDPREFIX, entityId => ENTITYID_PARTICIPANT, expectsInlineQoS => (others => '0'), metatrafficUnicastLocatorList => (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => DEST_LOC.meta.locator(3), others => EMPTY_LOCATOR)), metatrafficMulticastLocatorList => (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => DEST_LOC.meta.locator(2), others => EMPTY_LOCATOR)), defaultUnicastLocatorList => (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => DEST_LOC.user.locator(1), others => EMPTY_LOCATOR)), defaultMulticastLocatorList => (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => DEST_LOC.user.locator(0), others => EMPTY_LOCATOR)), leaseDuration => 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', DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER => '1', DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR => '1', DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER => '1', DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR => '1', others => '0'), match => MATCH, nr => 0, PREFER_MULTICAST => FALSE ); constant DEFAULT_ENDPOINT_DATA : ENDPOINT_DATA_TYPE := ( reader => TRUE, littleEndian => '0', participant => DEFAULT_PARTICIPANT_DATA, entityId => DEFAULT_READER_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_RELIABILITY_QOS_R, max_blocking_time => DEFAULT_MAX_BLOCKING_TIME, 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'), match => MATCH, nr => 0 ); constant DEFAULT_CACHE_CHANGE : CACHE_CHANGE_TYPE := ( serialized_key => FALSE, kind => ALIVE, writer_guid => GUID_UNKNOWN, instance => HANDLE_NIL, seq_nr => SEQUENCENUMBER_UNKNOWN, src_timestamp => TIME_INVALID, payload => EMPTY_TEST_PACKET ); constant DEFAULT_SAMPLE : SAMPLE_TYPE := ( inst => HANDLE_NIL, data => EMPTY_TEST_PACKET, sstate => NOT_READ_SAMPLE_STATE, istate => ALIVE_INSTANCE_STATE, vstate => NEW_VIEW_STATE, dis_gen_cnt => 0, no_w_gen_cnt => 0, srank => 0, grank => 0, agrank => 0, ts => TIME_INVALID ); constant DEFAULT_COLLECTION : COLLECTION_TYPE := ( s => (others => DEFAULT_SAMPLE), len => 0 ); constant DEFAULT_INSTANCE_CACHE_TYPE : INSTANCE_CACHE_TYPE := ( inst => HANDLE_NIL, istate => ALIVE_INSTANCE_STATE, vstate => NEW_VIEW_STATE, dis_gen_cnt => 0, no_w_gen_cnt => 0 ); constant DEFAULT_DDS_READER_MEM : DDS_READER_MEM_TYPE := ( s => (others => DEFAULT_SAMPLE), slen => 0, inst => (others => DEFAULT_INSTANCE_CACHE_TYPE), ilen => 0 ); constant DEFAULT_DDS_READER_TEST : DDS_READER_TEST_TYPE := ( opcode => NOP, sstate => ANY_SAMPLE_STATE, istate => ANY_INSTANCE_STATE, vstate => ANY_VIEW_STATE, max_samples => 1, inst => HANDLE_NIL, ret_code => RETCODE_OK, count => 0, change => 0, last_reason => NOT_REJECTED ); constant DEFAULT_RTPS_WRITER_TEST : RTPS_WRITER_TEST_TYPE := ( opcode => NOP, cc => DEFAULT_CACHE_CHANGE, ret_code => OK ); constant DEFAULT_RTPS_READER_TEST : RTPS_READER_TEST_TYPE := ( opcode => NOP, cc => DEFAULT_CACHE_CHANGE, lifespan => DURATION_INFINITE, writer_pos => 0, ret_code => OK ); constant DEFAULT_DDS_WRITER_TEST : DDS_WRITER_TEST_TYPE := ( opcode => NOP, cc => DEFAULT_CACHE_CHANGE, ret_code => RETCODE_OK, count => 0, change => 0, inst => HANDLE_NIL, assertion => '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_output_header(ref : in OUTPUT_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; -- 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; -- Packet Length output.data(output.length) := (others => '0'); output.length := output.length + 1; end procedure; procedure fix_output_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(3) := int(output.length-4, WORD_WIDTH); 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; function is_valid_loc (ref : LOCATOR_TYPE) return boolean is begin if (ref.kind /= LOCATOR_KIND_UDPv4) then return FALSE; elsif (ref.addr(IPv4_ADDRESS_WIDTH-1 downto 0) = IPv4_ADDRESS_INVALID) then return FALSE; elsif (ref.portn(UDP_PORT_WIDTH-1 downto 0) = UDP_PORT_INVALID) then return FALSE; else return TRUE; end if; end function; function get_loc (ref : LOCATOR_LIST_TYPE) return LOCATOR_TYPE is variable ret : LOCATOR_TYPE := EMPTY_LOCATOR; begin for i in 0 to to_integer(unsigned(ref.numLocators))-1 loop if (is_valid_loc(ref.locator(i))) then ret := ref.locator(i); end if; end loop; return ret; end function; function get_loc (ref : PARTICIPANT_DATA_TYPE; meta : boolean) return LOCATOR_TYPE is variable ret : LOCATOR_TYPE := EMPTY_LOCATOR; begin --*METATRAFFIC* if (meta) then if (ref.PREFER_MULTICAST) then -- Multicast Locator valid if (is_valid_loc(get_loc(ref.metatrafficMulticastLocatorList))) then return get_loc(ref.metatrafficMulticastLocatorList); -- Fallback to given Unicast Locator elsif (is_valid_loc(get_loc(ref.metatrafficUnicastLocatorList))) then return get_loc(ref.metatrafficUnicastLocatorList); -- Fallback to Protocol Locator else ret.kind := LOCATOR_KIND_UDPv4; ret.addr := (IPv4_ADDRESS_WIDTH to LOCATOR_ADDR_WIDTH-1 => '0') & DEFAULT_IPv4_META_ADDRESS; ret.portn := (UDP_PORT_WIDTH to LOCATOR_PORT_WIDTH-1 => '0') & META_IPv4_MULTICAST_PORT; return ret; end if; else -- Unicast Locator valid if (is_valid_loc(get_loc(ref.metatrafficUnicastLocatorList))) then return get_loc(ref.metatrafficUnicastLocatorList); -- Fallback to given Multicast Locator elsif (is_valid_loc(get_loc(ref.metatrafficMulticastLocatorList))) then return get_loc(ref.metatrafficMulticastLocatorList); -- Fallback to Protocol Locator else ret.kind := LOCATOR_KIND_UDPv4; ret.addr := (IPv4_ADDRESS_WIDTH to LOCATOR_ADDR_WIDTH-1 => '0') & DEFAULT_IPv4_META_ADDRESS; ret.portn := (UDP_PORT_WIDTH to LOCATOR_PORT_WIDTH-1 => '0') & META_IPv4_UNICAST_PORT; return ret; end if; end if; --*DEFAULT* else if (ref.PREFER_MULTICAST) then -- Multicast Locator valid if (is_valid_loc(get_loc(ref.defaultMulticastLocatorList))) then return get_loc(ref.defaultMulticastLocatorList); -- Fallback to given Unicast Locator elsif (is_valid_loc(get_loc(ref.defaultUnicastLocatorList))) then return get_loc(ref.defaultUnicastLocatorList); -- Fallback to Protocol Locator else ret.kind := LOCATOR_KIND_UDPv4; ret.addr := (IPv4_ADDRESS_WIDTH to LOCATOR_ADDR_WIDTH-1 => '0') & DEFAULT_IPv4_META_ADDRESS; ret.portn := (UDP_PORT_WIDTH to LOCATOR_PORT_WIDTH-1 => '0') & USER_IPv4_MULTICAST_PORT; return ret; end if; else -- Unicast Locator valid if (is_valid_loc(get_loc(ref.defaultUnicastLocatorList))) then return get_loc(ref.defaultUnicastLocatorList); -- Fallback to given Multicast Locator elsif (is_valid_loc(get_loc(ref.defaultMulticastLocatorList))) then return get_loc(ref.defaultMulticastLocatorList); -- Fallback to Protocol Locator else ret.kind := LOCATOR_KIND_UDPv4; ret.addr := (IPv4_ADDRESS_WIDTH to LOCATOR_ADDR_WIDTH-1 => '0') & DEFAULT_IPv4_META_ADDRESS; ret.portn := (UDP_PORT_WIDTH to LOCATOR_PORT_WIDTH-1 => '0') & USER_IPv4_UNICAST_PORT; return ret; end if; end if; end if; end function; function get_loc (ref : ENDPOINT_DATA_TYPE) return LOCATOR_TYPE is begin if (ref.participant.PREFER_MULTICAST) then -- Multicast Locator valid if (is_valid_loc(get_loc(ref.multicastLocatorList))) then return get_loc(ref.multicastLocatorList); -- Fallback to given unicast Locator elsif (is_valid_loc(get_loc(ref.unicastLocatorList))) then return get_loc(ref.unicastLocatorList); -- Fallback to Participant default else return get_loc(ref.participant, FALSE); end if; else -- Unicast Locator valid if (is_valid_loc(get_loc(ref.unicastLocatorList))) then return get_loc(ref.unicastLocatorList); -- Fallback to given Multicast Locator elsif (is_valid_loc(get_loc(ref.multicastLocatorList))) then return get_loc(ref.multicastLocatorList); else return get_loc(ref.participant, FALSE); end if; end if; end function; 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; -- INLINE QOS if (ref.inlineQos.length > 0) then for i in 0 to (ref.inlineQos.length*4)-1 loop store_byte((i+tmp) mod 4, ref.inlineQos.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; -- 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 -- NOTE: A Submessage Length of 0 is left as is. -- Fix Submessage Length if (ref.submessageLength = (ref.submessageLength'reverse_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(Truncate/Extend) Packet Length to specified Length elsif (ref.submessageLength /= (ref.submessageLength'reverse_range => '0')) then 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 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; -- 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; -- 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; -- INLINE QOS if (ref.inlineQos.length > 0) then for i in 0 to ref.inlineQos.length-1 loop output.data(output.length) := ref.inlineQos.data(i); output.length := output.length + 1; end loop; 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); -- UNUSED output.data(output.length) := (others => '0'); output.length := output.length + 1; end if; -- Mark Last Word output.last(output.length-1) := '1'; end procedure; procedure gen_rtps_handler_out(ref : in RTPS_SUBMESSAGE_TYPE; participant : PARTICIPANT_DATA_TYPE; output : inout TEST_PACKET_TYPE) is begin gen_rtps_handler_out(ref, get_loc(participant, TRUE), TRUE, TIME_INVALID, participant.guidPrefix, output); end procedure; procedure gen_rtps_handler_out(ref : in RTPS_SUBMESSAGE_TYPE; endpoint : ENDPOINT_DATA_TYPE; output : inout TEST_PACKET_TYPE) is begin gen_rtps_handler_out(ref, get_loc(endpoint.participant, TRUE), TRUE, TIME_INVALID, endpoint.participant.guidPrefix, output); end procedure; function gen_cache_change(ref : RTPS_SUBMESSAGE_TYPE) return CACHE_CHANGE_TYPE is variable ret : CACHE_CHANGE_TYPE := DEFAULT_CACHE_CHANGE; begin assert(ref.submessageID = SID_DATA) report "Cache Change can only be derived from DATA Submessages." severity FAILURE; ret.seq_nr := ref.writerSN; ret.payload := ref.data; ret.serialized_key := TRUE when (ref.flags(SUBMESSAGE_KEY_FLAG_POS) = '1') else FALSE; return ret; end function; procedure gen_add_cache_change_dds(ref : in CACHE_CHANGE_TYPE; lifespan_deadline : in TIME_TYPE; pos : in natural; output : inout TEST_PACKET_TYPE) is begin -- Status Info output.data(output.length) := (others => '0'); case (ref.kind) is when ALIVE_FILTERED => output.data(output.length)(SSI_FILTERED_FLAG) := '1'; when NOT_ALIVE_DISPOSED => output.data(output.length)(SSI_DISPOSED_FLAG) := '1'; when NOT_ALIVE_UNREGISTERED => output.data(output.length)(SSI_UNREGISTERED_FLAG) := '1'; when others => null; end case; if (ref.payload.length > 0 and (not ref.serialized_key)) then output.data(output.length)(SSI_DATA_FLAG) := '1'; end if; if (ref.instance /= HANDLE_NIL) then output.data(output.length)(SSI_KEY_HASH_FLAG) := '1'; end if; output.length := output.length + 1; -- Source Timestamp output.data(output.length) := std_logic_vector(ref.src_timestamp(0)); output.length := output.length + 1; output.data(output.length) := std_logic_vector(ref.src_timestamp(1)); output.length := output.length + 1; -- Lifespan Deadline output.data(output.length) := std_logic_vector(lifespan_deadline(0)); output.length := output.length + 1; output.data(output.length) := std_logic_vector(lifespan_deadline(1)); output.length := output.length + 1; -- Key Hash if (ref.instance /= HANDLE_NIL) then output.data(output.length) := ref.instance(0); output.length := output.length + 1; output.data(output.length) := ref.instance(1); output.length := output.length + 1; output.data(output.length) := ref.instance(2); output.length := output.length + 1; output.data(output.length) := ref.instance(3); output.length := output.length + 1; end if; -- Remote Writer Endpoint Position output.data(output.length) := std_logic_vector(to_unsigned(pos, WORD_WIDTH)); output.length := output.length + 1; -- Payload -- NOTE: Do not send Serialized Key if Key Hash is available if (ref.payload.length > 0 and (not (ref.serialized_key and ref.instance /= HANDLE_NIL))) then for i in 0 to ref.payload.length-1 loop output.data(output.length) := ref.payload.data(i); output.length := output.length + 1; end loop; end if; -- Mark Last Word output.last(output.length-1) := '1'; end procedure; procedure gen_liveliness_assertion(participant : in PARTICIPANT_DATA_TYPE; manual : in boolean; extra_data : in TEST_PACKET_TYPE; output : inout TEST_PACKET_TYPE) is begin -- Representation Identifier & Representation Options output.data(output.length) := CDR_BE & x"0000"; output.length := output.length + 1; -- GUID Prefix output.data(output.length) := participant.guidPrefix(0); output.length := output.length + 1; output.data(output.length) := participant.guidPrefix(1); output.length := output.length + 1; output.data(output.length) := participant.guidPrefix(2); output.length := output.length + 1; -- Participant Message Kind if (manual) then output.data(output.length) := PARTICIPANT_MESSAGE_DATA_KIND_MANUAL_LIVELINESS_UPDATE; else output.data(output.length) := PARTICIPANT_MESSAGE_DATA_KIND_AUTOMATIC_LIVELINESS_UPDATE; end if; output.length := output.length + 1; -- DATA Length output.data(output.length) := int(extra_data.length, WORD_WIDTH); output.length := output.length + 1; for i in 0 to extra_data.length-1 loop output.data(output.length) := extra_data.data(i); output.length := output.length + 1; end loop; end procedure; procedure gen_liveliness_assertion(participant : in PARTICIPANT_DATA_TYPE; manual : in boolean; output : inout TEST_PACKET_TYPE) is begin gen_liveliness_assertion(participant, manual, EMPTY_TEST_PACKET, output); end procedure; procedure gen_participant_data( ref : in PARTICIPANT_DATA_TYPE; output : inout TEST_PACKET_TYPE; pid : in std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0); offset : in integer) 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 if (pid = PID_PARTICIPANT_GUID) then assert (16+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_PARTICIPANT_GUID) & endian_swap(ref.littleEndian, int(16+(offset*4), PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_PARTICIPANT_GUID) & endian_swap(ref.littleEndian, int(16, PARAMETER_LENGTH_WIDTH)); end if; 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; if (pid = PID_PARTICIPANT_GUID) then output.length := output.length + offset; end if; -- DOMAIN ID if (pid = PID_DOMAIN_ID) then assert (4+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_DOMAIN_ID) & endian_swap(ref.littleEndian, int(4+(offset*4), PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_DOMAIN_ID) & endian_swap(ref.littleEndian, int(4, PARAMETER_LENGTH_WIDTH)); end if; output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.domainId); output.length := output.length + 1; if (pid = PID_DOMAIN_ID) then output.length := output.length + offset; end if; -- DOMAIN TAG if (ref.domainTag /= DEFAULT_DOMAIN_TAG or pid = PID_DOMAIN_TAG) then tmp := string_len(ref.domainTag); if (pid = PID_DOMAIN_TAG) then assert (((round_div(tmp,4)+1)*4)+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_DOMAIN_TAG) & endian_swap(ref.littleEndian, int(((round_div(tmp,4)+1)*4)+(offset*4), PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_DOMAIN_TAG) & endian_swap(ref.littleEndian, int((round_div(tmp,4)+1)*4, PARAMETER_LENGTH_WIDTH)); end if; 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; if (pid = PID_DOMAIN_TAG) then output.length := output.length + offset; end if; end if; -- PROTOCOL VERSION if (pid = PID_PROTOCOL_VERSION) then assert (4+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_PROTOCOL_VERSION) & endian_swap(ref.littleEndian, int(4+(offset*4), PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_PROTOCOL_VERSION) & endian_swap(ref.littleEndian, int(4, PARAMETER_LENGTH_WIDTH)); end if; 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; if (pid = PID_PROTOCOL_VERSION) then output.length := output.length + offset; end if; -- VENDORID if (pid = PID_VENDORID) then assert (4+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_VENDORID) & endian_swap(ref.littleEndian, int(4+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_VENDORID) & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); end if; 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; if (pid = PID_VENDORID) then output.length := output.length + offset; end if; -- EXPECTS IN-LINE QOS if (ref.expectsInlineQoS(0) /= DEFAULT_EXPECTS_INLINE_QOS or pid = PID_EXPECTS_INLINE_QOS) then if (pid = PID_EXPECTS_INLINE_QOS) then assert (4+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_EXPECTS_INLINE_QOS) & endian_swap(ref.littleEndian, int(4+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_EXPECTS_INLINE_QOS) & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); end if; 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; if (pid = PID_EXPECTS_INLINE_QOS) then output.length := output.length + offset; end if; end if; -- METATRAFFIC MULTICAST LOCATOR if (ref.metatrafficMulticastLocatorList.numLocators /= (ref.metatrafficMulticastLocatorList.numLocators'reverse_range => '0')) then tmp := to_integer(unsigned(ref.metatrafficMulticastLocatorList.numLocators)); for i in 0 to tmp-1 loop if (pid = PID_METATRAFFIC_MULTICAST_LOCATOR) then assert (24+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_METATRAFFIC_MULTICAST_LOCATOR) & endian_swap(ref.littleEndian, int(24+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_METATRAFFIC_MULTICAST_LOCATOR) & endian_swap(ref.littleEndian, int(24,PARAMETER_LENGTH_WIDTH)); end if; output.length := output.length + 1; 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; if (pid = PID_METATRAFFIC_MULTICAST_LOCATOR) then output.length := output.length + offset; end if; end loop; end if; -- METATRAFFIC UNICAST LOCATOR if (ref.metatrafficUnicastLocatorList.numLocators /= (ref.metatrafficUnicastLocatorList.numLocators'reverse_range => '0')) then tmp := to_integer(unsigned(ref.metatrafficUnicastLocatorList.numLocators)); for i in 0 to tmp-1 loop if (pid = PID_METATRAFFIC_UNICAST_LOCATOR) then assert (24+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_METATRAFFIC_UNICAST_LOCATOR) & endian_swap(ref.littleEndian, int(24+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_METATRAFFIC_UNICAST_LOCATOR) & endian_swap(ref.littleEndian, int(24,PARAMETER_LENGTH_WIDTH)); end if; output.length := output.length + 1; 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; if (pid = PID_METATRAFFIC_UNICAST_LOCATOR) then output.length := output.length + offset; end if; end loop; end if; -- DEFAULT MULTICAST LOCATOR if (ref.defaultMulticastLocatorList.numLocators /= (ref.defaultMulticastLocatorList.numLocators'reverse_range => '0')) then tmp := to_integer(unsigned(ref.defaultMulticastLocatorList.numLocators)); for i in 0 to tmp-1 loop if (pid = PID_DEFAULT_MULTICAST_LOCATOR) then assert (24+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_DEFAULT_MULTICAST_LOCATOR) & endian_swap(ref.littleEndian, int(24+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_DEFAULT_MULTICAST_LOCATOR) & endian_swap(ref.littleEndian, int(24,PARAMETER_LENGTH_WIDTH)); end if; output.length := output.length + 1; 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; if (pid = PID_DEFAULT_MULTICAST_LOCATOR) then output.length := output.length + offset; end if; 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'reverse_range => '0')) then tmp := to_integer(unsigned(ref.defaultUnicastLocatorList.numLocators)); for i in 0 to tmp-1 loop if (pid = PID_DEFAULT_UNICAST_LOCATOR) then assert (24+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_DEFAULT_UNICAST_LOCATOR) & endian_swap(ref.littleEndian, int(24+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_DEFAULT_UNICAST_LOCATOR) & endian_swap(ref.littleEndian, int(24,PARAMETER_LENGTH_WIDTH)); end if; output.length := output.length + 1; 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; if (pid = PID_DEFAULT_UNICAST_LOCATOR) then output.length := output.length + offset; end if; end loop; end if; -- LEASE DURATION if (ref.leaseDuration /= DEFAULT_PARTICIPANT_LEASE_DURATION or pid = PID_PARTICIPANT_LEASE_DURATION) then if (pid = PID_PARTICIPANT_LEASE_DURATION) then assert (8+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_PARTICIPANT_LEASE_DURATION) & endian_swap(ref.littleEndian, int(8+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_PARTICIPANT_LEASE_DURATION) & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH)); end if; 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; if (pid = PID_PARTICIPANT_LEASE_DURATION) then output.length := output.length + offset; end if; end if; -- AVAILABLE ENDPOINTS if (pid = PID_BUILTIN_ENDPOINT_SET) then assert (4+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_BUILTIN_ENDPOINT_SET) & endian_swap(ref.littleEndian, int(4+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_BUILTIN_ENDPOINT_SET) & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); end if; output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.availableBuiltinEndpoints); output.length := output.length + 1; if (pid = PID_BUILTIN_ENDPOINT_SET) then output.length := output.length + offset; end if; -- BUILTIN ENDPOINT QOS if (ref.builtinEndpointQoS /= DEFAULT_BUILTIN_ENDPOINT_QOS or pid = PID_BUILTIN_ENDPOINT_QOS) then if (pid = PID_BUILTIN_ENDPOINT_QOS) then assert (4+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_BUILTIN_ENDPOINT_QOS) & endian_swap(ref.littleEndian, int(4+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_BUILTIN_ENDPOINT_QOS) & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); end if; output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.builtinEndpointQoS); output.length := output.length + 1; if (pid = PID_BUILTIN_ENDPOINT_QOS) then output.length := output.length + offset; end if; end if; -- MANUAL LIVELINESS COUNT if (pid = PID_PARTICIPANT_MANUAL_LIVELINESS_COUNT) then assert (4+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_PARTICIPANT_MANUAL_LIVELINESS_COUNT) & endian_swap(ref.littleEndian, int(4+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_PARTICIPANT_MANUAL_LIVELINESS_COUNT) & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); end if; output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.manualLivelinessCount); output.length := output.length + 1; if (pid = PID_PARTICIPANT_MANUAL_LIVELINESS_COUNT) then output.length := output.length + offset; end if; end procedure; procedure gen_participant_data( ref : in PARTICIPANT_DATA_TYPE; output : inout TEST_PACKET_TYPE) is begin gen_participant_data(ref, output, PID_PAD, 0); end procedure; function gen_participant_mem_frame (ref : PARTICIPANT_DATA_TYPE) return TEST_PARTICIPANT_MEMORY_FRAME_TYPE is variable ret : TEST_PARTICIPANT_MEMORY_FRAME_TYPE; variable start : natural; variable meta_loc : LOCATOR_TYPE; variable user_loc : LOCATOR_TYPE; begin ret := (others => (addr => 0, data => (others => '0'))); -- Calculate Start Address start := PARTICIPANT_FRAME_SIZE * ref.nr; -- Fetch relevant Locators meta_loc := get_loc (ref, TRUE); user_loc := get_loc (ref, FALSE); for i in 0 to PARTICIPANT_FRAME_SIZE-1 loop ret(i).addr := start + i; case (i) is -- GUID Prefix 1/3 when 1 => ret(i).data := ref.guidPrefix(0); -- GUID Prefix 2/3 when 2 => ret(i).data := ref.guidPrefix(1); -- GUID Prefix 3/3 when 3 => ret(i).data := ref.guidPrefix(2); -- METATRAFFIC IPv4 Address when 4 => ret(i).data := meta_loc.addr(IPv4_ADDRESS_WIDTH-1 downto 0); -- DEFAULT IPv4 Address when 5 => ret(i).data := user_loc.addr(IPv4_ADDRESS_WIDTH-1 downto 0); -- METATRAFFIC & DEFAULT UDP Port when 6 => ret(i).data := meta_loc.portn(UDP_PORT_WIDTH-1 downto 0) & user_loc.portn(UDP_PORT_WIDTH-1 downto 0); -- Lease Duration 1/2 when 9 => ret(i).data := std_logic_vector(ref.leaseDuration(0)); -- Lease Duration 2/2 when 10 => ret(i).data := std_logic_vector(ref.leaseDuration(1)); -- Other Fields Ignored when others => ret(i).data := (others => '-'); end case; end loop; return ret; end function; function gen_writer_endpoint_mem_frame_a (ref : ENDPOINT_DATA_TYPE) return TEST_WRITER_ENDPOINT_MEMORY_FRAME_TYPE_A is variable ret : TEST_WRITER_ENDPOINT_MEMORY_FRAME_TYPE_A; variable start : natural; variable user_loc : LOCATOR_TYPE; begin ret := (others => (addr => 0, data => (others => '0'))); -- Calculate Start Address start := WRITER_ENDPOINT_FRAME_SIZE_A * ref.nr; -- Fetch relevant Locators user_loc := get_loc (ref); for i in 0 to WRITER_ENDPOINT_FRAME_SIZE_A-1 loop ret(i).addr := start + i; case (i) is -- Entity ID when 0 => if (ref.match = MATCH) then ret(i).data := ref.entityId; else ret(i).data := (others => '0'); end if; -- GUID Prefix 1/3 when 1 => if (ref.match = MATCH) then ret(i).data := ref.participant.guidPrefix(0); else ret(i).data := (others => '-'); end if; -- GUID Prefix 2/3 when 2 => if (ref.match = MATCH) then ret(i).data := ref.participant.guidPrefix(1); else ret(i).data := (others => '-'); end if; -- GUID Prefix 3/3 when 3 => if (ref.match = MATCH) then ret(i).data := ref.participant.guidPrefix(2); else ret(i).data := (others => '-'); end if; -- IPv4 Address when 4 => if (ref.match = MATCH) then ret(i).data := user_loc.addr(IPv4_ADDRESS_WIDTH-1 downto 0); else ret(i).data := (others => '-'); end if; -- UDP Port when 5 => if (ref.match = MATCH) then ret(i).data := user_loc.portn(UDP_PORT_WIDTH-1 downto 0) & UDP_PORT_INVALID; else ret(i).data := (others => '-'); end if; -- Lifespan Duration 1/2 when 10 => if (ref.match = MATCH) then ret(i).data := std_logic_vector(ref.lifespan(0)); else ret(i).data := (others => '-'); end if; -- Lifespan Duration 2/2 when 11 => if (ref.match = MATCH) then ret(i).data := std_logic_vector(ref.lifespan(1)); else ret(i).data := (others => '-'); end if; -- Other Fields Ignored when others => ret(i).data := (others => '-'); end case; end loop; return ret; end function; function gen_writer_endpoint_mem_frame_b (ref : ENDPOINT_DATA_TYPE) return TEST_WRITER_ENDPOINT_MEMORY_FRAME_TYPE_B is variable ret : TEST_WRITER_ENDPOINT_MEMORY_FRAME_TYPE_B; variable start : natural; variable user_loc : LOCATOR_TYPE; begin ret := (others => (addr => 0, data => (others => '0'))); -- Calculate Start Address start := WRITER_ENDPOINT_FRAME_SIZE_B * ref.nr; -- Fetch relevant Locators user_loc := get_loc (ref); for i in 0 to WRITER_ENDPOINT_FRAME_SIZE_B-1 loop ret(i).addr := start + i; case (i) is -- Entity ID when 0 => if (ref.match = MATCH) then ret(i).data := ref.entityId; else ret(i).data := (others => '0'); end if; -- GUID Prefix 1/3 when 1 => if (ref.match = MATCH) then ret(i).data := ref.participant.guidPrefix(0); else ret(i).data := (others => '-'); end if; -- GUID Prefix 2/3 when 2 => if (ref.match = MATCH) then ret(i).data := ref.participant.guidPrefix(1); else ret(i).data := (others => '-'); end if; -- GUID Prefix 3/3 when 3 => if (ref.match = MATCH) then ret(i).data := ref.participant.guidPrefix(2); else ret(i).data := (others => '-'); end if; -- Lifespan Duration 1/2 when 8 => if (ref.match = MATCH) then ret(i).data := std_logic_vector(ref.lifespan(0)); else ret(i).data := (others => '-'); end if; -- Lifespan Duration 2/2 when 9 => if (ref.match = MATCH) then ret(i).data := std_logic_vector(ref.lifespan(1)); else ret(i).data := (others => '-'); end if; -- Other Fields Ignored when others => ret(i).data := (others => '-'); end case; end loop; return ret; end function; function gen_reader_endpoint_mem_frame_a (ref : ENDPOINT_DATA_TYPE) return TEST_READER_ENDPOINT_MEMORY_FRAME_TYPE_A is variable ret : TEST_READER_ENDPOINT_MEMORY_FRAME_TYPE_A; variable start : natural; variable user_loc : LOCATOR_TYPE; begin ret := (others => (addr => 0, data => (others => '0'))); -- Calculate Start Address start := READER_ENDPOINT_FRAME_SIZE_A * ref.nr; -- Fetch relevant Locators user_loc := get_loc (ref); for i in 0 to READER_ENDPOINT_FRAME_SIZE_A-1 loop ret(i).addr := start + i; case (i) is -- Entity ID when 0 => if (ref.match = MATCH) then ret(i).data := ref.entityId; else ret(i).data := (others => '0'); end if; -- GUID Prefix 1/3 when 1 => if (ref.match = MATCH) then ret(i).data := ref.participant.guidPrefix(0); else ret(i).data := (others => '-'); end if; -- GUID Prefix 2/3 when 2 => if (ref.match = MATCH) then ret(i).data := ref.participant.guidPrefix(1); else ret(i).data := (others => '-'); end if; -- GUID Prefix 3/3 when 3 => if (ref.match = MATCH) then ret(i).data := ref.participant.guidPrefix(2); else ret(i).data := (others => '-'); end if; -- IPv4 Address when 4 => if (ref.match = MATCH) then ret(i).data := user_loc.addr(IPv4_ADDRESS_WIDTH-1 downto 0); else ret(i).data := (others => '-'); end if; -- UDP Port when 5 => if (ref.match = MATCH) then ret(i).data := user_loc.portn(UDP_PORT_WIDTH-1 downto 0) & UDP_PORT_INVALID; ret(i).data(READER_EXPECTS_INLINE_QOS_FLAG) := ref.expectsInlineQoS(0); ret(i).data(READER_EXPECTS_HISTORICAL_DATA_FLAG) := '1' when (ref.durability /= VOLATILE_DURABILITY_QOS) else '0'; ret(i).data(READER_IS_BEST_EFFORT_FLAG) := '1' when (ref.reliability = BEST_EFFORT_RELIABILITY_QOS) else '0'; else ret(i).data := (others => '-'); end if; -- Other Fields Ignored when others => ret(i).data := (others => '-'); end case; end loop; return ret; end function; function gen_reader_endpoint_mem_frame_b (ref : ENDPOINT_DATA_TYPE) return TEST_READER_ENDPOINT_MEMORY_FRAME_TYPE_B is variable ret : TEST_READER_ENDPOINT_MEMORY_FRAME_TYPE_B; variable start : natural; variable user_loc : LOCATOR_TYPE; begin ret := (others => (addr => 0, data => (others => '0'))); -- Calculate Start Address start := READER_ENDPOINT_FRAME_SIZE_B * ref.nr; -- Fetch relevant Locators user_loc := get_loc (ref); for i in 0 to READER_ENDPOINT_FRAME_SIZE_B-1 loop ret(i).addr := start + i; case (i) is -- Entity ID when 0 => if (ref.match = MATCH) then ret(i).data := ref.entityId; else ret(i).data := (others => '0'); end if; -- GUID Prefix 1/3 when 1 => if (ref.match = MATCH) then ret(i).data := ref.participant.guidPrefix(0); else ret(i).data := (others => '-'); end if; -- GUID Prefix 2/3 when 2 => if (ref.match = MATCH) then ret(i).data := ref.participant.guidPrefix(1); else ret(i).data := (others => '-'); end if; -- GUID Prefix 3/3 when 3 => if (ref.match = MATCH) then ret(i).data := ref.participant.guidPrefix(2); else ret(i).data := (others => '-'); end if; -- IPv4 Address when 4 => if (ref.match = MATCH) then ret(i).data := user_loc.addr(IPv4_ADDRESS_WIDTH-1 downto 0); else ret(i).data := (others => '-'); end if; -- UDP Port when 5 => if (ref.match = MATCH) then ret(i).data := user_loc.portn(UDP_PORT_WIDTH-1 downto 0) & UDP_PORT_INVALID; ret(i).data(READER_EXPECTS_INLINE_QOS_FLAG) := ref.expectsInlineQoS(0); ret(i).data(READER_EXPECTS_HISTORICAL_DATA_FLAG) := '1' when (ref.durability /= VOLATILE_DURABILITY_QOS) else '0'; ret(i).data(READER_IS_BEST_EFFORT_FLAG) := '1' when (ref.reliability = BEST_EFFORT_RELIABILITY_QOS) else '0'; else ret(i).data := (others => '-'); end if; -- Other Fields Ignored when others => ret(i).data := (others => '-'); end case; end loop; return ret; end function; procedure gen_participant_match_frame( ref : in PARTICIPANT_DATA_TYPE; output : inout TEST_PACKET_TYPE) is begin -- OPCODE case (ref.match) is when MATCH => report "No Endpoint Frame generated on Participant match" severity WARNING; return; when UNMATCH => output.data(output.length) := EMO_PARTICIPANT_UNMATCH; output.length := output.length + 1; when others => null; end case; -- 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; -- Mark Last Word output.last(output.length-1) := '1'; end procedure; procedure gen_liveliness_update_frame( ref : in PARTICIPANT_DATA_TYPE; output : inout TEST_PACKET_TYPE) is begin -- OPCODE output.data(output.length) := EMO_LIVELINESS_UPDATE; 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; -- Mark Last Word output.last(output.length-1) := '1'; end procedure; procedure gen_endpoint_data( ref : in ENDPOINT_DATA_TYPE; output : inout TEST_PACKET_TYPE; pid : in std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0); offset : in integer) 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 if (pid = PID_ENDPOINT_GUID) then assert (16+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_ENDPOINT_GUID) & endian_swap(ref.littleEndian, int(16+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_ENDPOINT_GUID) & endian_swap(ref.littleEndian, int(16,PARAMETER_LENGTH_WIDTH)); end if; 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; if (pid = PID_ENDPOINT_GUID) then output.length := output.length + offset; end if; -- EXPECTS IN-LINE QOS if (ref.reader) then if (ref.expectsInlineQoS(0) /= DEFAULT_EXPECTS_INLINE_QOS or pid = PID_EXPECTS_INLINE_QOS) then if (pid = PID_EXPECTS_INLINE_QOS) then assert (4+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_EXPECTS_INLINE_QOS) & endian_swap(ref.littleEndian, int(4+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_EXPECTS_INLINE_QOS) & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); end if; 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; if (pid = PID_EXPECTS_INLINE_QOS) then output.length := output.length + offset; end if; end if; end if; -- TOPIC NAME tmp := string_len(ref.topic_name); if (pid = PID_TOPIC_NAME) then assert (((round_div(tmp,4)+1)*4)+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_TOPIC_NAME) & endian_swap(ref.littleEndian, int(((round_div(tmp,4)+1)*4)+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_TOPIC_NAME) & endian_swap(ref.littleEndian, int((round_div(tmp,4)+1)*4,PARAMETER_LENGTH_WIDTH)); end if; 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; if (pid = PID_TOPIC_NAME) then output.length := output.length + offset; end if; -- TYPE NAME tmp := string_len(ref.type_name); if (pid = PID_TYPE_NAME) then assert (((round_div(tmp,4)+1)*4)+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_TYPE_NAME) & endian_swap(ref.littleEndian, int(((round_div(tmp,4)+1)*4)+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_TYPE_NAME) & endian_swap(ref.littleEndian, int((round_div(tmp,4)+1)*4,PARAMETER_LENGTH_WIDTH)); end if; 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; if (pid = PID_TYPE_NAME) then output.length := output.length + offset; end if; -- DURABILITY if (ref.durability /= DEFAULT_DURABILITY_QOS or pid = PID_DURABILITY) then if (pid = PID_DURABILITY) then assert (4+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_DURABILITY) & endian_swap(ref.littleEndian, int(4+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_DURABILITY) & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); end if; output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.durability); output.length := output.length + 1; if (pid = PID_DURABILITY) then output.length := output.length + offset; end if; 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 or pid = PID_DURABILITY_SERVICE) then if (pid = PID_DURABILITY_SERVICE) then assert (28+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_DURABILITY_SERVICE) & endian_swap(ref.littleEndian, int(28+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_DURABILITY_SERVICE) & endian_swap(ref.littleEndian, int(28,PARAMETER_LENGTH_WIDTH)); end if; 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; if (pid = PID_DURABILITY_SERVICE) then output.length := output.length + offset; end if; 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) or pid = PID_PRESENTATION) then if (pid = PID_PRESENTATION) then assert (8+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_PRESENTATION) & endian_swap(ref.littleEndian, int(8+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_PRESENTATION) & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH)); end if; 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) & (0 to 15 => '0'); output.length := output.length + 1; if (pid = PID_PRESENTATION) then output.length := output.length + offset; end if; end if; -- DEADLINE if (ref.deadline /= DEFAULT_DEADLINE_QOS or pid = PID_DEADLINE) then if (pid = PID_DEADLINE) then assert (8+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_DEADLINE) & endian_swap(ref.littleEndian, int(8+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_DEADLINE) & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH)); end if; 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; if (pid = PID_DEADLINE) then output.length := output.length + offset; end if; end if; -- LATENCY BUDGET if (ref.latency_budget /= DEFAULT_LATENCY_BUDGET_QOS or pid = PID_LATENCY_BUDGET) then if (pid = PID_LATENCY_BUDGET) then assert (8+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_LATENCY_BUDGET) & endian_swap(ref.littleEndian, int(8+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_LATENCY_BUDGET) & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH)); end if; output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.latency_budget(0))); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.latency_budget(1))); output.length := output.length + 1; if (pid = PID_LATENCY_BUDGET) then output.length := output.length + offset; end if; end if; -- OWNERSHIP if (ref.ownership /= DEFAULT_OWNERSHIP_QOS or pid = PID_OWNERSHIP) then if (pid = PID_OWNERSHIP) then assert (4+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_OWNERSHIP) & endian_swap(ref.littleEndian, int(4+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_OWNERSHIP) & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); end if; output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.ownership); output.length := output.length + 1; if (pid = PID_OWNERSHIP) then output.length := output.length + offset; end if; end if; -- OWNERSHIP STRENGTH if (not ref.reader) then if (ref.ownership_strength /= DEFAULT_OWNERSHIP_STRENGTH_QOS or pid = PID_OWNERSHIP_STRENGTH) then if (pid = PID_OWNERSHIP_STRENGTH) then assert (4+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_OWNERSHIP_STRENGTH) & endian_swap(ref.littleEndian, int(4+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_OWNERSHIP_STRENGTH) & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); end if; output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.ownership_strength); output.length := output.length + 1; if (pid = PID_OWNERSHIP_STRENGTH) then output.length := output.length + offset; end if; end if; end if; -- LIVELINESS if (ref.liveliness /= DEFAULT_LIVELINESS_QOS or ref.leaseDuration /= DEFAULT_LEASE_DURATION or pid = PID_LIVELINESS) then if (pid = PID_LIVELINESS) then assert (12+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_LIVELINESS) & endian_swap(ref.littleEndian, int(12+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_LIVELINESS) & endian_swap(ref.littleEndian, int(12,PARAMETER_LENGTH_WIDTH)); end if; 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; if (pid = PID_LIVELINESS) then output.length := output.length + offset; end if; end if; -- TIME BASED FILTER if (ref.time_based_filter /= DEFAULT_TIME_BASED_FILTER_QOS or pid = PID_TIME_BASED_FILTER) then if (pid = PID_TIME_BASED_FILTER) then assert (8+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_TIME_BASED_FILTER) & endian_swap(ref.littleEndian, int(8+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_TIME_BASED_FILTER) & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH)); end if; 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; if (pid = PID_TIME_BASED_FILTER) then output.length := output.length + offset; end if; end if; -- RELIABILITY if ((ref.reader and ref.reliability /= DEFAULT_RELIABILITY_QOS_R) or ((not ref.reader) and ref.reliability /= DEFAULT_RELIABILITY_QOS_W) or ref.max_blocking_time /= DEFAULT_MAX_BLOCKING_TIME or pid = PID_RELIABILITY) then if (pid = PID_RELIABILITY) then assert (12+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_RELIABILITY) & endian_swap(ref.littleEndian, int(12+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_RELIABILITY) & endian_swap(ref.littleEndian, int(12,PARAMETER_LENGTH_WIDTH)); end if; 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; if (pid = PID_RELIABILITY) then output.length := output.length + offset; end if; end if; -- LIFESPAN if (ref.lifespan /= DEFAULT_LIFESPAN_QOS or pid = PID_LIFESPAN) then if (pid = PID_LIFESPAN) then assert (8+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_LIFESPAN) & endian_swap(ref.littleEndian, int(8+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_LIFESPAN) & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH)); end if; 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; if (pid = PID_LIFESPAN) then output.length := output.length + offset; end if; end if; -- DESTINATION ORDER if (ref.destination_order /= DEFAULT_DESTINATION_ORDER_QOS or pid = PID_DESTINATION_ORDER) then if (pid = PID_DESTINATION_ORDER) then assert (4+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_DESTINATION_ORDER) & endian_swap(ref.littleEndian, int(4+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_DESTINATION_ORDER) & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); end if; output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.destination_order); output.length := output.length + 1; if (pid = PID_DESTINATION_ORDER) then output.length := output.length + offset; end if; 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 if (pid = PID_MULTICAST_LOCATOR) then assert (24+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_MULTICAST_LOCATOR) & endian_swap(ref.littleEndian, int(24+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_MULTICAST_LOCATOR) & endian_swap(ref.littleEndian, int(24,PARAMETER_LENGTH_WIDTH)); end if; 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; if (pid = PID_MULTICAST_LOCATOR) then output.length := output.length + offset; end if; end loop; 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 if (pid = PID_UNICAST_LOCATOR) then assert (24+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_UNICAST_LOCATOR) & endian_swap(ref.littleEndian, int(24+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_UNICAST_LOCATOR) & endian_swap(ref.littleEndian, int(24,PARAMETER_LENGTH_WIDTH)); end if; 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; if (pid = PID_UNICAST_LOCATOR) then output.length := output.length + offset; end if; end loop; end if; -- USER DATA tmp := string_len(ref.user_data); if (tmp > 1) then output.data(output.length) := endian_swap(ref.littleEndian, 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) := endian_swap(ref.littleEndian, 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) := endian_swap(ref.littleEndian, 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 (not ref.reader) then -- NOTE: PID_DATA_MAX_SIZE_SERIALIZED has no default value, but we use the value zero as default for not sending the parameter if (unsigned(ref.max_size_serialized) /= 0) then if (pid = PID_DATA_MAX_SIZE_SERIALIZED) then assert (4+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(ref.littleEndian, PID_DATA_MAX_SIZE_SERIALIZED) & endian_swap(ref.littleEndian, int(4+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(ref.littleEndian, PID_DATA_MAX_SIZE_SERIALIZED) & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); end if; output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.max_size_serialized); output.length := output.length + 1; if (pid = PID_DATA_MAX_SIZE_SERIALIZED) then output.length := output.length + offset; end if; end if; end if; end procedure; procedure gen_endpoint_data( ref : in ENDPOINT_DATA_TYPE; output : inout TEST_PACKET_TYPE) is begin gen_endpoint_data(ref, output, PID_PAD, 0); end procedure; procedure gen_endpoint_match_frame( ref : in ENDPOINT_DATA_TYPE; output : inout TEST_PACKET_TYPE) is variable loc : LOCATOR_TYPE; begin -- Fetch relevant Locator loc := get_loc(ref); -- OPCODE case (ref.match) is when MATCH => output.data(output.length) := EMO_ENDPOINT_MATCH; output.length := output.length + 1; when UNMATCH => output.data(output.length) := EMO_ENDPOINT_UNMATCH; output.length := output.length + 1; when others => null; end case; -- GUID Prefix 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; -- ENTITY ID output.data(output.length) := ref.entityId; output.length := output.length + 1; if (ref.match = MATCH) then -- IPv4 Address output.data(output.length) := loc.addr(IPv4_ADDRESS_WIDTH-1 downto 0); output.length := output.length + 1; -- Port & expectsInlineQoS output.data(output.length) := (others => '0'); output.data(output.length)(WORD_WIDTH-1 downto UDP_PORT_WIDTH) := loc.portn(UDP_PORT_WIDTH-1 downto 0); if (ref.reader) then output.data(output.length)(READER_EXPECTS_INLINE_QOS_FLAG) := ref.expectsInlineQoS(0); output.data(output.length)(READER_EXPECTS_HISTORICAL_DATA_FLAG) := '0' when (ref.durability = VOLATILE_DURABILITY_QOS) else '1'; output.data(output.length)(READER_IS_BEST_EFFORT_FLAG) := '1' when (ref.reliability = BEST_EFFORT_RELIABILITY_QOS) else '0'; end if; output.length := output.length + 1; -- Lifespan Duration if (not ref.reader) then output.data(output.length) := std_logic_vector(ref.lifespan(0)); output.length := output.length + 1; output.data(output.length) := std_logic_vector(ref.lifespan(1)); output.length := output.length + 1; end if; end if; -- Mark Last Word output.last(output.length-1) := '1'; end procedure; procedure gen_sentinel(littleEndian : in std_logic; output : inout TEST_PACKET_TYPE) is begin output.data(output.length) := endian_swap(littleEndian, PID_SENTINEL) & (0 to PARAMETER_LENGTH_WIDTH-1 => '0'); output.length := output.length + 1; end procedure; procedure gen_sentinel(output : inout TEST_PACKET_TYPE) is begin gen_sentinel('0', output); end procedure; procedure gen_parameter(pid : in std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0); data : in TEST_PACKET_TYPE; littleEndian : in std_logic; output : inout TEST_PACKET_TYPE) is begin -- PARAMETER HEADER output.data(output.length) := endian_swap(littleEndian, pid) & endian_swap(littleEndian, int(data.length*4, PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; -- DATA for i in 0 to data.length-1 loop output.data(output.length) := data.data(i); output.length := output.length + 1; end loop; end procedure; procedure gen_inline_qos(ref : in CACHE_CHANGE_TYPE; endpoint : in ENDPOINT_DATA_TYPE; expectsInlineQoS : in boolean; littleEndian : in std_logic; output : inout TEST_PACKET_TYPE; pid : in std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0); offset : in integer) is variable tmp : natural := 0; begin -- *INLINE-ONLY* -- Key Hash if (ref.instance /= HANDLE_NIL or pid = PID_KEY_HASH) then if (pid = PID_KEY_HASH) then assert (16+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(littleEndian, PID_KEY_HASH) & endian_swap(littleEndian, int(16+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(littleEndian, PID_KEY_HASH) & endian_swap(littleEndian, int(16,PARAMETER_LENGTH_WIDTH)); end if; output.length := output.length + 1; output.data(output.length) := ref.instance(0); output.length := output.length + 1; output.data(output.length) := ref.instance(1); output.length := output.length + 1; output.data(output.length) := ref.instance(2); output.length := output.length + 1; output.data(output.length) := ref.instance(3); output.length := output.length + 1; if (pid = PID_KEY_HASH) then output.length := output.length + offset; end if; end if; -- Status Info if (ref.kind /= ALIVE or pid = PID_STATUS_INFO) then if (pid = PID_STATUS_INFO) then assert (4+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(littleEndian, PID_STATUS_INFO) & endian_swap(littleEndian, int(4+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(littleEndian, PID_STATUS_INFO) & endian_swap(littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); end if; output.length := output.length + 1; output.data(output.length) := (others => '0'); case (ref.kind) is when ALIVE_FILTERED => output.data(output.length)(SSI_FILTERED_FLAG) := '1'; when NOT_ALIVE_DISPOSED => output.data(output.length)(SSI_DISPOSED_FLAG) := '1'; when NOT_ALIVE_UNREGISTERED => output.data(output.length)(SSI_UNREGISTERED_FLAG) := '1'; when others => null; end case; output.length := output.length + 1; if (pid = PID_STATUS_INFO) then output.length := output.length + offset; end if; end if; -- ENDPOINT DATA QOS if (expectsInlineQoS) then -- TOPIC NAME tmp := string_len(endpoint.topic_name); if (pid = PID_TOPIC_NAME) then assert (((round_div(tmp,4)+1)*4)+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(littleEndian, PID_TOPIC_NAME) & endian_swap(littleEndian, int(((round_div(tmp,4)+1)*4)+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(littleEndian, PID_TOPIC_NAME) & endian_swap(littleEndian, int((round_div(tmp,4)+1)*4,PARAMETER_LENGTH_WIDTH)); end if; output.length := output.length + 1; output.data(output.length) := endian_swap(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) := endpoint.topic_name(i); output.length := output.length + 1; end loop; if (pid = PID_TOPIC_NAME) then output.length := output.length + offset; end if; -- DURABILITY if (endpoint.durability /= DEFAULT_DURABILITY_QOS or pid = PID_DURABILITY) then if (pid = PID_DURABILITY) then assert (4+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(littleEndian, PID_DURABILITY) & endian_swap(littleEndian, int(4+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(littleEndian, PID_DURABILITY) & endian_swap(littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); end if; output.length := output.length + 1; output.data(output.length) := endian_swap(littleEndian, endpoint.durability); output.length := output.length + 1; if (pid = PID_DURABILITY) then output.length := output.length + offset; end if; end if; -- PRESENTATION if (endpoint.presentation /= DEFAULT_PRESENTATION_QOS or endpoint.coherent_access(0) /= boolean_to_std_logic(DEFAULT_COHERENT_ACCESS) or endpoint.ordered_access(0) /= boolean_to_std_logic(DEFAULT_ORDERED_ACCESS) or pid = PID_PRESENTATION) then if (pid = PID_PRESENTATION) then assert (8+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(littleEndian, PID_PRESENTATION) & endian_swap(littleEndian, int(8+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(littleEndian, PID_PRESENTATION) & endian_swap(littleEndian, int(8,PARAMETER_LENGTH_WIDTH)); end if; output.length := output.length + 1; output.data(output.length) := endian_swap(littleEndian, endpoint.presentation); output.length := output.length + 1; output.data(output.length) := endian_swap(littleEndian, endpoint.coherent_access) & endian_swap(littleEndian, endpoint.ordered_access) & (0 to 15 => '0'); output.length := output.length + 1; if (pid = PID_PRESENTATION) then output.length := output.length + offset; end if; end if; -- DEADLINE if (endpoint.deadline /= DEFAULT_DEADLINE_QOS or pid = PID_DEADLINE) then if (pid = PID_DEADLINE) then assert (8+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(littleEndian, PID_DEADLINE) & endian_swap(littleEndian, int(8+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(littleEndian, PID_DEADLINE) & endian_swap(littleEndian, int(8,PARAMETER_LENGTH_WIDTH)); end if; output.length := output.length + 1; output.data(output.length) := endian_swap(littleEndian, std_logic_vector(endpoint.deadline(0))); output.length := output.length + 1; output.data(output.length) := endian_swap(littleEndian, std_logic_vector(endpoint.deadline(1))); output.length := output.length + 1; if (pid = PID_DEADLINE) then output.length := output.length + offset; end if; end if; -- LATENCY BUDGET if (endpoint.latency_budget /= DEFAULT_LATENCY_BUDGET_QOS or pid = PID_LATENCY_BUDGET) then if (pid = PID_LATENCY_BUDGET) then assert (8+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(littleEndian, PID_LATENCY_BUDGET) & endian_swap(littleEndian, int(8+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(littleEndian, PID_LATENCY_BUDGET) & endian_swap(littleEndian, int(8,PARAMETER_LENGTH_WIDTH)); end if; output.length := output.length + 1; output.data(output.length) := endian_swap(littleEndian, std_logic_vector(endpoint.latency_budget(0))); output.length := output.length + 1; output.data(output.length) := endian_swap(littleEndian, std_logic_vector(endpoint.latency_budget(1))); output.length := output.length + 1; if (pid = PID_LATENCY_BUDGET) then output.length := output.length + offset; end if; end if; -- OWNERSHIP if (endpoint.ownership /= DEFAULT_OWNERSHIP_QOS or pid = PID_OWNERSHIP) then if (pid = PID_OWNERSHIP) then assert (4+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(littleEndian, PID_OWNERSHIP) & endian_swap(littleEndian, int(4+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(littleEndian, PID_OWNERSHIP) & endian_swap(littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); end if; output.length := output.length + 1; output.data(output.length) := endian_swap(littleEndian, endpoint.ownership); output.length := output.length + 1; if (pid = PID_OWNERSHIP) then output.length := output.length + offset; end if; end if; -- OWNERSHIP STRENGTH if (endpoint.ownership_strength /= DEFAULT_OWNERSHIP_STRENGTH_QOS or pid = PID_OWNERSHIP_STRENGTH) then if (pid = PID_OWNERSHIP_STRENGTH) then assert (4+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(littleEndian, PID_OWNERSHIP_STRENGTH) & endian_swap(littleEndian, int(4+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(littleEndian, PID_OWNERSHIP_STRENGTH) & endian_swap(littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); end if; output.length := output.length + 1; output.data(output.length) := endian_swap(littleEndian, endpoint.ownership_strength); output.length := output.length + 1; if (pid = PID_OWNERSHIP_STRENGTH) then output.length := output.length + offset; end if; end if; -- LIVELINESS if (endpoint.liveliness /= DEFAULT_LIVELINESS_QOS or endpoint.leaseDuration /= DEFAULT_LEASE_DURATION or pid = PID_LIVELINESS) then if (pid = PID_LIVELINESS) then assert (12+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(littleEndian, PID_LIVELINESS) & endian_swap(littleEndian, int(12+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(littleEndian, PID_LIVELINESS) & endian_swap(littleEndian, int(12,PARAMETER_LENGTH_WIDTH)); end if; output.length := output.length + 1; output.data(output.length) := endian_swap(littleEndian, endpoint.liveliness); output.length := output.length + 1; output.data(output.length) := endian_swap(littleEndian, std_logic_vector(endpoint.leaseDuration(0))); output.length := output.length + 1; output.data(output.length) := endian_swap(littleEndian, std_logic_vector(endpoint.leaseDuration(1))); output.length := output.length + 1; if (pid = PID_LIVELINESS) then output.length := output.length + offset; end if; end if; -- RELIABILITY if (endpoint.reliability /= DEFAULT_RELIABILITY_QOS_W or endpoint.max_blocking_time /= DEFAULT_MAX_BLOCKING_TIME or pid = PID_RELIABILITY) then if (pid = PID_RELIABILITY) then assert (12+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(littleEndian, PID_RELIABILITY) & endian_swap(littleEndian, int(12+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(littleEndian, PID_RELIABILITY) & endian_swap(littleEndian, int(12,PARAMETER_LENGTH_WIDTH)); end if; output.length := output.length + 1; output.data(output.length) := endian_swap(littleEndian, endpoint.reliability); output.length := output.length + 1; output.data(output.length) := endian_swap(littleEndian, std_logic_vector(endpoint.max_blocking_time(0))); output.length := output.length + 1; output.data(output.length) := endian_swap(littleEndian, std_logic_vector(endpoint.max_blocking_time(1))); output.length := output.length + 1; if (pid = PID_RELIABILITY) then output.length := output.length + offset; end if; end if; -- LIFESPAN if (endpoint.lifespan /= DEFAULT_LIFESPAN_QOS or pid = PID_LIFESPAN) then if (pid = PID_LIFESPAN) then assert (8+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(littleEndian, PID_LIFESPAN) & endian_swap(littleEndian, int(8+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(littleEndian, PID_LIFESPAN) & endian_swap(littleEndian, int(8,PARAMETER_LENGTH_WIDTH)); end if; output.length := output.length + 1; output.data(output.length) := endian_swap(littleEndian, std_logic_vector(endpoint.lifespan(0))); output.length := output.length + 1; output.data(output.length) := endian_swap(littleEndian, std_logic_vector(endpoint.lifespan(1))); output.length := output.length + 1; if (pid = PID_LIFESPAN) then output.length := output.length + offset; end if; end if; -- DESTINATION ORDER if (endpoint.destination_order /= DEFAULT_DESTINATION_ORDER_QOS or pid = PID_DESTINATION_ORDER) then if (pid = PID_DESTINATION_ORDER) then assert (4+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; output.data(output.length) := endian_swap(littleEndian, PID_DESTINATION_ORDER) & endian_swap(littleEndian, int(4+(offset*4),PARAMETER_LENGTH_WIDTH)); else output.data(output.length) := endian_swap(littleEndian, PID_DESTINATION_ORDER) & endian_swap(littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); end if; output.length := output.length + 1; output.data(output.length) := endian_swap(littleEndian, endpoint.destination_order); output.length := output.length + 1; if (pid = PID_DESTINATION_ORDER) then output.length := output.length + offset; end if; end if; end if; end procedure; procedure gen_inline_qos(ref : in CACHE_CHANGE_TYPE; endpoint : in ENDPOINT_DATA_TYPE; expectsInlineQoS : in boolean; littleEndian : in std_logic; output : inout TEST_PACKET_TYPE) is begin gen_inline_qos(ref,endpoint,expectsInlineQoS,littleEndian,output,PID_PAD,0); end procedure; procedure gen_inline_qos(ref : in CACHE_CHANGE_TYPE; output : inout TEST_PACKET_TYPE) is begin gen_inline_qos(ref,DEFAULT_ENDPOINT_DATA,FALSE,'0',output,PID_PAD,0); end procedure; procedure gen_inline_qos(status : in CACHE_CHANGE_KIND_TYPE; key : in INSTANCE_HANDLE_TYPE; output : inout TEST_PACKET_TYPE; pid : in std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0); offset : in integer) is variable tmp : CACHE_CHANGE_TYPE := DEFAULT_CACHE_CHANGE; begin tmp.kind := status; tmp.instance := key; gen_inline_qos(tmp,DEFAULT_ENDPOINT_DATA,FALSE,'0',output,pid,offset); end procedure; procedure gen_inline_qos(status : in CACHE_CHANGE_KIND_TYPE; key : in INSTANCE_HANDLE_TYPE; output : inout TEST_PACKET_TYPE) is begin gen_inline_qos(status,key,output,PID_PAD,0); end procedure; function test_memory_match (A,B : TEST_MEMORY_TYPE) return boolean is begin if (A'length /= B'length) then return FALSE; end if; for i in 0 to A'length loop if (A(i).addr /= B(i).addr or (A(i).data ?/= B(i).data) = '1') then return FALSE; end if; end loop; return TRUE; end function; function gen_endpoint(id : natural) return ENDPOINT_DATA_TYPE is variable ret : ENDPOINT_DATA_TYPE := DEFAULT_ENDPOINT_DATA; begin assert (id <= NUM_ENDPOINTS-1) report "ID outside bounds." severity FAILURE; ret.reader := TRUE when (id < NUM_READERS) else FALSE; ret.topic_name := ENDPOINT_TOPIC(id); ret.type_name := ENDPOINT_TYPE(id); ret.durability := ENDPOINT_CONFIG(id).DURABILITY_QOS; ret.durability_service_cleanup_delay := ENDPOINT_CONFIG(id).DURABILITY_SERVICE_CLEANUP_DELAY; ret.durability_service_history := ENDPOINT_CONFIG(id).DURABILITY_SERVICE_HISTORY; ret.durability_service_history_depth := ENDPOINT_CONFIG(id).DURABILITY_SERVICE_HISTORY_DEPTH; ret.durability_service_max_samples := ENDPOINT_CONFIG(id).DURABILITY_SERVICE_MAX_SAMPLES; ret.durability_service_max_instances := ENDPOINT_CONFIG(id).DURABILITY_SERVICE_MAX_INSTANCES; ret.durability_service_max_samples_per_instances := ENDPOINT_CONFIG(id).DURABILITY_SERVICE_MAX_SAMPLES_PER_INSTANCE; ret.presentation := ENDPOINT_CONFIG(id).PRESENTATION_QOS; ret.coherent_access(0) := boolean_to_std_logic(ENDPOINT_CONFIG(id).COHERENT_ACCESS); ret.ordered_access(0) := boolean_to_std_logic(ENDPOINT_CONFIG(id).ORDERED_ACCESS); ret.deadline := ENDPOINT_CONFIG(id).DEADLINE_QOS; ret.latency_budget := ENDPOINT_CONFIG(id).LATENCY_BUDGET_QOS; ret.ownership := ENDPOINT_CONFIG(id).OWNERSHIP_QOS; ret.ownership_strength := ENDPOINT_CONFIG(id).OWNERSHIP_STRENGTH_QOS; ret.liveliness := ENDPOINT_CONFIG(id).LIVELINESS_QOS; ret.leaseDuration := ENDPOINT_CONFIG(id).LEASE_DURATION; ret.time_based_filter := ENDPOINT_CONFIG(id).TIME_BASED_FILTER_QOS; ret.reliability := ENDPOINT_CONFIG(id).RELIABILITY_QOS; ret.max_blocking_time := ENDPOINT_CONFIG(id).MAX_BLOCKING_TIME; ret.lifespan := ENDPOINT_CONFIG(id).LIFESPAN_QOS; ret.destination_order := ENDPOINT_CONFIG(id).DESTINATION_ORDER_QOS; ret.expectsInlineQoS(0) := DEFAULT_EXPECTS_INLINE_QOS when (id < NUM_READERS) else '0'; ret.participant := THIS_PARTICIPANT_DATA; ret.entityId := ENTITYID(id); ret.nr := id; return ret; end function; function gen_endpoint_array(readers : boolean) return ENDPOINT_DATA_ARRAY_TYPE is variable ret_readers : ENDPOINT_DATA_ARRAY_TYPE(0 to NUM_READERS-1) := (others => DEFAULT_ENDPOINT_DATA); variable ret_writers : ENDPOINT_DATA_ARRAY_TYPE(0 to NUM_WRITERS-1) := (others => DEFAULT_ENDPOINT_DATA); begin if (readers) then for i in 0 to NUM_READERS-1 loop ret_readers(i) := gen_endpoint(i); end loop; return ret_readers; else for i in NUM_READERS to NUM_ENDPOINTS-1 loop ret_writers(i-NUM_READERS) := gen_endpoint(i); end loop; return ret_writers; end if; end function; function to_string (input : TEST_MEMORY_TYPE) return string is begin return "length: " & integer'image(input'length) & ", start_addr: " & integer'image(input(0).addr) & "end_addr: " & integer'image(input(input'length-1).addr); end function; function to_string1 (input : std_logic_vector) return string is begin return "wr: " & to_string(input(0 to NUM_ENDPOINTS-1)) & ", last_word: " & to_string(input(NUM_ENDPOINTS)) & ", data: " & to_hstring(input(NUM_ENDPOINTS+1 to input'length-1)); end function; procedure add_instance(inst : in INSTANCE_HANDLE_TYPE; istate : in std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); mem : inout DDS_READER_MEM_TYPE) is variable ind : natural := 0; begin -- Find Position ind := mem.ilen; for i in 0 to mem.ilen-1 loop if (to_unsigned(inst) < to_unsigned(mem.inst(i).inst)) then ind := i; exit; end if; end loop; -- Move elements to make Space for i in mem.ilen-1 downto ind loop mem.inst(i+1) := mem.inst(i); end loop; -- Insert at desired index mem.inst(ind) := DEFAULT_INSTANCE_CACHE_TYPE; mem.inst(ind).inst := inst; mem.inst(ind).istate := istate; mem.ilen := mem.ilen + 1; end procedure; function to_sample(cc : CACHE_CHANGE_TYPE; istate : std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0)) return SAMPLE_TYPE is variable ret : SAMPLE_TYPE := DEFAULT_SAMPLE; begin ret.inst := cc.instance; if (not cc.serialized_key) then ret.data := cc.payload; end if; ret.ts := cc.src_timestamp; ret.istate := istate; return ret; end function; procedure change_istate(inst : in INSTANCE_HANDLE_TYPE; istate : in std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); mem : inout DDS_READER_MEM_TYPE) is begin -- Check Instance State for i in 0 to max(mem.ilen-1,0) loop -- Instance Found if (inst = mem.inst(i).inst) then case (istate) is when ALIVE_INSTANCE_STATE => case (mem.inst(i).istate) is when NOT_ALIVE_DISPOSED_INSTANCE_STATE => mem.inst(i).dis_gen_cnt := mem.inst(i).dis_gen_cnt + 1; mem.inst(i).istate := ALIVE_INSTANCE_STATE; mem.inst(i).vstate := NEW_VIEW_STATE; when NOT_ALIVE_NO_WRITERS_INSTANCE_STATE => mem.inst(i).no_w_gen_cnt := mem.inst(i).no_w_gen_cnt + 1; mem.inst(i).istate := ALIVE_INSTANCE_STATE; mem.inst(i).vstate := NEW_VIEW_STATE; when others => null; end case; when NOT_ALIVE_DISPOSED_INSTANCE_STATE => case (mem.inst(i).istate) is when ALIVE_INSTANCE_STATE => mem.inst(i).istate := NOT_ALIVE_DISPOSED_INSTANCE_STATE; when NOT_ALIVE_NO_WRITERS_INSTANCE_STATE => mem.inst(i).istate := NOT_ALIVE_DISPOSED_INSTANCE_STATE; mem.inst(i).no_w_gen_cnt := mem.inst(i).no_w_gen_cnt + 1; mem.inst(i).vstate := NEW_VIEW_STATE; when others => null; end case; when NOT_ALIVE_NO_WRITERS_INSTANCE_STATE => case (mem.inst(i).istate) is when ALIVE_INSTANCE_STATE => mem.inst(i).istate := NOT_ALIVE_NO_WRITERS_INSTANCE_STATE; when others => null; end case; when others => null; end case; exit; end if; end loop; end procedure; procedure add_sample(sample : inout SAMPLE_TYPE; mem : inout DDS_READER_MEM_TYPE; DESTINATION_ORDER_QOS : in std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0)) is variable found : boolean := FALSE; variable ind : natural := 0; begin -- Zero Meta Data sample.dis_gen_cnt := 0; sample.no_w_gen_cnt := 0; sample.srank := 0; sample.grank := 0; sample.agrank := 0; sample.sstate := NOT_READ_SAMPLE_STATE; -- NOTE: We change the Instance State here, because we need the new Sample needs the updated Generation Counters/View State change_istate(sample.inst, sample.istate, mem); -- NOTE: We always check at least the first index for keyless cases (instance = HANDLE_NIL) -- Check Instance State for i in 0 to max(mem.ilen-1,0) loop -- Instance Found if (sample.inst = mem.inst(i).inst) then found := TRUE; sample.vstate := mem.inst(i).vstate; sample.dis_gen_cnt := mem.inst(i).dis_gen_cnt; sample.no_w_gen_cnt := mem.inst(i).no_w_gen_cnt; exit; end if; end loop; -- New Instance if (not found) then add_instance(sample.inst, sample.istate, mem); end if; -- Add Sample ind := mem.slen; case (DESTINATION_ORDER_QOS) is when BY_RECEPTION_TIMESTAMP_DESTINATION_ORDER_QOS => -- Insert at End of Array mem.s(ind) := sample; when BY_SOURCE_TIMESTAMP_DESTINATION_ORDER_QOS => -- Find Position for i in mem.slen-1 downto 0 loop if (sample.ts >= mem.s(i).ts) then exit; end if; ind := i; end loop; -- Move elements to make Space for i in mem.slen-1 downto ind loop mem.s(i+1) := mem.s(i); end loop; -- Insert at desired index mem.s(ind) := sample; when others => assert FALSE report "Unkown DESTINATION_ORDER_QOS" severity FAILURE; end case; mem.slen := mem.slen + 1; end procedure; procedure remove_sample(ind : in natural; mem : inout DDS_READER_MEM_TYPE) is begin assert (ind < mem.slen) report "Index is out of Bounds" severity FAILURE; assert (mem.slen /= 0) report "Remove on empty array" severity FAILURE; for i in ind to mem.slen-2 loop mem.s(i) := mem.s(i+1); end loop; mem.s(mem.slen-1) := DEFAULT_SAMPLE; mem.slen := mem.slen - 1; end procedure; procedure remove_inst(inst : in INSTANCE_HANDLE_TYPE; mem : inout DDS_READER_MEM_TYPE) is variable ind : natural := 0; begin assert (mem.ilen /= 0) report "Remove on empty array" severity FAILURE; ind := mem.ilen; for i in 0 to mem.ilen-1 loop -- Instance Found if (mem.inst(i).inst = inst) then ind := i; exit; end if; end loop; if (ind /= mem.ilen) then for i in ind to mem.ilen-2 loop mem.inst(i) := mem.inst(i+1); end loop; mem.inst(mem.ilen-1) := DEFAULT_INSTANCE_CACHE_TYPE; mem.ilen := mem.ilen - 1; end if; end procedure; function check_instance(istate : std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); vstate : std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0); mem : DDS_READER_MEM_TYPE; inst : INSTANCE_HANDLE_TYPE) return boolean is begin -- NOTE: We always check at least the first index for keyless cases (instance = HANDLE_NIL) for i in 0 to max(mem.ilen-1,0) loop -- Instance Found if (inst = mem.inst(i).inst) then if (((mem.inst(i).istate and istate) /= (istate'reverse_range => '0')) and ((mem.inst(i).vstate and vstate) /= (vstate'reverse_range => '0'))) then return TRUE; end if; end if; end loop; return FALSE; end function; function find_instance(mem : DDS_READER_MEM_TYPE; inst : INSTANCE_HANDLE_TYPE) return natural is begin -- NOTE: We always check at least the first index for keyless cases (instance = HANDLE_NIL) for i in 0 to max(mem.ilen-1,0) loop -- Instance Found if (inst = mem.inst(i).inst) then return i; end if; end loop; assert FALSE report "Instance not in Memory" severity FAILURE; return mem.ilen; end function; procedure gen_collection (mem : inout DDS_READER_MEM_TYPE; col : inout COLLECTION_TYPE; inst : INSTANCE_HANDLE_TYPE; sstate : in std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0); istate : in std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); vstate : in std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0); max_samples : in natural; remove : in boolean; sort : in boolean) is variable i,j : natural := 0; variable tmp_inst : INSTANCE_HANDLE_TYPE := HANDLE_NIL; variable rank, mrsic_gen, mrs_gen : natural := 0; variable done : std_logic_vector(0 to max_samples-1) := (others => '0'); variable sel : std_logic_vector(0 to mem.slen-1) := (others => '0'); variable no_inst : boolean := TRUE; begin col := DEFAULT_COLLECTION; i := 0; loop if (no_inst) then -- Sample and Instance Compatible if (((mem.s(i).sstate and sstate) /= (sstate'reverse_range => '0')) and check_instance(istate, vstate, mem, mem.s(i).inst) and ((inst /= HANDLE_NIL and inst = mem.s(i).inst) or inst = HANDLE_NIL) and (sel(i) /= '1')) then col.s(col.len) := mem.s(i); col.s(col.len).istate := mem.inst(find_instance(mem,mem.s(i).inst)).istate; col.s(col.len).vstate := mem.inst(find_instance(mem,mem.s(i).inst)).vstate; col.len := col.len + 1; -- Change READ STATE mem.s(i).sstate := READ_SAMPLE_STATE; -- Mark as Selected sel(i) := '1'; tmp_inst := mem.s(i).inst; -- NOTE: If we sort by Instance, we need to first get all compatible Samples from one Instance, before moving to the next compatible Instance. -- This is achieved by toggling no_inst. if (sort) then no_inst := FALSE; end if; end if; -- Sample Compatible (and belonging to specified Instance) elsif (((mem.s(i).sstate and sstate) /= (sstate'reverse_range => '0')) and (mem.s(i).inst = tmp_inst) and (sel(i) /= '1')) then col.s(col.len) := mem.s(i); col.s(col.len).istate := mem.inst(find_instance(mem,mem.s(i).inst)).istate; col.s(col.len).vstate := mem.inst(find_instance(mem,mem.s(i).inst)).vstate; col.len := col.len + 1; -- Change READ STATE mem.s(i).sstate := READ_SAMPLE_STATE; -- Mark as Selected sel(i) := '1'; tmp_inst := mem.s(i).inst; end if; i := i + 1; -- Loop Exit Condition if (col.len >= max_samples) then exit; elsif (i >= mem.slen) then -- No more compatible Samples if (no_inst) then exit; -- Check next instance else i := 0; no_inst := TRUE; tmp_inst := HANDLE_NIL; end if; end if; end loop; -- Remove Selected Samples if (remove) then for i in mem.slen-1 downto 0 loop if (sel(i) = '1') then remove_sample(i,mem); end if; end loop; end if; if (col.len = 0) then report "Empty Collection" severity NOTE; return; end if; -- Calculate Ranks i := col.len-1; tmp_inst := col.s(i).inst; j := find_instance(mem,tmp_inst); rank := 1; mrs_gen := mem.inst(j).dis_gen_cnt + mem.inst(j).no_w_gen_cnt; mrsic_gen := col.s(i).dis_gen_cnt + col.s(i).no_w_gen_cnt; col.s(i).agrank := mrs_gen - mrsic_gen; if (mrs_gen - mrsic_gen = 0) then -- Change VIEW STATE mem.inst(j).vstate := NOT_NEW_VIEW_STATE; end if; done(col.len-1 to done'length-1) := (others => '1'); no_inst := FALSE; -- Single Sample if (col.len-1 = 0) then return; else loop i := i - 1; -- Select Next Instance if (no_inst) then if (done(i) = '0') then tmp_inst := col.s(i).inst; j := find_instance(mem, tmp_inst); no_inst := FALSE; -- Reset rank := 1; mrs_gen := mem.inst(j).dis_gen_cnt + mem.inst(j).no_w_gen_cnt; mrsic_gen := col.s(i).dis_gen_cnt + col.s(i).no_w_gen_cnt; col.s(i).agrank := mrs_gen - mrsic_gen; if (mrs_gen - mrsic_gen = 0) then -- Change VIEW STATE mem.inst(j).vstate := NOT_NEW_VIEW_STATE; end if; done(i) := '1'; end if; elsif (done(i) = '0' and col.s(i).inst = tmp_inst) then col.s(i).srank := rank; rank := rank + 1; col.s(i).grank := mrsic_gen - (col.s(i).dis_gen_cnt + col.s(i).no_w_gen_cnt); col.s(i).agrank := mrs_gen - (col.s(i).dis_gen_cnt + col.s(i).no_w_gen_cnt); done(i) := '1'; end if; -- Exit Condition if (done = (done'range => '1')) then exit; -- Reset elsif (i = 0) then tmp_inst := HANDLE_NIL; no_inst := TRUE; i := col.len-1; end if; end loop; end if; end procedure; procedure gen_collection (mem : inout DDS_READER_MEM_TYPE; col : inout COLLECTION_TYPE; opcode : in DDS_READER_TEST_TYPE; PRESENTATION_QOS : in std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0); ordered : in boolean) is variable sort : boolean := FALSE; variable tmp_inst : INSTANCE_HANDLE_TYPE := HANDLE_NIL; begin col := DEFAULT_COLLECTION; sort := TRUE when (not ordered or PRESENTATION_QOS = INSTANCE_PRESENTATION_QOS) else FALSE; case (opcode.opcode) is when READ => gen_collection(mem, col, HANDLE_NIL, opcode.sstate, opcode.istate, opcode.vstate, opcode.max_samples, FALSE, sort); when TAKE => gen_collection(mem, col, HANDLE_NIL, opcode.sstate, opcode.istate, opcode.vstate, opcode.max_samples, TRUE, sort); when READ_NEXT_SAMPLE => gen_collection(mem, col, HANDLE_NIL, NOT_READ_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE, 1, FALSE, FALSE); when TAKE_NEXT_SAMPLE => gen_collection(mem, col, HANDLE_NIL, NOT_READ_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE, 1, TRUE, FALSE); when READ_INSTANCE => gen_collection(mem, col, opcode.inst, opcode.sstate, opcode.istate, opcode.vstate, opcode.max_samples, FALSE, sort); when TAKE_INSTANCE => gen_collection(mem, col, opcode.inst, opcode.sstate, opcode.istate, opcode.vstate, opcode.max_samples, TRUE, sort); when READ_NEXT_INSTANCE => tmp_inst := mem.inst(find_instance(mem,opcode.inst)+1).inst when (opcode.inst /= HANDLE_NIL) else mem.inst(0).inst; if (tmp_inst /= HANDLE_NIL) then gen_collection(mem, col, tmp_inst, opcode.sstate, opcode.istate, opcode.vstate, opcode.max_samples, FALSE, sort); end if; when TAKE_NEXT_INSTANCE => tmp_inst := mem.inst(find_instance(mem,opcode.inst)+1).inst when (opcode.inst /= HANDLE_NIL) else mem.inst(0).inst; if (tmp_inst /= HANDLE_NIL) then gen_collection(mem, col, tmp_inst, opcode.sstate, opcode.istate, opcode.vstate, opcode.max_samples, TRUE, sort); end if; when others => assert FALSE report "Unknown DDS Reader Operation" severity FAILURE; end case; end procedure; procedure gen_CDR(input : std_logic_vector; target_align : ALIGN_TYPE; align_offset : inout unsigned; output : inout TEST_PACKET_TYPE) is begin -- Align Stream while (not check_align(align_offset,target_align)) loop output.data(output.length) := write_sub_vector(output.data(output.length),(BYTE_WIDTH-1 downto 0 => '0'), to_integer(align_offset(1 downto 0)), TRUE); if (align_offset(1 downto 0) = "11") then output.length := output.length + 1; end if; align_offset := align_offset + 1; end loop; for i in (input'length/BYTE_WIDTH)-1 downto 0 loop output.data(output.length) := write_sub_vector(output.data(output.length),input(((i+1)*BYTE_WIDTH)-1 downto i*BYTE_WIDTH), to_integer(align_offset(1 downto 0)), TRUE); if (align_offset(1 downto 0) = "11") then output.length := output.length + 1; end if; align_offset := align_offset + 1; end loop; end procedure; end package body;