Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9aa7607d92 | |||
| d73fe79b60 | |||
| df67cf626d | |||
| 4c51a3944a | |||
| 84fd330802 | |||
| 676101f287 | |||
| 0e085a3b03 | |||
| d3a69dbe99 | |||
| 66ed1d846b | |||
| a20890e126 | |||
| c667c6ed5e | |||
| a1e0297fcb | |||
| d8647ddec9 | |||
| f0cc29fcd6 | |||
| 5f7f2685c2 | |||
| 41814f6bcc | |||
| 8004f21a7c | |||
| c318b3c560 | |||
| d2c0b37c27 | |||
| 35baf341c7 | |||
| d2d40c1326 | |||
| 3f2e4e82d1 | |||
| 839170c5ad | |||
| c577d4f671 | |||
| d537cd7460 | |||
| ca80910494 | |||
| 5f58b0bca4 |
19
.gitignore
vendored
19
.gitignore
vendored
@ -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/**
|
||||
|
||||
8
READ.txt
8
READ.txt
@ -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
|
||||
============
|
||||
|
||||
127
Report.txt
127
Report.txt
@ -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
BIN
doc/DDSI-RTPS_2-0.pdf
(Stored with Git LFS)
Normal file
Binary file not shown.
45
sim/L0_moving_average_wrapper_test1.do
Normal file
45
sim/L0_moving_average_wrapper_test1.do
Normal 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}
|
||||
124
sim/L2_ROS_loopback_test1.do
Normal file
124
sim/L2_ROS_loopback_test1.do
Normal 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}
|
||||
@ -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.
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
|
||||
|
||||
1146
src/REF.txt
1146
src/REF.txt
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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');
|
||||
|
||||
458
src/TODO.txt
458
src/TODO.txt
@ -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 Writer’s 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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
181
src/Tests/Level_0/L0_moving_average_wrapper_test1.vhd
Normal file
181
src/Tests/Level_0/L0_moving_average_wrapper_test1.vhd
Normal 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;
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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');
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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');
|
||||
|
||||
@ -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');
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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',
|
||||
|
||||
@ -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',
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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',
|
||||
|
||||
@ -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',
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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]
|
||||
|
||||
@ -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###
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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###
|
||||
@ -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);
|
||||
|
||||
@ -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###
|
||||
@ -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);
|
||||
|
||||
@ -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';
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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###
|
||||
|
||||
@ -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;
|
||||
@ -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;
|
||||
|
||||
@ -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###
|
||||
|
||||
@ -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;
|
||||
};
|
||||
};
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 (
|
||||
|
||||
@ -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
@ -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
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
87
src/moving_average.vhd
Normal 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;
|
||||
104
src/moving_average_wrapper.vhd
Normal file
104
src/moving_average_wrapper.vhd
Normal 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;
|
||||
@ -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.
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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###
|
||||
|
||||
@ -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 =>
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 =>
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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###
|
||||
|
||||
@ -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###
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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]
|
||||
|
||||
@ -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]
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
Loading…
Reference in New Issue
Block a user