Compare commits

...

27 Commits
tmp ... master

Author SHA1 Message Date
9aa7607d92 Add missing hps_0.h Header File 2023-08-03 18:01:36 +02:00
d73fe79b60 Add sw Folder with related source code for practical testing 2023-07-30 16:41:56 +02:00
df67cf626d Update and resynthesize all examples in GHRD Project 2023-07-30 16:09:55 +02:00
4c51a3944a Add UDP loopback in De10-Nano GHRD Project and generate output files
The UDP loopback just reads from the input FIFO, reverses src and destination
addresses, and writes back to the output FIFO.
This can be used to measure the throughput of the HPS-FPGA communication
2023-07-29 12:23:06 +02:00
84fd330802 Add ROS RTT in DE10-Nano GHRD Project and generate output files 2023-07-28 23:52:18 +02:00
676101f287 Update .gitignore 2023-07-27 13:23:52 +02:00
0e085a3b03 Modify DDS Writer/Reader to instantiate the Key Holder only when WITH_KEY=true 2023-07-27 13:23:52 +02:00
d3a69dbe99 Fix multiple driver issue in test_loopback_util.vhd 2023-07-27 13:23:52 +02:00
66ed1d846b Modify conditional operators in moving_average.vhd for Quartus compatibility 2023-07-27 13:23:52 +02:00
a20890e126 Modify test_top and config for ROS RTT Test and add to DE10-Nano Project 2023-07-27 13:23:52 +02:00
c667c6ed5e Add ROS Level 2 RTT Test
A new Level 2 ROS test is defined, that is similar to the DDS loopback test
and can be used to measure the round trip time between a server and a client.
L2_Testbench_ROS_Lib6 is the server implementation, while L2_Testbench_ROS_Lib7
is the client implementation.
A custom (ROS) type is also defined (Type1).
Read the comments in L2_ROS_Loopback_test1 for implementation details.
2023-07-27 13:23:46 +02:00
a1e0297fcb Add GHRD Quartus Project
The Golden Hardware Reference Design (GHRD) is used to implement designs
with PS support.
The UDP/IP stack of the Linux running on the PS is used to move UDP packets
to/from the PL.
2023-07-23 14:12:50 +02:00
d8647ddec9 Move SDC file specific to DE10-Nano Quartus project to project root 2023-07-23 14:12:50 +02:00
f0cc29fcd6 Modified Type Size convention
The RTPS Payload size overhead was defined in the rtps_package, and is to be
used by all type packages to calculate the MAX_<TYPENAME>_SIZE.
The service overhead size was also renamed to ROS_SERVICE_OVERHEAD_BYTES to
make the connection with ROS clearer.
2023-07-22 14:46:49 +02:00
5f7f2685c2 Refactor some TEMPLATE VHDL files 2023-07-22 14:46:49 +02:00
41814f6bcc Update Altera implementation of FWFT_FIFO
Update the Altera implemenation of the FWFT FIFO to allow write
and read on the smae cycle when the FIFO is full.
This is a requirement for the moving_average implementation.
2023-07-22 14:46:49 +02:00
8004f21a7c Add moving_average VHDL Implementation
Add a configurable moving_average implementaion, that has a configurable
window size and is enable triggered.
Also add a moving_average_wrapper that instantiates 2 moving_average instances
(an inner and an outer) to lower the memory resource requirement for large
window sizes. Effective window size is OUTER*INNER, whereas the resources are
only OUTER+INNER. A trigger signal signals when the average is "valid".

Accompanying testebench was also implemented.
2023-06-24 00:02:02 +02:00
c318b3c560 Re-design Key Holder interaction of DDS Reader/Writer
The DDS Writer was expecting the user to provide the serialized key
on DISPOSE/UNREGISTER operations. The user should have no direct
interaction with the serialized key.
The operation flow was changed to expect the normal payload from the
user, push it to the Key Holder, and the calculate the serialized key.
The stage that was responsible for simutanously pushing the input to
payload memory and/or the Key Holder was simplified, and the decode
error signal of the Key Holder is now handled.

The last two changes (simplified stage and decode error handling)
were also ported to the DDS Reader.
2023-06-22 20:11:17 +02:00
d2c0b37c27 Change latching behaviour of "last_word_in" latches
During testing a scenario arose, where a toggling in the last_word
signal lane while the rest of the signals were not valid was falsely
latched.
All entities with "last_word_in" latches were modifies to only latch
the signal when in valid state.
2023-06-22 08:18:23 +02:00
35baf341c7 Bug Fix: DDS Reader and Writer Interfaces had no signal passthrough for non-Type dependent Operations
The ready/valid Signals were missing from the DDS Reader and Writer Interfaces,
preventing the user from effectively using non-Type dependent operations
(like GET_OFFERED_DEADLINE_MISSED_STATUS).
The L1_Type1_test1 was extended to test for this non-type dependent operation.
2023-06-17 13:32:58 +02:00
d2d40c1326 Bug Fix: Key_Holder was not resetting the decode_error signal
Fixed Updated Template-, Type1-, and Type2-key_holder to reset the
decode_error signal when a new PUSH_* operation is initiated.
Testbenches are extended to test foe decode_error and its reset.
2023-06-17 10:48:16 +02:00
3f2e4e82d1 Fix Bug in TEMPLATE_ros_action_server, that could lead to deadlocks.
The server could at any time reset and sever the connection of the user to the
result memory, that could lead to the user indefenitely waiting for a droped
memory read request.
The server now only sever the connection when the result memory has no pending
requests.
L1_Fibanacci_ros_ation_server_test1 and L1_Fibanacci_ros_ation_server_test2
are exetnded to test the fix.
2023-06-17 10:48:16 +02:00
839170c5ad Fix Bug in TEMPLATE_ros_action_client where sequence_id & request_id output signals are only valid for one clock cycle. 2023-06-17 10:48:16 +02:00
c577d4f671 Update IDL-VHDL Generation: Make length of nested collections available for WRITER Interface
In case of nested collections in a WRITER Interface, the length of the
collection is latched into memories, but the output is not made available
to the user. Since the signal is lacthed either way, making the stored
value also available to the user gives more flexibility to the user.
2023-06-17 10:48:16 +02:00
d537cd7460 Documentation Refactoring (Fix Typos) 2023-06-17 10:48:16 +02:00
ca80910494 Documentation & Code Refactoring 2023-06-17 10:48:11 +02:00
5f58b0bca4 Fix testbench for Linux OS (Linux is case Sensitive) 2023-06-16 14:02:44 +02:00
231 changed files with 18725 additions and 2396 deletions

19
.gitignore vendored
View File

@ -1,32 +1,19 @@
#Ignore List
/syn/**
/sim/**
*.NPPSESS
.vscode/**
#Unignore Directories (Needed to unignore files in Subdirectories)
!*/
#WHITELIST
#***VIVADO***
#Project File
!*.xpr
#***MODELSIM***
#Do files
!*.do
#Modelsim INI File
!*modelsim.ini
#***QUARTUS***
#Project File
!*.qpf
#Settings File
!*.qsf
#QSYS File
!*.qsys
#Constraint File
!*.sdc
#Unignore VHDL Files in syn Directory First Level
!/syn/*.vhd
#Delete download from existence
/download
/download/**
/download/**

View File

@ -12,11 +12,11 @@ AUTOMATICALLY
-------------
* Open Terminal in /sim directory
* Run 'vsim -do test_all.do'
* Run 'vsim -c -do test_all.do'
NOTE: After some time the compilation of the simulator gets sluggisly slow.
I noticed that deleting the Libraries and re-creating them re-vitalizes the speed
In order to do so start a simulation (so that the Library is loaded), make sure that you end the current simulation, and type 'RemoveAllLibraries'. After a vsim re-start everything shoudl run faster
NOTE: After some time the compilation of the simulator gets sluggishly slow.
I noticed that deleting the Libraries and re-creating them re-vitalizes the speed.
In order to do so start a simulation (so that the Library is loaded), make sure that you end the current simulation, and type 'RemoveAllLibraries'. After a vsim re-start everything should run faster
RUN ON BOARD
============

View File

@ -1,127 +0,0 @@
---------------------------------------------------------------------------------
Start RTL Component Statistics (1 Buffer)
---------------------------------------------------------------------------------
Detailed RTL Component Info :
+---Adders :
3 Input 14 Bit Adders := 1
2 Input 14 Bit Adders := 3
2 Input 9 Bit Adders := 1
+---Registers :
400 Bit Registers := 1
88 Bit Registers := 1
32 Bit Registers := 1
14 Bit Registers := 5
9 Bit Registers := 1
4 Bit Registers := 1
1 Bit Registers := 3
+---RAMs :
512K Bit RAMs := 1
+---Muxes :
2 Input 400 Bit Muxes := 2
18 Input 400 Bit Muxes := 1
2 Input 32 Bit Muxes := 10
18 Input 32 Bit Muxes := 2
2 Input 14 Bit Muxes := 1
18 Input 14 Bit Muxes := 4
18 Input 9 Bit Muxes := 1
17 Input 5 Bit Muxes := 1
2 Input 5 Bit Muxes := 10
2 Input 2 Bit Muxes := 2
2 Input 1 Bit Muxes := 7
18 Input 1 Bit Muxes := 16
---------------------------------------------------------------------------------------------------
State | New Encoding | Previous Encoding
---------------------------------------------------------------------------------------------------
ipv4_init | 00000 | 00000
ipv4_header_1 | 00001 | 00001
ipv4_header_2 | 00010 | 00010
ipv4_header_3 | 00011 | 00011
ipv4_header_4 | 00100 | 00100
ipv4_header_5 | 00101 | 00101
skip_header | 00110 | 01111
ipv4_fragment_pre | 00111 | 01000
ipv4_fragment | 01000 | 01001
ipv4_fragment_post | 01001 | 01010
ipv4_buffer_src | 01010 | 01011
ipv4_buffer_dest | 01011 | 01100
ipv4_buffer_length | 01100 | 01101
ipv4_buffer_payload | 01101 | 01110
skip_packet | 01110 | 10000
iSTATE | 01111 | 11111
ipv4_payload_length | 10000 | 00110
ipv4_payload | 10001 | 00111
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------
Start RTL Component Statistics (0 Buffer)
---------------------------------------------------------------------------------
Detailed RTL Component Info :
+---Adders :
2 Input 14 Bit Adders := 3
3 Input 14 Bit Adders := 1
2 Input 9 Bit Adders := 1
+---Registers :
400 Bit Registers := 1
88 Bit Registers := 1
14 Bit Registers := 5
9 Bit Registers := 1
4 Bit Registers := 1
1 Bit Registers := 2
+---Muxes :
2 Input 400 Bit Muxes := 2
2 Input 32 Bit Muxes := 7
12 Input 32 Bit Muxes := 1
2 Input 14 Bit Muxes := 1
11 Input 4 Bit Muxes := 1
2 Input 4 Bit Muxes := 7
2 Input 1 Bit Muxes := 4
12 Input 1 Bit Muxes := 7
---------------------------------------------------------------------------------------------------
State | New Encoding | Previous Encoding
---------------------------------------------------------------------------------------------------
ipv4_init | 0000 | 00000
ipv4_header_1 | 0001 | 00001
ipv4_header_2 | 0010 | 00010
ipv4_header_3 | 0011 | 00011
ipv4_header_4 | 0100 | 00100
ipv4_header_5 | 0101 | 00101
skip_header | 0110 | 01111
ipv4_fragment_pre | 0111 | 01000
ipv4_payload_length | 1000 | 00110
ipv4_payload | 1001 | 00111
skip_packet | 1010 | 10000
iSTATE | 1011 | 11111
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------
Start RTL Component Statistics (No Frag)
---------------------------------------------------------------------------------
Detailed RTL Component Info :
+---Adders :
2 Input 14 Bit Adders := 1
3 Input 14 Bit Adders := 1
+---Registers :
14 Bit Registers := 1
4 Bit Registers := 1
+---Muxes :
2 Input 32 Bit Muxes := 3
11 Input 32 Bit Muxes := 1
10 Input 4 Bit Muxes := 1
2 Input 4 Bit Muxes := 5
2 Input 1 Bit Muxes := 1
11 Input 1 Bit Muxes := 6
---------------------------------------------------------------------------------------------------
State | New Encoding | Previous Encoding
---------------------------------------------------------------------------------------------------
ipv4_init | 0000 | 0000
ipv4_header_1 | 0001 | 0001
ipv4_header_2 | 0010 | 0010
ipv4_header_3 | 0011 | 0011
ipv4_header_4 | 0100 | 0100
ipv4_header_5 | 0101 | 0101
skip_header | 0110 | 1000
ipv4_payload_length | 0111 | 0110
ipv4_payload | 1000 | 0111
skip_packet | 1001 | 1001
iSTATE | 1010 | 1111
---------------------------------------------------------------------------------------------------

BIN
doc/DDSI-RTPS_2-0.pdf (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,45 @@
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -divider SYSTEM
add wave -noupdate /l0_moving_average_wrapper_test1/uut/clk
add wave -noupdate /l0_moving_average_wrapper_test1/uut/reset
add wave -noupdate -divider WRAPPER
add wave -noupdate -radix unsigned /l0_moving_average_wrapper_test1/uut/data_in
add wave -noupdate -radix unsigned /l0_moving_average_wrapper_test1/uut/average
add wave -noupdate /l0_moving_average_wrapper_test1/uut/trigger
add wave -noupdate /l0_moving_average_wrapper_test1/uut/overflow
add wave -noupdate -divider INNER
add wave -noupdate /l0_moving_average_wrapper_test1/uut/inner_average_inst/enable
add wave -noupdate -radix unsigned /l0_moving_average_wrapper_test1/uut/inner_average_inst/data_in
add wave -noupdate -radix unsigned /l0_moving_average_wrapper_test1/uut/inner_average_inst/average
add wave -noupdate /l0_moving_average_wrapper_test1/uut/inner_average_inst/overflow
add wave -noupdate /l0_moving_average_wrapper_test1/uut/inner_average_inst/fifo_full
add wave -noupdate -divider OUTER
add wave -noupdate /l0_moving_average_wrapper_test1/uut/outer_average_inst/enable
add wave -noupdate -radix unsigned /l0_moving_average_wrapper_test1/uut/outer_average_inst/data_in
add wave -noupdate -radix unsigned /l0_moving_average_wrapper_test1/uut/outer_average_inst/average
add wave -noupdate /l0_moving_average_wrapper_test1/uut/outer_average_inst/overflow
add wave -noupdate /l0_moving_average_wrapper_test1/uut/outer_average_inst/fifo_full
add wave -noupdate -divider MISC
add wave -noupdate /l0_moving_average_wrapper_test1/uut/inner_cnt
add wave -noupdate /l0_moving_average_wrapper_test1/uut/outer_cnt
add wave -noupdate /l0_moving_average_wrapper_test1/uut/inner_trigger
add wave -noupdate /l0_moving_average_wrapper_test1/uut/outer_trigger
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {400000 ps} 0}
quietly wave cursor active 1
configure wave -namecolwidth 150
configure wave -valuecolwidth 100
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} {1007104 ps}

View File

@ -0,0 +1,124 @@
onerror {resume}
radix define ROS_RETCODE {
"10#0#" "ROS_RET_OK",
"10#1#" "ROS_RET_ERROR",
"10#2#" "ROS_RET_TIMEOUT",
"10#3#" "ROS_RET_UNSUPPORTED",
"10#10#" "ROS_RET_BAD_ALLOC",
"10#11#" "ROS_RET_INVALID_ARGUMENT",
"10#12#" "ROS_RET_INCORRECT_RMW_IMPLEMENTATION",
"10#100#" "ROS_RET_ALREADY_INIT",
"10#101#" "ROS_RET_NOT_INIT",
"10#102#" "ROS_RET_MISMATCHED_RMW",
"10#103#" "ROS_RET_TOPIC_NAME_INVALID",
"10#104#" "ROS_RET_SERVICE_NAME_INVALID",
"10#105#" "ROS_RET_UNKNOWN_SUBSTITUTION",
"10#106#" "ROS_RET_ALREADY_SHUTDOWN",
"10#200#" "ROS_RET_NODE_INVALID",
"10#201#" "ROS_RET_NODE_INVALID_NAME",
"10#202#" "ROS_RET_NODE_INVALID_NAMESPACE",
"10#203#" "ROS_RET_NODE_NAME_NON_EXISTENT",
"10#400#" "ROS_RET_SUBSCRIPTION_INVALID",
"10#401#" "ROS_RET_SUBSCRIPTION_TAKE_FAILED",
"10#500#" "ROS_RET_CLIENT_INVALID",
"10#501#" "ROS_RET_CLIENT_TAKE_FAILED",
"10#600#" "ROS_RET_SERVICE_INVALID",
"10#601#" "ROS_RET_SERVICE_TAKE_FAILED",
"10#800#" "ROS_RET_TIMER_INVALID",
"10#801#" "ROS_RET_TIMER_CANCELED",
"10#900#" "ROS_RET_WAIT_SET_INVALID",
"10#901#" "ROS_RET_WAIT_SET_EMPTY",
"10#902#" "ROS_RET_WAIT_SET_FULL",
"10#1001#" "ROS_RET_INVALID_REMAP_RULE",
"10#1002#" "ROS_RET_WRONG_LEXEME",
"10#1003#" "ROS_RET_INVALID_ROS_ARGS",
"10#1010#" "ROS_RET_INVALID_PARAM_RULE",
"10#1020#" "ROS_RET_INVALID_LOG_LEVEL_RULE",
"10#2001#" "ROS_RET_EVENT_TAKE_FAILED",
"10#2000#" "ROS_RET_ACTION_NAME_INVALID",
"10#2100#" "ROS_RET_ACTION_GOAL_ACCEPTED",
"10#2101#" "ROS_RET_ACTION_GOAL_REJECTED",
"10#2102#" "ROS_RET_ACTION_CLIENT_INVALID",
"10#2103#" "ROS_RET_ACTION_CLIENT_TAKE_FAILED",
"10#2200#" "ROS_RET_ACTION_SERVER_INVALID",
"10#2201#" "ROS_RET_ACTION_SERVER_TAKE_FAILED",
"10#2300#" "ROS_RET_ACTION_GOAL_HANDLE_INVALID",
"10#2301#" "ROS_RET_ACTION_GOAL_EVENT_INVALID",
"10#3000#" "ROS_RET_LIFECYCLE_STATE_REGISTERED",
"10#3001#" "ROS_RET_LIFECYCLE_STATE_NOT_REGISTERED",
-default unsigned
}
radix define GOAL_STATUS {
"10#0#" "STATUS_UNKNOWN",
"10#1#" "STATUS_ACCEPTED",
"10#2#" "STATUS_EXECUTING",
"10#3#" "STATUS_CANCELING",
"10#4#" "STATUS_SUCCEEDED",
"10#5#" "STATUS_CANCELED",
"10#6#" "STATUS_ABORTED",
-default unsigned
}
quietly WaveActivateNextPane {} 0
add wave -noupdate -divider SYSTEM
add wave -noupdate /l2_ros_loopback_test1/clk
add wave -noupdate /l2_ros_loopback_test1/reset
add wave -noupdate -divider {Lib7 ROS Publish}
add wave -noupdate /l2_ros_loopback_test1/Lib7_inst/Type1_ros_pub_inst/start_user
add wave -noupdate /l2_ros_loopback_test1/Lib7_inst/Type1_ros_pub_inst/opcode_user
add wave -noupdate /l2_ros_loopback_test1/Lib7_inst/Type1_ros_pub_inst/ack_user
add wave -noupdate -radix unsigned /l2_ros_loopback_test1/Lib7_inst/Type1_ros_pub_inst/id
add wave -noupdate -radix unsigned /l2_ros_loopback_test1/Lib7_inst/Type1_ros_pub_inst/a
add wave -noupdate /l2_ros_loopback_test1/Lib7_inst/Type1_ros_pub_inst/done_user
add wave -noupdate -radix ROS_RETCODE /l2_ros_loopback_test1/Lib7_inst/Type1_ros_pub_inst/return_code_user
add wave -noupdate /l2_ros_loopback_test1/Lib7_inst/Type1_ros_pub_inst/stage
add wave -noupdate -divider {Lib6 ROS Subscriber}
add wave -noupdate /l2_ros_loopback_test1/Lib6_inst/Type1_ros_sub_inst/start_user
add wave -noupdate /l2_ros_loopback_test1/Lib6_inst/Type1_ros_sub_inst/opcode_user
add wave -noupdate /l2_ros_loopback_test1/Lib6_inst/Type1_ros_sub_inst/ack_user
add wave -noupdate /l2_ros_loopback_test1/Lib6_inst/Type1_ros_sub_inst/done_user
add wave -noupdate -radix ROS_RETCODE /l2_ros_loopback_test1/Lib6_inst/Type1_ros_sub_inst/return_code_user
add wave -noupdate /l2_ros_loopback_test1/Lib6_inst/Type1_ros_sub_inst/data_available_user
add wave -noupdate -radix unsigned /l2_ros_loopback_test1/Lib6_inst/Type1_ros_sub_inst/id
add wave -noupdate -radix unsigned /l2_ros_loopback_test1/Lib6_inst/Type1_ros_sub_inst/a
add wave -noupdate /l2_ros_loopback_test1/Lib6_inst/Type1_ros_sub_inst/message_info_user
add wave -noupdate /l2_ros_loopback_test1/Lib6_inst/Type1_ros_sub_inst/taken_user
add wave -noupdate /l2_ros_loopback_test1/Lib6_inst/Type1_ros_sub_inst/stage
add wave -noupdate -divider {Lib6 ROS Publisher}
add wave -noupdate /l2_ros_loopback_test1/Lib6_inst/Type1_ros_pub_inst/start_user
add wave -noupdate /l2_ros_loopback_test1/Lib6_inst/Type1_ros_pub_inst/opcode_user
add wave -noupdate /l2_ros_loopback_test1/Lib6_inst/Type1_ros_pub_inst/ack_user
add wave -noupdate -radix unsigned /l2_ros_loopback_test1/Lib6_inst/Type1_ros_pub_inst/id
add wave -noupdate -radix unsigned /l2_ros_loopback_test1/Lib6_inst/Type1_ros_pub_inst/a
add wave -noupdate /l2_ros_loopback_test1/Lib6_inst/Type1_ros_pub_inst/done_user
add wave -noupdate -radix ROS_RETCODE /l2_ros_loopback_test1/Lib6_inst/Type1_ros_pub_inst/return_code_user
add wave -noupdate /l2_ros_loopback_test1/Lib6_inst/Type1_ros_pub_inst/stage
add wave -noupdate -divider {Lib7 ROS Subscribe}
add wave -noupdate /l2_ros_loopback_test1/Lib7_inst/Type1_ros_sub_inst/start_user
add wave -noupdate /l2_ros_loopback_test1/Lib7_inst/Type1_ros_sub_inst/opcode_user
add wave -noupdate /l2_ros_loopback_test1/Lib7_inst/Type1_ros_sub_inst/ack_user
add wave -noupdate /l2_ros_loopback_test1/Lib7_inst/Type1_ros_sub_inst/done_user
add wave -noupdate -radix ROS_RETCODE /l2_ros_loopback_test1/Lib7_inst/Type1_ros_sub_inst/return_code_user
add wave -noupdate /l2_ros_loopback_test1/Lib7_inst/Type1_ros_sub_inst/data_available_user
add wave -noupdate -radix unsigned /l2_ros_loopback_test1/Lib7_inst/Type1_ros_sub_inst/id
add wave -noupdate -radix unsigned /l2_ros_loopback_test1/Lib7_inst/Type1_ros_sub_inst/a
add wave -noupdate /l2_ros_loopback_test1/Lib7_inst/Type1_ros_sub_inst/message_info_user
add wave -noupdate /l2_ros_loopback_test1/Lib7_inst/Type1_ros_sub_inst/taken_user
add wave -noupdate /l2_ros_loopback_test1/Lib7_inst/Type1_ros_sub_inst/stage
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {2981796 ps} 0}
quietly wave cursor active 1
configure wave -namecolwidth 150
configure wave -valuecolwidth 100
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 ns
update
WaveRestoreZoom {0 ps} {2042496 ps}

View File

@ -16,18 +16,20 @@ others = $MODEL_TECH/../modelsim.ini
;
; Verilog Section
;
default = W:/HDL-SIM/OSVVM-Scripts/../sim/VHDL_LIBS/ModelSim-2020.02/default.lib
osvvm = W:/HDL-SIM/OSVVM-Scripts/../sim/VHDL_LIBS/ModelSim-2020.02/osvvm.lib
Testbench_Lib2 = W:/HDL-SIM/OSVVM-Scripts/../sim/VHDL_LIBS/ModelSim-2020.02/Testbench_Lib2.lib
Testbench_Lib3 = W:/HDL-SIM/OSVVM-Scripts/../sim/VHDL_LIBS/ModelSim-2020.02/Testbench_Lib3.lib
Testbench_Lib4 = W:/HDL-SIM/OSVVM-Scripts/../sim/VHDL_LIBS/ModelSim-2020.02/Testbench_Lib4.lib
Testbench_Lib5 = W:/HDL-SIM/OSVVM-Scripts/../sim/VHDL_LIBS/ModelSim-2020.02/Testbench_Lib5.lib
Testbench_Lib1 = W:/HDL-SIM/OSVVM-Scripts/../sim/VHDL_LIBS/ModelSim-2020.02/Testbench_Lib1.lib
Testbench_ROS_Lib1 = W:/HDL-SIM/OSVVM-Scripts/../sim/VHDL_LIBS/ModelSim-2020.02/Testbench_ROS_Lib1.lib
Testbench_ROS_Lib2 = W:/HDL-SIM/OSVVM-Scripts/../sim/VHDL_LIBS/ModelSim-2020.02/Testbench_ROS_Lib2.lib
Testbench_ROS_Lib3 = W:/HDL-SIM/OSVVM-Scripts/../sim/VHDL_LIBS/ModelSim-2020.02/Testbench_ROS_Lib3.lib
Testbench_ROS_Lib4 = W:/HDL-SIM/OSVVM-Scripts/../sim/VHDL_LIBS/ModelSim-2020.02/Testbench_ROS_Lib4.lib
Testbench_ROS_Lib5 = W:/HDL-SIM/OSVVM-Scripts/../sim/VHDL_LIBS/ModelSim-2020.02/Testbench_ROS_Lib5.lib
default = /tmp/sim_temp/VHDL_LIBS/ModelSim-2020.02/default.lib
osvvm = /tmp/sim_temp/VHDL_LIBS/ModelSim-2020.02/osvvm.lib
Testbench_Lib2 = /tmp/sim_temp/VHDL_LIBS/ModelSim-2020.02/Testbench_Lib2.lib
Testbench_Lib3 = /tmp/sim_temp/VHDL_LIBS/ModelSim-2020.02/Testbench_Lib3.lib
Testbench_Lib4 = /tmp/sim_temp/VHDL_LIBS/ModelSim-2020.02/Testbench_Lib4.lib
Testbench_Lib5 = /tmp/sim_temp/VHDL_LIBS/ModelSim-2020.02/Testbench_Lib5.lib
Testbench_Lib1 = /tmp/sim_temp/VHDL_LIBS/ModelSim-2020.02/Testbench_Lib1.lib
Testbench_ROS_Lib1 = /tmp/sim_temp/VHDL_LIBS/ModelSim-2020.02/Testbench_ROS_Lib1.lib
Testbench_ROS_Lib2 = /tmp/sim_temp/VHDL_LIBS/ModelSim-2020.02/Testbench_ROS_Lib2.lib
Testbench_ROS_Lib3 = /tmp/sim_temp/VHDL_LIBS/ModelSim-2020.02/Testbench_ROS_Lib3.lib
Testbench_ROS_Lib4 = /tmp/sim_temp/VHDL_LIBS/ModelSim-2020.02/Testbench_ROS_Lib4.lib
Testbench_ROS_Lib5 = /tmp/sim_temp/VHDL_LIBS/ModelSim-2020.02/Testbench_ROS_Lib5.lib
Testbench_ROS_Lib6 = /tmp/sim_temp/VHDL_LIBS/ModelSim-2020.02/Testbench_ROS_Lib6.lib
Testbench_ROS_Lib7 = /tmp/sim_temp/VHDL_LIBS/ModelSim-2020.02/Testbench_ROS_Lib7.lib
[vcom]
; VHDL93 variable selects language version as the default.
; Default is VHDL-2002.

View File

@ -29,7 +29,9 @@ begin
lpm_widthu => log2c(FIFO_DEPTH),
overflow_checking => "ON",
underflow_checking => "ON",
use_eab => "ON"
use_eab => "ON",
ram_block_type => "AUTO",
allow_rwcycle_when_full => "ON"
)
port map (
clock => clk,

View File

@ -13,7 +13,7 @@ The 'GET_PAYLOAD_HEADER' stage jumps to the stage handling the first declared me
Each stage jumps to the decode_stage of the next declared member.
If there is no next declared member, stage 'SKIP_PAYLOAD' is selected.
The signal 'align_offset' keeps track of the current alignement offset (Basically byte_count mod 8).
The signal 'align_offset' keeps track of the current alignment offset (Basically byte_count mod 8).
The general procedure is that the input is latched ('data_in_latch') allowing to work Byte-oriented, since
the input is word-sized. Each time the 'align_offset' reaches b"X11" a new input word is latched.
@ -23,10 +23,10 @@ The CDR Encodings of all types are Byte aligned.
PRIMITIVES TYPES
================
Primitive Types are directly latched into registers of equal size (name <NAME>_lach), that are
accesible directly via a port of the same name (i.e. <NAME>).
Primitive Types are directly latched into registers of equal size (name <NAME>_latch), that are
accessible directly via a port of the same name (i.e. <NAME>).
The name of the generated decode_stage is GET_<NAME>.
The generated decode_stage first checks the alignement and aligns the stream using the 'ALIGN_STREAM' stage.
The generated decode_stage first checks the alignment and aligns the stream using the 'ALIGN_STREAM' stage.
* Primitive size 1
The input is directly latched using the get_sub_vector function together with the current 'align_offset',
1 is added to the 'align_offset', the decode_stage of the next declared member is taken, and the 'FETCH'
@ -54,9 +54,9 @@ The generated decode_stage first checks the alignement and aligns the stream usi
NOTE: The extra sub-stage is used to push the signal to a memory in a single operation
NOTE: If there is no next declared member, the last sub-stage should not call the "FETCH" stage.
(Should be overriden by "SKIP_PAYLOAD")
(Should be overridden by "SKIP_PAYLOAD")
The alignements and sizes for IDL primitive types are following:
The alignments and sizes for IDL primitive types are following:
IDL TYPE SIZE ALIGNMENT [2]
int8/uint8 1 1
@ -88,7 +88,7 @@ BIT_BOUND PRIMITIVE [3]
COLLECTION TYPES
================
In contrast to primitive types, collection types are latched into memories of equal width and depth
In contrast to primitive types, collection types are latched into same width memories and with a depth
equal to the maximum length. Memory access port signals are made available to the user to allow to access
the contents.
@ -101,7 +101,7 @@ Following Port signals are defined:
NAME DIRECTION CONNECTED
<NAME>_len out <NAME>_len_latch
<NAME>_addr in <NAME>_mem_addr in 'IDLE' stage
<NAME>_ready out <NAME>_mem_ready_in in 'IDLE' stage, else '0' [NOTE: ANDing for aggregated elment types (see Structures below)]
<NAME>_ready out <NAME>_mem_ready_in in 'IDLE' stage, else '0' [NOTE: ANDing for aggregated element types (see Structures below)]
<NAME>_ren in <NAME>_mem_read and <NAME>_mem_valid_in in 'IDLE' stage
<NAME>_valid out <NAME>_mem_valid_out [NOTE: ANDing for aggregated element types (see Structures below)]
<NAME>_ack in <NAME>_mem_ready_out in 'IDLE' stage
@ -116,8 +116,8 @@ NAME DIRECTION CONNECTED
type package. A special <NAME>_cnt counter (used to index the type specific memory) is initialized to 0.
NOTE: It could be configured, that instead of truncating larger sequences, a decode error is triggered.
* GET_<NAME>
This stage is similar to the respective primitive decode_stage with following valiations:
The <NAME>_cnt is used to set the current <NAME>_mem_addr. On sucessful latch
This stage is similar to the respective primitive decode_stage with following variations:
The <NAME>_cnt is used to set the current <NAME>_mem_addr. On successful latch
(<NAME>_mem_valid_in and <NAME>_ready_in = '1') the align_offset is incremented by the
respective size, the <NAME>_cnt is incremented, and if the current <NAME>_cnt is equal to
<NAME>_len-1, the decode_stage of the next declared member is taken.
@ -212,7 +212,7 @@ A new <NAME>_opt port signal is defined, that is connected to a <NAME>_opt_latch
The previous decode_stage selects the 'GET_OPTIONAL_HEADER' decode_stage, and sets the 'return_stage'
to the actual next decode_stage (The decode_stage of the optional member).
The first generated decode_stage of the <NAME> (i.e. the stage that was in return_stage) checks
the 'optional' signal before anything else (even before the alignement). If 'optional' is '0', it sets
the 'optional' signal before anything else (even before the alignment). If 'optional' is '0', it sets
the <NAME>_opt_latch to '0' and selects the decode_stage of the next declared member. Otherwise
the <NAME>_opt_latch is set to '1'.
@ -229,7 +229,7 @@ In General the writer_interface is a similar layout to the reader_interface with
All "GET_*" stages are renamed to "WRITE_*".
The "FETCH" stage is renamed to "PUSH".
'write_sub_vector' is used to write into 'data_out_latch' (instead of 'get_sub_vector' and 'data_in_latch').
The direction of the <NAME> port signals are inverted (i.e. in).
The direction of the <NAME> port signals are inverted.
Instead of calling 'SKIP_PAYLOAD' stage on the last declared member, the 'PUSH' stage is explicitly called
and the 'encode_done' and 'finalize_payload' signals are set.
@ -248,7 +248,7 @@ The <NAME>_len_latch is removed (Since the Length is now an input).
The 'WRITE_<NAME>' encode_stage is divided with the help of 'cnt' into 2 sub-stages.
The first sub-stage is responsible for requesting the value from the memory (Memory READ request).
The second sub-stage waits until the value is valid (<NAME>_mem_valid_out) and does the usual write
procedure. On sucessfull write the <NAME>_mem_ready_out has to be pulsed high to finalize the memory
procedure. On successful write the <NAME>_mem_ready_out has to be pulsed high to finalize the memory
operation.
NOTE: If the encode_stage already is divided into sub-stages (due to the primitive type), a single
sub-stage is added that does the Memory fetch operation, and the <NAME>_mem_ready_out is pulled high
@ -261,10 +261,13 @@ SEQUENCE/MAP
------------
In case the nested collection is a sequence/map, a <INNER_COLLECTION_NAME>_len_mem memory is again needed
for storing the individual sequence lengths, similar to the reader_interface.
The <INNER_COLLECTION_NAME>_len signal is split into 2 signals named <INNER_COLLECTION_NAME>_len_r and
<INNER_COLLECTION_NAME>_len_w and connected to the <INNER_COLLECTION_NAME>_len_mem_data_out and
<INNER_COLLECTION_NAME>_len_mem_data_in memory signals (similar to the <NAME>_r and <NAME>_w ports described above).
The memory signal connections are similar to the normal write_interface collection case, allowing the
length to be stored when a write to the outer collection happens.
The WRITE_<INNER_COLLECTION_NAME>_LENGTH stage has to be implemented, similar to the normal collection
case, with a extra sub-stage for the memory fetch operation.
case, with an extra sub-stage for the memory fetch operation.
OPTIONALS
@ -298,21 +301,21 @@ The 'ALIGN_STREAM' stage is split into 'ALIGN_IN_STREAM' (for decode_stage) and
The decode procedure (decode_stage stages) follows 2 different decoding procedures.
The first - taken on a 'PUSH_DATA' opcode - follows the reader_interface procedure of the <TOPIC> type until
the last declared member that is also member of the KeyHolder(<NAME>)[6] Type (i.e. the last decalred
the last declared member that is also member of the KeyHolder(<NAME>)[6] Type (i.e. the last declared
key of the type), after which the 'SKIP_PAYLOAD' stage is taken.
(Since the serialized key only uses the KeyHolder(<NAME>) members, the rest is ignored)
The second - taken on a 'PUSH_SERIALIZED_KEY' opcode - follows the reader_interface procedure of the
KeyHolder(<NAME>) directly.
Since the decode_stages for the second decoding procedure are a subset of the first decoding procedure,
the same decode stages are used, and only the 'decode_stage_next' signal is set depending on the
'opcode_latch' signal. The 'GET_PAYLAOD_HEADER' stage selects the correct first decode stage.
'opcode_latch' signal. The 'GET_PAYLOAD_HEADER' stage selects the correct first decode stage.
Similarly the encode procedure also follows 2 different encoding procedures.
The first - taken on a 'READ_SERIALIZED_KEY' opcode - follows the write_interface procedure of the
KeyHolder(<NAME>) Type.
The second - taken on a 'READ_KEY_HASH' opcode (if the key is not already calculated) - follows the
write_interface procedure of the <NAME>KeyHolder[7] Type. Note that this encoding is in PLAIN_CDR2
Big Endian, meaning that types wich have an ALIGN_8 in PLAIN_CDR have a ALIGN_4 in PLAIN_CDR2.
Big Endian, meaning that types which have an ALIGN_8 in PLAIN_CDR have a ALIGN_4 in PLAIN_CDR2.
Both encoding procedures share the same encode_stages, and the 'encode_stage_next' signal is
set depending on the 'opcode_latch' signal. On a 'READ_SERIALIZED_KEY' opcode the
'WRITE_PAYLOAD_HEADER' stage selects the first encode_stage, while on a 'READ_KEY_HASH' opcode the
@ -331,4 +334,4 @@ PITFALLS
[4] DDS_XTYPES v1.3, 7.4.1.1.4
[5] DDS_XTYPES v1.3, 7.4.1.1.5.2
[6] DDS_XTYPES v1.3, 7.2.2.4.7
[7] DDS_XTYPES v1.3, 7.6.8
[7] DDS_XTYPES v1.3, 7.6.8

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@ use ieee.numeric_std.all;
use work.rtps_package.all;
use work.rtps_config_package.all;
architecture TYPENAME of key_holder is
architecture TEMPLATE of key_holder is
--*****COMPONENT DECLARATION*****
component key_hash_generator is
@ -135,7 +135,7 @@ begin
-- ###GENERATED END###
-- Last Word Latch Setter
if (last_word_in = '1') then
if (last_word_in = '1' and valid_in = '1') then
last_word_in_latch_next <= '1';
end if;
@ -150,12 +150,14 @@ begin
ack <= '1';
stage_next <= GET_PAYLOAD_HEADER;
-- Reset
key_hash_next <= KEY_HASH_NIL;
key_hash_next <= KEY_HASH_NIL;
decode_error_latch_next <= '0';
when PUSH_SERIALIZED_KEY =>
ack <= '1';
stage_next <= GET_PAYLOAD_HEADER;
-- Reset
key_hash_next <= KEY_HASH_NIL;
key_hash_next <= KEY_HASH_NIL;
decode_error_latch_next <= '0';
when READ_KEY_HASH =>
ack <= '1';
-- Key Hash not calculated
@ -198,7 +200,7 @@ begin
when CDR_BE =>
endian_flag_next <= '0';
stage_next <= FETCH;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
if (opcode_latch = PUSH_DATA) then
-- ###GENERATED START###
@ -213,7 +215,7 @@ begin
when CDR_LE =>
endian_flag_next <= '1';
stage_next <= FETCH;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
if (opcode_latch = PUSH_DATA) then
-- ###GENERATED START###
@ -289,7 +291,7 @@ begin
stage_next <= FETCH;
decode_stage_next <= return_stage;
cnt_next <= 0;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- Optional omitted
@ -299,7 +301,7 @@ begin
optional_next <= '1';
end if;
end if;
-- eMemberHeader
-- eMemberHeader
when 1 =>
-- Ignore Parameter ID
cnt_next <= cnt + 1;
@ -309,7 +311,7 @@ begin
stage_next <= FETCH;
decode_stage_next <= return_stage;
cnt_next <= 0;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- Optional omitted
@ -335,7 +337,7 @@ begin
-- Output Guard
if (ready_out = '1') then
stage_next <= ENCODE_PAYLOAD;
-- Reset
-- Reset
align_offset_next <= (others => '0');
data_out_latch_next <= (others => '0');
-- ###GENERATED START###
@ -539,4 +541,4 @@ begin
end if;
end process;
end architecture;
end architecture;

View File

@ -48,6 +48,10 @@ entity TYPENAME_reader_interface is
get_data_user : in std_logic;
done_user : out std_logic;
return_code_user : out std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
valid_out_user : out std_logic;
ready_out_user : in std_logic;
data_out_user : out std_logic_vector(WORD_WIDTH-1 downto 0);
last_word_out_user : out std_logic;
-- Sample Info
sample_info_user : out SAMPLE_INFO_TYPE;
sample_info_valid_user : out std_logic;
@ -87,7 +91,7 @@ architecture arch of TYPENAME_reader_interface is
signal optional, optional_next : std_logic;
signal abort_mem : std_logic;
signal ready_in_dds_sig : std_logic;
signal valid_sig, valid_sig_next : std_logic;
signal valid_latch, valid_latch_next : std_logic;
signal decode_stage, decode_stage_next : DECODE_STAGE_TYPE;
signal return_stage, return_stage_next : DECODE_STAGE_TYPE;
-- ###GENERATED START###
@ -125,7 +129,7 @@ begin
eoc_user <= eoc_dds;
status_user <= status_dds;
valid <= valid_sig;
valid <= valid_latch;
decode_error <= decode_error_latch;
ready_in_dds <= ready_in_dds_sig;
@ -147,7 +151,7 @@ begin
align_offset_next <= align_offset;
target_align_next <= target_align;
optional_next <= optional;
valid_sig_next <= valid_sig;
valid_latch_next <= valid_latch;
data_in_latch_next <= data_in_latch;
align_op_next <= align_op;
abort_mem <= '0';
@ -157,7 +161,7 @@ begin
-- ###GENERATED END###
-- Last Word Latch Setter
if (last_word_in_dds = '1') then
if (last_word_in_dds = '1' and valid_in_dds = '1') then
last_word_in_latch_next <= '1';
end if;
@ -168,9 +172,13 @@ begin
stage_next <= GET_PAYLOAD_HEADER;
-- RESET
decode_error_latch_next <= '0';
valid_sig_next <= '0';
valid_latch_next <= '0';
abort_mem <= '1';
else
valid_out_user <= valid_in_dds;
ready_in_dds_sig <= ready_out_user;
data_out_user <= data_in_dds;
last_word_out_user <= last_word_in_dds;
-- ###GENERATED START###
-- MEMORY SIGNAL CONNECTIONS
-- ###GENERATED END###
@ -185,7 +193,7 @@ begin
when CDR_BE =>
endian_flag_next <= '0';
stage_next <= FETCH;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- ###GENERATED START###
decode_stage_next <= TODO;
@ -194,7 +202,7 @@ begin
when CDR_LE =>
endian_flag_next <= '1';
stage_next <= FETCH;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- ###GENERATED START###
decode_stage_next <= TODO;
@ -232,21 +240,6 @@ begin
stage_next <= FETCH;
end if;
end if;
when SKIP_PAYLOAD =>
if (last_word_in_latch = '0') then
-- Skip Read
ready_in_dds_sig <= '1';
else
stage_next <= IDLE;
-- If no Decode Error, mark output as valid
if (decode_error_latch = '0') then
valid_sig_next <= '1';
end if;
-- Reset
last_word_in_latch_next <= '0';
end if;
when DECODE_PAYLOAD =>
case (decode_stage) is
-- ###GENERATED START###
@ -269,7 +262,7 @@ begin
stage_next <= FETCH;
decode_stage_next <= return_stage;
cnt_next <= 0;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- Optional omitted
@ -279,7 +272,7 @@ begin
optional_next <= '1';
end if;
end if;
-- eMemberHeader
-- eMemberHeader
when 1 =>
-- Ignore Parameter ID
cnt_next <= cnt + 1;
@ -289,7 +282,7 @@ begin
stage_next <= FETCH;
decode_stage_next <= return_stage;
cnt_next <= 0;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- Optional omitted
@ -305,6 +298,21 @@ begin
when others =>
null;
end case;
when SKIP_PAYLOAD =>
if (last_word_in_latch = '0') then
-- Skip Read
ready_in_dds_sig <= '1';
else
stage_next <= IDLE;
-- If no Decode Error, mark output as valid
if (decode_error_latch = '0') then
valid_latch_next <= '1';
end if;
-- Reset
last_word_in_latch_next <= '0';
end if;
when others =>
null;
end case;
@ -331,7 +339,7 @@ begin
last_word_in_latch <= '0';
decode_error_latch <= '0';
optional <= '0';
valid_sig <= '0';
valid_latch <= '0';
align_op <= '0';
align_offset <= (others => '0');
data_in_latch <= (others => '0');
@ -348,7 +356,7 @@ begin
last_word_in_latch <= last_word_in_latch_next;
decode_error_latch <= decode_error_latch_next;
optional <= optional_next;
valid_sig <= valid_sig_next;
valid_latch <= valid_latch_next;
align_op <= align_op_next;
align_offset <= align_offset_next;
data_in_latch <= data_in_latch_next;

View File

@ -47,6 +47,10 @@ entity TYPENAME_writer_interface is
done_user : out std_logic;
return_code_user : out std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
instance_handle_out_user : out INSTANCE_HANDLE_TYPE;
valid_out_user : out std_logic;
ready_out_user : in std_logic;
data_out_user : out std_logic_vector(WORD_WIDTH-1 downto 0);
last_word_out_user : out std_logic;
-- Communication Status
status_user : out std_logic_vector(STATUS_KIND_WIDTH-1 downto 0);
@ -100,6 +104,10 @@ begin
return_code_user <= return_code_dds;
instance_handle_out_user <= instance_handle_out_dds;
status_user <= status_dds;
valid_out_user <= valid_in_dds;
ready_in_dds <= ready_out_user;
data_out_user <= data_in_dds;
last_word_out_user <= last_word_in_dds;
-- ###GENERATED START###
-- PORT SIGNAL CONNECTIONS
@ -118,7 +126,6 @@ begin
finalize_payload_next <= finalize_payload;
abort_mem <= '0';
encode_done <= '0';
ready_in_dds <= '0';
valid_out_dds <= '0';
last_word_out_dds <= '0';
data_out_dds <= (others => '0');

View File

@ -5,7 +5,7 @@
- TwinOaks Computing Inc (CoreDX)
- OpenVPX
* Implementation makes unnecessary transitions, that are ignored in later stages.
This was a design decision to simplify complexity of each stage (and probably FMAX), but increases power consumtion.
This was a design decision to simplify complexity of each stage (and probably FMAX), but increases power consumption.
* Is the Timestamp used by something else except ordering by source? If not, does it have to be "sane"?
2.2.3.16
This QoS relies on the sender and receiving applications having their clocks sufficiently synchronized. If this is not the case
@ -33,6 +33,7 @@
If reliability is BEST_EFFORT then the Service is allowed to drop samples. If the reliability is
RELIABLE, the Service will block the DataWriter or discard the sample at the DataReader in order not to lose existing
samples.
- It means that if the reliability is RELIABLE, and the Reader has no more space for a sample, the Reader will not accept any more samples (hence discard, and by extension block further writes in the Writer, if the Writer has also no more space for storing samples, since the Reader is no longer accepting his sends) until the application takes samples.
* What is now the valid Parameter List length?
According to DDSI-RTPS 9.4.2.11
The length encodes the number of octets following the length to reach the ID of the next parameter (or the ID of the sentinel). Because every parameterId starts on a 4-byte boundary, the length is always a multiple of four.
@ -50,8 +51,9 @@
duplicate messages that can result from the presence of redundant communication paths."
But then, in 8.4.15.7 it says:
"So, an implementation should ensure that same logical HEARTBEATs are tagged with the same Count."
Does that mean there are cases were I have to put the same count? What is a logical HEARTBEAT?
Does that mean there are cases where I have to put the same count? What is a logical HEARTBEAT?
* Should a "Keyed" Endpoint communicate with a "Non-Keyed"? (In the sense of Entity Kind)
- Well, since the Topic determines if it is keyed or keyless, and since Endpoints are matched by topics, only Endpoints of either type will be matched.
* 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?)
* Can we make an array of records of uncontrained strings? Than we could make an array of variable sized strings...
@ -71,6 +73,7 @@
* Assert Heartbeat period > Heartbeat Suppression Period
* Can I request (NACK) SNs that were NOT announced by the writer (> last_sn in Heartbeat)?
* Does AUTOMATIC Liveliness QoS also update the lease on write/assert_liveliness operations?
- unspecified. Only requirement is that automatic liveliness is asserted at least faster than the required period
* The Lease Duration is also updated if the Cache Change is not accepted by the DDS/HC. This in effect "skews" the "correctness" of the Writer Liveliness Protocol until the reader has no pending request from the Writer.
* If an Instance is DISPOSED, but later has no active writers, the Instance STAYS in the NOT_ALIVE_DISPOSED state.
* Is a Writer that is Disposing an Instance also Unregistering that instance? (Currently only Unregistering removes the remote Writer)
@ -78,14 +81,13 @@
* Since Lifespan is a duration, there is an inherent difference in the expiration time between writer and reader. This in addition to the fact that the reader may use the Reception time for the expiration time calculation could lead to an actual expiration duration almost double in length (If sent right before expiring locally in the writer).
* The current implementation will sent a second unregister/dispose Sample, if the user does the unregister/dispose operation a second time. Should we handle that specially?
* If a Keyed Reader receives a DATA Message with no Key hash and no Payload, it will drop it since there is no way to determine the instance (And the SN will never be accepted).
* If a Best Effort Remote Reader sends a ACKNACK, he will indirectly receive a lease deadline and may timeout (DoS Attack)
* If a Best Effort Remote Reader sends an ACKNACK, he will indirectly receive a lease deadline and may timeout (DoS Attack)
* Since the Instance Handle has to be Unique but also orderable, we could use the actual Instance Memory Base Address. Since the Instances are in a list, we also have implicitly an order to all registered Instances. [It may be necessary to add a PREV pointer to the IMF to better support the read_previous_isntance operation]
- Not possible, because according to 2.2.2.5.3.16 read_next_instance, DDS v1.4:
'This ordering is between the instance handles: It [...] must be defined even for instance handles that do not correspond to instances currently managed by the DataReader.'
* Does the DEADLINE_QOS apply also to NOT_ALIVE Instances? (Current implementation makes no distinction)
* Does TIME_BASED_FILTER also apply to meta-samples (DISPOSED, NO_WRITERS)? That is an easy way to not get convergent state in different DDS Readers. What do other implementations do?
* The Participant GUID of the ParticipantMessageData is theoretically not needed, since it is the same as the source GUID of the Packet. This is done, so that the ParticipantMessageData has a key and can be decrypted as every other DATA Message. Our implementation checks if it is the expected GUID and drops it otherwise.
- see (https://issues.omg.org/issues/DDSIRTP21-4)
* The Participant GUID of the ParticipantMessageData is theoretically not needed, since it is the same as the source GUID of the Packet, but tt forms the DDS key together with the kind field. Our implementation checks if it is the expected GUID and drops it otherwise.
* The Discovery Module skips a Packet it doesn't understand. The Discovery Module does not parse "serialized key" of DATA messages (since the specification does not actually define what the serialized key even is). So a SPDP DATA Packet with in-line QoS (PID_STATUS_INFO) and serialized key will be dropped if the Discovery Module does not know the GUID, and that may stall the whole process pipeline (since the SN will be never acknowledged)
* Is the parameter header of an optional member in CDR_LE also endian swapped?
- Yes. (See Figure 24, 7.4.1.2.1, DDS-XTYPES 1.3)
@ -112,6 +114,23 @@
We have to change the RTPS Reader to request the last SN, if the RTPS Writer did not publish for a minimum_separation period.
* [8.4.7.1 RTPS Writer, DDSI-RTPS 2.3] states:
"nackSuppressionDuration = ignore requests for data from negative acknowledgments that arrive too soon after the corresponding change is sent."
* According to [Table 8.9, 8.2.6 The RTPS Endpoint, DDSI-RTPS 2.3], topicKind "indicates wether the Endpoint supports instance lifecycle management operations", while at the same time "indicates wether the Endpoint is associated with a DataType that has defined some fields as containing the DDS Key".
This implies that key-less Topics DO NOT have instance lifecycle management operations (i.e. no register/unregister/dispose operations)
* Section [8.7 Implementing DDS QoS and advanced DDS features using RTPS] states:
"This sub clause forms a normative part of the specification for the purpose of interoperability."
- Which means that it is part of the Specification and NOT optional. Hence why 8.4.2.2.5 requires writers to send Writer Group Information for the purposes of interoperability.
- Since LIVELINESS is also a DDS QoS why is the Writer Liveliness Protocol described in section [8.4.13 Writer Liveliness Protocol] of the Behaviour Module? It should also be described in section 8.7. As a matter of fact, section 8.4.13 explicitly states "The DDS specification requires the presence of a liveliness mechanism. RTPS realizes this requirement with the Writer Liveliness Protocol." while section 8.7 describes how the components introduced in section 8.4.13 can be used to implement the LIVELINESS QoS.
* Section [9.3.1.2 Mapping of the EntityId_t] describes the correct mapping for Reader/Writers with/without key. How should Entities with GUIDs not following these rules be handled? Is it even illegal?
* Section [2.3.2 PIM to PSM Mapping Rules] of the DDS specification explicitly states "The reason is that DCPS targets 'C' as one of the key deployment languages"
* Section [9.6.2.2 Simple Discovery Protocol built-in Endpoints] implicitly defines the DDS keys of the built-in topics, by defining a key-only DATA message. Table 9.14 than also explicitly maps PID_ENDPOINT_GUID to the TopicBuiltinTopicData::key, SubscriptionBuiltinTopicData::key, and PublicationBuiltinTopicData::key fields.
Should the key mapping also be explicitly written in text form.
* I don't understand the use case of the PID_DIRECTED_WRITE of the RTPS specification. It was added with OMG issue (https://issues.omg.org/issues/DDSIRTP2-16), but is explained terribly.
"The serialized information denotes the GUIDs of the targeted reader(s)."
Isn't that the purpose of the Reader/Writer GUID of the DATA Submessage?
Can I have multiple PID_DIRECTED_WRITE?
* Since the DDS Reader is waiting on USER via the 'sample_info_ack' signal before continuing, a single user can stall all other USERs/Readers (DoS) of a vector entity of the DDS Reader.
* Source Port of SPDP is irrelevant, since it is BEST EFFORT and we do not reply (only Destination Port is of significance)
* According to "2.2.4.2.2 Changes in Read Communication Statuses" in the DDS 1.4 Specification it seems like it is meant to modify existing samples, instead of generating new data-less ones in order to transition the instance state.
* Fast-RTPS does not follow DDSI-RTPS Specification
- Open Github Issue
@ -132,24 +151,47 @@
interpret the Reader entityIds appearing in the Submessages that follow it.'
But state is changed as follows 'Receiver.destGuidPrefix = InfoDestination.guidPrefix'.
Isn't Reader -> Writer also valid? Does it have a specific direction?
- 9.4.5.3 Data Submessage
writerSN is incorrectly shown as only 32 bits in width
- 8.2.3 The RTPS CacheChange
Add IDL Specification for CacheChange_t
- 8.3.4 The RTPS Message Receiver, Table 8.16 - Initial State of the Receiver
Port of UnicastReplyLocatorList should be initialized to Source Port.
- 8.3.4.1 Rules Followed by the Message Receiver
'Submessage and when it should be considered invalid.'
This belongs to the previous sentence.
- 8.3.7
"Contains information regarding the value of an application Date-object."
Shoulbe be Data-object
Should be Data-object
- 8.3.7.2.3 Validity
"inlineQos is invalid."
It is not specified what an invalid inlineQoS is.
- 8.3.7.4.3 Validity
gapList.Base >= gapStart
- 8.3.7.4.5 Logical Interpretation
'See section 8.7.6 for how DDS uses this feature.'
Wrong reference. 8.7.5 correct
- 8.3.7.5.5 Logical Interpretation
'These fields provide relate the CacheChanges of Writers belonging to a Writer Group.'
Remove provide
'See 8.7.6 for how DDS uses this feature.'
Wrong reference. 8.7.5 correct
- 8.3.7.10.3 Validity
'This Submessage is invalid when the following is true:
submessageLength in the Submessage header is too small'
But if InvalidateFlag is set, Length can be Zero. Since the length is unsigned, there cannot be an invalid length.
- 8.3.7.11.1
"Given the size of a SequenceNumberSet is limited to 256, an AckNack Submessage is limited to NACKing only those samples whose sequence number does not not exceed that of the first missing sample by more than 256."
'Given the size of a SequenceNumberSet is limited to 256, an AckNack Submessage is limited to NACKing only those samples whose sequence number does not not exceed that of the first missing sample by more than 256.'
Remove one not
- 8.4.2.2.5 Sending Heartbeats and Gaps with Writer Group Information
This rules seems like a last minute addition and does not follow the format until now.
Maybe rewrite as "Writers must send Heartbeats and Gaps with Writer Group Information"?
'A Writer belonging to a Group shall send HEARTBEAT or GAP Submessages to its matched Readers even if the Reader has acknowledged all of that Writers samples.'
This sentence has nothing in common with the actual requirement/rule. Usually the first sentence following the actual requirement explains the requirement in more detail.
Is this sentnce do be understood in addition or instead of the actual requirement/rule?
'The exception to this rule is when the Writer has sent DATA or DATA_FRAG Submessages that contain the same information.'
Link section 8.7.6 which states how this information is sent
- 8.4.7 RTPS Writer Reference Implementation
According to 8.2.2 the History Cache (HC) is the interface between RTPS nad DDS, and can be invoked
by both RTPS and DDS Entities.
@ -160,6 +202,8 @@
This goes against 8.4.7 (and Table 8.5), which states that the RTPS Writer is adding the Cache Changes to the HC
and is responsible for assigning Sequence Numbers.
- Well, according to the Virtual machine, the new_change() method is invoked on the RTPS Writer
- 8.4.13.4 Data Types Associated with Built-in Endpoints used by Writer Liveliness Protocol
Figure 8.26 states that GUID_t is used, but the PSM (9.6.2.1) maps GuidPrefix_t (Which also makes more sense)
- 8.7.2.2.1 DURABILITY
'While volatile and transient-local durability do not affect the RTPS protocol'
But in case of Durability TRANSIENT_LOCAL the writer has to send historical Data.
@ -171,9 +215,31 @@
MANUAL_BY_PARTICIPANT Liveliness.
- 8.7.3.2 Indicating to a Reader that a Sample has been filtered
Text refs 8.3.7.2.2 for DataFlag, but shoudl also ref 8.7.4 for FilteredFlag
- 8.7.4 Changes in the Instance State
Wrong reference 9.6.3.4 (Correct 9.6.3.9)
- 8.7.4 Changes in the Instance State
'The DDS DataReader can determine the nature of the change by inspecting the InstanceState instance_state field in the SampleInfo that is returned on the DDS DataReader read or take call.'
'The serialized information within the inline QoS contains the new InstanceState, that is, whether the instance has been registered, unregistered, or disposed.'
The Specification uses the term "InstanceState" to mean both the instance states defined in the DDS specification (ALIVE, NOT_ALIVE_DISPOSED, NOT_ALIVE_NO_WRITERS) and the ChangeKind_t (ALIVE, ALIVE_FILTERED, NOT_ALIVE_DISPOSED, NOT_ALIVE_UNREGISTERED) defined in 8.2.1.2
This section should do a mapping between the two, or rename the "local" ones and use the respective terms uniformly.
- 8.7.7 Directed Write
Mention or link the PID_DIRECTED_WRITE?
- 8.7.9 Original Writer Info
"This service that forwards messages"
Replace "This" with "The"
"The RTPS protocol suports this forwarding of messages by including information of the original writer."
supports
- 9.2.2
Add newline to IDL definition after "OctetArray3 entityKey;"
- 9.3.1.2 Mapping of the EntityId_t
Add newline to IDL definition after "typedef octet OctetArray3[3];"
- 9.3.2.4 GroupDigest_t
Missing "EntityId_t" struct type name on the second struct IDL definition.
- 9.4.5.1.2 Flags
Clarify from where the endianness begins.
One might think it would begin after the Submessage Header, but the length is also endian dependent.
- 9.4.5.3 Data Submessage
writerSN is incorrectly shown as only 32 bits in width
- 9.4.5.3.1 Data Flags
"D=1 and K=1 is an invalid combination in this version of the protocol."
Does this invalidate the Submessage? Does 8.3.4.1 apply (Invalidate rest of Message)?
@ -204,6 +270,8 @@
- 8.2.1 Overview
Figure 8.1 should contain the RTPS Group Entry (it even has its own section 8.2.6)
It should also get an Entry in the Table 8.1
- 8.5.4.4 Data Types associated with built-in Endpoints used by the Simple Endpoint Discovery Protocol
Figure 8.30 does not represent the types defined in DDS Specification
- 8.7.5 Group Ordered Access
"A DataReader attached to a Subscriber configured with access scope GROUP" should be Reader (RTPS), and not DataReader (DDS)
- This section has general incosistency in the use of the RTPS and DDS counterparts
@ -227,64 +295,144 @@
But the opration only returns InstanceHandle_t. Other vendors return HANDLE_NIL also on error and not only
"if the Service does not want to allocate any handle for that instance".
It should propably behave like the Lookup_Instance operation.
* Source Port of SPDP is irrelevant, since it is BEST EFFORT and we do not reply (only Destination Port is of significance)
- General
Clarify semantic difference between lost and rejected samples.
- General
How handling of MAX_INSTANCES is affected by the HISTORY QoS Policy
- General
The DDS Specification does not explicitly state that the behaviour of the Register/Unregister/Dispose Operations have on non-keyed Topics
- General
The DDS Specification is not entirely clear how to handle transition between the NOT_ALIVE states. Going by the
petri-net state-flowchart transitions between the NOT_ALIVE states are not allowed, meaning that the first taken
NOT_ALIVE state stays until the instance is reborn. But since the Disposal of an Instance is of higher
Information value, we should support transitioning from NOT_ALIVE_NO_WRITERS to NOT_ALIVE_DISPOSED.
- General
An RTPS CacheChange is not equal to a DDS Sample. (e.g. an unregister CacheChange does not necessarily translate
to a DDS Sample). State the translation.
DESIGN DECISIONS
================
GENERAL
-------
* !REJECTED!
In order to save memory GUID should only be saved once.
Decision was made to replace GUID with internal reference index.
Discovery module is responsible for saving the GUID and map it to a refernece index, that can then be used by other entities.
Writer Endpoints may need access to the real GUID for message fields.
2 options exist:
In order to save memory GUID should only be saved once. Decision was made to replace GUID with internal reference
index. Discovery module is responsible for saving the GUID and map it to a reference index, that can then be used
by other entities. Writer Endpoints may need access to the real GUID for message fields.
2 options exist:
- All Endpoints have access to the central memory where the real GUID is saved (needs Arbiter, handle starvation)
- Writer Endpoints fill the fields with the reference index as placeholder, and a seperate Entity will access the central memory and replace the actual values
- Writer Endpoints fill the fields with the reference index as placeholder, and a separate Entity will access
the central memory and replace the actual values
The Second option was chosen (Less resources)
RTPS Handler should lookup received message GUID in central memory (The lookup should happen in parallel with the actual message handling):
RTPS Handler should lookup received message GUID in central memory (The lookup should happen in parallel with the
actual message handling):
- If not stored, and message not for Discovery Module, drop message
- If in memory, replace with refernece index
The central memory is accessd by 3 Entities:
- If in memory, replace with reference index
The central memory is accessed by 3 Entities:
- RTPS Handler (READ, GUID Lookup)
- Placeholder Handler (READ, GUID Lookup)
- Discovery Module (WRITE, GUID Save) [Need initial Lookup? RTPS Handler should have already handled it. How does DM know if actual GUID or reference index?]
- Discovery Module (WRITE, GUID Save) [Need initial Lookup? RTPS Handler should have already handled it. How
does DM know if actual GUID or reference index?]
Use a 2-port RAM with an arbiter for READ operations (Give Placeholder Handler priority to prevent DoS starvation)
* Use the lowest bit of the Heartbeat/Acknack Deadline stored in the Participant Data to differentiate
* Use the lowest bit of the Heartbeat/Acknack Deadline stored in the memory to differentiate
between Delay and Suppression. This reduces the resolution from 0.23 ns to 0.47 ns
(A previous version was using the unused extra flags in the stored participant data)
* Originally we stored the mask of local matching endpoints in the memory frame of the remote endpoint
in order to be able to send MATCH frames only to new matches, and UNMATCH frames only to previously
matched local endpoints. This decision was reverted, and we just sent MATCH frames to the currently
matched local endpoints (non depending on if they are already matched) and UNMATCH frames to the
* Initially the RTPS/DDS Endpoints were designed as one Endpoint per Entity. This allows maximum parallel
processing and each entity having the bare minimum HW based on generics that define the properties of
each Endpoint. Nevertheless the amount of Resources needed to synthesize are quite substantial, and there
is a (low) limit of how many Endpoints can be instantiated. This limit was reached when trying to
synthesize a ROS action server, which instantiates 9 RTPS and DDS Endpoints.
Since the only real difference between the Endpoints is the Memory, we could reuse the main state
machine for all Endpoints and just instantiate different memories.
A redesign of all Endpoints was decided, in which multiple Endpoints are simulated by one Entity.
The contained Endpoints are addressed in sequential order, meaning that we lose the parallel processing,
but since the RTPS protocol is primarily used over UDP, there is no difference in performance.
Although the ports of the entity could remain single dimension (since only one Endpoint is
reading/writing at a time), we would lose the information of which Endpoint is addressed and would have
to extend the inter-communication schema to relay this information. To avoid this, and to be backwards
compatible (allow to instantiate multiple Endpoint Entities), the dimensions of the ports of the
Endpoints will be extended by the dimension of Endpoints contained with some exceptions.
These exceptions are the all RTPS Output ports, and the read, data_in, and last_word_in RTPS Handler
and DISCOVERY Module ports. This prevents wasting resources on FIFOs, but still conveys addressing
information via the empty signal.
This works, because the RTPS Handler and DISCOVERY MODULE write in a multicast fashion (meaning that all
addressed Entities become the same data).
* The above decision brings with it another challenge. Since now the input signals are unbalanced
(empty port is vector, but read, data_in, and last_word_in are not) we need a special kind of FIFO
to connect to the input ports of the Endpoints. This special FIFO is called "vector_FIFO" and contains
a FIFO for the data, and a FIFO for the write signal, that is internally converted to the empty signal
and simulates multiple FIFOs.
DISCOVERY MODULE
----------------
* Originally we stored the mask of local matching endpoints in the memory frame of the remote participant
in order to be able to send MATCH frames only to new matches, and UNMATCH frames only to previously
matched local endpoints. This decision was reverted, and we just sent MATCH frames to the currently
matched local endpoints (non depending on if they are already matched) and UNMATCH frames to the
rest of the local endpoints (non depending on if they were previously matched).
So we basically push the responsibility to the local endpoints, which have to handle these situations
accordingly. Since META traffic is not supposed to be generated as often, this should not produce
any significant overhead. As optimization, on new matched remote endpoints UNMATCH frames can be
So we basically push the responsibility to the local endpoints, which have to handle these situations
accordingly. Since META traffic is not supposed to be generated as often, this should not produce
any significant overhead. As optimization, on new matched remote endpoints UNMATCH frames can be
ignored.
* The HEARTBEATs are sent out together with the liveliness assertions. This adds a 96-Byte overhead
to the output RTPS Message. This was done to prevent having to loop through the memory to find
* The HEARTBEATs are sent out together with the liveliness assertions. This adds a 96-Byte overhead
to the output RTPS Message. This was done to prevent having to loop through the memory to find
remote participant destination more than once.
* The Publisher, Subscriber, and Message Data is written on separate RTPS Messages, even though they are
sent simutanously. This decision was made to support as many local Endpoints as possible. We could
make a compile-time check and sent them in the same RTPS Message/UDP Packet, but the overhead is
* The Publisher, Subscriber, and Message Data is written on separate RTPS Messages, even though they are
sent simultaneously. This decision was made to support as many local Endpoints as possible. We could
make a compile-time check and sent them in the same RTPS Message/UDP Packet, but the overhead is
quite small and not worth the hassle.
* Even though the Reader does not need to keep track of received SN with respect to each Writer with
exception of the Highest/Last received (since it only keeps the SN in order and does only need to
request from the last stored SN on), the writer does need to keep track of the requested SN (and
RTPS ENDPOINTS
--------------
* Even though the Reader does not need to keep track of received SN with respect to each Writer with
exception of the Highest/Last received (since it only keeps the SN in order and does only need to
request from the last stored SN on), the writer does need to keep track of the requested SN (and
possibly also the acknowledgements).
This could be solved by either storing the SN in a bitmap in the endpoint data, or be storing the
requester bitmap (endpoint data address) in the change data.
But since the writer might drop SN in any order, the highest and lowest SN inside the cache history
is unbounded. We can thus only reference to still available SN, and not to GAPs.
In order to acoomodate for that, we could store the lowest (and possibly highest) SN of a requested
This could be solved by either storing the SN in a bitmap in the endpoint data, or by storing the
requester bitmap (endpoint data address) in the cache change data.
But since the writer might drop SNs in any order, the highest and lowest SN inside the cache history
is unbounded. We can thus only reference to still available SNs, and not to GAPs.
In order to accommodate for that, we could store the lowest (and possibly highest) SN of a requested
lost SN and always send ALL GAPs in that range.
* Since the RTPS Writer only gets ACKNACK Messages from the matched Readers, and these Messages are
dropped by the rtps_handler if smaller than expected, we do not need a "READ GUARD" in the RTPS
Writer.
* Because "Once Acknowledged, Always Acknowledged" the Base of an ACKNACK can only be bigger or
equal to the SN of the last ACKNACK. It is also reasonable, that the Reader will always request
ALL missing segments each time it sends an ACKNACK (i.e. does not assume once requested, always
requested until reception). This means that during the ACKNACK response delay, we can just parse
the new request bitmap and overwrite the last old one.
* In the RTPS Writer remote Volatile Reliable Readers are initialized with a SN equal to
the last written. This means that while the Reader can access the historical SNs via ACKNACK, the SNs
are not NACKed in the HC, and can therefore be removed at any time, not depending on the state of the
remote reader.
* The RTPS Writer is only sending GAPs when processing ACKNACK Requests or sending Historical DATA.
That means that if the HC pulls the 'data_available' Signal and deletes Cache Changes before the
RTPS Writer has requested them, it will just ignore the Cache Change. A GAP will only be generated
if a reliable Reader subsequently requests this Cache Change.
* If PUSH_MODE is false, packets are only written as response to ACKNACK requests (except HEARTBEATS).
This means that a Reliable RTPS Writer in PUSH_MODE = FALSE cannot communicate with Best Effort Readers.
Historical Data is also only sent out on request (But NACKed in the HC, until the remote Reader ACKs them).
* Following the vector entity change, since the message format from RTPS reader to DDS reader contains information
specific to the individual writer (Writer ID, Lifespan Deadline), we cannot write to multiple DDS endpoints at the
same time. This means that we have to temporarily store the payload and push it to each DDS Endpoint individually.
DDS ENDPOINTS
-------------
* The meta_data (sample info) of a cache change is fixed size, and a cache change may be connected to
data (payload), which may be variable in size. For this reason, we store the cache change and
@ -294,7 +442,8 @@ DESIGN DECISIONS
of the next linked memory frame. If this is the last frame (or if the payload is static and there
are no linked frames), the address is MAX_ADDRESS.
* !REJECTED! The last bit of this address is the "occupied" bit. This bit signifies if the memory
* !REJECTED!
The last bit of this address is the "occupied" bit. This bit signifies if the memory
frame is used or free, and is used for the insert operation to find a new empty slot. This in
effect means that all frame sizes have to be a multiple of 2 (all frame addresses have to be
aligned to 2).
@ -303,7 +452,8 @@ DESIGN DECISIONS
Payload slot, we mark this via a bit in the sample info memory, and store the last address of the
actual payload in the last address of the payload slot.
* !REJECTED! The History Cache (HC) is the interface between RTPS and DDS. The History Cache contains
* !REJECTED!
The History Cache (HC) is the interface between RTPS and DDS. The History Cache contains
the Sample Info and Payload memories. The HC has two input "sides", one is connected to the DDS
and one to the RTPS entity. Housing the memories inside the HC entity and abstracting the direct
memory address via opcode requests allows the memory interface to be replaced in future (e.g. AXI
@ -321,12 +471,15 @@ DESIGN DECISIONS
* Since most of the DDS QoS need information that is directly available to the History Cache (HC),
it makes sense to integrate most of the DDS functionality directly into the HC to save up space
and performance. Further more the needed stored information for a DDS Entity is different enough
from the generic HC defined in the RTPS Specification to warrant a seperate entity for both.
from the generic HC defined in the RTPS Specification to warrant a separate entity for both.
The DDS Entity will directly connect to the RTPS Endpoint. A separate generic HC will be
implemented, that follows the RTPS Specification.
The RTPS Endpoint will have to output multiple versions of Changes, depending on the connected
Entity, in order to facilitate this design decision.
* Since the "reading" side needs to have consistent state during it's processing, it does not make
sense to implement dual port RAMs for the History Cache.
* Because the Key Hash has to be known in order to make an ACCEPT/REJECT decision for the new
Sample, and the fact that the Key Hash is not always given and has to be manually calculated from
the payload, we need "buffer" slots to store the Sample and Payload until the decision can be
@ -344,42 +497,6 @@ DESIGN DECISIONS
to multiple Sample removals (One prior the addition in order to free up a Payload "buffer", and
one after addition as a result of QoS policies).
* Since the "reading" side needs to have consistent state during it's processing, it does not make
sense to implement dual port RAMs for the History Cache.
* Since the RTPS Writer only gets ACKNACK Messages from the matched Readers, and these Messages are
dropped by the rtps_handler if smaller than expected, we do not need a "READ GUARD" in the RTPS
Writer.
* Because "Once Acknowledged, Always Acknowledged" the Base of an ACKNACK can only be bigger or
equal to the SN of the last ACKNACK. It is also reasonable, that the Reader will always request
ALL missing segments each time it sends an ACKNACK (i.e. does not assume once requested, always
requested until reception). This means that during the ACKNACK response delay, we can just parse
the new request bitmap and overwrite the last old one.
* In the RTPS Writer remote Volatile Reliable Readers are initialized with a SN equal to
the last written. This means that while the Reader can access the historical SNs via ACKNACK, the SNs
are not NACKed in the HC, and can therefore be removed at any time, not depending on the state of the
remote reader.
* Since all code related to encoding/decoding the DATA stream is dependent on the IDL type
specification, we have to encapsule that code separately and link them as necessary. Two such
dynamic Entities are defined: KEY_HOLDER, and <TYPENAME>_INTERFACE.
The KEY_HOLDER Entity contains a Byte-Wide internal memory (In size equal to the maximum key size),
that can be filled with PLAIN_CDR/PL_CDR DATA Streams, and Serialized Key Streams.
The Entity allows outputting the memory contents (Key) either in a KEY_HASH format (needs
to instantiate a MD5 calculator), or in Serialized Key Format. The Entity uses the start/opcode/ack
interface for operations (similar to the RTPS/DDS Interface).
The <TYPENAME>_INTERFACE entity has all type-components linked to ports and latched in registers/memory.
In output mode the entity is able to fill the registers/memory with a PLAIN_CDR/PL_CDR Data Stream, and
in input mode the registers are filled directly from the input ports and the Entity is able to produce
a PLAIN_CDR/PL_CDR Data Stream from the registers/memory.
Due to the type-specific nature of the entities, those are not instantiated inside the DDS Endpoints,
but will be instantiated in a seperate entity (Interface) and linked through port mapping with the
DDS Endpoints.
X: Due to port mapping differences between DDS Reader and Writer the <TYPENAME>_INTERFACE is splitt into
<TYPENAME>_READER_INTERFACE and <TYPENAME>_WRITER_INTERFACE.
* Due to the requirements of read_next_instance/take_next_instance of the DDS Reader, the Instances are
inserted in numerical Key Hash order into the Instance Memory. This extra sorting logic is not needed
in the DDS Writer, where Instances are inserted normally to the end of the List.
@ -394,12 +511,13 @@ DESIGN DECISIONS
lead to inconsistent behavior (see REF.txt). RTI has thus decided to only delete unregistered
instances. I will copy this behavior.
* !REJECTED! DATA WRITER: Once an instance is unregistered, it is eligible for deletion except if it is
* !REJECTED!
DATA WRITER: Once an instance is unregistered, it is eligible for deletion except if it is
Re-registered, or a write operation occurs on that instance. Disposal of an unregistered Instance
does not re-register the instance (State remains NOT_ALIVE) and is still eligible for deletion.
NOTE: The statement above is incorrect, as a writer wanting to dispose an Intsnace has to re-register
NOTE: The statement above is incorrect, as a writer wanting to dispose an Instance has to re-register
the Instance. Hence, it is re-registered (and the disposing writer is again active), the state
Instance remains howerer in a NOT_ALIVE state.
Instance remains however in a NOT_ALIVE state.
* The DDS Specification does not explicitly state that the behaviour of the Register/Unregister/Dispose
Operations have on non-keyed Topics. RTI basically does a NOP and does not modify the instance in
@ -409,7 +527,7 @@ DESIGN DECISIONS
* The DDS Specification states that if after an Unregister Operation "the application wants to modify
(write or dispose) the instance, it has to register it again, or else use the special handle value
HANDLE_NIL". I do not have this prerequirement. It will return BAD_PARAMETER only if the Instance
HANDLE_NIL". I do not have this pre-requirement. It will return BAD_PARAMETER only if the Instance
is not in the memory anymore.
* The DDS Specification is not entirely clear how to handle transition between the NOT_ALIVE states.
@ -448,22 +566,37 @@ DESIGN DECISIONS
Data Readers having different Generation Counters (depending on their reception order).
NOTE: The NOT_ALIVE Samples are always added to the end of the list, not depending on their TS. This
is the only exception in which samples TS does not follow their list order.
* The DEADLINE check times of the DDS Entities are aligned to the release of the reset, and not on the addition of
a new instance. That means that all Instances are checked at the same time, non depending on when they were added.
IDL
---
* Since all code related to encoding/decoding the DATA stream is dependent on the IDL type
specification, we have to encapsulate that code separately and link them as necessary. Two such
dynamic Entities are defined: KEY_HOLDER, and <TYPENAME>_INTERFACE.
The KEY_HOLDER Entity contains a Byte-Wide internal memory (In size equal to the maximum key size),
that can be filled with PLAIN_CDR/PL_CDR DATA Streams, and Serialized Key Streams.
The Entity allows outputting the memory contents (Key) either in a KEY_HASH format (needs
to instantiate a MD5 calculator), or in Serialized Key Format. The Entity uses the start/opcode/ack
interface for operations (similar to the RTPS/DDS Interface).
The <TYPENAME>_INTERFACE entity has all type-components linked to ports and latched in registers/memory.
In output mode the entity is able to fill the registers/memory with a PLAIN_CDR/PL_CDR Data Stream, and
in input mode the registers are filled directly from the input ports and the Entity is able to produce
a PLAIN_CDR/PL_CDR Data Stream from the registers/memory.
Due to the type-specific nature of the entities, those are not instantiated inside the DDS Endpoints,
but will be instantiated in a separate entity (Interface) and linked through port mapping with the
DDS Endpoints.
X: Due to port mapping differences between DDS Reader and Writer the <TYPENAME>_INTERFACE is split into
<TYPENAME>_READER_INTERFACE and <TYPENAME>_WRITER_INTERFACE.
* MUTABLE extensibility is currently unsupported, as the PL_CDR encoding needs to be able to dynamically
calculate the sizes of type members, which was deemed to complicated.
calculate the sizes of type members, which was deemed too complicated.
* Similar to the previous decision, only optional members with fixed size are supported (Since the optional
members need a parameter list header, which has a length field).
* The RTPS Writer is only sending GAPs when processing ACKNACK Requests or sending Historical DATA.
That means that if the HC pulls the 'data_available' Signal and deletes Cache Changes before the
RTPS Writer has requested them, it will just ignore the Cache Change. A GAP will only be generated
if a reliable Reader subsequently requests this Cache Change.
* If PUSH_MODE is false, packets are only written as response to ACKNACK requests (except HEARTBEATS).
This means that a Reliable RTPS Writer in PUSH_MODE = FALSE cannot communicate with Best Effort Readers.
Historical Data is also only sent out on request (But NACKed in the HC, until the remote Reader ACKs them).
* Whereas the DDS Writer/Reader are flexible in the handling of variable sized Payloads - they write the
payload in multiple memory slots, effectively eating away from the MAX_SAMPLES limit, since there are
only MAX_SAMPLES memory slots avialable - the decoding in TYPENAME_interface requires and explicitly
@ -472,6 +605,9 @@ DESIGN DECISIONS
does enforce those limits implicitly, since it encodes the memory/registers that are physically limited
to those specified upper bounds during static generation.
ROS
---
* RTPS/DDS use a time representation of 64-bit seconds in 32Q32 fixed point format. The ROS libraries
use a 64-bit unsigned nanosecond representation, and ROS sends time (defined in
rcl_interfaces/builtin_interfaces) in 32-bit second and 32-bit nanosecond respresentation.
@ -479,67 +615,96 @@ DESIGN DECISIONS
between the representations are quite resource and latency heavy.
Since the ros action server directly interfaces ros services with the builtin_interfaces definition,
it was decided that the entire server works on this representation to avoid costly conversions. This in
effect mitigates the converion problem to the instantiating entity, but a single conversion point could
effect mitigates the conversion problem to the instantiating entity, but a single conversion point could
be defined that can be used throughout the system.
* Initialy the RTPS/DDS Endpoints were designed as one Endpoint per Entity. This allows maximum parallel
processing and each entity having the bare minimum HW beased on generics that define the properties of
each Endpoint. Nevertheless the amount of Resources needed to synthesize are quite substantial, and there
is a (low) limit of how many Endpoints can be instantiated. This limit was reached when trying to
synthesize a ROS action server, which instantiates 9 RTPS and DDS Endpoints.
Since the only real difference between the Endpoints is the Memory, we could reuse the main state
machine for all Endpoints and just instantiate different memories.
A redesign of all Endpoints was decided, in which multiple Endpoints are simulated by one Entity.
The contained Endpoints are addressed in sequential order, meaning that we lose the parrallel processing,
but since the RTPS protocol is primarilly used over UDP, there is no difference in performance.
Although the ports of the entity could remain single dimension (since only one Endpoint is
reading/writing at a time), we would lose the information of which Endpoint is addressed and would have
to extend the inter-communication shema to relay this information. To avoid this, and to be backwards
compatible (allow to instantiate multiple Endpoint Entities), the dimensions of the ports of the
Endpoints will be extended by the dimension of Endpoinst contained with some exceptions.
These exceptions are the all RTPS Output ports, and the read,data_in, and last_word_in RTPS Handler
and DISCOVERY Module ports. This prevents wasting resources on FIFOs, but still conveys addressing
information via the empty signal.
This works, because the RTPS Handler and DISCOVERY MODULE write in a multicast fashion (meaning that all
addressed Entities become the smae data).
* The above decision brings which it another challenge. Sice now the input signals are unbalanced
(empty port is vector, but read, data_in, and last_word_in are not) we need a special kind of FIFO
to connect to the input ports of the Endpoints. This special FIFO is called "vector_FIFO" and contains
a FIFO for the data, and a FIFO for the write signal, that is internally converted to the empty signal
and simulates multiple FIFOs.
* Since the message format from RTPS reader to DDS reader contains information specific to the individual
writer (Writer ID, Lifespan Deadline), we cannot write to multiple DDS endpoints at the same time.
This means that we have to temporarily store the payload and push it to each DDS Endpoint individually.
* Since the DDS Reader is waiting on USER via the 'sample_info_ack' signal before continuing, a singel
user can stall all other USERs/Readers (DoS) of a vector entity of the DDS Reader.
* The DEADLINE check times of the DDS Entities are aligned to the release of the reset, and not on the
addition of a new instance. That means that all Instances are checked at the smae time, non depending
on when they were added.
* Because the DATA_AVAILABLE bit of the status of the DDS Reader is reset on first read, the DATA_AVAILABLE
bit can be zero even if the DDS Reader still contains unread data. For this reason the ROS entities are
showing data_available until the first empty read after the DATA_AVAILABLE bit is set.
This has the inverse effect, that even if the DDS Reader has no more data it is showing DATA_AVAILABLE
(since a empty read has to be done to reset the bit). This trait has to be taken into account.
The ros_action_server, for instance, will for instance remove a goal entering terminal state, if the
MAX_GOALS limit is reached
This has the inverse effect, that even if the DDS Reader has no more data the ROS Entity is showing DATA_AVAILABLE
(since an empty read has to be done to reset the bit). This trait has to be taken into account.
The ros_action_server, for instance, has to remove a goal in terminal state if the MAX_GOALS limit
is reached, and relying solely on the DATA_AVAILABLE signal could unnecessarily trigger a goal removal.
* It was decided to not follow the ROS Action Server RCL API to the letter, as the ROS Action server is more
involved and needs to do extra stuff, that the user should not really be bothered with. Using the provided
API as is requires the user to trigger various server functionality and also requires data to be unnecessarily
moved out and into the server. (Which makes sense, considering that there should be a RMW layer above this RCL
functionality).
Therefore a different API is conceptualized for the ROS Action server, that only requires User interaction to the
parts that actually matter to the user. That means that all ROS Service interactions are now hidden inside
the ROS Action server. The user is only prompted (via high active signals) for user interaction (like accepting
a new goal or cancellation request). The user primarily interacts with the server with goal handles, which are
the memory addresses of the stored goals in the goal memory. The user can fetch currently stored/accepted goals
and modify their state. The user can also directly publish feedback for specific goals. The goal results are
stored in an array, which the user directly interacts with (It is the responsibility of the user to store the
results in the array before transitioning the goal state to the SUCCEEDED state).
* According to the ROS "specification" the ROS action server should discard stored goal result based on a
configurable timeout period. A timeout period of -1 disables goal result removal (result are kept indefinitely),
and a timeout period of 0 removes goal result immediately (after serving any pending result requests).
Since we are resource limited, the timeout "option" -1 cannot be implemented as is.
Also, since the goal and result memories are linked, we are not storing and removing goal results, but the stored
goals themselves.
The design decision was made that if the timeout period is set to infinite, the oldest goal is removed if the memory
is full and a new goal request comes in.
The 0 timeout option is ignored entirely, since it is pointless and provides no benefit at all.
BRAINSTORMING
-------------
* Add all Participant specific configuration into a generic array (maybe array of record?) and modify the
discovery module to be centric to ALL participants. That means that the Participant Memory will
contain ALL remortely matched participants (even if they are matched only be 1 local participant).
contain ALL remotely matched participants (even if they are matched only be 1 local participant).
The discovery module will also need to differentiate between the local participants for replies
(Parse RTPPS GUID and set local array index).
(Parse RTPS GUID and set local array index).
The port interface of the discovery module will not change, meaning that ALL the endpoints of all the
local participants will be flattened into one array for communication purposes (Maybe define "static"
demangle package function?).
* Since Publisher and Subscriber Groups are static, we can also generate the GroupDigests statically
and avoid having to use a HW MD5 calculator.
* An important step for later testing automation would be to simulate the hardware implementation with
existing software implementations.
Currently I do not know how the hardware/software interconnection can work in the simulation level.
Can we build a SystemC wrapper around a software implementation and simulate it together with the
VHDL implementation? (QuestaSim is allowing mixed language simulations)
- Following post (https://discourse.ros.org/t/proposal-for-ros-2-hardware-acceleration-working-group-hawg/20112/22)
gave me a different idea. Do the HLS tools simulate PS and PL side together? If so implementing the software
implementation on the PS side and communicating to the PL side would implicitly allow to simulate both together.
- Wait, I think I am over-complicating stuff. Why do I need to integrate an existing software in its entirety in
a simulation capable form? Can I not just implement a SIMULATION-to-UDP bridge similar to the current module
sitting in the PS side connecting the FPGA implementation with a software implementation?
I guess only timing relevant problems would arise (Timeouts in the sw implementation because the hw implementation
takes to long to simulate a response).
* The DDS Specification differentiates between lost and rejected samples, but does not state what the semantic
difference between them is. RTI defines lost samples as dropped samples that will not be NACKed anymore. They
even extended the SAMPLE_LOST_STATUS with reasons.
My implementation is making a distinction between rejected, lost, and dropped. A sample is Rejected if it is dropped
without ACKing, dropped if it is dropped with ACKing, and lost if the DDS Reader never received a Sequence Number
(analog to the LOST_BY_WRITER reason of RTI). RTI started mapping rejected samples on BEST_EFFORT communication as
lost (since there is no way to request them).
I think that lost samples should be only samples that we have never any knowledge about (Probably also what the Spec
assumes, since the SAMPLE_LOST_STATUS has not reason). Thus I would not do the mapping, and document that rejected
samples can be considered lost if the communication is BEST_EFFORT.
On the other hand my implementation currently drops samples without any user feedback, which is quite bad. We should
extend the communication statuses with a DROPPED_SAMPLE_STATUS. Also I think it is stupid to only state the reason
of the last dropped sample, and we should do a flag variable (similar to the status register) collecting the
cumulative reasons, since some reasons are of higher value for the user than others (like dropping a Dispose sample
instead of a Filtered sample).
REF: https://community.rti.com/kb/statuses-changes
REF: https://community.rti.com/static/documentation/connext-dds/5.2.3/doc/manuals/connext_dds/html_files/RTI_ConnextDDS_CoreLibraries_UsersManual/Content/UsersManual/Statuses_for_DataReaders.htm
* The LivelinessChangedStatus of the DDS Reader requires remote endpoints to not be deleted when they lose liveliness.
On the other hand keeping "stale" remote endpoint indefinitely may also not be a good option, so we may want to add
a second configurable deadline that removes stale endpoints. We could even use the same liveliness deadline and
differentiate between the 2 deadlines with the last bit (similar to how we do it for HEARTBEAT/ACKNACK delay and
suppression)
* If we can find a way to dynamically 'use' a package in testbenches, we could dynamically overload some predefined
constants/functions that testbenches use and be Type independent.
PROTOCOL UNCOMPLIANCE
=====================
@ -547,13 +712,14 @@ PROTOCOL UNCOMPLIANCE
* Coherent Sets Not Supported
* Built-in Endpoints (of Discovery Module) is NOT the same as a normal Endpoint
-> No User access to Data
* Known but unused Submessage IDs are treated as uknown
* Known but unused Submessage IDs are treated as unknown
-> No validity check
* Inline QoS validated in Endpoint
-> Cannot invalidate Rest of Message/Packet
* RESOURCE_LIMITS applies also to "empty" samples (Samples with no valid data).
* Write/Dispose/Untergister Operations do not return (TIMEOUT). I.e. the MAX_BLOCKING_TIME is not used.
* The Participant Message Data may contain additional data, and according to DDSI-RTPS 2.3 implementations must be able
to support up to 128 Bytes of additional data.
RTPS ENDPOINT

View File

@ -51,10 +51,10 @@ use work.rtps_test_package.all;
-- TEST: ADD SAMPLE ON MAX_SAMPLES_PER_INSTANCE
-- TEST: ADD SAMPLE ON MAX_SAMPLES [KNOWN INSTANCE]
-- TEST: ADD SAMPLE ON MAX_SAMPLES [UNKNOWN INSTANCE]
-- TEST: ADD SAMPLE ON MAX_INSTANCES [UNKOWN INSTANCE, WITH STALE INSTANCE]
-- TEST: ADD SAMPLE ON MAX_INSTANCES [UNKOWN INSTANCE, WITHOUT STALE INSTANCE]
-- TEST: ADD SAMPLE ON MAX_INSTANCES [UNKOWN INSTANCE, WITHOUT STALE INSTANCE, WITH EMPTY INSTANCE]
-- TEST: ADD SAMPLE ON MAX_INSTANCES [UNKOWN INSTANCE, NOT_ALIVE_DISPOSED & STALE INSTANCE]
-- TEST: ADD SAMPLE ON MAX_INSTANCES [UNKNOWN INSTANCE, WITH STALE INSTANCE]
-- TEST: ADD SAMPLE ON MAX_INSTANCES [UNKNOWN INSTANCE, WITHOUT STALE INSTANCE]
-- TEST: ADD SAMPLE ON MAX_INSTANCES [UNKNOWN INSTANCE, WITHOUT STALE INSTANCE, WITH EMPTY INSTANCE]
-- TEST: ADD SAMPLE ON MAX_INSTANCES [UNKNOWN INSTANCE, NOT_ALIVE_DISPOSED & STALE INSTANCE]
-- TEST: ADD SAMPLE ON MAX_SAMPLES & MAX_INSTANCES [UNKNOWN INSTANCE, WITH STALE INSTANCE]
-- TEST: ADD SAMPLE ON MAX_SAMPLES & MAX_INSTANCES [UNKNOWN INSTANCE, WITHOUT STALE INSTANCE]
-- TEST: ADD SAMPLE BIGGER THAN AVAILABLE MEMORY SPACE
@ -377,7 +377,7 @@ begin
istate_id <= GetAlertLogID("Instance State", ALERTLOG_BASE_ID);
ts_id <= GetAlertLogID("Source Timestamp", ALERTLOG_BASE_ID);
inst_id <= GetAlertLogID("Instance Handle", ALERTLOG_BASE_ID);
pub_id <= GetAlertLogID("Publication Hanlde", ALERTLOG_BASE_ID);
pub_id <= GetAlertLogID("Publication Handle", ALERTLOG_BASE_ID);
dis_gen_cnt_id <= GetAlertLogID("Disposed Generation Count", ALERTLOG_BASE_ID);
no_w_gen_cnt_id <= GetAlertLogID("No Writers Generation Count", ALERTLOG_BASE_ID);
srank_id <= GetAlertLogID("Sample Rank", ALERTLOG_BASE_ID);
@ -534,7 +534,7 @@ begin
AffirmIf(status_id,(status(0) and DATA_AVAILABLE_STATUS) = DATA_AVAILABLE_STATUS, "Expected: 1", "Received: 0");
AffirmIf(status_id,(status(5) and DATA_AVAILABLE_STATUS) = DATA_AVAILABLE_STATUS, "Expected: 1", "Received: 0");
-- VAILDATE STATE
-- VALIDATE STATE
Log("R0,R5: DDS Operation READ [MAX_SAMPLES 4, ANY_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE]", INFO);
dds := DEFAULT_DDS_READER_TEST;
@ -1013,7 +1013,7 @@ begin
cc.payload := gen_payload(kh4,10);
cc.src_timestamp := gen_duration(7 sec);
-- TEST: ADD SAMPLE ON MAX_INSTANCES [UNKOWN INSTANCE, WITHOUT STALE INSTANCE, WITH EMPTY INSTANCE]
-- TEST: ADD SAMPLE ON MAX_INSTANCES [UNKNOWN INSTANCE, WITHOUT STALE INSTANCE, WITH EMPTY INSTANCE]
Log("R0,R5: RTPS Operation ADD_CACHE_CHANGE [KEY_HASH, Instance 4, Writer 1, Aligned Payload]", INFO);
Log("R0,R5: REJECTED [MAX_INSTANCES exceeded]", DEBUG);
@ -1094,7 +1094,7 @@ begin
AffirmIf(status_id,(status(0) and DATA_AVAILABLE_STATUS) = DATA_AVAILABLE_STATUS, "Expected: 1", "Received: 0");
AffirmIf(status_id,(status(5) and DATA_AVAILABLE_STATUS) = DATA_AVAILABLE_STATUS, "Expected: 1", "Received: 0");
-- TEST: ADD SAMPLE ON MAX_INSTANCES [UNKOWN INSTANCE, WITH STALE INSTANCE]
-- TEST: ADD SAMPLE ON MAX_INSTANCES [UNKNOWN INSTANCE, WITH STALE INSTANCE]
Log("R0,R5: RTPS Operation ADD_CACHE_CHANGE [KEY_HASH, Instance 4, Writer 1, Aligned Payload]", INFO);
Log("R0,R5: ACCEPTED", DEBUG);
@ -1224,7 +1224,7 @@ begin
cc.payload := gen_payload(kh1,10);
cc.src_timestamp := gen_duration(8 sec);
-- TEST: ADD SAMPLE ON MAX_INSTANCES [UNKOWN INSTANCE, WITHOUT STALE INSTANCE]
-- TEST: ADD SAMPLE ON MAX_INSTANCES [UNKNOWN INSTANCE, WITHOUT STALE INSTANCE]
Log("R0,R5: RTPS Operation ADD_CACHE_CHANGE [KEY_HASH, Instance 1, Writer 0, Aligned Payload]", INFO);
Log("R0,R5: REJECTED [MAX_INSTANCES exceeded]", DEBUG);
@ -2344,7 +2344,7 @@ begin
cc.payload := gen_payload(kh2,10);
cc.src_timestamp := gen_duration(25 sec);
-- TEST: ADD SAMPLE ON MAX_INSTANCES [UNKOWN INSTANCE, NOT_ALIVE_DISPOSED & STALE INSTANCE]
-- TEST: ADD SAMPLE ON MAX_INSTANCES [UNKNOWN INSTANCE, NOT_ALIVE_DISPOSED & STALE INSTANCE]
Log("R0,R5: RTPS Operation ADD_CACHE_CHANGE [KEY_HASH, Instance 2, Writer 0, Aligned Payload]", INFO);
Log("R0,R5: ACCEPTED", DEBUG);
@ -3520,7 +3520,7 @@ begin
cc.payload := gen_payload(kh4,10);
cc.src_timestamp := gen_duration(8 sec);
-- TEST: ADD SAMPLE ON MAX_INSTANCES [UNKOWN INSTANCE, WITHOUT STALE INSTANCE, WITH EMPTY INSTANCE]
-- TEST: ADD SAMPLE ON MAX_INSTANCES [UNKNOWN INSTANCE, WITHOUT STALE INSTANCE, WITH EMPTY INSTANCE]
Log("R1,R2,R3: RTPS Operation ADD_CACHE_CHANGE [KEY_HASH, Instance 4, Writer 1, Aligned Payload]", INFO);
Log("R1,R2,R3: REJECTED [MAX_INSTANCES exceeded]", DEBUG);
@ -3630,7 +3630,7 @@ begin
AffirmIf(status_id,(status(2) and DATA_AVAILABLE_STATUS) = DATA_AVAILABLE_STATUS, "Expected: 1", "Received: 0");
AffirmIf(status_id,(status(3) and DATA_AVAILABLE_STATUS) = DATA_AVAILABLE_STATUS, "Expected: 1", "Received: 0");
-- TEST: ADD SAMPLE ON MAX_INSTANCES [UNKOWN INSTANCE, WITH STALE INSTANCE]
-- TEST: ADD SAMPLE ON MAX_INSTANCES [UNKNOWN INSTANCE, WITH STALE INSTANCE]
Log("R1,R2,R3: RTPS Operation ADD_CACHE_CHANGE [KEY_HASH, Instance 4, Writer 1, Aligned Payload]", INFO);
Log("R1,R2,R3: ACCEPTED", DEBUG);
@ -3804,7 +3804,7 @@ begin
cc.payload := gen_payload(kh1,10);
cc.src_timestamp := gen_duration(9 sec);
-- TEST: ADD SAMPLE ON MAX_INSTANCES [UNKOWN INSTANCE, WITHOUT STALE INSTANCE]
-- TEST: ADD SAMPLE ON MAX_INSTANCES [UNKNOWN INSTANCE, WITHOUT STALE INSTANCE]
Log("R1,R2,R3: RTPS Operation ADD_CACHE_CHANGE [KEY_HASH, Instance 1, Writer 0, Aligned Payload]", INFO);
Log("R1,R2,R3: REJECTED [MAX_INSTANCES exceeded]", DEBUG);
@ -5295,7 +5295,7 @@ begin
cc.payload := gen_payload(kh2,10);
cc.src_timestamp := gen_duration(27 sec);
-- TEST: ADD SAMPLE ON MAX_INSTANCES [UNKOWN INSTANCE, NOT_ALIVE_DISPOSED & STALE INSTANCE]
-- TEST: ADD SAMPLE ON MAX_INSTANCES [UNKNOWN INSTANCE, NOT_ALIVE_DISPOSED & STALE INSTANCE]
Log("R1,R2,R3: RTPS Operation ADD_CACHE_CHANGE [KEY_HASH, Instance 2, Writer 0, Aligned Payload]", INFO);
Log("R1,R2,R3: ACCEPTED", DEBUG);

View File

@ -260,7 +260,7 @@ begin
istate_id <= GetAlertLogID("Instance State", ALERTLOG_BASE_ID);
ts_id <= GetAlertLogID("Source Timestamp", ALERTLOG_BASE_ID);
inst_id <= GetAlertLogID("Instance Handle", ALERTLOG_BASE_ID);
pub_id <= GetAlertLogID("Publication Hanlde", ALERTLOG_BASE_ID);
pub_id <= GetAlertLogID("Publication Handle", ALERTLOG_BASE_ID);
dis_gen_cnt_id <= GetAlertLogID("Disposed Generation Count", ALERTLOG_BASE_ID);
no_w_gen_cnt_id <= GetAlertLogID("No Writers Generation Count", ALERTLOG_BASE_ID);
srank_id <= GetAlertLogID("Sample Rank", ALERTLOG_BASE_ID);
@ -538,7 +538,7 @@ begin
-- ISTATE: I1:ALIVE, I2:ALIVE
-- WRITER: W0:I1, W1:I2
-- VAILDATE STATE
-- VALIDATE STATE
Log("R0,R1: DDS Operation READ [MAX_SAMPLES 4, ANY_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE]", INFO);
dds := DEFAULT_DDS_READER_TEST;

View File

@ -33,13 +33,13 @@ use work.rtps_test_package.all;
-- TEST: TAKE_NEXT_SAMPLE [NO SAMPLE]
-- TEST: TAKE_NEXT_SAMPLE
-- TEST: READ_INSTANCE [UNKNOWN INSTANCE]
-- TEST: READ_INSTANCE [KNOWN INSTANCE, UNCOMPATIBLE SAMPLES]
-- TEST: READ_INSTANCE [KNOWN INSTANCE, INCOMPATIBLE SAMPLES]
-- TEST: READ_INSTANCE [KNOWN INSTANCE, COMPATIBLE SAMPLES]
-- TEST: READ_INSTANCE [NO SAMPLES]
-- TEST: TAKE_INSTANCE [NO SAMPLES]
-- TEST: TAKE_INSTANCE
-- TEST: READ_NEXT_INSTANCE [WITH SAMPLES, WITHOUT NEXT INSTANCE]
-- TEST: READ_NEXT_INSTANCE [WITH NEXT INSTANCE, UNCOMPATIBLE SAMPLES]
-- TEST: READ_NEXT_INSTANCE [WITH NEXT INSTANCE, INCOMPATIBLE SAMPLES]
-- TEST: READ_NEXT_INSTANCE [WITH NEXT INSTANCE, COMPATIBLE SAMPLES]
-- TEST: READ_NEXT_INSTANCE [HANDLE_NIL]
-- TEST: READ_NEXT_INSTANCE [WITH NEXT INSTANCE, WITH COMPATIBLE SAMPLE, NOT DIRECT NEXT INSTANCE]
@ -350,7 +350,7 @@ begin
istate_id <= GetAlertLogID("Instance State", ALERTLOG_BASE_ID);
ts_id <= GetAlertLogID("Source Timestamp", ALERTLOG_BASE_ID);
inst_id <= GetAlertLogID("Instance Handle", ALERTLOG_BASE_ID);
pub_id <= GetAlertLogID("Publication Hanlde", ALERTLOG_BASE_ID);
pub_id <= GetAlertLogID("Publication Handle", ALERTLOG_BASE_ID);
dis_gen_cnt_id <= GetAlertLogID("Disposed Generation Count", ALERTLOG_BASE_ID);
no_w_gen_cnt_id <= GetAlertLogID("No Writers Generation Count", ALERTLOG_BASE_ID);
srank_id <= GetAlertLogID("Sample Rank", ALERTLOG_BASE_ID);
@ -1393,7 +1393,7 @@ begin
-- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NEW
-- WRITER: W0:I1, W1:I2, W2:I3,I4
-- TEST: READ_INSTANCE [KNOWN INSTANCE, UNCOMPATIBLE SAMPLES]
-- TEST: READ_INSTANCE [KNOWN INSTANCE, INCOMPATIBLE SAMPLES]
Log("R0,R1,R2,R3: DDS Operation READ_INSTANCE [MAX_SAMPLES 20, NOT_READ_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE, Instance 1]", INFO);
dds := DEFAULT_DDS_READER_TEST;
@ -1430,7 +1430,7 @@ begin
-- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NEW
-- WRITER: W0:I1, W1:I2, W2:I3,I4
-- TEST: READ_NEXT_INSTANCE [WITH NEXT INSTANCE, UNCOMPATIBLE SAMPLES]
-- TEST: READ_NEXT_INSTANCE [WITH NEXT INSTANCE, INCOMPATIBLE SAMPLES]
Log("R0,R1,R2,R3: DDS Operation READ_NEXT_INSTANCE [MAX_SAMPLES 20, ANY_SAMPLE_STATE, NOT_ALIVE_DISPOSED_INSTANCE_STATE, ANY_VIEW_STATE, Instance 2]", INFO);
dds := DEFAULT_DDS_READER_TEST;
@ -2695,7 +2695,7 @@ begin
wait_on_sig(rtps_done);
wait_on_idle;
-- MEM: I4S2-(7)
-- ISTATE: I4:DISOSED
-- ISTATE: I4:DISPOSED
-- VIEW: I4:NEW
-- WRITER: W2:I4
@ -2727,7 +2727,7 @@ begin
wait_on_sig(rtps_done);
wait_on_idle;
-- MEM: I1S1(0), I4S2-(7)
-- ISTATE: I1:ALIVE, I4:DISOSED
-- ISTATE: I1:ALIVE, I4:DISPOSED
-- VIEW: I1:NEW, I4:NEW
-- WRITER: W0:I1, W2:I4
@ -2759,7 +2759,7 @@ begin
wait_on_sig(rtps_done);
wait_on_idle;
-- MEM: I1S1(0), I1S2-(1), I4S2-(7)
-- ISTATE: I1:DISPOSED, I4:DISOSED
-- ISTATE: I1:DISPOSED, I4:DISPOSED
-- VIEW: I1:NEW, I4:NEW
-- WRITER: W0:I1, W2:I4
@ -2791,7 +2791,7 @@ begin
wait_on_sig(rtps_done);
wait_on_idle;
-- MEM: I1S1(0), I1S2-(1), I4S2-(7), I1S3(9)
-- ISTATE: I1:ALIVE, I4:DISOSED
-- ISTATE: I1:ALIVE, I4:DISPOSED
-- VIEW: I1:NEW, I4:NEW
-- WRITER: W0:I1, W2:I4
@ -2823,7 +2823,7 @@ begin
wait_on_sig(rtps_done);
wait_on_idle;
-- MEM: I1S1(0), I1S2-(1), I4S1(4), I4S2-(7), I1S3(9)
-- ISTATE: I1:ALIVE, I4:DISOSED
-- ISTATE: I1:ALIVE, I4:DISPOSED
-- VIEW: I1:NEW, I4:NEW
-- WRITER: W0:I1, W2:I4
@ -2845,7 +2845,7 @@ begin
wait_on_sig(dds_done);
wait_on_idle;
-- MEM: I1S1(0), I1S2-(1), I4S1(4), I4S2-(7), I1S3(9)
-- ISTATE: I1:ALIVE, I4:DISOSED
-- ISTATE: I1:ALIVE, I4:DISPOSED
-- VIEW: I1:NEW, I4:NEW
-- WRITER: W0:I1, W2:I4
@ -2877,7 +2877,7 @@ begin
wait_on_sig(rtps_done);
wait_on_idle;
-- MEM: I1S1(0), I1S2-(1), I3S1(3), I4S1(4), I4S2-(7), I1S3(9)
-- ISTATE: I1:ALIVE, I3:ALIVE, I4:DISOSED
-- ISTATE: I1:ALIVE, I3:ALIVE, I4:DISPOSED
-- VIEW: I1:NEW, I3:NEW, I4:NEW
-- WRITER: W0:I1, W2:I3,I4
@ -2909,7 +2909,7 @@ begin
wait_on_sig(rtps_done);
wait_on_idle;
-- MEM: I1S1(0), I1S2-(1), I2S1(2), I3S1(3), I4S1(4), I4S2-(7), I1S3(9)
-- ISTATE: I1:ALIVE, I2:ALIVE, I3:ALIVE, I4:DISOSED
-- ISTATE: I1:ALIVE, I2:ALIVE, I3:ALIVE, I4:DISPOSED
-- VIEW: I1:NEW, I2:NEW, I3:NEW, I4:NEW
-- WRITER: W0:I1, W2:I3,I4
@ -2941,7 +2941,7 @@ begin
wait_on_sig(rtps_done);
wait_on_idle;
-- MEM: I1S1(0), I1S2-(1), I2S1(2), I3S1(3), I4S1(4), I2S2-(5), I4S2-(7), I1S3(9)
-- ISTATE: I1:ALIVE, I2:DISPOSED, I3:ALIVE, I4:DISOSED
-- ISTATE: I1:ALIVE, I2:DISPOSED, I3:ALIVE, I4:DISPOSED
-- VIEW: I1:NEW, I2:NEW, I3:NEW, I4:NEW
-- WRITER: W0:I1, W2:I3,I4
@ -2973,7 +2973,7 @@ begin
wait_on_sig(rtps_done);
wait_on_idle;
-- MEM: I1S1(0), I1S2-(1), I2S1(2), I3S1(3), I4S1(4), I2S2-(5), I3S2-(6), I4S2-(7), I1S3(9)
-- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:DISOSED
-- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:DISPOSED
-- VIEW: I1:NEW, I2:NEW, I3:NEW, I4:NEW
-- WRITER: W0:I1, W2:I3,I4
@ -3069,7 +3069,7 @@ begin
wait_on_sig(rtps_done);
wait_on_idle;
-- MEM: I1S1(0), I1S2-(1), I2S1(2), I3S1(3), I4S1(4), I2S2-(5), I3S2-(6), I4S2-(7), I4S3(8), I1S3(9), I2S3(10), I2S4-(11)
-- ISTATE: I1:ALIVE, I2:DISPSOED, I3:DISPOSED, I4:ALIVE
-- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
-- VIEW: I1:NEW, I2:NEW, I3:NEW, I4:NEW
-- WRITER: W0:I1, W2:I3,I4
@ -3318,7 +3318,7 @@ begin
-- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NEW
-- WRITER: W0:I1, W1:I2, W2:I3,I4
-- TEST: READ_INSTANCE [KNOWN INSTANCE, UNCOMPATIBLE SAMPLES]
-- TEST: READ_INSTANCE [KNOWN INSTANCE, INCOMPATIBLE SAMPLES]
Log("R5: DDS Operation READ_INSTANCE [MAX_SAMPLES 20, NOT_READ_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE, Instance 1]", INFO);
dds := DEFAULT_DDS_READER_TEST;
@ -3340,7 +3340,7 @@ begin
-- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NEW
-- WRITER: W0:I1, W1:I2, W2:I3,I4
-- TEST: READ_NEXT_INSTANCE [WITH NEXT INSTANCE, UNCOMPATIBLE SAMPLES]
-- TEST: READ_NEXT_INSTANCE [WITH NEXT INSTANCE, INCOMPATIBLE SAMPLES]
Log("R5: DDS Operation READ_NEXT_INSTANCE [MAX_SAMPLES 20, ANY_SAMPLE_STATE, NOT_ALIVE_DISPOSED_INSTANCE_STATE, ANY_VIEW_STATE, Instance 2]", INFO);
dds := DEFAULT_DDS_READER_TEST;

View File

@ -268,7 +268,7 @@ begin
istate_id <= GetAlertLogID("Instance State", ALERTLOG_BASE_ID);
ts_id <= GetAlertLogID("Source Timestamp", ALERTLOG_BASE_ID);
inst_id <= GetAlertLogID("Instance Handle", ALERTLOG_BASE_ID);
pub_id <= GetAlertLogID("Publication Hanlde", ALERTLOG_BASE_ID);
pub_id <= GetAlertLogID("Publication Handle", ALERTLOG_BASE_ID);
dis_gen_cnt_id <= GetAlertLogID("Disposed Generation Count", ALERTLOG_BASE_ID);
no_w_gen_cnt_id <= GetAlertLogID("No Writers Generation Count", ALERTLOG_BASE_ID);
srank_id <= GetAlertLogID("Sample Rank", ALERTLOG_BASE_ID);

View File

@ -240,7 +240,7 @@ begin
istate_id <= GetAlertLogID("Instance State", ALERTLOG_BASE_ID);
ts_id <= GetAlertLogID("Source Timestamp", ALERTLOG_BASE_ID);
inst_id <= GetAlertLogID("Instance Handle", ALERTLOG_BASE_ID);
pub_id <= GetAlertLogID("Publication Hanlde", ALERTLOG_BASE_ID);
pub_id <= GetAlertLogID("Publication Handle", ALERTLOG_BASE_ID);
dis_gen_cnt_id <= GetAlertLogID("Disposed Generation Count", ALERTLOG_BASE_ID);
no_w_gen_cnt_id <= GetAlertLogID("No Writers Generation Count", ALERTLOG_BASE_ID);
srank_id <= GetAlertLogID("Sample Rank", ALERTLOG_BASE_ID);
@ -326,7 +326,7 @@ begin
AffirmIf(status_id,(status(0) and SAMPLE_REJECTED_STATUS) = SAMPLE_REJECTED_STATUS, "Expected: 1", "Received: 0");
Log("R0: DDS Operation GET_SAMPLE_REJECTED_STATUS", INFO);
Log("R0: Expected [Count 1, Change 1, HANDLE_NIL, REJECTED_BY_PAYOAD_MEMORY_LIMIT]", DEBUG);
Log("R0: Expected [Count 1, Change 1, HANDLE_NIL, REJECTED_BY_PAYLOAD_MEMORY_LIMIT]", DEBUG);
dds := DEFAULT_DDS_READER_TEST;
dds.opcode := GET_SAMPLE_REJECTED_STATUS;
dds.ret_code := RETCODE_OK;
@ -384,7 +384,7 @@ begin
AffirmIf(status_id,(status(0) and SAMPLE_REJECTED_STATUS) = SAMPLE_REJECTED_STATUS, "Expected: 1", "Received: 0");
Log("R0: DDS Operation GET_SAMPLE_REJECTED_STATUS", INFO);
Log("R0: Expected [Count 2, Change 1, Instance 2, REJECTED_BY_PAYOAD_MEMORY_LIMIT]", DEBUG);
Log("R0: Expected [Count 2, Change 1, Instance 2, REJECTED_BY_PAYLOAD_MEMORY_LIMIT]", DEBUG);
dds := DEFAULT_DDS_READER_TEST;
dds.opcode := GET_SAMPLE_REJECTED_STATUS;
dds.ret_code := RETCODE_OK;

View File

@ -240,7 +240,7 @@ begin
istate_id <= GetAlertLogID("Instance State", ALERTLOG_BASE_ID);
ts_id <= GetAlertLogID("Source Timestamp", ALERTLOG_BASE_ID);
inst_id <= GetAlertLogID("Instance Handle", ALERTLOG_BASE_ID);
pub_id <= GetAlertLogID("Publication Hanlde", ALERTLOG_BASE_ID);
pub_id <= GetAlertLogID("Publication Handle", ALERTLOG_BASE_ID);
dis_gen_cnt_id <= GetAlertLogID("Disposed Generation Count", ALERTLOG_BASE_ID);
no_w_gen_cnt_id <= GetAlertLogID("No Writers Generation Count", ALERTLOG_BASE_ID);
srank_id <= GetAlertLogID("Sample Rank", ALERTLOG_BASE_ID);

View File

@ -240,7 +240,7 @@ begin
istate_id <= GetAlertLogID("Instance State", ALERTLOG_BASE_ID);
ts_id <= GetAlertLogID("Source Timestamp", ALERTLOG_BASE_ID);
inst_id <= GetAlertLogID("Instance Handle", ALERTLOG_BASE_ID);
pub_id <= GetAlertLogID("Publication Hanlde", ALERTLOG_BASE_ID);
pub_id <= GetAlertLogID("Publication Handle", ALERTLOG_BASE_ID);
dis_gen_cnt_id <= GetAlertLogID("Disposed Generation Count", ALERTLOG_BASE_ID);
no_w_gen_cnt_id <= GetAlertLogID("No Writers Generation Count", ALERTLOG_BASE_ID);
srank_id <= GetAlertLogID("Sample Rank", ALERTLOG_BASE_ID);

View File

@ -251,7 +251,7 @@ begin
istate_id <= GetAlertLogID("Instance State", ALERTLOG_BASE_ID);
ts_id <= GetAlertLogID("Source Timestamp", ALERTLOG_BASE_ID);
inst_id <= GetAlertLogID("Instance Handle", ALERTLOG_BASE_ID);
pub_id <= GetAlertLogID("Publication Hanlde", ALERTLOG_BASE_ID);
pub_id <= GetAlertLogID("Publication Handle", ALERTLOG_BASE_ID);
dis_gen_cnt_id <= GetAlertLogID("Disposed Generation Count", ALERTLOG_BASE_ID);
no_w_gen_cnt_id <= GetAlertLogID("No Writers Generation Count", ALERTLOG_BASE_ID);
srank_id <= GetAlertLogID("Sample Rank", ALERTLOG_BASE_ID);

View File

@ -13,7 +13,7 @@ use work.rtps_test_package.all;
entity L0_dds_writer_test1 is
end entity;
-- This testbench tests the General Operation of the DDS Writer. It tests the correctness of the RTPS
-- This testbench tests the General Operation of the DDS Writer. It tests the correctness of the RTPS
-- GET_MIN_SN, GET_MAX_SN, GET_CACHE_CHANGE, REMOVE_CACHE_CHANGE, ACK_CACHE_CHANGE, and NACK_CACHE_CHANGE Operations and the
-- DDS REGISTER_INSTANCE, UNREGISTER_INSTANCE, WRITE, DISPOSE, and LOOKUP_INSTANCE Operations.
-- More specifically the testbench covers following tests:
@ -284,6 +284,22 @@ begin
return ret;
end function;
function convert_to_serialized_key(input : CACHE_CHANGE_TYPE) return CACHE_CHANGE_TYPE is
variable ret : CACHE_CHANGE_TYPE := input;
begin
if (input.serialized_key) then
return ret;
else
-- Convert Payload to Serialized Key, compatible with test_key_holder
-- (Keep Only First 4 Bytes of the Payload)
ret.serialized_key := TRUE;
ret.payload.last(3) := '1';
ret.payload.length := 4;
return ret;
end if;
end function;
procedure start_dds is
begin
dds_start <= '1';
@ -410,7 +426,6 @@ begin
-- TEST: ADD SAMPLE WITH KEY_HASH [UNKNOWN INSTANCE]
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh1;
cc.payload := gen_payload(kh1,10);
@ -502,7 +517,6 @@ begin
-- TEST: WRITE UNALIGNED PAYLOAD [>1 SLOT]
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh2;
cc.payload := gen_payload(kh2,12);
@ -593,7 +607,6 @@ begin
-- TEST: ADD SAMPLE WITH HANDLE_NIL [KNOWN INSTANCE]
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh1;
cc.payload := gen_payload(kh1,15);
@ -703,7 +716,6 @@ begin
-- TEST: WRITE UNALIGNED PAYLOAD [<1 SLOT]
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh3;
cc.payload := gen_payload(kh3,8);
@ -847,7 +859,6 @@ begin
-- TEST: NORMAL DISPOSE
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := TRUE;
cc.kind := NOT_ALIVE_DISPOSED;
cc.instance := kh1;
cc.payload := gen_payload(kh1,5);
@ -938,7 +949,7 @@ begin
start_dds;
wait_on_sig(dds_done);
wait_on_idle;
cc1 := cc;
cc1 := convert_to_serialized_key(cc);
-- WRITER 0
AlertIf(empty_sample_head(0) /= 11, "Sample Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_payload_head(0) /= 0, "Payload Memory Empty List Head incorrect", FAILURE);
@ -1006,7 +1017,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh4;
cc.payload := gen_payload(kh4,10);
@ -1102,7 +1112,6 @@ begin
-- TEST: NORMAL UNREGISTER
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := TRUE;
cc.kind := NOT_ALIVE_UNREGISTERED;
cc.instance := kh1;
cc.payload := gen_payload(kh1,5);
@ -1126,7 +1135,7 @@ begin
start_dds;
wait_on_sig(dds_done);
wait_on_idle;
cc3 := cc;
cc3 := convert_to_serialized_key(cc);
-- WRITER 0
AlertIf(empty_sample_head(0) /= 0, "Sample Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_payload_head(0) /= 33, "Payload Memory Empty List Head incorrect", FAILURE);
@ -1195,7 +1204,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh4;
cc.payload := gen_payload(kh4,10);
@ -1326,7 +1334,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh2;
cc.payload := gen_payload(kh2,15);
@ -1365,7 +1372,6 @@ begin
-- INSTANCE MEMORY: 0(I4),18(I3),9(I2)/-
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh1;
cc.payload := gen_payload(kh1,10);
@ -1407,7 +1413,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := NOT_ALIVE_UNREGISTERED;
cc.instance := kh3;
cc.payload := gen_payload(kh3,5);
@ -1429,7 +1434,7 @@ begin
start_dds;
wait_on_sig(dds_done);
wait_on_idle;
cc4 := cc;
cc4 := convert_to_serialized_key(cc);
-- WRITER 0
AlertIf(empty_sample_head(0) /= 11, "Sample Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_payload_head(0) /= 54, "Payload Memory Empty List Head incorrect", FAILURE);
@ -1534,7 +1539,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh1;
cc.payload := gen_payload(kh1,10);
@ -1605,7 +1609,6 @@ begin
-- INSTANCE MEMORY: 18(I1),0(I4),9(I2)/-
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh4;
cc.payload := gen_payload(kh4,10);
@ -1638,7 +1641,6 @@ begin
-- INSTANCE MEMORY: 18(I1),0(I4),9(I2)/-
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh2;
cc.payload := gen_payload(kh2,10);
@ -1715,7 +1717,6 @@ begin
-- INSTANCE MEMORY: 18(I1),0(I4),9(I2)/-
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh4;
cc.payload := gen_payload(kh4,10);
@ -1902,7 +1903,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := NOT_ALIVE_UNREGISTERED;
cc.instance := kh2;
cc.payload := gen_payload(kh2,5);
@ -1924,7 +1924,7 @@ begin
start_dds;
wait_on_sig(dds_done);
wait_on_idle;
cc3 := cc;
cc3 := convert_to_serialized_key(cc);
-- WRITER 0
AlertIf(empty_sample_head(0) /= 44, "Sample Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_payload_head(0) /= 0, "Payload Memory Empty List Head incorrect", FAILURE);
@ -1955,7 +1955,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh4;
cc.payload := gen_payload(kh4,20);
@ -2044,7 +2043,6 @@ begin
-- TEST: UNREGISTER INSTANCE ON PAYLOAD MEMORY FULL [WITHOUT ACKed SAMPLES]
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := NOT_ALIVE_UNREGISTERED;
cc.instance := kh1;
cc.payload := gen_payload(kh1,5);
@ -2104,7 +2102,7 @@ begin
start_dds;
wait_on_sig(dds_done);
wait_on_idle;
cc2 := cc;
cc2 := convert_to_serialized_key(cc);
-- WRITER 0
AlertIf(empty_sample_head(0) /= 11, "Sample Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_payload_head(0) /= 54, "Payload Memory Empty List Head incorrect", FAILURE);
@ -2121,7 +2119,6 @@ begin
-- INSTANCE MEMORY: 18(I1),0(I4),9(I2)/-
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := NOT_ALIVE_DISPOSED;
cc.instance := kh3;
cc.payload := gen_payload(kh3,5);
@ -2205,7 +2202,7 @@ begin
start_dds;
wait_on_sig(dds_done);
wait_on_idle;
cc1 := cc;
cc1 := convert_to_serialized_key(cc);
-- WRITER 0
AlertIf(empty_sample_head(0) /= 22, "Sample Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_payload_head(0) /= 33, "Payload Memory Empty List Head incorrect", FAILURE);
@ -2322,7 +2319,6 @@ begin
-- INSTANCE MEMORY: 18(I3),0(I4),9(I2)/-
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh3;
cc.payload := gen_payload(kh3,10);
@ -2363,7 +2359,6 @@ begin
-- INSTANCE MEMORY: 18(I3),0(I4),9(I2)/-
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh4;
cc.payload := gen_payload(kh4,10);
@ -2402,7 +2397,6 @@ begin
-- INSTANCE MEMORY: 18(I3),0(I4),9(I2)/-
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh2;
cc.payload := gen_payload(kh2,10);
@ -2489,7 +2483,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := NOT_ALIVE_UNREGISTERED;
cc.instance := kh4;
cc.payload := gen_payload(kh4,5);
@ -2511,7 +2504,7 @@ begin
start_dds;
wait_on_sig(dds_done);
wait_on_idle;
cc1 := cc;
cc1 := convert_to_serialized_key(cc);
-- WRITER 0
AlertIf(empty_sample_head(0) /= 11, "Sample Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_payload_head(0) /= 22, "Payload Memory Empty List Head incorrect", FAILURE);
@ -2531,18 +2524,17 @@ begin
rtps := DEFAULT_RTPS_WRITER_TEST;
rtps.opcode := ACK_CACHE_CHANGE;
rtps.cc.seq_nr := gen_sn(19);
-- WRIITER 0
-- WRITER 0
ind <= 0;
start_rtps;
wait_on_sig(rtps_done);
-- WRIITER 3
-- WRITER 3
ind <= 3;
start_rtps;
wait_on_sig(rtps_done);
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh1;
cc.payload := gen_payload(kh1,10);
@ -2625,7 +2617,6 @@ begin
-- INSTANCE MEMORY: 18(I2),9(I3),0(I4)/-
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := NOT_ALIVE_UNREGISTERED;
cc.instance := kh2;
cc.payload := gen_payload(kh2,5);
@ -2647,7 +2638,7 @@ begin
start_dds;
wait_on_sig(dds_done);
wait_on_idle;
cc1 := cc;
cc1 := convert_to_serialized_key(cc);
-- WRITER 0
AlertIf(empty_sample_head(0) /= 0, "Sample Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_payload_head(0) /= 0, "Payload Memory Empty List Head incorrect", FAILURE);
@ -2664,7 +2655,6 @@ begin
-- INSTANCE MEMORY: 0(I1),18(I3),9(I2)/-
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := NOT_ALIVE_UNREGISTERED;
cc.instance := kh3;
cc.payload := gen_payload(kh3,5);
@ -2688,7 +2678,7 @@ begin
start_dds;
wait_on_sig(dds_done);
wait_on_idle;
cc4 := cc;
cc4 := convert_to_serialized_key(cc);
-- WRITER 0
AlertIf(empty_sample_head(0) /= 33, "Sample Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_payload_head(0) /= 22, "Payload Memory Empty List Head incorrect", FAILURE);
@ -2700,7 +2690,6 @@ begin
-- TEST: ADD SAMPLE ON MAX_SAMPLES & MAX_INSTANCES [UNKNOWN INSTANCE,WITH STALE INSTANCE, WITHOUT ACKed SAMPLE]
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh1;
cc.payload := gen_payload(kh1,10);
@ -2804,7 +2793,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh4;
cc.payload := gen_payload(kh4,10);
@ -2906,7 +2894,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh3;
cc.payload := gen_payload(kh3,10);
@ -2948,7 +2935,6 @@ begin
-- INSTANCE MEMORY: 0(I1),18(I3),9(I2)/-
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh4;
cc.payload := gen_payload(kh4,10);
@ -2972,7 +2958,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := NOT_ALIVE_UNREGISTERED;
cc.instance := kh4;
cc.payload := gen_payload(kh4,5);
@ -3027,7 +3012,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := TRUE;
cc.kind := NOT_ALIVE_UNREGISTERED;
cc.instance := kh3;
cc.payload := gen_payload(kh3,5);
@ -3121,7 +3105,7 @@ begin
start_dds;
wait_on_sig(dds_done);
wait_on_idle;
cc4 := cc;
cc4 := convert_to_serialized_key(cc);
-- WRITER 0
AlertIf(empty_sample_head(0) /= 0, "Sample Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_payload_head(0) /= 0, "Payload Memory Empty List Head incorrect", FAILURE);
@ -3146,7 +3130,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := TRUE;
cc.kind := NOT_ALIVE_DISPOSED;
cc.instance := kh3;
cc.payload := gen_payload(kh3,5);
@ -3170,7 +3153,7 @@ begin
start_dds;
wait_on_sig(dds_done);
wait_on_idle;
cc3 := cc;
cc3 := convert_to_serialized_key(cc);
-- WRITER 0
AlertIf(empty_sample_head(0) /= 44, "Sample Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_payload_head(0) /= 33, "Payload Memory Empty List Head incorrect", FAILURE);
@ -3213,7 +3196,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh4;
cc.payload := gen_payload(kh4,10);
@ -3364,7 +3346,6 @@ begin
-- INSTANCE MEMORY: 9(I4),0(I1),18(I2)/-
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh2;
cc.payload := gen_payload(kh2,10);
@ -3428,7 +3409,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh1;
cc.payload := gen_payload(kh1,10);
@ -3505,7 +3485,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh2;
cc.payload := gen_payload(kh2,10);
@ -3606,7 +3585,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh1;
cc.payload := gen_payload(kh1,10);
@ -3631,7 +3609,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh3;
cc.payload := gen_payload(kh3,10);
@ -3685,7 +3662,6 @@ begin
-- TEST: ADD SAMPLE WITH KEY_HASH
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh1;
cc.payload := gen_payload(kh1,10);
@ -3747,7 +3723,6 @@ begin
-- TEST: WRITE UNALIGNED PAYLOAD [>1 SLOT]
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh1;
cc.payload := gen_payload(kh1,18);
@ -3772,7 +3747,6 @@ begin
-- PAYLOAD MEMORY: 0(S1),11(S2),22(S2)/33,44
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh2;
cc.payload := gen_payload(kh2,10);
@ -3796,7 +3770,6 @@ begin
-- TEST: WRITE UNALIGNED PAYLOAD [<1 SLOT]
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := TRUE;
cc.kind := NOT_ALIVE_DISPOSED;
cc.instance := kh1;
cc.payload := gen_payload(kh1,5);
@ -3903,7 +3876,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh1;
cc.payload := gen_payload(kh1,10);
@ -3930,7 +3902,6 @@ begin
-- PAYLOAD MEMORY: 0(S1),11(S2),22(S2),33(S3),44(S4)/-
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := TRUE;
cc.kind := NOT_ALIVE_UNREGISTERED;
cc.instance := kh1;
cc.payload := gen_payload(kh1,5);
@ -3994,7 +3965,6 @@ begin
-- PAYLOAD MEMORY: 11(S2),22(S2),33(S3),44(S4),0(S5)/-
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh1;
cc.payload := gen_payload(kh1,10);
@ -4065,7 +4035,6 @@ begin
-- PAYLOAD MEMORY: 11(S2),22(S2),44(S4),0(S5),33(S6)/-
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := TRUE;
cc.kind := NOT_ALIVE_DISPOSED;
cc.instance := kh1;
cc.payload := gen_payload(kh1,5);
@ -4126,7 +4095,6 @@ begin
-- PAYLOAD MEMORY: 44(S4),0(S5),33(S6),11(S7)/22
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := TRUE;
cc.kind := NOT_ALIVE_UNREGISTERED;
cc.instance := kh1;
cc.payload := gen_payload(kh1,5);
@ -4257,7 +4225,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := TRUE;
cc.kind := NOT_ALIVE_DISPOSED;
cc.instance := kh1;
cc.payload := gen_payload(kh1,5);
@ -4284,7 +4251,6 @@ begin
-- PAYLOAD MEMORY: 44(S4),11(S7),22(S8),0(S9)/33
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := TRUE;
cc.kind := NOT_ALIVE_UNREGISTERED;
cc.instance := kh1;
cc.payload := gen_payload(kh1,5);
@ -4320,7 +4286,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh1;
cc.payload := gen_payload(kh1,20);
@ -4495,7 +4460,6 @@ begin
-- TEST: ADD SAMPLE WITH KEY_HASH [UNKNOWN INSTANCE]
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh1;
cc.payload := gen_payload(kh1,9);
@ -4559,7 +4523,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh1;
cc.payload := gen_payload(kh1,16);
@ -4588,7 +4551,6 @@ begin
-- INSTANCE MEMORY: 0(I1)/9,18
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := TRUE;
cc.kind := NOT_ALIVE_DISPOSED;
cc.instance := kh2;
cc.payload := gen_payload(kh2,5);
@ -4639,7 +4601,7 @@ begin
start_dds;
wait_on_sig(dds_done);
wait_on_idle;
cc3 := cc;
cc3 := convert_to_serialized_key(cc);
AlertIf(empty_sample_head(2) /= 33, "Sample Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_payload_head(2) /= 40, "Payload Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_inst_head(2) /= 18, "Instance Memory Empty List Head incorrect", FAILURE);
@ -4717,7 +4679,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh2;
cc.payload := gen_payload(kh2,9);
@ -4747,7 +4708,6 @@ begin
-- INSTANCE MEMORY: 9(I2),0(I1)/18
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh3;
cc.payload := gen_payload(kh3,9);
@ -4787,7 +4747,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh3;
cc.payload := gen_payload(kh3,9);
@ -4873,7 +4832,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := TRUE;
cc.kind := NOT_ALIVE_DISPOSED;
cc.instance := kh1;
cc.payload := gen_payload(kh1,5);
@ -4892,7 +4850,7 @@ begin
start_dds;
wait_on_sig(dds_done);
wait_on_idle;
cc2 := cc;
cc2 := convert_to_serialized_key(cc);
AlertIf(empty_sample_head(2) /= 11, "Sample Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_payload_head(2) /= 20, "Payload Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_inst_head(2) /= 26, "Instance Memory Empty List Head incorrect", FAILURE);
@ -4910,7 +4868,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh2;
cc.payload := gen_payload(kh2,18);
@ -4988,7 +4945,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := TRUE;
cc.kind := NOT_ALIVE_DISPOSED;
cc.instance := kh3;
cc.payload := gen_payload(kh3,5);
@ -5007,7 +4963,7 @@ begin
start_dds;
wait_on_sig(dds_done);
wait_on_idle;
cc2 := cc;
cc2 := convert_to_serialized_key(cc);
AlertIf(empty_sample_head(2) /= 22, "Sample Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_payload_head(2) /= 54, "Payload Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_inst_head(2) /= 26, "Instance Memory Empty List Head incorrect", FAILURE);
@ -5074,7 +5030,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := TRUE;
cc.kind := NOT_ALIVE_UNREGISTERED;
cc.instance := kh1;
cc.payload := gen_payload(kh1,5);
@ -5094,7 +5049,7 @@ begin
start_dds;
wait_on_sig(dds_done);
wait_on_idle;
cc4 := cc;
cc4 := convert_to_serialized_key(cc);
AlertIf(empty_sample_head(2) /= 33, "Sample Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_payload_head(2) /= 54, "Payload Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_inst_head(2) /= 26, "Instance Memory Empty List Head incorrect", FAILURE);
@ -5112,7 +5067,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := TRUE;
cc.kind := NOT_ALIVE_UNREGISTERED;
cc.instance := kh2;
cc.payload := gen_payload(kh2,5);
@ -5131,7 +5085,7 @@ begin
start_dds;
wait_on_sig(dds_done);
wait_on_idle;
cc2 := cc;
cc2 := convert_to_serialized_key(cc);
AlertIf(empty_sample_head(2) /= 44, "Sample Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_payload_head(2) /= 54, "Payload Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_inst_head(2) /= 26, "Instance Memory Empty List Head incorrect", FAILURE);
@ -5167,7 +5121,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh4;
cc.payload := gen_payload(kh4,9);
@ -5238,7 +5191,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh2;
cc.payload := gen_payload(kh2,9);
@ -5319,7 +5271,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh2;
cc.payload := gen_payload(kh2,9);
@ -5345,7 +5296,6 @@ begin
-- INSTANCE MEMORY: 0(I2),9(I4),18(I3)/-
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh2;
cc.payload := gen_payload(kh2,9);
@ -5382,7 +5332,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh2;
cc.payload := gen_payload(kh2,9);
@ -5419,7 +5368,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := TRUE;
cc.kind := NOT_ALIVE_UNREGISTERED;
cc.instance := kh2;
cc.payload := gen_payload(kh2,5);
@ -5439,7 +5387,7 @@ begin
start_dds;
wait_on_sig(dds_done);
wait_on_idle;
cc3 := cc;
cc3 := convert_to_serialized_key(cc);
AlertIf(empty_sample_head(2) /= 33, "Sample Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_payload_head(2) /= 10, "Payload Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_inst_head(2) /= 26, "Instance Memory Empty List Head incorrect", FAILURE);
@ -5497,7 +5445,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := TRUE;
cc.kind := NOT_ALIVE_UNREGISTERED;
cc.instance := kh4;
cc.payload := gen_payload(kh4,5);
@ -5514,7 +5461,7 @@ begin
start_dds;
wait_on_sig(dds_done);
wait_on_idle;
cc4 := cc;
cc4 := convert_to_serialized_key(cc);
AlertIf(empty_sample_head(2) /= 11, "Sample Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_payload_head(2) /= 20, "Payload Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_inst_head(2) /= 26, "Instance Memory Empty List Head incorrect", FAILURE);
@ -5523,7 +5470,6 @@ begin
-- INSTANCE MEMORY: 0(I2),9(I4),18(I3)/-
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := TRUE;
cc.kind := NOT_ALIVE_UNREGISTERED;
cc.instance := kh3;
cc.payload := gen_payload(kh3,5);
@ -5562,7 +5508,7 @@ begin
start_dds;
wait_on_sig(dds_done);
wait_on_idle;
cc4 := cc;
cc4 := convert_to_serialized_key(cc);
AlertIf(empty_sample_head(2) /= 33, "Sample Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_payload_head(2) /= 10, "Payload Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_inst_head(2) /= 26, "Instance Memory Empty List Head incorrect", FAILURE);
@ -5571,7 +5517,6 @@ begin
-- INSTANCE MEMORY: 0(I2),9(I4),18(I3)/-
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh3;
cc.payload := gen_payload(kh3,9);
@ -5600,7 +5545,6 @@ begin
-- INSTANCE MEMORY: 0(I2),9(I4),18(I3)/-
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh3;
cc.payload := gen_payload(kh3,9);
@ -5637,7 +5581,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh3;
cc.payload := gen_payload(kh3,9);
@ -5674,7 +5617,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh3;
cc.payload := gen_payload(kh3,9);
@ -5752,7 +5694,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := TRUE;
cc.kind := NOT_ALIVE_UNREGISTERED;
cc.instance := kh1;
cc.payload := gen_payload(kh1,5);
@ -5774,7 +5715,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh1;
cc.payload := gen_payload(kh1,9);
@ -5804,7 +5744,6 @@ begin
-- INSTANCE MEMORY: 9(I1),0(I2),18(I3)/-
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh4;
cc.payload := gen_payload(kh4,9);
@ -5871,7 +5810,7 @@ begin
start_dds;
wait_on_sig(dds_done);
wait_on_idle;
cc3 := cc;
cc3 := cc;
AlertIf(empty_sample_head(2) /= 0, "Sample Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_payload_head(2) /= 0, "Payload Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_inst_head(2) /= 26, "Instance Memory Empty List Head incorrect", FAILURE);
@ -5891,7 +5830,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh2;
cc.payload := gen_payload(kh2,9);
@ -5936,7 +5874,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := TRUE;
cc.kind := NOT_ALIVE_UNREGISTERED;
cc.instance := kh1;
cc.payload := gen_payload(kh1,5);
@ -5953,7 +5890,7 @@ begin
start_dds;
wait_on_sig(dds_done);
wait_on_idle;
cc4 := cc;
cc4 := convert_to_serialized_key(cc);
AlertIf(empty_sample_head(2) /= 44, "Sample Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_payload_head(2) /= 30, "Payload Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_inst_head(2) /= 26, "Instance Memory Empty List Head incorrect", FAILURE);
@ -5984,7 +5921,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh2;
cc.payload := gen_payload(kh2,9);
@ -6004,7 +5940,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := TRUE;
cc.kind := NOT_ALIVE_UNREGISTERED;
cc.instance := kh3;
cc.payload := gen_payload(kh3,5);
@ -6021,7 +5956,7 @@ begin
start_dds;
wait_on_sig(dds_done);
wait_on_idle;
cc2 := cc;
cc2 := convert_to_serialized_key(cc);
AlertIf(empty_sample_head(2) /= 11, "Sample Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_payload_head(2) /= 20, "Payload Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_inst_head(2) /= 26, "Instance Memory Empty List Head incorrect", FAILURE);
@ -6030,7 +5965,6 @@ begin
-- INSTANCE MEMORY: 0(I4),9(I1),18(I3)/-
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := TRUE;
cc.kind := NOT_ALIVE_DISPOSED;
cc.instance := kh3;
cc.payload := gen_payload(kh3,5);
@ -6049,7 +5983,7 @@ begin
start_dds;
wait_on_sig(dds_done);
wait_on_idle;
cc1 := cc;
cc1 := convert_to_serialized_key(cc);
AlertIf(empty_sample_head(2) /= 33, "Sample Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_payload_head(2) /= 10, "Payload Memory Empty List Head incorrect", FAILURE);
AlertIf(empty_inst_head(2) /= 26, "Instance Memory Empty List Head incorrect", FAILURE);
@ -6076,7 +6010,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh2;
cc.payload := gen_payload(kh2,9);
@ -6152,7 +6085,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh2;
cc.payload := gen_payload(kh2,9);
@ -6196,7 +6128,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh4;
cc.payload := gen_payload(kh4,9);
@ -6257,7 +6188,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh2;
cc.payload := gen_payload(kh2,9);
@ -6345,7 +6275,6 @@ begin
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh3;
cc.payload := gen_payload(kh3,9);

View File

@ -7,7 +7,7 @@ context osvvm.OsvvmContext;
use work.rtps_test_package.all;
-- This testbench tests the general operation of thr Memory Controler.
-- This testbench tests the general operation of thr Memory Controller.
entity L0_mem_ctrl_test1 is
end entity;

View File

@ -0,0 +1,181 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library osvvm; -- Utility Library
context osvvm.OsvvmContext;
use work.rtps_test_package.all;
-- TODO
entity L0_moving_average_wrapper_test1 is
end entity;
architecture testbench of L0_moving_average_wrapper_test1 is
-- *SIGNAL DECLARATION*
signal clk : std_logic := '0';
signal reset : std_logic := '1';
signal data_in, average : std_logic_vector(31 downto 0);
signal trigger, overflow : std_logic;
shared variable SB : osvvm.ScoreBoardPkg_slv.ScoreBoardPType;
signal stim_done, check_done : std_logic := '0';
begin
-- Unit Under Test
uut : entity work.moving_average_wrapper(arch)
generic map(
INNER_WINDOW_SIZE => 2,
OUTER_WINDOW_SIZE => 2,
DATA_WIDTH => 32,
ENABLE_ROUNDING => TRUE
)
port map(
clk => clk,
reset => reset,
data_in => data_in,
average => average,
trigger => trigger,
overflow => overflow
);
stimulus_prc : process
variable RV : RandomPType;
procedure wait_clock(num : in natural := 1) is
begin
assert (num > 0) report "Num has to be > 0" severity FAILURE;
for i in 0 to num-1 loop
wait until rising_edge(clk);
end loop;
end procedure;
procedure wait_on_sig(signal sig : std_logic) is
begin
if (sig /= '1') then
wait on sig until sig = '1';
end if;
end procedure;
begin
SetAlertLogName("L0_moving_average_wrapper_test1 - General");
SetAlertEnable(FAILURE, TRUE);
SetAlertEnable(ERROR, TRUE);
SetAlertEnable(WARNING, TRUE);
SetLogEnable(DEBUG, FALSE);
SetLogEnable(PASSED, FALSE);
SetLogEnable(INFO, TRUE);
RV.InitSeed(RV'instance_name);
--
Log("Initiating Test", INFO);
stim_done <= '0';
reset <= '1';
data_in <= (others => '0');
wait until rising_edge(clk);
wait until rising_edge(clk);
reset <= '0';
Log("TEST 1: {100, 100, 100, 100}}", INFO);
SB.Push(int(100,32));
data_in <= int(100, 32);
wait_clock(4);
Log("TEST 2: {0, 0, 0, 0}}", INFO);
SB.Push(int(0,32));
data_in <= int(0, 32);
wait_clock(4);
Log("TEST 3: {100,0,100,0}", INFO);
SB.Push(int(50,32));
data_in <= int(100, 32);
wait_clock;
data_in <= int(0, 32);
wait_clock;
data_in <= int(100, 32);
wait_clock;
data_in <= int(0, 32);
wait_clock;
Log("TEST 4: {0,0,100,100}", INFO);
SB.Push(int(50,32));
data_in <= int(0, 32);
wait_clock;
data_in <= int(0, 32);
wait_clock;
data_in <= int(100, 32);
wait_clock;
data_in <= int(100, 32);
wait_clock;
Log("TEST 5: {0,25,50,75}", INFO);
SB.Push(int(38,32)); -- ROUND!
data_in <= int(0, 32);
wait_clock;
data_in <= int(25, 32);
wait_clock;
data_in <= int(50, 32);
wait_clock;
data_in <= int(75, 32);
wait_clock;
Log("TEST 6: {10,50,100,50}", INFO);
SB.Push(int(53,32)); -- ROUND!
data_in <= int(10, 32);
wait_clock;
data_in <= int(50, 32);
wait_clock;
data_in <= int(100, 32);
wait_clock;
data_in <= int(50, 32);
wait_clock;
TranscriptOpen(RESULTS_FILE, APPEND_MODE);
SetTranscriptMirror;
stim_done <= '1';
wait until check_done = '1';
AlertIf(not SB.empty, "Incomplete test run");
ReportAlerts;
TranscriptClose;
std.env.stop;
wait;
end process;
output_check_prc : process(all)
begin
check_done <= '0';
if rising_edge(clk) then
if (trigger = '1') then
SB.Check(average);
end if;
if (stim_done = '1' and SB.empty) then
check_done <= '1';
end if;
end if;
end process;
clock_prc : process
begin
clk <= '1';
wait for 10 ns;
clk <= '0';
wait for 10 ns;
end process;
alert_prc : process(all)
begin
if rising_edge(clk) then
alertif(overflow = '1', "Overflow signal asserted", ERROR);
end if;
end process;
watchdog : process
begin
wait for 5 ms;
Alert("Test timeout", FAILURE);
std.env.stop;
end process;
end architecture;

View File

@ -13,7 +13,7 @@ use work.rtps_test_package.all;
-- This testbench tests the matching of remote participants. Due to the fact, that participant matching does not have an immediate effect visible to the outside,
-- this testbench is using external names to access the memory of the rtps_discovery_module directly and check the contents at the supposed participant locations.
-- This testbench covers following:
-- * Mathing compatible Participants
-- * Matching compatible Participants
-- * Ignoring incompatible Participants
-- * Unmatching previously matched Participants (Due to incompatibility)
-- * Unmatching previously matched Participants (Due to Unregister/Dispose Status Updates)

View File

@ -13,7 +13,7 @@ use work.rtps_test_package.all;
-- This testbench tests the matching of remote participants. Due to the fact, that participant matching does not have an immediate effect visible to the outside,
-- this testbench is using external names to access the memory of the rtps_discovery_module directly and check the contents at the supposed participant locations.
-- This testbench covers following:
-- * Mathing compatible Participants
-- * Matching compatible Participants
-- * Ignoring incompatible Participants
-- * Unmatching previously matched Participants (Due to incompatibility)
-- * Unmatching previously matched Participants (Due to Unregister/Dispose Status Updates)

View File

@ -313,7 +313,7 @@ begin
p1.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1';
p1.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1';
-- Participant 2 (Used for dyncamic Endpoints)
-- Participant 2 (Used for dynamic Endpoints)
p2.guidPrefix := gen_rand_guid_prefix;
p2.nr := 2;
p2.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR));

View File

@ -13,7 +13,7 @@ use work.rtps_test_package.all;
-- This testbench tests the input handling of parameter lists. We issue one parameter list with invalid parameter length (less than expected)
-- and one with valid larger parameter length (extra Bytes after expected parameter end) for each of the parameters that are handled by the Discovery Module by checking if the Participant/Endpoint matched.
-- (We also issue a parameter list that is missing its sentinel)
-- Particpant matches are checked by memory content, and Endpoint matches by the generated match frame.
-- Participant matches are checked by memory content, and Endpoint matches by the generated match frame.
-- The PIDs handled are:
-- * PID_PARTICIPANT_GUID
-- * PID_DOMAIN_ID

View File

@ -16,7 +16,7 @@ use work.rtps_test_package.all;
-- * The Message has less than the required number of octets to contain a full Header
-- * Its protocol value does not match the value of PROTOCOL_RTPS
-- * The major protocol version is larger than the major protocol version supported by the implementation
-- DATA SUBEMSSAGE
-- DATA SUBMESSAGE
-- * Empty DATA Submessage (No payload/inline-QoS)
-- * META/USER Traffic
-- * Little/Big Endian
@ -50,11 +50,11 @@ use work.rtps_test_package.all;
-- * lastSN.value < firstSN.value - 1
-- INFO_SOURCE SUBMESSAGE
-- * Little/Big Endian
-- * Protocol Version missmatch
-- * Protocol Version mismatch
-- * SubmessageLength invalid
-- INFO_DESTINATION SUBMESSAGE
-- * Little/Big Endian
-- * Destination GUID Prefix missmatch
-- * Destination GUID Prefix mismatch
-- * SubmessageLength invalid
-- INFO_REPLY SUBMESSAGE
-- * Little/Big Endian
@ -73,11 +73,11 @@ use work.rtps_test_package.all;
-- * SubmessageLength invalid
-- PAD SUBMESSAGE
-- * 28 Padding Bytes
-- UKNOWN SUBMESSAGE
-- UNKNOWN SUBMESSAGE
-- * DATA_FRAG Submessage
-- * HEARTBEAT_FRAG Submessage
-- * NACK_FRAG Submessage
-- * UKNOWN SID
-- * UNKNOWN SID
entity L0_rtps_handler_test1 is
end entity;
@ -207,7 +207,7 @@ begin
stimulus := EMPTY_TEST_PACKET;
reference := EMPTY_TEST_PACKET;
Log("Sending invalid RTPS Header [Protocol Missmatch]", INFO);
Log("Sending invalid RTPS Header [Protocol Mismatch]", INFO);
-- UDP Header
gen_output_header(UDP_META, stimulus);
-- RTPS Header [Incompatible Protocol]
@ -225,7 +225,7 @@ begin
stimulus := EMPTY_TEST_PACKET;
reference := EMPTY_TEST_PACKET;
Log("Sending invalid RTPS Header [Protocol Major Version Missmatch]", INFO);
Log("Sending invalid RTPS Header [Protocol Major Version Mismatch]", INFO);
-- UDP Header
gen_output_header(UDP_META, stimulus);
-- RTPS Header [Incompatible Version]
@ -243,7 +243,7 @@ begin
stimulus := EMPTY_TEST_PACKET;
reference := EMPTY_TEST_PACKET;
Log("Sending valid RTPS Header [Protocol Minor Version Missmatch]", INFO);
Log("Sending valid RTPS Header [Protocol Minor Version Mismatch]", INFO);
-- UDP Header
gen_output_header(UDP_META, stimulus);
-- RTPS Header
@ -382,7 +382,7 @@ begin
gen_output_header(UDP_META, stimulus);
-- RTPS Header
gen_rtps_header(rtps_header, stimulus);
-- Valid DATA [SubLength > PackeSize] (Dropped)
-- Valid DATA [SubLength > PacketSize] (Dropped)
rtps_sub := DEFAULT_RTPS_SUBMESSAGE;
rtps_sub.submessageID := SID_DATA;
rtps_sub.writerId := DEFAULT_WRITER_ENTITYID;
@ -930,7 +930,7 @@ begin
gen_output_header(UDP_META, stimulus);
-- RTPS Header
gen_rtps_header(rtps_header, stimulus);
-- Invalid HEARTBEAT [SubLength > PackeSize] (Dropped)
-- Invalid HEARTBEAT [SubLength > PacketSize] (Dropped)
rtps_sub := DEFAULT_RTPS_SUBMESSAGE;
rtps_sub.submessageID := SID_HEARTBEAT;
rtps_sub.writerId := DEFAULT_WRITER_ENTITYID;
@ -1082,7 +1082,7 @@ begin
gen_rtps_submessage(rtps_data, stimulus);
gen_rtps_handler_out(rtps_data, UDP_META.src, TRUE, TIME_INVALID, rtps_sub.guidPrefix, reference);
rtps_data.writerSN := rtps_data.writerSN + 1;
-- Valid INFO_SOURCE [Protocol Major Version Missmatch] (Dropped)
-- Valid INFO_SOURCE [Protocol Major Version Mismatch] (Dropped)
rtps_sub := DEFAULT_RTPS_SUBMESSAGE;
rtps_sub.submessageID := SID_INFO_SRC;
rtps_sub.version := PROTOCOLVERSION_1_0;
@ -1382,7 +1382,7 @@ begin
stimulus := EMPTY_TEST_PACKET;
reference := EMPTY_TEST_PACKET;
Log("Sending invalid INFO_TMESTAMP [Submessage Length too small]", INFO);
Log("Sending invalid INFO_TIMESTAMP [Submessage Length too small]", INFO);
-- UDP Header
gen_output_header(UDP_META, stimulus);
-- RTPS Header
@ -1469,7 +1469,7 @@ begin
gen_rtps_submessage(rtps_data, stimulus);
gen_rtps_handler_out(rtps_data, UDP_META.src, TRUE, TIME_INVALID, rtps_header.guidPrefix, reference);
rtps_data.writerSN := rtps_data.writerSN + 1;
-- UKNOWN (Dropped)
-- UNKNOWN (Dropped)
rtps_sub := DEFAULT_RTPS_SUBMESSAGE;
rtps_sub.submessageID := (others => '1');
rtps_sub.submessageLength := int(28,16);

View File

@ -127,7 +127,7 @@ begin
wait until rising_edge(clk);
reset <= '0';
for i in 0 to 2 loop -- USER/META/UKNOWN Traffic
for i in 0 to 2 loop -- USER/META/UNKNOWN Traffic
case (i) is
-- META TRAFFIC ADDRESSES
when 0 =>
@ -139,7 +139,7 @@ begin
tmp_loc_list := DEST_LOC.user;
ref1 := (NUM_ENDPOINTS => '0', others => '1');
is_meta := FALSE;
-- UKNOWN ADDRESSES
-- UNKNOWN ADDRESSES
when others =>
ref1 := (others => '0');
tmp_loc_list := ( numLocators => int(2,CDR_LONG_WIDTH),
@ -164,13 +164,13 @@ begin
for k in 0 to NUM_ENDPOINTS+2 loop -- Destination Entity ID
case (k) is
-- UKNOWN
-- UNKNOWN
when NUM_ENDPOINTS =>
ref2 := (others => '0');
tmp_id := RV.RandSlv(ENTITYID_WIDTH);
tmp_id(ENTITY_KIND_H_RANGE) := USER_DEFINED_ENTITY;
tmp_id(ENTITY_KIND_L_RANGE) := UNKNOWN_KIND;
-- ENTITYID_UKNOWN
-- ENTITYID_UNKNOWN
when NUM_ENDPOINTS+1 =>
tmp_id := ENTITYID_UNKNOWN;
ref2 := (others => '1');

View File

@ -199,7 +199,7 @@ begin
-- Push T3 Packet 1
push_reference(1, stimulus(t3));
start_test;
-- Wait until begining of t3 sending
-- Wait until beginning of t3 sending
tmp := (others => '1');
tmp(t3) := '0';
wait on rd_sig until packet_sent = tmp and rd_sig = not tmp;

View File

@ -13,7 +13,7 @@ use work.rtps_test_package.all;
-- This testbench tests the metatraffic operation behaviour of the RTPS Reader. (Remote Endpoint matching and memory behaviour)
-- This testbench is using external names to access the memory of the rtps_reader directly and check the contents at the supposed locations.
-- This testbench covers following:
-- * Mathing Endpoint
-- * Matching Endpoint
-- * Memory Full Behaviour
-- * Unmatching Endpoint
-- * Unmatching Participant
@ -369,7 +369,7 @@ begin
-- MEMORY 0 STATE 0(P1E2),34(P1E3)/17
-- MEMORY 1 STATE 17(P1E3)/0,34
Log("Unknown Metatraffic Operation followed by insertion of Enpoint 1 Participant 0 {READER 0, READER 1}", INFO);
Log("Unknown Metatraffic Operation followed by insertion of Endpoint 1 Participant 0 {READER 0, READER 1}", INFO);
for i in 0 to 9 loop
stimulus.data(i) := RV.RandSlv(WORD_WIDTH);
end loop;
@ -542,7 +542,7 @@ begin
case (stage_hc) is
when IDLE =>
if (start_hc /= (start_hc'range => '0')) then
-- HACK: We trigger all acks because we cannot use 'ind' variable in the same clock cycle
-- HACK: We trigger all ACKs because we cannot use 'ind' variable in the same clock cycle
-- Since the uut only interfaces with 1 HC at a time (one-hot encoded start_hc) this
-- is still valid.
ack_hc <= (others => '1');

View File

@ -1736,7 +1736,7 @@ begin
case (stage_hc) is
when IDLE =>
if (start_hc /= (start_hc'range => '0')) then
-- HACK: We trigger all acks because we cannot use 'ind' variable in the same clock cycle
-- HACK: We trigger all ACKs because we cannot use 'ind' variable in the same clock cycle
-- Since the uut only interfaces with 1 HC at a time (one-hot encoded start_hc) this
-- is still valid.
ack_hc <= (others => '1');

View File

@ -13,7 +13,7 @@ use work.rtps_test_package.all;
-- This testbench tests the metatraffic operation behaviour of the RTPS Writer. (Remote Endpoint matching and Memory behaviour)
-- This testbench is using external names to access the memory of the rtps_reader directly and check the contents at the supposed locations.
-- This testbench covers following:
-- * Mathing Endpoint
-- * Matching Endpoint
-- * Memory Full Behaviour
-- * Unmatching Endpoint
-- * Unmatching Participant
@ -356,7 +356,7 @@ begin
-- MEMORY 0 STATE 0(P1E2),34(P1E3)/17
-- MEMORY 1 STATE 17(P1E3)/0,34
Log("Unknown Metatraffic Operation followed by insertion of Enpoint 1 Participant 0 {WRITER 0, WRITER 1}", INFO);
Log("Unknown Metatraffic Operation followed by insertion of Endpoint 1 Participant 0 {WRITER 0, WRITER 1}", INFO);
for i in 0 to 9 loop
stimulus.data(i) := RV.RandSlv(WORD_WIDTH);
end loop;

View File

@ -338,7 +338,7 @@ begin
wait_on_idle;
Log("Current Time: 1s", INFO);
Log("WRITER 0: Removal of Enpoint 0", INFO);
Log("WRITER 0: Removal of Endpoint 0", INFO);
test_time <= gen_duration(1 sec);
wait until rising_edge(clk);
wait until rising_edge(clk); -- Allow idle_sig to go low
@ -369,7 +369,7 @@ begin
-- MEMORY 1 STATE 34(E2),17(E1),0(E0)/-
Log("Current Time: 1.5s", INFO);
Log("WRITER 0: Removal of Enpoint 2", INFO);
Log("WRITER 0: Removal of Endpoint 2", INFO);
test_time <= gen_duration(1.5 sec);
wait until rising_edge(clk);
wait until rising_edge(clk); -- Allow idle_sig to go low

View File

@ -75,6 +75,10 @@ begin
done_user => open,
return_code_user => open,
instance_handle_out_user => open,
valid_out_user => open,
ready_out_user => '1',
data_out_user => open,
last_word_out_user => open,
status_user => open,
id => id_in,
a => a_in,
@ -116,6 +120,10 @@ begin
get_data_user => get_data_r,
done_user => open,
return_code_user => open,
valid_out_user => open,
ready_out_user => '1',
data_out_user => open,
last_word_out_user => open,
sample_info_user => open,
sample_info_valid_user => open,
sample_info_ack_user => '1',

View File

@ -78,6 +78,10 @@ begin
done_user => open,
return_code_user => open,
instance_handle_out_user => open,
valid_out_user => open,
ready_out_user => '1',
data_out_user => open,
last_word_out_user => open,
status_user => open,
id => id_in,
a => a_in,
@ -119,6 +123,10 @@ begin
get_data_user => get_data_r,
done_user => open,
return_code_user => open,
valid_out_user => open,
ready_out_user => '1',
data_out_user => open,
last_word_out_user => open,
sample_info_user => open,
sample_info_valid_user => open,
sample_info_ack_user => '1',

View File

@ -9,11 +9,12 @@ use work.rtps_package.all;
use work.user_config.all;
use work.rtps_config_package.all;
use work.rtps_test_package.all;
use work.Type2_package.all;
use work.Type1_package.all;
-- This testbench tests the KEY_HOLDER commands of TYPE1.
-- It uses the writer_interface to send a valid payload, then reads the serialized key and the key hash. The returned serialized key is compared to a "handcrafted" reference, and the key hash is latched for later comparison.
-- Then the reference serialized key is pushed (resetting the internaly generated key hash), and the serialized key and key hash are re-read and compared (The key hash is compared to the previosuly compared).
-- Firstly an invalid serialized payload is sent to test the decode error.
-- Secondly the writer_interface is used to send a valid payload, then reads the serialized key and the key hash. The returned serialized key is compared to a "handcrafted" reference, and the key hash is latched for later comparison.
-- Thirty the reference serialized key is pushed (resetting the internally generated key hash), and the serialized key and key hash are re-read and compared (The key hash is compared to the previously compared).
-- The payload is sent in Big Endian.
entity L1_Type1_key_holder_test1 is
@ -22,13 +23,14 @@ end entity;
architecture testbench of L1_Type1_key_holder_test1 is
signal clk, reset : std_logic := '0';
signal ready_sk, ready_w, ready_kh_in, ready_kh_out, valid_sk, valid_w, valid_kh_in, valid_kh_out, last_word_sk, last_word_w, last_word_kh_in, last_word_kh_out : std_logic := '0';
signal data_sk, data_w, data_kh_in, data_kh_out : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0');
signal ready_de, ready_sk, ready_w, ready_kh_in, ready_kh_out, valid_de, valid_sk, valid_w, valid_kh_in, valid_kh_out, last_word_de, last_word_sk, last_word_w, last_word_kh_in, last_word_kh_out : std_logic := '0';
signal data_de, data_sk, data_w, data_kh_in, data_kh_out : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0');
signal start_w, ack_w, start_kh, ack_kh, decode_error, encode_done : std_logic := '0';
signal opcode_kh : KEY_HOLDER_OPCODE_TYPE := NOP;
shared variable SB_out : osvvm.ScoreBoardPkg_slv.ScoreBoardPType;
shared variable serialized_key : TEST_PACKET_TYPE := EMPTY_TEST_PACKET;
shared variable serialized_key, invalid_data : TEST_PACKET_TYPE := EMPTY_TEST_PACKET;
signal key_hash, key_hash_latch : KEY_HASH_TYPE := KEY_HASH_NIL;
signal send_invalid_data : std_logic := '0';
signal id_in : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0');
signal a_in : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0');
@ -65,6 +67,10 @@ begin
done_user => open,
return_code_user => open,
instance_handle_out_user => open,
valid_out_user => open,
ready_out_user => '1',
data_out_user => open,
last_word_out_user => open,
status_user => open,
encode_done => encode_done,
id => id_in,
@ -125,15 +131,24 @@ begin
KH := GetAlertLogID("KeyHash", ALERTLOG_BASE_ID);
Log("Initial Reset", INFO);
start_w <= '0';
reset <= '1';
send_invalid_data <= '0';
start_w <= '0';
reset <= '1';
wait until rising_edge(clk);
wait until rising_edge(clk);
reset <= '0';
-- Create Invalid Serialized Payload
for i in 0 to MAX_TYPE1_SIZE loop
invalid_data.data(i) := RV.RandSlv(invalid_data.data(i)'length);
invalid_data.length := invalid_data.length + 1;
end loop;
invalid_data.last(invalid_data.length-1) := '1';
-- Serialized Key Payload Header
gen_CDR(SERIALIZED_KEY_HEADER, ALIGN_4, align_offset, serialized_key);
-- Reset Alignement
write_serialized_payload(SERIALIZED_KEY_HEADER, ALIGN_4, align_offset, serialized_key);
-- Reset Alignment
align_offset := (others => '0');
Log("Setting Data in Writer Side", INFO);
@ -141,7 +156,7 @@ begin
id_in <= RV.RandSlv(id_in'length);
a_in <= RV.RandSlv(a_in'length);
wait for 0 ns;
gen_CDR(id_in, ALIGN_4, align_offset, serialized_key);
write_serialized_payload(id_in, ALIGN_4, align_offset, serialized_key);
-- Finalize Serialized Key
if (align_offset(1 downto 0) /= "00") then
@ -150,6 +165,24 @@ begin
push_sk;
Log("Push Invalid DATA", INFO);
send_invalid_data <= '1';
opcode_kh <= PUSH_DATA;
start_w <= '1';
wait_on_sig(ack_w);
wait until rising_edge(clk);
start_w <= '0';
start_kh <= '1';
wait_on_sig(ack_kh);
wait until rising_edge(clk);
start_kh <= '0';
wait_on_sig(last_word_kh_in);
wait_on_sig(ready_kh_in);
wait until rising_edge(clk);
Alertif(decode_error /= '1', "Decode error not asserted", ERROR);
send_invalid_data <= '0';
Log("Push DATA", INFO);
opcode_kh <= PUSH_DATA;
start_w <= '1';
@ -160,9 +193,12 @@ begin
wait_on_sig(ack_kh);
wait until rising_edge(clk);
start_kh <= '0';
wait for 1 ps; -- Wait until signals are stable
Alertif(decode_error /= '0', "Decode error still asserted", ERROR);
wait_on_sig(last_word_kh_in);
wait_on_sig(ready_kh_in);
wait until rising_edge(clk);
Alertif(decode_error = '1', "Decode error asserted", ERROR);
Log("Read and Compare Serialized Key", INFO);
opcode_kh <= READ_SERIALIZED_KEY;
@ -193,6 +229,7 @@ begin
wait_on_sig(last_word_sk);
wait_on_sig(ready_sk);
wait until rising_edge(clk);
Alertif(decode_error = '1', "Decode error asserted", ERROR);
push_sk;
Log("Read and Compare Serialized Key", INFO);
@ -234,28 +271,29 @@ begin
wait for TEST_CLOCK_PERIOD/2;
end process;
alert_prc : process(all)
begin
if rising_edge(clk) then
Alertif(decode_error = '1', "The Reader signals a DECODE Error", ERROR);
end if;
end process;
switch_prc : process(all)
begin
ready_w <= '0';
ready_de <= '0';
ready_sk <= '0';
case (opcode_kh) is
when PUSH_SERIALIZED_KEY =>
ready_sk <= ready_kh_in;
valid_kh_in <= valid_sk;
data_kh_in <= data_sk;
last_word_kh_in <= last_word_sk;
ready_w <= '0';
when others =>
ready_w <= ready_kh_in;
valid_kh_in <= valid_w;
data_kh_in <= data_w;
last_word_kh_in <= last_word_w;
ready_sk <= '0';
if (send_invalid_data = '1') then
ready_de <= ready_kh_in;
valid_kh_in <= valid_de;
data_kh_in <= data_de;
last_word_kh_in <= last_word_de;
else
ready_w <= ready_kh_in;
valid_kh_in <= valid_w;
data_kh_in <= data_w;
last_word_kh_in <= last_word_w;
end if;
end case;
end process;
@ -279,6 +317,26 @@ begin
end if;
end process;
de_prc : process(all)
variable cnt : natural := 0;
begin
valid_de <= '1';
data_de <= invalid_data.data(cnt);
if (cnt = invalid_data.length-1) then
last_word_de <= '1';
end if;
if rising_edge(clk) then
if (ready_de = '1') then
if (cnt = invalid_data.length-1) then
cnt := 0;
else
cnt := cnt + 1;
end if;
end if;
end if;
end process;
output_check_prc : process(all)
variable cnt : natural range 0 to 3 := 0;
begin

View File

@ -9,11 +9,12 @@ use work.rtps_package.all;
use work.user_config.all;
use work.rtps_config_package.all;
use work.rtps_test_package.all;
use work.Type2_package.all;
use work.Type1_package.all;
-- This testbench tests the KEY_HOLDER commands of TYPE1.
-- It uses the writer_interface to send a valid payload, then reads the serialized key and the key hash. The returned serialized key is compared to a "handcrafted" reference, and the key hash is latched for later comparison.
-- Then the reference serialized key is pushed (resetting the internaly generated key hash), and the serialized key and key hash are re-read and compared (The key hash is compared to the previosuly compared).
-- Firstly an invalid serialized payload is sent to test the decode error.
-- Secondly the writer_interface is used to send a valid payload, then reads the serialized key and the key hash. The returned serialized key is compared to a "handcrafted" reference, and the key hash is latched for later comparison.
-- Thirty the reference serialized key is pushed (resetting the internally generated key hash), and the serialized key and key hash are re-read and compared (The key hash is compared to the previously compared).
-- The payload is sent in Little Endian.
entity L1_Type1_key_holder_test2 is
@ -22,13 +23,14 @@ end entity;
architecture testbench of L1_Type1_key_holder_test2 is
signal clk, reset : std_logic := '0';
signal ready_sk, ready_w, ready_kh_in, ready_kh_out, valid_sk, valid_w, valid_kh_in, valid_kh_out, last_word_sk, last_word_w, last_word_kh_in, last_word_kh_out : std_logic := '0';
signal data_sk, data_w, data_kh_in, data_kh_out : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0');
signal ready_de, ready_sk, ready_w, ready_kh_in, ready_kh_out, valid_de, valid_sk, valid_w, valid_kh_in, valid_kh_out, last_word_de, last_word_sk, last_word_w, last_word_kh_in, last_word_kh_out : std_logic := '0';
signal data_de, data_sk, data_w, data_kh_in, data_kh_out : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0');
signal start_w, ack_w, start_kh, ack_kh, decode_error, encode_done : std_logic := '0';
signal opcode_kh : KEY_HOLDER_OPCODE_TYPE := NOP;
shared variable SB_out : osvvm.ScoreBoardPkg_slv.ScoreBoardPType;
shared variable serialized_key : TEST_PACKET_TYPE := EMPTY_TEST_PACKET;
shared variable serialized_key, invalid_data : TEST_PACKET_TYPE := EMPTY_TEST_PACKET;
signal key_hash, key_hash_latch : KEY_HASH_TYPE := KEY_HASH_NIL;
signal send_invalid_data : std_logic := '0';
signal id_in : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0');
signal a_in : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0');
@ -68,6 +70,10 @@ begin
done_user => open,
return_code_user => open,
instance_handle_out_user => open,
valid_out_user => open,
ready_out_user => '1',
data_out_user => open,
last_word_out_user => open,
status_user => open,
encode_done => encode_done,
id => id_in,
@ -131,15 +137,24 @@ begin
KH := GetAlertLogID("KeyHash", ALERTLOG_BASE_ID);
Log("Initial Reset", INFO);
start_w <= '0';
reset <= '1';
send_invalid_data <= '0';
start_w <= '0';
reset <= '1';
wait until rising_edge(clk);
wait until rising_edge(clk);
reset <= '0';
-- Create Invalid Serialized Payload
for i in 0 to MAX_TYPE1_SIZE loop
invalid_data.data(i) := RV.RandSlv(invalid_data.data(i)'length);
invalid_data.length := invalid_data.length + 1;
end loop;
invalid_data.last(invalid_data.length-1) := '1';
-- Serialized Key Payload Header
gen_CDR(SERIALIZED_KEY_HEADER, ALIGN_4, align_offset, serialized_key);
-- Reset Alignement
write_serialized_payload(SERIALIZED_KEY_HEADER, ALIGN_4, align_offset, serialized_key);
-- Reset Alignment
align_offset := (others => '0');
Log("Setting Data in Writer Side", INFO);
@ -147,7 +162,7 @@ begin
id_in <= RV.RandSlv(id_in'length);
a_in <= RV.RandSlv(a_in'length);
wait for 0 ns;
gen_CDR(endian_swap('1',id_in), ALIGN_4, align_offset, serialized_key);
write_serialized_payload(endian_swap('1',id_in), ALIGN_4, align_offset, serialized_key);
-- Finalize Serialized Key
if (align_offset(1 downto 0) /= "00") then
@ -156,6 +171,24 @@ begin
push_sk;
Log("Push Invalid DATA", INFO);
send_invalid_data <= '1';
opcode_kh <= PUSH_DATA;
start_w <= '1';
wait_on_sig(ack_w);
wait until rising_edge(clk);
start_w <= '0';
start_kh <= '1';
wait_on_sig(ack_kh);
wait until rising_edge(clk);
start_kh <= '0';
wait_on_sig(last_word_kh_in);
wait_on_sig(ready_kh_in);
wait until rising_edge(clk);
Alertif(decode_error /= '1', "Decode error not asserted", ERROR);
send_invalid_data <= '0';
Log("Push DATA", INFO);
opcode_kh <= PUSH_DATA;
start_w <= '1';
@ -166,9 +199,12 @@ begin
wait_on_sig(ack_kh);
wait until rising_edge(clk);
start_kh <= '0';
wait for 1 ps; -- Wait until signals are stable
Alertif(decode_error /= '0', "Decode error still asserted", ERROR);
wait_on_sig(last_word_kh_in);
wait_on_sig(ready_kh_in);
wait until rising_edge(clk);
Alertif(decode_error = '1', "Decode error asserted", ERROR);
Log("Read and Compare Serialized Key", INFO);
opcode_kh <= READ_SERIALIZED_KEY;
@ -199,6 +235,7 @@ begin
wait_on_sig(last_word_sk);
wait_on_sig(ready_sk);
wait until rising_edge(clk);
Alertif(decode_error = '1', "Decode error asserted", ERROR);
push_sk;
Log("Read and Compare Serialized Key", INFO);
@ -240,28 +277,29 @@ begin
wait for TEST_CLOCK_PERIOD/2;
end process;
alert_prc : process(all)
begin
if rising_edge(clk) then
Alertif(decode_error = '1', "The Reader signals a DECODE Error", ERROR);
end if;
end process;
switch_prc : process(all)
begin
ready_w <= '0';
ready_de <= '0';
ready_sk <= '0';
case (opcode_kh) is
when PUSH_SERIALIZED_KEY =>
ready_sk <= ready_kh_in;
valid_kh_in <= valid_sk;
data_kh_in <= data_sk;
last_word_kh_in <= last_word_sk;
ready_w <= '0';
when others =>
if (send_invalid_data = '1') then
ready_de <= ready_kh_in;
valid_kh_in <= valid_de;
data_kh_in <= data_de;
last_word_kh_in <= last_word_de;
else
ready_w <= ready_kh_in;
valid_kh_in <= valid_w;
data_kh_in <= data_w;
last_word_kh_in <= last_word_w;
ready_sk <= '0';
end if;
end case;
end process;
@ -285,6 +323,26 @@ begin
end if;
end process;
de_prc : process(all)
variable cnt : natural := 0;
begin
valid_de <= '1';
data_de <= invalid_data.data(cnt);
if (cnt = invalid_data.length-1) then
last_word_de <= '1';
end if;
if rising_edge(clk) then
if (ready_de = '1') then
if (cnt = invalid_data.length-1) then
cnt := 0;
else
cnt := cnt + 1;
end if;
end if;
end if;
end process;
output_check_prc : process(all)
variable cnt : natural range 0 to 3 := 0;
begin

View File

@ -97,6 +97,10 @@ begin
done_user => open,
return_code_user => open,
instance_handle_out_user => open,
valid_out_user => open,
ready_out_user => '1',
data_out_user => open,
last_word_out_user => open,
status_user => open,
id => id_in,
TestSequence_len => TestSequence_len_in,
@ -188,6 +192,10 @@ begin
get_data_user => get_data_r,
done_user => open,
return_code_user => open,
valid_out_user => open,
ready_out_user => '1',
data_out_user => open,
last_word_out_user => open,
sample_info_user => open,
sample_info_valid_user => open,
sample_info_ack_user => '1',

View File

@ -100,6 +100,10 @@ begin
done_user => open,
return_code_user => open,
instance_handle_out_user => open,
valid_out_user => open,
ready_out_user => '1',
data_out_user => open,
last_word_out_user => open,
status_user => open,
id => id_in,
TestSequence_len => TestSequence_len_in,
@ -191,6 +195,10 @@ begin
get_data_user => get_data_r,
done_user => open,
return_code_user => open,
valid_out_user => open,
ready_out_user => '1',
data_out_user => open,
last_word_out_user => open,
sample_info_user => open,
sample_info_valid_user => open,
sample_info_ack_user => '1',

View File

@ -12,8 +12,9 @@ use work.rtps_test_package.all;
use work.Type2_package.all;
-- This testbench tests the KEY_HOLDER commands of TYPE2.
-- It uses the writer_interface to send a valid payload, then reads the serialized key and the key hash. The returned serialized key is compared to a "handcrafted" reference, and the key hash is latched for later comparison.
-- Then the reference serialized key is pushed (resetting the internaly generated key hash), and the serialized key and key hash are re-read and compared (The key hash is compared to the previosuly compared).
-- Firstly an invalid serialized payload is sent to test the decode error.
-- Secondly the writer_interface is used to send a valid payload, then reads the serialized key and the key hash. The returned serialized key is compared to a "handcrafted" reference, and the key hash is latched for later comparison.
-- Thirty the reference serialized key is pushed (resetting the internally generated key hash), and the serialized key and key hash are re-read and compared (The key hash is compared to the previously compared).
-- The payload is sent in Big Endian.
entity L1_Type2_key_holder_test1 is
@ -22,13 +23,14 @@ end entity;
architecture testbench of L1_Type2_key_holder_test1 is
signal clk, reset : std_logic := '0';
signal ready_sk, ready_w, ready_kh_in, ready_kh_out, valid_sk, valid_w, valid_kh_in, valid_kh_out, last_word_sk, last_word_w, last_word_kh_in, last_word_kh_out : std_logic := '0';
signal data_sk, data_w, data_kh_in, data_kh_out : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0');
signal ready_de, ready_sk, ready_w, ready_kh_in, ready_kh_out, valid_de, valid_sk, valid_w, valid_kh_in, valid_kh_out, last_word_de, last_word_sk, last_word_w, last_word_kh_in, last_word_kh_out : std_logic := '0';
signal data_de, data_sk, data_w, data_kh_in, data_kh_out : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0');
signal start_w, ack_w, start_kh, ack_kh, decode_error, encode_done : std_logic := '0';
signal opcode_kh : KEY_HOLDER_OPCODE_TYPE := NOP;
shared variable SB_out : osvvm.ScoreBoardPkg_slv.ScoreBoardPType;
shared variable serialized_key : TEST_PACKET_TYPE := EMPTY_TEST_PACKET;
shared variable serialized_key, invalid_data : TEST_PACKET_TYPE := EMPTY_TEST_PACKET;
signal key_hash, key_hash_latch : KEY_HASH_TYPE := KEY_HASH_NIL;
signal send_invalid_data : std_logic := '0';
signal id_in : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0');
signal TestSequence_len_in, TestSequence_addr_in: std_logic_vector(TESTSEQUENCE_ADDR_WIDTH-1 downto 0) := (others => '0');
@ -87,6 +89,10 @@ begin
done_user => open,
return_code_user => open,
instance_handle_out_user => open,
valid_out_user => open,
ready_out_user => '1',
data_out_user => open,
last_word_out_user => open,
status_user => open,
encode_done => encode_done,
id => id_in,
@ -197,15 +203,24 @@ begin
KH := GetAlertLogID("KeyHash", ALERTLOG_BASE_ID);
Log("Initial Reset", INFO);
start_w <= '0';
reset <= '1';
send_invalid_data <= '0';
start_w <= '0';
reset <= '1';
wait until rising_edge(clk);
wait until rising_edge(clk);
reset <= '0';
-- Create Invalid Serialized Payload
for i in 0 to MAX_TYPE2_SIZE loop
invalid_data.data(i) := RV.RandSlv(invalid_data.data(i)'length);
invalid_data.length := invalid_data.length + 1;
end loop;
invalid_data.last(invalid_data.length-1) := '1';
-- Serialized Key Payload Header
gen_CDR(SERIALIZED_KEY_HEADER, ALIGN_4, align_offset, serialized_key);
-- Reset Alignement
write_serialized_payload(SERIALIZED_KEY_HEADER, ALIGN_4, align_offset, serialized_key);
-- Reset Alignment
align_offset := (others => '0');
Log("Setting Data in Writer Side", INFO);
@ -218,10 +233,10 @@ begin
TestUnion_OctetU_in <= RV.RandSlv(TestUnion_OctetU_in'length);
TestBitmask_in <= RV.RandSlv(TestBitmask_in'length);
wait for 0 ns;
gen_CDR(id_in, ALIGN_4, align_offset, serialized_key);
write_serialized_payload(id_in, ALIGN_4, align_offset, serialized_key);
TestSequence_len_in <= int(2,TestSequence_len_in'length);
gen_CDR(int(2,CDR_LONG_WIDTH), ALIGN_4, align_offset, serialized_key);
write_serialized_payload(int(2,CDR_LONG_WIDTH), ALIGN_4, align_offset, serialized_key);
-- Memory
for i in 0 to 1 loop
TestSequence_addr_in <= int(i,TestSequence_addr_in'length);
@ -237,7 +252,7 @@ begin
TestSequence_TestArray_wen_in <= '1';
wait until rising_edge(clk);
TestSequence_TestArray_wen_in <= '0';
gen_CDR(TestSequence_TestArray_w_in, ALIGN_1, align_offset, serialized_key);
write_serialized_payload(TestSequence_TestArray_w_in, ALIGN_1, align_offset, serialized_key);
end loop;
wait_on_sig(TestSequence_ready_in);
TestSequence_wen_in <= '1';
@ -273,9 +288,10 @@ begin
push_sk;
Log("Push DATA", INFO);
opcode_kh <= PUSH_DATA;
start_w <= '1';
Log("Push Invalid DATA", INFO);
send_invalid_data <= '1';
opcode_kh <= PUSH_DATA;
start_w <= '1';
wait_on_sig(ack_w);
wait until rising_edge(clk);
start_w <= '0';
@ -287,6 +303,26 @@ begin
wait_on_sig(ready_kh_in);
wait until rising_edge(clk);
Alertif(decode_error /= '1', "Decode error not asserted", ERROR);
send_invalid_data <= '0';
Log("Push DATA", INFO);
opcode_kh <= PUSH_DATA;
start_w <= '1';
wait_on_sig(ack_w);
wait until rising_edge(clk);
start_w <= '0';
start_kh <= '1';
wait_on_sig(ack_kh);
wait until rising_edge(clk);
start_kh <= '0';
wait for 1 ps; -- Wait until signals are stable
Alertif(decode_error /= '0', "Decode error still asserted", ERROR);
wait_on_sig(last_word_kh_in);
wait_on_sig(ready_kh_in);
wait until rising_edge(clk);
Alertif(decode_error = '1', "Decode error asserted", ERROR);
Log("Read and Compare Serialized Key", INFO);
opcode_kh <= READ_SERIALIZED_KEY;
start_kh <= '1';
@ -316,6 +352,7 @@ begin
wait_on_sig(last_word_sk);
wait_on_sig(ready_sk);
wait until rising_edge(clk);
Alertif(decode_error = '1', "Decode error asserted", ERROR);
push_sk;
Log("Read and Compare Serialized Key", INFO);
@ -357,28 +394,29 @@ begin
wait for TEST_CLOCK_PERIOD/2;
end process;
alert_prc : process(all)
begin
if rising_edge(clk) then
Alertif(decode_error = '1', "The Reader signals a DECODE Error", ERROR);
end if;
end process;
switch_prc : process(all)
begin
ready_w <= '0';
ready_de <= '0';
ready_sk <= '0';
case (opcode_kh) is
when PUSH_SERIALIZED_KEY =>
ready_sk <= ready_kh_in;
valid_kh_in <= valid_sk;
data_kh_in <= data_sk;
last_word_kh_in <= last_word_sk;
ready_w <= '0';
when others =>
if (send_invalid_data = '1') then
ready_de <= ready_kh_in;
valid_kh_in <= valid_de;
data_kh_in <= data_de;
last_word_kh_in <= last_word_de;
else
ready_w <= ready_kh_in;
valid_kh_in <= valid_w;
data_kh_in <= data_w;
last_word_kh_in <= last_word_w;
ready_sk <= '0';
end if;
end case;
end process;
@ -402,6 +440,26 @@ begin
end if;
end process;
de_prc : process(all)
variable cnt : natural := 0;
begin
valid_de <= '1';
data_de <= invalid_data.data(cnt);
if (cnt = invalid_data.length-1) then
last_word_de <= '1';
end if;
if rising_edge(clk) then
if (ready_de = '1') then
if (cnt = invalid_data.length-1) then
cnt := 0;
else
cnt := cnt + 1;
end if;
end if;
end if;
end process;
output_check_prc : process(all)
variable cnt : natural range 0 to 3 := 0;
begin

View File

@ -12,8 +12,9 @@ use work.rtps_test_package.all;
use work.Type2_package.all;
-- This testbench tests the KEY_HOLDER commands of TYPE2.
-- It uses the writer_interface to send a valid payload, then reads the serialized key and the key hash. The returned serialized key is compared to a "handcrafted" reference, and the key hash is latched for later comparison.
-- Then the reference serialized key is pushed (resetting the internaly generated key hash), and the serialized key and key hash are re-read and compared (The key hash is compared to the previosuly compared).
-- Firstly an invalid serialized payload is sent to test the decode error.
-- Secondly the writer_interface is used to send a valid payload, then reads the serialized key and the key hash. The returned serialized key is compared to a "handcrafted" reference, and the key hash is latched for later comparison.
-- Thirty the reference serialized key is pushed (resetting the internally generated key hash), and the serialized key and key hash are re-read and compared (The key hash is compared to the previously compared).
-- The payload is sent in Little Endian.
entity L1_Type2_key_holder_test2 is
@ -22,13 +23,14 @@ end entity;
architecture testbench of L1_Type2_key_holder_test2 is
signal clk, reset : std_logic := '0';
signal ready_sk, ready_w, ready_kh_in, ready_kh_out, valid_sk, valid_w, valid_kh_in, valid_kh_out, last_word_sk, last_word_w, last_word_kh_in, last_word_kh_out : std_logic := '0';
signal data_sk, data_w, data_kh_in, data_kh_out : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0');
signal ready_de, ready_sk, ready_w, ready_kh_in, ready_kh_out, valid_de, valid_sk, valid_w, valid_kh_in, valid_kh_out, last_word_de, last_word_sk, last_word_w, last_word_kh_in, last_word_kh_out : std_logic := '0';
signal data_de, data_sk, data_w, data_kh_in, data_kh_out : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0');
signal start_w, ack_w, start_kh, ack_kh, decode_error, encode_done : std_logic := '0';
signal opcode_kh : KEY_HOLDER_OPCODE_TYPE := NOP;
shared variable SB_out : osvvm.ScoreBoardPkg_slv.ScoreBoardPType;
shared variable serialized_key : TEST_PACKET_TYPE := EMPTY_TEST_PACKET;
shared variable serialized_key, invalid_data : TEST_PACKET_TYPE := EMPTY_TEST_PACKET;
signal key_hash, key_hash_latch : KEY_HASH_TYPE := KEY_HASH_NIL;
signal send_invalid_data : std_logic := '0';
signal id_in : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0');
signal TestSequence_len_in, TestSequence_addr_in: std_logic_vector(TESTSEQUENCE_ADDR_WIDTH-1 downto 0) := (others => '0');
@ -90,6 +92,10 @@ begin
done_user => open,
return_code_user => open,
instance_handle_out_user => open,
valid_out_user => open,
ready_out_user => '1',
data_out_user => open,
last_word_out_user => open,
status_user => open,
encode_done => encode_done,
id => id_in,
@ -203,15 +209,24 @@ begin
KH := GetAlertLogID("KeyHash", ALERTLOG_BASE_ID);
Log("Initial Reset", INFO);
start_w <= '0';
reset <= '1';
send_invalid_data <= '0';
start_w <= '0';
reset <= '1';
wait until rising_edge(clk);
wait until rising_edge(clk);
reset <= '0';
-- Create Invalid Serialized Payload
for i in 0 to MAX_TYPE2_SIZE loop
invalid_data.data(i) := RV.RandSlv(invalid_data.data(i)'length);
invalid_data.length := invalid_data.length + 1;
end loop;
invalid_data.last(invalid_data.length-1) := '1';
-- Serialized Key Payload Header
gen_CDR(SERIALIZED_KEY_HEADER, ALIGN_4, align_offset, serialized_key);
-- Reset Alignement
write_serialized_payload(SERIALIZED_KEY_HEADER, ALIGN_4, align_offset, serialized_key);
-- Reset Alignment
align_offset := (others => '0');
Log("Setting Data in Writer Side", INFO);
@ -224,10 +239,10 @@ begin
TestUnion_OctetU_in <= RV.RandSlv(TestUnion_OctetU_in'length);
TestBitmask_in <= RV.RandSlv(TestBitmask_in'length);
wait for 0 ns;
gen_CDR(endian_swap('1',id_in), ALIGN_4, align_offset, serialized_key);
write_serialized_payload(endian_swap('1',id_in), ALIGN_4, align_offset, serialized_key);
TestSequence_len_in <= int(2,TestSequence_len_in'length);
gen_CDR(endian_swap('1',int(2,CDR_LONG_WIDTH)), ALIGN_4, align_offset, serialized_key);
write_serialized_payload(endian_swap('1',int(2,CDR_LONG_WIDTH)), ALIGN_4, align_offset, serialized_key);
-- Memory
for i in 0 to 1 loop
TestSequence_addr_in <= int(i,TestSequence_addr_in'length);
@ -243,7 +258,7 @@ begin
TestSequence_TestArray_wen_in <= '1';
wait until rising_edge(clk);
TestSequence_TestArray_wen_in <= '0';
gen_CDR(endian_swap('1',TestSequence_TestArray_w_in), ALIGN_1, align_offset, serialized_key);
write_serialized_payload(endian_swap('1',TestSequence_TestArray_w_in), ALIGN_1, align_offset, serialized_key);
end loop;
wait_on_sig(TestSequence_ready_in);
TestSequence_wen_in <= '1';
@ -279,9 +294,10 @@ begin
push_sk;
Log("Push DATA", INFO);
opcode_kh <= PUSH_DATA;
start_w <= '1';
Log("Push Invalid DATA", INFO);
send_invalid_data <= '1';
opcode_kh <= PUSH_DATA;
start_w <= '1';
wait_on_sig(ack_w);
wait until rising_edge(clk);
start_w <= '0';
@ -293,6 +309,26 @@ begin
wait_on_sig(ready_kh_in);
wait until rising_edge(clk);
Alertif(decode_error /= '1', "Decode error not asserted", ERROR);
send_invalid_data <= '0';
Log("Push DATA", INFO);
opcode_kh <= PUSH_DATA;
start_w <= '1';
wait_on_sig(ack_w);
wait until rising_edge(clk);
start_w <= '0';
start_kh <= '1';
wait_on_sig(ack_kh);
wait until rising_edge(clk);
start_kh <= '0';
wait for 1 ps; -- Wait until signals are stable
Alertif(decode_error /= '0', "Decode error still asserted", ERROR);
wait_on_sig(last_word_kh_in);
wait_on_sig(ready_kh_in);
wait until rising_edge(clk);
Alertif(decode_error = '1', "Decode error asserted", ERROR);
Log("Read and Compare Serialized Key", INFO);
opcode_kh <= READ_SERIALIZED_KEY;
start_kh <= '1';
@ -322,6 +358,7 @@ begin
wait_on_sig(last_word_sk);
wait_on_sig(ready_sk);
wait until rising_edge(clk);
Alertif(decode_error = '1', "Decode error asserted", ERROR);
push_sk;
Log("Read and Compare Serialized Key", INFO);
@ -363,28 +400,29 @@ begin
wait for TEST_CLOCK_PERIOD/2;
end process;
alert_prc : process(all)
begin
if rising_edge(clk) then
Alertif(decode_error = '1', "The Reader signals a DECODE Error", ERROR);
end if;
end process;
switch_prc : process(all)
begin
ready_w <= '0';
ready_de <= '0';
ready_sk <= '0';
case (opcode_kh) is
when PUSH_SERIALIZED_KEY =>
ready_sk <= ready_kh_in;
valid_kh_in <= valid_sk;
data_kh_in <= data_sk;
last_word_kh_in <= last_word_sk;
ready_w <= '0';
when others =>
if (send_invalid_data = '1') then
ready_de <= ready_kh_in;
valid_kh_in <= valid_de;
data_kh_in <= data_de;
last_word_kh_in <= last_word_de;
else
ready_w <= ready_kh_in;
valid_kh_in <= valid_w;
data_kh_in <= data_w;
last_word_kh_in <= last_word_w;
ready_sk <= '0';
end if;
end case;
end process;
@ -408,6 +446,26 @@ begin
end if;
end process;
de_prc : process(all)
variable cnt : natural := 0;
begin
valid_de <= '1';
data_de <= invalid_data.data(cnt);
if (cnt = invalid_data.length-1) then
last_word_de <= '1';
end if;
if rising_edge(clk) then
if (ready_de = '1') then
if (cnt = invalid_data.length-1) then
cnt := 0;
else
cnt := cnt + 1;
end if;
end if;
end if;
end process;
output_check_prc : process(all)
variable cnt : natural range 0 to 3 := 0;
begin

View File

@ -12,11 +12,11 @@ use work.rtps_test_package.all;
-- This testbench tests the rtps output of the Discovery Module (Local Liveliness Assertion, Local Heartbeat Generation, Local Participant Announcement, Remote HEARTBEAT Response, Remote ACKNACK Response).
-- This test is a Level 1 Test (Meaning the input/output is not connected directly to the uut) in order to have output in the same format as the input of the system and allow us to compare using existing data generators.
-- The testflow is as follows:
-- The test flow is as follows:
-- * 0s
-- - Local participant Announcement
-- - Match a remote participant
-- - Send HEARTBEAT 0 (Publisher, Empty, Final Flag) [Test Final Flag pasing]
-- - Send HEARTBEAT 0 (Publisher, Empty, Final Flag) [Test Final Flag passing]
-- * 0.105s
-- - No HEARTBEAT 0 Response
-- - Send HEARTBEAT 1 (Publisher, Empty) [Test empty HEARTBEAT Response]
@ -30,16 +30,16 @@ use work.rtps_test_package.all;
-- - Send HEARTBEAT 3 (Publisher, First SN 1, Last SN 5) [Test HEARTBEAT Suppression Delay]
-- * 0.415s
-- - No HEARTBEAT 3 Response
-- - Send HEARTBEAT 4 (Publisher, First SN 1, Last SN 5) [Test normal HARTBEAT Response]
-- - Send HEARTBEAT 4 (Publisher, First SN 1, Last SN 5) [Test normal HEARTBEAT Response]
-- - Send ACKNACK 2 (Publisher, Expecting 1) [Test ACKNACK Suppression Delay]
-- * 0.450s
-- - Send HEARTBEAT 5 (Subscriber, First Sn 2, Last SN 5) [Test HEARTBEAT Response Delay, Test HEARTBEAT Resposne Update]
-- - Send HEARTBEAT 5 (Subscriber, First Sn 2, Last SN 5) [Test HEARTBEAT Response Delay, Test HEARTBEAT Response Update]
-- * 0.520s
-- - HEARTBEAT 4/5 Response
-- - Send ACKNACK 3 (Publisher, Expecting SN 1) [Test normal ACKNACK Response]
-- * 0.620s
-- - No ACKNACK 2 Response
-- - Send ACKNACK 4 (Subscriber, Expecting SN 1) [Test ACKNACK Resposne Delay, Test ACKNACK Response Update]
-- - Send ACKNACK 4 (Subscriber, Expecting SN 1) [Test ACKNACK Response Delay, Test ACKNACK Response Update]
-- * 0.725s
-- - ACKNACK 3/4 Response
-- * 1.000s
@ -49,14 +49,14 @@ use work.rtps_test_package.all;
-- * 1.205s
-- - ACKNACK 5 Response
-- * 1.500s
-- - Send ACKNACK 6 (Publihser, Expecting SN 18) [Test ACKNACK SN Response]
-- - Send ACKNACK 6 (Publisher, Expecting SN 18) [Test ACKNACK SN Response]
-- * 1.705s
-- - No ACKNACK 6 Response
-- * 2.000s
-- - Local HEARTBEAT generation
-- - Liveliness Assertion (Auto only)
-- - Send ACKNACK 7 (Message, Expecting SN 5) [Test GAP sending on ACKNACK Response]
-- - Send ACKNACK 8 (Publihser, Expecing SN 2) [Test full ACKNACK Response]
-- - Send ACKNACK 8 (Publisher, Expecting SN 2) [Test full ACKNACK Response]
-- - Send ACKNACK 9 (Subscriber, Expecting SN 8) [Test full ACKNACK Response]
-- * 2.205s
-- - ACKNACK 7/8/9 Response

View File

@ -12,7 +12,7 @@ use work.rtps_test_package.all;
-- This testbench tests the output handling (ACKNACK) of the RTPS Reader
-- This test is a Level 1 Test (Meaning the input/output is not connected directly to the uut) in order to have output in the same format as the input of the system and allow us to compare using existing data generators.
-- The testflow is as follows (Heartbeat Suppression and Response delay are configured to 5s):
-- The test flow is as follows (Heartbeat Suppression and Response delay are configured to 5s):
-- * 0s
-- - Match Remote Endpoints 0,1,2
-- - Send HEARTBEAT 0 from Endpoint 0 (Empty, Final Flag) [Test Final Flag Handling]

View File

@ -34,6 +34,10 @@ entity L2_Testbench_Lib2 is
done_user : out std_logic;
return_code_user : out std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
instance_handle_out_user : out INSTANCE_HANDLE_TYPE;
valid_out_user : out std_logic;
ready_out_user : in std_logic;
data_out_user : out std_logic_vector(WORD_WIDTH-1 downto 0);
last_word_out_user : out std_logic;
-- Communication Status
status_user : out std_logic_vector(STATUS_KIND_WIDTH-1 downto 0);
-- ###GENERATED START###
@ -574,6 +578,10 @@ begin
done_user => done_user,
return_code_user => return_code_user,
instance_handle_out_user => instance_handle_out_user,
valid_out_user => valid_out_user,
ready_out_user => ready_out_user,
data_out_user => data_out_user,
last_word_out_user => last_word_out_user,
-- Communication Status
status_user => status_user,
-- ###GENERATED START###

View File

@ -29,16 +29,16 @@ package user_config is
constant NUM_ENDPOINTS : natural := NUM_READERS+NUM_WRITERS;
-- PB Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_PB : natural := 7400;
-- DG Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
-- DG Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_DG : natural := 250;
-- PG Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_PG : natural := 2;
constant PORT_CONFIG_PG : natural := 2;
-- D0 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_D0 : natural := 0;
constant PORT_CONFIG_D0 : natural := 0;
-- D1 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_D1 : natural := 10;
-- D2 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_D2 : natural := 1;
-- D2 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_D2 : natural := 1;
-- D3 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_D3 : natural := 11;
-- MAC Address of underlying network stack (Used to generate GUIDs)
@ -89,7 +89,7 @@ package body user_config is
c.RELIABILITY_QOS := RELIABLE_RELIABILITY_QOS;
c.MAX_SAMPLES := std_logic_vector(to_unsigned(5, CDR_LONG_WIDTH));
c.MAX_INSTANCES := std_logic_vector(to_unsigned(5, CDR_LONG_WIDTH));
c.MAX_PAYLOAD_SIZE := MAX_TYPE1_SIZE + 4; -- (+ PAYLOAD HEADER)
c.MAX_PAYLOAD_SIZE := MAX_TYPE1_SIZE;
ret := (others => c);

View File

@ -36,6 +36,10 @@ entity L2_Testbench_Lib3 is
get_data_user : in std_logic;
done_user : out std_logic;
return_code_user : out std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
valid_out_user : out std_logic;
ready_out_user : in std_logic;
data_out_user : out std_logic_vector(WORD_WIDTH-1 downto 0);
last_word_out_user : out std_logic;
sample_info_user : out SAMPLE_INFO_TYPE;
sample_info_valid_user : out std_logic;
sample_info_ack_user : in std_logic;
@ -585,6 +589,10 @@ begin
get_data_user => get_data_user,
done_user => done_user,
return_code_user => return_code_user,
valid_out_user => valid_out_user,
ready_out_user => ready_out_user,
data_out_user => data_out_user,
last_word_out_user => last_word_out_user,
sample_info_user => sample_info_user,
sample_info_valid_user => sample_info_valid_user,
sample_info_ack_user => sample_info_ack_user,

View File

@ -29,16 +29,16 @@ package user_config is
constant NUM_ENDPOINTS : natural := NUM_READERS+NUM_WRITERS;
-- PB Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_PB : natural := 7400;
-- DG Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
-- DG Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_DG : natural := 250;
-- PG Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_PG : natural := 2;
constant PORT_CONFIG_PG : natural := 2;
-- D0 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_D0 : natural := 0;
constant PORT_CONFIG_D0 : natural := 0;
-- D1 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_D1 : natural := 10;
-- D2 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_D2 : natural := 1;
-- D2 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_D2 : natural := 1;
-- D3 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_D3 : natural := 11;
-- MAC Address of underlying network stack (Used to generate GUIDs)
@ -89,7 +89,7 @@ package body user_config is
c.RELIABILITY_QOS := RELIABLE_RELIABILITY_QOS;
c.MAX_SAMPLES := std_logic_vector(to_unsigned(5, CDR_LONG_WIDTH));
c.MAX_INSTANCES := std_logic_vector(to_unsigned(5, CDR_LONG_WIDTH));
c.MAX_PAYLOAD_SIZE := MAX_TYPE1_SIZE + 4; -- (+ PAYLOAD HEADER)
c.MAX_PAYLOAD_SIZE := MAX_TYPE1_SIZE;
ret := (others => c);

View File

@ -581,6 +581,10 @@ begin
get_data_user => get_data_user_ri,
done_user => done_ri_user,
return_code_user => return_code_ri_user,
valid_out_user => open,
ready_out_user => '1',
data_out_user => open,
last_word_out_user => open,
sample_info_user => sample_info_ri_user,
sample_info_valid_user => sample_info_valid_ri_user,
sample_info_ack_user => sample_info_ack_user_ri,
@ -631,6 +635,10 @@ begin
done_user => done_wi_user,
return_code_user => return_code_wi_user,
instance_handle_out_user => instance_handle_wi_user,
valid_out_user => open,
ready_out_user => '1',
data_out_user => open,
last_word_out_user => open,
-- Communication Status
status_user => status_wi_user,
-- ###GENERATED START###

View File

@ -24,21 +24,21 @@ package user_config is
-- Number of RTPS Writer Endpoints
constant NUM_WRITERS : natural := 1;
-- Number of RTPS Reader Endpoints
constant NUM_READERS : natural := 1;
constant NUM_READERS : natural := 1;
-- Number of RTPS Endpoints (Do not modify)
constant NUM_ENDPOINTS : natural := NUM_READERS+NUM_WRITERS;
-- PB Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_PB : natural := 7400;
-- DG Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
-- DG Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_DG : natural := 250;
-- PG Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_PG : natural := 2;
constant PORT_CONFIG_PG : natural := 2;
-- D0 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_D0 : natural := 0;
constant PORT_CONFIG_D0 : natural := 0;
-- D1 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_D1 : natural := 10;
-- D2 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_D2 : natural := 1;
-- D2 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_D2 : natural := 1;
-- D3 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_D3 : natural := 11;
-- MAC Address of underlying network stack (Used to generate GUIDs)
@ -90,7 +90,7 @@ package body user_config is
c.HISTORY_DEPTH := std_logic_vector(to_unsigned(5, CDR_LONG_WIDTH));
c.MAX_SAMPLES := std_logic_vector(to_unsigned(20, CDR_LONG_WIDTH));
c.MAX_INSTANCES := std_logic_vector(to_unsigned(5, CDR_LONG_WIDTH));
c.MAX_PAYLOAD_SIZE := MAX_TYPE1_SIZE + 4; -- (+ PAYLOAD HEADER)
c.MAX_PAYLOAD_SIZE := MAX_TYPE1_SIZE;
ret := (others => c);

View File

@ -36,6 +36,10 @@ entity L2_Testbench_Lib5 is
get_data_r : in std_logic;
done_r : out std_logic;
return_code_r : out std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
valid_out_r : out std_logic;
ready_out_r : in std_logic;
data_out_r : out std_logic_vector(WORD_WIDTH-1 downto 0);
last_word_out_r : out std_logic;
sample_info_r : out SAMPLE_INFO_TYPE;
sample_info_valid_r : out std_logic;
sample_info_ack_r : in std_logic;
@ -55,6 +59,10 @@ entity L2_Testbench_Lib5 is
done_w : out std_logic;
return_code_w : out std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
instance_handle_out_w : out INSTANCE_HANDLE_TYPE;
valid_out_w : out std_logic;
ready_out_w : in std_logic;
data_out_w : out std_logic_vector(WORD_WIDTH-1 downto 0);
last_word_out_w : out std_logic;
status_w : out std_logic_vector(STATUS_KIND_WIDTH-1 downto 0);
id_w : in std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
a_w : in std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
@ -596,6 +604,10 @@ begin
get_data_user => get_data_r,
done_user => done_r,
return_code_user => return_code_r,
valid_out_user => valid_out_r,
ready_out_user => ready_out_r,
data_out_user => data_out_r,
last_word_out_user => last_word_out_r,
sample_info_user => sample_info_r,
sample_info_valid_user => sample_info_valid_r,
sample_info_ack_user => sample_info_ack_r,
@ -646,6 +658,10 @@ begin
done_user => done_w,
return_code_user => return_code_w,
instance_handle_out_user => instance_handle_out_w,
valid_out_user => valid_out_w,
ready_out_user => ready_out_w,
data_out_user => data_out_w,
last_word_out_user => last_word_out_w,
-- Communication Status
status_user => status_w,
-- ###GENERATED START###

View File

@ -24,21 +24,21 @@ package user_config is
-- Number of RTPS Writer Endpoints
constant NUM_WRITERS : natural := 1;
-- Number of RTPS Reader Endpoints
constant NUM_READERS : natural := 1;
constant NUM_READERS : natural := 1;
-- Number of RTPS Endpoints (Do not modify)
constant NUM_ENDPOINTS : natural := NUM_READERS+NUM_WRITERS;
-- PB Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_PB : natural := 7400;
-- DG Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
-- DG Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_DG : natural := 250;
-- PG Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_PG : natural := 2;
constant PORT_CONFIG_PG : natural := 2;
-- D0 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_D0 : natural := 0;
constant PORT_CONFIG_D0 : natural := 0;
-- D1 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_D1 : natural := 10;
-- D2 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_D2 : natural := 1;
-- D2 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_D2 : natural := 1;
-- D3 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_D3 : natural := 11;
-- MAC Address of underlying network stack (Used to generate GUIDs)
@ -90,7 +90,7 @@ package body user_config is
c.HISTORY_DEPTH := std_logic_vector(to_unsigned(5, CDR_LONG_WIDTH));
c.MAX_SAMPLES := std_logic_vector(to_unsigned(20, CDR_LONG_WIDTH));
c.MAX_INSTANCES := std_logic_vector(to_unsigned(5, CDR_LONG_WIDTH));
c.MAX_PAYLOAD_SIZE := MAX_TYPE1_SIZE + 4; -- (+ PAYLOAD HEADER)
c.MAX_PAYLOAD_SIZE := MAX_TYPE1_SIZE;
ret := (others => c);

View File

@ -14,12 +14,12 @@ use work.rtps_config_package.all;
use work.rtps_test_package.all;
use work.Type1_package.all;
-- This testbench tests the general system operation by interconnecting a complete system with a single writer with a complete sysetm with a single reader.
-- This testbench tests the general system operation by interconnecting a complete system with a single writer with a complete system with a single reader.
-- Libraries are used to allow to use systems with different configurations. Testbench_Lib2 contains a single endpoint writer (Type1), and Testbench_Lib3 contains a single endpoint reader (Type1).
-- Both Libraries have compatible settings for matching.
-- The testbench first registers 2 instances, and writes 2 samples for each instance (once using the instance handle, and onc using HANDLE_NIL). This initial 4 writes are done before
-- the two systems have discovered each other (due to the initial Participant Announcement happening at 50k ns), and are thus considered historical data (Data that will be sent to the
-- Reader immediately on matching due to trasient local durability setting).
-- Reader immediately on matching due to transient local durability setting).
-- After data has arrived on the reader side, the data is read out and compared to the original.
-- Afterwards another sample on an unknown instance is written, and the instance handle is fetched via a register lookup operation. After the sample has arrived at the reader side the data is again
-- compared to the original.
@ -47,7 +47,7 @@ architecture testbench of L2_Type1_test1 is
signal clk, reset : std_logic := '0';
signal time : TIME_TYPE := TIME_ZERO;
-- INPUT
signal start_w, ack_w, done_w, ready_out_w, valid_out_w, last_word_out_w, encode_done_w, empty_rtps_w, full_rtps_w, rd_rtps_w, wr_rtps_w : std_logic := '0';
signal start_w, ack_w, done_w, ready_out_w, ready_out_r, valid_out_w, valid_out_r, last_word_out_w, last_word_out_r, encode_done_w, empty_rtps_w, full_rtps_w, rd_rtps_w, wr_rtps_w : std_logic := '0';
--signal opcode_w : Testbench_Lib2.rtps_config_package.DDS_WRITER_OPCODE_TYPE := Testbench_Lib2.rtps_config_package.DDS_WRITER_OPCODE_TYPE'(NOP);
signal opcode_w : DDS_WRITER_OPCODE_TYPE;
signal instance_handle_in_w : INSTANCE_HANDLE_TYPE := HANDLE_NIL;
@ -55,7 +55,7 @@ architecture testbench of L2_Type1_test1 is
signal source_ts_w : TIME_TYPE := TIME_INVALID;
signal max_wait_w : DURATION_TYPE := DURATION_ZERO;
signal return_code_w : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0) := RETCODE_OK;
signal data_out_w, data_in_rtps_w, data_out_rtps_w : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0');
signal data_out_w, data_out_r, data_in_rtps_w, data_out_rtps_w : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0');
signal status_w : std_logic_vector(STATUS_KIND_WIDTH-1 downto 0) := (others => '0');
signal id_w, a_w : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0');
@ -75,6 +75,8 @@ architecture testbench of L2_Type1_test1 is
signal id1, id2, id3, a1, a2, a3 : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0');
signal inst1, inst2, inst3 : INSTANCE_HANDLE_TYPE := HANDLE_NIL;
signal sample, data_out : AlertLogIDType;
-- HACK: For some reason (possibly Modelsim/Questasim Bug) I cannot declare the opcode signals from their respective Library sources,
-- because I cannot use a qualified expression to define an enumeration literal (and direct type casting cannot be done because
-- the types are not closely related). So I have to do define explicit type conversions between the types...
@ -115,6 +117,10 @@ begin
done_user => done_w,
return_code_user => return_code_w,
instance_handle_out_user => instance_handle_out_w,
valid_out_user => valid_out_w,
ready_out_user => ready_out_w,
data_out_user => data_out_w,
last_word_out_user => last_word_out_w,
-- Communication Status
status_user => status_w,
-- ###GENERATED START###
@ -186,6 +192,10 @@ begin
get_data_user => get_data_r,
done_user => done_r,
return_code_user => return_code_r,
valid_out_user => valid_out_r,
ready_out_user => ready_out_r,
data_out_user => data_out_r,
last_word_out_user => last_word_out_r,
sample_info_user => sample_info_r,
sample_info_valid_user => sample_info_valid_r,
sample_info_ack_user => sample_info_ack_r,
@ -262,6 +272,8 @@ begin
SetLogEnable(PASSED, FALSE);
SetLogEnable(INFO, TRUE);
RV.InitSeed(RV'instance_name);
sample <= GetAlertLogID("DDS Sample", ALERTLOG_BASE_ID);
data_out <= GetAlertLogID("Data Out", ALERTLOG_BASE_ID);
id1 <= RV.RandSlv(CDR_LONG_WIDTH);
id2 <= RV.RandSlv(CDR_LONG_WIDTH);
@ -345,7 +357,7 @@ begin
AlertIf(return_code_w /= RETCODE_OK, "DDS Write Operation Failed", ERROR);
wait until rising_edge(clk);
Log("Write Instance 1 Sample 1 (Historical)", INFO);
Log("Write Instance 2 Sample 2 (Historical)", INFO);
start_w <= '1';
opcode_w <= WRITE;
source_ts_w <= TIME_INVALID;
@ -372,7 +384,7 @@ begin
wait_on_sig(sample_info_valid_r);
wait for 1 ps; -- Make sure all signals stable
AlertIf(sample_info_r.valid_data /= '1', "Reader returned no Data", ERROR);
AffirmIfEqual(to_unsigned(INSTANCE_HANDLE_TYPE(sample_info_r.instance_handle)), to_unsigned(inst1));
AffirmIfEqual(sample, to_unsigned(INSTANCE_HANDLE_TYPE(sample_info_r.instance_handle)), to_unsigned(inst1));
sample_info_ack_r <= '1';
get_data_r <= '1';
wait until rising_edge(clk);
@ -380,8 +392,8 @@ begin
get_data_r <= '0';
wait_on_sig(valid_r);
wait for 1 ps; -- Make sure all signals stable
AffirmIfEqual(id_r, id1);
AffirmIfEqual(a_r, a1);
AffirmIfEqual(sample, id_r, id1);
AffirmIfEqual(sample, a_r, a1);
wait_on_sig(eoc_r);
wait until rising_edge(clk);
@ -390,7 +402,7 @@ begin
wait_on_sig(sample_info_valid_r);
wait for 1 ps; -- Make sure all signals stable
AlertIf(sample_info_r.valid_data /= '1', "Reader returned no Data", ERROR);
AffirmIfEqual(to_unsigned(INSTANCE_HANDLE_TYPE(sample_info_r.instance_handle)), to_unsigned(inst2));
AffirmIfEqual(sample, to_unsigned(INSTANCE_HANDLE_TYPE(sample_info_r.instance_handle)), to_unsigned(inst2));
sample_info_ack_r <= '1';
get_data_r <= '1';
wait until rising_edge(clk);
@ -398,8 +410,8 @@ begin
get_data_r <= '0';
wait_on_sig(valid_r);
wait for 1 ps; -- Make sure all signals stable
AffirmIfEqual(id_r, id2);
AffirmIfEqual(a_r, a1);
AffirmIfEqual(sample, id_r, id2);
AffirmIfEqual(sample, a_r, a1);
wait_on_sig(eoc_r);
wait until rising_edge(clk);
@ -408,7 +420,7 @@ begin
wait_on_sig(sample_info_valid_r);
wait for 1 ps; -- Make sure all signals stable
AlertIf(sample_info_r.valid_data /= '1', "Reader returned no Data", ERROR);
AffirmIfEqual(to_unsigned(INSTANCE_HANDLE_TYPE(sample_info_r.instance_handle)), to_unsigned(inst1));
AffirmIfEqual(sample, to_unsigned(INSTANCE_HANDLE_TYPE(sample_info_r.instance_handle)), to_unsigned(inst1));
sample_info_ack_r <= '1';
get_data_r <= '1';
wait until rising_edge(clk);
@ -416,8 +428,8 @@ begin
get_data_r <= '0';
wait_on_sig(valid_r);
wait for 1 ps; -- Make sure all signals stable
AffirmIfEqual(id_r, id1);
AffirmIfEqual(a_r, a2);
AffirmIfEqual(sample, id_r, id1);
AffirmIfEqual(sample, a_r, a2);
wait_on_sig(eoc_r);
wait until rising_edge(clk);
@ -426,7 +438,7 @@ begin
wait_on_sig(sample_info_valid_r);
wait for 1 ps; -- Make sure all signals stable
AlertIf(sample_info_r.valid_data /= '1', "Reader returned no Data", ERROR);
AffirmIfEqual(to_unsigned(INSTANCE_HANDLE_TYPE(sample_info_r.instance_handle)), to_unsigned(inst2));
AffirmIfEqual(sample, to_unsigned(INSTANCE_HANDLE_TYPE(sample_info_r.instance_handle)), to_unsigned(inst2));
sample_info_ack_r <= '1';
get_data_r <= '1';
wait until rising_edge(clk);
@ -434,8 +446,8 @@ begin
get_data_r <= '0';
wait_on_sig(valid_r);
wait for 1 ps; -- Make sure all signals stable
AffirmIfEqual(id_r, id2);
AffirmIfEqual(a_r, a2);
AffirmIfEqual(sample, id_r, id2);
AffirmIfEqual(sample, a_r, a2);
wait_on_sig(eoc_r);
wait until rising_edge(clk);
@ -475,7 +487,7 @@ begin
wait_on_sig(sample_info_valid_r);
wait for 1 ps; -- Make sure all signals stable
AlertIf(sample_info_r.valid_data /= '1', "Reader returned no Data", ERROR);
AffirmIfEqual(to_unsigned(INSTANCE_HANDLE_TYPE(sample_info_r.instance_handle)), to_unsigned(inst3));
AffirmIfEqual(sample, to_unsigned(INSTANCE_HANDLE_TYPE(sample_info_r.instance_handle)), to_unsigned(inst3));
sample_info_ack_r <= '1';
get_data_r <= '1';
wait until rising_edge(clk);
@ -483,11 +495,29 @@ begin
get_data_r <= '0';
wait_on_sig(valid_r);
wait for 1 ps; -- Make sure all signals stable
AffirmIfEqual(id_r, id3);
AffirmIfEqual(a_r, a3);
AffirmIfEqual(sample, id_r, id3);
AffirmIfEqual(sample, a_r, a3);
wait_on_sig(eoc_r);
wait until rising_edge(clk);
Log("Test non Type Related Writer Operation (GET_OFFERED_DEADLINE_MISSED_STATUS)", INFO);
start_w <= '1';
opcode_w <= GET_OFFERED_DEADLINE_MISSED_STATUS;
wait_on_sig(ack_w);
wait until rising_edge(clk);
start_w <= '0';
wait_on_sig(done_w);
wait_on_sig(last_word_out_w);
Log("Test non Type Related Reader Operation (GET_REQUESTED_DEADLINE_MISSED_STATUS)", INFO);
start_r <= '1';
opcode_r <= GET_REQUESTED_DEADLINE_MISSED_STATUS;
wait_on_sig(ack_r);
wait until rising_edge(clk);
start_r <= '0';
wait_on_sig(done_r);
wait_on_sig(last_word_out_r);
TranscriptOpen(RESULTS_FILE, APPEND_MODE);
SetTranscriptMirror;
ReportAlerts;
@ -496,6 +526,42 @@ begin
wait;
end process;
check_out_w : process(all)
variable cnt : natural := 0;
begin
if rising_edge(clk) then
ready_out_w <= '1';
if (valid_out_w = '1') then
AffirmIfEqual(data_out, data_out_w, (data_out_w'range => '0'));
if (cnt = 5) then
AffirmIfEqual(data_out, last_word_out_w, '1');
cnt := 0;
else
AffirmIfEqual(data_out, last_word_out_w, '0');
cnt := cnt + 1;
end if;
end if;
end if;
end process;
check_out_r : process(all)
variable cnt : natural := 0;
begin
if rising_edge(clk) then
ready_out_r <= '1';
if (valid_out_r = '1') then
AffirmIfEqual(data_out, data_out_r, (data_out_r'range => '0'));
if (cnt = 5) then
AffirmIfEqual(data_out, last_word_out_r, '1');
cnt := 0;
else
AffirmIfEqual(data_out, last_word_out_r, '0');
cnt := cnt + 1;
end if;
end if;
end if;
end process;
clock_prc : process
begin
clk <= '0';

View File

@ -14,11 +14,11 @@ use work.rtps_config_package.all;
use work.rtps_test_package.all;
use work.Type1_package.all;
-- This testbench tests the general system operation by interconnecting two complete systems with a reader and a writer respectively, and perforing a loopback operation.
-- This testbench tests the general system operation by interconnecting two complete systems with a reader and a writer respectively, and performing a loopback operation.
-- Libraries are used to allow to use systems with different configurations.
-- The testbench is interfacing with the readr and writer of Testbench_Lib5, and the loopback entity (test_loopback) is interfacing with the reader and writer of Testbench_Lib4.
-- The testbench is interfacing with the reader and writer of Testbench_Lib5, and the loopback entity (test_loopback) is interfacing with the reader and writer of Testbench_Lib4.
-- The testbench->test_loopback communication uses a Type1 Instance with id=1, and the test_loopback->testbench communication uses a Type1 Instance with id=2.
-- The testbench performs a REGISTER_INSTANCE operation to get the Instance Handle of the response channel. The it sends 5 samples with content 1,2,3,4, and 5, respectively.
-- The testbench performs a REGISTER_INSTANCE operation to get the Instance Handle of the response channel. Then it sends 5 samples with content 1,2,3,4, and 5, respectively.
-- The test_loopback reads these Samples and responds with a x+1000 calculation on the Sample Contents (i.e. 1001,1002,1003,1004,1005).
-- The testbench reads only Samples with the correct instance and checks for the expected content.
@ -169,6 +169,10 @@ begin
get_data_r => get_data_r,
done_r => done_r,
return_code_r => return_code_r,
valid_out_r => open,
ready_out_r => '1',
data_out_r => open,
last_word_out_r => open,
sample_info_r => sample_info_r,
sample_info_valid_r => sample_info_valid_r,
sample_info_ack_r => sample_info_ack_r,
@ -188,6 +192,10 @@ begin
done_w => done_w,
return_code_w => return_code_w,
instance_handle_out_w => instance_handle_out_w,
valid_out_w => open,
ready_out_w => '1',
data_out_w => open,
last_word_out_w => open,
status_w => status_w,
id_w => id_w,
a_w => a_w,
@ -236,7 +244,7 @@ begin
wait until rising_edge(clk);
reset <= '0';
Log("Register Target Instance (Get Instance Handle of Responce)", INFO);
Log("Register Target Instance (Get Instance Handle of Response)", INFO);
start_w <= '1';
opcode_w <= REGISTER_INSTANCE;
id_w <= int(2,CDR_LONG_WIDTH);

View File

@ -131,7 +131,7 @@ begin
-- ###GENERATED END###
-- Last Word Latch Setter
if (last_word_in = '1') then
if (last_word_in = '1' and valid_in = '1') then
last_word_in_latch_next <= '1';
end if;
@ -146,12 +146,14 @@ begin
ack <= '1';
stage_next <= GET_PAYLOAD_HEADER;
-- Reset
key_hash_next <= KEY_HASH_NIL;
key_hash_next <= KEY_HASH_NIL;
decode_error_latch_next <= '0';
when PUSH_SERIALIZED_KEY =>
ack <= '1';
stage_next <= GET_PAYLOAD_HEADER;
-- Reset
key_hash_next <= KEY_HASH_NIL;
key_hash_next <= KEY_HASH_NIL;
decode_error_latch_next <= '0';
when READ_KEY_HASH =>
ack <= '1';
-- Key Hash not calculated
@ -194,7 +196,7 @@ begin
when CDR_BE =>
endian_flag_next <= '0';
stage_next <= FETCH;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
if (opcode_latch = PUSH_DATA) then
-- ###GENERATED START###
@ -209,7 +211,7 @@ begin
when CDR_LE =>
endian_flag_next <= '1';
stage_next <= FETCH;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
if (opcode_latch = PUSH_DATA) then
-- ###GENERATED START###
@ -296,7 +298,7 @@ begin
stage_next <= FETCH;
decode_stage_next <= return_stage;
cnt_next <= 0;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- Optional omitted
@ -306,7 +308,7 @@ begin
optional_next <= '1';
end if;
end if;
-- eMemberHeader
-- eMemberHeader
when 1 =>
-- Ignore Parameter ID
cnt_next <= cnt + 1;
@ -316,7 +318,7 @@ begin
stage_next <= FETCH;
decode_stage_next <= return_stage;
cnt_next <= 0;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- Optional omitted
@ -342,7 +344,7 @@ begin
-- Output Guard
if (ready_out = '1') then
stage_next <= ENCODE_PAYLOAD;
-- Reset
-- Reset
align_offset_next <= (others => '0');
data_out_latch_next <= (others => '0');
-- ###GENERATED START###

View File

@ -7,12 +7,9 @@ use work.rtps_package.all;
package Type1_package is
constant MAX_ID_SIZE : natural := 4;
constant MAX_A_SIZE : natural := 4; -- 8
constant MAX_TYPE1_SIZE : natural := 8;
constant MAX_TYPE1_KEY_HOLDER_SIZE : natural := 4;
constant MAX_TYPE1_SIZE : natural := 8 + RTPS_PAYLOAD_HEADER_SIZE;
end package;

View File

@ -26,11 +26,10 @@ entity Type1_reader_interface is
get_data_dds : out std_logic;
done_dds : in std_logic;
return_code_dds : in std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
ready_in_dds : out std_logic;
valid_in_dds : in std_logic;
ready_in_dds : out std_logic;
data_in_dds : in std_logic_vector(WORD_WIDTH-1 downto 0);
last_word_in_dds : in std_logic;
-- Sample Info
sample_info_dds : in SAMPLE_INFO_TYPE;
sample_info_valid_dds : in std_logic;
sample_info_ack_dds : out std_logic;
@ -50,6 +49,10 @@ entity Type1_reader_interface is
get_data_user : in std_logic;
done_user : out std_logic;
return_code_user : out std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
valid_out_user : out std_logic;
ready_out_user : in std_logic;
data_out_user : out std_logic_vector(WORD_WIDTH-1 downto 0);
last_word_out_user : out std_logic;
-- Sample Info
sample_info_user : out SAMPLE_INFO_TYPE;
sample_info_valid_user : out std_logic;
@ -138,7 +141,7 @@ begin
begin
-- DEFAULT
stage_next <= stage;
decode_stage_next <= decode_stage;
decode_stage_next <= decode_stage;
return_stage_next <= return_stage;
cnt_next <= cnt;
endian_flag_next <= endian_flag;
@ -158,7 +161,7 @@ begin
-- ###GENERATED END###
-- Last Word Latch Setter
if (last_word_in_dds = '1') then
if (last_word_in_dds = '1' and valid_in_dds = '1') then
last_word_in_latch_next <= '1';
end if;
@ -172,7 +175,10 @@ begin
valid_latch_next <= '0';
abort_mem <= '1';
else
null;
valid_out_user <= valid_in_dds;
ready_in_dds_sig <= ready_out_user;
data_out_user <= data_in_dds;
last_word_out_user <= last_word_in_dds;
end if;
when GET_PAYLOAD_HEADER =>
-- TODO: Latch Offset from Options Field?
@ -184,7 +190,7 @@ begin
when CDR_BE =>
endian_flag_next <= '0';
stage_next <= FETCH;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- ###GENERATED START###
decode_stage_next <= GET_ID;
@ -193,7 +199,7 @@ begin
when CDR_LE =>
endian_flag_next <= '1';
stage_next <= FETCH;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- ###GENERATED START###
decode_stage_next <= GET_ID;
@ -231,21 +237,6 @@ begin
stage_next <= FETCH;
end if;
end if;
when SKIP_PAYLOAD =>
if (last_word_in_latch = '0') then
-- Skip Read
ready_in_dds_sig <= '1';
else
stage_next <= IDLE;
-- If no Decode Error, mark output as valid
if (decode_error_latch = '0') then
valid_latch_next <= '1';
end if;
-- Reset
last_word_in_latch_next <= '0';
end if;
when DECODE_PAYLOAD =>
case (decode_stage) is
-- ###GENERATED START###
@ -291,7 +282,7 @@ begin
stage_next <= FETCH;
decode_stage_next <= return_stage;
cnt_next <= 0;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- Optional omitted
@ -301,7 +292,7 @@ begin
optional_next <= '1';
end if;
end if;
-- eMemberHeader
-- eMemberHeader
when 1 =>
-- Ignore Parameter ID
cnt_next <= cnt + 1;
@ -309,9 +300,9 @@ begin
-- Llength
when 2 =>
stage_next <= FETCH;
decode_stage_next <= return_stage;
decode_stage_next <= return_stage;
cnt_next <= 0;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- Optional omitted
@ -327,6 +318,21 @@ begin
when others =>
null;
end case;
when SKIP_PAYLOAD =>
if (last_word_in_latch = '0') then
-- Skip Read
ready_in_dds_sig <= '1';
else
stage_next <= IDLE;
-- If no Decode Error, mark output as valid
if (decode_error_latch = '0') then
valid_latch_next <= '1';
end if;
-- Reset
last_word_in_latch_next <= '0';
end if;
when others =>
null;
end case;

View File

@ -15,48 +15,52 @@ entity Type1_writer_interface is
);
port (
-- SYSTEM
clk : in std_logic;
reset : in std_logic;
clk : in std_logic;
reset : in std_logic;
-- FROM DDS WRITER
start_dds : out std_logic;
ack_dds : in std_logic;
opcode_dds : out DDS_WRITER_OPCODE_TYPE;
instance_handle_in_dds : out INSTANCE_HANDLE_TYPE;
source_ts_dds : out TIME_TYPE;
max_wait_dds : out DURATION_TYPE;
done_dds : in std_logic;
return_code_dds : in std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
instance_handle_out_dds : in INSTANCE_HANDLE_TYPE;
ready_out_dds : in std_logic;
valid_out_dds : out std_logic;
data_out_dds : out std_logic_vector(WORD_WIDTH-1 downto 0);
last_word_out_dds : out std_logic;
ready_in_dds : out std_logic;
valid_in_dds : in std_logic;
data_in_dds : in std_logic_vector(WORD_WIDTH-1 downto 0);
last_word_in_dds : in std_logic;
start_dds : out std_logic;
ack_dds : in std_logic;
opcode_dds : out DDS_WRITER_OPCODE_TYPE;
instance_handle_in_dds : out INSTANCE_HANDLE_TYPE;
source_ts_dds : out TIME_TYPE;
max_wait_dds : out DURATION_TYPE;
done_dds : in std_logic;
return_code_dds : in std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
instance_handle_out_dds : in INSTANCE_HANDLE_TYPE;
valid_out_dds : out std_logic;
ready_out_dds : in std_logic;
data_out_dds : out std_logic_vector(WORD_WIDTH-1 downto 0);
last_word_out_dds : out std_logic;
valid_in_dds : in std_logic;
ready_in_dds : out std_logic;
data_in_dds : in std_logic_vector(WORD_WIDTH-1 downto 0);
last_word_in_dds : in std_logic;
-- Communication Status
status_dds : in std_logic_vector(STATUS_KIND_WIDTH-1 downto 0);
status_dds : in std_logic_vector(STATUS_KIND_WIDTH-1 downto 0);
-- TO USER ENTITY
start_user : in std_logic;
ack_user : out std_logic;
opcode_user : in DDS_WRITER_OPCODE_TYPE;
instance_handle_in_user : in INSTANCE_HANDLE_TYPE;
source_ts_user : in TIME_TYPE;
max_wait_user : in DURATION_TYPE;
done_user : out std_logic;
return_code_user : out std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
instance_handle_out_user : out INSTANCE_HANDLE_TYPE;
start_user : in std_logic;
ack_user : out std_logic;
opcode_user : in DDS_WRITER_OPCODE_TYPE;
instance_handle_in_user : in INSTANCE_HANDLE_TYPE;
source_ts_user : in TIME_TYPE;
max_wait_user : in DURATION_TYPE;
done_user : out std_logic;
return_code_user : out std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
instance_handle_out_user : out INSTANCE_HANDLE_TYPE;
valid_out_user : out std_logic;
ready_out_user : in std_logic;
data_out_user : out std_logic_vector(WORD_WIDTH-1 downto 0);
last_word_out_user : out std_logic;
-- Communication Status
status_user : out std_logic_vector(STATUS_KIND_WIDTH-1 downto 0);
status_user : out std_logic_vector(STATUS_KIND_WIDTH-1 downto 0);
-- ###GENERATED START###
id : in std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
a : in std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
-- ###GENERATED END###
encode_done : out std_logic
encode_done : out std_logic
);
end entity;
@ -95,6 +99,10 @@ begin
return_code_user <= return_code_dds;
instance_handle_out_user <= instance_handle_out_dds;
status_user <= status_dds;
valid_out_user <= valid_in_dds;
ready_in_dds <= ready_out_user;
data_out_user <= data_in_dds;
last_word_out_user <= last_word_in_dds;
main_prc : process (all)
begin
@ -109,7 +117,6 @@ begin
finalize_payload_next <= finalize_payload;
abort_mem <= '0';
encode_done <= '0';
ready_in_dds <= '0';
valid_out_dds <= '0';
last_word_out_dds <= '0';
data_out_dds <= (others => '0');
@ -155,7 +162,7 @@ begin
-- Output Guard
if (ready_out_dds = '1') then
stage_next <= ENCODE_PAYLOAD;
-- Reset
-- Reset
align_offset_next <= (others => '0');
data_out_latch_next <= (others => '0');
-- ###GENERATED START###

View File

@ -43,7 +43,7 @@ struct Type2 {
TestMap_t TestMap;
TestEnum_t TestEnum;
@optional TestUnion_t TestUnion;
TestBitmask_t TestBitmask
TestBitmask_t TestBitmask;
TestString_t TestString;
};
@ -58,4 +58,4 @@ typedef sequence<NestedStruct_tKeyHolder, 4> TestSequence_tKeyHolder;
struct Type2KeyHolder {
long id;
TestSequence_tKeyHolder TestSequence;
};
};

View File

@ -173,7 +173,7 @@ begin
-- ###GENERATED END###
-- Last Word Latch Setter
if (last_word_in = '1') then
if (last_word_in = '1' and valid_in = '1') then
last_word_in_latch_next <= '1';
end if;
@ -188,12 +188,14 @@ begin
ack <= '1';
stage_next <= GET_PAYLOAD_HEADER;
-- Reset
key_hash_next <= KEY_HASH_NIL;
key_hash_next <= KEY_HASH_NIL;
decode_error_latch_next <= '0';
when PUSH_SERIALIZED_KEY =>
ack <= '1';
stage_next <= GET_PAYLOAD_HEADER;
-- Reset
key_hash_next <= KEY_HASH_NIL;
key_hash_next <= KEY_HASH_NIL;
decode_error_latch_next <= '0';
when READ_KEY_HASH =>
ack <= '1';
-- Key Hash not calculated
@ -236,7 +238,7 @@ begin
when CDR_BE =>
endian_flag_next <= '0';
stage_next <= FETCH;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
if (opcode_latch = PUSH_DATA) then
-- ###GENERATED START###
@ -251,7 +253,7 @@ begin
when CDR_LE =>
endian_flag_next <= '1';
stage_next <= FETCH;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
if (opcode_latch = PUSH_DATA) then
-- ###GENERATED START###
@ -352,7 +354,7 @@ begin
if (not check_align(align_offset, ALIGN_1)) then
target_align_next <= ALIGN_1;
stage_next <= ALIGN_IN_STREAM;
else
else
TestSequence_TestArray_mem_addr(TestSequence_cnt) <= std_logic_vector(to_unsigned(TestSequence_TestArray_cnt,TESTSEQUENCE_TESTARRAY_ADDR_WIDTH));
TestSequence_TestArray_mem_data_in(TestSequence_cnt) <= endian_swap(endian_flag, get_sub_vector(data_in_latch, to_integer(align_offset(1 downto 0)), CDR_OCTET_WIDTH, TRUE));
TestSequence_TestArray_mem_valid_in(TestSequence_cnt) <= '1';
@ -363,7 +365,7 @@ begin
-- All Elements processed
if (TestSequence_TestArray_cnt = TESTSEQUENCE_TESTARRAY_MAX_DEPTH-1) then
-- DES: The decoding stages are used for both PUSH_DATA and PUSH_SERIALIZED_KEY.
-- We us the latched opcode to differentiate between them.
-- We use the latched opcode to differentiate between them.
if (opcode_latch = PUSH_SERIALIZED_KEY) then
-- All Elements processed
if (TestSequence_cnt = TestSequence_len_latch-1) then
@ -512,7 +514,7 @@ begin
stage_next <= FETCH;
decode_stage_next <= return_stage;
cnt_next <= 0;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- Optional omitted
@ -522,7 +524,7 @@ begin
optional_next <= '1';
end if;
end if;
-- eMemberHeader
-- eMemberHeader
when 1 =>
-- Ignore Parameter ID
cnt_next <= cnt + 1;
@ -532,7 +534,7 @@ begin
stage_next <= FETCH;
decode_stage_next <= return_stage;
cnt_next <= 0;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- Optional omitted
@ -558,7 +560,7 @@ begin
-- Output Guard
if (ready_out = '1') then
stage_next <= ENCODE_PAYLOAD;
-- Reset
-- Reset
align_offset_next <= (others => '0');
data_out_latch_next <= (others => '0');
-- ###GENERATED START###
@ -683,7 +685,7 @@ begin
if (not check_align(align_offset, ALIGN_1)) then
target_align_next <= ALIGN_1;
stage_next <= ALIGN_OUT_STREAM;
else
else
case (cnt) is
-- GET
when 0 =>
@ -726,7 +728,7 @@ begin
stage_next <= PUSH;
end if;
end if;
when others =>
when others =>
end case;
end if;
-- ###GENERATED END###
@ -853,4 +855,4 @@ begin
end if;
end process;
end architecture;
end architecture;

View File

@ -45,8 +45,7 @@ package Type2_package is
constant MAX_TESTUNION_SIZE : natural := 7; -- 180
constant MAX_TESTBITMASK_SIZE : natural := 4; -- 184
constant MAX_TESTSTRING_SIZE : natural := 17; -- 201
constant MAX_TYPE2_SIZE : natural := 201;
constant MAX_TYPE2_KEY_HOLDER_SIZE : natural := 28;
constant MAX_TYPE2_SIZE : natural := 201 + RTPS_PAYLOAD_HEADER_SIZE;
end package;

View File

@ -26,11 +26,10 @@ entity Type2_reader_interface is
get_data_dds : out std_logic;
done_dds : in std_logic;
return_code_dds : in std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
ready_in_dds : out std_logic;
valid_in_dds : in std_logic;
ready_in_dds : out std_logic;
data_in_dds : in std_logic_vector(WORD_WIDTH-1 downto 0);
last_word_in_dds : in std_logic;
-- Sample Info
sample_info_dds : in SAMPLE_INFO_TYPE;
sample_info_valid_dds : in std_logic;
sample_info_ack_dds : out std_logic;
@ -50,6 +49,10 @@ entity Type2_reader_interface is
get_data_user : in std_logic;
done_user : out std_logic;
return_code_user : out std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
valid_out_user : out std_logic;
ready_out_user : in std_logic;
data_out_user : out std_logic_vector(WORD_WIDTH-1 downto 0);
last_word_out_user : out std_logic;
-- Sample Info
sample_info_user : out SAMPLE_INFO_TYPE;
sample_info_valid_user : out std_logic;
@ -487,7 +490,7 @@ begin
-- ###GENERATED END###
-- Last Word Latch Setter
if (last_word_in_dds = '1') then
if (last_word_in_dds = '1' and valid_in_dds = '1') then
last_word_in_latch_next <= '1';
end if;
@ -501,6 +504,10 @@ begin
valid_latch_next <= '0';
abort_mem <= '1';
else
valid_out_user <= valid_in_dds;
ready_in_dds_sig <= ready_out_user;
data_out_user <= data_in_dds;
last_word_out_user <= last_word_in_dds;
-- ###GENERATED START###
TestSequence_ready <= TestSequence_TestChar_mem_ready_in and TestSequence_TestWChar_mem_ready_in and TestSequence_TestLongLong_mem_ready_in and TestSequence_TestLongDouble_mem_ready_in;
TestSequence_TestChar_mem_addr <= TestSequence_addr;
@ -550,7 +557,7 @@ begin
when CDR_BE =>
endian_flag_next <= '0';
stage_next <= FETCH;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- ###GENERATED START###
decode_stage_next <= GET_ID;
@ -559,7 +566,7 @@ begin
when CDR_LE =>
endian_flag_next <= '1';
stage_next <= FETCH;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- ###GENERATED START###
decode_stage_next <= GET_ID;
@ -597,21 +604,6 @@ begin
stage_next <= FETCH;
end if;
end if;
when SKIP_PAYLOAD =>
if (last_word_in_latch = '0') then
-- Skip Read
ready_in_dds_sig <= '1';
else
stage_next <= IDLE;
-- If no Decode Error, mark output as valid
if (decode_error_latch = '0') then
valid_latch_next <= '1';
end if;
-- Reset
last_word_in_latch_next <= '0';
end if;
when DECODE_PAYLOAD =>
case (decode_stage) is
-- ###GENERATED START###
@ -658,7 +650,7 @@ begin
if (not check_align(align_offset, ALIGN_1)) then
target_align_next <= ALIGN_1;
stage_next <= ALIGN_STREAM;
else
else
TestSequence_TestArray_mem_addr(TestSequence_cnt) <= std_logic_vector(to_unsigned(TestSequence_TestArray_cnt,TESTSEQUENCE_TESTARRAY_ADDR_WIDTH));
TestSequence_TestArray_mem_data_in(TestSequence_cnt) <= endian_swap(endian_flag, get_sub_vector(data_in_latch, to_integer(align_offset(1 downto 0)), CDR_OCTET_WIDTH, TRUE));
TestSequence_TestArray_mem_valid_in(TestSequence_cnt) <= '1';
@ -918,7 +910,7 @@ begin
if(align_offset(1 downto 0) = "11") then
stage_next <= FETCH;
end if;
end if;
end if;
when GET_TESTUNION_D =>
-- Optional Omitted
if (optional = '0') then
@ -1019,7 +1011,7 @@ begin
if (not check_align(align_offset, ALIGN_1)) then
target_align_next <= ALIGN_1;
stage_next <= ALIGN_STREAM;
else
else
TestString_mem_addr <= std_logic_vector(to_unsigned(TestString_cnt,TESTSTRING_ADDR_WIDTH));
TestString_mem_data_in <= endian_swap(endian_flag, get_sub_vector(data_in_latch, to_integer(align_offset(1 downto 0)), CDR_CHAR_WIDTH, TRUE));
TestString_mem_valid_in <= '1';
@ -1059,7 +1051,7 @@ begin
stage_next <= FETCH;
decode_stage_next <= return_stage;
cnt_next <= 0;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- Optional omitted
@ -1069,7 +1061,7 @@ begin
optional_next <= '1';
end if;
end if;
-- eMemberHeader
-- eMemberHeader
when 1 =>
-- Ignore Parameter ID
cnt_next <= cnt + 1;
@ -1079,7 +1071,7 @@ begin
stage_next <= FETCH;
decode_stage_next <= return_stage;
cnt_next <= 0;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- Optional omitted
@ -1095,6 +1087,21 @@ begin
when others =>
null;
end case;
when SKIP_PAYLOAD =>
if (last_word_in_latch = '0') then
-- Skip Read
ready_in_dds_sig <= '1';
else
stage_next <= IDLE;
-- If no Decode Error, mark output as valid
if (decode_error_latch = '0') then
valid_latch_next <= '1';
end if;
-- Reset
last_word_in_latch_next <= '0';
end if;
when others =>
null;
end case;

View File

@ -15,41 +15,45 @@ entity Type2_writer_interface is
);
port (
-- SYSTEM
clk : in std_logic;
reset : in std_logic;
clk : in std_logic;
reset : in std_logic;
-- FROM DDS WRITER
start_dds : out std_logic;
ack_dds : in std_logic;
opcode_dds : out DDS_WRITER_OPCODE_TYPE;
instance_handle_in_dds : out INSTANCE_HANDLE_TYPE;
source_ts_dds : out TIME_TYPE;
max_wait_dds : out DURATION_TYPE;
done_dds : in std_logic;
return_code_dds : in std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
instance_handle_out_dds : in INSTANCE_HANDLE_TYPE;
ready_out_dds : in std_logic;
valid_out_dds : out std_logic;
data_out_dds : out std_logic_vector(WORD_WIDTH-1 downto 0);
last_word_out_dds : out std_logic;
ready_in_dds : out std_logic;
valid_in_dds : in std_logic;
data_in_dds : in std_logic_vector(WORD_WIDTH-1 downto 0);
last_word_in_dds : in std_logic;
start_dds : out std_logic;
ack_dds : in std_logic;
opcode_dds : out DDS_WRITER_OPCODE_TYPE;
instance_handle_in_dds : out INSTANCE_HANDLE_TYPE;
source_ts_dds : out TIME_TYPE;
max_wait_dds : out DURATION_TYPE;
done_dds : in std_logic;
return_code_dds : in std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
instance_handle_out_dds : in INSTANCE_HANDLE_TYPE;
valid_out_dds : out std_logic;
ready_out_dds : in std_logic;
data_out_dds : out std_logic_vector(WORD_WIDTH-1 downto 0);
last_word_out_dds : out std_logic;
valid_in_dds : in std_logic;
ready_in_dds : out std_logic;
data_in_dds : in std_logic_vector(WORD_WIDTH-1 downto 0);
last_word_in_dds : in std_logic;
-- Communication Status
status_dds : in std_logic_vector(STATUS_KIND_WIDTH-1 downto 0);
status_dds : in std_logic_vector(STATUS_KIND_WIDTH-1 downto 0);
-- TO USER ENTITY
start_user : in std_logic;
ack_user : out std_logic;
opcode_user : in DDS_WRITER_OPCODE_TYPE;
instance_handle_in_user : in INSTANCE_HANDLE_TYPE;
source_ts_user : in TIME_TYPE;
max_wait_user : in DURATION_TYPE;
done_user : out std_logic;
return_code_user : out std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
instance_handle_out_user : out INSTANCE_HANDLE_TYPE;
start_user : in std_logic;
ack_user : out std_logic;
opcode_user : in DDS_WRITER_OPCODE_TYPE;
instance_handle_in_user : in INSTANCE_HANDLE_TYPE;
source_ts_user : in TIME_TYPE;
max_wait_user : in DURATION_TYPE;
done_user : out std_logic;
return_code_user : out std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
instance_handle_out_user : out INSTANCE_HANDLE_TYPE;
valid_out_user : out std_logic;
ready_out_user : in std_logic;
data_out_user : out std_logic_vector(WORD_WIDTH-1 downto 0);
last_word_out_user : out std_logic;
-- Communication Status
status_user : out std_logic_vector(STATUS_KIND_WIDTH-1 downto 0);
status_user : out std_logic_vector(STATUS_KIND_WIDTH-1 downto 0);
-- ###GENERATED START###
id : in std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
@ -106,7 +110,7 @@ entity Type2_writer_interface is
TestString_w : in std_logic_vector(CDR_CHAR_WIDTH-1 downto 0);
-- ###GENERATED END###
encode_done : out std_logic
encode_done : out std_logic
);
end entity;
@ -350,6 +354,10 @@ begin
return_code_user <= return_code_dds;
instance_handle_out_user <= instance_handle_out_dds;
status_user <= status_dds;
valid_out_user <= valid_in_dds;
ready_in_dds <= ready_out_user;
data_out_user <= data_in_dds;
last_word_out_user <= last_word_in_dds;
-- ###GENERATED START###
TestSequence_valid <= TestSequence_TestChar_mem_valid_out and TestSequence_TestWChar_mem_valid_out and TestSequence_TestLongLong_mem_valid_out and TestSequence_TestLongDouble_mem_valid_out;
@ -388,7 +396,6 @@ begin
finalize_payload_next <= finalize_payload;
abort_mem <= '0';
encode_done <= '0';
ready_in_dds <= '0';
valid_out_dds <= '0';
last_word_out_dds <= '0';
data_out_dds <= (others => '0');
@ -787,7 +794,7 @@ begin
TestSequence_TestArray_cnt_next <= 0;
cnt_next <= 0;
end if;
-- "Comsume" input word
-- "Consume" input word
TestSequence_TestLongDouble_mem_ready_out <= '1';
end if;
-- Reset Alignment

View File

@ -9,7 +9,7 @@ architecture test of key_holder is
--*****TYPE DECLARATION*****
-- FSM states. Explained below in detail
type STAGE_TYPE is (IDLE,SKIP_PAYLOAD,GET_KEY_HASH,PUSH_KEY_HASH);
type STAGE_TYPE is (IDLE,SKIP_PAYLOAD,GET_KEY_HASH,PUSH_KEY_HASH,PUSH_SERIALIZED_KEY);
-- ###GENERATED END###
-- *MAIN PROCESS*
@ -54,7 +54,7 @@ begin
cnt_next <= 0;
when READ_SERIALIZED_KEY =>
ack <= '1';
stage_next <= PUSH_KEY_HASH;
stage_next <= PUSH_SERIALIZED_KEY;
cnt_next <= 0;
when others =>
null;
@ -123,6 +123,45 @@ begin
when others =>
null;
end case;
when PUSH_SERIALIZED_KEY =>
case (cnt) is
-- Key Hash 1/4
when 0 =>
data_out <= not key_hash(0);
valid_out <= '1';
-- Output Guard
if (ready_out = '1') then
cnt_next <= cnt + 1;
end if;
-- Key Hash 2/4
when 1 =>
data_out <= not key_hash(1);
valid_out <= '1';
-- Output Guard
if (ready_out = '1') then
cnt_next <= cnt + 1;
end if;
-- Key Hash 3/4
when 2 =>
data_out <= not key_hash(2);
valid_out <= '1';
-- Output Guard
if (ready_out = '1') then
cnt_next <= cnt + 1;
end if;
-- Key Hash 4/4
when 3 =>
data_out <= not key_hash(3);
valid_out <= '1';
last_word_out <= '1';
-- Output Guard
if (ready_out = '1') then
-- DONE
stage_next <= IDLE;
end if;
when others =>
null;
end case;
when others =>
null;
end case;

View File

@ -162,6 +162,8 @@ analyze FWFT_FIFO_cfg.vhd
analyze ../vector_FIFO.vhd
analyze ../mem_ctrl.vhd
analyze ../dp_mem_ctrl.vhd
analyze ../moving_average.vhd
analyze ../moving_average_wrapper.vhd
analyze ../rtps_handler.vhd
analyze ../rtps_discovery_module.vhd
analyze ../rtps_out.vhd
@ -183,6 +185,7 @@ analyze Type2_key_holder.vhd
analyze test_key_holder.vhd
analyze ScoreBoard_test_memory.vhd
analyze ScoreBoard_discovery_module.vhd
analyze Level_0/L0_moving_average_wrapper_test1.vhd
analyze Level_0/L0_rtps_handler_test1.vhd
analyze Level_0/L0_rtps_handler_test2.vhd
analyze Level_0/L0_rtps_discovery_module_test1_uc.vhd
@ -228,7 +231,7 @@ analyze Level_2/L2_Type1_test1.vhd
analyze Level_2/L2_Type1_test2.vhd
analyze test_cfg.vhd
simulate L0_moving_average_wrapper_test1
simulate L0_rtps_handler_test1
simulate L0_rtps_handler_test2
simulate L0_rtps_out_test1

View File

@ -13,7 +13,7 @@ use UNIMACRO.vcomponents.all;
-- Add/Sub
-- This entity adds or subtracts inputs 'A' and 'B', depending on 'mode' (1 = add, 0 = sub).
-- If 'cap' is high, on Overfolw/Underflow conditions the result is capped at max/min value.
-- If 'cap' is high, on Overflow/Underflow conditions the result is capped at max/min value.
entity addsub is
generic (

View File

@ -10,6 +10,295 @@ use work.rtps_package.all;
use work.user_config.all;
use work.rtps_config_package.all;
-- DDS READER
-- This Entity is implementing the DDS reader endpoints.
-- The entity represents multiple reader endpoints (configurable via the NUM_READERS generic).
-- In terms of the RTPS/DDS interaction structure, the HistoryCache (which is the communication point of both the RTPS
-- and DDS endpoints) is integrated into the DDS endpoints, because the DDS endpoints need to perform modifying memory
-- operations, and storing everything twice is a waste of resources.
-- This entity has 3 memories: an instance memory, a sample memory, and a payload memory.
-- The instance memory contains instances (samples with the same key and topic form an instance) of received samples.
-- The sample memory contains the sample(CacheChange) "meta" data, and the payload memory contains the respective data
-- of the samples (if available).
-- This entity receives operations from both the RTPS endpoint, and the downstream user endpoints using a start/done
-- schema.
-- The allowed RTPS operations are ADD_CACHE_CHANGE, and REMOVE_WRITER. See below for the data input formats.
-- If the data of the ADD_CACHE_CHANGE does not include a Key Hash it has to be calculated manually. For this reason
-- a KEY HOLDER is instantiated for each reader, which is fed the payload/serialized key and calculates the Key Hash.
-- Because this has to be done before we can make an ACCEPT/REJECT decision for the sample, the sample and its possible
-- associated payload has to be temporarily buffered. This is solved by extending both the sample memory and payload
-- memory by one slot, that is not counted towards the RESOURCE_LIMITS QoS.
-- If the Key Hash of the ADD_CACHE_CHANGE is of an unknown instance, a new instance is added in the instance memory.
-- The instance is added in numerical Key Hash order to the instance memory, in order to support some specific DDS
-- operations (see READ_NEXT_INSTANCE and TAKE_NEXT_INSTANCE below).
-- If the instance memory is full, the first stale instance is removed to make space for the new instance. An instance
-- is stale if the sample memory has no samples associated with the instance, and no writer is currently associated
-- with the instance (REMOVE_WRITER was called for all writers known to write this instance). If no stale instance is
-- available, the ADD_CACHE_CHANGE operation is rejected.
-- CacheChanges are inserted into the Sample memory in receive order (ADD_CACHE_CHANGE order), except if the
-- DESTINATION_ORDER QoS is set to BY_SOURCE_TIMESTAMP, in which case they are inserted based on their timestamp.
-- Note that in the case of BY_SOURCE_TIMESTAMP DESTINATION_ORDER QoS, no CacheChange with a timestamp earlier than the
-- last read sample is accepted.
-- Even though the meta-information stored in the sample memory is always the same size, the same can not be said for the
-- payload, which can have (depending on the associated IDL type) a more dynamic size. Despite that, the payload memory
-- also works with fixed-size slots. If a payload is bigger it just occupies multiple linked memory slots. If the end
-- of the payload is not aligned with the end of the memory slot (which is always known due to the fixed-size nature), the
-- end address of the payload is stored in the end of the memory slot. This dynamic nature of the payload arises the
-- situation, that during an ADD_CACHE_CHANGE operation a sample memory slot is available, but all payload memory slots
-- are occupied. In this situation (depending on the configured QoS) either the operation is directly rejected, or the
-- oldest sample is removed from the memories. Note that since the oldest sample may have no associated payload,
-- multiple sample removals may be triggered. Also note that this happens also when the sample to be added has no
-- associated payload, since we cannot know this in advance. On the other hand, because this action is preliminary and
-- before the actual decision based on the sample to be added (which again may reject the operation or remove a specific
-- sample), a situation may arise were a single ADD_CACHE_CHANGE operation may trigger multiple sample removals
-- (one/multiple to make space for the payload, and one based on the sample to be added, like maximum number of samples
-- per instance).
-- CacheChanges without associated payload are only stored, if the sample causes an instance state change (Between
-- ALIVE, NOT_ALIVE_NO_WRITERS, NOT_ALIVE_DISPOSED). An instance state change to the NOT_ALIVE_NO_WRITERS instance state
-- (meaning that no writer is writing this instance anymore) can also occur without receiving a CacheChange (e.g. Due
-- to the last writer failing to assert his liveliness). For this special instance state transition a sample is
-- generated for the respective instance.
-- The REMOVE_WRITER operation removes the specified writer form all currently stored instances, and is used to track
-- stale instances (see above).
-- To start an operation the 'start' signal is asserted with the respective opcode in 'opcode' and waits until the
-- operation is acknowledged by asserting the 'ack' signal. The REMOVE_WRITER operation needs to also transfer a single
-- word of data for the operation (see below for Format), which has to be on the 'data' signal while the 'start' signal
-- is asserted. The ADD_CACHE_CHANGE operation also needs a data transfer, but uses a valid/ready schema for the
-- transfer. The 'valid' signal is asserted whenever the data signal contains valid data, and if the 'ready' signal is
-- asserted, the data is considered latched by the recipient. An asserted 'last_word' signal marks the last word of the
-- transaction. After the operation is completed, the 'done' signal is asserted for one clock cycle, and the return
-- status can be found in the 'ret' signal on the same clock cycle.
-- The allowed DDS (user) operations are READ, TAKE, READ_NEXT_SAMPLE, TAKE_NEXT_SAMPLE, READ_INSTANCE, TAKE_INSTANCE,
-- READ_NEXT_INSTANCE, TAKE_NEXT_INSTANCE, GET_SAMPLE_REJECTED_STATUS, and GET_REQUESTED_DEADLINE_MISSED_STATUS.
-- The description of the operations, their inputs, and outputs can be taken directly from the DDS specification.
-- Similar to the RTPS operations, the 'start' signal is asserted with the respective opcode in 'opcode' to start an
-- operation until the 'ack' signal is asserted, and an asserted 'done' signal signifies the end of the operation with
-- the return status found in the 'return_code' signal on the same clock cycle. The READ and TAKE operation also need
-- valid 'sample_state', 'view_state', 'instance_state', and 'max_samples' signals while the 'start' signal is asserted,
-- whereas the READ_INSTANCE, TAKE_INSTANCE, READ_NEXT_INSTANCE, and TAKE_NEXT_INSTANCE operations need in addition to
-- those signals also a valid 'instance_handle' signal. After completion ('done' signal asserted), the GET_* operations
-- initiate a data transfer (using valid/ready schema like for the RTPS operations) for the requested data (see below
-- for output format). All READ_* and TAKE_* operations will return at least one sample info after the operation is
-- completed ('done' signal asserted) and the return code is "RETCODE_OK". All the 'sample_info.*' signals are valid
-- when the 'sample_info_valid' signal is asserted. The 'sample_info.*' signals stay valid until the 'sample_info_ack'
-- signal is asserted. If the sample has associated data ('sample_info.valid_data' asserted), the data can be requested
-- by asserting the 'get_data' signal on the same clock cycle the 'sample_info_ack' signal is asserted. In this case a
-- data transfer (using a valid/ready schema like for the RTPS operations) is initiated. If no more samples are to be
-- returned, the 'eoc' (End Of Collection) signal is asserted for one clock cycle, signifying the end of the operation.
-- NOTE: Dispose and Unregister CacheChanges are dropped if BY_SOURCE_TIMESTAMP_DESTINATION_ORDER_QOS is used and a
-- newer Sample of the same Instance exists. (This is done to keep a consistent history)
-- ADD_CACHE_CHANGE DATA FORMAT
-- ============================
-- 31............24..............16..............8...............0
-- | | | | |
-- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-- +---------------------------------------------------------------+
-- 01| STATUS_INFO |
-- +---------------------------------------------------------------+
-- 02| |
-- + TIMESTAMP +
-- 03| |
-- +---------------------------------------------------------------+
-- 04| |
-- + LIFESPAN_DEADLINE +
-- 05| |
-- +---------------------------------------------------------------+
-- 06| |
-- + +
-- 07| |
-- + KEY_HASH [only if K=1] +
-- 08| |
-- + +
-- 09| |
-- +---------------------------------------------------------------+
-- 10| WRITER_ID |
-- +---------------------------------------------------------------+
-- 11| |
-- ~ PAYLOAD [only if P=1 or P=K=0] ~
-- **| |
-- +---------------------------------------------------------------+
--
-- STATUS INFO
-- -----------
-- 31............24..............16..............8...............0
-- | | | | |
-- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-- +-+-+-+-+-------------------------------------------------+-+-+-+
-- | |P| |K| UNUSED |F|U|D|
-- +-+-+-+-+-------------------------------------------------+-+-+-+
-- P...Sample has associated DATA Payload
-- K...Key Hash available
-- F...FilteredFlag (1:1 PID_STATUS_INFO Mapping)
-- U...UnregisteredFlag (1:1 PID_STATUS_INFO Mapping)
-- D...DisposedFlag (1:1 PID_STATUS_INFO Mapping)
-- NOTE: If P=0 and K=0, the Payload contains the Serialized Key
-- REMOVE_WRITER DATA FORMAT
-- =========================
-- 31............24..............16..............8...............0
-- | | | | |
-- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-- +---------------------------------------------------------------+
-- 01| WRITER_ID |
-- +---------------------------------------------------------------+
-- GET_SAMPLE_REJECTED_STATUS DATA FORMAT
-- ======================================
-- 31............24..............16..............8...............0
-- | | | | |
-- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-- +---------------------------------------------------------------+
-- 01| TOTAL_COUNT |
-- +---------------------------------------------------------------+
-- 02| TOTAL_COUNT_CHANGE |
-- +---------------------------------------------------------------+
-- 03| LAST_REASON |
-- +---------------------------------------------------------------+
-- 04| |
-- + +
-- 05| |
-- + LAST_INSTANCE_HANDLE +
-- 06| |
-- + +
-- 07| |
-- +---------------------------------------------------------------+
-- GET_REQUESTED_DEADLINE_MISSED_STATUS DATA FORMAT
-- ================================================
-- 31............24..............16..............8...............0
-- | | | | |
-- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-- +---------------------------------------------------------------+
-- 01| TOTAL_COUNT |
-- +---------------------------------------------------------------+
-- 02| TOTAL_COUNT_CHANGE |
-- +---------------------------------------------------------------+
-- 03| |
-- + +
-- 04| |
-- + LAST_INSTANCE_HANDLE +
-- 05| |
-- + +
-- 06| |
-- +---------------------------------------------------------------+
-- MEMORY LAYOUT
-- This entity is using double linked lists of fixed-size memory frames for the sample and instance memories, while
-- using single linked list for the payload memory.
-- 2 lists of frames are kept for the sample and instance memories, one for the empty frames, and one for the occupied
-- frames, whereas only one list for the empty frames is kept for the payload memory.
-- The memory frames have following structure:
-- SAMPLE DATA MEMORY FORMAT
-- =========================
-- 31............24..............16..............8...............0
-- | | | | |
-- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-- +---------------------------------------------------------------+
-- 01| STATUS_INFO |
-- +---------------------------------------------------------------+
-- 02| |
-- + TIMESTAMP +
-- 03| |
-- +---------------------------------------------------------------+
-- 04| |
-- + LIFESPAN_DEADLINE +
-- 05| |
-- +---------------------------------------------------------------+
-- 06| PAYLOAD_ADDRESS |
-- +---------------------------------------------------------------+
-- 07| INSTANCE_ADDRESS [only if WITH_KEY] |
-- +---------------------------------------------------------------+
-- 08| DISPOSED_GENERATION_COUNT |
-- +---------------------------------------------------------------+
-- 09| NO_WRITERS_GENERATION_COUNT |
-- +---------------------------------------------------------------+
-- 10| PREV_ADDRESS |
-- +---------------------------------------------------------------+
-- 11| NEXT_ADDRESS |
-- +---------------------------------------------------------------+
--
-- STATUS INFO
-- -----------
-- 31............24..............16..............8...............0
-- | | | | |
-- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-- +-+-+-+---------------------------------------------------+-+-+-+
-- |R|P|A| UNUSED |F|U|D|
-- +-+-+-+---------------------------------------------------+-+-+-+
-- R...Sample has been Read
-- P...Sample has associated DATA Payload
-- A...Associated Payload is aligned (Payload does extend until end of last Payload Slot)
-- F...FilteredFlag (1:1 PID_STATUS_INFO Mapping)
-- U...UnregisteredFlag (1:1 PID_STATUS_INFO Mapping)
-- D...DisposedFlag (1:1 PID_STATUS_INFO Mapping)
-- INSTANCE DATA MEMORY FORMAT
-- ===========================
-- 31............24..............16..............8...............0
-- | | | | |
-- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-- +---------------------------------------------------------------+
-- 01| NEXT_ADDRESS |
-- +---------------------------------------------------------------+
-- 02| PREV_ADDRESS |
-- +---------------------------------------------------------------+
-- 03| |
-- + +
-- 04| |
-- + KEY_HASH +
-- 05| |
-- + +
-- 06| |
-- +---------------------------------------------------------------+
-- 07| STATUS_INFO |
-- +---------------------------------------------------------------+
-- 08| SAMPLE_COUNT |
-- +---------------------------------------------------------------+
-- 09| DISPOSED_GENERATION_COUNT |
-- +---------------------------------------------------------------+
-- 10| NO_WRITERS_GENERATION_COUNT |
-- +---------------------------------------------------------------+
-- 11| |
-- + IGNORE_DEADLINE +
-- 12| [only if TIME_BASED_FILTER /= 0] |
-- +---------------------------------------------------------------+
-- 13| |
-- ~ WRITER_BITMAP ~
-- **| |
-- +---------------------------------------------------------------+
--
-- STATUS INFO
-- -----------
-- 31............24..............16..............8...............0
-- | | | | |
-- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-- +---------------------------------------------------+-+-+-+-+-+-+
-- | UNUSED |G|M|V|L|W|D|
-- +---------------------------------------------------+-+-+-+-+-+-+
-- D...NOT_ALIVE_DISPOSED
-- W...NOT_ALIVE_NO_WRITERS
-- L...LIVELINESS FLAG
-- V...VIEW STATE
-- M...MARK
-- G...GENERATE SAMPLE
-- PAYLOAD DATA MEMORY FORMAT
-- ==========================
-- 31............24..............16..............8...............0
-- | | | | |
-- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-- +---------------------------------------------------------------+
-- 01| NEXT_ADDRESS |
-- +---------------------------------------------------------------+
-- 02| |
-- ~ PAYLOAD ~
-- **| |
-- +---------------------------------------------------------------+
entity dds_reader is
generic (
NUM_READERS : natural;
@ -91,7 +380,7 @@ architecture arch of dds_reader is
data_in : in std_logic_vector(WORD_WIDTH-1 downto 0);
last_word_in : in std_logic;
-- OUTPUT
ready_out : in std_logic;
ready_out : in std_logic;
valid_out : out std_logic;
data_out : out std_logic_vector(WORD_WIDTH-1 downto 0);
last_word_out : out std_logic
@ -317,13 +606,13 @@ architecture arch of dds_reader is
--*****TYPE DECLARATION*****
-- FSM states. Explained below in detail
type STAGE_TYPE is (IDLE, RETURN_DDS, RETURN_RTPS, ADD_SAMPLE_INFO, ADD_PAYLOAD, NEXT_PAYLOAD_SLOT, ALIGN_PAYLOAD, GET_KEY_HASH, INITIATE_INSTANCE_SEARCH,
FILTER_STAGE, UPDATE_INSTANCE, FINALIZE_PAYLOAD, PRE_SAMPLE_FINALIZE, FIND_POS, FIX_POINTERS, FINALIZE_SAMPLE, GENERATE_SAMPLE, GET_OLDEST_SAMPLE_INSTANCE,
FIND_OLDEST_INST_SAMPLE, REMOVE_SAMPLE, POST_SAMPLE_REMOVE, SKIP_AND_RETURN, REMOVE_WRITER, REMOVE_STALE_INSTANCE, WAIT_READ, GET_PAYLOAD, CHECK_LIFESPAN,
type STAGE_TYPE is (IDLE, RETURN_DDS, RETURN_RTPS, ADD_SAMPLE_INFO, PROCESS_INPUT, NEXT_PAYLOAD_SLOT, ALIGN_PAYLOAD, GET_KEY_HASH, INITIATE_INSTANCE_SEARCH,
FILTER_STAGE, UPDATE_INSTANCE, FINALIZE_PAYLOAD, PRE_SAMPLE_FINALIZE, FIND_POS, FIX_POINTERS, FINALIZE_SAMPLE, GENERATE_SAMPLE, GET_OLDEST_SAMPLE_INSTANCE,
FIND_OLDEST_INST_SAMPLE, REMOVE_SAMPLE, POST_SAMPLE_REMOVE, SKIP_AND_RETURN, REMOVE_WRITER, REMOVE_STALE_INSTANCE, WAIT_READ, GET_PAYLOAD, CHECK_LIFESPAN,
PROCESS_PENDING_SAMPLE_GENERATION, GET_SAMPLE_REJECTED_STATUS, GET_REQUESTED_DEADLINE_MISSED_STATUS, CHECK_DEADLINE, RESET_SAMPLE_MEMORY, RESET_PAYLOAD_MEMORY);
type READ_STAGE_TYPE is (IDLE, GET_NEXT_SAMPLE, PRE_CALCULATE, FINALIZE_SAMPLE_INFO, FIND_NEXT_INSTANCE, CHECK_INSTANCE, WAIT_PAYLOAD, WAIT_REMOVE, DONE);
-- Instance Memory FSM states. Explained below in detail
type INST_STAGE_TYPE is (IDLE, SEARCH_INSTANCE, GET_NEXT_INSTANCE, GET_INSTANCE_DATA, FIND_POS, INSERT_INSTANCE, UPDATE_INSTANCE,
type INST_STAGE_TYPE is (IDLE, SEARCH_INSTANCE, GET_NEXT_INSTANCE, GET_INSTANCE_DATA, FIND_POS, INSERT_INSTANCE, UPDATE_INSTANCE,
REMOVE_INSTANCE, UNMARK_INSTANCES, RESET_MEMORY);
-- *Instance Memory Opcodes*
-- OPCODE DESCRIPTION
@ -339,7 +628,7 @@ architecture arch of dds_reader is
-- REMOVE_INSTANCE Remove Instance pointed by "inst_data.addr".
-- "inst_data.addr" is set to the next Instance (or INSTANCE_MEMORY_MAX_ADDRESS if no next Instance exists)
-- UNMARK_INSTANCES Reset the MARK_FLAG of all Instances in Memory.
type INSTANCE_OPCODE_TYPE is (NOP, SEARCH_INSTANCE, INSERT_INSTANCE, UPDATE_INSTANCE, GET_FIRST_INSTANCE, GET_NEXT_INSTANCE, REMOVE_INSTANCE,
type INSTANCE_OPCODE_TYPE is (NOP, SEARCH_INSTANCE, INSERT_INSTANCE, UPDATE_INSTANCE, GET_FIRST_INSTANCE, GET_NEXT_INSTANCE, REMOVE_INSTANCE,
GET_INSTANCE, UNMARK_INSTANCES);
type WRITER_BITMAP_ARRAY_TYPE is array (0 to round_div(MAX_REMOTE_ENDPOINTS, WORD_WIDTH)-1) of std_logic_vector(0 to WORD_WIDTH-1);
constant ZERO_WRITER_BITMAP_ARRAY : WRITER_BITMAP_ARRAY_TYPE := (others => (others => '0'));
@ -415,7 +704,7 @@ architecture arch of dds_reader is
signal inst_abort_read_i : std_logic_vector(0 to NUM_READERS-1);
-- *KEY HOLDER CONNECTION SIGNALS*
signal start_kh, ack_kh, valid_in_kh, ready_in_kh, last_word_in_kh, valid_out_kh, ready_out_kh, last_word_out_kh, abort_kh : std_logic_vector(0 to NUM_READERS-1);
signal start_kh, ack_kh, valid_in_kh, ready_in_kh, last_word_in_kh, valid_out_kh, ready_out_kh, last_word_out_kh, abort_kh, decode_error_kh : std_logic_vector(0 to NUM_READERS-1);
signal opcode_kh : KEY_HOLDER_OPCODE_ARRAY_TYPE(0 to NUM_READERS-1);
signal data_in_kh, data_out_kh : WORD_ARRAY_TYPE(0 to NUM_READERS-1);
@ -554,7 +843,7 @@ architecture arch of dds_reader is
signal cur_generation_rank, cur_generation_rank_next : unsigned(GENERATION_RANK_WIDTH-1 downto 0);
-- Denotes if a TAKE operation is in progress
signal is_take, is_take_next : std_logic;
-- NOTE: We use this signal to prevent the costly Instance Marking in the case that we only need to ouptput samples of one Instance.
-- NOTE: We use this signal to prevent the costly Instance Marking in the case that we only need to output samples of one Instance.
-- Denotes if the READ/TAKE operation applies to a single Instance
signal single_instance, single_instance_next : std_logic;
-- Denotes if the READ/TAKE operation does not apply to a specific Instance
@ -703,28 +992,37 @@ begin
--*****COMPONENT INSTANTIATION*****
key_holder_gen : for i in 0 to NUM_READERS-1 generate
key_holder_inst : key_holder
port map (
-- SYSTEM
clk => clk,
reset => reset,
-- CONTROL
start => start_kh(i),
opcode => opcode_kh(i),
ack => ack_kh(i),
decode_error => open,
abort => abort_kh(i),
-- INPUT
ready_in => ready_out_kh(i),
valid_in => valid_out_kh(i),
data_in => data_out_kh(i),
last_word_in => last_word_out_kh(i),
-- OUTPUT
ready_out => ready_in_kh(i),
valid_out => valid_in_kh(i),
data_out => data_in_kh(i),
last_word_out => last_word_in_kh(i)
);
key_holder_if_gen : if CONFIG_ARRAY_T(i).WITH_KEY generate
key_holder_inst : key_holder
port map (
-- SYSTEM
clk => clk,
reset => reset,
-- CONTROL
start => start_kh(i),
opcode => opcode_kh(i),
ack => ack_kh(i),
decode_error => decode_error_kh(i),
abort => abort_kh(i),
-- INPUT
ready_in => ready_out_kh(i),
valid_in => valid_out_kh(i),
data_in => data_out_kh(i),
last_word_in => last_word_out_kh(i),
-- OUTPUT
ready_out => ready_in_kh(i),
valid_out => valid_in_kh(i),
data_out => data_in_kh(i),
last_word_out => last_word_in_kh(i)
);
else generate
ack_kh(i) <= '0';
decode_error_kh(i) <= '0';
ready_in_kh(i) <= '0';
valid_out_kh(i) <= '0';
last_word_out_kh(i) <= '0';
data_out_kh(i) <= (others => '0');
end generate;
end generate;
sample_mem_ctrl_gen : for i in 0 to NUM_READERS-1 generate
@ -900,11 +1198,11 @@ begin
-- *Main State Machine*
-- STATE DESCRIPTION
-- IDLE Idle State. Initiates Deadline Miss Checks, Lifespan Expiry Checks, RTPS Operation handling, and DDS Operation handling, in that priority order.
-- IDLE Idle State. Initiates Deadline Miss Checks, Lifespan Expiry Checks, Instance State Sample Generation, RTPS Operation handling, Instance unmarking, and DDS Operation handling, in that priority order.
-- RETURN_DDS Return latched DDS Return Code
-- RETURN_RTPS Return latched RTPS Return Code
-- ADD_SAMPLE_INFO Latch and store Cache Change (pre-payload)
-- ADD_PAYLOAD Push payload to memory and key hash generator (as needed)
-- PROCESS_INPUT Push payload to memory and/or Key Holder (as needed)
-- NEXT_PAYLOAD_SLOT Get pointer to next empty payload slot
-- ALIGN_PAYLOAD Store the offset of the actual payload in the last address of the last payload slot.
-- GET_KEY_HASH Fetch the calculated key hash from the Key Hash Generator
@ -921,15 +1219,11 @@ begin
-- FIND_OLDEST_INST_SAMPLE Find the oldest sample of a specific Instance
-- REMOVE_SAMPLE Remove sample and linked payload
-- POST_SAMPLE_REMOVE Update Instance Data of removed sample. If Instance Memory is full, and Instance is now eligible for removal, it is removed.
-- SKIP_AND_RETURN Skip DDS Input and return latched Return Code
-- SKIP_AND_RETURN Skip RTPS Input and return latched Return Code
-- REMOVE_WRITER Unmark specified Writer Bitmap Position from all stored Instances. (Also updates Instance Data if necessary)
-- REMOVE_STALE_INSTANCE Find and remove the first eligible Instance in the memory
-- GET_NEXT_SAMPLE Find the next sample in the requested collection
-- PRE_CALCULATE Calculate ranks for the selected sample in the requested collection.
-- FINALIZE_SAMPLE_INFO Finalize the Sample Info Data, and present them.
-- WAIT_READ Synchronisation state between main and read FSM. Waits until read/take operation is complete and triggers sample removal and payload fetch.
-- GET_PAYLOAD Push linked Payload to output
-- FIND_NEXT_INSTANCE Find next Instance that passes requested masks
-- CHECK_INSTANCE Check if selected Instance passes requested masks
-- CHECK_LIFESPAN Check and remove samples with expired Lifespans
-- PROCESS_PENDING_SAMPLE_GENERATION Iterate through the Instances and Generate Samples where required (A Sample is generated for NOT_ALIVE_NO_WRITERS transitions)
-- GET_SAMPLE_REJECTED_STATUS Return Sample Rejected Status
@ -1083,7 +1377,7 @@ begin
else
case (opcode_rtps(ind)) is
when ADD_CACHE_CHANGE =>
-- NOTE: We have to explicitly check the Payload Memory, as it may be "unaligned" with our Sample Memory
-- NOTE: We have to explicitly check the Payload Memory, as it may be "unaligned" with our Sample Memory
-- (Sample Memory has available Slot, but Payload Memory not)
-- Payload Memory Full
if (empty_payload_list_head(ind) = PAYLOAD_MEMORY_MAX_ADDRESS) then
@ -1103,8 +1397,6 @@ begin
sample_rej_last_inst_next(ind) <= HANDLE_NIL;
else
assert (oldest_sample(ind) /= SAMPLE_MEMORY_MAX_ADDRESS) severity FAILURE;
-- Do not ACK Operation
ack_dds(ind) <= '0';
remove_oldest_sample_next <= '1';
stage_next <= GET_OLDEST_SAMPLE_INSTANCE;
@ -1401,7 +1693,7 @@ begin
if (has_key_hash = '0') then
cnt_next <= cnt + 1;
elsif (has_data = '1') then
stage_next <= ADD_PAYLOAD;
stage_next <= PROCESS_INPUT;
cnt_next <= 0;
payload_cnt_next <= 1;
else
@ -1422,20 +1714,14 @@ begin
end if;
if (ack_kh(ind) = '1') then
-- Payload is Serialized Key
if (has_data = '0') then
stage_next <= ADD_PAYLOAD;
cnt_next <= 1;
else
stage_next <= ADD_PAYLOAD;
cnt_next <= 0;
payload_cnt_next <= 1;
end if;
stage_next <= PROCESS_INPUT;
cnt_next <= 0; -- Process Input
payload_cnt_next <= 1;
end if;
when others =>
null;
end case;
when ADD_PAYLOAD =>
when PROCESS_INPUT =>
-- Precondition (if has_data = '1'): cur_payload set (Current Slot)
-- NOTE: This state is responsible for reading the payload and writing it through to the local payload memory
@ -1443,97 +1729,62 @@ begin
-- has_data has_key_hash
-- 1 1 The payload is written to memory
-- 1 0 The payload is written to memory and the KHG at the same time (KHG controls the flow)
-- 0 0 There is no payload to write, but the input contains the key for the KHG
-- 0 0 There is no payload to write, but the input contains the serialized key for the KHG
case (cnt) is
-- Push to memory
-- Process Input
when 0 =>
-- Input Guard
if (valid_in_rtps(ind) = '1') then
payload_valid_in <= '1';
-- Payload Memory
payload_addr <= cur_payload + payload_cnt;
payload_write_data <= data_in_rtps(ind);
-- Memory Control Flow Guard
if (payload_ready_in = '1') then
-- Key Hash needs to be calculated
if (CONFIG_ARRAY_T(ind).WITH_KEY and has_key_hash = '0') then
cnt_next <= cnt + 1;
else
ready_in_rtps(ind) <= '1';
-- End of Payload
if (last_word_in_rtps(ind) = '1') then
-- End of Payload Slot
if (payload_cnt = PAYLOAD_FRAME_SIZE(ind)-1) then
stage_next <= INITIATE_INSTANCE_SEARCH;
else
stage_next <= ALIGN_PAYLOAD;
cnt_next <= 0;
end if;
-- Key Holder
data_out_kh(ind) <= data_in_rtps(ind);
last_word_out_kh(ind) <= last_word_in_rtps(ind);
-- Control Flow Guard
if ((((not has_data) or payload_ready_in) = '1') and (((has_key_hash) or ready_out_kh(ind)) = '1')) then
ready_in_rtps(ind) <= '1';
if (has_data = '1') then
payload_valid_in <= '1';
-- End of Payload Slot
if (payload_cnt = PAYLOAD_FRAME_SIZE(ind)-1) then
stage_next <= NEXT_PAYLOAD_SLOT;
cnt_next <= 0;
else
-- End of Payload Slot
if (payload_cnt = PAYLOAD_FRAME_SIZE(ind)-1) then
stage_next <= NEXT_PAYLOAD_SLOT;
cnt_next <= 0;
else
-- Next Word
payload_cnt_next <= payload_cnt + 1;
end if;
-- Next Word
payload_cnt_next <= payload_cnt + 1;
end if;
end if;
if (has_key_hash = '0') then
valid_out_kh(ind) <= '1';
end if;
-- End of Input
if (last_word_in_rtps(ind) = '1') then
-- Overrule
stage_next <= PROCESS_INPUT;
cnt_next <= cnt + 1;
payload_cnt_next <= payload_cnt;
end if;
end if;
end if;
-- Push to KHG
-- Post Input Process
when 1 =>
assert (CONFIG_ARRAY_T(ind).WITH_KEY) severity FAILURE;
-- Input Guard
if (valid_in_rtps(ind) = '1') then
valid_out_kh(ind) <= '1';
data_out_kh(ind) <= data_in_rtps(ind);
-- Output Guard
if (ready_out_kh(ind) = '1') then
ready_in_rtps(ind) <= '1';
if (has_data = '1') then
-- End of Payload
if (last_word_in_rtps(ind) = '1') then
last_word_out_kh(ind) <= '1';
-- End of Payload Slot
if (payload_cnt = PAYLOAD_FRAME_SIZE(ind)-1) then
-- Fetch the Key Hash
stage_next <= GET_KEY_HASH;
cnt_next <= 0;
payload_cnt_next <= 0;
else
stage_next <= ALIGN_PAYLOAD;
cnt_next <= 0;
end if;
else
-- End of Payload Slot
if (payload_cnt = PAYLOAD_FRAME_SIZE(ind)-1) then
stage_next <= NEXT_PAYLOAD_SLOT;
cnt_next <= 0;
else
-- Next Word
cnt_next <= 0; -- PUSH TO MEMORY
payload_cnt_next <= payload_cnt + 1;
end if;
end if;
else
-- End of Payload
if (last_word_in_rtps(ind) = '1') then
last_word_out_kh(ind) <= '1';
-- Fetch the Key Hash
stage_next <= GET_KEY_HASH;
cnt_next <= 0;
payload_cnt_next <= 0;
else
-- Next Word
cnt_next <= 1; -- Same Sub-state
end if;
end if;
end if;
-- Payload Unaligned
if (has_data = '1' and payload_cnt /= PAYLOAD_FRAME_SIZE(ind)-1) then
stage_next <= ALIGN_PAYLOAD;
cnt_next <= 0; -- Mark Payload as Unaligned
elsif (has_key_hash = '0') then
-- Fetch the Key Hash
stage_next <= GET_KEY_HASH;
cnt_next <= 0; -- Initiate READ Operation
payload_cnt_next <= 0;
else
stage_next <= INITIATE_INSTANCE_SEARCH;
end if;
when others =>
null;
@ -1575,9 +1826,9 @@ begin
else
-- Latch next Payload Slot and Continue
cur_payload_next <= resize(unsigned(payload_read_data),PAYLOAD_MEMORY_ADDR_WIDTH);
stage_next <= ADD_PAYLOAD;
stage_next <= PROCESS_INPUT;
cnt_next <= 0;
payload_cnt_next <= 1;
payload_cnt_next <= 1;
end if;
end if;
when others =>
@ -1589,7 +1840,7 @@ begin
when 0 =>
sample_valid_in1 <= '1';
sample_addr1 <= cur_sample + SMF_STATUS_INFO_OFFSET;
sample_write_data1 <= sample_status_info;
sample_write_data1 <= sample_status_info; -- TODO: This overwrites the removed flags
sample_write_data1(SSI_ALIGNED_FLAG) <= '0';
-- Memory Control Flow Guard
@ -1620,17 +1871,26 @@ begin
case (cnt) is
-- Initiate READ Operation
when 0 =>
start_kh(ind) <= '1';
opcode_kh(ind) <= READ_KEY_HASH;
if (ack_kh(ind) = '1') then
cnt_next <= cnt + 1;
when 0 =>
-- Key Holder Decode Error
if (decode_error_kh(ind) = '1') then
done_dds(ind) <= '1';
return_code_dds(ind) <= RETCODE_ERROR;
-- DONE
stage_next <= IDLE;
else
start_kh(ind) <= '1';
opcode_kh(ind) <= READ_KEY_HASH;
if (ack_kh(ind) = '1') then
cnt_next <= cnt + 1;
end if;
end if;
-- READ Key Hash
when 1 =>
ready_in_kh(ind) <= '1';
if (valid_in_kh(ind) = '1') then
payload_cnt_next <= payload_cnt + 1;
@ -1639,11 +1899,11 @@ begin
-- Exit Condition
if (last_word_in_kh(ind) = '1') then
-- DONE
-- Exit
stage_next <= INITIATE_INSTANCE_SEARCH;
end if;
end if;
when others =>
when others =>
null;
end case;
when INITIATE_INSTANCE_SEARCH =>
@ -1821,7 +2081,7 @@ begin
stage_next <= REMOVE_STALE_INSTANCE;
cnt_next <= 0;
end if;
else
else
done_rtps(ind) <= '1';
ret_rtps(ind) <= OK;
@ -2018,7 +2278,7 @@ begin
prev_sample_next <= resize(unsigned(sample_read_data),SAMPLE_MEMORY_ADDR_WIDTH);
cnt_next <= cnt + 1;
end if;
-- READ Instance Poiner
-- READ Instance Pointer
when 7 =>
sample_ready_out1 <= '1';
@ -2133,7 +2393,7 @@ begin
tmp_bitmap := from_writer_bitmap_array(inst_data.writer_bitmap);
-- ALIVE/FILTERED/DISPOSE Operation
if (sample_status_info(SSI_UNREGISTERED_FLAG) /= '1') then
-- Write if Writer New for Instance
-- Insert if Writer New for Instance
if (tmp_bitmap(writer_id) /= '1') then
-- Insert Writer
tmp_bitmap(writer_id) := '1';
@ -2142,9 +2402,9 @@ begin
tmp_update := tmp_update or IMF_WRITER_BITMAP_FLAG;
end if;
else
-- Write if Writer New for Instance
-- Writer previously inserted
if (tmp_bitmap(writer_id) /= '0') then
-- Insert Writer
-- Remove Writer
tmp_bitmap(writer_id) := '0';
-- Convert Back
inst_r1.writer_bitmap <= to_writer_bitmap_array(tmp_bitmap);
@ -2174,7 +2434,7 @@ begin
-- NOT_ALIVE_DISPOSED -> NOT_ALIVE_DISPOSED
if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '1') then
tmp_bool := FALSE;
-- Only Update Instance State if Sample if newest
-- Only Update Instance State if Sample is newest
elsif (newer_inst_sample = '0') then
inst_r1.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) <= '1';
inst_r1.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) <= '0';
@ -2199,7 +2459,7 @@ begin
else
assert (has_data = '1') severity FAILURE;
end if;
-- Only Update Instance State if Sample if newest
-- Only Update Instance State if Sample is newest
elsif (newer_inst_sample = '0') then
inst_r1.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) <= '0';
inst_r1.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) <= '0';
@ -2225,7 +2485,7 @@ begin
-- Instance was Stale
if (inst_data.sample_cnt = 0 and inst_data.writer_bitmap = ZERO_WRITER_BITMAP_ARRAY) then
assert (stale_inst_cnt(ind) /= 0) severity FAILURE;
-- NOTE: The UPDATE_INSTANCE state is only taken if a new Sample is added to an existing Instance.
-- NOTE: The UPDATE_INSTANCE state is only taken if a new Sample is added to an existing Instance.
-- Since Instances with Samples are not stale, we have to unmark the Instance.
stale_inst_cnt_next(ind) <= stale_inst_cnt(ind) - 1;
end if;
@ -2257,7 +2517,7 @@ begin
when FINALIZE_PAYLOAD =>
-- Precondition: cur_payload set
case (cnt) is
case (cnt) is
-- GET Next Pointer
when 0 =>
payload_valid_in <= '1';
@ -2492,7 +2752,7 @@ begin
when GENERATE_SAMPLE =>
-- Precondition: cur_sample set, cur_inst set, inst_data set (IMF_DISPOSED_CNT_FLAG, IMF_NO_WRITERS_CNT_FLAG)
-- Wait for Instane Data
-- Wait for Instance Data
if (inst_op_done = '1') then
assert (inst_data.addr /= INSTANCE_MEMORY_MAX_ADDRESS) severity FAILURE;
assert (stable(clk, inst_data.i = ind and check_mask(inst_data.field_flags, IMF_DISPOSED_CNT_FLAG or IMF_NO_WRITERS_CNT_FLAG))) severity FAILURE;
@ -2759,7 +3019,7 @@ begin
case (cnt) is
-- GET Instance Data
when 0 =>
when 0 =>
if (cur_inst = inst_data.addr and inst_data.i = ind and check_mask(inst_data.field_flags, IMF_SAMPLE_CNT_FLAG or IMF_WRITER_BITMAP_FLAG)) then
cnt_next <= cnt + 1;
else
@ -3238,7 +3498,7 @@ begin
case (cnt) is
-- GET Next Pointer
when 0 =>
-- NOTE: We have to make sure that no pending Reads are in the Memory Controler Buffer,
-- NOTE: We have to make sure that no pending Reads are in the Memory Controller Buffer,
-- else the Next Payload Pointer cannot be read.
-- No Pending Reads
if (payload_cnt2 = 0) then
@ -3301,7 +3561,7 @@ begin
if (payload_cnt = unsigned(long_latch)) then
-- End of Payload
if (next_payload = PAYLOAD_MEMORY_MAX_ADDRESS) then
-- DONE (Wait for Output to finidh reading)
-- DONE (Wait for Output to finish reading)
cnt_next <= cnt + 1;
else
-- Next Payload Slot
@ -3336,7 +3596,7 @@ begin
-- Increment in same clock cycle
if (tmp_bool) then
payload_cnt2_next <= payload_cnt2; -- Override increment
else
else
payload_cnt2_next <= payload_cnt2 - 1;
end if;
@ -3349,7 +3609,7 @@ begin
end if;
end if;
when CHECK_LIFESPAN =>
-- Precondition: cur_sample set,
-- Precondition: cur_sample set,
case (cnt) is
-- GET NEXT WRITER
@ -3483,7 +3743,7 @@ begin
cnt_next <= 0;
end if;
end if;
when others =>
when others =>
null;
end case;
when PROCESS_PENDING_SAMPLE_GENERATION =>
@ -3895,6 +4155,17 @@ begin
end case;
end process;
-- *Main State Machine*
-- STATE DESCRIPTION
-- IDLE Idle State. Synchronization state between main and read FSM. Waits until main FSM triggers a read/take operation.
-- GET_NEXT_SAMPLE Find the next sample in the requested collection
-- PRE_CALCULATE Calculate ranks for the selected sample in the requested collection.
-- FINALIZE_SAMPLE_INFO Finalize the Sample Info Data, and present them.
-- FIND_NEXT_INSTANCE Find next Instance that passes requested masks
-- CHECK_INSTANCE Check if selected Instance passes requested masks
-- WAIT_PAYLOAD Synchronization state between main and read FSM. Waits until main FSM finishes payload transfer.
-- WAIT_REMOVE Synchronization state between main and read FSM. Waits until main FSM finishes sample removal.
-- DONE Signal end of operation to main FSM.
read_prc : process (all)
variable tmp_bool : boolean;
alias sample_p1 : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) is sample_addr_latch_4;
@ -3926,7 +4197,7 @@ begin
si_sample_state_sig_next <= si_sample_state_sig;
si_view_state_sig_next <= si_view_state_sig;
si_instance_state_sig_next <= si_instance_state_sig;
si_source_timestamp_sig_next <= si_source_timestamp_sig;
si_source_timestamp_sig_next <= si_source_timestamp_sig;
si_instance_handle_sig_next <= si_instance_handle_sig;
si_publication_handle_sig_next <= si_publication_handle_sig;
si_disposed_generation_count_sig_next <= si_disposed_generation_count_sig;
@ -4218,7 +4489,7 @@ begin
end if;
when ANY_SAMPLE_STATE =>
null;
-- Uknown Sample State
-- Unknown Sample State
when others =>
tmp_bool := FALSE;
end case;
@ -4555,7 +4826,7 @@ begin
cnt2_next <= 0; -- GET NEXT SAMPLE
end if;
end if;
when others =>
when others =>
null;
end case;
when PRE_CALCULATE =>
@ -4641,7 +4912,7 @@ begin
end if;
when ANY_SAMPLE_STATE =>
null;
-- Uknown Sample State
-- Unknown Sample State
when others =>
tmp_bool := FALSE;
end case;
@ -4830,7 +5101,7 @@ begin
-- Sample Info Generation Rank
si_generation_rank_sig_next <= collection_generation_rank - cur_generation_rank;
-- Sample Info Absolut Generation Rank
-- Sample Info Absolute Generation Rank
-- XXX: Possible Worst Case Path (2 32-bit Operations in same clock)
si_absolute_generation_rank_sig_next <= (inst_data.disposed_gen_cnt + inst_data.no_writers_gen_cnt) - cur_generation_rank;
@ -4990,7 +5261,7 @@ begin
cnt2_next <= cnt2 + 1;
end if;
-- KEY HASH 1/4
when 3 =>
when 3 =>
assert (inst_data.addr /= INSTANCE_MEMORY_MAX_ADDRESS) severity FAILURE;
assert stable(clk, inst_data.i = ind and check_mask(inst_data.field_flags, IMF_KEY_HASH_FLAG)) severity FAILURE;
@ -5003,7 +5274,7 @@ begin
cnt2_next <= 1; -- GET NEXT INSTANCE
end if;
-- KEY HASH 2/4
when 4 =>
when 4 =>
assert (inst_data.addr /= INSTANCE_MEMORY_MAX_ADDRESS) severity FAILURE;
assert stable(clk, inst_data.i = ind and check_mask(inst_data.field_flags, IMF_KEY_HASH_FLAG)) severity FAILURE;
@ -5016,7 +5287,7 @@ begin
cnt2_next <= 1; -- GET NEXT INSTANCE
end if;
-- KEY HASH 3/4
when 5 =>
when 5 =>
assert (inst_data.addr /= INSTANCE_MEMORY_MAX_ADDRESS) severity FAILURE;
assert stable(clk, inst_data.i = ind and check_mask(inst_data.field_flags, IMF_KEY_HASH_FLAG)) severity FAILURE;
@ -5029,7 +5300,7 @@ begin
cnt2_next <= 1; -- GET NEXT INSTANCE
end if;
-- KEY HASH 4/4
when 6 =>
when 6 =>
assert stable(clk, inst_data.i = ind and check_mask(inst_data.field_flags, IMF_KEY_HASH_FLAG)) severity FAILURE;
if (unsigned(inst_data.key_hash(3)) > unsigned(instance_handle(3))) then
@ -5243,7 +5514,7 @@ begin
-- INSERT_INSTANCE See Memory OPCODE Description
-- UPDATE_INSTANCE See Memory OPCODE Description
-- REMOVE_INSTANCE See Memory OPCODE Description
-- UNMARK_INTANCES See Memory OPCODE Description
-- UNMARK_INSTANCES See Memory OPCODE Description
-- RESET_MEMORY Reset Endpoint Memory to Empty State
inst_ctrl_prc : process(all)
begin
@ -6008,7 +6279,7 @@ begin
inst_stage_next <= IDLE;
end if;
end if;
-- READ Writer Bitamp
-- READ Writer Bitmap
when 21 =>
inst_ready_out <= '1';
@ -6178,7 +6449,7 @@ begin
inst_cnt_next <= 0;
end if;
end if;
when others =>
when others =>
null;
end case;
when INSERT_INSTANCE =>
@ -6218,7 +6489,7 @@ begin
inst_cnt_next <= inst_cnt + 4; -- SET PREV ADDR
-- NOTE: inst_addr_base contains the current occupied tail
inst_addr_latch_next <= inst_addr_base;
else
else
inst_cnt_next <= inst_cnt + 1;
end if;
end if;
@ -6264,7 +6535,7 @@ begin
if (inst_addr_latch = INSTANCE_MEMORY_MAX_ADDRESS) then
inst_cnt_next <= inst_cnt + 2; -- SET Key Hash 1/4
inst_occupied_head_next(inst_latch_data.i) <= inst_addr_base;
else
else
inst_cnt_next <= inst_cnt + 1;
end if;
end if;
@ -6414,7 +6685,7 @@ begin
inst_cnt2_next <= inst_cnt2 + 1;
end if;
end if;
when others =>
when others =>
null;
end case;
when UPDATE_INSTANCE =>

File diff suppressed because it is too large Load Diff

View File

@ -20,7 +20,7 @@ entity history_cache is
start_a : in std_logic;
opcode_a : in HISTORY_CACHE_OPCODE_TYPE;
res_a : out HISTORY_CACHE_RESPOSNE_TYPE;
res_a : out HISTORY_CACHE_RESPONSE_TYPE;
data_in_a : in std_logic_vector(WORD_WIDTH-1 downto 0);
valid_in_a : in std_logic;
ready_in_a : out std_logic;
@ -28,7 +28,7 @@ entity history_cache is
start_b : in std_logic;
opcode_b : in HISTORY_CACHE_OPCODE_TYPE;
res_b : out HISTORY_CACHE_RESPOSNE_TYPE;
res_b : out HISTORY_CACHE_RESPONSE_TYPE;
data_out_b : out std_logic_vector(WORD_WIDTH-1 downto 0);
last_word_out_b : in std_logic;
);
@ -382,7 +382,7 @@ begin
res_a <= ACK;
end if;
when REMOVE_WRITER =>
-- Input and Memory Gurad
-- Input and Memory Guard
if (valid_in_a = '1' and inst_op_done_a = '1') then
-- Latch Writer Pos
writer_pos_next <= to_integer(unsigned(data_in_a));
@ -425,7 +425,7 @@ begin
-- Timestamp 2/2
when 2 =>
ts_latch_next(1) <= data_in_a;
-- Lifespna Deadline 2/2
-- Lifespan Deadline 2/2
when 4 =>
-- Skip Key Hash, if not available
if (has_key_hash = '0') then
@ -484,7 +484,7 @@ begin
sample_write_data_a <= PAYLOAD_MEMORY_MAX_ADDRESS;
end if;
-- If key Hash is avialable, start the Instacne Search first
-- If key Hash is available, start the Instance Search first
if (has_key_hash = '1') then
stage_a_next <= INITIATE_INSTANCE_SEARCH;
else
@ -737,7 +737,7 @@ begin
end if;
end if;
-- INSANCE SAMPLE COUNT
-- INSTANCE SAMPLE COUNT
if (MAX_SAMPLES_PER_INSTANCE /= LENGTH_UNLIMITED) then
tmp_update := tmp_update or SAMPLE_CNT_FLAG;
end if;
@ -939,7 +939,7 @@ begin
when 2 =>
-- No empty Sample Slot Available
if (sample_read_data_a = SAMPLE_MEMORY_MAX_ADDRESS) then
-- Signal Smaple Memory Full
-- Signal Sample Memory Full
sample_mem_full_next <= '1';
else
empty_sample_list_head_next <= sample_read_data_a;
@ -1101,7 +1101,7 @@ begin
end if;
if (inst_op_start_a = '1') then
-- Latch Signals needed for Mermory Operation (Use _next signals, because some signals are set in same clk)
-- Latch Signals needed for Memory Operation (Use _next signals, because some signals are set in same clk)
inst_latch_data_next <= (
key_hash => key_hash_next,
instance_state => instance_state,
@ -1122,17 +1122,17 @@ begin
-- Reset Data
inst_data_next <= ZERO_INSTANCE_DATA;
-- NOTE: This process gets the lock implicitly when the SEARCH_INSTANCE, or GET_FIRST_INSTANCE operation is called, and has to be released explicitly
-- by the main process. There are two ways to release the lock: 1) The man process explicitly calles the RELEASE_LOCK operation 2) The main
-- process pulls the release_inst_lock signal high during the issuing of the last memory operation (Lock will be release after the opration finishes)
-- by the main process. There are two ways to release the lock: 1) The man process explicitly calls the RELEASE_LOCK operation 2) The main
-- process pulls the release_inst_lock signal high during the issuing of the last memory operation (Lock will be release after the operation finishes)
-- Process B has lock
if (inst_delete_lock_b = '1') then
-- Wait until process B releases lock
inst_stage_a_next <= WAIT_FOR_LOCK_1;
else
-- NOTE: The case that both processes aqcuire the lock at the same time is handled by the B process in the next clock cycle.
-- NOTE: The case that both processes acquire the lock at the same time is handled by the B process in the next clock cycle.
-- Get Lock
inst_delete_lock_a_next <= '1';
-- No Instances avialable
-- No Instances available
if (inst_occupied_head = INSTANCE_MEMORY_MAX_ADDRESS) then
inst_addr_base_a_next <= INSTANCE_MEMORY_MAX_ADDRESS;
else
@ -1187,10 +1187,10 @@ begin
-- Wait until process B releases lock
inst_stage_a_next <= WAIT_FOR_LOCK_2;
else
-- NOTE: The case that both processes aqcuire the lock at the same time is handled by the B process in the next clock cycle.
-- NOTE: The case that both processes acquire the lock at the same time is handled by the B process in the next clock cycle.
-- Get Lock
inst_delete_lock_a_next <= '1';
-- No Instances avialable
-- No Instances available
if (inst_occupied_head = INSTANCE_MEMORY_MAX_ADDRESS) then
inst_addr_base_a_next <= INSTANCE_MEMORY_MAX_ADDRESS;
else
@ -1232,7 +1232,7 @@ begin
if (inst_delete_lock_b = '0') then
-- Get Lock
inst_delete_lock_a_next <= '1';
-- No Instances avialable
-- No Instances available
if (inst_occupied_head = INSTANCE_MEMORY_MAX_ADDRESS) then
inst_addr_base_a_next <= INSTANCE_MEMORY_MAX_ADDRESS;
else

View File

@ -7,7 +7,7 @@ use ieee.numeric_std.all;
package ip_package is
-- TODO : Fix assignemnt of 1 wide array
-- TODO : Fix assignment of 1 wide array
constant LAYER3_PROTOCOL_NUM : integer := 1;
type LAYER3_PROTOCOL_TYPE is array (LAYER3_PROTOCOL_NUM-1 downto 0) of std_logic_vector(7 downto 0);
constant LAYER3_PROTOCOLS : LAYER3_PROTOCOL_TYPE := (0 => x"11");

View File

@ -104,7 +104,7 @@ architecture with_frag of ipv4_in_handler is
constant RAM_ADDR_WIDTH : integer := max(log2c(MAX_PARALLEL_FRAG*MAX_FRAG_SIZE), 14);
--*****TYPE DECLARATION*****
-- FSM states. Explained delow in detail
-- FSM states. Explained below in detail
type PARSER_STAGE_TYPE is (IPv4_INIT, IPv4_HEADER_1, IPv4_HEADER_2, IPv4_HEADER_3, IPv4_HEADER_4,
IPv4_HEADER_5, IPv4_PAYLOAD_LENGTH, IPv4_PAYLOAD, IPv4_FRAGMENT_PRE, IPv4_FRAGMENT,
IPv4_FRAGMENT_POST, IPv4_BUFFER_SRC, IPv4_BUFFER_DEST, IPv4_BUFFER_LENGTH, IPv4_BUFFER_PAYLOAD,
@ -120,7 +120,7 @@ architecture with_frag of ipv4_in_handler is
type BUFFER_ADDR_OFFSET_TYPE is array (MAX_PARALLEL_FRAG-1 downto 0) of unsigned(RAM_ADDR_WIDTH-1 downto 0);
-- Array of packet sizes in buffers
type FRAG_SIZE_ARRAY is array (MAX_PARALLEL_FRAG-1 downto 0) of std_logic_vector(13 downto 0);
-- Array of 32-bit buffer word counters. Used for counting new received fragments and determining if the packet is completely re-assebled
-- Array of 32-bit buffer word counters. Used for counting new received fragments and determining if the packet is completely re-assembled
type BUFFER_WORD_COUNTER_ARRAY is array (MAX_PARALLEL_FRAG-1 downto 0) of integer range 0 to (MAX_FRAG_SIZE/4);
@ -183,7 +183,7 @@ architecture with_frag of ipv4_in_handler is
signal buffer_addr_old, buffer_addr_old_next : unsigned(RAM_ADDR_WIDTH-1 downto 0);
--*****ALIAS DEFINATION*****
--*****ALIAS DEFINITION*****
--IPv4 HEADER
alias ip_version : std_logic_vector(3 downto 0) is data_in(31 downto 28);
alias ip_ihl : std_logic_vector(3 downto 0) is data_in(27 downto 24);
@ -292,7 +292,7 @@ begin
end process;
-- Main State Machine
-- STATE DESCRIPSION
-- STATE DESCRIPTION
-- IPv4_INIT Initial and idle state. Responsible for checking the buffer timers, and reading the packet length from the input FIFO
-- IPv4_HEADER_1 Parsing first word of IPv4 HEADER
-- IPv4_HEADER_2 Parsing second word of IPv4 HEADER
@ -301,7 +301,7 @@ begin
-- IPv4_HEADER_5 Parsing fifth word of IPv4 HEADER and writing DEST Addr to output FIFO (if not a fragment)
-- IPv4_PAYLOAD_LENGTH Writing packet(payload) length to output FIFO
-- IPv4_PAYLOAD Writing of packet(payload) from input FIFO to output FIFO
-- IPv4_FRAGMENT_PRE Fragment pre-processing. Checking if fragment is part of already initiated packet re-assembly, initiating new packetre-assembly, or dropping packet if no resources available
-- IPv4_FRAGMENT_PRE Fragment pre-processing. Checking if fragment is part of already initiated packet re-assembly, initiating new packet re-assembly, or dropping packet if no resources available
-- IPv4_FRAGMENT Writing fragment from input FIFO to RAM buffer
-- IPv4_FRAGMENT_POST Fragment post-processing. Checking if received fragment completes the re-assembled packet.
-- IPv4_BUFFER_SRC Writing re-assembled packet(payload) SRC Address to output FIFO
@ -369,7 +369,7 @@ begin
when IPv4_HEADER_1 =>
if (empty = '0') then
rd_sig <= '1';
-- Wrong IP Version or Packet Length missmatch, skip packet
-- Wrong IP Version or Packet Length mismatch, skip packet
if (ip_version /= "0100" or normalize_length(ip_length) /= std_logic_vector(packet_length)) then
stage_next <= SKIP_PACKET;
-- Store data and continue Parsing
@ -382,7 +382,7 @@ begin
when IPv4_HEADER_2 =>
if (empty = '0') then
rd_sig <= '1';
-- No fragmentation, continue parsing normaly
-- No fragmentation, continue parsing normally
if (ip_MF_flag = '0' and ip_frag_offset = (ip_frag_offset'reverse_range => '0')) then
stage_next <= IPv4_HEADER_3;
-- IP Fragmentation
@ -528,7 +528,7 @@ begin
reset_buffer_timer_id <= tmp;
-- Reset Maximum Fragment Size
frag_size_next(tmp) <= (others => '0');
-- Reset fragment word cntouer
-- Reset fragment word counter
buffer_word_cnt_next(tmp) <= 0;
-- Calculate buffer address
tmp_frag_offset := (others => '0');
@ -779,7 +779,7 @@ architecture no_frag of ipv4_in_handler is
--*****TYPE DECLARATION*****
-- FSM states. Explained delow in detail
-- FSM states. Explained below in detail
type PARSER_STAGE_TYPE is (IPv4_INIT, IPv4_HEADER_1, IPv4_HEADER_2, IPv4_HEADER_3, IPv4_HEADER_4,
IPv4_HEADER_5, IPv4_PAYLOAD_LENGTH, IPv4_PAYLOAD, SKIP_HEADER, SKIP_PACKET);
@ -803,7 +803,7 @@ architecture no_frag of ipv4_in_handler is
-- Intermediate output signal, and its 1 clk cycle delayed variant
signal wr_sig : std_logic;
--*****ALIAS DEFINATION*****
--*****ALIAS DEFINITION*****
--IPv4 HEADER
alias ip_version : std_logic_vector(3 downto 0) is data_in(31 downto 28);
alias ip_ihl : std_logic_vector(3 downto 0) is data_in(27 downto 24);
@ -844,7 +844,7 @@ begin
end process;
-- Main State Machine
-- STATE DESCRIPSION
-- STATE DESCRIPTION
-- IPv4_INIT Initial and idle state. Responsible for checking the buffer timers, and reading the packet length from the input FIFO
-- IPv4_HEADER_1 Parsing first word of IPv4 HEADER
-- IPv4_HEADER_2 Parsing second word of IPv4 HEADER
@ -885,7 +885,7 @@ begin
when IPv4_HEADER_1 =>
if (empty = '0') then
rd_sig <= '1';
-- Wrong IP Version or Packet Length missmatch, skip packet
-- Wrong IP Version or Packet Length mismatch, skip packet
if (ip_version /= "0100" or normalize_length(ip_length) /= std_logic_vector(packet_length)) then
stage_next <= SKIP_PACKET;
-- Store data and continue Parsing
@ -898,7 +898,7 @@ begin
when IPv4_HEADER_2 =>
if (empty = '0') then
rd_sig <= '1';
-- No fragmentation, continue parsing normaly
-- No fragmentation, continue parsing normally
if (ip_MF_flag = '0' and ip_frag_offset = (ip_frag_offset'reverse_range => '0')) then
stage_next <= IPv4_HEADER_3;
-- IP Fragmentation

View File

@ -28,7 +28,7 @@ entity key_holder is
data_in : in std_logic_vector(WORD_WIDTH-1 downto 0);
last_word_in : in std_logic;
-- OUTPUT
ready_out : in std_logic;
ready_out : in std_logic;
valid_out : out std_logic;
data_out : out std_logic_vector(WORD_WIDTH-1 downto 0);
last_word_out : out std_logic

View File

@ -12,7 +12,7 @@ package math_pkg is
-- returns the minimum of the two operands
function min(constant value1, value2 : in integer) return integer;
function round_div(constant divident, divisor : in integer) return integer;
function round_div(constant dividend, divisor : in integer) return integer;
end package;
@ -72,11 +72,11 @@ package body math_pkg is
end function;
-- TODO: Rename to ceil_div, since we do not actually round
function round_div(constant divident, divisor : in integer) return integer is
function round_div(constant dividend, divisor : in integer) return integer is
variable ret : integer;
begin
ret := divident / divisor;
if (divident mod divisor /= 0) then
ret := dividend / divisor;
if (dividend mod divisor /= 0) then
ret := ret + 1;
end if;
return ret;

87
src/moving_average.vhd Normal file
View File

@ -0,0 +1,87 @@
-- 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;
use work.math_pkg.all;
entity moving_average is
generic(
WINDOW_SIZE : natural := 2; -- Must be Power of Two
DATA_WIDTH : natural := 32;
ENABLE_ROUNDING : boolean := true
);
port(
-- SYSTEM
clk : in std_logic;
reset : in std_logic;
enable : in std_logic;
data_in : in std_logic_vector(DATA_WIDTH-1 downto 0);
average : out std_logic_vector(DATA_WIDTH-1 downto 0);
overflow : out std_logic
);
end entity;
architecture arch of moving_average is
signal read_sig : std_logic;
signal fifo_out : std_logic_vector(DATA_WIDTH-1 downto 0);
signal accumulator : unsigned(DATA_WIDTH downto 0);
signal fifo_full : std_logic;
begin
fifo_inst : configuration work.FWFT_FIFO_cfg
generic map (
FIFO_DEPTH => WINDOW_SIZE,
DATA_WIDTH => DATA_WIDTH
)
port map (
clk => clk,
reset => reset,
data_in => data_in,
write => enable,
read => read_sig,
data_out => fifo_out,
empty => open,
full => fifo_full,
free => open
);
-- Keep FIFO in a full state
read_sig <= '1' when (enable = '1' and fifo_full = '1') else '0';
main_prc : process(clk)
begin
if rising_edge(clk) then
if (reset = '1') then
accumulator <= (others => '0');
overflow <= '0';
else
-- Overflow Latch
if (accumulator(DATA_WIDTH) = '1') then
overflow <= '1';
end if;
if (enable = '1') then
if (fifo_full = '1') then
accumulator <= accumulator + unsigned("0" & data_in) - unsigned("0" & fifo_out);
else
accumulator <= accumulator + unsigned("0" & data_in);
end if;
end if;
end if;
end if;
end process;
average_prc: process(all)
begin
if (ENABLE_ROUNDING and accumulator(log2c(WINDOW_SIZE)-1) = '1') then
average <= std_logic_vector(((log2c(WINDOW_SIZE)-1 downto 0 => '0') & accumulator(DATA_WIDTH-1 downto log2c(WINDOW_SIZE))) + 1);
else
average <= std_logic_vector(((log2c(WINDOW_SIZE)-1 downto 0 => '0') & accumulator(DATA_WIDTH-1 downto log2c(WINDOW_SIZE))));
end if;
end process;
end architecture;

View File

@ -0,0 +1,104 @@
-- 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;
entity moving_average_wrapper is
generic(
INNER_WINDOW_SIZE : natural := 8192; -- Must be Power of Two
OUTER_WINDOW_SIZE : natural := 8192;
DATA_WIDTH : natural := 32;
ENABLE_ROUNDING : boolean := true
);
port(
-- SYSTEM
clk : in std_logic;
reset : in std_logic;
data_in : in std_logic_vector(DATA_WIDTH-1 downto 0);
average : out std_logic_vector(DATA_WIDTH-1 downto 0);
trigger : out std_logic;
overflow : out std_logic
);
end entity;
architecture arch of moving_average_wrapper is
signal inner_cnt : natural range 0 to INNER_WINDOW_SIZE;
signal outer_cnt : natural range 0 to OUTER_WINDOW_SIZE;
signal inner_out : std_logic_vector(DATA_WIDTH-1 downto 0);
signal inner_overflow : std_logic;
signal outer_overflow : std_logic;
signal inner_trigger : std_logic;
signal outer_trigger : std_logic;
begin
overflow <= inner_overflow or outer_overflow;
inner_average_inst : entity work.moving_average
generic map(
WINDOW_SIZE => INNER_WINDOW_SIZE,
DATA_WIDTH => DATA_WIDTH,
ENABLE_ROUNDING => ENABLE_ROUNDING
)
port map
(
clk => clk,
reset => reset,
enable => '1',
data_in => data_in,
average => inner_out,
overflow => inner_overflow
);
outer_average_inst : entity work.moving_average
generic map(
WINDOW_SIZE => OUTER_WINDOW_SIZE,
DATA_WIDTH => DATA_WIDTH,
ENABLE_ROUNDING => ENABLE_ROUNDING
)
port map
(
clk => clk,
reset => reset,
enable => inner_trigger,
data_in => inner_out,
average => average,
overflow => outer_overflow
);
main_prc : process(clk)
begin
if rising_edge(clk) then
if (reset = '1') then
inner_cnt <= 0;
outer_cnt <= 0;
inner_trigger <= '0';
outer_trigger <= '0';
else
-- DEFAULT
inner_trigger <= '0';
outer_trigger <= '0';
trigger <= outer_trigger;
if (inner_cnt = INNER_WINDOW_SIZE-1) then
inner_cnt <= 0;
inner_trigger <= '1';
if (outer_cnt = OUTER_WINDOW_SIZE-1) then
outer_cnt <= 0;
outer_trigger <= '1';
else
outer_cnt <= outer_cnt + 1;
end if;
else
inner_cnt <= inner_cnt + 1;
end if;
end if;
end if;
end process;
end architecture;

View File

@ -4,9 +4,9 @@ PUBLISH/SUBSCRIBE
GENERAL
=======
The wrapper Entities that define and implement the ROS Publisher and Subscriber - named <TOPICNAME>_ros_pub
and <TOPICNAME>_ros_sub - are basically carbon copies of a normal <TYPENAME>_reader_interface and
<TYPENAME>_writer_interface, with the exception of hiding all the user facing DDS signals and being
The wrapper Entities that define and implement the ROS Publisher and Subscriber - named <MESSAGENAME>_ros_pub
and <MESSAGENAME>_ros_sub - are basically carbon copies of a normal <TYPENAME>_reader_interface and
<TYPENAME>_writer_interface, with the exception of hiding all the user facing DDS signals and being
responsible for interacting with the DDS entity directly.
All these changes are static for all ROS messages, and the actual message dependent VHDL generation is the
same, as the RTPS IDL interface generation.
@ -21,20 +21,20 @@ The Service VHDL generation closely follows the general RTPS IDL interface gener
For each Service (i.e. .srv File) two files are generated, a server (called <SERVICENAME>_ros_srv_server)
and a client (called <SERVICENAME>_ros_srv_client) file.
Each file contains both encoding and decoding functionality (similar to the key_holder entities).
The files also contain extra logic that may be necessary to parse the SERVICE_OVERHEAD_BYTES that may be
The files also contain extra logic that may be necessary to parse the ROS_SERVICE_OVERHEAD_BYTES that may be
present in the payload.
The code generation follows the normal code generation for encoding and decoding with following changes:
* Encoding and Decoding stages get a "RQ_"or "RR_" prepended to the <NAME> to differentiate between
* Encoding and Decoding stages get a "RQ_" or "RR_" prefixed to the <NAME> to differentiate between
Request and Response message members, respectively.
e.g. GET_A -> GET_RQ_A, WRITE_SUM -> WRITE_RR_SUM
* Similar to the previous point, the <SERVICENAME>_package differentiates the MAX_* sizes of the Request
* Similar to the previous point, the <SERVICENAME>_package differentiates the MAX_* sizes of the Request
and Response message members.
e.g. MAX_A_SIZE -> MAX_RQ_A_SIZE, MAX_SUM_SIZE -> MAX_RR_SUM_SIZE
* The <SERVICENAME>_package calculates both a maximum request and response message size, named
* The <SERVICENAME>_package calculates both a maximum request and response message size, named
MAX_<SERVICENAME>_RQ_SIZE and MAX_<SERVICENAME>_RR_SIZE, respectively.
The maximum includes the service overhead bytes that are contained in the DDS Payloads. The constant
SERVICE_OVERHEAD_BYTES from ros_package gives this overhead bytes.
The maximum includes the service overhead bytes that are contained in the DDS Payloads. The constant
ROS_SERVICE_OVERHEAD_BYTES from ros_package gives this overhead bytes.
ACTION
@ -55,53 +55,53 @@ For each Action (i.e. .action File) 8 files are generated:
<ACTIONNAME>_ros_action_server (Action server)
<ACTIONNAME>_ros_action_client (Action client)
The GOAL and RESULT serrvice files are similar to normal ROS Service files generation, with the addition
The GOAL and RESULT service files are similar to normal ROS Service files generation, with the addition
of static logic responsible for encoding/decoding static parts of the action messages.
Similarly the FEEDBACK publsiher/subscriber files is also similar to normal ROS publisher/subscriber files,
Similarly the FEEDBACK publisher/subscriber files are also similar to normal ROS publisher/subscriber files,
with the addition of static logic responsible for encoding/decoding static parts of the action messages.
ACTION SERVER
-------------
The ROS Action server is responsible for storing up to MAX_GOALS results.
This is achieved by storing results in memories of MAX_GOALS depth.
The ros_action_server entity contains the ROS action server logic, where as all the memories responsible
The ros_action_server entity contains the ROS action server logic, whereas all the memories responsible
for storing the results reside in <ACTIONNAME>_ros_action_server.
The <ACTIONNAME>_ros_action_server contains a FSM responsible for fetching the requested RESULT on demand,
which is communcated from ros_action_server via the r_index, r_sel, and r_sel_ack signals.
which is communicated from ros_action_server via the r_index, r_sel, and r_sel_ack signals.
In the IDLE stage, similar to the normal code generation, the memory signals are directly driven by the
user facing port signals, allowing the user to write the RESULT. The 'index_result' signal is used to index
user facing port signals, allowing the user to write the RESULT. The 'result_addr' signal is used to index
the (outer) memories.
If r_sel is '1', the FETCH_RESULT stage is entered, which is responsible for fetching the correct RESULT.
The FETCH_RESULT stage is split into 2 sub-stages, a GET and a READ sub-stage. The GET sub-stage is waiting
The FETCH_RESULT stage is split into 2 sub-stages, a GET and a READ sub-stage. The GET sub-stage is waiting
for all memories to be ready (ANDing the ready_in signals) before toggling the valid_in signal to initiate
the memory read operation and proceeding to th next sub-stage. The READ sub-stage is waiting for all
the memory read operation and proceeding to the next sub-stage. The READ sub-stage is waiting for all
memory read operations to finish (ANDing the valid_out signals) before proceeding to the next stage.
If the RESULT contains collections, they have to be manually pushed to the
If the RESULT contains collections, they have to be manually pushed to the
<ACTIONNAME>_ros_action_result_srv_server. In that case the next stage is a stage called PUSH_<COLLECTIONNAME>,
which, similar to the normal code generation of a collection in a writer_interface, has 2 sub-stages
which, similar to the normal code generation of a collection in a writer_interface, has 2 sub-stages
(GET, WRITE). The difference is that the second sub-stage (WRITE) is not only waiting on the valid_out
signal of the memory, but also on the respective ready port signal of the
signal of the memory, but also on the respective ready port signal of the
<ACTIONNAME>_ros_action_result_srv_server.
Once the RESULT is ready and available on the <ACTIONNAME>_ros_action_result_srv_server, the PASSTHROUGH
stage is entered. In this stage the r_sel_ack signal is toggled, signaling to the ros_action_server that
it can continue its operations. The stage is held until the r_sel goes low, in which case the IDLE stage
it can continue its operations. The stage is held until the r_sel goes low, in which case the IDLE stage
is resumed.
If r_index is equal to MAX_GOALS, it is treated as a special value, in which the RESULT is empty/don't care.
If that is the case the PASSTHROUGH stage is taken directly (since we don't have to fetch any particular
result from the memories), and a empty RESULT is made available to the
If that is the case the PASSTHROUGH stage is taken directly (since we don't have to fetch any particular
result from the memories), and a empty RESULT is made available to the
<ACTIONNAME>_ros_action_result_srv_server.
If ENABLE_FEEDBACK is '0', no ROS publisher for the FEEDBACK is generated, and the FEEDBACK output ports
If ENABLE_FEEDBACK is '0', no ROS publisher for the FEEDBACK is generated, and the FEEDBACK output ports
have to manually be set to default values.
NOTE: If the RESULT contains a collection, the read port signals of the
NOTE: If the RESULT contains a collection, the read port signals of the
<ACTIONNAME>_ros_action_result_srv_server are not needed, and can be hardwired to defaults
(*_ren = '0', *_valid = open, *_ack = '1', *_r = open)
ACTION CLIENT
-------------
The <ACTIONNAME>_ros_action_client contains a FSM responsible for interfacing all the underlying service
clients and subscribers. Since this state machine is static, only the port connection of the
The <ACTIONNAME>_ros_action_client contains a FSM responsible for interfacing all the underlying service
clients and subscribers. Since this state machine is static, only the port connection of the
instantiated entities has to be generated.
Similarly to the action server, if ENABLE_FEEDBACK is '0', the FEEDBACK output ports have to manually be
set to default values.
Similarly to the action server, if ENABLE_FEEDBACK is '0', the FEEDBACK output ports have to manually be
set to default values.

View File

@ -12,7 +12,7 @@ use work.GoalStatus_package;
use work.GoalStatusArray_package;
use work.CancelGoal_package;
entity Fibonacci_ros_action_client is
entity TEMPLATE_ros_action_client is
generic (
ENABLE_FEEDBACK : std_logic := '1';
LITTLE_ENDIAN : std_logic := '0'
@ -212,7 +212,7 @@ entity Fibonacci_ros_action_client is
);
end entity;
architecture arch of Fibonacci_ros_action_client is
architecture arch of TEMPLATE_ros_action_client is
--*****TYPE DECLARATION*****
type STAGE_TYPE is (IDLE,SEND_GOAL_REQUEST,TAKE_GOAL_RESPONSE,SEND_RESULT_REQUEST,TAKE_RESULT_RESPONSE,SEND_CANCEL_REQUEST,TAKE_CANCEL_RESPONSE,TAKE_FEEDBACK,RETURN_ROS);
@ -222,8 +222,8 @@ architecture arch of Fibonacci_ros_action_client is
signal cnt, cnt_next : natural range 0 to 5;
signal g_start_user, r_start_user, c_start_user, g_ack_user, r_ack_user, c_ack_user, g_taken_user, r_taken_user, c_taken_user, g_done_user, r_done_user, c_done_user : std_logic;
signal g_opcode_user, r_opcode_user, c_opcode_user : ROS_SERVICE_OPCODE_TYPE;
signal g_service_info_user, r_service_info_user, c_service_info_user : SERVICE_INFO_TYPE;
signal g_sequence_id_user, r_sequence_id_user, c_sequence_id_user : std_logic_vector(ROS_SEQUENCE_ID_WIDTH-1 downto 0);
signal g_service_info_user, r_service_info_user, c_service_info_user, service_info_sig, service_info_sig_next : SERVICE_INFO_TYPE;
signal g_sequence_id_user, r_sequence_id_user, c_sequence_id_user, sequence_id_sig, sequence_id_sig_next : std_logic_vector(ROS_SEQUENCE_ID_WIDTH-1 downto 0);
signal g_return_code_user, r_return_code_user, c_return_code_user : std_logic_vector(ROS_RETCODE_WIDTH-1 downto 0);
signal f_start_user, f_ack_user, f_done_user, f_taken_user : std_logic;
@ -237,7 +237,7 @@ architecture arch of Fibonacci_ros_action_client is
begin
goal_srv_client_inst : entity work.Fibonacci_ros_action_goal_srv_client(arch)
goal_srv_client_inst : entity work.TEMPLATE_ros_action_goal_srv_client(arch)
generic map (
LITTLE_ENDIAN => LITTLE_ENDIAN
)
@ -301,7 +301,7 @@ begin
goal_stamp <= to_ROS_TIME(goal_stamp_sig);
result_srv_client_inst : entity work.Fibonacci_ros_action_result_srv_client(arch)
result_srv_client_inst : entity work.TEMPLATE_ros_action_result_srv_client(arch)
generic map (
LITTLE_ENDIAN => LITTLE_ENDIAN
)
@ -430,7 +430,7 @@ begin
);
feedback_gen : if ENABLE_FEEDBACK = '1' generate
feedback_sub_inst : entity work.Fibonacci_ros_action_feedback_sub(arch)
feedback_sub_inst : entity work.TEMPLATE_ros_action_feedback_sub(arch)
port map (
clk => clk,
reset => reset,
@ -489,6 +489,8 @@ begin
-- ###GENERATED END###
end generate;
sequence_id <= sequence_id_sig;
service_info <= service_info_sig;
main_prc : process(all)
begin
@ -496,6 +498,8 @@ begin
stage_next <= stage;
cnt_next <= cnt;
return_code_latch_next <= return_code_latch;
sequence_id_sig_next <= sequence_id_sig;
service_info_sig_next <= service_info_sig;
-- DEFAULT Unregistered
f_start_user <= '0';
f_opcode_user <= NOP;
@ -505,8 +509,6 @@ begin
g_opcode_user <= NOP;
c_start_user <= '0';
c_opcode_user <= NOP;
sequence_id <= (others => '0');
service_info <= EMPTY_SERVICE_INFO;
ack <= '0';
done <= '0';
return_code <= ROS_RET_OK;
@ -560,9 +562,9 @@ begin
end if;
-- Wait for Subscriber
when 1 =>
sequence_id <= g_sequence_id_user;
done <= g_done_user;
return_code <= g_return_code_user;
sequence_id_sig_next <= g_sequence_id_user;
done <= g_done_user;
return_code <= g_return_code_user;
if (g_done_user = '1') then
-- DONE
@ -583,12 +585,12 @@ begin
end if;
-- Wait for Subscriber
when 1 =>
service_info <= g_service_info_user;
return_code <= g_return_code_user;
service_info_sig_next <= g_service_info_user;
if (g_done_user = '1') then
if (g_taken_user = '1') then
done <= g_done_user;
return_code <= g_return_code_user;
stage_next <= IDLE;
else
return_code_latch_next <= ROS_RET_ACTION_CLIENT_TAKE_FAILED;
@ -610,9 +612,9 @@ begin
end if;
-- Wait for Subscriber
when 1 =>
sequence_id <= r_sequence_id_user;
done <= r_done_user;
return_code <= r_return_code_user;
sequence_id_sig_next <= r_sequence_id_user;
done <= r_done_user;
return_code <= r_return_code_user;
if (r_done_user = '1') then
-- DONE
@ -633,12 +635,12 @@ begin
end if;
-- Wait for Subscriber
when 1 =>
service_info <= r_service_info_user;
return_code <= r_return_code_user;
service_info_sig_next <= r_service_info_user;
if (r_done_user = '1') then
if (r_taken_user = '1') then
done <= r_done_user;
return_code <= r_return_code_user;
stage_next <= IDLE;
else
return_code_latch_next <= ROS_RET_ACTION_CLIENT_TAKE_FAILED;
@ -660,9 +662,9 @@ begin
end if;
-- Wait for Subscriber
when 1 =>
sequence_id <= c_sequence_id_user;
done <= c_done_user;
return_code <= c_return_code_user;
sequence_id_sig_next <= c_sequence_id_user;
done <= c_done_user;
return_code <= c_return_code_user;
if (c_done_user = '1') then
-- DONE
@ -683,12 +685,12 @@ begin
end if;
-- Wait for Subscriber
when 1 =>
service_info <= c_service_info_user;
return_code <= c_return_code_user;
service_info_sig_next <= c_service_info_user;
if (c_done_user = '1') then
if (c_taken_user = '1') then
done <= c_done_user;
return_code <= c_return_code_user;
stage_next <= IDLE;
else
return_code_latch_next <= ROS_RET_ACTION_CLIENT_TAKE_FAILED;
@ -740,10 +742,14 @@ begin
stage <= IDLE;
cnt <= 0;
return_code_latch <= ROS_RET_OK;
sequence_id_sig <= (others => '0');
service_info_sig <= EMPTY_SERVICE_INFO;
else
stage <= stage_next;
cnt <= cnt_next;
return_code_latch <= return_code_latch_next;
sequence_id_sig <= sequence_id_sig_next;
service_info_sig <= service_info_sig_next;
end if;
end if;
end process;

View File

@ -201,7 +201,7 @@ begin
-- ###GENERATED END###
-- Last Word Latch Setter
if (last_word_in_r = '1') then
if (last_word_in_r = '1' and valid_in_r = '1') then
last_word_in_latch_next <= '1';
end if;
-- Data Available Setter
@ -289,7 +289,7 @@ begin
when CDR_BE =>
endian_flag_next <= '0';
stage_next <= FETCH;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
decode_stage_next <= GET_RID_WGUID;
cnt_next <= 0;
@ -297,7 +297,7 @@ begin
when CDR_LE =>
endian_flag_next <= '1';
stage_next <= FETCH;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
decode_stage_next <= GET_RID_WGUID;
cnt_next <= 0;
@ -344,7 +344,7 @@ begin
-- };
-- 'seq' is set by a counter that is incremented on each "send_request".
-- 'guid' is set to the publication handle of the request writer of the service client.
-- Note that the publication handle is useless for the server, since it is only meanigful localy (i.e. only the client can do something with it)
-- Note that the publication handle is useless for the server, since it is only meaningful locally (i.e. only the client can do something with it)
-- Nevertheless the same 'guid' has to be returned to the client.
when GET_RID_WGUID =>
-- ALIGN GUARD
@ -417,7 +417,7 @@ begin
end if;
end if;
when GET_RR_STAMP =>
-- We intepret the TIME as a double word for efficiency
-- We interpret the TIME as a double word for efficiency
-- ALIGN GUARD
if (not check_align(align_offset, ALIGN_4)) then
target_align_next <= ALIGN_4;
@ -462,7 +462,7 @@ begin
stage_next <= FETCH;
decode_stage_next <= return_stage;
cnt_next <= 0;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- Optional omitted
@ -472,7 +472,7 @@ begin
optional_next <= '1';
end if;
end if;
-- eMemberHeader
-- eMemberHeader
when 1 =>
-- Ignore Parameter ID
cnt_next <= cnt + 1;
@ -482,7 +482,7 @@ begin
stage_next <= FETCH;
decode_stage_next <= return_stage;
cnt_next <= 0;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- Optional omitted
@ -534,7 +534,7 @@ begin
-- Output Guard
if (ready_out_w = '1') then
stage_next <= ENCODE_PAYLOAD;
-- Reset
-- Reset
align_offset_next <= (others => '0');
data_out_latch_next <= (others => '0');
encode_stage_next <= WRITE_RID_WGUID;
@ -597,7 +597,7 @@ begin
align_offset_next <= align_offset + 8;
encode_stage_next <= WRITE_RID_SN;
cnt_next <= 0;
when others =>
when others =>
end case;
end if;
when WRITE_RID_SN =>
@ -616,11 +616,11 @@ begin
stage_next <= PUSH;
align_offset_next <= align_offset + 8;
encode_stage_next <= WRITE_RQ_GOAL_ID;
when others =>
when others =>
end case;
end if;
when WRITE_RQ_GOAL_ID =>
-- Special Encoding for effieciency (Prevent having to define memory for UUID)
-- Special Encoding for efficiency (Prevent having to define memory for UUID)
-- ALIGN GUARD
if (not check_align(align_offset, ALIGN_1)) then
target_align_next <= ALIGN_1;
@ -698,7 +698,7 @@ begin
sequence_id_sig <= (others => '0');
return_code_latch <= ROS_RET_OK;
service_info_sig <= EMPTY_SERVICE_INFO;
uuid_cnt <= 0;
uuid_cnt <= 0;
accepted_latch <= '0';
stamp_latch <= (others => '0');
-- ###GENERATED START###

View File

@ -197,7 +197,7 @@ begin
-- ###GENERATED END###
-- Last Word Latch Setter
if (last_word_in_r = '1') then
if (last_word_in_r = '1' and valid_in_r = '1') then
last_word_in_latch_next <= '1';
end if;
-- Data Available Setter
@ -283,7 +283,7 @@ begin
when CDR_BE =>
endian_flag_next <= '0';
stage_next <= FETCH;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
decode_stage_next <= GET_RID_WGUID;
cnt_next <= 0;
@ -291,7 +291,7 @@ begin
when CDR_LE =>
endian_flag_next <= '1';
stage_next <= FETCH;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
decode_stage_next <= GET_RID_WGUID;
cnt_next <= 0;
@ -338,7 +338,7 @@ begin
-- };
-- 'seq' is set by a counter that is incremented on each "send_request".
-- 'guid' is set to the publication handle of the request writer of the service client.
-- Note that the publication handle is useless for the server, since it is only meanigful localy (i.e. only the client can do something with it)
-- Note that the publication handle is useless for the server, since it is only meaningful locally (i.e. only the client can do something with it)
-- Nevertheless the same 'guid' has to be returned to the client.
when GET_RID_WGUID =>
-- ALIGN GUARD
@ -396,12 +396,12 @@ begin
end case;
end if;
when GET_RQ_GOAL_ID =>
-- Special Decoding for effieciency (Prevent having to define memory for UUID)
-- Special Decoding for efficiency (Prevent having to define memory for UUID)
-- ALIGN GUARD
if (not check_align(align_offset, ALIGN_1)) then
target_align_next <= ALIGN_1;
stage_next <= ALIGN_IN_STREAM;
else
else
goal_id_latch_next <= write_sub_vector(goal_id_latch, get_sub_vector(data_in_latch, to_integer(align_offset(1 downto 0)), CDR_INT8_WIDTH, TRUE), uuid_cnt, TRUE);
align_offset_next <= align_offset + 1;
@ -440,7 +440,7 @@ begin
stage_next <= FETCH;
decode_stage_next <= return_stage;
cnt_next <= 0;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- Optional omitted
@ -450,7 +450,7 @@ begin
optional_next <= '1';
end if;
end if;
-- eMemberHeader
-- eMemberHeader
when 1 =>
-- Ignore Parameter ID
cnt_next <= cnt + 1;
@ -460,7 +460,7 @@ begin
stage_next <= FETCH;
decode_stage_next <= return_stage;
cnt_next <= 0;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- Optional omitted
@ -512,7 +512,7 @@ begin
-- Output Guard
if (ready_out_w = '1') then
stage_next <= ENCODE_PAYLOAD;
-- Reset
-- Reset
align_offset_next <= (others => '0');
data_out_latch_next <= (others => '0');
encode_stage_next <= WRITE_RID_WGUID;
@ -575,7 +575,7 @@ begin
align_offset_next <= align_offset + 8;
encode_stage_next <= WRITE_RID_SN;
cnt_next <= 0;
when others =>
when others =>
end case;
end if;
when WRITE_RID_SN =>
@ -594,7 +594,7 @@ begin
stage_next <= PUSH;
align_offset_next <= align_offset + 8;
encode_stage_next <= WRITE_RR_ACCEPTED;
when others =>
when others =>
end case;
end if;
when WRITE_RR_ACCEPTED =>
@ -615,7 +615,7 @@ begin
end if;
end if;
when WRITE_RR_STAMP =>
-- We intepret the TIME as a double word for efficiency
-- We interpret the TIME as a double word for efficiency
-- ALIGN GUARD
if (not check_align(align_offset, ALIGN_4)) then
target_align_next <= ALIGN_4;
@ -635,7 +635,7 @@ begin
-- DONE
stage_next <= PUSH;
finalize_payload_next <= '1';
when others =>
when others =>
end case;
end if;
when others =>

View File

@ -197,7 +197,7 @@ begin
-- ###GENERATED END###
-- Last Word Latch Setter
if (last_word_in_r = '1') then
if (last_word_in_r = '1' and valid_in_r = '1') then
last_word_in_latch_next <= '1';
end if;
-- Data Available Setter
@ -285,7 +285,7 @@ begin
when CDR_BE =>
endian_flag_next <= '0';
stage_next <= FETCH;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
decode_stage_next <= GET_RID_WGUID;
cnt_next <= 0;
@ -293,7 +293,7 @@ begin
when CDR_LE =>
endian_flag_next <= '1';
stage_next <= FETCH;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
decode_stage_next <= GET_RID_WGUID;
cnt_next <= 0;
@ -340,7 +340,7 @@ begin
-- };
-- 'seq' is set by a counter that is incremented on each "send_request".
-- 'guid' is set to the publication handle of the request writer of the service client.
-- Note that the publication handle is useless for the server, since it is only meanigful localy (i.e. only the client can do something with it)
-- Note that the publication handle is useless for the server, since it is only meaningful locally (i.e. only the client can do something with it)
-- Nevertheless the same 'guid' has to be returned to the client.
when GET_RID_WGUID =>
-- ALIGN GUARD
@ -434,7 +434,7 @@ begin
stage_next <= FETCH;
decode_stage_next <= return_stage;
cnt_next <= 0;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- Optional omitted
@ -444,7 +444,7 @@ begin
optional_next <= '1';
end if;
end if;
-- eMemberHeader
-- eMemberHeader
when 1 =>
-- Ignore Parameter ID
cnt_next <= cnt + 1;
@ -454,7 +454,7 @@ begin
stage_next <= FETCH;
decode_stage_next <= return_stage;
cnt_next <= 0;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- Optional omitted
@ -506,7 +506,7 @@ begin
-- Output Guard
if (ready_out_w = '1') then
stage_next <= ENCODE_PAYLOAD;
-- Reset
-- Reset
align_offset_next <= (others => '0');
data_out_latch_next <= (others => '0');
encode_stage_next <= WRITE_RID_WGUID;
@ -569,7 +569,7 @@ begin
align_offset_next <= align_offset + 8;
encode_stage_next <= WRITE_RID_SN;
cnt_next <= 0;
when others =>
when others =>
end case;
end if;
when WRITE_RID_SN =>
@ -588,11 +588,11 @@ begin
stage_next <= PUSH;
align_offset_next <= align_offset + 8;
encode_stage_next <= WRITE_RQ_GOAL_ID;
when others =>
when others =>
end case;
end if;
when WRITE_RQ_GOAL_ID =>
-- Special Encoding for effieciency (Prevent having to define memory for UUID)
-- Special Encoding for efficiency (Prevent having to define memory for UUID)
-- ALIGN GUARD
if (not check_align(align_offset, ALIGN_1)) then
target_align_next <= ALIGN_1;

View File

@ -194,7 +194,7 @@ begin
-- ###GENERATED END###
-- Last Word Latch Setter
if (last_word_in_r = '1') then
if (last_word_in_r = '1' and valid_in_r = '1') then
last_word_in_latch_next <= '1';
end if;
-- Data Available Setter
@ -280,7 +280,7 @@ begin
when CDR_BE =>
endian_flag_next <= '0';
stage_next <= FETCH;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
decode_stage_next <= GET_RID_WGUID;
cnt_next <= 0;
@ -288,7 +288,7 @@ begin
when CDR_LE =>
endian_flag_next <= '1';
stage_next <= FETCH;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
decode_stage_next <= GET_RID_WGUID;
cnt_next <= 0;
@ -335,7 +335,7 @@ begin
-- };
-- 'seq' is set by a counter that is incremented on each "send_request".
-- 'guid' is set to the publication handle of the request writer of the service client.
-- Note that the publication handle is useless for the server, since it is only meanigful localy (i.e. only the client can do something with it)
-- Note that the publication handle is useless for the server, since it is only meaningful locally (i.e. only the client can do something with it)
-- Nevertheless the same 'guid' has to be returned to the client.
when GET_RID_WGUID =>
-- ALIGN GUARD
@ -392,12 +392,12 @@ begin
end case;
end if;
when GET_RQ_GOAL_ID =>
-- Special Decoding for effieciency (Prevent having to define memory for UUID)
-- Special Decoding for efficiency (Prevent having to define memory for UUID)
-- ALIGN GUARD
if (not check_align(align_offset, ALIGN_1)) then
target_align_next <= ALIGN_1;
stage_next <= ALIGN_IN_STREAM;
else
else
goal_id_latch_next <= write_sub_vector(goal_id_latch, get_sub_vector(data_in_latch, to_integer(align_offset(1 downto 0)), CDR_INT8_WIDTH, TRUE), uuid_cnt, TRUE);
align_offset_next <= align_offset + 1;
@ -432,7 +432,7 @@ begin
stage_next <= FETCH;
decode_stage_next <= return_stage;
cnt_next <= 0;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- Optional omitted
@ -442,7 +442,7 @@ begin
optional_next <= '1';
end if;
end if;
-- eMemberHeader
-- eMemberHeader
when 1 =>
-- Ignore Parameter ID
cnt_next <= cnt + 1;
@ -452,7 +452,7 @@ begin
stage_next <= FETCH;
decode_stage_next <= return_stage;
cnt_next <= 0;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- Optional omitted
@ -504,7 +504,7 @@ begin
-- Output Guard
if (ready_out_w = '1') then
stage_next <= ENCODE_PAYLOAD;
-- Reset
-- Reset
align_offset_next <= (others => '0');
data_out_latch_next <= (others => '0');
encode_stage_next <= WRITE_RID_WGUID;
@ -567,7 +567,7 @@ begin
align_offset_next <= align_offset + 8;
encode_stage_next <= WRITE_RID_SN;
cnt_next <= 0;
when others =>
when others =>
end case;
end if;
when WRITE_RID_SN =>
@ -586,7 +586,7 @@ begin
stage_next <= PUSH;
align_offset_next <= align_offset + 8;
encode_stage_next <= WRITE_RR_STATUS;
when others =>
when others =>
end case;
end if;
when WRITE_RR_STATUS =>

View File

@ -12,7 +12,7 @@ use work.GoalStatus_package;
use work.GoalStatusArray_package;
use work.CancelGoal_package;
entity Fibonacci_ros_action_server is
entity TEMPLATE_ros_action_server is
generic (
TIMEOUT_DURATION : ROS_DURATION_TYPE;
MAX_GOALS : natural;
@ -221,7 +221,7 @@ entity Fibonacci_ros_action_server is
result_valid : out std_logic;
result_ack : in std_logic;
-- ###GENERATED START###
-- RESULT PORTS (Prepend with result_)
-- RESULT PORTS (Prepend with result_, both _w and _r signals are generated)
-- ###GENERATED END###
-- FEEDBACK SIGNALS
-- ###GENERATED START###
@ -230,7 +230,7 @@ entity Fibonacci_ros_action_server is
);
end entity;
architecture arch of Fibonacci_ros_action_server is
architecture arch of TEMPLATE_ros_action_server is
--*****CONSTANT DECLARATION*****
constant RESULT_INDEX_WIDTH : natural := log2c(MAX_GOALS);
@ -272,13 +272,14 @@ architecture arch of Fibonacci_ros_action_server is
signal s_status_list_goal_info_goal_id_r, s_status_list_goal_info_goal_id_w : std_logic_vector(UUID_WIDTH-1 downto 0);
signal s_status_list_goal_info_stamp_r, s_status_list_goal_info_stamp_w : std_logic_vector(ROS_TIME_WIDTH-1 downto 0);
signal s_status_list_status_r, s_status_list_status_w : std_logic_vector(CDR_INT8_WIDTH-1 downto 0);
signal idle_sig : std_logic := '0'; -- Test signal used in testbenches
-- ###GENERATED START###
-- SIGNAL DECLARATIONS
-- ###GENERATED END###
begin
goal_srv_server_inst : entity work.Fibonacci_ros_action_goal_srv_server(arch)
goal_srv_server_inst : entity work.TEMPLATE_ros_action_goal_srv_server(arch)
generic map (
LITTLE_ENDIAN => LITTLE_ENDIAN
)
@ -340,7 +341,7 @@ begin
return_code_user => g_return_code_user
);
result_srv_server_inst : entity work.Fibonacci_ros_action_result_srv_server(arch)
result_srv_server_inst : entity work.TEMPLATE_ros_action_result_srv_server(arch)
generic map (
LITTLE_ENDIAN => LITTLE_ENDIAN
)
@ -472,7 +473,7 @@ begin
);
feedback_gen : if ENABLE_FEEDBACK = '1' generate
feedback_pub_inst : entity work.Fibonacci_ros_action_feedback_pub(arch)
feedback_pub_inst : entity work.TEMPLATE_ros_action_feedback_pub(arch)
generic map (
LITTLE_ENDIAN => LITTLE_ENDIAN
)
@ -697,13 +698,17 @@ begin
result_ready <= '0';
r_sel_ack <= '0';
abort_mem <= '0';
idle_sig <= '0';
-- ###GENERATED START###
-- DEFAULT SIGNAL ASSIGNMENTS
-- ###GENERATED END###
case (stage) is
when IDLE =>
if (r_sel = '1') then
idle_sig <= '1';
-- ###GENERATED START###
if (r_sel = '1' and TODO_result_ready = '1' and result_ren = '0') then
-- ###GENERATED END###
if (unsigned(r_index) = MAX_GOALS) then
stage_next <= PASSTHROUGH;
else

View File

@ -9,7 +9,7 @@ use work.rtps_package.all;
use work.rtps_config_package.all;
use work.ros_package.all;
entity TEMPLATE_pub is
entity TEMPLATE_ros_pub is
generic (
LITTLE_ENDIAN : std_logic := '0'
);
@ -52,7 +52,7 @@ entity TEMPLATE_pub is
);
end entity;
architecture arch of TEMPLATE_pub is
architecture arch of TEMPLATE_ros_pub is
--*****TYPE DECLARATION*****
-- FSM states. Explained below in detail
@ -109,7 +109,7 @@ begin
opcode_dds <= NOP;
valid_out_dds <= '0';
last_word_out_dds <= '0';
ack_user <= '0';
ack_user <= '0';
done_user <= '0';
return_code_user <= ROS_RET_OK;
data_out_dds <= (others => '0');
@ -159,7 +159,7 @@ begin
-- Output Guard
if (ready_out_dds = '1') then
stage_next <= ENCODE_PAYLOAD;
-- Reset
-- Reset
align_offset_next <= (others => '0');
data_out_latch_next <= (others => '0');
-- ###GENERATED START###
@ -253,7 +253,7 @@ begin
align_offset <= align_offset_next;
data_out_latch <= data_out_latch_next;
-- ###GENERATED START###
-- SYNC SIGNALS
-- SYNC SIGNALS
-- ###GENERATED END###
end if;
end if;

View File

@ -193,7 +193,7 @@ begin
-- ###GENERATED END###
-- Last Word Latch Setter
if (last_word_in_r = '1') then
if (last_word_in_r = '1' and valid_in_r = '1') then
last_word_in_latch_next <= '1';
end if;
-- Data Available Setter
@ -281,7 +281,7 @@ begin
when CDR_BE =>
endian_flag_next <= '0';
stage_next <= FETCH;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
decode_stage_next <= GET_RID_WGUID;
cnt_next <= 0;
@ -289,7 +289,7 @@ begin
when CDR_LE =>
endian_flag_next <= '1';
stage_next <= FETCH;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
decode_stage_next <= GET_RID_WGUID;
cnt_next <= 0;
@ -336,7 +336,7 @@ begin
-- };
-- 'seq' is set by a counter that is incremented on each "send_request".
-- 'guid' is set to the publication handle of the request writer of the service client.
-- Note that the publication handle is useless for the server, since it is only meanigful localy (i.e. only the client can do something with it)
-- Note that the publication handle is useless for the server, since it is only meaningful locally (i.e. only the client can do something with it)
-- Nevertheless the same 'guid' has to be returned to the client.
when GET_RID_WGUID =>
-- ALIGN GUARD
@ -414,7 +414,7 @@ begin
stage_next <= FETCH;
decode_stage_next <= return_stage;
cnt_next <= 0;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- Optional omitted
@ -424,7 +424,7 @@ begin
optional_next <= '1';
end if;
end if;
-- eMemberHeader
-- eMemberHeader
when 1 =>
-- Ignore Parameter ID
cnt_next <= cnt + 1;
@ -434,7 +434,7 @@ begin
stage_next <= FETCH;
decode_stage_next <= return_stage;
cnt_next <= 0;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- Optional omitted
@ -486,7 +486,7 @@ begin
-- Output Guard
if (ready_out_w = '1') then
stage_next <= ENCODE_PAYLOAD;
-- Reset
-- Reset
align_offset_next <= (others => '0');
data_out_latch_next <= (others => '0');
encode_stage_next <= WRITE_RID_WGUID;
@ -549,7 +549,7 @@ begin
align_offset_next <= align_offset + 8;
encode_stage_next <= WRITE_RID_SN;
cnt_next <= 0;
when others =>
when others =>
end case;
end if;
when WRITE_RID_SN =>
@ -570,7 +570,7 @@ begin
-- ###GENERATED START###
encode_stage_next <= TODO;
-- ###GENERATED END###
when others =>
when others =>
end case;
end if;
-- ###GENERATED START###

View File

@ -190,7 +190,7 @@ begin
-- ###GENERATED END###
-- Last Word Latch Setter
if (last_word_in_r = '1') then
if (last_word_in_r = '1' and valid_in_r = '1') then
last_word_in_latch_next <= '1';
end if;
-- Data Available Setter
@ -276,7 +276,7 @@ begin
when CDR_BE =>
endian_flag_next <= '0';
stage_next <= FETCH;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
decode_stage_next <= GET_RID_WGUID;
cnt_next <= 0;
@ -284,7 +284,7 @@ begin
when CDR_LE =>
endian_flag_next <= '1';
stage_next <= FETCH;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
decode_stage_next <= GET_RID_WGUID;
cnt_next <= 0;
@ -331,7 +331,7 @@ begin
-- };
-- 'seq' is set by a counter that is incremented on each "send_request".
-- 'guid' is set to the publication handle of the request writer of the service client.
-- Note that the publication handle is useless for the server, since it is only meanigful localy (i.e. only the client can do something with it)
-- Note that the publication handle is useless for the server, since it is only meaningful locally (i.e. only the client can do something with it)
-- Nevertheless the same 'guid' has to be returned to the client.
when GET_RID_WGUID =>
-- ALIGN GUARD
@ -409,7 +409,7 @@ begin
stage_next <= FETCH;
decode_stage_next <= return_stage;
cnt_next <= 0;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- Optional omitted
@ -419,7 +419,7 @@ begin
optional_next <= '1';
end if;
end if;
-- eMemberHeader
-- eMemberHeader
when 1 =>
-- Ignore Parameter ID
cnt_next <= cnt + 1;
@ -429,7 +429,7 @@ begin
stage_next <= FETCH;
decode_stage_next <= return_stage;
cnt_next <= 0;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- Optional omitted
@ -481,7 +481,7 @@ begin
-- Output Guard
if (ready_out_w = '1') then
stage_next <= ENCODE_PAYLOAD;
-- Reset
-- Reset
align_offset_next <= (others => '0');
data_out_latch_next <= (others => '0');
encode_stage_next <= WRITE_RID_WGUID;
@ -544,7 +544,7 @@ begin
align_offset_next <= align_offset + 8;
encode_stage_next <= WRITE_RID_SN;
cnt_next <= 0;
when others =>
when others =>
end case;
end if;
when WRITE_RID_SN =>
@ -565,7 +565,7 @@ begin
-- ###GENERATED START###
encode_stage_next <= TODO;
-- ###GENERATED END###
when others =>
when others =>
end case;
end if;
-- ###GENERATED START###

View File

@ -9,7 +9,7 @@ use work.rtps_package.all;
use work.rtps_config_package.all;
use work.ros_package.all;
entity TEMPLATE_sub is
entity TEMPLATE_ros_sub is
port (
-- SYSTEM
clk : in std_logic;
@ -55,7 +55,7 @@ entity TEMPLATE_sub is
);
end entity;
architecture arch of TEMPLATE_sub is
architecture arch of TEMPLATE_ros_sub is
--*****TYPE DECLARATION*****
-- FSM states. Explained below in detail
@ -147,7 +147,7 @@ begin
-- ###GENERATED END###
-- Last Word Latch Setter
if (last_word_in_dds = '1') then
if (last_word_in_dds = '1' and valid_in_dds = '1') then
last_word_in_latch_next <= '1';
end if;
-- Data Available Setter
@ -231,7 +231,7 @@ begin
when CDR_BE =>
endian_flag_next <= '0';
stage_next <= FETCH;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- ###GENERATED START###
decode_stage_next <= TODO;
@ -240,7 +240,7 @@ begin
when CDR_LE =>
endian_flag_next <= '1';
stage_next <= FETCH;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- ###GENERATED START###
decode_stage_next <= TODO;
@ -300,7 +300,7 @@ begin
stage_next <= FETCH;
decode_stage_next <= return_stage;
cnt_next <= 0;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- Optional omitted
@ -310,7 +310,7 @@ begin
optional_next <= '1';
end if;
end if;
-- eMemberHeader
-- eMemberHeader
when 1 =>
-- Ignore Parameter ID
cnt_next <= cnt + 1;
@ -320,7 +320,7 @@ begin
stage_next <= FETCH;
decode_stage_next <= return_stage;
cnt_next <= 0;
-- Alignment Reset
-- Alignment Reset
align_offset_next <= (others => '0');
-- Optional omitted

View File

@ -49,7 +49,8 @@ entity Fibonacci is
result_wen : out std_logic;
result_valid : in std_logic;
result_ack : out std_logic;
result_seq_len : out std_logic_vector(R_RR_SEQ_ADDR_WIDTH-1 downto 0);
result_seq_len_r : in std_logic_vector(R_RR_SEQ_ADDR_WIDTH-1 downto 0);
result_seq_len_w : out std_logic_vector(R_RR_SEQ_ADDR_WIDTH-1 downto 0);
result_seq_addr : out std_logic_vector(R_RR_SEQ_ADDR_WIDTH-1 downto 0);
result_seq_ready : in std_logic;
result_seq_ren : out std_logic;
@ -91,7 +92,7 @@ begin
result_ren <= '0';
result_ack <= '0';
feedback_seq_len <= std_logic_vector(i);
result_seq_len <= std_logic_vector(i);
result_seq_len_w <= std_logic_vector(i);
main_prc : process(all)
begin

View File

@ -14,7 +14,7 @@ use work.GoalStatusArray_package;
-- NOTE: Even though this Test instantiates other components, we only (mis-) use them for the memory they instantiate, and thus this Test only tests the uut device (Level 0)
-- This testbench tests the General Behavour of ROS Action Server.
-- This testbench tests the General Behaviour of ROS Action Server.
-- More specifically following tests are done:
-- TEST: NEW GOAL [MEMORY EMPTY]
-- TEST: NEW GOAL [ACCEPT]

View File

@ -14,7 +14,7 @@ use work.GoalStatusArray_package;
-- NOTE: Even though this Test instantiates other components, we only (mis-) use them for the memory they instantiate, and thus this Test only tests the uut device (Level 0)
-- This testbench tests the General Behavour of ROS Action Server.
-- This testbench tests the General Behaviour of ROS Action Server.
-- More specifically following tests are done:
-- TEST: NEW GOAL [MEMORY EMPTY]
-- TEST: NEW GOAL [ACCEPT]

View File

@ -9,9 +9,9 @@ use work.rtps_package.all;
use work.ros_package.all;
use work.rtps_test_package.all;
-- This testbench tests the General Behavour of ROS Services.
-- This testbench tests the General Behaviour of ROS Services.
-- More specifically following tests are done:
-- * Test Unssuported Opcode Operations
-- * Test Unsupported Opcode Operations
-- * Test RETCODE_NO_DATA response from DDS Reader
-- * Test RETCODE_ERROR response from DDS Reader
-- * Test RETCODE_ERROR response from DDS Writer

View File

@ -9,9 +9,9 @@ use work.rtps_package.all;
use work.ros_package.all;
use work.rtps_test_package.all;
-- This testbench tests the General Behavour of ROS Services.
-- This testbench tests the General Behaviour of ROS Services.
-- More specifically following tests are done:
-- * Test Unssuported Opcode Operations
-- * Test Unsupported Opcode Operations
-- * Test RETCODE_NO_DATA response from DDS Reader
-- * Test RETCODE_ERROR response from DDS Reader
-- * Test RETCODE_ERROR response from DDS Writer

View File

@ -10,9 +10,9 @@ use work.ros_package.all;
use work.rtps_test_package.all;
use work.CancelGoal_package.all;
-- This testbench tests the General Behavour of the ROS Services.
-- This testbench tests the General Behaviour of the ROS Services.
-- More specifically following tests are done:
-- * Test Unssuported Opcode Operations
-- * Test Unsupported Opcode Operations
-- * Test RETCODE_NO_DATA response from DDS Reader
-- * Test RETCODE_ERROR response from DDS Reader
-- * Test RETCODE_ERROR response from DDS Writer

View File

@ -10,9 +10,9 @@ use work.ros_package.all;
use work.rtps_test_package.all;
use work.CancelGoal_package.all;
-- This testbench tests the General Behavour of ROS Services.
-- This testbench tests the General Behaviour of ROS Services.
-- More specifically following tests are done:
-- * Test Unssuported Opcode Operations
-- * Test Unsupported Opcode Operations
-- * Test RETCODE_NO_DATA response from DDS Reader
-- * Test RETCODE_ERROR response from DDS Reader
-- * Test RETCODE_ERROR response from DDS Writer

View File

@ -10,9 +10,9 @@ use work.ros_package.all;
use work.rtps_test_package.all;
use work.Fibonacci_package.all;
-- This testbench tests the General Behavour of ROS publishers and subscribers
-- This testbench tests the General Behaviour of ROS publishers and subscribers
-- More specifically following tests are done:
-- * Test Unssuported Opcode Operations
-- * Test Unsupported Opcode Operations
-- * Test RETCODE_NO_DATA response from DDS Reader
-- * Test RETCODE_ERROR response from DDS Reader
-- * Test RETCODE_ERROR response from DDS Writer

View File

@ -10,9 +10,9 @@ use work.ros_package.all;
use work.rtps_test_package.all;
use work.Fibonacci_package.all;
-- This testbench tests the General Behavour of ROS publishers and subscribers
-- This testbench tests the General Behaviour of ROS publishers and subscribers
-- More specifically following tests are done:
-- * Test Unssuported Opcode Operations
-- * Test Unsupported Opcode Operations
-- * Test RETCODE_NO_DATA response from DDS Reader
-- * Test RETCODE_ERROR response from DDS Reader
-- * Test RETCODE_ERROR response from DDS Writer

View File

@ -9,9 +9,9 @@ use work.rtps_package.all;
use work.ros_package.all;
use work.rtps_test_package.all;
-- This testbench tests the General Behavour of ROS Services.
-- This testbench tests the General Behaviour of ROS Services.
-- More specifically following tests are done:
-- * Test Unssuported Opcode Operations
-- * Test Unsupported Opcode Operations
-- * Test RETCODE_NO_DATA response from DDS Reader
-- * Test RETCODE_ERROR response from DDS Reader
-- * Test RETCODE_ERROR response from DDS Writer

View File

@ -9,9 +9,9 @@ use work.rtps_package.all;
use work.ros_package.all;
use work.rtps_test_package.all;
-- This testbench tests the General Behavour of ROS Services.
-- This testbench tests the General Behaviour of ROS Services.
-- More specifically following tests are done:
-- * Test Unssuported Opcode Operations
-- * Test Unsupported Opcode Operations
-- * Test RETCODE_NO_DATA response from DDS Reader
-- * Test RETCODE_ERROR response from DDS Reader
-- * Test RETCODE_ERROR response from DDS Writer

View File

@ -10,9 +10,9 @@ use work.ros_package.all;
use work.rtps_test_package.all;
use work.Fibonacci_package.all;
-- This testbench tests the General Behavour of ROS Services.
-- This testbench tests the General Behaviour of ROS Services.
-- More specifically following tests are done:
-- * Test Unssuported Opcode Operations
-- * Test Unsupported Opcode Operations
-- * Test RETCODE_NO_DATA response from DDS Reader
-- * Test RETCODE_ERROR response from DDS Reader
-- * Test RETCODE_ERROR response from DDS Writer

Some files were not shown because too many files have changed in this diff Show More