* Added OSVVM Library as Submodule
* Merged stimulus generation procedures to one single procedure * Integrated OSVVM into testbench * Generated OSVVM Project Script File * Various Bug Fixes to compile testbench
This commit is contained in:
parent
a792cb7d8a
commit
9c95e58e32
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,6 +1,6 @@
|
|||||||
#Ignore List
|
#Ignore List
|
||||||
/syn/**
|
/syn/**
|
||||||
/modelsim/**
|
/sim/**
|
||||||
/download/**
|
/download/**
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "src/OSVVM"]
|
||||||
|
path = src/OSVVM
|
||||||
|
url = https://github.com/OSVVM/OSVVM.git
|
||||||
44
sim/rtps_handler.do
Normal file
44
sim/rtps_handler.do
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
onerror {resume}
|
||||||
|
quietly WaveActivateNextPane {} 0
|
||||||
|
add wave -noupdate -divider SYSTEM
|
||||||
|
add wave -noupdate /rtps_handler_test1/uut/clk
|
||||||
|
add wave -noupdate /rtps_handler_test1/uut/reset
|
||||||
|
add wave -noupdate -divider INPUT
|
||||||
|
add wave -noupdate /rtps_handler_test1/uut/empty
|
||||||
|
add wave -noupdate /rtps_handler_test1/uut/rd
|
||||||
|
add wave -noupdate -radix hexadecimal /rtps_handler_test1/uut/data_in
|
||||||
|
add wave -noupdate -divider OUTPUT
|
||||||
|
add wave -noupdate -radix hexadecimal /rtps_handler_test1/uut/data_out
|
||||||
|
add wave -noupdate /rtps_handler_test1/uut/builtin_full
|
||||||
|
add wave -noupdate /rtps_handler_test1/uut/builtin_wr
|
||||||
|
add wave -noupdate /rtps_handler_test1/uut/user_full
|
||||||
|
add wave -noupdate /rtps_handler_test1/uut/user_wr
|
||||||
|
add wave -noupdate /rtps_handler_test1/uut/last_word_out
|
||||||
|
add wave -noupdate -divider MISC
|
||||||
|
add wave -noupdate /rtps_handler_test1/stimulus.length
|
||||||
|
add wave -noupdate /rtps_handler_test1/cnt_stim
|
||||||
|
add wave -noupdate /rtps_handler_test1/packet_sent
|
||||||
|
add wave -noupdate /rtps_handler_test1/reference.length
|
||||||
|
add wave -noupdate /rtps_handler_test1/cnt_ref
|
||||||
|
add wave -noupdate /rtps_handler_test1/packet_checked
|
||||||
|
add wave -noupdate -divider RTPS_HANDLER
|
||||||
|
add wave -noupdate /rtps_handler_test1/uut/stage
|
||||||
|
add wave -noupdate /rtps_handler_test1/uut/stage_next
|
||||||
|
TreeUpdate [SetDefaultTree]
|
||||||
|
WaveRestoreCursors {{Cursor 1} {0 ps} 0}
|
||||||
|
quietly wave cursor active 1
|
||||||
|
configure wave -namecolwidth 150
|
||||||
|
configure wave -valuecolwidth 63
|
||||||
|
configure wave -justifyvalue left
|
||||||
|
configure wave -signalnamewidth 1
|
||||||
|
configure wave -snapdistance 10
|
||||||
|
configure wave -datasetprefix 0
|
||||||
|
configure wave -rowmargin 4
|
||||||
|
configure wave -childrowmargin 2
|
||||||
|
configure wave -gridoffset 0
|
||||||
|
configure wave -gridperiod 1
|
||||||
|
configure wave -griddelta 40
|
||||||
|
configure wave -timeline 0
|
||||||
|
configure wave -timelineunits ps
|
||||||
|
update
|
||||||
|
WaveRestoreZoom {0 ps} {1206528 ps}
|
||||||
1
src/OSVVM
Submodule
1
src/OSVVM
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 6b810535967433ae4bec4094ea58fc09c1e49227
|
||||||
@ -51,6 +51,7 @@
|
|||||||
* Should a "Keyed" Endpoint communicate with a "Non-Keyed"?
|
* Should a "Keyed" Endpoint communicate with a "Non-Keyed"?
|
||||||
* Is the empty String a valid Topic and Type Name?
|
* Is the empty String a valid Topic and Type Name?
|
||||||
* We can determine if a Endpoint is a Reader or Writer via the Entity ID. Is it illegal to get a SEDP with incompatible source (Reader Entity ID from Publications Announcer?)
|
* We can determine if a Endpoint is a Reader or Writer via the Entity ID. Is it illegal to get a SEDP with incompatible source (Reader Entity ID from Publications Announcer?)
|
||||||
|
* Can we make an array of records of uncontrained strings? That we we could make an array of variable sized strings...
|
||||||
|
|
||||||
|
|
||||||
* Fast-RTPS doen not follow DDSI-RTPS Specification
|
* Fast-RTPS doen not follow DDSI-RTPS Specification
|
||||||
@ -119,3 +120,4 @@ PROTOCOL UNCOMPLIANCE
|
|||||||
|
|
||||||
-- Input FIFO Guard
|
-- Input FIFO Guard
|
||||||
-- Output FIFO Guard
|
-- Output FIFO Guard
|
||||||
|
-- Deferred to package Body
|
||||||
@ -1,834 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
|
|
||||||
|
|
||||||
entity rtps_handler-test1 is
|
|
||||||
end entity;
|
|
||||||
|
|
||||||
architecture testbench of rtps_handler-test1 is
|
|
||||||
|
|
||||||
-- *COMPONENT DECLARATION*
|
|
||||||
component rtps_handler is
|
|
||||||
port (
|
|
||||||
clk : in std_logic; -- Input Clock
|
|
||||||
reset : in std_logic; -- Synchronous Reset
|
|
||||||
empty : in std_logic; -- Input FIFO empty flag
|
|
||||||
rd : out std_logic; -- Input FIFO read signal
|
|
||||||
data_in : in std_logic_vector(WORD_WIDTH-1 downto 0); -- Input FIFO data signal
|
|
||||||
data_out : out std_logic_vector(WORD_WIDTH-1 downto 0); -- Output data signal
|
|
||||||
builtin_full : in std_logic; -- Output FIFO (Built-In Endpoint) full signal
|
|
||||||
builtin_wr : out std_logic; -- Output FIFO (Built-In Endpoint) write signal
|
|
||||||
user_full : in std_logic_vector(0 to NUM_ENDPOINTS-1); -- Output FIFO (User Endpoints) full signal
|
|
||||||
user_wr : out std_logic_vector(0 to NUM_ENDPOINTS-1); -- Output FIFO (User Endpoints) write signal
|
|
||||||
last_word_out : out std_logic -- Output FIFO Last Word signal
|
|
||||||
);
|
|
||||||
end component;
|
|
||||||
|
|
||||||
-- *FUNCTION DECLARATION*
|
|
||||||
|
|
||||||
-- *SIGNAL DECLARATION*
|
|
||||||
signal clk, reset, in_empty, rd_sig, builtin_full, builtin_wr, user_full, user_wr, last_word_out, packet_done : std_logic := '0';
|
|
||||||
signal data_in, data_out : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0');
|
|
||||||
signal stimulus, reference : TEST_PACKET_TYPE := (
|
|
||||||
data => (others => (others => '0')),
|
|
||||||
length => 0
|
|
||||||
);
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
-- Unit Under Test
|
|
||||||
uut : rtps_handler
|
|
||||||
port map (
|
|
||||||
clk => clk,
|
|
||||||
reset => reset,
|
|
||||||
empty => in_empty,
|
|
||||||
rd => rd_sig,
|
|
||||||
data_in => data_in,
|
|
||||||
data_out => data_out,
|
|
||||||
builtin_full => builtin_full,
|
|
||||||
builtin_wr => builtin_wr
|
|
||||||
user_full => user_full,
|
|
||||||
user_wr => user_wr
|
|
||||||
last_word_out => last_word_out
|
|
||||||
);
|
|
||||||
|
|
||||||
stimulus_prc : process
|
|
||||||
variable ep : ENDPOINT_DATA_TYPE := DEFAULT_ENDPOINT_DATA;
|
|
||||||
constant rand_data : TEST_PACKET_TYPE := (length => 2, data => (0 => rand_slv(WORD_WIDTH), 1 => rand_slv(WORD_WIDTH)));
|
|
||||||
variable rtps_header : RTPS_HEADER_TYPE := DEFAULT_RTPS_HEADER;
|
|
||||||
variable acknack : RTPS_ACKNACK_SUBMESSAGE_TYPE := DEFAULT_RTPS_ACKNACK_SUBMESSAGE;
|
|
||||||
variable data : RTPS_DATA_SUBMESSAGE_TYPE := DEFAULT_RTPS_DATA_SUBMESSAGE;
|
|
||||||
variable gap : RTPS_GAP_SUBMESSAGE_TYPE := DEFAULT_RTPS_GAP_SUBMESSAGE;
|
|
||||||
variable heartbeat : RTPS_HEARTBEAT_SUBMESSAGE_TYPE := DEFAULT_RTPS_HEARTBEAT_SUBMESSAGE;
|
|
||||||
variable info_ts : RTPS_INFO_TIMESTAMP_SUBMESSAGE_TYPE := DEFAULT_RTPS_INFO_TIMESTAMP_SUBMESSAGE;
|
|
||||||
variable pad : RTPS_PAD_SUBMESSAGE_TYPE := DEFAULT_RTPS_PAD_SUBMESSAGE;
|
|
||||||
variable info_dest : RTPS_INFO_DESTINATION_SUBMESSAGE_TYPE := DEFAULT_RTPS_INFO_DESTINATION_SUBMESSAGE;
|
|
||||||
variable info_src : RTPS_INFO_SOURCE_SUBMESSAGE_TYPE := DEFAULT_RTPS_INFO_SOURCE_SUBMESSAGE;
|
|
||||||
variable info_reply : RTPS_INFO_REPLY_SUBMESSAGE_TYPE := DEFAULT_RTPS_INFO_REPLY_SUBMESSAGE;
|
|
||||||
variable info_reply4 : RTPS_INFO_REPLY_IP4_SUBMESSAGE_TYPE := DEFAULT_RTPS_INFO_REPLY_IP4_SUBMESSAGE;
|
|
||||||
variable udp_header_meta, udp_header_user : UDP_HEADER_TYPE := DEFAULT_UDP_HEADER;
|
|
||||||
begin
|
|
||||||
ep.entityId := rand_slv(ep.entityId'length);
|
|
||||||
acknack.readerId := ep.entityId;
|
|
||||||
data.writerId := ep.entityId;
|
|
||||||
gap.writerId := ep.entityId;
|
|
||||||
heartbeat.writerId := ep.entityId;
|
|
||||||
|
|
||||||
data.flags(SUBMESSAGE_DATA_FLAG_POS) := '1';
|
|
||||||
data.data := rand_data;
|
|
||||||
|
|
||||||
rtps_header.guidPrefix := ep.participant.guidPrefix;
|
|
||||||
udp_header_meta.dest := DEST_LOC.meta.locator(0);
|
|
||||||
udp_header_user.dest := DEST_LOC.user.locator(0);
|
|
||||||
udp_header_meta.src := ep.participant.defaultUnicastLocatorList.locator(0);
|
|
||||||
udp_header_user.src := ep.participant.defaultUnicastLocatorList.locator(0);
|
|
||||||
info_dest.guidPrefix := GUIDPREFIX;
|
|
||||||
info_ts.flags(SUBMESSAGE_INVALIDATE_FLAG_POS) := '0';
|
|
||||||
info_ts.timestamp := (unsigned(rand_slv(WORD_WIDTH)),unsigned(rand_slv(WORD_WIDTH)));
|
|
||||||
pad.submessageLength := int(28,16);
|
|
||||||
info_reply.unicastLocatorList.numLocators := int(2,32);
|
|
||||||
info_reply.unicastLocatorList.locator(0) := (
|
|
||||||
kind => LOCATOR_KIND_UDPv4,
|
|
||||||
port_(UDP_PORT_WIDTH-1 downto 0) => rand_slv(UDP_PORT_WIDTH),
|
|
||||||
addr(IPv4_ADDRESS_WIDTH-1 downto 0) => rand_slv(IPv4_ADDRESS_WIDTH)
|
|
||||||
);
|
|
||||||
info_reply.unicastLocatorList.locator(1) := (
|
|
||||||
kind => LOCATOR_KIND_UDPv4,
|
|
||||||
port_(UDP_PORT_WIDTH-1 downto 0) => (others => '0'), -- Invalid Port
|
|
||||||
addr(IPv4_ADDRESS_WIDTH-1 downto 0) => rand_slv(IPv4_ADDRESS_WIDTH)
|
|
||||||
);
|
|
||||||
info_reply.multicastLocatorList.numLocators := int(2,32);
|
|
||||||
info_reply.multicastLocatorList.locator(0) := (
|
|
||||||
kind => LOCATOR_KIND_UDPv4,
|
|
||||||
port_(UDP_PORT_WIDTH-1 downto 0) => rand_slv(UDP_PORT_WIDTH),
|
|
||||||
addr(IPv4_ADDRESS_WIDTH-1 downto 0) => rand_slv(IPv4_ADDRESS_WIDTH)
|
|
||||||
);
|
|
||||||
info_reply.multicastLocatorList.locator(1) := (
|
|
||||||
kind => LOCATOR_KIND_UDPv4,
|
|
||||||
port_(UDP_PORT_WIDTH-1 downto 0) => rand_slv(UDP_PORT_WIDTH),
|
|
||||||
addr(IPv4_ADDRESS_WIDTH-1 downto 0) => (others => '0') -- Invalid Addr
|
|
||||||
);
|
|
||||||
info_reply4.unicastLocator := (
|
|
||||||
kind => LOCATOR_KIND_UDPv4,
|
|
||||||
port_(UDP_PORT_WIDTH-1 downto 0) => rand_slv(UDP_PORT_WIDTH),
|
|
||||||
addr(IPv4_ADDRESS_WIDTH-1 downto 0) => rand_slv(IPv4_ADDRESS_WIDTH)
|
|
||||||
);
|
|
||||||
info_reply4.multicastLocator := (
|
|
||||||
kind => LOCATOR_KIND_UDPv4,
|
|
||||||
port_(UDP_PORT_WIDTH-1 downto 0) => rand_slv(UDP_PORT_WIDTH),
|
|
||||||
addr(IPv4_ADDRESS_WIDTH-1 downto 0) => rand_slv(IPv4_ADDRESS_WIDTH)
|
|
||||||
);
|
|
||||||
|
|
||||||
report "Initiating Test" severity note;
|
|
||||||
reset <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
|
|
||||||
|
|
||||||
-- *RTPS HEADER*
|
|
||||||
report "Sending invalid RTPS Header [Packet Size to small]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
stimulus.length := length-1;
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending invalid RTPS Header [Protocol Missmatch]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
rtps_header.protocol := rand_slv(PROTOCOL_WIDTH);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
rtps_header.protocol := DEFAULT_RTPS_HEADER.protocol;
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending invalid RTPS Header [Protocol Major Version Missmatch]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
rtps_header.version := PROTOCOLVERSION_1_0;
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
rtps_header.version := DEFAULT_RTPS_HEADER.version;
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
|
|
||||||
-- *DATA SUBMESSAGE*
|
|
||||||
report "Sending valid DATA [Empty Submessage]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
data.flags(SUBMESSAGE_DATA_FLAG_POS) := '0';
|
|
||||||
data.data.length := 0;
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
data.flags(SUBMESSAGE_DATA_FLAG_POS) := '1';
|
|
||||||
data.data := rand_data;
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending valid DATA [Meta Traffic, Both Endianness]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, rtps_header.guidPrefix, reference);
|
|
||||||
data.littleEndian := '1';
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, rtps_header.guidPrefix, reference);
|
|
||||||
data.littleEndian := '0';
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending valid DATA [User Traffic]" severity note;
|
|
||||||
gen_udp_header(udp_header_user, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
gen_data_out(data, udp_header_user.src, FALSE, TIME_INVALID, rtps_header.guidPrefix, reference);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending valid DATA [Extra Header Bytes]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
data.octetsToInlineQos := int(23,16);
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
data.octetsToInlineQos := DEFAULT_RTPS_DATA_SUBMESSAGE.octetsToInlineQos;
|
|
||||||
gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, rtps_header.guidPrefix, reference);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending invalid DATA [DATA and KEY Flag set]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
data.flags(SUBMESSAGE_KEY_FLAG_POS) := '1';
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
data.flags(SUBMESSAGE_KEY_FLAG_POS) := '0';
|
|
||||||
gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, rtps_header.guidPrefix, reference);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending invalid DATA [Packet Size too small]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
stimulus.length := length-1;
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending invalid DATA [Submessage Length too small]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
data.submessageLength := int(16,16);
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
data.submessageLength := DEFAULT_RTPS_DATA_SUBMESSAGE.submessageLength;
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending invalid DATA [Invalid writerSN]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
data.sequenceNumber := (others => (others => '0'));
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
data.sequenceNumber := DEFAULT_RTPS_DATA_SUBMESSAGE.sequenceNumber;
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
|
|
||||||
-- *ACKNACK SUBMESSAGE*
|
|
||||||
report "Sending valid ACKNACK [Meta Traffic, Both Endianness]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
gen_acknack(acknack, stimulus);
|
|
||||||
gen_acknack_out(acknack, udp_header_meta.src, TRUE, rtps_header.guidPrefix, reference);
|
|
||||||
acknack.littleEndian := '1';
|
|
||||||
gen_acknack(acknack, stimulus);
|
|
||||||
gen_acknack_out(acknack, udp_header_meta.src, TRUE, rtps_header.guidPrefix, reference);
|
|
||||||
acknack.littleEndian := '0';
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending valid ACKNACK [User Traffic]" severity note;
|
|
||||||
gen_udp_header(udp_header_user, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
gen_acknack(acknack, stimulus);
|
|
||||||
gen_acknack_out(acknack, udp_header_user.src, FALSE, rtps_header.guidPrefix, reference);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending invalid ACKNACK [Packet Size too small]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
gen_acknack(acknack, stimulus);
|
|
||||||
stimulus.length := length-1;
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending invalid ACKNACK [Submessage Length too small]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
acknack.submessageLength := int(20,16);
|
|
||||||
gen_acknack(acknack, stimulus);
|
|
||||||
acknack.submessageLength := DEFAULT_RTPS_ACKNACK_SUBMESSAGE.submessageLength;
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending invalid ACKNACK [ReaderSNState invalid (Base invalid)]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
acknack.readerSNState.base := (others => (others => '0'));
|
|
||||||
gen_acknack(acknack, stimulus);
|
|
||||||
acknack.readerSNState := DEFAULT_RTPS_ACKNACK_SUBMESSAGE.readerSNState;
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending invalid ACKNACK [ReaderSNState invalid (NumBits invalid)]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
acknack.readerSNState.numBits := int(257, 32);
|
|
||||||
gen_acknack(acknack, stimulus);
|
|
||||||
acknack.readerSNState := DEFAULT_RTPS_ACKNACK_SUBMESSAGE.readerSNState;
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
-- *GAP SUBMESSAGE*
|
|
||||||
report "Sending valid GAP [Meta Traffic, Both Endianness]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
gen_gap(gap, stimulus);
|
|
||||||
gen_gap_out(gap, udp_header_meta.src, TRUE, rtps_header.guidPrefix, reference);
|
|
||||||
gap.littleEndian := '1';
|
|
||||||
gen_gap(gap, stimulus);
|
|
||||||
gen_gap_out(gap, udp_header_meta.src, TRUE, rtps_header.guidPrefix, reference);
|
|
||||||
gap.littleEndian := '0';
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending valid GAP [User Traffic]" severity note;
|
|
||||||
gen_udp_header(udp_header_user, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
gen_gap(gap, stimulus);
|
|
||||||
gen_gap_out(gap, udp_header_user.src, FALSE, rtps_header.guidPrefix, reference);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending invalid GAP [Packet Size too small]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
gen_gap(gap, stimulus);
|
|
||||||
stimulus.length := length-1;
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending invalid GAP [Submessage Length too small]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
gap.submessageLength := int(24,16);
|
|
||||||
gen_gap(gap, stimulus);
|
|
||||||
gap.submessageLength := DEFAULT_RTPS_GAP_SUBMESSAGE.submessageLength;
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending invalid GAP [GapStart invalid]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
gap.gapStart := (others => (others => '0'));
|
|
||||||
gen_gap(gap, stimulus);
|
|
||||||
gap.gapStart := DEFAULT_RTPS_GAP_SUBMESSAGE.gapStart;
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending invalid GAP [GapList invalid (Base invalid)]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
gap.gapList.base := (others => (others => '0'));
|
|
||||||
gen_gap(gap, stimulus);
|
|
||||||
gap.gapList := DEFAULT_RTPS_GAP_SUBMESSAGE.gapList;
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending invalid GAP [GapList invalid (NumBits invalid)]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
gap.gapList.numBits := int(257,32);
|
|
||||||
gen_gap(gap, stimulus);
|
|
||||||
gap.gapList := DEFAULT_RTPS_GAP_SUBMESSAGE.gapList;
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
|
|
||||||
-- *HEARTBEAT SUBMESSAGE*
|
|
||||||
report "Sending valid HEARTBEAT [Meta Traffic, Both Endianness]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
gen_heartbeat(heartbeat, stimulus);
|
|
||||||
gen_heartbeat_out(heartbeat, udp_header_meta.src, TRUE, rtps_header.guidPrefix, reference);
|
|
||||||
heartbeat.littleEndian := '1';
|
|
||||||
gen_heartbeat(heartbeat, stimulus);
|
|
||||||
gen_heartbeat_out(heartbeat, udp_header_meta.src, TRUE, rtps_header.guidPrefix, reference);
|
|
||||||
heartbeat.littleEndian := '0';
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending valid HEARTBEAT [User Traffic]" severity note;
|
|
||||||
gen_udp_header(udp_header_user, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
gen_heartbeat(heartbeat, stimulus);
|
|
||||||
gen_heartbeat_out(heartbeat, udp_header_user.src, FALSE, rtps_header.guidPrefix, reference);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending invalid HEARTBEAT [Packet Size too small]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
gen_heartbeat(heartbeat, stimulus);
|
|
||||||
stimulus.length := length-1;
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending invalid HEARTBEAT [Submessage Length too small]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
heartbeat.submessageLength := int(24,16);
|
|
||||||
gen_heartbeat(heartbeat, stimulus);
|
|
||||||
heartbeat.submessageLength := (others => '1');
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending invalid HEARTBEAT [FirstSN invalid]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
heartbeat.firstSN := (others => (others => '0'));
|
|
||||||
gen_heartbeat(heartbeat, stimulus);
|
|
||||||
heartbeat.firstSN := DEFAULT_RTPS_HEARTBEAT_SUBMESSAGE.firstSN;
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending invalid HEARTBEAT [LastSN invalid]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
heartbeat.lastSN := (others => (others => '1'));
|
|
||||||
gen_heartbeat(heartbeat, stimulus);
|
|
||||||
heartbeat.lastSN := DEFAULT_RTPS_HEARTBEAT_SUBMESSAGE.lastSN;
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
|
|
||||||
-- *INFO_SOURCE SUBMESSAGE*
|
|
||||||
report "Testing INFO_SOURCE interpretation" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
-- Send valid DATA
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, rtps_header.guidPrefix, reference);
|
|
||||||
-- Send INFO_SOURCE (Change Source GUID Prefix)
|
|
||||||
info_src.guidPrefix(0) := rand_slv(WORD_WIDTH);
|
|
||||||
gen_info_src(info_src, stimulus);
|
|
||||||
-- Send valid DATA
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, info_dest.guidPrefix, reference);
|
|
||||||
-- Send INFO_SOURCE (Change GUID Prefix, Little Endian)
|
|
||||||
info_src.littleEndian := '1';
|
|
||||||
info_src.guidPrefix := ep.participant.guidPrefix;
|
|
||||||
gen_info_src(info_src, stimulus);
|
|
||||||
info_src.littleEndian := '0';
|
|
||||||
-- Send valid DATA
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, ep.participant.guidPrefix, reference);
|
|
||||||
-- Send INFO_SOURCE [Protocol Major Version Missmatch]
|
|
||||||
info_src.version := PROTOCOLVERSION_1_0;
|
|
||||||
gen_info_src(info_src, stimulus);
|
|
||||||
info_src.version := PROTOCOLVERSION_2_4;
|
|
||||||
-- Send valid DATA
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending invalid INFO_SOURCE [Submessage Length too small]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
info_src.submessageLength := int(16,16);
|
|
||||||
gen_info_src(info_src, stimulus);
|
|
||||||
info_src.submessageLength := DEFAULT_RTPS_INFO_SOURCE_SUBMESSAGE.submessageLength;
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
|
|
||||||
-- *INFO_DESTINATION SUBMESSAGE*
|
|
||||||
report "Testing INFO_DESTINATION interpretation" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
-- Send valid DATA
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, rtps_header.guidPrefix, reference);
|
|
||||||
-- Send INFO_DESTINATION [Correct GUID Prefix]
|
|
||||||
gen_info_dest(info_dest, stimulus);
|
|
||||||
-- Send valid DATA
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, info_dest.guidPrefix, reference);
|
|
||||||
-- Send INFO_DESTINATION [Correct GUID Prefix, Little Endian]
|
|
||||||
info_dest.littleEndian := '1';
|
|
||||||
gen_info_dest(info_dest, stimulus);
|
|
||||||
info_dest.littleEndian := '0';
|
|
||||||
-- Send valid DATA
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, info_dest.guidPrefix, reference);
|
|
||||||
-- Send INFO_DESTINATION [Incorrect GUID Prefix]
|
|
||||||
info_dest.guidPrefix := rtps_header.guidPrefix;
|
|
||||||
gen_info_src(info_dest, stimulus);
|
|
||||||
info_dest.guidPrefix := GUIDPREFIX;
|
|
||||||
-- Send valid DATA
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending invalid INFO_DESTINATION [Submessage Length too small]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
info_dest.submessageLength := int(8,16);
|
|
||||||
gen_info_dest(info_dest, stimulus);
|
|
||||||
info_dest.submessageLength := DEFAULT_RTPS_INFO_DESTINATION_SUBMESSAGE.submessageLength;
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
|
|
||||||
-- *INFO_REPLY SUBMESSAGE*
|
|
||||||
report "Testing INFO_REPLY interpretation" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
-- Send valid DATA
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, rtps_header.guidPrefix, reference);
|
|
||||||
-- Send INFO_REPLY [Empty Locator Lists]
|
|
||||||
info_reply.unicastLocatorList.numLocators := int(0,32);
|
|
||||||
gen_info_reply(info_reply, stimulus);
|
|
||||||
info_reply.unicastLocatorList.numLocators := int(2,32);
|
|
||||||
-- Send valid DATA
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, info_dest.guidPrefix, reference);
|
|
||||||
-- Send INFO_REPLY [1 valid Unicast, 1 invalid Unicast]
|
|
||||||
gen_info_reply(info_reply, stimulus);
|
|
||||||
-- Send valid DATA
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
gen_data_out(data, info_reply.unicastLocatorList.locator(0), TRUE, TIME_INVALID, info_dest.guidPrefix, reference);
|
|
||||||
-- Send INFO_REPLY [0 Unicast, 1 invalid Multicast, 1 valid Multicast, Little Endian]
|
|
||||||
info_reply.unicastLocatorList.numLocators := int(0,32);
|
|
||||||
info_reply.flags(SUBMESSAGE_MULTICAST_FLAG_POS) := '1';
|
|
||||||
gen_info_reply(info_reply, stimulus);
|
|
||||||
info_reply.flags(SUBMESSAGE_MULTICAST_FLAG_POS) := '0';
|
|
||||||
info_reply.unicastLocatorList.numLocators := int(2,32);
|
|
||||||
-- Send valid DATA
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
gen_data_out(data, info_reply.multicastLocatorList.locator(0), TRUE, TIME_INVALID, info_dest.guidPrefix, reference);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending invalid INFO_REPLY [Submessage Length too small]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
info_reply.submessageLength := int(48,16);
|
|
||||||
gen_info_reply(info_reply, stimulus);
|
|
||||||
info_reply.submessageLength := DEFAULT_RTPS_INFO_REPLY_SUBMESSAGE.submessageLength;
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
|
|
||||||
-- *INFO_REPLY_IP4 SUBMESSAGE*
|
|
||||||
report "Testing INFO_REPLY_IP4 interpretation" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
-- Send valid DATA
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, rtps_header.guidPrefix, reference);
|
|
||||||
-- Send INFO_REPLY_IP4 [Valid Unicast]
|
|
||||||
gen_info_reply(info_reply, stimulus);
|
|
||||||
-- Send valid DATA
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
gen_data_out(data, info_reply4.unicastLocator, TRUE, TIME_INVALID, info_dest.guidPrefix, reference);
|
|
||||||
-- Send INFO_REPLY_IP4 [Invalid Unicast, Valid Multicast, Little Endian]
|
|
||||||
info_reply4.littleEndian := '1';
|
|
||||||
info_reply4.flags(SUBMESSAGE_MULTICAST_FLAG_POS) := '1';
|
|
||||||
info_reply4.unicastLocator.addr := (others => '0');
|
|
||||||
gen_info_reply(info_reply, stimulus);
|
|
||||||
info_reply4.littleEndian := '0';
|
|
||||||
-- Send valid DATA
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
gen_data_out(data, info_reply4.multicastLocator, TRUE, TIME_INVALID, info_dest.guidPrefix, reference);
|
|
||||||
-- Send INFO_REPLY_IP4 [Invalid Unicast, Invalid Multicast]
|
|
||||||
gen_data_out(data, info_reply4.multicastLocator, TRUE, TIME_INVALID, info_dest.guidPrefix, reference); -- Generate Reference while locator still valid
|
|
||||||
info_reply4.multicastLocator.port_ := (others => '0');
|
|
||||||
gen_info_reply(info_reply, stimulus);
|
|
||||||
info_reply4.unicastLocator.addr := rand_slv(IPv4_ADDRESS_WIDTH);
|
|
||||||
info_reply4.multicastLocator.port_ := rand_slv(UDP_PORT_WIDTH);
|
|
||||||
info_reply4.flags(SUBMESSAGE_MULTICAST_FLAG_POS) := '0';
|
|
||||||
-- Send valid DATA
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending invalid INFO_REPLY_IP4 [Submessage Length too small]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
info_reply4.submessageLength := int(4,16);
|
|
||||||
gen_info_reply_ip4(info_reply4, stimulus);
|
|
||||||
info_reply4.submessageLength := DEFAULT_RTPS_INFO_REPLY_IP4_SUBMESSAGE.submessageLength;
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
-- *INFO TS*
|
|
||||||
report "Testing INFO_TIMESTAMP interpretation" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
-- Send valid DATA
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, info_dest.guidPrefix, reference);
|
|
||||||
-- Send INFO_TIMESTAMP [Change Timestamp]
|
|
||||||
gen_info_ts(info_ts, stimulus);
|
|
||||||
-- Send valid Data
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
gen_data_out(data, udp_header_meta.src, TRUE, info_ts.timestamp, info_dest.guidPrefix, reference);
|
|
||||||
-- Send INFO_TIMESTAMP [Change Timestamp, Little Endian]
|
|
||||||
info_ts.timestamp(0) := unsigned(rand_slv(WORD_WIDTH));
|
|
||||||
info_ts.littleEndian := '1';
|
|
||||||
gen_info_ts(info_ts, stimulus);
|
|
||||||
info_ts.littleEndian := '0';
|
|
||||||
-- Send valid DATA
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
gen_data_out(data, udp_header_meta.src, TRUE, info_ts.timestamp, info_dest.guidPrefix, reference);
|
|
||||||
-- Send INFO_TIMESTAMP [Invalidate Timestamp]
|
|
||||||
info_ts.timestamp(0) := unsigned(rand_slv(WORD_WIDTH));
|
|
||||||
info_ts.flags(SUBMESSAGE_INVALIDATE_FLAG_POS) := '1';
|
|
||||||
gen_info_ts(info_ts, stimulus);
|
|
||||||
info_ts.flags(SUBMESSAGE_INVALIDATE_FLAG_POS) := '0';
|
|
||||||
-- Send valid DATA
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, info_dest.guidPrefix, reference);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
report "Sending invalid INFO_TMESTAMP [Submessage Length too small]" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
info_ts.submessageLength := int(4,16);
|
|
||||||
gen_info_ts(info_ts, stimulus);
|
|
||||||
info_ts.submessageLength := DEFAULT_RTPS_INFO_REPLY_IP4_SUBMESSAGE.submessageLength;
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
|
|
||||||
-- *PAD*
|
|
||||||
report "Testing PAD interpretation" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
-- Send valid DATA
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, info_dest.guidPrefix, reference);
|
|
||||||
-- Send PAD
|
|
||||||
gen_pad(pad, stimulus);
|
|
||||||
-- Send valid DATA
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, info_dest.guidPrefix, reference);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
|
|
||||||
-- *UNKNOWN*
|
|
||||||
report "Testing unknown Submessage handling" severity note;
|
|
||||||
gen_udp_header(udp_header_meta, stimulus);
|
|
||||||
gen_rtps_header(rtps_header, stimulus);
|
|
||||||
-- Send valid DATA
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, info_dest.guidPrefix, reference);
|
|
||||||
-- Send valid DATA_FRAG Submessage (DATA_FRAG ignored)
|
|
||||||
gen_data_frag(DEFAULT_RTPS_DATA_FRAG_SUBMESSAGE, stimulus);
|
|
||||||
-- Send valid DATA
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, info_dest.guidPrefix, reference);
|
|
||||||
-- Send valid HEARTBEAT_FRAG Submessage (HEARTBEAT_FRAG ignored)
|
|
||||||
gen_heartbeat_frag(DEFAULT_RTPS_HEARTBEAT_FRAG_SUBMESSAGE, stimulus);
|
|
||||||
-- Send valid DATA
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, info_dest.guidPrefix, reference);
|
|
||||||
-- Send valid NACK_FRAG Submesage (NACK_FRAG ignored)
|
|
||||||
gen_nack_frag(DEFAULT_RTPS_NACK_FRAG_SUBMESSAGE, stimulus);
|
|
||||||
-- Send valid DATA
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, info_dest.guidPrefix, reference);
|
|
||||||
-- Send UNKNOWN Submessage (ignored)
|
|
||||||
pad.submessageID := (others => '1');
|
|
||||||
gen_pad(pad, stimulus);
|
|
||||||
pad.submessageID := DEFAULT_RTPS_PAD_SUBMESSAGE.submessageID;
|
|
||||||
-- Send valid DATA
|
|
||||||
gen_data(data, stimulus);
|
|
||||||
gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, info_dest.guidPrefix, reference);
|
|
||||||
fix_udp_packet(stimulus);
|
|
||||||
wait until (packet_done = '1');
|
|
||||||
stimulus.length := 0;
|
|
||||||
reference.length := 0;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
clock_prc : process
|
|
||||||
begin
|
|
||||||
clk <= '0';
|
|
||||||
wait for 25 ns;
|
|
||||||
clk <= '1';
|
|
||||||
wait for 25 ns;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
fifo_ctl_prc : process
|
|
||||||
begin
|
|
||||||
in_empty <= '0';
|
|
||||||
builtin_full <= '0';
|
|
||||||
user_full <= '0';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
in_empty <= '1';
|
|
||||||
builtin_full <= '0';
|
|
||||||
user_full <= '0';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
in_empty <= '0';
|
|
||||||
builtin_full <= '1';
|
|
||||||
user_full <= '0';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
in_empty <= '0';
|
|
||||||
builtin_full <= '0';
|
|
||||||
user_full <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
end process;
|
|
||||||
|
|
||||||
assert (not (in_empty = '1' and rd_sig = '1')) report "Input FIFO read signal high while empty signal high" severity failure;
|
|
||||||
assert (not (builtin_full = '1' and builtin_wr = '1')) report "Builtin FIFO write signal high while full signal high" severity failure;
|
|
||||||
assert (not (user_full = '1' and user_wr = '1')) report "Builtin FIFO write signal high while full signal high" severity failure;
|
|
||||||
|
|
||||||
input_prc : process(all)
|
|
||||||
signal cnt : natural := 0;
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if (reset = '1') then
|
|
||||||
data_in <= (others => '0');
|
|
||||||
cnt <= 0;
|
|
||||||
packet_done <= '0';
|
|
||||||
else
|
|
||||||
if (cnt = stimulus.length) then
|
|
||||||
cnt <= 0;
|
|
||||||
packet_done <= '1';
|
|
||||||
elsif (rd_sig = '1') then
|
|
||||||
data_in <= stimulus.data(cnt);
|
|
||||||
cnt <= cnt + 1;
|
|
||||||
packet_done <= '0';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
output_prc : process(all)
|
|
||||||
signal cnt : natural := 0;
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if (reset = '1') then
|
|
||||||
cnt <= 0;
|
|
||||||
else
|
|
||||||
assert (cnt <= reference.length) report "Received too many words in output" severity failure;
|
|
||||||
if ((builtin_wr = '1' or user_wr = '1') and rd_sig = '0') then
|
|
||||||
assert (data_out = reference.data(cnt)) report "Received unexpected output. Received: " & str(data_out) & ", Expected: " & str(reference.data(cnt)) severity failure;
|
|
||||||
cnt <= cnt + 1;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
end architecture;
|
|
||||||
1265
src/Tests/Level_0/rtps_handler_test1.vhd
Normal file
1265
src/Tests/Level_0/rtps_handler_test1.vhd
Normal file
File diff suppressed because it is too large
Load Diff
14
src/Tests/testbench.pro
Normal file
14
src/Tests/testbench.pro
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# Compile OSVVM Library
|
||||||
|
include ../OSVVM/osvvm.pro
|
||||||
|
|
||||||
|
# Compile
|
||||||
|
library Level0-rtps_handler
|
||||||
|
analyze ../math_pkg.vhd
|
||||||
|
analyze ../rtps_package.vhd
|
||||||
|
analyze ../user_config.vhd
|
||||||
|
analyze ../rtps_config_package.vhd
|
||||||
|
analyze ../rtps_test_package.vhd
|
||||||
|
analyze ../rtps_handler.vhd
|
||||||
|
analyze Level_0/rtps_handler_test1.vhd
|
||||||
|
|
||||||
|
simulate rtps_handler_test1
|
||||||
@ -257,11 +257,11 @@ package body rtps_config_package is
|
|||||||
begin
|
begin
|
||||||
ret := 0;
|
ret := 0;
|
||||||
for i in 0 to str'length-1 loop
|
for i in 0 to str'length-1 loop
|
||||||
for j in 0 to (str(i)'length/8)-1 loop
|
for j in 0 to (WORD_WIDTH/BYTE_WIDTH)-1 loop
|
||||||
-- Count Bytes
|
-- Count Bytes
|
||||||
ret := ret + 1;
|
ret := ret + 1;
|
||||||
-- Exit on first NULL byte (NULL Byte included in count)
|
-- Exit on first NULL byte (NULL Byte included in count)
|
||||||
if (str(i)(str(i)'length-j*8-1 downto str(i)'length-j*8-8) = (7 downto 0 => '0')) then
|
if (str(i)(WORD_WIDTH-(j*BYTE_WIDTH)-1 downto WORD_WIDTH-(j*BYTE_WIDTH)-BYTE_WIDTH) = (BYTE_WIDTH-1 downto 0 => '0')) then
|
||||||
exit;
|
exit;
|
||||||
end if;
|
end if;
|
||||||
end loop;
|
end loop;
|
||||||
@ -613,8 +613,7 @@ package body rtps_config_package is
|
|||||||
len := len + 1;
|
len := len + 1;
|
||||||
ret.data(ind+len):= DOMAIN_ID;
|
ret.data(ind+len):= DOMAIN_ID;
|
||||||
-- DOMAIN TAG
|
-- DOMAIN TAG
|
||||||
-- TODO: Check if Guard works
|
if (DOMAIN_TAG /= EMPTY_STRING) then
|
||||||
if (USER_DOMAIN_TAG /= "") then
|
|
||||||
tmp := string_len(DOMAIN_TAG);
|
tmp := string_len(DOMAIN_TAG);
|
||||||
len := len + 1;
|
len := len + 1;
|
||||||
ret.data(ind+len) := PID_DOMAIN_TAG & std_logic_vector(to_unsigned((round_div(tmp,4)+1)*4, 16));
|
ret.data(ind+len) := PID_DOMAIN_TAG & std_logic_vector(to_unsigned((round_div(tmp,4)+1)*4, 16));
|
||||||
|
|||||||
@ -182,7 +182,7 @@ begin
|
|||||||
data_in_aligned <= input(39 downto 8);
|
data_in_aligned <= input(39 downto 8);
|
||||||
when "10" =>
|
when "10" =>
|
||||||
data_in_aligned <= input(47 downto 16);
|
data_in_aligned <= input(47 downto 16);
|
||||||
when "11" =>
|
when others => --"11"
|
||||||
data_in_aligned <= input(55 downto 24);
|
data_in_aligned <= input(55 downto 24);
|
||||||
end case;
|
end case;
|
||||||
end process;
|
end process;
|
||||||
@ -1008,7 +1008,7 @@ begin
|
|||||||
when PUSH_PAYLOAD_HEADER =>
|
when PUSH_PAYLOAD_HEADER =>
|
||||||
-- NOTE: This is a synchronised push on potentially multiple output FIFOs. If one FIFO gets full, the process stalls for all FIFOs.
|
-- NOTE: This is a synchronised push on potentially multiple output FIFOs. If one FIFO gets full, the process stalls for all FIFOs.
|
||||||
-- Output FIFO Guard
|
-- Output FIFO Guard
|
||||||
if (builtin_endpoint = '1' and builtin_full = '0') or (builtin_endpoint = '0' and ((user_endpoint and user_full) = (user_endpoint'reverse_range => '0'))) then
|
if (builtin_endpoint = '1' and builtin_full = '0') or (builtin_endpoint = '0' and ((user_endpoint and user_full) = (user_endpoint'range => '0'))) then
|
||||||
cnt_next <= cnt + 1;
|
cnt_next <= cnt + 1;
|
||||||
|
|
||||||
case (cnt) is
|
case (cnt) is
|
||||||
@ -1076,7 +1076,7 @@ begin
|
|||||||
when PUSH_PAYLOAD =>
|
when PUSH_PAYLOAD =>
|
||||||
-- NOTE: This is a synchronised push on potentially multiple output FIFOs. If one FIFO gets full, the process stalls for all FIFOs.
|
-- NOTE: This is a synchronised push on potentially multiple output FIFOs. If one FIFO gets full, the process stalls for all FIFOs.
|
||||||
-- Output FIFO Guard
|
-- Output FIFO Guard
|
||||||
if (builtin_endpoint = '1' and builtin_full = '0') or (builtin_endpoint = '0' and ((user_endpoint and user_full) = (user_endpoint'reverse_range => '0'))) then
|
if (builtin_endpoint = '1' and builtin_full = '0') or (builtin_endpoint = '0' and ((user_endpoint and user_full) = (user_endpoint'range => '0'))) then
|
||||||
cnt_next <= cnt + 1;
|
cnt_next <= cnt + 1;
|
||||||
|
|
||||||
case (opcode) is
|
case (opcode) is
|
||||||
|
|||||||
@ -2,6 +2,7 @@ library ieee;
|
|||||||
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
||||||
use ieee.numeric_std.all;
|
use ieee.numeric_std.all;
|
||||||
use ieee.math_real.CEIL;
|
use ieee.math_real.CEIL;
|
||||||
|
use ieee.math_real.TRUNC;
|
||||||
|
|
||||||
package rtps_package is
|
package rtps_package is
|
||||||
|
|
||||||
@ -49,7 +50,6 @@ package rtps_package is
|
|||||||
|
|
||||||
-- *TYPES DEFINITION*
|
-- *TYPES DEFINITION*
|
||||||
-- Generic Types
|
-- Generic Types
|
||||||
type STRING_WORD_ARRAY_TYPE is array (0 to ((256*BYTE_WIDTH)/WORD_WIDTH)-1) of std_logic_vector(WORD_WIDTH-1 downto 0); -- Strings are constrained to 256 Characters
|
|
||||||
type DOUBLE_WORD_ARRAY is array (0 to 1) of unsigned(WORD_WIDTH-1 downto 0);
|
type DOUBLE_WORD_ARRAY is array (0 to 1) of unsigned(WORD_WIDTH-1 downto 0);
|
||||||
-- RTPS
|
-- RTPS
|
||||||
-- TODO: Define unconstrained WORD_ARRAY and define constrained subtypes
|
-- TODO: Define unconstrained WORD_ARRAY and define constrained subtypes
|
||||||
@ -260,7 +260,7 @@ package rtps_package is
|
|||||||
constant RELIABLE_RELIABILITY_QOS : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(2,CDR_ENUMERATION_WIDTH));
|
constant RELIABLE_RELIABILITY_QOS : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(2,CDR_ENUMERATION_WIDTH));
|
||||||
constant DEFAULT_RELIABILTY_QOS : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := RELIABLE_RELIABILITY_QOS;
|
constant DEFAULT_RELIABILTY_QOS : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := RELIABLE_RELIABILITY_QOS;
|
||||||
-- MAX BLOCKING TIME (RELIABILITY)
|
-- MAX BLOCKING TIME (RELIABILITY)
|
||||||
constant DEFAULT_MAX_BLOCKING_TIME : DURATION_TYPE := gen_duration(0,100 * (10**6)); -- 100 ms
|
constant DEFAULT_MAX_BLOCKING_TIME : DURATION_TYPE; --Deferred to Package Body (100 ms)
|
||||||
-- TRANSPORT_PRIORITY
|
-- TRANSPORT_PRIORITY
|
||||||
constant DEFAULT_TRANSPORT_PRIORITY_QOS : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0');
|
constant DEFAULT_TRANSPORT_PRIORITY_QOS : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0');
|
||||||
-- LIFESPAN
|
-- LIFESPAN
|
||||||
@ -295,7 +295,7 @@ package rtps_package is
|
|||||||
constant DEFAULT_DURABILITY_SERVICE_MAX_INSTANCES : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := std_logic_vector(to_signed(-1,CDR_LONG_WIDTH)); -- LENGTH_UNLIMITED
|
constant DEFAULT_DURABILITY_SERVICE_MAX_INSTANCES : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := std_logic_vector(to_signed(-1,CDR_LONG_WIDTH)); -- LENGTH_UNLIMITED
|
||||||
constant DEFAULT_DURABILITY_SERVICE_MAX_SAMPLES_PER_INSTANCE: std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := std_logic_vector(to_signed(-1,CDR_LONG_WIDTH)); -- LENGTH_UNLIMITED
|
constant DEFAULT_DURABILITY_SERVICE_MAX_SAMPLES_PER_INSTANCE: std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := std_logic_vector(to_signed(-1,CDR_LONG_WIDTH)); -- LENGTH_UNLIMITED
|
||||||
|
|
||||||
constant DEFAULT_PARTICIPANT_LEASE_DURATION : DURATION_TYPE := gen_duration(100, 0); -- 100 s
|
constant DEFAULT_PARTICIPANT_LEASE_DURATION : DURATION_TYPE; -- Deferred to package Body (100 s)
|
||||||
|
|
||||||
-- *BUILTIN ENDPOINT SET POSITIONS*
|
-- *BUILTIN ENDPOINT SET POSITIONS*
|
||||||
constant DISC_BUILTIN_ENDPOINT_PARTICIPANT_ANNOUNCER : natural := 0;
|
constant DISC_BUILTIN_ENDPOINT_PARTICIPANT_ANNOUNCER : natural := 0;
|
||||||
@ -358,6 +358,32 @@ end package;
|
|||||||
|
|
||||||
package body rtps_package is
|
package body rtps_package is
|
||||||
|
|
||||||
|
function gen_duration(s,ns : integer) return DURATION_TYPE is
|
||||||
|
variable ret : DURATION_TYPE := (others => (others => '0'));
|
||||||
|
-- "unit" is the value of "ret(1)" equal to 1 nanosecond
|
||||||
|
-- (1 / 2^-32) * 10^-9
|
||||||
|
constant unit : real := 4.294967296;
|
||||||
|
constant sec : natural := 10**9;
|
||||||
|
constant half_sec : natural := sec/2;
|
||||||
|
begin
|
||||||
|
assert (ns < 10**9) report "ns argument has to be less than a second" severity failure;
|
||||||
|
ret(0) := to_unsigned(s, 32);
|
||||||
|
|
||||||
|
-- If Fraction Bit is >= 500 ms it cannot be represented as a natural (because naturals/integers are signed).
|
||||||
|
-- So we handle that manualy
|
||||||
|
if (ns >= half_sec) then
|
||||||
|
ret(1)(31) := '1';
|
||||||
|
ret(1) := to_unsigned(natural(CEIL(real(ns/2)*unit)),32);
|
||||||
|
else
|
||||||
|
ret(1) := to_unsigned(natural(CEIL(real(ns)*unit)),32);
|
||||||
|
end if;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
end function;
|
||||||
|
|
||||||
|
constant DEFAULT_MAX_BLOCKING_TIME : DURATION_TYPE := gen_duration(0,100 * (10**6)); -- 100 ms
|
||||||
|
constant DEFAULT_PARTICIPANT_LEASE_DURATION : DURATION_TYPE := gen_duration(100, 0); -- 100 s
|
||||||
|
|
||||||
function convert_from_double_word (input: DOUBLE_WORD_ARRAY) return unsigned is
|
function convert_from_double_word (input: DOUBLE_WORD_ARRAY) return unsigned is
|
||||||
variable ret : unsigned(63 downto 0) := (others => '0');
|
variable ret : unsigned(63 downto 0) := (others => '0');
|
||||||
begin
|
begin
|
||||||
@ -516,16 +542,4 @@ package body rtps_package is
|
|||||||
return ret;
|
return ret;
|
||||||
end function;
|
end function;
|
||||||
|
|
||||||
function gen_duration(s,ns : integer) return DURATION_TYPE is
|
|
||||||
variable ret : DURATION_TYPE := (others => (others => '0'));
|
|
||||||
-- "unit" is the value of "ret(1)" equal to 1 nanosecond
|
|
||||||
-- (1 / 2^-32) * 10^-9
|
|
||||||
constant unit : real := 4.294967296;
|
|
||||||
begin
|
|
||||||
assert (ns < 10**9) report "ns argument has to be less than a second" severity failure;
|
|
||||||
ret(0) := to_unsigned(s, 32);
|
|
||||||
ret(1) := to_unsigned(natural(CEIL(real(ns)*unit)),32);
|
|
||||||
return ret;
|
|
||||||
end function;
|
|
||||||
|
|
||||||
end package body;
|
end package body;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user