From 90a4c7928a5e0154c89734cdd8ec3f3f5c758515 Mon Sep 17 00:00:00 2001 From: Greek Date: Tue, 11 May 2021 13:23:55 +0200 Subject: [PATCH] Backport Memory Controller to rtps_builtin_endpoint Backport Memory Controller and Memory FSM from RTPS/DDS Endpoints to RTPS Builtin Endpoint. The Memory is now using a single linked list and the FSM uses Frame Field Flags. The main FSM uses check_time to initiate stale checks, and the stale checks are done in the main FSM. Testbench was modified to accomodate the changes (Previous L0 Test4 was removed and integrated in L0 Test 1). --- sim/L0_dds_reader_test7_arzkriu.do | 199 + sim/L0_rtps_builtin_endpoint_test1.do | 93 +- sim/L0_rtps_builtin_endpoint_test5.do | 100 +- sim/L0_rtps_builtin_endpoint_test7.do | 71 - sim/L1_rtps_builtin_endpoint_test1.do | 120 +- src/REF.txt | 57 +- src/TODO.txt | 1 + .../L0_rtps_builtin_endpoint_test1.vhd | 197 +- .../L0_rtps_builtin_endpoint_test3.vhd | 256 +- .../L0_rtps_builtin_endpoint_test4.vhd | 312 +- .../L0_rtps_builtin_endpoint_test5.vhd | 358 +- .../L0_rtps_builtin_endpoint_test6.vhd | 216 +- .../L0_rtps_builtin_endpoint_test7.vhd | 348 -- .../L1_rtps_builtin_endpoint_test1.vhd | 145 +- src/Tests/testbench.pro | 242 +- src/rtps_builtin_endpoint.vhd | 4455 +++++++++++------ src/rtps_config_package.vhd | 4 +- src/rtps_test_package.vhd | 92 +- 18 files changed, 4391 insertions(+), 2875 deletions(-) create mode 100644 sim/L0_dds_reader_test7_arzkriu.do delete mode 100644 sim/L0_rtps_builtin_endpoint_test7.do delete mode 100644 src/Tests/Level_0/L0_rtps_builtin_endpoint_test7.vhd diff --git a/sim/L0_dds_reader_test7_arzkriu.do b/sim/L0_dds_reader_test7_arzkriu.do new file mode 100644 index 0000000..77616fb --- /dev/null +++ b/sim/L0_dds_reader_test7_arzkriu.do @@ -0,0 +1,199 @@ +onerror {resume} +radix define DDS_RETCODE { + "10#0#" "RETCODE_OK", + "10#1#" "RETCODE_ERROR", + "10#2#" "RETCODE_UNSUPPORTED", + "10#3#" "RETCODE_BAD_PARAMETER", + "10#4#" "RETCODE_PRECONDITION_NOT_MET", + "10#5#" "RETCODE_OUT_OF_RESOURCES", + "10#6#" "RETCODE_NOT_ENABLED", + "10#7#" "RETCODE_IMMUTABLE_POLICY", + "10#8#" "RETCODE_INCONSISTENT_POLICY", + "10#9#" "RETCODE_ALREADY_DELETED", + "10#10#" "RETCODE_TIMEOUT", + "10#11#" "RETCODE_NO_DATA", + "10#12#" "RETCODE_ILLEGAL_OPERATION", + -default unsigned +} +radix define SAMPLE_STATE { + "16#00000001#" "READ_SAMPLE_STATE", + "16#00000002#" "NOT_READ_SAMPLE_STATE", + "16#FFFFFFFF#" "ANY_SAMPLE_STATE", + -default binary +} +radix define VIEW_STATE { + "16#00000001#" "NEW_VIEW_STATE", + "16#00000002#" "NOT_NEW_VIEW_STATE", + "16#FFFFFFFF#" "ANY_VIEW_STATE", + -default binary +} +radix define INSTANCE_STATE { + "16#00000001#" "ALIVE_INSTANCE_STATE", + "16#00000002#" "NOT_ALIVE_DISPOSED_INSTANCE_STATE", + "16#00000004#" "NOT_ALIVE_NO_WRITERS_INSTANCE_STATE", + "16#FFFFFFFF#" "ANY_INSTANCE_STATE", + -default binary +} +radix define LAST_REASON { + "16#00000000#" "NOT_REJECTED", + "16#00000001#" "REJECTED_BY_INSTANCES_LIMIT", + "16#00000002#" "REJECTED_BY_SAMPLES_LIMIT", + "16#00000003#" "REJECTED_BY_SAMPLES_PER_INSTANCE_LIMIT", + "16#000000FF#" "REJECTED_BY_PAYOAD_MEMORY_LIMIT", + -default binary +} +quietly WaveActivateNextPane {} 0 +add wave -noupdate -divider SYSTEM +add wave -noupdate /l0_dds_reader_test7_arzkriu/uut/clk +add wave -noupdate /l0_dds_reader_test7_arzkriu/uut/reset +add wave -noupdate -radix unsigned /l0_dds_reader_test7_arzkriu/uut/time +add wave -noupdate -radix unsigned /l0_dds_reader_test7_arzkriu/uut/lifespan_time +add wave -noupdate -divider RTPS +add wave -noupdate -expand -group RTPS /l0_dds_reader_test7_arzkriu/uut/start_rtps +add wave -noupdate -expand -group RTPS /l0_dds_reader_test7_arzkriu/uut/opcode_rtps +add wave -noupdate -expand -group RTPS /l0_dds_reader_test7_arzkriu/uut/ack_rtps +add wave -noupdate -expand -group RTPS /l0_dds_reader_test7_arzkriu/uut/ret_rtps +add wave -noupdate -expand -group RTPS /l0_dds_reader_test7_arzkriu/uut/done_rtps +add wave -noupdate -expand -group RTPS /l0_dds_reader_test7_arzkriu/uut/ready_in_rtps +add wave -noupdate -expand -group RTPS /l0_dds_reader_test7_arzkriu/uut/valid_in_rtps +add wave -noupdate -expand -group RTPS -radix hexadecimal /l0_dds_reader_test7_arzkriu/uut/data_in_rtps +add wave -noupdate -expand -group RTPS /l0_dds_reader_test7_arzkriu/uut/last_word_in_rtps +add wave -noupdate -divider DDS +add wave -noupdate -group DDS /l0_dds_reader_test7_arzkriu/uut/start_dds +add wave -noupdate -group DDS /l0_dds_reader_test7_arzkriu/uut/ack_dds +add wave -noupdate -group DDS /l0_dds_reader_test7_arzkriu/uut/opcode_dds +add wave -noupdate -group DDS -radix SAMPLE_STATE /l0_dds_reader_test7_arzkriu/uut/sample_state_dds +add wave -noupdate -group DDS -radix INSTANCE_STATE /l0_dds_reader_test7_arzkriu/uut/instance_state_dds +add wave -noupdate -group DDS -radix VIEW_STATE /l0_dds_reader_test7_arzkriu/uut/view_state_dds +add wave -noupdate -group DDS -radix hexadecimal /l0_dds_reader_test7_arzkriu/uut/instance_handle_dds +add wave -noupdate -group DDS -radix unsigned /l0_dds_reader_test7_arzkriu/uut/max_samples_dds +add wave -noupdate -group DDS -radix DDS_RETCODE /l0_dds_reader_test7_arzkriu/uut/return_code_dds +add wave -noupdate -group DDS /l0_dds_reader_test7_arzkriu/uut/done_dds +add wave -noupdate -group DDS -divider SI +add wave -noupdate -group DDS -radix SAMPLE_STATE /l0_dds_reader_test7_arzkriu/uut/si_sample_state +add wave -noupdate -group DDS -radix VIEW_STATE /l0_dds_reader_test7_arzkriu/uut/si_view_state +add wave -noupdate -group DDS -radix INSTANCE_STATE /l0_dds_reader_test7_arzkriu/uut/si_instance_state +add wave -noupdate -group DDS -radix unsigned /l0_dds_reader_test7_arzkriu/uut/si_source_timestamp +add wave -noupdate -group DDS -radix hexadecimal /l0_dds_reader_test7_arzkriu/uut/si_instance_handle +add wave -noupdate -group DDS -radix hexadecimal /l0_dds_reader_test7_arzkriu/uut/si_publication_handle +add wave -noupdate -group DDS -radix unsigned /l0_dds_reader_test7_arzkriu/uut/si_disposed_generation_count +add wave -noupdate -group DDS -radix unsigned /l0_dds_reader_test7_arzkriu/uut/si_no_writers_generation_count +add wave -noupdate -group DDS -radix unsigned /l0_dds_reader_test7_arzkriu/uut/si_sample_rank +add wave -noupdate -group DDS -radix unsigned /l0_dds_reader_test7_arzkriu/uut/si_generation_rank +add wave -noupdate -group DDS -radix unsigned /l0_dds_reader_test7_arzkriu/uut/si_absolute_generation_rank +add wave -noupdate -group DDS /l0_dds_reader_test7_arzkriu/uut/si_valid_data +add wave -noupdate -group DDS /l0_dds_reader_test7_arzkriu/uut/si_valid +add wave -noupdate -group DDS /l0_dds_reader_test7_arzkriu/uut/get_data_dds +add wave -noupdate -group DDS /l0_dds_reader_test7_arzkriu/uut/eoc +add wave -noupdate -group DDS -divider OUTPUT +add wave -noupdate -group DDS /l0_dds_reader_test7_arzkriu/uut/ready_out_dds +add wave -noupdate -group DDS /l0_dds_reader_test7_arzkriu/uut/valid_out_dds +add wave -noupdate -group DDS -radix hexadecimal /l0_dds_reader_test7_arzkriu/uut/data_out_dds +add wave -noupdate -group DDS /l0_dds_reader_test7_arzkriu/uut/last_word_out_dds +add wave -noupdate -divider {MAIN FSM} +add wave -noupdate /l0_dds_reader_test7_arzkriu/uut/stage +add wave -noupdate /l0_dds_reader_test7_arzkriu/uut/stage_next +add wave -noupdate /l0_dds_reader_test7_arzkriu/uut/cnt +add wave -noupdate -divider MEMORY +add wave -noupdate -group {SAMPLE MEM} /l0_dds_reader_test7_arzkriu/uut/sample_abort_read +add wave -noupdate -group {SAMPLE MEM} -radix unsigned /l0_dds_reader_test7_arzkriu/uut/sample_mem_ctrl_inst/addr +add wave -noupdate -group {SAMPLE MEM} /l0_dds_reader_test7_arzkriu/uut/sample_mem_ctrl_inst/read +add wave -noupdate -group {SAMPLE MEM} /l0_dds_reader_test7_arzkriu/uut/sample_mem_ctrl_inst/ready_in +add wave -noupdate -group {SAMPLE MEM} /l0_dds_reader_test7_arzkriu/uut/sample_mem_ctrl_inst/valid_in +add wave -noupdate -group {SAMPLE MEM} -radix hexadecimal /l0_dds_reader_test7_arzkriu/uut/sample_mem_ctrl_inst/data_in +add wave -noupdate -group {SAMPLE MEM} /l0_dds_reader_test7_arzkriu/uut/sample_mem_ctrl_inst/ready_out +add wave -noupdate -group {SAMPLE MEM} /l0_dds_reader_test7_arzkriu/uut/sample_mem_ctrl_inst/valid_out +add wave -noupdate -group {SAMPLE MEM} -radix hexadecimal /l0_dds_reader_test7_arzkriu/uut/sample_mem_ctrl_inst/data_out +add wave -noupdate -group {PAYLOAD MEM} /l0_dds_reader_test7_arzkriu/uut/payload_abort_read +add wave -noupdate -group {PAYLOAD MEM} -radix unsigned /l0_dds_reader_test7_arzkriu/uut/payload_mem_ctrl_inst/addr +add wave -noupdate -group {PAYLOAD MEM} /l0_dds_reader_test7_arzkriu/uut/payload_mem_ctrl_inst/read +add wave -noupdate -group {PAYLOAD MEM} /l0_dds_reader_test7_arzkriu/uut/payload_mem_ctrl_inst/ready_in +add wave -noupdate -group {PAYLOAD MEM} /l0_dds_reader_test7_arzkriu/uut/payload_mem_ctrl_inst/valid_in +add wave -noupdate -group {PAYLOAD MEM} -radix hexadecimal /l0_dds_reader_test7_arzkriu/uut/payload_mem_ctrl_inst/data_in +add wave -noupdate -group {PAYLOAD MEM} /l0_dds_reader_test7_arzkriu/uut/payload_mem_ctrl_inst/ready_out +add wave -noupdate -group {PAYLOAD MEM} /l0_dds_reader_test7_arzkriu/uut/payload_mem_ctrl_inst/valid_out +add wave -noupdate -group {PAYLOAD MEM} -radix hexadecimal /l0_dds_reader_test7_arzkriu/uut/payload_mem_ctrl_inst/data_out +add wave -noupdate -group {INSTANCE MEM} /l0_dds_reader_test7_arzkriu/uut/inst_abort_read +add wave -noupdate -group {INSTANCE MEM} -radix unsigned /l0_dds_reader_test7_arzkriu/uut/gen_instance_mem_ctrl_inst/instance_mem_ctrl_inst/addr +add wave -noupdate -group {INSTANCE MEM} /l0_dds_reader_test7_arzkriu/uut/gen_instance_mem_ctrl_inst/instance_mem_ctrl_inst/read +add wave -noupdate -group {INSTANCE MEM} /l0_dds_reader_test7_arzkriu/uut/gen_instance_mem_ctrl_inst/instance_mem_ctrl_inst/ready_in +add wave -noupdate -group {INSTANCE MEM} /l0_dds_reader_test7_arzkriu/uut/gen_instance_mem_ctrl_inst/instance_mem_ctrl_inst/valid_in +add wave -noupdate -group {INSTANCE MEM} -radix hexadecimal /l0_dds_reader_test7_arzkriu/uut/gen_instance_mem_ctrl_inst/instance_mem_ctrl_inst/data_in +add wave -noupdate -group {INSTANCE MEM} /l0_dds_reader_test7_arzkriu/uut/gen_instance_mem_ctrl_inst/instance_mem_ctrl_inst/ready_out +add wave -noupdate -group {INSTANCE MEM} /l0_dds_reader_test7_arzkriu/uut/gen_instance_mem_ctrl_inst/instance_mem_ctrl_inst/valid_out +add wave -noupdate -group {INSTANCE MEM} -radix hexadecimal /l0_dds_reader_test7_arzkriu/uut/gen_instance_mem_ctrl_inst/instance_mem_ctrl_inst/data_out +add wave -noupdate /l0_dds_reader_test7_arzkriu/uut/inst_op_start +add wave -noupdate /l0_dds_reader_test7_arzkriu/uut/inst_opcode +add wave -noupdate /l0_dds_reader_test7_arzkriu/uut/inst_op_done +add wave -noupdate /l0_dds_reader_test7_arzkriu/uut/inst_stage +add wave -noupdate /l0_dds_reader_test7_arzkriu/uut/inst_stage_next +add wave -noupdate /l0_dds_reader_test7_arzkriu/uut/inst_cnt +add wave -noupdate -radix unsigned /l0_dds_reader_test7_arzkriu/uut/inst_addr_base +add wave -noupdate /l0_dds_reader_test7_arzkriu/uut/inst_mem_fields +add wave -noupdate -childformat {{/l0_dds_reader_test7_arzkriu/uut/inst_data.key_hash -radix hexadecimal} {/l0_dds_reader_test7_arzkriu/uut/inst_data.status_info -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.sample_cnt -radix unsigned} {/l0_dds_reader_test7_arzkriu/uut/inst_data.disposed_gen_cnt -radix unsigned} {/l0_dds_reader_test7_arzkriu/uut/inst_data.no_writers_gen_cnt -radix unsigned} {/l0_dds_reader_test7_arzkriu/uut/inst_data.ignore_deadline -radix unsigned} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap -radix binary -childformat {{/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0) -radix binary -childformat {{/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(0) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(1) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(2) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(3) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(4) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(5) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(6) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(7) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(8) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(9) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(10) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(11) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(12) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(13) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(14) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(15) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(16) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(17) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(18) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(19) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(20) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(21) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(22) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(23) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(24) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(25) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(26) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(27) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(28) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(29) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(30) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(31) -radix binary}}}}}} -expand -subitemconfig {/l0_dds_reader_test7_arzkriu/uut/inst_data.key_hash {-height 15 -radix hexadecimal} /l0_dds_reader_test7_arzkriu/uut/inst_data.status_info {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.sample_cnt {-height 15 -radix unsigned} /l0_dds_reader_test7_arzkriu/uut/inst_data.disposed_gen_cnt {-height 15 -radix unsigned} /l0_dds_reader_test7_arzkriu/uut/inst_data.no_writers_gen_cnt {-height 15 -radix unsigned} /l0_dds_reader_test7_arzkriu/uut/inst_data.ignore_deadline {-height 15 -radix unsigned} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap {-height 15 -radix binary -childformat {{/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0) -radix binary -childformat {{/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(0) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(1) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(2) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(3) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(4) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(5) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(6) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(7) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(8) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(9) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(10) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(11) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(12) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(13) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(14) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(15) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(16) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(17) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(18) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(19) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(20) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(21) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(22) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(23) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(24) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(25) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(26) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(27) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(28) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(29) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(30) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(31) -radix binary}}}}} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0) {-height 15 -radix binary -childformat {{/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(0) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(1) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(2) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(3) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(4) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(5) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(6) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(7) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(8) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(9) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(10) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(11) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(12) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(13) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(14) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(15) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(16) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(17) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(18) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(19) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(20) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(21) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(22) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(23) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(24) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(25) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(26) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(27) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(28) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(29) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(30) -radix binary} {/l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(31) -radix binary}}} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(0) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(1) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(2) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(3) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(4) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(5) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(6) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(7) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(8) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(9) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(10) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(11) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(12) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(13) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(14) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(15) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(16) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(17) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(18) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(19) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(20) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(21) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(22) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(23) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(24) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(25) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(26) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(27) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(28) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(29) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(30) {-height 15 -radix binary} /l0_dds_reader_test7_arzkriu/uut/inst_data.writer_bitmap(0)(31) {-height 15 -radix binary}} /l0_dds_reader_test7_arzkriu/uut/inst_data +add wave -noupdate -radix unsigned /l0_dds_reader_test7_arzkriu/uut/inst_next_addr_base +add wave -noupdate -radix unsigned /l0_dds_reader_test7_arzkriu/uut/inst_prev_addr_base +add wave -noupdate /l0_dds_reader_test7_arzkriu/uut/current_imf +add wave -noupdate /l0_dds_reader_test7_arzkriu/uut/stale_inst_cnt +add wave -noupdate -divider POINTERS +add wave -noupdate -group {LIST POINTERS} -radix unsigned /l0_dds_reader_test7_arzkriu/uut/empty_sample_list_head +add wave -noupdate -group {LIST POINTERS} -radix unsigned /l0_dds_reader_test7_arzkriu/uut/empty_sample_list_tail +add wave -noupdate -group {LIST POINTERS} -radix unsigned /l0_dds_reader_test7_arzkriu/uut/empty_payload_list_head +add wave -noupdate -group {LIST POINTERS} -radix unsigned /l0_dds_reader_test7_arzkriu/uut/oldest_sample +add wave -noupdate -group {LIST POINTERS} -radix unsigned /l0_dds_reader_test7_arzkriu/uut/newest_sample +add wave -noupdate -group {LIST POINTERS} -radix unsigned /l0_dds_reader_test7_arzkriu/uut/inst_empty_head +add wave -noupdate -group {LIST POINTERS} -radix unsigned /l0_dds_reader_test7_arzkriu/uut/inst_occupied_head +add wave -noupdate -expand -group {GENERAL POINTERS} -radix unsigned /l0_dds_reader_test7_arzkriu/uut/cur_sample +add wave -noupdate -expand -group {GENERAL POINTERS} -radix unsigned /l0_dds_reader_test7_arzkriu/uut/next_sample +add wave -noupdate -expand -group {GENERAL POINTERS} -radix unsigned /l0_dds_reader_test7_arzkriu/uut/prev_sample +add wave -noupdate -expand -group {GENERAL POINTERS} -radix unsigned /l0_dds_reader_test7_arzkriu/uut/cur_payload +add wave -noupdate -expand -group {GENERAL POINTERS} -radix unsigned /l0_dds_reader_test7_arzkriu/uut/next_payload +add wave -noupdate -expand -group {GENERAL POINTERS} -radix unsigned /l0_dds_reader_test7_arzkriu/uut/cur_inst +add wave -noupdate -expand -group {GENERAL POINTERS} -radix unsigned /l0_dds_reader_test7_arzkriu/uut/next_inst +add wave -noupdate -divider TESTBENCH +add wave -noupdate -group TESTBENCH /l0_dds_reader_test7_arzkriu/dds_start +add wave -noupdate -group TESTBENCH /l0_dds_reader_test7_arzkriu/dds_stage +add wave -noupdate -group TESTBENCH /l0_dds_reader_test7_arzkriu/dds_cnt +add wave -noupdate -group TESTBENCH /l0_dds_reader_test7_arzkriu/dds_cnt2 +add wave -noupdate -group TESTBENCH /l0_dds_reader_test7_arzkriu/dds_done +add wave -noupdate -group TESTBENCH /l0_dds_reader_test7_arzkriu/rtps_start +add wave -noupdate -group TESTBENCH /l0_dds_reader_test7_arzkriu/rtps_stage +add wave -noupdate -group TESTBENCH /l0_dds_reader_test7_arzkriu/rtps_cnt +add wave -noupdate -group TESTBENCH /l0_dds_reader_test7_arzkriu/rtps_done +add wave -noupdate -divider {KEY HOLDER} +add wave -noupdate -group {KEY HOLDER} /l0_dds_reader_test7_arzkriu/uut/start_kh +add wave -noupdate -group {KEY HOLDER} /l0_dds_reader_test7_arzkriu/uut/opcode_kh +add wave -noupdate -group {KEY HOLDER} /l0_dds_reader_test7_arzkriu/uut/ack_kh +add wave -noupdate -group {KEY HOLDER} -radix hexadecimal /l0_dds_reader_test7_arzkriu/uut/data_in_kh +add wave -noupdate -group {KEY HOLDER} /l0_dds_reader_test7_arzkriu/uut/valid_in_kh +add wave -noupdate -group {KEY HOLDER} /l0_dds_reader_test7_arzkriu/uut/ready_in_kh +add wave -noupdate -group {KEY HOLDER} /l0_dds_reader_test7_arzkriu/uut/last_word_in_kh +add wave -noupdate -group {KEY HOLDER} -radix hexadecimal /l0_dds_reader_test7_arzkriu/uut/data_out_kh +add wave -noupdate -group {KEY HOLDER} /l0_dds_reader_test7_arzkriu/uut/valid_out_kh +add wave -noupdate -group {KEY HOLDER} /l0_dds_reader_test7_arzkriu/uut/ready_out_kh +add wave -noupdate -group {KEY HOLDER} /l0_dds_reader_test7_arzkriu/uut/last_word_out_kh +add wave -noupdate -group {KEY HOLDER} /l0_dds_reader_test7_arzkriu/uut/abort_kh +add wave -noupdate -divider MISC +add wave -noupdate /l0_dds_reader_test7_arzkriu/uut/status +add wave -noupdate -radix unsigned /l0_dds_reader_test7_arzkriu/uut/sample_rej_cnt +add wave -noupdate -radix unsigned /l0_dds_reader_test7_arzkriu/uut/sample_rej_cnt_change +add wave -noupdate /l0_dds_reader_test7_arzkriu/uut/sample_rej_last_reason +add wave -noupdate -radix hexadecimal /l0_dds_reader_test7_arzkriu/uut/sample_rej_last_inst +TreeUpdate [SetDefaultTree] +WaveRestoreCursors {{Cursor 1} {7016727 ps} 0} {{Cursor 2} {115175000 ps} 1} +quietly wave cursor active 1 +configure wave -namecolwidth 187 +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 {6874680 ps} {7875321 ps} diff --git a/sim/L0_rtps_builtin_endpoint_test1.do b/sim/L0_rtps_builtin_endpoint_test1.do index 8a527f2..5962c1f 100644 --- a/sim/L0_rtps_builtin_endpoint_test1.do +++ b/sim/L0_rtps_builtin_endpoint_test1.do @@ -1,51 +1,64 @@ onerror {resume} quietly WaveActivateNextPane {} 0 add wave -noupdate -divider SYSTEM -add wave -noupdate /L0_rtps_builtin_endpoint_test1/uut/clk -add wave -noupdate /L0_rtps_builtin_endpoint_test1/uut/reset +add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/clk +add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/reset add wave -noupdate -divider INPUT -add wave -noupdate /L0_rtps_builtin_endpoint_test1/uut/empty -add wave -noupdate /L0_rtps_builtin_endpoint_test1/uut/rd -add wave -noupdate -radix hexadecimal /L0_rtps_builtin_endpoint_test1/uut/data_in -add wave -noupdate /L0_rtps_builtin_endpoint_test1/uut/last_word_in -add wave -noupdate /L0_rtps_builtin_endpoint_test1/uut/last_word_in_latch -add wave -noupdate -divider TESTBENCH -add wave -noupdate /L0_rtps_builtin_endpoint_test1/start -add wave -noupdate /L0_rtps_builtin_endpoint_test1/stim_stage -add wave -noupdate /L0_rtps_builtin_endpoint_test1/stimulus.length -add wave -noupdate /L0_rtps_builtin_endpoint_test1/cnt_stim -add wave -noupdate /L0_rtps_builtin_endpoint_test1/packet_sent +add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/empty +add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/rd +add wave -noupdate -radix hexadecimal /l0_rtps_builtin_endpoint_test1/uut/data_in +add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/last_word_in +add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/last_word_in_latch add wave -noupdate -divider {MAIN FSM} -add wave -noupdate /L0_rtps_builtin_endpoint_test1/uut/stage -add wave -noupdate /L0_rtps_builtin_endpoint_test1/uut/stage_next -add wave -noupdate /L0_rtps_builtin_endpoint_test1/uut/cnt -add wave -noupdate /L0_rtps_builtin_endpoint_test1/uut/endpoint_mask -add wave -noupdate /L0_rtps_builtin_endpoint_test1/uut/participant_match +add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/stage +add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/stage_next +add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/cnt +add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/endpoint_mask +add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/participant_match add wave -noupdate -divider {MEM FSM} -add wave -noupdate /L0_rtps_builtin_endpoint_test1/uut/mem_opcode -add wave -noupdate /L0_rtps_builtin_endpoint_test1/uut/mem_op_start -add wave -noupdate /L0_rtps_builtin_endpoint_test1/uut/mem_op_done -add wave -noupdate /L0_rtps_builtin_endpoint_test1/uut/mem_stage -add wave -noupdate /L0_rtps_builtin_endpoint_test1/uut/mem_stage_next -add wave -noupdate /L0_rtps_builtin_endpoint_test1/uut/mem_cnt -add wave -noupdate -radix unsigned /L0_rtps_builtin_endpoint_test1/uut/mem_addr_base -add wave -noupdate -radix unsigned /L0_rtps_builtin_endpoint_test1/uut/addr_res +add wave -noupdate -group MEMORY -radix unsigned /l0_rtps_builtin_endpoint_test1/uut/mem_ctrl_inst/addr +add wave -noupdate -group MEMORY /l0_rtps_builtin_endpoint_test1/uut/mem_ctrl_inst/read +add wave -noupdate -group MEMORY /l0_rtps_builtin_endpoint_test1/uut/mem_ctrl_inst/ready_in +add wave -noupdate -group MEMORY /l0_rtps_builtin_endpoint_test1/uut/mem_ctrl_inst/valid_in +add wave -noupdate -group MEMORY -radix hexadecimal /l0_rtps_builtin_endpoint_test1/uut/mem_ctrl_inst/data_in +add wave -noupdate -group MEMORY /l0_rtps_builtin_endpoint_test1/uut/mem_ctrl_inst/ready_out +add wave -noupdate -group MEMORY /l0_rtps_builtin_endpoint_test1/uut/mem_ctrl_inst/valid_out +add wave -noupdate -group MEMORY -radix hexadecimal /l0_rtps_builtin_endpoint_test1/uut/mem_ctrl_inst/data_out +add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/mem_op_start +add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/mem_opcode +add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/mem_op_done +add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/mem_stage +add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/mem_stage_next +add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/mem_cnt +add wave -noupdate -radix unsigned /l0_rtps_builtin_endpoint_test1/uut/mem_addr_base +add wave -noupdate -radix unsigned /l0_rtps_builtin_endpoint_test1/uut/mem_empty_head +add wave -noupdate -radix unsigned /l0_rtps_builtin_endpoint_test1/uut/mem_occupied_head +add wave -noupdate -childformat {{/l0_rtps_builtin_endpoint_test1/uut/participant_data.guid_prefix -radix hexadecimal} {/l0_rtps_builtin_endpoint_test1/uut/participant_data.meta_addr -radix hexadecimal} {/l0_rtps_builtin_endpoint_test1/uut/participant_data.def_addr -radix hexadecimal} {/l0_rtps_builtin_endpoint_test1/uut/participant_data.meta_port -radix hexadecimal} {/l0_rtps_builtin_endpoint_test1/uut/participant_data.def_port -radix hexadecimal} {/l0_rtps_builtin_endpoint_test1/uut/participant_data.lease_duration -radix unsigned} {/l0_rtps_builtin_endpoint_test1/uut/participant_data.lease_deadline -radix unsigned} {/l0_rtps_builtin_endpoint_test1/uut/participant_data.heartbeat_res_time -radix unsigned} {/l0_rtps_builtin_endpoint_test1/uut/participant_data.acknack_res_time -radix unsigned} {/l0_rtps_builtin_endpoint_test1/uut/participant_data.spdp_seq_nr -radix unsigned} {/l0_rtps_builtin_endpoint_test1/uut/participant_data.pub_seq_nr -radix unsigned} {/l0_rtps_builtin_endpoint_test1/uut/participant_data.sub_seq_nr -radix unsigned} {/l0_rtps_builtin_endpoint_test1/uut/participant_data.mes_seq_nr -radix unsigned}} -subitemconfig {/l0_rtps_builtin_endpoint_test1/uut/participant_data.guid_prefix {-height 15 -radix hexadecimal} /l0_rtps_builtin_endpoint_test1/uut/participant_data.meta_addr {-height 15 -radix hexadecimal} /l0_rtps_builtin_endpoint_test1/uut/participant_data.def_addr {-height 15 -radix hexadecimal} /l0_rtps_builtin_endpoint_test1/uut/participant_data.meta_port {-height 15 -radix hexadecimal} /l0_rtps_builtin_endpoint_test1/uut/participant_data.def_port {-height 15 -radix hexadecimal} /l0_rtps_builtin_endpoint_test1/uut/participant_data.lease_duration {-height 15 -radix unsigned} /l0_rtps_builtin_endpoint_test1/uut/participant_data.lease_deadline {-height 15 -radix unsigned} /l0_rtps_builtin_endpoint_test1/uut/participant_data.heartbeat_res_time {-height 15 -radix unsigned} /l0_rtps_builtin_endpoint_test1/uut/participant_data.acknack_res_time {-height 15 -radix unsigned} /l0_rtps_builtin_endpoint_test1/uut/participant_data.spdp_seq_nr {-height 15 -radix unsigned} /l0_rtps_builtin_endpoint_test1/uut/participant_data.pub_seq_nr {-height 15 -radix unsigned} /l0_rtps_builtin_endpoint_test1/uut/participant_data.sub_seq_nr {-height 15 -radix unsigned} /l0_rtps_builtin_endpoint_test1/uut/participant_data.mes_seq_nr {-height 15 -radix unsigned}} /l0_rtps_builtin_endpoint_test1/uut/participant_data +add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/current_pmf +add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/mem_field_flags add wave -noupdate -divider GUARD -add wave -noupdate -radix unsigned /L0_rtps_builtin_endpoint_test1/uut/read_cnt -add wave -noupdate -radix unsigned /L0_rtps_builtin_endpoint_test1/uut/parameter_end -add wave -noupdate /L0_rtps_builtin_endpoint_test1/uut/parse_prc/rd_guard -add wave -noupdate -divider MEMORY -add wave -noupdate -group MEMORY -radix unsigned /L0_rtps_builtin_endpoint_test1/uut/ram_inst/addr -add wave -noupdate -group MEMORY /L0_rtps_builtin_endpoint_test1/uut/ram_inst/wen -add wave -noupdate -group MEMORY /L0_rtps_builtin_endpoint_test1/uut/ram_inst/ren -add wave -noupdate -group MEMORY -radix hexadecimal /L0_rtps_builtin_endpoint_test1/uut/ram_inst/wr_data -add wave -noupdate -group MEMORY -radix hexadecimal /L0_rtps_builtin_endpoint_test1/uut/ram_inst/rd_data +add wave -noupdate -radix unsigned /l0_rtps_builtin_endpoint_test1/uut/read_cnt +add wave -noupdate -radix unsigned /l0_rtps_builtin_endpoint_test1/uut/parameter_end +add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/parse_prc/rd_guard add wave -noupdate -divider MISC -add wave -noupdate /L0_rtps_builtin_endpoint_test1/uut/update_participant_flags -add wave -noupdate -radix unsigned /L0_rtps_builtin_endpoint_test1/uut/mem_seq_nr -add wave -noupdate -radix unsigned /L0_rtps_builtin_endpoint_test1/uut/seq_nr +add wave -noupdate -radix unsigned /l0_rtps_builtin_endpoint_test1/uut/seq_nr +add wave -noupdate -divider TESTBENCH +add wave -noupdate -expand -group TESTBENCH /l0_rtps_builtin_endpoint_test1/start +add wave -noupdate -expand -group TESTBENCH /l0_rtps_builtin_endpoint_test1/stim_stage +add wave -noupdate -expand -group TESTBENCH /l0_rtps_builtin_endpoint_test1/stimulus.length +add wave -noupdate -expand -group TESTBENCH /l0_rtps_builtin_endpoint_test1/cnt_stim +add wave -noupdate -expand -group TESTBENCH /l0_rtps_builtin_endpoint_test1/packet_sent +add wave -noupdate -expand -group TESTBENCH /l0_rtps_builtin_endpoint_test1/mem_check_done +add wave -noupdate -expand -group TESTBENCH /l0_rtps_builtin_endpoint_test1/check_done +add wave -noupdate -divider OUTPUT +add wave -noupdate -radix hexadecimal /l0_rtps_builtin_endpoint_test1/uut/data_out +add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/endpoint_full +add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/endpoint_wr +add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/rtps_wr +add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/rtps_full +add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/last_word_out TreeUpdate [SetDefaultTree] -WaveRestoreCursors {{Cursor 1} {10125000 ps} 1} +WaveRestoreCursors {{Cursor 1} {82041201 ps} 0} quietly wave cursor active 1 configure wave -namecolwidth 149 configure wave -valuecolwidth 144 @@ -61,4 +74,4 @@ configure wave -griddelta 40 configure wave -timeline 0 configure wave -timelineunits ps update -WaveRestoreZoom {9084076 ps} {10232418 ps} +WaveRestoreZoom {81521938 ps} {82670280 ps} diff --git a/sim/L0_rtps_builtin_endpoint_test5.do b/sim/L0_rtps_builtin_endpoint_test5.do index 7acbeee..3743b08 100644 --- a/sim/L0_rtps_builtin_endpoint_test5.do +++ b/sim/L0_rtps_builtin_endpoint_test5.do @@ -1,55 +1,65 @@ onerror {resume} quietly WaveActivateNextPane {} 0 add wave -noupdate -divider SYSTEM -add wave -noupdate /L0_rtps_builtin_endpoint_test5/uut/clk -add wave -noupdate /L0_rtps_builtin_endpoint_test5/uut/reset +add wave -noupdate /l0_rtps_builtin_endpoint_test5/uut/clk +add wave -noupdate /l0_rtps_builtin_endpoint_test5/uut/reset +add wave -noupdate -radix unsigned /l0_rtps_builtin_endpoint_test5/uut/time +add wave -noupdate -radix unsigned /l0_rtps_builtin_endpoint_test5/uut/check_time add wave -noupdate -divider INPUT -add wave -noupdate /L0_rtps_builtin_endpoint_test5/uut/empty -add wave -noupdate /L0_rtps_builtin_endpoint_test5/uut/rd -add wave -noupdate -radix hexadecimal /L0_rtps_builtin_endpoint_test5/uut/data_in -add wave -noupdate /L0_rtps_builtin_endpoint_test5/uut/last_word_in -add wave -noupdate /L0_rtps_builtin_endpoint_test5/uut/last_word_in_latch -add wave -noupdate -divider OUTPUT -add wave -noupdate -radix hexadecimal /L0_rtps_builtin_endpoint_test5/uut/data_out -add wave -noupdate /L0_rtps_builtin_endpoint_test5/uut/endpoint_wr -add wave -noupdate /L0_rtps_builtin_endpoint_test5/uut/last_word_out -add wave -noupdate -divider TESTBENCH -add wave -noupdate /L0_rtps_builtin_endpoint_test5/start -add wave -noupdate /L0_rtps_builtin_endpoint_test5/stim_stage -add wave -noupdate /L0_rtps_builtin_endpoint_test5/stimulus.length -add wave -noupdate /L0_rtps_builtin_endpoint_test5/cnt_stim -add wave -noupdate /L0_rtps_builtin_endpoint_test5/packet_sent +add wave -noupdate /l0_rtps_builtin_endpoint_test5/uut/empty +add wave -noupdate /l0_rtps_builtin_endpoint_test5/uut/rd +add wave -noupdate -radix hexadecimal /l0_rtps_builtin_endpoint_test5/uut/data_in +add wave -noupdate /l0_rtps_builtin_endpoint_test5/uut/last_word_in +add wave -noupdate /l0_rtps_builtin_endpoint_test5/uut/last_word_in_latch add wave -noupdate -divider {MAIN FSM} -add wave -noupdate /L0_rtps_builtin_endpoint_test5/uut/stage -add wave -noupdate /L0_rtps_builtin_endpoint_test5/uut/stage_next -add wave -noupdate /L0_rtps_builtin_endpoint_test5/uut/cnt -add wave -noupdate /L0_rtps_builtin_endpoint_test5/uut/endpoint_mask -add wave -noupdate /L0_rtps_builtin_endpoint_test5/uut/participant_match +add wave -noupdate /l0_rtps_builtin_endpoint_test5/uut/stage +add wave -noupdate /l0_rtps_builtin_endpoint_test5/uut/stage_next +add wave -noupdate /l0_rtps_builtin_endpoint_test5/uut/cnt +add wave -noupdate /l0_rtps_builtin_endpoint_test5/uut/endpoint_mask +add wave -noupdate /l0_rtps_builtin_endpoint_test5/uut/participant_match add wave -noupdate -divider {MEM FSM} -add wave -noupdate -group MEM_FSM /L0_rtps_builtin_endpoint_test5/uut/mem_opcode -add wave -noupdate -group MEM_FSM /L0_rtps_builtin_endpoint_test5/uut/mem_op_start -add wave -noupdate -group MEM_FSM /L0_rtps_builtin_endpoint_test5/uut/mem_op_done -add wave -noupdate -group MEM_FSM /L0_rtps_builtin_endpoint_test5/uut/mem_stage -add wave -noupdate -group MEM_FSM /L0_rtps_builtin_endpoint_test5/uut/mem_stage_next -add wave -noupdate -group MEM_FSM /L0_rtps_builtin_endpoint_test5/uut/mem_cnt -add wave -noupdate -group MEM_FSM -radix unsigned /L0_rtps_builtin_endpoint_test5/uut/mem_addr_base -add wave -noupdate -group MEM_FSM -radix unsigned /L0_rtps_builtin_endpoint_test5/uut/addr_res +add wave -noupdate -group MEMORY -radix unsigned /l0_rtps_builtin_endpoint_test5/uut/mem_ctrl_inst/addr +add wave -noupdate -group MEMORY /l0_rtps_builtin_endpoint_test5/uut/mem_ctrl_inst/read +add wave -noupdate -group MEMORY /l0_rtps_builtin_endpoint_test5/uut/mem_ctrl_inst/ready_in +add wave -noupdate -group MEMORY /l0_rtps_builtin_endpoint_test5/uut/mem_ctrl_inst/valid_in +add wave -noupdate -group MEMORY -radix hexadecimal /l0_rtps_builtin_endpoint_test5/uut/mem_ctrl_inst/data_in +add wave -noupdate -group MEMORY /l0_rtps_builtin_endpoint_test5/uut/mem_ctrl_inst/ready_out +add wave -noupdate -group MEMORY /l0_rtps_builtin_endpoint_test5/uut/mem_ctrl_inst/valid_out +add wave -noupdate -group MEMORY -radix hexadecimal /l0_rtps_builtin_endpoint_test5/uut/mem_ctrl_inst/data_out +add wave -noupdate /l0_rtps_builtin_endpoint_test5/uut/mem_op_start +add wave -noupdate /l0_rtps_builtin_endpoint_test5/uut/mem_opcode +add wave -noupdate /l0_rtps_builtin_endpoint_test5/uut/mem_op_done +add wave -noupdate /l0_rtps_builtin_endpoint_test5/uut/mem_stage +add wave -noupdate /l0_rtps_builtin_endpoint_test5/uut/mem_stage_next +add wave -noupdate /l0_rtps_builtin_endpoint_test5/uut/mem_cnt +add wave -noupdate -radix unsigned /l0_rtps_builtin_endpoint_test5/uut/mem_addr_base +add wave -noupdate -radix unsigned /l0_rtps_builtin_endpoint_test5/uut/mem_empty_head +add wave -noupdate -radix unsigned /l0_rtps_builtin_endpoint_test5/uut/mem_occupied_head +add wave -noupdate -childformat {{/l0_rtps_builtin_endpoint_test5/uut/participant_data.guid_prefix -radix hexadecimal} {/l0_rtps_builtin_endpoint_test5/uut/participant_data.meta_addr -radix hexadecimal} {/l0_rtps_builtin_endpoint_test5/uut/participant_data.def_addr -radix hexadecimal} {/l0_rtps_builtin_endpoint_test5/uut/participant_data.meta_port -radix hexadecimal} {/l0_rtps_builtin_endpoint_test5/uut/participant_data.def_port -radix hexadecimal} {/l0_rtps_builtin_endpoint_test5/uut/participant_data.lease_duration -radix unsigned} {/l0_rtps_builtin_endpoint_test5/uut/participant_data.lease_deadline -radix unsigned} {/l0_rtps_builtin_endpoint_test5/uut/participant_data.heartbeat_res_time -radix unsigned} {/l0_rtps_builtin_endpoint_test5/uut/participant_data.acknack_res_time -radix unsigned} {/l0_rtps_builtin_endpoint_test5/uut/participant_data.spdp_seq_nr -radix unsigned} {/l0_rtps_builtin_endpoint_test5/uut/participant_data.pub_seq_nr -radix unsigned} {/l0_rtps_builtin_endpoint_test5/uut/participant_data.sub_seq_nr -radix unsigned} {/l0_rtps_builtin_endpoint_test5/uut/participant_data.mes_seq_nr -radix unsigned}} -subitemconfig {/l0_rtps_builtin_endpoint_test5/uut/participant_data.guid_prefix {-height 15 -radix hexadecimal} /l0_rtps_builtin_endpoint_test5/uut/participant_data.meta_addr {-height 15 -radix hexadecimal} /l0_rtps_builtin_endpoint_test5/uut/participant_data.def_addr {-height 15 -radix hexadecimal} /l0_rtps_builtin_endpoint_test5/uut/participant_data.meta_port {-height 15 -radix hexadecimal} /l0_rtps_builtin_endpoint_test5/uut/participant_data.def_port {-height 15 -radix hexadecimal} /l0_rtps_builtin_endpoint_test5/uut/participant_data.lease_duration {-height 15 -radix unsigned} /l0_rtps_builtin_endpoint_test5/uut/participant_data.lease_deadline {-height 15 -radix unsigned} /l0_rtps_builtin_endpoint_test5/uut/participant_data.heartbeat_res_time {-height 15 -radix unsigned} /l0_rtps_builtin_endpoint_test5/uut/participant_data.acknack_res_time {-height 15 -radix unsigned} /l0_rtps_builtin_endpoint_test5/uut/participant_data.spdp_seq_nr {-height 15 -radix unsigned} /l0_rtps_builtin_endpoint_test5/uut/participant_data.pub_seq_nr {-height 15 -radix unsigned} /l0_rtps_builtin_endpoint_test5/uut/participant_data.sub_seq_nr {-height 15 -radix unsigned} /l0_rtps_builtin_endpoint_test5/uut/participant_data.mes_seq_nr {-height 15 -radix unsigned}} /l0_rtps_builtin_endpoint_test5/uut/participant_data +add wave -noupdate /l0_rtps_builtin_endpoint_test5/uut/current_pmf +add wave -noupdate /l0_rtps_builtin_endpoint_test5/uut/mem_field_flags add wave -noupdate -divider GUARD -add wave -noupdate -radix unsigned /L0_rtps_builtin_endpoint_test5/uut/read_cnt -add wave -noupdate -radix unsigned /L0_rtps_builtin_endpoint_test5/uut/parameter_end -add wave -noupdate /L0_rtps_builtin_endpoint_test5/uut/parse_prc/rd_guard -add wave -noupdate -divider MEMORY -add wave -noupdate -group MEMORY -radix unsigned /L0_rtps_builtin_endpoint_test5/uut/ram_inst/addr -add wave -noupdate -group MEMORY /L0_rtps_builtin_endpoint_test5/uut/ram_inst/wen -add wave -noupdate -group MEMORY /L0_rtps_builtin_endpoint_test5/uut/ram_inst/ren -add wave -noupdate -group MEMORY -radix hexadecimal /L0_rtps_builtin_endpoint_test5/uut/ram_inst/wr_data -add wave -noupdate -group MEMORY -radix hexadecimal /L0_rtps_builtin_endpoint_test5/uut/ram_inst/rd_data +add wave -noupdate -radix unsigned /l0_rtps_builtin_endpoint_test5/uut/read_cnt +add wave -noupdate -radix unsigned /l0_rtps_builtin_endpoint_test5/uut/parameter_end +add wave -noupdate /l0_rtps_builtin_endpoint_test5/uut/parse_prc/rd_guard add wave -noupdate -divider MISC -add wave -noupdate /L0_rtps_builtin_endpoint_test5/uut/update_participant_flags -add wave -noupdate -radix unsigned /L0_rtps_builtin_endpoint_test5/uut/mem_seq_nr -add wave -noupdate -radix unsigned /L0_rtps_builtin_endpoint_test5/uut/seq_nr +add wave -noupdate -radix unsigned /l0_rtps_builtin_endpoint_test5/uut/seq_nr +add wave -noupdate -divider TESTBENCH +add wave -noupdate -expand -group TESTBENCH /l0_rtps_builtin_endpoint_test5/start +add wave -noupdate -expand -group TESTBENCH /l0_rtps_builtin_endpoint_test5/stim_stage +add wave -noupdate -expand -group TESTBENCH /l0_rtps_builtin_endpoint_test5/stimulus.length +add wave -noupdate -expand -group TESTBENCH /l0_rtps_builtin_endpoint_test5/cnt_stim +add wave -noupdate -expand -group TESTBENCH /l0_rtps_builtin_endpoint_test5/packet_sent +add wave -noupdate -expand -group TESTBENCH /l0_rtps_builtin_endpoint_test5/check_done +add wave -noupdate -divider OUTPUT +add wave -noupdate -radix hexadecimal /l0_rtps_builtin_endpoint_test5/uut/data_out +add wave -noupdate /l0_rtps_builtin_endpoint_test5/uut/endpoint_full +add wave -noupdate /l0_rtps_builtin_endpoint_test5/uut/endpoint_wr +add wave -noupdate /l0_rtps_builtin_endpoint_test5/uut/rtps_wr +add wave -noupdate /l0_rtps_builtin_endpoint_test5/uut/rtps_full +add wave -noupdate /l0_rtps_builtin_endpoint_test5/uut/last_word_out TreeUpdate [SetDefaultTree] -WaveRestoreCursors {Begin {847825000 ps} 1} {Error {851525000 ps} 1} {Cursor {33675000 ps} 0} +WaveRestoreCursors {{Cursor 1} {64726 ps} 0} quietly wave cursor active 1 configure wave -namecolwidth 149 configure wave -valuecolwidth 144 @@ -63,6 +73,6 @@ configure wave -gridoffset 0 configure wave -gridperiod 1 configure wave -griddelta 40 configure wave -timeline 0 -configure wave -timelineunits ns +configure wave -timelineunits ps update -WaveRestoreZoom {848883724 ps} {850032066 ps} +WaveRestoreZoom {0 ps} {1148342 ps} diff --git a/sim/L0_rtps_builtin_endpoint_test7.do b/sim/L0_rtps_builtin_endpoint_test7.do deleted file mode 100644 index 6dcbd16..0000000 --- a/sim/L0_rtps_builtin_endpoint_test7.do +++ /dev/null @@ -1,71 +0,0 @@ -onerror {resume} -quietly WaveActivateNextPane {} 0 -add wave -noupdate -divider SYSTEM -add wave -noupdate /L0_rtps_builtin_endpoint_test7/uut/clk -add wave -noupdate /L0_rtps_builtin_endpoint_test7/uut/reset -add wave -noupdate -divider INPUT -add wave -noupdate /L0_rtps_builtin_endpoint_test7/uut/empty -add wave -noupdate /L0_rtps_builtin_endpoint_test7/uut/rd -add wave -noupdate -radix hexadecimal /L0_rtps_builtin_endpoint_test7/uut/data_in -add wave -noupdate /L0_rtps_builtin_endpoint_test7/uut/last_word_in -add wave -noupdate /L0_rtps_builtin_endpoint_test7/uut/last_word_in_latch -add wave -noupdate -radix hexadecimal /L0_rtps_builtin_endpoint_test7/uut/time -add wave -noupdate -divider OUTPUT -add wave -noupdate -radix hexadecimal /L0_rtps_builtin_endpoint_test7/uut/data_out -add wave -noupdate /L0_rtps_builtin_endpoint_test7/uut/endpoint_wr -add wave -noupdate /L0_rtps_builtin_endpoint_test7/uut/last_word_out -add wave -noupdate -divider TESTBENCH -add wave -noupdate /L0_rtps_builtin_endpoint_test7/start -add wave -noupdate /L0_rtps_builtin_endpoint_test7/stim_stage -add wave -noupdate /L0_rtps_builtin_endpoint_test7/stimulus.length -add wave -noupdate /L0_rtps_builtin_endpoint_test7/cnt_stim -add wave -noupdate /L0_rtps_builtin_endpoint_test7/packet_sent -add wave -noupdate -divider {MAIN FSM} -add wave -noupdate /L0_rtps_builtin_endpoint_test7/uut/stage -add wave -noupdate /L0_rtps_builtin_endpoint_test7/uut/stage_next -add wave -noupdate /L0_rtps_builtin_endpoint_test7/uut/cnt -add wave -noupdate /L0_rtps_builtin_endpoint_test7/uut/endpoint_mask -add wave -noupdate /L0_rtps_builtin_endpoint_test7/uut/participant_match -add wave -noupdate -radix hexadecimal /L0_rtps_builtin_endpoint_test7/uut/lease_duration -add wave -noupdate -radix hexadecimal /L0_rtps_builtin_endpoint_test7/uut/deadline -add wave -noupdate -divider {MEM FSM} -add wave -noupdate -expand -group MEM_FSM /L0_rtps_builtin_endpoint_test7/uut/mem_opcode -add wave -noupdate -expand -group MEM_FSM /L0_rtps_builtin_endpoint_test7/uut/mem_op_start -add wave -noupdate -expand -group MEM_FSM /L0_rtps_builtin_endpoint_test7/uut/mem_op_done -add wave -noupdate -expand -group MEM_FSM /L0_rtps_builtin_endpoint_test7/uut/mem_stage -add wave -noupdate -expand -group MEM_FSM /L0_rtps_builtin_endpoint_test7/uut/mem_stage_next -add wave -noupdate -expand -group MEM_FSM /L0_rtps_builtin_endpoint_test7/uut/mem_cnt -add wave -noupdate -expand -group MEM_FSM -radix unsigned /L0_rtps_builtin_endpoint_test7/uut/mem_addr_base -add wave -noupdate -expand -group MEM_FSM -radix unsigned /L0_rtps_builtin_endpoint_test7/uut/addr_res -add wave -noupdate -divider GUARD -add wave -noupdate -radix unsigned /L0_rtps_builtin_endpoint_test7/uut/read_cnt -add wave -noupdate -radix unsigned /L0_rtps_builtin_endpoint_test7/uut/parameter_end -add wave -noupdate /L0_rtps_builtin_endpoint_test7/uut/parse_prc/rd_guard -add wave -noupdate -divider MEMORY -add wave -noupdate -expand -group MEMORY -radix unsigned /L0_rtps_builtin_endpoint_test7/uut/ram_inst/addr -add wave -noupdate -expand -group MEMORY /L0_rtps_builtin_endpoint_test7/uut/ram_inst/wen -add wave -noupdate -expand -group MEMORY /L0_rtps_builtin_endpoint_test7/uut/ram_inst/ren -add wave -noupdate -expand -group MEMORY -radix hexadecimal /L0_rtps_builtin_endpoint_test7/uut/ram_inst/wr_data -add wave -noupdate -expand -group MEMORY -radix hexadecimal /L0_rtps_builtin_endpoint_test7/uut/ram_inst/rd_data -add wave -noupdate -divider MISC -add wave -noupdate /L0_rtps_builtin_endpoint_test7/uut/update_participant_flags -add wave -noupdate -radix unsigned /L0_rtps_builtin_endpoint_test7/uut/mem_seq_nr -add wave -noupdate -radix unsigned /L0_rtps_builtin_endpoint_test7/uut/seq_nr -TreeUpdate [SetDefaultTree] -WaveRestoreCursors {Begin {31125000 ps} 1} {Error {45825000 ps} 1} {Cursor {31192063 ps} 0} -quietly wave cursor active 3 -configure wave -namecolwidth 149 -configure wave -valuecolwidth 144 -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 {30675309 ps} {31823651 ps} diff --git a/sim/L1_rtps_builtin_endpoint_test1.do b/sim/L1_rtps_builtin_endpoint_test1.do index fa09718..510400e 100644 --- a/sim/L1_rtps_builtin_endpoint_test1.do +++ b/sim/L1_rtps_builtin_endpoint_test1.do @@ -1,68 +1,76 @@ onerror {resume} quietly WaveActivateNextPane {} 0 add wave -noupdate -divider SYSTEM -add wave -noupdate /L1_rtps_builtin_endpoint_test1/uut/clk -add wave -noupdate /L1_rtps_builtin_endpoint_test1/uut/reset +add wave -noupdate /l1_rtps_builtin_endpoint_test1/uut/clk +add wave -noupdate /l1_rtps_builtin_endpoint_test1/uut/reset +add wave -noupdate -radix unsigned /l1_rtps_builtin_endpoint_test1/uut/time +add wave -noupdate -radix unsigned /l1_rtps_builtin_endpoint_test1/uut/check_time add wave -noupdate -divider INPUT -add wave -noupdate /L1_rtps_builtin_endpoint_test1/uut/empty -add wave -noupdate /L1_rtps_builtin_endpoint_test1/uut/rd -add wave -noupdate -radix hexadecimal /L1_rtps_builtin_endpoint_test1/uut/data_in -add wave -noupdate /L1_rtps_builtin_endpoint_test1/uut/last_word_in -add wave -noupdate /L1_rtps_builtin_endpoint_test1/uut/last_word_in_latch -add wave -noupdate -radix hexadecimal /L1_rtps_builtin_endpoint_test1/uut/time +add wave -noupdate /l1_rtps_builtin_endpoint_test1/uut/empty +add wave -noupdate /l1_rtps_builtin_endpoint_test1/uut/rd +add wave -noupdate -radix hexadecimal /l1_rtps_builtin_endpoint_test1/uut/data_in +add wave -noupdate /l1_rtps_builtin_endpoint_test1/uut/last_word_in +add wave -noupdate /l1_rtps_builtin_endpoint_test1/uut/last_word_in_latch +add wave -noupdate -radix hexadecimal /l1_rtps_builtin_endpoint_test1/uut/time add wave -noupdate -divider OUTPUT -add wave -noupdate -radix hexadecimal /L1_rtps_builtin_endpoint_test1/uut/data_out -add wave -noupdate /L1_rtps_builtin_endpoint_test1/uut/last_word_out -add wave -noupdate /L1_rtps_builtin_endpoint_test1/uut/rtps_wr -add wave -noupdate /L1_rtps_builtin_endpoint_test1/uut/rtps_full -add wave -noupdate -divider TESTBENCH -add wave -noupdate /L1_rtps_builtin_endpoint_test1/start -add wave -noupdate /L1_rtps_builtin_endpoint_test1/stim_stage -add wave -noupdate /L1_rtps_builtin_endpoint_test1/stimulus.length -add wave -noupdate /L1_rtps_builtin_endpoint_test1/cnt_stim -add wave -noupdate /L1_rtps_builtin_endpoint_test1/packet_sent +add wave -noupdate -radix hexadecimal /l1_rtps_builtin_endpoint_test1/uut/data_out +add wave -noupdate /l1_rtps_builtin_endpoint_test1/uut/last_word_out +add wave -noupdate /l1_rtps_builtin_endpoint_test1/uut/rtps_wr +add wave -noupdate /l1_rtps_builtin_endpoint_test1/uut/rtps_full add wave -noupdate -divider {MAIN FSM} -add wave -noupdate /L1_rtps_builtin_endpoint_test1/uut/stage -add wave -noupdate /L1_rtps_builtin_endpoint_test1/uut/stage_next -add wave -noupdate /L1_rtps_builtin_endpoint_test1/uut/cnt +add wave -noupdate /l1_rtps_builtin_endpoint_test1/uut/stage +add wave -noupdate /l1_rtps_builtin_endpoint_test1/uut/stage_next +add wave -noupdate /l1_rtps_builtin_endpoint_test1/uut/cnt add wave -noupdate -divider {MEM FSM} -add wave -noupdate -expand -group MEM_FSM /L1_rtps_builtin_endpoint_test1/uut/mem_opcode -add wave -noupdate -expand -group MEM_FSM /L1_rtps_builtin_endpoint_test1/uut/mem_op_start -add wave -noupdate -expand -group MEM_FSM /L1_rtps_builtin_endpoint_test1/uut/mem_op_done -add wave -noupdate -expand -group MEM_FSM /L1_rtps_builtin_endpoint_test1/uut/mem_stage -add wave -noupdate -expand -group MEM_FSM /L1_rtps_builtin_endpoint_test1/uut/mem_stage_next -add wave -noupdate -expand -group MEM_FSM /L1_rtps_builtin_endpoint_test1/uut/mem_cnt -add wave -noupdate -expand -group MEM_FSM -radix unsigned /L1_rtps_builtin_endpoint_test1/uut/mem_addr_base -add wave -noupdate -expand -group MEM_FSM -radix unsigned /L1_rtps_builtin_endpoint_test1/uut/addr_res +add wave -noupdate -group MEMORY /l1_rtps_builtin_endpoint_test1/uut/mem_abort_read +add wave -noupdate -group MEMORY -radix unsigned /l1_rtps_builtin_endpoint_test1/uut/mem_ctrl_inst/addr +add wave -noupdate -group MEMORY /l1_rtps_builtin_endpoint_test1/uut/mem_ctrl_inst/read +add wave -noupdate -group MEMORY /l1_rtps_builtin_endpoint_test1/uut/mem_ctrl_inst/ready_in +add wave -noupdate -group MEMORY /l1_rtps_builtin_endpoint_test1/uut/mem_ctrl_inst/valid_in +add wave -noupdate -group MEMORY -radix hexadecimal /l1_rtps_builtin_endpoint_test1/uut/mem_ctrl_inst/data_in +add wave -noupdate -group MEMORY /l1_rtps_builtin_endpoint_test1/uut/mem_ctrl_inst/ready_out +add wave -noupdate -group MEMORY /l1_rtps_builtin_endpoint_test1/uut/mem_ctrl_inst/valid_out +add wave -noupdate -group MEMORY -radix hexadecimal /l1_rtps_builtin_endpoint_test1/uut/mem_ctrl_inst/data_out +add wave -noupdate /l1_rtps_builtin_endpoint_test1/uut/mem_op_start +add wave -noupdate /l1_rtps_builtin_endpoint_test1/uut/mem_op_done +add wave -noupdate /l1_rtps_builtin_endpoint_test1/uut/mem_opcode +add wave -noupdate /l1_rtps_builtin_endpoint_test1/uut/mem_stage +add wave -noupdate /l1_rtps_builtin_endpoint_test1/uut/mem_stage_next +add wave -noupdate /l1_rtps_builtin_endpoint_test1/uut/mem_cnt +add wave -noupdate -childformat {{/l1_rtps_builtin_endpoint_test1/uut/participant_data.guid_prefix -radix hexadecimal} {/l1_rtps_builtin_endpoint_test1/uut/participant_data.meta_addr -radix hexadecimal} {/l1_rtps_builtin_endpoint_test1/uut/participant_data.def_addr -radix hexadecimal} {/l1_rtps_builtin_endpoint_test1/uut/participant_data.meta_port -radix hexadecimal} {/l1_rtps_builtin_endpoint_test1/uut/participant_data.def_port -radix hexadecimal} {/l1_rtps_builtin_endpoint_test1/uut/participant_data.lease_duration -radix unsigned} {/l1_rtps_builtin_endpoint_test1/uut/participant_data.lease_deadline -radix unsigned} {/l1_rtps_builtin_endpoint_test1/uut/participant_data.heartbeat_res_time -radix unsigned} {/l1_rtps_builtin_endpoint_test1/uut/participant_data.acknack_res_time -radix unsigned} {/l1_rtps_builtin_endpoint_test1/uut/participant_data.spdp_seq_nr -radix unsigned} {/l1_rtps_builtin_endpoint_test1/uut/participant_data.pub_seq_nr -radix unsigned} {/l1_rtps_builtin_endpoint_test1/uut/participant_data.sub_seq_nr -radix unsigned} {/l1_rtps_builtin_endpoint_test1/uut/participant_data.mes_seq_nr -radix unsigned}} -expand -subitemconfig {/l1_rtps_builtin_endpoint_test1/uut/participant_data.guid_prefix {-height 15 -radix hexadecimal} /l1_rtps_builtin_endpoint_test1/uut/participant_data.meta_addr {-height 15 -radix hexadecimal} /l1_rtps_builtin_endpoint_test1/uut/participant_data.def_addr {-height 15 -radix hexadecimal} /l1_rtps_builtin_endpoint_test1/uut/participant_data.meta_port {-height 15 -radix hexadecimal} /l1_rtps_builtin_endpoint_test1/uut/participant_data.def_port {-height 15 -radix hexadecimal} /l1_rtps_builtin_endpoint_test1/uut/participant_data.lease_duration {-height 15 -radix unsigned} /l1_rtps_builtin_endpoint_test1/uut/participant_data.lease_deadline {-height 15 -radix unsigned} /l1_rtps_builtin_endpoint_test1/uut/participant_data.heartbeat_res_time {-height 15 -radix unsigned} /l1_rtps_builtin_endpoint_test1/uut/participant_data.acknack_res_time {-height 15 -radix unsigned} /l1_rtps_builtin_endpoint_test1/uut/participant_data.spdp_seq_nr {-height 15 -radix unsigned} /l1_rtps_builtin_endpoint_test1/uut/participant_data.pub_seq_nr {-height 15 -radix unsigned} /l1_rtps_builtin_endpoint_test1/uut/participant_data.sub_seq_nr {-height 15 -radix unsigned} /l1_rtps_builtin_endpoint_test1/uut/participant_data.mes_seq_nr {-height 15 -radix unsigned}} /l1_rtps_builtin_endpoint_test1/uut/participant_data +add wave -noupdate -radix unsigned /l1_rtps_builtin_endpoint_test1/uut/mem_addr_base +add wave -noupdate -radix unsigned /l1_rtps_builtin_endpoint_test1/uut/mem_empty_head +add wave -noupdate -radix unsigned /l1_rtps_builtin_endpoint_test1/uut/mem_occupied_head add wave -noupdate -divider GUARD -add wave -noupdate -radix unsigned /L1_rtps_builtin_endpoint_test1/uut/read_cnt -add wave -noupdate -radix unsigned /L1_rtps_builtin_endpoint_test1/uut/parameter_end -add wave -noupdate /L1_rtps_builtin_endpoint_test1/uut/parse_prc/rd_guard -add wave -noupdate -divider MEMORY -add wave -noupdate -expand -group MEMORY -radix unsigned /L1_rtps_builtin_endpoint_test1/uut/ram_inst/addr -add wave -noupdate -expand -group MEMORY /L1_rtps_builtin_endpoint_test1/uut/ram_inst/wen -add wave -noupdate -expand -group MEMORY /L1_rtps_builtin_endpoint_test1/uut/ram_inst/ren -add wave -noupdate -expand -group MEMORY -radix hexadecimal /L1_rtps_builtin_endpoint_test1/uut/ram_inst/wr_data -add wave -noupdate -expand -group MEMORY -radix hexadecimal /L1_rtps_builtin_endpoint_test1/uut/ram_inst/rd_data +add wave -noupdate -radix unsigned /l1_rtps_builtin_endpoint_test1/uut/read_cnt +add wave -noupdate -radix unsigned /l1_rtps_builtin_endpoint_test1/uut/parameter_end +add wave -noupdate /l1_rtps_builtin_endpoint_test1/uut/parse_prc/rd_guard add wave -noupdate -divider MISC -add wave -noupdate /L1_rtps_builtin_endpoint_test1/uut/update_participant_flags -add wave -noupdate -radix unsigned /L1_rtps_builtin_endpoint_test1/uut/seq_nr -add wave -noupdate -group FIFO -radix hexadecimal /L1_rtps_builtin_endpoint_test1/fifo_inst/data_in -add wave -noupdate -group FIFO /L1_rtps_builtin_endpoint_test1/fifo_inst/write -add wave -noupdate -group FIFO /L1_rtps_builtin_endpoint_test1/fifo_inst/full -add wave -noupdate -group FIFO -radix hexadecimal /L1_rtps_builtin_endpoint_test1/fifo_inst/data_out -add wave -noupdate -group FIFO /L1_rtps_builtin_endpoint_test1/fifo_inst/read -add wave -noupdate -group FIFO /L1_rtps_builtin_endpoint_test1/fifo_inst/empty -add wave -noupdate -group RTPS_OUT -radix hexadecimal /L1_rtps_builtin_endpoint_test1/rtps_out_inst/data_in -add wave -noupdate -group RTPS_OUT /L1_rtps_builtin_endpoint_test1/rtps_out_inst/last_word_in -add wave -noupdate -group RTPS_OUT /L1_rtps_builtin_endpoint_test1/rtps_out_inst/rd -add wave -noupdate -group RTPS_OUT /L1_rtps_builtin_endpoint_test1/rtps_out_inst/empty -add wave -noupdate -group RTPS_OUT -radix hexadecimal /L1_rtps_builtin_endpoint_test1/rtps_out_inst/data_out -add wave -noupdate -group RTPS_OUT /L1_rtps_builtin_endpoint_test1/rtps_out_inst/wr -add wave -noupdate -group RTPS_OUT /L1_rtps_builtin_endpoint_test1/rtps_out_inst/full -add wave -noupdate -group RTPS_OUT /L1_rtps_builtin_endpoint_test1/rtps_out_inst/selector +add wave -noupdate /l1_rtps_builtin_endpoint_test1/uut/alive +add wave -noupdate /l1_rtps_builtin_endpoint_test1/uut/endpoint_alive +add wave -noupdate -radix unsigned -childformat {{/l1_rtps_builtin_endpoint_test1/uut/seq_nr(0) -radix unsigned} {/l1_rtps_builtin_endpoint_test1/uut/seq_nr(1) -radix unsigned}} -subitemconfig {/l1_rtps_builtin_endpoint_test1/uut/seq_nr(0) {-radix unsigned} /l1_rtps_builtin_endpoint_test1/uut/seq_nr(1) {-radix unsigned}} /l1_rtps_builtin_endpoint_test1/uut/seq_nr +add wave -noupdate -group FIFO -radix hexadecimal /l1_rtps_builtin_endpoint_test1/fifo_inst/data_in +add wave -noupdate -group FIFO /l1_rtps_builtin_endpoint_test1/fifo_inst/write +add wave -noupdate -group FIFO /l1_rtps_builtin_endpoint_test1/fifo_inst/full +add wave -noupdate -group FIFO -radix hexadecimal /l1_rtps_builtin_endpoint_test1/fifo_inst/data_out +add wave -noupdate -group FIFO /l1_rtps_builtin_endpoint_test1/fifo_inst/read +add wave -noupdate -group FIFO /l1_rtps_builtin_endpoint_test1/fifo_inst/empty +add wave -noupdate -group RTPS_OUT -radix hexadecimal /l1_rtps_builtin_endpoint_test1/rtps_out_inst/data_in +add wave -noupdate -group RTPS_OUT /l1_rtps_builtin_endpoint_test1/rtps_out_inst/last_word_in +add wave -noupdate -group RTPS_OUT /l1_rtps_builtin_endpoint_test1/rtps_out_inst/rd +add wave -noupdate -group RTPS_OUT /l1_rtps_builtin_endpoint_test1/rtps_out_inst/empty +add wave -noupdate -group RTPS_OUT -radix hexadecimal /l1_rtps_builtin_endpoint_test1/rtps_out_inst/data_out +add wave -noupdate -group RTPS_OUT /l1_rtps_builtin_endpoint_test1/rtps_out_inst/wr +add wave -noupdate -group RTPS_OUT /l1_rtps_builtin_endpoint_test1/rtps_out_inst/full +add wave -noupdate -group RTPS_OUT /l1_rtps_builtin_endpoint_test1/rtps_out_inst/selector +add wave -noupdate -divider TESTBENCH +add wave -noupdate -group TESTBENCH /l1_rtps_builtin_endpoint_test1/start +add wave -noupdate -group TESTBENCH /l1_rtps_builtin_endpoint_test1/stim_stage +add wave -noupdate -group TESTBENCH /l1_rtps_builtin_endpoint_test1/stimulus.length +add wave -noupdate -group TESTBENCH /l1_rtps_builtin_endpoint_test1/cnt_stim +add wave -noupdate -group TESTBENCH /l1_rtps_builtin_endpoint_test1/packet_sent TreeUpdate [SetDefaultTree] -WaveRestoreCursors {Begin {31125000 ps} 1} {Error {50874035 ps} 1} {Cursor {28075000 ps} 0} +WaveRestoreCursors {Begin {31125000 ps} 1} {Error {36375000 ps} 1} {Cursor {36411652 ps} 0} quietly wave cursor active 2 configure wave -namecolwidth 149 configure wave -valuecolwidth 144 @@ -78,4 +86,4 @@ configure wave -griddelta 40 configure wave -timeline 0 configure wave -timelineunits ns update -WaveRestoreZoom {50582404 ps} {51730746 ps} +WaveRestoreZoom {35541123 ps} {36689465 ps} diff --git a/src/REF.txt b/src/REF.txt index 269ed2e..01a8d96 100644 --- a/src/REF.txt +++ b/src/REF.txt @@ -189,54 +189,55 @@ PARTICICPANT DATA 31............24..............16..............8...............0 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-------------------------------------------------------------+ -00| | - + + -01| GUIDPREFIX | - + + -02| | +00| NEXT_ADDRESS | +-------------------------------------------------------------+ -03| META_IPv4_ADDRESS | +01| | + + + +02| GUIDPREFIX | + + + +03| | +-------------------------------------------------------------+ -04| DEFAULT_IPv4_ADDRESS | +04| META_IPv4_ADDRESS | + +-------------------------------------------------------------+ +05| DEFAULT_IPv4_ADDRESS | +-----------------------------+-------------------------------+ -05| META_UDP_PORT | DEFAULT_UDP_PORT | +06| META_UDP_PORT | DEFAULT_UDP_PORT | +-----------------------------+-------------------------------+ -06| | - + SPDP_SEQ_NR + 07| | - +-------------------------------------------------------------+ + + SPDP_SEQ_NR + 08| | - + LEASE_DURATION + + +-------------------------------------------------------------+ 09| | - +-------------------------------------------------------------+ + + LEASE_DURATION + 10| | - + LEASE_DEADLINE + + +-------------------------------------------------------------+ 11| | - +-----------------------------------------------------+-+-+-+-+ -12| UNUSED |P|S|M|Q| - +-----------------------------------------------------+-+-+-+-+ -13| | - + ACKNACK_RES_TIME + + + LEASE_DEADLINE + +12| | + +-------------------------------------------------------+-+-+-+ +13| UNUSED |P|S|M| + +-------------------------------------------------------+-+-+-+ 14| | - +-------------------------------------------------------------+ + + ACKNACK_RES_TIME + 15| | - + HEARTBEAT_RES_TIME + + +-------------------------------------------------------------+ 16| | - +-------------------------------------------------------------+ + + HEARTBEAT_RES_TIME + 17| | - + PUBLICATION_SEQ_NR + + +-------------------------------------------------------------+ 18| | - +-------------------------------------------------------------+ + + PUBLICATION_SEQ_NR + 19| | - + SUBSCRIPTION_SEQ_NR + -20| | +-------------------------------------------------------------+ +20| | + + SUBSCRIPTION_SEQ_NR + 21| | - + MESSAGE_SEQ_NR + + +-------------------------------------------------------------+ 22| | + + MESSAGE_SEQ_NR + +23| | +-------------------------------------------------------------+ -Q...Reader expects in-line QoS M...Send Message Data (Liveliness Update) S...Send Subriber Data P...Send Publisher Data diff --git a/src/TODO.txt b/src/TODO.txt index b390ebd..8667648 100644 --- a/src/TODO.txt +++ b/src/TODO.txt @@ -82,6 +82,7 @@ * 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] * 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? +* In rtps_builtin_endpoint we initiate a participant memory search ASAP (in the PACKET_SRC_GUIDPREFIX stage). Further down we branch to several different branches, which each needing different Participant Data Fields. Currently we are fetching ALL needed Fields from ALL branches. Would it make sense to delay the search until the PACKET_DEST_ENTITYID/CHECK_SRC_ENTITYID stage, and only fetch the relevant Fields? * Fast-RTPS does not follow DDSI-RTPS Specification - Open Github Issue diff --git a/src/Tests/Level_0/L0_rtps_builtin_endpoint_test1.vhd b/src/Tests/Level_0/L0_rtps_builtin_endpoint_test1.vhd index 6aab308..54d1359 100644 --- a/src/Tests/Level_0/L0_rtps_builtin_endpoint_test1.vhd +++ b/src/Tests/Level_0/L0_rtps_builtin_endpoint_test1.vhd @@ -18,6 +18,7 @@ use work.rtps_test_package.all; -- * Unmatching previously matched Participants (Due to incompatibility) -- * Update data of previously matched Participant -- * Big/Little Endian Participant Data +-- * Memory Full Behaviour entity L0_rtps_builtin_endpoint_test1 is @@ -44,9 +45,24 @@ architecture testbench of L0_rtps_builtin_endpoint_test1 is signal start : std_logic := '0'; shared variable SB_out : work.ScoreBoardPkg_builtin_endpoint.ScoreBoardPType; shared variable SB_mem : work.ScoreBoardPkg_MemoryTest.ScoreBoardPType; - signal stim_done, check_done : std_logic := '0'; + signal stim_done, mem_check_done, check_done, test_done : std_logic := '0'; + -- *FUNCTION DECLARATION* procedure wait_on_complete is + begin + if (test_done /= '1') then + wait until test_done = '1'; + end if; + end procedure; + + procedure wait_on_mem_check is + begin + if (mem_check_done /= '1') then + wait until mem_check_done = '1'; + end if; + end procedure; + + procedure wait_on_sent is begin wait until rising_edge(packet_sent); end procedure; @@ -79,7 +95,8 @@ begin variable rtps_sub : RTPS_SUBMESSAGE_TYPE := DEFAULT_RTPS_SUBMESSAGE; variable RV : RandomPType; variable participant : PARTICIPANT_DATA_TYPE := DEFAULT_PARTICIPANT_DATA; - variable p0, p1, p2 : GUIDPREFIX_TYPE; + variable m0, m1, m2 : PARTICIPANT_DATA_TYPE := DEFAULT_PARTICIPANT_DATA; + variable p0, p1, p2, p3 : GUIDPREFIX_TYPE; -- Wrapper to use procedure as function impure function gen_rand_loc_2 return LOCATOR_TYPE is @@ -135,6 +152,7 @@ begin p0 := gen_rand_guid_prefix; p1 := gen_rand_guid_prefix; p2 := gen_rand_guid_prefix; + p3 := gen_rand_guid_prefix; Log("Initiating Test", INFO); @@ -143,6 +161,7 @@ begin wait until rising_edge(clk); wait until rising_edge(clk); reset <= '0'; + -- MEMORY STATE: -/0,1,2 Log("Match Participant 0 [Compatible]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -154,16 +173,18 @@ begin participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER):= '1'; participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; + m0 := participant; gen_participant_data(participant, rtps_sub.data); gen_sentinel(rtps_sub.data); gen_rtps_handler_out(rtps_sub, participant, stimulus); SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE [p0,0,0] + -- MEMORY STATE: 0(p0)/1,2 Log("Match Participant 1 [Compatible, Little Endian]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -176,16 +197,18 @@ begin participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER):= '1'; participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; + m1 := participant; gen_participant_data(participant, rtps_sub.data); gen_sentinel(rtps_sub.data); gen_rtps_handler_out(rtps_sub, participant, stimulus); SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE [p0,p1,0] + -- MEMORY STATE: 1(p1),0(p0)/2 Log("Ignore Participant 2 [Incompatible Domain ID]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -201,13 +224,13 @@ begin gen_participant_data(participant, rtps_sub.data); gen_sentinel(rtps_sub.data); gen_rtps_handler_out(rtps_sub, participant, stimulus); - SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE [p0,p1,0] + -- MEMORY STATE: 1(p1),0(p0)/2 Log("Unmatch Participant 0 [Incompatible Domain ID]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -220,17 +243,19 @@ begin participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER):= '1'; participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; + m0 := DEFAULT_PARTICIPANT_DATA; gen_participant_data(participant, rtps_sub.data); gen_sentinel(rtps_sub.data); gen_rtps_handler_out(rtps_sub, participant, stimulus); - SB_mem.Push(gen_participant_mem_frame(participant)); push_reference; start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE [0,p1,0] + -- MEMORY STATE: 1(p1)/0,2 + Log("Ignore Participant 2 [Incompatible Domain TAG]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -246,13 +271,13 @@ begin gen_participant_data(participant, rtps_sub.data); gen_sentinel(rtps_sub.data); gen_rtps_handler_out(rtps_sub, participant, stimulus); - SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE [0,p1,0] + -- MEMORY STATE: 1(p1)/0,2 Log("Unmatch Participant 1 [Incompatible Domain TAG]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -268,19 +293,19 @@ begin gen_participant_data(participant, rtps_sub.data); gen_sentinel(rtps_sub.data); gen_rtps_handler_out(rtps_sub, participant, stimulus); - SB_mem.Push(gen_participant_mem_frame(participant)); push_reference; start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE [0,0,0] + -- MEMORY STATE: -/1,0,2 Log("Match Participant 0 [+Unicast Metatraffic Locator]", INFO); participant := DEFAULT_PARTICIPANT_DATA; participant.guidPrefix := p0; - participant.nr := 0; + participant.nr := 1; participant.match := MATCH; participant.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); participant.metatrafficUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); @@ -288,21 +313,23 @@ begin participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER):= '1'; participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; + m1 := participant; gen_participant_data(participant, rtps_sub.data); gen_sentinel(rtps_sub.data); gen_rtps_handler_out(rtps_sub, participant, stimulus); SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE [p0,0,0] + -- MEMORY STATE: 1(p0)/0,2 Log("Match Participant 1 [ALL Values Set non default]", INFO); participant := DEFAULT_PARTICIPANT_DATA; participant.guidPrefix := p1; - participant.nr := 1; + participant.nr := 0; participant.vendorId := RV.RandSlv(VENDORID_WIDTH); participant.expectsInlineQoS(0) := '1'; participant.leaseDuration := gen_duration(5,500); @@ -317,16 +344,18 @@ begin participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER):= '1'; participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; + m0 := participant; gen_participant_data(participant, rtps_sub.data); gen_sentinel(rtps_sub.data); gen_rtps_handler_out(rtps_sub, participant, stimulus); SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE [p0,p1,0] + -- MEMORY STATE: 0(p1),1(p0)/2 Log("Ignore Participant 2 [Incompatible Protocol Version]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -342,13 +371,13 @@ begin gen_participant_data(participant, rtps_sub.data); gen_sentinel(rtps_sub.data); gen_rtps_handler_out(rtps_sub, participant, stimulus); - SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE [p0,p1,0] + -- MEMORY STATE: 0(p1),1(p0)/2 Log("Unmatch Participant 0 [Incompatible Protocol Version]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -361,36 +390,39 @@ begin participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER):= '1'; participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; + m1 := DEFAULT_PARTICIPANT_DATA; gen_participant_data(participant, rtps_sub.data); gen_sentinel(rtps_sub.data); gen_rtps_handler_out(rtps_sub, participant, stimulus); - SB_mem.Push(gen_participant_mem_frame(participant)); push_reference; start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE [0,p1,0] + -- MEMORY STATE: 0(p1)/1,2 Log("Match Participant 0 [Compatible, Only Subscribers]", INFO); participant := DEFAULT_PARTICIPANT_DATA; participant.guidPrefix := p0; - participant.nr := 0; + participant.nr := 1; participant.match := MATCH; participant.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER):= '1'; participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; + m1 := participant; gen_participant_data(participant, rtps_sub.data); gen_sentinel(rtps_sub.data); gen_rtps_handler_out(rtps_sub, participant, stimulus); SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE [p0,p1,0] + -- MEMORY STATE: 1(p0),0(p1)/2 Log("Match Participant 2 [Compatible, Only Publishers]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -400,21 +432,23 @@ begin participant.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR) := '1'; + m2 := participant; gen_participant_data(participant, rtps_sub.data); gen_sentinel(rtps_sub.data); gen_rtps_handler_out(rtps_sub, participant, stimulus); SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE [p0,p1,p2] + -- MEMORY STATE: 2(p2),1(p0),0(p1)/- Log("Update Participant 1 [Valid/Invalid Default/Metatraffic Locators]", INFO); participant := DEFAULT_PARTICIPANT_DATA; participant.guidPrefix := p1; - participant.nr := 1; + participant.nr := 0; participant.match := MATCH; participant.defaultUnicastLocatorList := (numLocators => int(4,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, 1 => gen_rand_loc_2, 2 => gen_rand_loc_2, 3 => gen_rand_loc_2, others => EMPTY_LOCATOR)); participant.defaultUnicastLocatorList.locator(1).kind := LOCATOR_KIND_UDPv6; @@ -434,16 +468,42 @@ begin participant.metatrafficMulticastLocatorList.locator(3).addr := (others => '0'); participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR) := '1'; + m0 := participant; gen_participant_data(participant, rtps_sub.data); gen_sentinel(rtps_sub.data); gen_rtps_handler_out(rtps_sub, participant, stimulus); SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; + stimulus := EMPTY_TEST_PACKET; + rtps_sub.data := EMPTY_TEST_PACKET; + rtps_sub.writerSN := rtps_sub.writerSN + 1; + -- MEMORY STATE: 2(p2),1(p0),0(p1)/- + + Log("Ignore Participant 3 [Memory Full]", INFO); + participant := DEFAULT_PARTICIPANT_DATA; + participant.guidPrefix := p3; + participant.nr := 0; + participant.match := MATCH; + participant.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR) := '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER):= '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; + gen_participant_data(participant, rtps_sub.data); + gen_sentinel(rtps_sub.data); + gen_rtps_handler_out(rtps_sub, participant, stimulus); + -- Re-Check Memory + SB_mem.Push(gen_participant_mem_frame(m0)); + SB_mem.Push(gen_participant_mem_frame(m1)); + SB_mem.Push(gen_participant_mem_frame(m2)); + start_test; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE [p0,p1,p2] Log("Unmatch Participant 2 [No Endpoints]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -451,17 +511,18 @@ begin participant.nr := 2; participant.match := UNMATCH; participant.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + m2 := DEFAULT_PARTICIPANT_DATA; gen_participant_data(participant, rtps_sub.data); gen_sentinel(rtps_sub.data); gen_rtps_handler_out(rtps_sub, participant, stimulus); - SB_mem.Push(gen_participant_mem_frame(participant)); push_reference; start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE [p0,p1,0] + -- MEMORY STATE: 1(p0),0(p1)/2 Log("Unmatch Participant 0 [Incompatible Built-in Endpoints]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -471,31 +532,23 @@ begin participant.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR) := '1'; participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; + m1 := DEFAULT_PARTICIPANT_DATA; gen_participant_data(participant, rtps_sub.data); gen_sentinel(rtps_sub.data); gen_rtps_handler_out(rtps_sub, participant, stimulus); - SB_mem.Push(gen_participant_mem_frame(participant)); push_reference; start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE [0,p1,0] - - -- DUMMY PACKET (Trigger last mem check) - -- Mark Packet as non-standard Payload, in order to trigger the packet to be skipped (as early as possible) - rtps_sub.data := EMPTY_TEST_PACKET; - rtps_sub.flags(SUBMESSAGE_NON_STANDARD_PAYLOAD_FLAG_POS):= '1'; - gen_rtps_handler_out(rtps_sub, participant, stimulus); - start_test; - wait_on_complete; + -- MEMORY STATE: 0(p1)/1,2 stim_done <= '1'; - wait until check_done = '1'; + wait_on_complete; TranscriptOpen(RESULTS_FILE, APPEND_MODE); SetTranscriptMirror; - AlertIf((not SB_out.empty) or (not SB_mem.empty), "Incomplete test run"); ReportAlerts; TranscriptClose; std.env.stop; @@ -570,39 +623,59 @@ begin output_check_prc : process(all) begin - check_done <= '0'; if rising_edge(clk) then if (endpoint_wr /= (0 to NUM_ENDPOINTS-1 => '0')) then SB_out.Check(endpoint_wr & last_word_out & data_out); end if; if (stim_done = '1' and SB_out.empty) then check_done <= '1'; + else + check_done <= '0'; + end if; + end if; + end process; + + done_proc : process(clk) + begin + if rising_edge(clk) then + if (stim_done = '1' and SB_mem.empty and check_done = '1') then + test_done <= '1'; + else + test_done <= '0'; end if; end if; end process; mem_check_prc : process - alias mem is <>; + alias mem is <>; alias mem_op_done is <>; + alias idle_sig is <>; variable reference : TEST_PARTICIPANT_MEMORY_FRAME_TYPE; begin + mem_check_done <= '0'; -- SAFEGUARD: (Prevent Fall-through Behavior) if (reset /= '0') then wait until reset = '0'; end if; - -- NOTE: The first read after the packet is sent signifies that the State Machine has begun processing the next packet. - -- The memory operation that could still be in progress is the last one concerning the last sent packet. - wait until packet_sent = '1'; - wait until rising_edge(rd_sig); + -- Wait for Packet to be sent + wait until rising_edge(packet_sent); + -- Wait for UUT IDLE state + if (idle_sig /= '1') then + wait until idle_sig = '1'; + end if; + -- Wait for ongoing memory operation if (mem_op_done /= '1') then wait until mem_op_done = '1'; end if; - if (not SB_mem.empty) then + while (not SB_mem.empty) loop SB_mem.Pop(reference); for i in 0 to reference'length-1 loop AffirmIf(?? (mem(reference(i).addr) ?= reference(i).data), "Address: " & integer'image(reference(i).addr) & " Received: " & to_hstring(mem(reference(i).addr)) & " Expected: " & to_hstring(reference(i).data)); end loop; - end if; + end loop; + -- Toggle High for one clock cycle + mem_check_done <= '1'; + wait until rising_edge(clk); end process; watchdog : process diff --git a/src/Tests/Level_0/L0_rtps_builtin_endpoint_test3.vhd b/src/Tests/Level_0/L0_rtps_builtin_endpoint_test3.vhd index 7450e59..5fc940a 100644 --- a/src/Tests/Level_0/L0_rtps_builtin_endpoint_test3.vhd +++ b/src/Tests/Level_0/L0_rtps_builtin_endpoint_test3.vhd @@ -11,8 +11,10 @@ use work.rtps_config_package.all; 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 built-in endpoint. --- We also issue a parameter list that is missing its sentinel. +-- and one with valid larger parameter length (extra Bytes after expected parameter end) for each of the parameters that are handled by the built-in endpoint 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 match frame +-- The Participant -- The PIDs handled are: -- * PID_PARTICIPANT_GUID -- * PID_DOMAIN_ID @@ -64,10 +66,24 @@ architecture testbench of L0_rtps_builtin_endpoint_test3 is signal start : std_logic := '0'; shared variable SB_out : work.ScoreBoardPkg_builtin_endpoint.ScoreBoardPType; shared variable SB_mem : work.ScoreBoardPkg_MemoryTest.ScoreBoardPType; - signal stim_done, check_done, mem_check : std_logic := '0'; + signal stim_done, check_done, mem_check_done, test_done : std_logic := '0'; -- *FUNCTION DECLARATION* procedure wait_on_complete is + begin + if (test_done /= '1') then + wait until test_done = '1'; + end if; + end procedure; + + procedure wait_on_mem_check is + begin + if (mem_check_done /= '1') then + wait until mem_check_done = '1'; + end if; + end procedure; + + procedure wait_on_sent is begin wait until rising_edge(packet_sent); end procedure; @@ -160,10 +176,9 @@ begin procedure start_test is begin - start <= '1'; + start <= '1'; wait until rising_edge(clk); - start <= '0'; - mem_check <= '0'; + start <= '0'; wait until rising_edge(clk); end procedure; begin @@ -217,7 +232,6 @@ begin e0.type_name := ENDPOINT_TYPE(0); Log("Initiating Test", INFO); - mem_check <= '1'; stim_done <= '0'; start <= '0'; reset <= '1'; @@ -233,8 +247,8 @@ begin gen_rtps_handler_out(sub, participant, stimulus); SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - mem_check <= '1'; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub.data := EMPTY_TEST_PACKET; @@ -250,10 +264,9 @@ begin gen_participant_data(participant, sub.data, PID_PARTICIPANT_GUID, -1); gen_sentinel(sub.data); gen_rtps_handler_out(sub, participant, stimulus); - SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - mem_check <= '1'; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub.data := EMPTY_TEST_PACKET; @@ -270,8 +283,8 @@ begin gen_rtps_handler_out(sub, participant, stimulus); SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - mem_check <= '1'; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub.data := EMPTY_TEST_PACKET; @@ -287,10 +300,9 @@ begin gen_participant_data(participant, sub.data, PID_DOMAIN_ID, -1); gen_sentinel(sub.data); gen_rtps_handler_out(sub, participant, stimulus); - SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - mem_check <= '1'; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub.data := EMPTY_TEST_PACKET; @@ -307,8 +319,8 @@ begin gen_rtps_handler_out(sub, participant, stimulus); SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - mem_check <= '1'; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub.data := EMPTY_TEST_PACKET; @@ -324,10 +336,9 @@ begin gen_participant_data(participant, sub.data, PID_DOMAIN_TAG, -1); gen_sentinel(sub.data); gen_rtps_handler_out(sub, participant, stimulus); - SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - mem_check <= '1'; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub.data := EMPTY_TEST_PACKET; @@ -344,8 +355,8 @@ begin gen_rtps_handler_out(sub, participant, stimulus); SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - mem_check <= '1'; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub.data := EMPTY_TEST_PACKET; @@ -361,10 +372,9 @@ begin gen_participant_data(participant, sub.data, PID_PROTOCOL_VERSION, -1); gen_sentinel(sub.data); gen_rtps_handler_out(sub, participant, stimulus); - SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - mem_check <= '1'; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub.data := EMPTY_TEST_PACKET; @@ -381,8 +391,8 @@ begin gen_rtps_handler_out(sub, participant, stimulus); SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - mem_check <= '1'; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub.data := EMPTY_TEST_PACKET; @@ -398,10 +408,9 @@ begin gen_participant_data(participant, sub.data, PID_PARTICIPANT_LEASE_DURATION, -1); gen_sentinel(sub.data); gen_rtps_handler_out(sub, participant, stimulus); - SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - mem_check <= '1'; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub.data := EMPTY_TEST_PACKET; @@ -418,8 +427,8 @@ begin gen_rtps_handler_out(sub, participant, stimulus); SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - mem_check <= '1'; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub.data := EMPTY_TEST_PACKET; @@ -435,10 +444,9 @@ begin gen_participant_data(participant, sub.data, PID_BUILTIN_ENDPOINT_SET, -1); gen_sentinel(sub.data); gen_rtps_handler_out(sub, participant, stimulus); - SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - mem_check <= '1'; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub.data := EMPTY_TEST_PACKET; @@ -455,8 +463,8 @@ begin gen_rtps_handler_out(sub, participant, stimulus); SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - mem_check <= '1'; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub.data := EMPTY_TEST_PACKET; @@ -473,10 +481,9 @@ begin gen_participant_data(participant, sub.data, PID_DEFAULT_UNICAST_LOCATOR, -1); gen_sentinel(sub.data); gen_rtps_handler_out(sub, participant, stimulus); - SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - mem_check <= '1'; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub.data := EMPTY_TEST_PACKET; @@ -494,8 +501,8 @@ begin gen_rtps_handler_out(sub, participant, stimulus); SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - mem_check <= '1'; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub.data := EMPTY_TEST_PACKET; @@ -512,10 +519,9 @@ begin gen_participant_data(participant, sub.data, PID_DEFAULT_MULTICAST_LOCATOR, -1); gen_sentinel(sub.data); gen_rtps_handler_out(sub, participant, stimulus); - SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - mem_check <= '1'; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub.data := EMPTY_TEST_PACKET; @@ -533,8 +539,8 @@ begin gen_rtps_handler_out(sub, participant, stimulus); SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - mem_check <= '1'; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub.data := EMPTY_TEST_PACKET; @@ -551,10 +557,9 @@ begin gen_participant_data(participant, sub.data, PID_METATRAFFIC_UNICAST_LOCATOR, -1); gen_sentinel(sub.data); gen_rtps_handler_out(sub, participant, stimulus); - SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - mem_check <= '1'; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub.data := EMPTY_TEST_PACKET; @@ -572,8 +577,8 @@ begin gen_rtps_handler_out(sub, participant, stimulus); SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - mem_check <= '1'; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub.data := EMPTY_TEST_PACKET; @@ -590,10 +595,9 @@ begin gen_participant_data(participant, sub.data, PID_METATRAFFIC_MULTICAST_LOCATOR, -1); gen_sentinel(sub.data); gen_rtps_handler_out(sub, participant, stimulus); - SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - mem_check <= '1'; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub.data := EMPTY_TEST_PACKET; @@ -611,8 +615,8 @@ begin gen_rtps_handler_out(sub, participant, stimulus); SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - mem_check <= '1'; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub.data := EMPTY_TEST_PACKET; @@ -627,7 +631,8 @@ begin gen_endpoint_data(endpoint, sub_p.data); gen_rtps_handler_out(sub_p, endpoint, stimulus); start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -642,7 +647,8 @@ begin gen_sentinel(sub_p.data); gen_rtps_handler_out(sub_p, endpoint, stimulus); start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -658,7 +664,8 @@ begin wr_sig := (0 => '1', 9 => '1', 10 => '1', 15 => '1', others => '0'); push_endpoint_reference; start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -674,7 +681,8 @@ begin gen_sentinel(sub_p.data); gen_rtps_handler_out(sub_p, endpoint, stimulus); start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -690,7 +698,8 @@ begin wr_sig := (0 => '1', 9 => '1', 10 => '1', 15 => '1', others => '0'); push_endpoint_reference; start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -706,7 +715,8 @@ begin gen_sentinel(sub_p.data); gen_rtps_handler_out(sub_p, endpoint, stimulus); start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -722,7 +732,8 @@ begin wr_sig := (0 => '1', 9 => '1', 10 => '1', 15 => '1', others => '0'); push_endpoint_reference; start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -738,7 +749,8 @@ begin gen_sentinel(sub_p.data); gen_rtps_handler_out(sub_p, endpoint, stimulus); start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -754,7 +766,8 @@ begin wr_sig := (0 => '1', 9 => '1', 10 => '1', 15 => '1', others => '0'); push_endpoint_reference; start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -770,7 +783,8 @@ begin gen_sentinel(sub_p.data); gen_rtps_handler_out(sub_p, endpoint, stimulus); start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -786,7 +800,8 @@ begin wr_sig := (0 => '1', 9 => '1', 10 => '1', 15 => '1', others => '0'); push_endpoint_reference; start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -802,7 +817,8 @@ begin gen_sentinel(sub_p.data); gen_rtps_handler_out(sub_p, endpoint, stimulus); start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -818,7 +834,8 @@ begin wr_sig := (0 => '1', 9 => '1', 10 => '1', 15 => '1', others => '0'); push_endpoint_reference; start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -834,7 +851,8 @@ begin gen_sentinel(sub_p.data); gen_rtps_handler_out(sub_p, endpoint, stimulus); start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -850,7 +868,8 @@ begin wr_sig := (0 => '1', 9 => '1', 10 => '1', 15 => '1', others => '0'); push_endpoint_reference; start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -866,7 +885,8 @@ begin gen_sentinel(sub_p.data); gen_rtps_handler_out(sub_p, endpoint, stimulus); start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -882,7 +902,8 @@ begin wr_sig := (0 => '1', 9 => '1', 10 => '1', 15 => '1', others => '0'); push_endpoint_reference; start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -898,7 +919,8 @@ begin gen_sentinel(sub_p.data); gen_rtps_handler_out(sub_p, endpoint, stimulus); start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -914,7 +936,8 @@ begin wr_sig := (0 => '1', 9 => '1', 10 => '1', 15 => '1', others => '0'); push_endpoint_reference; start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -930,7 +953,8 @@ begin gen_sentinel(sub_p.data); gen_rtps_handler_out(sub_p, endpoint, stimulus); start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -946,7 +970,8 @@ begin wr_sig := (0 => '1', 9 => '1', 10 => '1', 15 => '1', others => '0'); push_endpoint_reference; start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -962,7 +987,8 @@ begin gen_sentinel(sub_p.data); gen_rtps_handler_out(sub_p, endpoint, stimulus); start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -978,7 +1004,8 @@ begin wr_sig := (0 => '1', 9 => '1', 10 => '1', 15 => '1', others => '0'); push_endpoint_reference; start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -994,7 +1021,8 @@ begin gen_sentinel(sub_p.data); gen_rtps_handler_out(sub_p, endpoint, stimulus); start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -1010,7 +1038,8 @@ begin wr_sig := (0 => '1', 9 => '1', 10 => '1', 15 => '1', others => '0'); push_endpoint_reference; start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -1027,7 +1056,8 @@ begin gen_sentinel(sub_p.data); gen_rtps_handler_out(sub_p, endpoint, stimulus); start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -1044,7 +1074,8 @@ begin wr_sig := (0 => '1', 9 => '1', 10 => '1', 15 => '1', others => '0'); push_endpoint_reference; start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -1061,7 +1092,8 @@ begin gen_sentinel(sub_p.data); gen_rtps_handler_out(sub_p, endpoint, stimulus); start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -1078,7 +1110,8 @@ begin wr_sig := (0 => '1', 9 => '1', 10 => '1', 15 => '1', others => '0'); push_endpoint_reference; start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -1095,7 +1128,8 @@ begin gen_sentinel(sub_p.data); gen_rtps_handler_out(sub_p, endpoint, stimulus); start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; @@ -1112,17 +1146,17 @@ begin wr_sig := (0 => '1', 9 => '1', 10 => '1', 15 => '1', others => '0'); push_endpoint_reference; start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; p_snp := p_snp + 1; + stim_done <= '1'; + wait_on_complete; TranscriptOpen(RESULTS_FILE, APPEND_MODE); SetTranscriptMirror; - stim_done <= '1'; - wait until check_done = '1'; - AlertIf((not SB_out.empty) or (not SB_mem.empty), "Incomplete test run"); ReportAlerts; TranscriptClose; std.env.stop; @@ -1197,39 +1231,59 @@ begin output_check_prc : process(all) begin - check_done <= '0'; if rising_edge(clk) then if (endpoint_wr /= (0 to NUM_ENDPOINTS-1 => '0')) then SB_out.Check(endpoint_wr & last_word_out & data_out); end if; if (stim_done = '1' and SB_out.empty) then check_done <= '1'; + else + check_done <= '0'; + end if; + end if; + end process; + + done_proc : process(clk) + begin + if rising_edge(clk) then + if (stim_done = '1' and SB_mem.empty and check_done = '1') then + test_done <= '1'; + else + test_done <= '0'; end if; end if; end process; mem_check_prc : process - alias mem is <>; + alias mem is <>; alias mem_op_done is <>; + alias idle_sig is <>; variable reference : TEST_PARTICIPANT_MEMORY_FRAME_TYPE; begin + mem_check_done <= '0'; -- SAFEGUARD: (Prevent Fall-through Behavior) if (reset /= '0') then wait until reset = '0'; end if; - -- NOTE: The first read after the packet is sent signifies that the State Machine has begun processing the next packet. - -- The memory operation that could still be in progress is the last one concerning the last sent packet. - wait on packet_sent until (packet_sent = '1' and mem_check = '1'); - wait until rising_edge(rd_sig); + -- Wait for Packet to be sent + wait until rising_edge(packet_sent); + -- Wait for UUT IDLE state + if (idle_sig /= '1') then + wait until idle_sig = '1'; + end if; + -- Wait for ongoing memory operation if (mem_op_done /= '1') then wait until mem_op_done = '1'; end if; - if (not SB_mem.empty) then + while (not SB_mem.empty) loop SB_mem.Pop(reference); for i in 0 to reference'length-1 loop AffirmIf(?? (mem(reference(i).addr) ?= reference(i).data), "Address: " & integer'image(reference(i).addr) & " Received: " & to_hstring(mem(reference(i).addr)) & " Expected: " & to_hstring(reference(i).data)); end loop; - end if; + end loop; + -- Toggle High for one clock cycle + mem_check_done <= '1'; + wait until rising_edge(clk); end process; watchdog : process diff --git a/src/Tests/Level_0/L0_rtps_builtin_endpoint_test4.vhd b/src/Tests/Level_0/L0_rtps_builtin_endpoint_test4.vhd index 6e50c1e..df2b349 100644 --- a/src/Tests/Level_0/L0_rtps_builtin_endpoint_test4.vhd +++ b/src/Tests/Level_0/L0_rtps_builtin_endpoint_test4.vhd @@ -10,7 +10,7 @@ use work.user_config.all; use work.rtps_config_package.all; use work.rtps_test_package.all; --- This testbench tests the internal memory handling of the rtps_builtin_endpoint. (Full Capacity behaviour) +-- This testbench tests the sequence number handling of the participant, subscriber, and publisher DATA Submessages. entity L0_rtps_builtin_endpoint_test4 is end entity; @@ -18,7 +18,7 @@ end entity; architecture testbench of L0_rtps_builtin_endpoint_test4 is -- *CONSTANT DECLARATION* - constant MAX_REMOTE_PARTICIPANTS : natural := 4; + constant MAX_REMOTE_PARTICIPANTS : natural := 1; -- *TYPE DECLARATION* type TEST_STAGE_TYPE is (IDLE, BUSY); @@ -36,14 +36,36 @@ architecture testbench of L0_rtps_builtin_endpoint_test4 is signal start : std_logic := '0'; shared variable SB_out : work.ScoreBoardPkg_builtin_endpoint.ScoreBoardPType; shared variable SB_mem : work.ScoreBoardPkg_MemoryTest.ScoreBoardPType; - signal stim_done, check_done, mem_check : std_logic := '0'; + signal stim_done, mem_check_done, check_done, test_done : std_logic := '0'; -- *FUNCTION DECLARATION* procedure wait_on_complete is + begin + if (test_done /= '1') then + wait until test_done = '1'; + end if; + end procedure; + + procedure wait_on_mem_check is + begin + if (mem_check_done /= '1') then + wait until mem_check_done = '1'; + end if; + end procedure; + + procedure wait_on_sent is begin wait until rising_edge(packet_sent); end procedure; + function gen_sn(input : natural) return SEQUENCENUMBER_TYPE is + variable ret : SEQUENCENUMBER_TYPE; + begin + ret(0) := (others => '0'); + ret(1) := unsigned(int(input, WORD_WIDTH)); + return ret; + end function; + begin -- Unit Under Test @@ -69,10 +91,10 @@ begin ); stimulus_prc : process - variable sub, sub_p : RTPS_SUBMESSAGE_TYPE := DEFAULT_RTPS_SUBMESSAGE; + variable sub, sub_p, sub_s : RTPS_SUBMESSAGE_TYPE := DEFAULT_RTPS_SUBMESSAGE; variable RV : RandomPType; - variable p0, p1, participant: PARTICIPANT_DATA_TYPE := DEFAULT_PARTICIPANT_DATA; - variable e0, endpoint : ENDPOINT_DATA_TYPE := DEFAULT_ENDPOINT_DATA; + variable p0, participant : PARTICIPANT_DATA_TYPE := DEFAULT_PARTICIPANT_DATA; + variable e0, e1, endpoint : ENDPOINT_DATA_TYPE := DEFAULT_ENDPOINT_DATA; variable p_sn, p_snp : SEQUENCENUMBER_TYPE := FIRST_SEQUENCENUMBER; variable wr_sig : std_logic_vector(0 to NUM_ENDPOINTS-1) := (others => '0'); @@ -135,14 +157,13 @@ begin start <= '1'; wait until rising_edge(clk); start <= '0'; - mem_check <= '0'; wait until rising_edge(clk); end procedure; begin assert (TEST_STRING = "TEST_CONFIG_1") report "user_config incompatible with testbench." severity FAILURE; - SetAlertLogName("rtps_builtin_endpoint - Level 0 - Memory Handling"); + SetAlertLogName("rtps_builtin_endpoint - Level 0 - Sequence Number Handling"); SetAlertEnable(FAILURE, TRUE); SetAlertEnable(ERROR, TRUE); SetAlertEnable(WARNING, TRUE); @@ -165,6 +186,13 @@ begin sub_p.readerId := ENTITYID_SEDP_BUILTIN_PUBLICATIONS_DETECTOR; sub_p.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; + -- Subscriber Endpoint RTPS Submessage + sub_s := DEFAULT_RTPS_SUBMESSAGE; + sub_s.submessageID := SID_DATA; + sub_s.writerId := ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_ANNOUNCER; + sub_s.readerId := ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_DETECTOR; + sub_s.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; + -- Participant 0 p0.guidPrefix := gen_rand_guid_prefix; p0.nr := 0; @@ -174,20 +202,19 @@ begin p0.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; p0.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; - p1.guidPrefix := gen_rand_guid_prefix; - p1.nr := MAX_REMOTE_PARTICIPANTS; - p1.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); - p1.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR) := '1'; - p1.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER):= '1'; - p1.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; - p1.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; - e0.participant := p0; e0.topic_name := ENDPOINT_TOPIC(2); e0.type_name := ENDPOINT_TYPE(2); + e0.reader := FALSE; + e0.entityId := gen_rand_entityid_2(FALSE); + + e1.participant := p0; + e1.topic_name := ENDPOINT_TOPIC(2); + e1.type_name := ENDPOINT_TYPE(2); + e1.reader := TRUE; + e1.entityId := gen_rand_entityid_2(FALSE); Log("Initiating Test", INFO); - mem_check <= '1'; stim_done <= '0'; start <= '0'; reset <= '1'; @@ -195,92 +222,209 @@ begin wait until rising_edge(clk); reset <= '0'; - Log("Match Participant 0", INFO); - sub.writerSN := p_sn; - participant := p0; + -- *PARTICIPANT* + + Log("Match Participant 0 [SN 1]", INFO); + sub.writerSN := gen_sn(1); + participant := p0; + participant.nr := 0; + participant.match := MATCH; gen_participant_data(participant, sub.data); gen_sentinel(sub.data); gen_rtps_handler_out(sub, participant, stimulus); SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - mem_check <= '1'; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub.data := EMPTY_TEST_PACKET; - p_sn := p_sn + 1; - for i in 1 to MAX_REMOTE_PARTICIPANTS-1 loop - Log("Match Participant " & to_string(i), INFO); - sub.writerSN := p_sn; - participant := p0; - participant.guidPrefix := gen_rand_guid_prefix; - participant.nr := i; - gen_participant_data(participant, sub.data); - gen_sentinel(sub.data); - gen_rtps_handler_out(sub, participant, stimulus); - SB_mem.Push(gen_participant_mem_frame(participant)); - start_test; - mem_check <= '1'; - wait_on_complete; - stimulus := EMPTY_TEST_PACKET; - reference := EMPTY_TEST_PACKET; - sub.data := EMPTY_TEST_PACKET; - p_sn := p_sn + 1; - end loop; + p0.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); - Log("Ignore Participant" & to_string(MAX_REMOTE_PARTICIPANTS) & " [No memory available]", INFO); - sub.writerSN := p_sn; - participant := p1; + Log("Update Participant 0 [SN 2]", INFO); + sub.writerSN := gen_sn(2); + participant := p0; + participant.nr := 0; + participant.match := MATCH; gen_participant_data(participant, sub.data); gen_sentinel(sub.data); gen_rtps_handler_out(sub, participant, stimulus); + SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub.data := EMPTY_TEST_PACKET; - p_sn := p_sn + 1; + p0.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); - Log("Ignore Endpoint 0 Participant 1 [No matching Participant]", INFO); - sub_p.writerSN := p_snp; - endpoint := e0; - endpoint.participant:= p1; - endpoint.reader := FALSE; - endpoint.entityId := gen_rand_entityid_2(FALSE); - gen_endpoint_data(endpoint, sub_p.data); - gen_sentinel(sub_p.data); - gen_rtps_handler_out(sub_p, endpoint, stimulus); + Log("Update Participant 0 [SN 5]", INFO); + sub.writerSN := gen_sn(5); + participant := p0; + participant.nr := 0; + participant.match := MATCH; + gen_participant_data(participant, sub.data); + gen_sentinel(sub.data); + gen_rtps_handler_out(sub, participant, stimulus); + SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; - sub_p.data := EMPTY_TEST_PACKET; + sub.data := EMPTY_TEST_PACKET; - Log("Match Endpoint 0 Participant 0", INFO); - sub_p.writerSN := p_snp; + Log("Ignore Update Participant 0 [SN 3]", INFO); + sub.writerSN := gen_sn(3); + participant := p0; + participant.nr := 0; + participant.match := MATCH; + participant.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + gen_participant_data(participant, sub.data); + gen_sentinel(sub.data); + gen_rtps_handler_out(sub, participant, stimulus); + SB_mem.Push(gen_participant_mem_frame(p0)); + start_test; + wait_on_sent; + wait_on_mem_check; + stimulus := EMPTY_TEST_PACKET; + reference := EMPTY_TEST_PACKET; + sub.data := EMPTY_TEST_PACKET; + + -- *PUBLISHER* + + Log("Match Writer Participant 0 [SN 1]", INFO); + sub_p.writerSN := gen_sn(1); endpoint := e0; endpoint.participant:= p0; - endpoint.reader := FALSE; - endpoint.entityId := gen_rand_entityid_2(FALSE); gen_endpoint_data(endpoint, sub_p.data); gen_sentinel(sub_p.data); gen_rtps_handler_out(sub_p, endpoint, stimulus); wr_sig := (2 => '1', others => '0'); push_endpoint_reference; start_test; - wait_on_complete; + wait_on_sent; + wait_on_mem_check; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub_p.data := EMPTY_TEST_PACKET; - p_snp := p_snp + 1; + e0.unicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + + Log("Update Writer Participant 0 [SN 2]", INFO); + sub_p.writerSN := gen_sn(2); + endpoint := e0; + endpoint.participant:= p0; + gen_endpoint_data(endpoint, sub_p.data); + gen_sentinel(sub_p.data); + gen_rtps_handler_out(sub_p, endpoint, stimulus); + wr_sig := (2 => '1', others => '0'); + push_endpoint_reference; + start_test; + wait_on_sent; + wait_on_mem_check; + stimulus := EMPTY_TEST_PACKET; + reference := EMPTY_TEST_PACKET; + sub_p.data := EMPTY_TEST_PACKET; + + Log("Ignore Update Writer Participant 0 [SN 5]", INFO); + sub_p.writerSN := gen_sn(5); + endpoint := e0; + endpoint.participant:= p0; + gen_endpoint_data(endpoint, sub_p.data); + gen_sentinel(sub_p.data); + gen_rtps_handler_out(sub_p, endpoint, stimulus); + start_test; + wait_on_sent; + wait_on_mem_check; + stimulus := EMPTY_TEST_PACKET; + reference := EMPTY_TEST_PACKET; + sub_p.data := EMPTY_TEST_PACKET; + + Log("Ignore Update Writer Participant 0 [SN 1]", INFO); + sub_p.writerSN := gen_sn(1); + endpoint := e0; + endpoint.participant:= p0; + gen_endpoint_data(endpoint, sub_p.data); + gen_sentinel(sub_p.data); + gen_rtps_handler_out(sub_p, endpoint, stimulus); + start_test; + wait_on_sent; + wait_on_mem_check; + stimulus := EMPTY_TEST_PACKET; + reference := EMPTY_TEST_PACKET; + sub_p.data := EMPTY_TEST_PACKET; + + -- *SUBSCRIBER* + + Log("Match Reader Participant 0 [SN 1]", INFO); + sub_s.writerSN := gen_sn(1); + endpoint := e1; + endpoint.participant:= p0; + gen_endpoint_data(endpoint, sub_s.data); + gen_sentinel(sub_s.data); + gen_rtps_handler_out(sub_s, endpoint, stimulus); + wr_sig := (NUM_READERS+2 => '1', others => '0'); + push_endpoint_reference; + start_test; + wait_on_sent; + wait_on_mem_check; + stimulus := EMPTY_TEST_PACKET; + reference := EMPTY_TEST_PACKET; + sub_s.data := EMPTY_TEST_PACKET; + + e1.unicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + + Log("Update Reader Participant 0 [SN 2]", INFO); + sub_s.writerSN := gen_sn(2); + endpoint := e1; + endpoint.participant:= p0; + gen_endpoint_data(endpoint, sub_s.data); + gen_sentinel(sub_s.data); + gen_rtps_handler_out(sub_s, endpoint, stimulus); + wr_sig := (NUM_READERS+2 => '1', others => '0'); + push_endpoint_reference; + start_test; + wait_on_sent; + wait_on_mem_check; + stimulus := EMPTY_TEST_PACKET; + reference := EMPTY_TEST_PACKET; + sub_s.data := EMPTY_TEST_PACKET; + + Log("Ignore Update Reader Participant 0 [SN 5]", INFO); + sub_s.writerSN := gen_sn(5); + endpoint := e1; + endpoint.participant:= p0; + gen_endpoint_data(endpoint, sub_s.data); + gen_sentinel(sub_s.data); + gen_rtps_handler_out(sub_s, endpoint, stimulus); + start_test; + wait_on_sent; + wait_on_mem_check; + stimulus := EMPTY_TEST_PACKET; + reference := EMPTY_TEST_PACKET; + sub_s.data := EMPTY_TEST_PACKET; + + Log("Ignore Update Reader Participant 0 [SN 1]", INFO); + sub_s.writerSN := gen_sn(1); + endpoint := e1; + endpoint.participant:= p0; + gen_endpoint_data(endpoint, sub_s.data); + gen_sentinel(sub_s.data); + gen_rtps_handler_out(sub_s, endpoint, stimulus); + start_test; + wait_on_sent; + wait_on_mem_check; + stimulus := EMPTY_TEST_PACKET; + reference := EMPTY_TEST_PACKET; + sub_s.data := EMPTY_TEST_PACKET; + + stim_done <= '1'; + wait_on_complete; TranscriptOpen(RESULTS_FILE, APPEND_MODE); SetTranscriptMirror; - stim_done <= '1'; - wait until check_done = '1'; - AlertIf((not SB_out.empty) or (not SB_mem.empty), "Incomplete test run"); ReportAlerts; TranscriptClose; std.env.stop; @@ -355,39 +499,59 @@ begin output_check_prc : process(all) begin - check_done <= '0'; if rising_edge(clk) then if (endpoint_wr /= (0 to NUM_ENDPOINTS-1 => '0')) then SB_out.Check(endpoint_wr & last_word_out & data_out); end if; if (stim_done = '1' and SB_out.empty) then check_done <= '1'; + else + check_done <= '0'; + end if; + end if; + end process; + + done_proc : process(clk) + begin + if rising_edge(clk) then + if (stim_done = '1' and SB_mem.empty and check_done = '1') then + test_done <= '1'; + else + test_done <= '0'; end if; end if; end process; mem_check_prc : process - alias mem is <>; + alias mem is <>; alias mem_op_done is <>; + alias idle_sig is <>; variable reference : TEST_PARTICIPANT_MEMORY_FRAME_TYPE; begin + mem_check_done <= '0'; -- SAFEGUARD: (Prevent Fall-through Behavior) if (reset /= '0') then wait until reset = '0'; end if; - -- NOTE: The first read after the packet is sent signifies that the State Machine has begun processing the next packet. - -- The memory operation that could still be in progress is the last one concerning the last sent packet. - wait on packet_sent until (packet_sent = '1' and mem_check = '1'); - wait until rising_edge(rd_sig); + -- Wait for Packet to be sent + wait until rising_edge(packet_sent); + -- Wait for UUT IDLE state + if (idle_sig /= '1') then + wait until idle_sig = '1'; + end if; + -- Wait for ongoing memory operation if (mem_op_done /= '1') then wait until mem_op_done = '1'; end if; - if (not SB_mem.empty) then + while (not SB_mem.empty) loop SB_mem.Pop(reference); for i in 0 to reference'length-1 loop AffirmIf(?? (mem(reference(i).addr) ?= reference(i).data), "Address: " & integer'image(reference(i).addr) & " Received: " & to_hstring(mem(reference(i).addr)) & " Expected: " & to_hstring(reference(i).data)); end loop; - end if; + end loop; + -- Toggle High for one clock cycle + mem_check_done <= '1'; + wait until rising_edge(clk); end process; watchdog : process diff --git a/src/Tests/Level_0/L0_rtps_builtin_endpoint_test5.vhd b/src/Tests/Level_0/L0_rtps_builtin_endpoint_test5.vhd index 0120320..679d4d6 100644 --- a/src/Tests/Level_0/L0_rtps_builtin_endpoint_test5.vhd +++ b/src/Tests/Level_0/L0_rtps_builtin_endpoint_test5.vhd @@ -10,7 +10,10 @@ use work.user_config.all; use work.rtps_config_package.all; use work.rtps_test_package.all; --- This testbench tests the sequence number handling of the participant, subscriber, and publisher DATA Submessages. +-- This testbench tests the stale participant handling of the rtps_builtin_endpoint. It does so by checking for the Participant Unmatch Frame. +-- It first matches 3 Participants: Participant 0 with default lease duration 100s, Participant 1 with lease duration 10s, and Participant 2 with lease duration 30s. +-- After matching the time is artificially progressed to 15s (from 0s), and the removal of Participant 1 is checked. Than the time is again artificially progressed to 101s +-- and the removal of Participant 0 and 2 is checked (in that order). entity L0_rtps_builtin_endpoint_test5 is end entity; @@ -18,7 +21,7 @@ end entity; architecture testbench of L0_rtps_builtin_endpoint_test5 is -- *CONSTANT DECLARATION* - constant MAX_REMOTE_PARTICIPANTS : natural := 1; + constant MAX_REMOTE_PARTICIPANTS : natural := 3; -- *TYPE DECLARATION* type TEST_STAGE_TYPE is (IDLE, BUSY); @@ -35,11 +38,18 @@ architecture testbench of L0_rtps_builtin_endpoint_test5 is signal cnt_stim : natural := 0; signal start : std_logic := '0'; shared variable SB_out : work.ScoreBoardPkg_builtin_endpoint.ScoreBoardPType; - shared variable SB_mem : work.ScoreBoardPkg_MemoryTest.ScoreBoardPType; - signal stim_done, check_done, mem_check : std_logic := '0'; + signal stim_done, check_done, test_done : std_logic := '0'; + signal test_time : TIME_TYPE := TIME_ZERO; -- *FUNCTION DECLARATION* procedure wait_on_complete is + begin + if (test_done /= '1') then + wait until test_done = '1'; + end if; + end procedure; + + procedure wait_on_sent is begin wait until rising_edge(packet_sent); end procedure; @@ -67,7 +77,7 @@ begin data_in => data_in, data_out => data_out, last_word_in => last_word_in, - time => TIME_ZERO, + time => test_time, endpoint_full => endpoint_full, endpoint_wr => endpoint_wr, rtps_wr => open, @@ -77,12 +87,14 @@ begin ); stimulus_prc : process - variable sub, sub_p, sub_s : RTPS_SUBMESSAGE_TYPE := DEFAULT_RTPS_SUBMESSAGE; - variable RV : RandomPType; - variable p0, participant : PARTICIPANT_DATA_TYPE := DEFAULT_PARTICIPANT_DATA; - variable e0, e1, endpoint : ENDPOINT_DATA_TYPE := DEFAULT_ENDPOINT_DATA; - variable p_sn, p_snp : SEQUENCENUMBER_TYPE := FIRST_SEQUENCENUMBER; - variable wr_sig : std_logic_vector(0 to NUM_ENDPOINTS-1) := (others => '0'); + variable sub : RTPS_SUBMESSAGE_TYPE := DEFAULT_RTPS_SUBMESSAGE; + variable RV : RandomPType; + variable p_sn : SEQUENCENUMBER_TYPE := FIRST_SEQUENCENUMBER; + variable wr_sig : std_logic_vector(0 to NUM_ENDPOINTS-1) := (others => '0'); + variable p0, p1, p2, participant : PARTICIPANT_DATA_TYPE := DEFAULT_PARTICIPANT_DATA; + + alias idle_sig is <>; + alias mem_op_done is <>; -- Wrapper to use procedure as function impure function gen_rand_loc_2 return LOCATOR_TYPE is @@ -99,28 +111,6 @@ begin return ret; end function; - procedure push_endpoint_reference is - begin - -- MATCH - if (wr_sig /= (wr_sig'range => '0')) then - endpoint.match := MATCH; - gen_endpoint_match_frame(endpoint, reference); - for i in 0 to reference.length-1 loop - SB_out.Push(wr_sig & reference.last(i) & reference.data(i)); - end loop; - reference := EMPTY_TEST_PACKET; - end if; - -- UNMATCH - if ((not wr_sig) /= (wr_sig'range => '0')) then - endpoint.match := UNMATCH; - gen_endpoint_match_frame(endpoint, reference); - for i in 0 to reference.length-1 loop - SB_out.Push((not wr_sig) & reference.last(i) & reference.data(i)); - end loop; - reference := EMPTY_TEST_PACKET; - end if; - end procedure; - procedure push_participant_reference is variable wr_sig : std_logic_vector(NUM_ENDPOINTS-1 downto 0) := (others => '1'); begin @@ -140,17 +130,33 @@ begin procedure start_test is begin - start <= '1'; + start <= '1'; wait until rising_edge(clk); - start <= '0'; - mem_check <= '0'; + start <= '0'; wait until rising_edge(clk); end procedure; + + -- NOTE: This procedure waits until the idle_sig is high for at least + -- two consecutive clock cycles. + procedure wait_on_idle is + variable first : boolean := TRUE; + begin + loop + if (idle_sig /= '1' or mem_op_done /= '1') then + wait until idle_sig = '1' and mem_op_done = '1'; + elsif (not first) then + exit; + end if; + wait until rising_edge(clk); + wait until rising_edge(clk); + first := FALSE; + end loop; + end procedure; begin assert (TEST_STRING = "TEST_CONFIG_1") report "user_config incompatible with testbench." severity FAILURE; - SetAlertLogName("rtps_builtin_endpoint - Level 0 - Sequence Number Handling"); + SetAlertLogName("rtps_builtin_endpoint - Level 0 - Stale Participant Handling"); SetAlertEnable(FAILURE, TRUE); SetAlertEnable(ERROR, TRUE); SetAlertEnable(WARNING, TRUE); @@ -166,21 +172,7 @@ begin sub.readerId := ENTITYID_SPDP_BUILTIN_PARTICIPANT_DETECTOR; sub.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; - -- Publisher Endpoint RTPS Submessage - sub_p := DEFAULT_RTPS_SUBMESSAGE; - sub_p.submessageID := SID_DATA; - sub_p.writerId := ENTITYID_SEDP_BUILTIN_PUBLICATIONS_ANNOUNCER; - sub_p.readerId := ENTITYID_SEDP_BUILTIN_PUBLICATIONS_DETECTOR; - sub_p.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; - - -- Subscriber Endpoint RTPS Submessage - sub_s := DEFAULT_RTPS_SUBMESSAGE; - sub_s.submessageID := SID_DATA; - sub_s.writerId := ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_ANNOUNCER; - sub_s.readerId := ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_DETECTOR; - sub_s.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; - - -- Participant 0 + -- Participant 0 (Default Lease Time 100 s) p0.guidPrefix := gen_rand_guid_prefix; p0.nr := 0; p0.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); @@ -189,20 +181,28 @@ begin p0.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; p0.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; - e0.participant := p0; - e0.topic_name := ENDPOINT_TOPIC(2); - e0.type_name := ENDPOINT_TYPE(2); - e0.reader := FALSE; - e0.entityId := gen_rand_entityid_2(FALSE); + -- Participant 1 (Lease Duration 10 s) + p1.guidPrefix := gen_rand_guid_prefix; + p1.nr := 1; + p1.leaseDuration := gen_duration(10,0); + p1.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + p1.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR) := '1'; + p1.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER):= '1'; + p1.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; + p1.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; - e1.participant := p0; - e1.topic_name := ENDPOINT_TOPIC(2); - e1.type_name := ENDPOINT_TYPE(2); - e1.reader := TRUE; - e1.entityId := gen_rand_entityid_2(FALSE); + -- Participant 2 (Lease Duration 30 s) + p2.guidPrefix := gen_rand_guid_prefix; + p2.nr := 2; + p2.leaseDuration := gen_duration(30,0); + p2.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + p2.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR) := '1'; + p2.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER):= '1'; + p2.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; + p2.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; Log("Initiating Test", INFO); - mem_check <= '1'; + test_time <= TIME_ZERO; stim_done <= '0'; start <= '0'; reset <= '1'; @@ -211,201 +211,71 @@ begin reset <= '0'; -- *PARTICIPANT* - - Log("Match Participant 0 [SN 1]", INFO); - sub.writerSN := gen_sn(1); + Log("Current Time: 0s", INFO); + Log("Match Participant 0 [Default Lease 100s]", INFO); + sub.writerSN := p_sn; participant := p0; - participant.nr := 0; - participant.match := MATCH; gen_participant_data(participant, sub.data); gen_sentinel(sub.data); gen_rtps_handler_out(sub, participant, stimulus); - SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - mem_check <= '1'; - wait_on_complete; + wait_on_sent; + wait_on_idle; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub.data := EMPTY_TEST_PACKET; + p_sn := p_sn + 1; - p0.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); - - Log("Update Participant 0 [SN 2]", INFO); - sub.writerSN := gen_sn(2); - participant := p0; - participant.nr := 0; - participant.match := MATCH; + Log("Match Participant 1 [Lease 10s]", INFO); + sub.writerSN := p_sn; + participant := p1; gen_participant_data(participant, sub.data); gen_sentinel(sub.data); gen_rtps_handler_out(sub, participant, stimulus); - SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - mem_check <= '1'; - wait_on_complete; + wait_on_sent; + wait_on_idle; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub.data := EMPTY_TEST_PACKET; + p_sn := p_sn + 1; - p0.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); - - Log("Update Participant 0 [SN 5]", INFO); - sub.writerSN := gen_sn(5); - participant := p0; - participant.nr := 0; - participant.match := MATCH; + Log("Match Participant 2 [Lease 30s]", INFO); + sub.writerSN := p_sn; + participant := p2; gen_participant_data(participant, sub.data); gen_sentinel(sub.data); gen_rtps_handler_out(sub, participant, stimulus); - SB_mem.Push(gen_participant_mem_frame(participant)); start_test; - mem_check <= '1'; - wait_on_complete; + wait_on_sent; + wait_on_idle; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; sub.data := EMPTY_TEST_PACKET; + p_sn := p_sn + 1; - Log("Ignore Update Participant 0 [SN 3]", INFO); - sub.writerSN := gen_sn(3); + + Log("Current Time: 15 s", INFO); + test_time <= gen_duration(15,0); + participant := p1; + participant.match := UNMATCH; + push_participant_reference; + wait_on_idle; + + Log("Current Time: 101 s", INFO); + test_time <= (unsigned(int(101, CDR_LONG_WIDTH)), unsigned(int(0, CDR_LONG_WIDTH))); + participant := p2; + participant.match := UNMATCH; + push_participant_reference; participant := p0; - participant.nr := 0; - participant.match := MATCH; - participant.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); - gen_participant_data(participant, sub.data); - gen_sentinel(sub.data); - gen_rtps_handler_out(sub, participant, stimulus); - SB_mem.Push(gen_participant_mem_frame(p0)); - start_test; - mem_check <= '1'; + participant.match := UNMATCH; + push_participant_reference; + wait_on_idle; + + stim_done <= '1'; wait_on_complete; - stimulus := EMPTY_TEST_PACKET; - reference := EMPTY_TEST_PACKET; - sub.data := EMPTY_TEST_PACKET; - - -- *PUBLISHER* - - Log("Match Writer Participant 0 [SN 1]", INFO); - sub_p.writerSN := gen_sn(1); - endpoint := e0; - endpoint.participant:= p0; - gen_endpoint_data(endpoint, sub_p.data); - gen_sentinel(sub_p.data); - gen_rtps_handler_out(sub_p, endpoint, stimulus); - wr_sig := (2 => '1', others => '0'); - push_endpoint_reference; - start_test; - wait_on_complete; - stimulus := EMPTY_TEST_PACKET; - reference := EMPTY_TEST_PACKET; - sub_p.data := EMPTY_TEST_PACKET; - - e0.unicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); - - Log("Update Writer Participant 0 [SN 2]", INFO); - sub_p.writerSN := gen_sn(2); - endpoint := e0; - endpoint.participant:= p0; - gen_endpoint_data(endpoint, sub_p.data); - gen_sentinel(sub_p.data); - gen_rtps_handler_out(sub_p, endpoint, stimulus); - wr_sig := (2 => '1', others => '0'); - push_endpoint_reference; - start_test; - wait_on_complete; - stimulus := EMPTY_TEST_PACKET; - reference := EMPTY_TEST_PACKET; - sub_p.data := EMPTY_TEST_PACKET; - - Log("Ignore Update Writer Participant 0 [SN 5]", INFO); - sub_p.writerSN := gen_sn(5); - endpoint := e0; - endpoint.participant:= p0; - gen_endpoint_data(endpoint, sub_p.data); - gen_sentinel(sub_p.data); - gen_rtps_handler_out(sub_p, endpoint, stimulus); - start_test; - wait_on_complete; - stimulus := EMPTY_TEST_PACKET; - reference := EMPTY_TEST_PACKET; - sub_p.data := EMPTY_TEST_PACKET; - - Log("Ignore Update Writer Participant 0 [SN 1]", INFO); - sub_p.writerSN := gen_sn(1); - endpoint := e0; - endpoint.participant:= p0; - gen_endpoint_data(endpoint, sub_p.data); - gen_sentinel(sub_p.data); - gen_rtps_handler_out(sub_p, endpoint, stimulus); - start_test; - wait_on_complete; - stimulus := EMPTY_TEST_PACKET; - reference := EMPTY_TEST_PACKET; - sub_p.data := EMPTY_TEST_PACKET; - - -- *SUBSCRIBER* - - Log("Match Reader Participant 0 [SN 1]", INFO); - sub_s.writerSN := gen_sn(1); - endpoint := e1; - endpoint.participant:= p0; - gen_endpoint_data(endpoint, sub_s.data); - gen_sentinel(sub_s.data); - gen_rtps_handler_out(sub_s, endpoint, stimulus); - wr_sig := (NUM_READERS+2 => '1', others => '0'); - push_endpoint_reference; - start_test; - wait_on_complete; - stimulus := EMPTY_TEST_PACKET; - reference := EMPTY_TEST_PACKET; - sub_s.data := EMPTY_TEST_PACKET; - - e1.unicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); - - Log("Update Reader Participant 0 [SN 2]", INFO); - sub_s.writerSN := gen_sn(2); - endpoint := e1; - endpoint.participant:= p0; - gen_endpoint_data(endpoint, sub_s.data); - gen_sentinel(sub_s.data); - gen_rtps_handler_out(sub_s, endpoint, stimulus); - wr_sig := (NUM_READERS+2 => '1', others => '0'); - push_endpoint_reference; - start_test; - wait_on_complete; - stimulus := EMPTY_TEST_PACKET; - reference := EMPTY_TEST_PACKET; - sub_s.data := EMPTY_TEST_PACKET; - - Log("Ignore Update Reader Participant 0 [SN 5]", INFO); - sub_s.writerSN := gen_sn(5); - endpoint := e1; - endpoint.participant:= p0; - gen_endpoint_data(endpoint, sub_s.data); - gen_sentinel(sub_s.data); - gen_rtps_handler_out(sub_s, endpoint, stimulus); - start_test; - wait_on_complete; - stimulus := EMPTY_TEST_PACKET; - reference := EMPTY_TEST_PACKET; - sub_s.data := EMPTY_TEST_PACKET; - - Log("Ignore Update Reader Participant 0 [SN 1]", INFO); - sub_s.writerSN := gen_sn(1); - endpoint := e1; - endpoint.participant:= p0; - gen_endpoint_data(endpoint, sub_s.data); - gen_sentinel(sub_s.data); - gen_rtps_handler_out(sub_s, endpoint, stimulus); - start_test; - wait_on_complete; - stimulus := EMPTY_TEST_PACKET; - reference := EMPTY_TEST_PACKET; - sub_s.data := EMPTY_TEST_PACKET; - TranscriptOpen(RESULTS_FILE, APPEND_MODE); SetTranscriptMirror; - stim_done <= '1'; - wait until check_done = '1'; - AlertIf((not SB_out.empty) or (not SB_mem.empty), "Incomplete test run"); ReportAlerts; TranscriptClose; std.env.stop; @@ -480,38 +350,26 @@ begin output_check_prc : process(all) begin - check_done <= '0'; if rising_edge(clk) then if (endpoint_wr /= (0 to NUM_ENDPOINTS-1 => '0')) then SB_out.Check(endpoint_wr & last_word_out & data_out); end if; if (stim_done = '1' and SB_out.empty) then check_done <= '1'; + else + check_done <= '0'; end if; end if; end process; - mem_check_prc : process - alias mem is <>; - alias mem_op_done is <>; - variable reference : TEST_PARTICIPANT_MEMORY_FRAME_TYPE; + done_proc : process(clk) begin - -- SAFEGUARD: (Prevent Fall-through Behavior) - if (reset /= '0') then - wait until reset = '0'; - end if; - -- NOTE: The first read after the packet is sent signifies that the State Machine has begun processing the next packet. - -- The memory operation that could still be in progress is the last one concerning the last sent packet. - wait on packet_sent until (packet_sent = '1' and mem_check = '1'); - wait until rising_edge(rd_sig); - if (mem_op_done /= '1') then - wait until mem_op_done = '1'; - end if; - if (not SB_mem.empty) then - SB_mem.Pop(reference); - for i in 0 to reference'length-1 loop - AffirmIf(?? (mem(reference(i).addr) ?= reference(i).data), "Address: " & integer'image(reference(i).addr) & " Received: " & to_hstring(mem(reference(i).addr)) & " Expected: " & to_hstring(reference(i).data)); - end loop; + if rising_edge(clk) then + if (stim_done = '1' and check_done = '1') then + test_done <= '1'; + else + test_done <= '0'; + end if; end if; end process; diff --git a/src/Tests/Level_0/L0_rtps_builtin_endpoint_test6.vhd b/src/Tests/Level_0/L0_rtps_builtin_endpoint_test6.vhd index e6ea5c4..866f2e4 100644 --- a/src/Tests/Level_0/L0_rtps_builtin_endpoint_test6.vhd +++ b/src/Tests/Level_0/L0_rtps_builtin_endpoint_test6.vhd @@ -10,23 +10,17 @@ use work.user_config.all; use work.rtps_config_package.all; use work.rtps_test_package.all; --- This testbench tests the stale participant handling of the rtps_builtin_endpoint. --- It first matches 3 Participants: Participant 0 with default lease duration 100s, Participant 1 with lease duration 10s, and Participant 2 with lease duration 30s. --- After matching the time is artificially progressed to 15s (from 0s), and the removal of Participant 1 is checked. Than the time is again artificially progressed to 101s --- and the removal of Participant 0 and 2 is checked (in that order). --- Note that dummy packets are sent in between to trigger the memory contents checks, since the stale checks are done in between packet processing. +-- This testbench tests the handling of remote Liveliness Assertions +-- The testbench matches 2 remote Participants, P0 and P1. P0 sends an automatic liveliness assertion, while P1 sends a manual liveliness assertion. +-- P0 also sends a manual liveliness assertion with extra Bytes. entity L0_rtps_builtin_endpoint_test6 is end entity; architecture testbench of L0_rtps_builtin_endpoint_test6 is - -- *CONSTANT DECLARATION* - constant MAX_REMOTE_PARTICIPANTS : natural := 3; - -- *TYPE DECLARATION* type TEST_STAGE_TYPE is (IDLE, BUSY); - type TEST_RAM_TYPE is array (0 to (MAX_REMOTE_PARTICIPANTS*PARTICIPANT_FRAME_SIZE)-1) of std_logic_vector(WORD_WIDTH-1 downto 0); -- *SIGNAL DECLARATION* signal clk, in_empty, rd_sig, last_word_in, last_word_out: std_logic := '0'; @@ -39,9 +33,7 @@ architecture testbench of L0_rtps_builtin_endpoint_test6 is signal cnt_stim : natural := 0; signal start : std_logic := '0'; shared variable SB_out : work.ScoreBoardPkg_builtin_endpoint.ScoreBoardPType; - shared variable SB_mem : work.ScoreBoardPkg_MemoryTest.ScoreBoardPType; signal stim_done, check_done, mem_check : std_logic := '0'; - signal test_time : TIME_TYPE := TIME_ZERO; -- *FUNCTION DECLARATION* procedure wait_on_complete is @@ -62,7 +54,7 @@ begin -- Unit Under Test uut : entity work.rtps_builtin_endpoint(arch) generic map ( - MAX_REMOTE_PARTICIPANTS => MAX_REMOTE_PARTICIPANTS + MAX_REMOTE_PARTICIPANTS => 2 ) port map ( clk => clk, @@ -72,7 +64,7 @@ begin data_in => data_in, data_out => data_out, last_word_in => last_word_in, - time => test_time, + time => TIME_ZERO, endpoint_full => endpoint_full, endpoint_wr => endpoint_wr, rtps_wr => open, @@ -82,11 +74,11 @@ begin ); stimulus_prc : process - variable sub : RTPS_SUBMESSAGE_TYPE := DEFAULT_RTPS_SUBMESSAGE; - variable RV : RandomPType; - variable p_sn : SEQUENCENUMBER_TYPE := FIRST_SEQUENCENUMBER; - variable wr_sig : std_logic_vector(0 to NUM_ENDPOINTS-1) := (others => '0'); - variable p0, p1, p2, participant : PARTICIPANT_DATA_TYPE := DEFAULT_PARTICIPANT_DATA; + variable sub : RTPS_SUBMESSAGE_TYPE := DEFAULT_RTPS_SUBMESSAGE; + variable RV : RandomPType; + variable p0, p1, participant: PARTICIPANT_DATA_TYPE := DEFAULT_PARTICIPANT_DATA; + variable wr_sig : std_logic_vector(0 to NUM_ENDPOINTS-1) := (others => '0'); + variable rand_data : TEST_PACKET_TYPE := EMPTY_TEST_PACKET; -- Wrapper to use procedure as function impure function gen_rand_loc_2 return LOCATOR_TYPE is @@ -96,23 +88,6 @@ begin return ret; end function; - impure function gen_rand_entityid_2(reader : boolean) return std_logic_vector is - variable ret : std_logic_vector(ENTITYID_WIDTH-1 downto 0) := (others => '0'); - begin - gen_rand_entityid(RV, reader, ret); - return ret; - end function; - - procedure push_participant_reference is - variable wr_sig : std_logic_vector(NUM_ENDPOINTS-1 downto 0) := (others => '1'); - begin - gen_participant_match_frame(participant, reference); - for i in 0 to reference.length-1 loop - SB_out.Push(wr_sig & reference.last(i) & reference.data(i)); - end loop; - reference := EMPTY_TEST_PACKET; - end procedure; - impure function gen_rand_guid_prefix return GUIDPREFIX_TYPE is variable ret : GUIDPREFIX_TYPE; begin @@ -120,6 +95,13 @@ begin return ret; end function; + procedure push_reference is + begin + for i in 0 to reference.length-1 loop + SB_out.Push(wr_sig & reference.last(i) & reference.data(i)); + end loop; + end procedure; + procedure start_test is begin start <= '1'; @@ -131,7 +113,7 @@ begin assert (TEST_STRING = "TEST_CONFIG_1") report "user_config incompatible with testbench." severity FAILURE; - SetAlertLogName("rtps_builtin_endpoint - Level 0 - Stale Participant Handling"); + SetAlertLogName("rtps_builtin_endpoint - Level 0 - Remote Liveliness Assertion Handling"); SetAlertEnable(FAILURE, TRUE); SetAlertEnable(ERROR, TRUE); SetAlertEnable(WARNING, TRUE); @@ -147,7 +129,7 @@ begin sub.readerId := ENTITYID_SPDP_BUILTIN_PARTICIPANT_DETECTOR; sub.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; - -- Participant 0 (Default Lease Time 100 s) + -- Participant 0 p0.guidPrefix := gen_rand_guid_prefix; p0.nr := 0; p0.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); @@ -156,28 +138,21 @@ begin p0.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; p0.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; - -- Participant 1 (Lease Duration 10 s) + -- Participant 1 p1.guidPrefix := gen_rand_guid_prefix; p1.nr := 1; - p1.leaseDuration := gen_duration(10,0); p1.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); p1.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR) := '1'; p1.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER):= '1'; p1.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; p1.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; - -- Participant 2 (Lease Duration 30 s) - p2.guidPrefix := gen_rand_guid_prefix; - p2.nr := 2; - p2.leaseDuration := gen_duration(30,0); - p2.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); - p2.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR) := '1'; - p2.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER):= '1'; - p2.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; - p2.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; + for i in 0 to RV.RandInt(1,10) loop + rand_data.data(i) := RV.RandSlv(WORD_WIDTH); + rand_data.length := rand_data.length + 1; + end loop; Log("Initiating Test", INFO); - test_time <= TIME_ZERO; stim_done <= '0'; start <= '0'; reset <= '1'; @@ -187,92 +162,97 @@ begin -- *PARTICIPANT* Log("Current Time: 0s", INFO); - Log("Match Participant 0 [Default Lease 100s]", INFO); - sub.writerSN := p_sn; + Log("Match Participant 0", INFO); + sub := DEFAULT_RTPS_SUBMESSAGE; + sub.submessageID := SID_DATA; + sub.writerId := ENTITYID_SPDP_BUILTIN_PARTICIPANT_ANNOUNCER; + sub.readerId := ENTITYID_SPDP_BUILTIN_PARTICIPANT_DETECTOR; + sub.writerSN := gen_sn(1); + sub.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; participant := p0; gen_participant_data(participant, sub.data); gen_sentinel(sub.data); gen_rtps_handler_out(sub, participant, stimulus); - SB_mem.Push(gen_participant_mem_frame(participant)); start_test; wait_on_complete; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; - sub.data := EMPTY_TEST_PACKET; - p_sn := p_sn + 1; - Log("Match Participant 1 [Lease 10s]", INFO); - sub.writerSN := p_sn; + Log("Match Participant 1", INFO); + sub := DEFAULT_RTPS_SUBMESSAGE; + sub.submessageID := SID_DATA; + sub.writerId := ENTITYID_SPDP_BUILTIN_PARTICIPANT_ANNOUNCER; + sub.readerId := ENTITYID_SPDP_BUILTIN_PARTICIPANT_DETECTOR; + sub.writerSN := gen_sn(1); + sub.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; participant := p1; gen_participant_data(participant, sub.data); gen_sentinel(sub.data); gen_rtps_handler_out(sub, participant, stimulus); - SB_mem.Push(gen_participant_mem_frame(participant)); start_test; wait_on_complete; stimulus := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; - sub.data := EMPTY_TEST_PACKET; - p_sn := p_sn + 1; - - Log("Match Participant 2 [Lease 30s]", INFO); - sub.writerSN := p_sn; - participant := p2; - gen_participant_data(participant, sub.data); - gen_sentinel(sub.data); - gen_rtps_handler_out(sub, participant, stimulus); - SB_mem.Push(gen_participant_mem_frame(participant)); - start_test; - wait_on_complete; - stimulus := EMPTY_TEST_PACKET; - reference := EMPTY_TEST_PACKET; - sub.data := EMPTY_TEST_PACKET; - p_sn := p_sn + 1; - - -- DUMMY PACKET (Trigger last mem check) - -- Mark Packet as non-standard Payload, in order to trigger the packet to be skipped (as early as possible) - sub.data := EMPTY_TEST_PACKET; - sub.flags(SUBMESSAGE_NON_STANDARD_PAYLOAD_FLAG_POS):= '1'; - gen_rtps_handler_out(sub, participant, stimulus); - - participant := p1; - participant.match := UNMATCH; - push_participant_reference; - SB_mem.Push(gen_participant_mem_frame(participant)); - - Log("Current Time: 15 s", INFO); - start_test; - -- Progress Time (15 s) - test_time <= (unsigned(int(15, CDR_LONG_WIDTH)), unsigned(int(0, CDR_LONG_WIDTH))); - wait_on_complete; - - start_test; - wait_on_complete; - - Log("Current Time: 101 s", INFO); - test_time <= (unsigned(int(101, CDR_LONG_WIDTH)), unsigned(int(0, CDR_LONG_WIDTH))); + Log("Participant 0 Automatic Liveliness Assertion", INFO); + sub := DEFAULT_RTPS_SUBMESSAGE; + sub.submessageID := SID_DATA; + sub.writerId := ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER; + sub.readerId := ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER; + sub.writerSN := gen_sn(1); + sub.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; participant := p0; - participant.match := UNMATCH; - push_participant_reference; - SB_mem.Push(gen_participant_mem_frame(participant)); - + gen_liveliness_assertion(p0, FALSE, sub.data); + gen_rtps_handler_out(sub, participant, stimulus); + gen_liveliness_update_frame(p0, reference); + wr_sig := AUTOMATIC_LIVELINESS_READERS; + push_reference; start_test; wait_on_complete; + stimulus := EMPTY_TEST_PACKET; + reference := EMPTY_TEST_PACKET; - participant := p2; - participant.match := UNMATCH; - push_participant_reference; - SB_mem.Push(gen_participant_mem_frame(participant)); - + Log("Participant 1 Manual Liveliness Assertion", INFO); + sub := DEFAULT_RTPS_SUBMESSAGE; + sub.submessageID := SID_DATA; + sub.writerId := ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER; + sub.readerId := ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER; + sub.writerSN := gen_sn(1); + sub.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; + participant := p1; + gen_liveliness_assertion(p1, TRUE, sub.data); + gen_rtps_handler_out(sub, participant, stimulus); + gen_liveliness_update_frame(p1, reference); + wr_sig := MANUAL_BY_PARTICIPANT_LIVELINESS_READERS; + push_reference; start_test; wait_on_complete; + stimulus := EMPTY_TEST_PACKET; + reference := EMPTY_TEST_PACKET; + + Log("Participant 0 Manual Liveliness Assertion [+DATA Bytes]", INFO); + sub := DEFAULT_RTPS_SUBMESSAGE; + sub.submessageID := SID_DATA; + sub.writerId := ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER; + sub.readerId := ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER; + sub.writerSN := gen_sn(2); + sub.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; + participant := p0; + gen_liveliness_assertion(p0, TRUE, rand_data, sub.data); + gen_rtps_handler_out(sub, participant, stimulus); + gen_liveliness_update_frame(p0, reference); + wr_sig := MANUAL_BY_PARTICIPANT_LIVELINESS_READERS; + push_reference; + start_test; + wait_on_complete; + stimulus := EMPTY_TEST_PACKET; + reference := EMPTY_TEST_PACKET; TranscriptOpen(RESULTS_FILE, APPEND_MODE); SetTranscriptMirror; stim_done <= '1'; wait until check_done = '1'; - AlertIf((not SB_out.empty) or (not SB_mem.empty), "Incomplete test run"); + AlertIf(not SB_out.empty, "Incomplete test run"); ReportAlerts; TranscriptClose; std.env.stop; @@ -358,30 +338,6 @@ begin end if; end process; - mem_check_prc : process - alias mem is <>; - alias mem_op_done is <>; - variable reference : TEST_PARTICIPANT_MEMORY_FRAME_TYPE; - begin - -- SAFEGUARD: (Prevent Fall-through Behavior) - if (reset /= '0') then - wait until reset = '0'; - end if; - -- NOTE: The first read after the packet is sent signifies that the State Machine has begun processing the next packet. - -- The memory operation that could still be in progress is the last one concerning the last sent packet. - wait until packet_sent = '1'; - wait until rising_edge(rd_sig); - if (mem_op_done /= '1') then - wait until mem_op_done = '1'; - end if; - if (not SB_mem.empty) then - SB_mem.Pop(reference); - for i in 0 to reference'length-1 loop - AffirmIf(?? (mem(reference(i).addr) ?= reference(i).data), "Address: " & integer'image(reference(i).addr) & " Received: " & to_hstring(mem(reference(i).addr)) & " Expected: " & to_hstring(reference(i).data)); - end loop; - end if; - end process; - watchdog : process begin wait for 1 ms; diff --git a/src/Tests/Level_0/L0_rtps_builtin_endpoint_test7.vhd b/src/Tests/Level_0/L0_rtps_builtin_endpoint_test7.vhd deleted file mode 100644 index 07c505a..0000000 --- a/src/Tests/Level_0/L0_rtps_builtin_endpoint_test7.vhd +++ /dev/null @@ -1,348 +0,0 @@ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library osvvm; -- Utility Library -context osvvm.OsvvmContext; - -use work.rtps_package.all; -use work.user_config.all; -use work.rtps_config_package.all; -use work.rtps_test_package.all; - --- This testbench tests the handling of remote Liveliness Assertions --- The testbench matches 2 remote Participants, P0 and P1. P0 sends an automatic liveliness assertion, while P1 sends a manual liveliness assertion. --- P0 also sends a manual liveliness assertion with extra Bytes. - -entity L0_rtps_builtin_endpoint_test7 is -end entity; - -architecture testbench of L0_rtps_builtin_endpoint_test7 is - - -- *TYPE DECLARATION* - type TEST_STAGE_TYPE is (IDLE, BUSY); - - -- *SIGNAL DECLARATION* - signal clk, in_empty, rd_sig, last_word_in, last_word_out: std_logic := '0'; - signal reset : std_logic := '1'; - signal endpoint_wr, endpoint_full : std_logic_vector(0 to NUM_ENDPOINTS-1) := (others => '0'); - signal data_in, data_out : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0'); - signal stim_stage : TEST_STAGE_TYPE := IDLE; - shared variable stimulus, reference : TEST_PACKET_TYPE := EMPTY_TEST_PACKET; - signal packet_sent : std_logic := '0'; - signal cnt_stim : natural := 0; - signal start : std_logic := '0'; - shared variable SB_out : work.ScoreBoardPkg_builtin_endpoint.ScoreBoardPType; - signal stim_done, check_done, mem_check : std_logic := '0'; - - -- *FUNCTION DECLARATION* - procedure wait_on_complete is - begin - wait until rising_edge(packet_sent); - end procedure; - - function gen_sn(input : natural) return SEQUENCENUMBER_TYPE is - variable ret : SEQUENCENUMBER_TYPE; - begin - ret(0) := (others => '0'); - ret(1) := unsigned(int(input, WORD_WIDTH)); - return ret; - end function; - -begin - - -- Unit Under Test - uut : entity work.rtps_builtin_endpoint(arch) - generic map ( - MAX_REMOTE_PARTICIPANTS => 2 - ) - port map ( - clk => clk, - reset => reset, - empty => in_empty or packet_sent, - rd => rd_sig, - data_in => data_in, - data_out => data_out, - last_word_in => last_word_in, - time => TIME_ZERO, - endpoint_full => endpoint_full, - endpoint_wr => endpoint_wr, - rtps_wr => open, - rtps_full => '0', - last_word_out => last_word_out, - alive => (others => '0') - ); - - stimulus_prc : process - variable sub : RTPS_SUBMESSAGE_TYPE := DEFAULT_RTPS_SUBMESSAGE; - variable RV : RandomPType; - variable p0, p1, participant: PARTICIPANT_DATA_TYPE := DEFAULT_PARTICIPANT_DATA; - variable wr_sig : std_logic_vector(0 to NUM_ENDPOINTS-1) := (others => '0'); - variable rand_data : TEST_PACKET_TYPE := EMPTY_TEST_PACKET; - - -- Wrapper to use procedure as function - impure function gen_rand_loc_2 return LOCATOR_TYPE is - variable ret : LOCATOR_TYPE := EMPTY_LOCATOR; - begin - gen_rand_loc(RV, ret); - return ret; - end function; - - impure function gen_rand_guid_prefix return GUIDPREFIX_TYPE is - variable ret : GUIDPREFIX_TYPE; - begin - ret := (0 => RV.RandSlv(WORD_WIDTH), 1 => RV.RandSlv(WORD_WIDTH), 2 => RV.RandSlv(WORD_WIDTH)); - return ret; - end function; - - procedure push_reference is - begin - for i in 0 to reference.length-1 loop - SB_out.Push(wr_sig & reference.last(i) & reference.data(i)); - end loop; - end procedure; - - procedure start_test is - begin - start <= '1'; - wait until rising_edge(clk); - start <= '0'; - wait until rising_edge(clk); - end procedure; - begin - - assert (TEST_STRING = "TEST_CONFIG_1") report "user_config incompatible with testbench." severity FAILURE; - - SetAlertLogName("rtps_builtin_endpoint - Level 0 - Remote Liveliness Assertion Handling"); - SetAlertEnable(FAILURE, TRUE); - SetAlertEnable(ERROR, TRUE); - SetAlertEnable(WARNING, TRUE); - SetLogEnable(DEBUG, FALSE); - SetLogEnable(PASSED, FALSE); - SetLogEnable(INFO, TRUE); - RV.InitSeed(RV'instance_name); - - -- Participant RTPS Submessage - sub := DEFAULT_RTPS_SUBMESSAGE; - sub.submessageID := SID_DATA; - sub.writerId := ENTITYID_SPDP_BUILTIN_PARTICIPANT_ANNOUNCER; - sub.readerId := ENTITYID_SPDP_BUILTIN_PARTICIPANT_DETECTOR; - sub.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; - - -- Participant 0 - p0.guidPrefix := gen_rand_guid_prefix; - p0.nr := 0; - p0.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); - p0.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR) := '1'; - p0.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER):= '1'; - p0.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; - p0.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; - - -- Participant 1 - p1.guidPrefix := gen_rand_guid_prefix; - p1.nr := 1; - p1.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); - p1.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR) := '1'; - p1.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER):= '1'; - p1.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; - p1.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; - - for i in 0 to RV.RandInt(1,10) loop - rand_data.data(i) := RV.RandSlv(WORD_WIDTH); - rand_data.length := rand_data.length + 1; - end loop; - - Log("Initiating Test", INFO); - stim_done <= '0'; - start <= '0'; - reset <= '1'; - wait until rising_edge(clk); - wait until rising_edge(clk); - reset <= '0'; - - -- *PARTICIPANT* - Log("Current Time: 0s", INFO); - Log("Match Participant 0", INFO); - sub := DEFAULT_RTPS_SUBMESSAGE; - sub.submessageID := SID_DATA; - sub.writerId := ENTITYID_SPDP_BUILTIN_PARTICIPANT_ANNOUNCER; - sub.readerId := ENTITYID_SPDP_BUILTIN_PARTICIPANT_DETECTOR; - sub.writerSN := gen_sn(1); - sub.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; - participant := p0; - gen_participant_data(participant, sub.data); - gen_sentinel(sub.data); - gen_rtps_handler_out(sub, participant, stimulus); - start_test; - wait_on_complete; - stimulus := EMPTY_TEST_PACKET; - reference := EMPTY_TEST_PACKET; - - Log("Match Participant 1", INFO); - sub := DEFAULT_RTPS_SUBMESSAGE; - sub.submessageID := SID_DATA; - sub.writerId := ENTITYID_SPDP_BUILTIN_PARTICIPANT_ANNOUNCER; - sub.readerId := ENTITYID_SPDP_BUILTIN_PARTICIPANT_DETECTOR; - sub.writerSN := gen_sn(1); - sub.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; - participant := p1; - gen_participant_data(participant, sub.data); - gen_sentinel(sub.data); - gen_rtps_handler_out(sub, participant, stimulus); - start_test; - wait_on_complete; - stimulus := EMPTY_TEST_PACKET; - reference := EMPTY_TEST_PACKET; - - Log("Participant 0 Automatic Liveliness Assertion", INFO); - sub := DEFAULT_RTPS_SUBMESSAGE; - sub.submessageID := SID_DATA; - sub.writerId := ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER; - sub.readerId := ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER; - sub.writerSN := gen_sn(1); - sub.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; - participant := p0; - gen_liveliness_assertion(p0, FALSE, sub.data); - gen_rtps_handler_out(sub, participant, stimulus); - gen_liveliness_update_frame(p0, reference); - wr_sig := AUTOMATIC_LIVELINESS_READERS; - push_reference; - start_test; - wait_on_complete; - stimulus := EMPTY_TEST_PACKET; - reference := EMPTY_TEST_PACKET; - - Log("Participant 1 Manual Liveliness Assertion", INFO); - sub := DEFAULT_RTPS_SUBMESSAGE; - sub.submessageID := SID_DATA; - sub.writerId := ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER; - sub.readerId := ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER; - sub.writerSN := gen_sn(1); - sub.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; - participant := p1; - gen_liveliness_assertion(p1, TRUE, sub.data); - gen_rtps_handler_out(sub, participant, stimulus); - gen_liveliness_update_frame(p1, reference); - wr_sig := MANUAL_BY_PARTICIPANT_LIVELINESS_READERS; - push_reference; - start_test; - wait_on_complete; - stimulus := EMPTY_TEST_PACKET; - reference := EMPTY_TEST_PACKET; - - Log("Participant 0 Manual Liveliness Assertion [+DATA Bytes]", INFO); - sub := DEFAULT_RTPS_SUBMESSAGE; - sub.submessageID := SID_DATA; - sub.writerId := ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER; - sub.readerId := ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER; - sub.writerSN := gen_sn(2); - sub.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; - participant := p0; - gen_liveliness_assertion(p0, TRUE, rand_data, sub.data); - gen_rtps_handler_out(sub, participant, stimulus); - gen_liveliness_update_frame(p0, reference); - wr_sig := MANUAL_BY_PARTICIPANT_LIVELINESS_READERS; - push_reference; - start_test; - wait_on_complete; - stimulus := EMPTY_TEST_PACKET; - reference := EMPTY_TEST_PACKET; - - TranscriptOpen(RESULTS_FILE, APPEND_MODE); - SetTranscriptMirror; - stim_done <= '1'; - wait until check_done = '1'; - AlertIf(not SB_out.empty, "Incomplete test run"); - ReportAlerts; - TranscriptClose; - std.env.stop; - wait; - end process; - - clock_prc : process - begin - clk <= '0'; - wait for 25 ns; - clk <= '1'; - wait for 25 ns; - end process; - - in_empty_prc : process - begin - in_empty <= '0'; - wait until rd_sig = '1'; - wait until rising_edge(clk); - in_empty <= '1'; - wait until rising_edge(clk); - end process; - - endpoint_full_prc : process - begin - endpoint_full <= (others => '0'); - wait until (or endpoint_wr) = '1'; - wait until rising_edge(clk); - endpoint_full <= (others => '1'); - wait until rising_edge(clk); - end process; - - alert_prc : process(all) - begin - if rising_edge(clk) then - alertif(in_empty = '1' and rd_sig = '1', "Input FIFO read signal high while empty signal high", ERROR); - alertif(endpoint_full /= (0 to NUM_ENDPOINTS-1 => '0') and (endpoint_wr /= (0 to NUM_ENDPOINTS-1 => '0')), "Endpoint FIFO write signal high while full signal high", ERROR); - end if; - end process; - - input_prc : process(all) - begin - data_in <= stimulus.data(cnt_stim); - last_word_in <= stimulus.last(cnt_stim); - - if rising_edge(clk) then - if (reset = '1') then - cnt_stim <= 0; - stim_stage <= IDLE; - packet_sent <= '1'; - else - case (stim_stage) is - when IDLE => - if (start = '1' and stimulus.length /= 0) then - stim_stage <= BUSY; - packet_sent <= '0'; - end if; - when BUSY => - if (rd_sig = '1') then - if (cnt_stim = stimulus.length-1) then - stim_stage <= IDLE; - packet_sent <= '1'; - cnt_stim <= 0; - else - cnt_stim <= cnt_stim + 1; - end if; - end if; - end case; - end if; - end if; - end process; - - output_check_prc : process(all) - begin - check_done <= '0'; - if rising_edge(clk) then - if (endpoint_wr /= (0 to NUM_ENDPOINTS-1 => '0')) then - SB_out.Check(endpoint_wr & last_word_out & data_out); - end if; - if (stim_done = '1' and SB_out.empty) then - check_done <= '1'; - end if; - end if; - end process; - - watchdog : process - begin - wait for 1 ms; - Alert("Test timeout", FAILURE); - std.env.stop; - end process; - -end architecture; \ No newline at end of file diff --git a/src/Tests/Level_1/L1_rtps_builtin_endpoint_test1.vhd b/src/Tests/Level_1/L1_rtps_builtin_endpoint_test1.vhd index a69a352..b1ba689 100644 --- a/src/Tests/Level_1/L1_rtps_builtin_endpoint_test1.vhd +++ b/src/Tests/Level_1/L1_rtps_builtin_endpoint_test1.vhd @@ -440,9 +440,7 @@ begin variable RV : RandomPType; variable p0, participant : PARTICIPANT_DATA_TYPE := DEFAULT_PARTICIPANT_DATA; - -- NOTE: The stale_check variable is set everytime a Participant Stale Check is done (which is done in last priority). - -- We use this together with mem_op_done to "synchronize" the stimulus process. - alias stale_check is <>; + alias idle_sig is <>; alias mem_op_done is <>; -- Wrapper to use procedure as function @@ -474,6 +472,24 @@ begin start <= '0'; wait until rising_edge(clk); end procedure; + + -- NOTE: This procedure waits until the idle_sig is high for at least + -- two consecutive clock cycles. + procedure wait_on_idle is + variable first : boolean := TRUE; + begin + loop + if (idle_sig /= '1' or mem_op_done /= '1') then + wait until idle_sig = '1' and mem_op_done = '1'; + elsif (not first) then + exit; + end if; + wait until rising_edge(clk); + wait until rising_edge(clk); + first := FALSE; + end loop; + end procedure; + begin assert (TEST_STRING = "TEST_CONFIG_1") report "user_config incompatible with testbench." severity FAILURE; @@ -523,10 +539,9 @@ begin gen_rtps_handler_out(sub, participant, stimulus); start_test; wait_on_complete; + wait_on_idle; stimulus := EMPTY_TEST_PACKET; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - -- *ACKNACK* Log("Send Remote Publisher Heartbeat [Empty, Final Flag] (No Response, Final Flag)", INFO); @@ -544,10 +559,9 @@ begin gen_rtps_handler_out(sub, participant, stimulus); start_test; wait_on_complete; + wait_on_idle; stimulus := EMPTY_TEST_PACKET; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - -- Progress time past the HEARTBEAT RESPONSE DELAY Log("Current Time: 0.105s", INFO); test_time <= gen_duration(0,105*(10**6)); @@ -566,10 +580,9 @@ begin gen_rtps_handler_out(sub, participant, stimulus); start_test; wait_on_complete; + wait_on_idle; stimulus := EMPTY_TEST_PACKET; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - Log("Send Remote Subscriber Heartbeat [Empty, Final Flag] (No Change)", INFO); -- RTPS SUBMESSAGE sub := DEFAULT_RTPS_SUBMESSAGE; @@ -585,10 +598,9 @@ begin gen_rtps_handler_out(sub, participant, stimulus); start_test; wait_on_complete; + wait_on_idle; stimulus := EMPTY_TEST_PACKET; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - Log("Send Remote Message AckNack [Expecting 1] (Response)", INFO); -- RTPS SUBMESSAGE sub := DEFAULT_RTPS_SUBMESSAGE; @@ -602,30 +614,26 @@ begin gen_rtps_handler_out(sub, participant, stimulus); start_test; wait_on_complete; + wait_on_idle; stimulus := EMPTY_TEST_PACKET; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - Log("Current Time: 0.210s", INFO); test_time <= gen_duration(0,210*(10**6)); gen_acknack(p0, 1, gen_sn(1), gen_sn(1), gen_sn(1)); + wait_on_idle; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; Log("Toggle local Writer 4 Liveliness for 1 clock cycle (MANUAL_BY_PARTICIPANT_QOS)", INFO); alive(NUM_READERS+4) <= '1'; wait until rising_edge(clk); alive <= (others => '0'); + wait_on_idle; Log("Current Time: 0.310s", INFO); test_time <= gen_duration(0,310*(10**6)); - gen_data(p0, FALSE, FALSE, TRUE, gen_sn(1), gen_sn(2)); - - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; + wait_on_idle; Log("Send Remote Publisher Heartbeat [First 1, Last 1] (No Response, Suppression Delay)", INFO); -- RTPS SUBMESSAGE @@ -641,15 +649,12 @@ begin gen_rtps_handler_out(sub, participant, stimulus); start_test; wait_on_complete; + wait_on_idle; stimulus := EMPTY_TEST_PACKET; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - Log("Current Time: 0.415s", INFO); test_time <= gen_duration(0,415*(10**6)); - - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; + wait_on_idle; Log("Send Remote Publisher Heartbeat [First 1, Last 5] (Response)", INFO); -- RTPS SUBMESSAGE @@ -665,10 +670,9 @@ begin gen_rtps_handler_out(sub, participant, stimulus); start_test; wait_on_complete; + wait_on_idle; stimulus := EMPTY_TEST_PACKET; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - Log("Send Remote Publisher AckNack [Expecting 1] (No Response, Suppression Delay)", INFO); -- RTPS SUBMESSAGE sub := DEFAULT_RTPS_SUBMESSAGE; @@ -682,15 +686,12 @@ begin gen_rtps_handler_out(sub, participant, stimulus); start_test; wait_on_complete; + wait_on_idle; stimulus := EMPTY_TEST_PACKET; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - Log("Current Time: 0.450s", INFO); test_time <= gen_duration(0,450*(10**6)); - - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; + wait_on_idle; Log("Send Remote Subscriber Heartbeat [First 2, Last 5] (Update Response)", INFO); -- RTPS SUBMESSAGE @@ -706,17 +707,13 @@ begin gen_rtps_handler_out(sub, participant, stimulus); start_test; wait_on_complete; + wait_on_idle; stimulus := EMPTY_TEST_PACKET; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - Log("Current Time: 0.520s", INFO); test_time <= gen_duration(0,520*(10**6)); - gen_acknack(p0, 2, gen_sn(1), gen_sn(2), gen_sn(1)); - - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; + wait_on_idle; Log("Send Remote Publisher AckNack [Expecting 1] (Response)", INFO); -- RTPS SUBMESSAGE @@ -731,12 +728,12 @@ begin gen_rtps_handler_out(sub, participant, stimulus); start_test; wait_on_complete; + wait_on_idle; stimulus := EMPTY_TEST_PACKET; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - Log("Current Time: 0.620s", INFO); test_time <= gen_duration(0,620*(10**6)); + wait_on_idle; Log("Send Remote Subscriber AckNack [Expecting 1] (Update Response)", INFO); -- RTPS SUBMESSAGE @@ -751,25 +748,18 @@ begin gen_rtps_handler_out(sub, participant, stimulus); start_test; wait_on_complete; + wait_on_idle; stimulus := EMPTY_TEST_PACKET; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - Log("Current Time: 0.725s", INFO); test_time <= gen_duration(0,725*(10**6)); - gen_data(p0, TRUE, TRUE, FALSE, SEQUENCENUMBER_UNKNOWN, SEQUENCENUMBER_UNKNOWN); - - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; + wait_on_idle; Log("Current Time: 1s", INFO); test_time <= gen_duration(1,0); - gen_heartbeat(p0, 3, gen_sn(3), gen_sn(4)); - - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; + wait_on_idle; Log("Send Remote Subscriber AckNack [Expecting 8] (Response)", INFO); -- RTPS SUBMESSAGE @@ -784,23 +774,17 @@ begin gen_rtps_handler_out(sub, participant, stimulus); start_test; wait_on_complete; + wait_on_idle; stimulus := EMPTY_TEST_PACKET; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - Log("Current Time: 1.205s", INFO); test_time <= gen_duration(1,205*(10**6)); - gen_data(p0, TRUE, FALSE, FALSE, SEQUENCENUMBER_UNKNOWN, SEQUENCENUMBER_UNKNOWN); - - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; + wait_on_idle; Log("Current Time: 1.500s", INFO); test_time <= gen_duration(1,500*(10**6)); - - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; + wait_on_idle; Log("Send Remote Publisher AckNack [Expecting 18] (No Response)", INFO); -- RTPS SUBMESSAGE @@ -815,21 +799,17 @@ begin gen_rtps_handler_out(sub, participant, stimulus); start_test; wait_on_complete; + wait_on_idle; stimulus := EMPTY_TEST_PACKET; Log("Current Time: 1.705s", INFO); test_time <= gen_duration(1,705*(10**6)); - - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; + wait_on_idle; Log("Current Time: 2s", INFO); test_time <= gen_duration(2,0); - gen_heartbeat(p0, 4, gen_sn(3), gen_sn(5)); - - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; + wait_on_idle; Log("Send Remote Message AckNack [Expecting 5] (Response)", INFO); -- RTPS SUBMESSAGE @@ -844,10 +824,9 @@ begin gen_rtps_handler_out(sub, participant, stimulus); start_test; wait_on_complete; + wait_on_idle; stimulus := EMPTY_TEST_PACKET; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - Log("Send Remote Publisher AckNack [Expecting 2] (No Response)", INFO); -- RTPS SUBMESSAGE sub := DEFAULT_RTPS_SUBMESSAGE; @@ -861,10 +840,9 @@ begin gen_rtps_handler_out(sub, participant, stimulus); start_test; wait_on_complete; + wait_on_idle; stimulus := EMPTY_TEST_PACKET; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - Log("Send Remote Subscriber AckNack [Expecting 8] (Response)", INFO); -- RTPS SUBMESSAGE sub := DEFAULT_RTPS_SUBMESSAGE; @@ -878,28 +856,23 @@ begin gen_rtps_handler_out(sub, participant, stimulus); start_test; wait_on_complete; + wait_on_idle; stimulus := EMPTY_TEST_PACKET; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - Log("Current Time: 2.205s", INFO); test_time <= gen_duration(2,205*(10**6)); - gen_data(p0, TRUE, TRUE, TRUE, gen_sn(3), gen_sn(5)); + wait_on_idle; Log("Toggle local Writer 0 Liveliness for 1 clock cycle (AUTOMATIC_QOS)", INFO); alive(NUM_READERS) <= '1'; wait until rising_edge(clk); alive <= (others => '0'); - - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; + wait_on_idle; Log("Current Time: 2.500s", INFO); test_time <= gen_duration(2,500*(10**6)); - - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; + wait_on_idle; Log("Send Remote Message AckNack [Expecting 6] (No Response)", INFO); -- RTPS SUBMESSAGE @@ -914,30 +887,23 @@ begin gen_rtps_handler_out(sub, participant, stimulus); start_test; wait_on_complete; + wait_on_idle; stimulus := EMPTY_TEST_PACKET; Log("Current Time: 2.705s", INFO); test_time <= gen_duration(2,705*(10**6)); - - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; + wait_on_idle; Log("Current Time: 3s", INFO); test_time <= gen_duration(3,0); - gen_heartbeat(p0, 5, gen_sn(6), gen_sn(7)); - - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; + wait_on_idle; Log("Current Time: 31s", INFO); test_time <= gen_duration(31,0); - gen_announcement; gen_heartbeat(p0, 6, gen_sn(6), gen_sn(8)); - - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; - wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; + wait_on_idle; TranscriptOpen(RESULTS_FILE, APPEND_MODE); SetTranscriptMirror; @@ -1007,6 +973,7 @@ begin if (cnt_stim = stimulus.length-1) then stim_stage <= IDLE; packet_sent <= '1'; + cnt_stim <= 0; else cnt_stim <= cnt_stim + 1; end if; diff --git a/src/Tests/testbench.pro b/src/Tests/testbench.pro index 36baa8a..4f17197 100644 --- a/src/Tests/testbench.pro +++ b/src/Tests/testbench.pro @@ -20,128 +20,126 @@ analyze ../rtps_reader.vhd analyze ../rtps_writer.vhd analyze ../dds_writer.vhd analyze ../dds_reader.vhd -#analyze Level_0/L0_rtps_handler_test1.vhd -#analyze Level_0/L0_rtps_handler_test2.vhd -#analyze Level_0/L0_rtps_builtin_endpoint_test1.vhd -#analyze Level_0/L0_rtps_builtin_endpoint_test2.vhd -#analyze Level_0/L0_rtps_builtin_endpoint_test3.vhd -#analyze Level_0/L0_rtps_builtin_endpoint_test4.vhd -#analyze Level_0/L0_rtps_builtin_endpoint_test5.vhd -#analyze Level_0/L0_rtps_builtin_endpoint_test6.vhd -#analyze Level_0/L0_rtps_builtin_endpoint_test7.vhd -#analyze Level_0/L0_rtps_out_test1.vhd -#analyze Level_1/L1_rtps_builtin_endpoint_test1.vhd -#analyze Level_0/L0_mem_ctrl_test1.vhd -#analyze Level_0/L0_rtps_reader_test1_vrk.vhd -#analyze Level_0/L0_rtps_reader_test1_vbk.vhd -#analyze Level_0/L0_rtps_reader_test2_vrk.vhd -#analyze Level_0/L0_rtps_reader_test2_trk.vhd -#analyze Level_0/L0_rtps_reader_test2_vbk.vhd -#analyze Level_0/L0_rtps_reader_test2_tbk.vhd -#analyze Level_0/L0_rtps_reader_test2_vrn.vhd -#analyze Level_0/L0_rtps_reader_test3_a.vhd -#analyze Level_0/L0_rtps_reader_test3_m.vhd -#analyze Level_1/L1_rtps_reader_test1_vrk.vhd -#analyze Level_1/L1_rtps_reader_test1_trk.vhd -#analyze Level_0/L0_rtps_writer_test1_vrkdp.vhd -#analyze Level_0/L0_rtps_writer_test1_vbkdp.vhd -#analyze Level_1/L1_rtps_writer_test1_vrkdp.vhd -#analyze Level_1/L1_rtps_writer_test1_trkdp.vhd -#analyze Level_1/L1_rtps_writer_test1_tbkdp.vhd -#analyze Level_1/L1_rtps_writer_test1_vbkdp.vhd -#analyze Level_1/L1_rtps_writer_test1_vrndp.vhd -#analyze Level_1/L1_rtps_writer_test1_vrksp.vhd -#analyze Level_1/L1_rtps_writer_test1_vrkdn.vhd -#analyze Level_1/L1_rtps_writer_test1_trkdn.vhd -#analyze Level_1/L1_rtps_writer_test2_vrkdn.vhd -#analyze Level_0/L0_rtps_writer_test2_vrkdp.vhd -#analyze Level_0/L0_dds_writer_test1_aik.vhd -#analyze Level_0/L0_dds_writer_test1_ain.vhd -#analyze Level_0/L0_dds_writer_test1_lik.vhd -#analyze Level_0/L0_dds_writer_test1_afk.vhd -#analyze Level_0/L0_dds_writer_test2_aik.vhd -#analyze Level_0/L0_dds_writer_test3_aik.vhd -#analyze Level_0/L0_dds_writer_test3_ain.vhd -#analyze Level_0/L0_dds_writer_test4_aik.vhd -#analyze Level_0/L0_dds_writer_test5_afk.vhd -#analyze Level_0/L0_dds_reader_test1_arzkriu.vhd -#analyze Level_0/L0_dds_reader_test1_lrzkriu.vhd -#analyze Level_0/L0_dds_reader_test1_lbzkriu.vhd -#analyze Level_0/L0_dds_reader_test1_abzkriu.vhd -#analyze Level_0/L0_dds_reader_test1_arznriu.vhd -#analyze Level_0/L0_dds_reader_test1_arzksiu.vhd -#analyze Level_0/L0_dds_reader_test2_arpkriu.vhd -#analyze Level_0/L0_dds_reader_test3_arzkriu.vhd -#analyze Level_0/L0_dds_reader_test3_arzkrio.vhd -#analyze Level_0/L0_dds_reader_test3_arzkrtu.vhd -#analyze Level_0/L0_dds_reader_test3_arzkrto.vhd -#analyze Level_0/L0_dds_reader_test3_arznriu.vhd -#analyze Level_0/L0_dds_reader_test3_arzksto.vhd -#analyze Level_0/L0_dds_reader_test4_arzkriu.vhd -#analyze Level_0/L0_dds_reader_test4_arznriu.vhd -#analyze Level_0/L0_dds_reader_test5_arzkriu.vhd -#analyze Level_0/L0_dds_reader_test6_arzkriu.vhd +analyze Level_0/L0_rtps_handler_test1.vhd +analyze Level_0/L0_rtps_handler_test2.vhd +analyze Level_0/L0_rtps_builtin_endpoint_test1.vhd +analyze Level_0/L0_rtps_builtin_endpoint_test2.vhd +analyze Level_0/L0_rtps_builtin_endpoint_test3.vhd +analyze Level_0/L0_rtps_builtin_endpoint_test4.vhd +analyze Level_0/L0_rtps_builtin_endpoint_test5.vhd +analyze Level_0/L0_rtps_builtin_endpoint_test6.vhd +analyze Level_0/L0_rtps_out_test1.vhd +analyze Level_1/L1_rtps_builtin_endpoint_test1.vhd +analyze Level_0/L0_mem_ctrl_test1.vhd +analyze Level_0/L0_rtps_reader_test1_vrk.vhd +analyze Level_0/L0_rtps_reader_test1_vbk.vhd +analyze Level_0/L0_rtps_reader_test2_vrk.vhd +analyze Level_0/L0_rtps_reader_test2_trk.vhd +analyze Level_0/L0_rtps_reader_test2_vbk.vhd +analyze Level_0/L0_rtps_reader_test2_tbk.vhd +analyze Level_0/L0_rtps_reader_test2_vrn.vhd +analyze Level_0/L0_rtps_reader_test3_a.vhd +analyze Level_0/L0_rtps_reader_test3_m.vhd +analyze Level_1/L1_rtps_reader_test1_vrk.vhd +analyze Level_1/L1_rtps_reader_test1_trk.vhd +analyze Level_0/L0_rtps_writer_test1_vrkdp.vhd +analyze Level_0/L0_rtps_writer_test1_vbkdp.vhd +analyze Level_1/L1_rtps_writer_test1_vrkdp.vhd +analyze Level_1/L1_rtps_writer_test1_trkdp.vhd +analyze Level_1/L1_rtps_writer_test1_tbkdp.vhd +analyze Level_1/L1_rtps_writer_test1_vbkdp.vhd +analyze Level_1/L1_rtps_writer_test1_vrndp.vhd +analyze Level_1/L1_rtps_writer_test1_vrksp.vhd +analyze Level_1/L1_rtps_writer_test1_vrkdn.vhd +analyze Level_1/L1_rtps_writer_test1_trkdn.vhd +analyze Level_1/L1_rtps_writer_test2_vrkdn.vhd +analyze Level_0/L0_rtps_writer_test2_vrkdp.vhd +analyze Level_0/L0_dds_writer_test1_aik.vhd +analyze Level_0/L0_dds_writer_test1_ain.vhd +analyze Level_0/L0_dds_writer_test1_lik.vhd +analyze Level_0/L0_dds_writer_test1_afk.vhd +analyze Level_0/L0_dds_writer_test2_aik.vhd +analyze Level_0/L0_dds_writer_test3_aik.vhd +analyze Level_0/L0_dds_writer_test3_ain.vhd +analyze Level_0/L0_dds_writer_test4_aik.vhd +analyze Level_0/L0_dds_writer_test5_afk.vhd +analyze Level_0/L0_dds_reader_test1_arzkriu.vhd +analyze Level_0/L0_dds_reader_test1_lrzkriu.vhd +analyze Level_0/L0_dds_reader_test1_lbzkriu.vhd +analyze Level_0/L0_dds_reader_test1_abzkriu.vhd +analyze Level_0/L0_dds_reader_test1_arznriu.vhd +analyze Level_0/L0_dds_reader_test1_arzksiu.vhd +analyze Level_0/L0_dds_reader_test2_arpkriu.vhd +analyze Level_0/L0_dds_reader_test3_arzkriu.vhd +analyze Level_0/L0_dds_reader_test3_arzkrio.vhd +analyze Level_0/L0_dds_reader_test3_arzkrtu.vhd +analyze Level_0/L0_dds_reader_test3_arzkrto.vhd +analyze Level_0/L0_dds_reader_test3_arznriu.vhd +analyze Level_0/L0_dds_reader_test3_arzksto.vhd +analyze Level_0/L0_dds_reader_test4_arzkriu.vhd +analyze Level_0/L0_dds_reader_test4_arznriu.vhd +analyze Level_0/L0_dds_reader_test5_arzkriu.vhd +analyze Level_0/L0_dds_reader_test6_arzkriu.vhd analyze Level_0/L0_dds_reader_test7_arzkriu.vhd -#simulate L0_rtps_handler_test1 -#simulate L0_rtps_handler_test2 -#simulate L0_rtps_builtin_endpoint_test1 -#simulate L0_rtps_builtin_endpoint_test2 -#simulate L0_rtps_builtin_endpoint_test3 -#simulate L0_rtps_builtin_endpoint_test4 -#simulate L0_rtps_builtin_endpoint_test5 -#simulate L0_rtps_builtin_endpoint_test6 -#simulate L0_rtps_builtin_endpoint_test7 -#simulate L0_rtps_out_test1 -#simulate L1_rtps_builtin_endpoint_test1 -#simulate L0_mem_ctrl_test1 -#simulate L0_rtps_reader_test1_vrk -#simulate L0_rtps_reader_test1_vbk -#simulate L0_rtps_reader_test2_vrk -#simulate L0_rtps_reader_test2_trk -#simulate L0_rtps_reader_test2_vbk -#simulate L0_rtps_reader_test2_tbk -#simulate L0_rtps_reader_test2_vrn -#simulate L0_rtps_reader_test3_a -#simulate L0_rtps_reader_test3_m -#simulate L1_rtps_reader_test1_vrk -#simulate L1_rtps_reader_test1_trk -#simulate L0_rtps_writer_test1_vrkdp -#simulate L0_rtps_writer_test1_vbkdp -#simulate L1_rtps_writer_test1_vrkdp -#simulate L1_rtps_writer_test1_trkdp -#simulate L1_rtps_writer_test1_tbkdp -#simulate L1_rtps_writer_test1_vbkdp -#simulate L1_rtps_writer_test1_vrndp -#simulate L1_rtps_writer_test1_vrksp -#simulate L1_rtps_writer_test1_vrkdn -#simulate L1_rtps_writer_test1_trkdn -#simulate L1_rtps_writer_test2_vrkdn -#simulate L0_rtps_writer_test2_vrkdp -#simulate L0_dds_writer_test1_aik -#simulate L0_dds_writer_test1_ain -#simulate L0_dds_writer_test1_lik -#simulate L0_dds_writer_test1_afk -#simulate L0_dds_writer_test2_aik -#simulate L0_dds_writer_test3_aik -#simulate L0_dds_writer_test3_ain -#simulate L0_dds_writer_test4_aik -#simulate L0_dds_writer_test5_afk -#simulate L0_dds_reader_test1_arzkriu -#simulate L0_dds_reader_test1_lrzkriu -#simulate L0_dds_reader_test1_lbzkriu -#simulate L0_dds_reader_test1_abzkriu -#simulate L0_dds_reader_test1_arznriu -#simulate L0_dds_reader_test1_arzksiu -#simulate L0_dds_reader_test2_arpkriu -#simulate L0_dds_reader_test3_arzkriu -#simulate L0_dds_reader_test3_arzkrio -#simulate L0_dds_reader_test3_arzkrtu -#simulate L0_dds_reader_test3_arzkrto -#simulate L0_dds_reader_test3_arznriu -#simulate L0_dds_reader_test3_arzksto -#simulate L0_dds_reader_test4_arzkriu -#simulate L0_dds_reader_test4_arznriu -#simulate L0_dds_reader_test5_arzkriu -#simulate L0_dds_reader_test6_arzkriu +simulate L0_rtps_handler_test1 +simulate L0_rtps_handler_test2 +simulate L0_rtps_builtin_endpoint_test1 +simulate L0_rtps_builtin_endpoint_test2 +simulate L0_rtps_builtin_endpoint_test3 +simulate L0_rtps_builtin_endpoint_test4 +simulate L0_rtps_builtin_endpoint_test5 +simulate L0_rtps_builtin_endpoint_test6 +simulate L0_rtps_out_test1 +simulate L1_rtps_builtin_endpoint_test1 +simulate L0_mem_ctrl_test1 +simulate L0_rtps_reader_test1_vrk +simulate L0_rtps_reader_test1_vbk +simulate L0_rtps_reader_test2_vrk +simulate L0_rtps_reader_test2_trk +simulate L0_rtps_reader_test2_vbk +simulate L0_rtps_reader_test2_tbk +simulate L0_rtps_reader_test2_vrn +simulate L0_rtps_reader_test3_a +simulate L0_rtps_reader_test3_m +simulate L1_rtps_reader_test1_vrk +simulate L1_rtps_reader_test1_trk +simulate L0_rtps_writer_test1_vrkdp +simulate L0_rtps_writer_test1_vbkdp +simulate L1_rtps_writer_test1_vrkdp +simulate L1_rtps_writer_test1_trkdp +simulate L1_rtps_writer_test1_tbkdp +simulate L1_rtps_writer_test1_vbkdp +simulate L1_rtps_writer_test1_vrndp +simulate L1_rtps_writer_test1_vrksp +simulate L1_rtps_writer_test1_vrkdn +simulate L1_rtps_writer_test1_trkdn +simulate L1_rtps_writer_test2_vrkdn +simulate L0_rtps_writer_test2_vrkdp +simulate L0_dds_writer_test1_aik +simulate L0_dds_writer_test1_ain +simulate L0_dds_writer_test1_lik +simulate L0_dds_writer_test1_afk +simulate L0_dds_writer_test2_aik +simulate L0_dds_writer_test3_aik +simulate L0_dds_writer_test3_ain +simulate L0_dds_writer_test4_aik +simulate L0_dds_writer_test5_afk +simulate L0_dds_reader_test1_arzkriu +simulate L0_dds_reader_test1_lrzkriu +simulate L0_dds_reader_test1_lbzkriu +simulate L0_dds_reader_test1_abzkriu +simulate L0_dds_reader_test1_arznriu +simulate L0_dds_reader_test1_arzksiu +simulate L0_dds_reader_test2_arpkriu +simulate L0_dds_reader_test3_arzkriu +simulate L0_dds_reader_test3_arzkrio +simulate L0_dds_reader_test3_arzkrtu +simulate L0_dds_reader_test3_arzkrto +simulate L0_dds_reader_test3_arznriu +simulate L0_dds_reader_test3_arzksto +simulate L0_dds_reader_test4_arzkriu +simulate L0_dds_reader_test4_arznriu +simulate L0_dds_reader_test5_arzkriu +simulate L0_dds_reader_test6_arzkriu simulate L0_dds_reader_test7_arzkriu \ No newline at end of file diff --git a/src/rtps_builtin_endpoint.vhd b/src/rtps_builtin_endpoint.vhd index 64ac5cd..a9ca281 100644 --- a/src/rtps_builtin_endpoint.vhd +++ b/src/rtps_builtin_endpoint.vhd @@ -7,12 +7,6 @@ use work.rtps_package.all; use work.user_config.all; use work.rtps_config_package.all; --- TODO: Initialise RAM to zeroes --- TODO: Skip Packet while we are waiting for memory operation to complete --- FIXME: ACNACK response does not nack, which is necessary to get the missing SNs. --- TODO: Could we overwrite the data (pre-GUIDPrefix) while the memory is using them before the first memory guard? (Add test case) --- TODO: Parse inlineQOS HASH_KEY. - entity rtps_builtin_endpoint is generic ( MAX_REMOTE_PARTICIPANTS : natural := 50 @@ -37,30 +31,95 @@ end entity; architecture arch of rtps_builtin_endpoint is - --*****COMPONENT DECLARATION****** - -- The RAM is used for storing remote Participant and Endpoint Data. - -- Participant Data is stored from low to high and Endpoint Data is stored from high to low. - -- The RAM should have a READ and WRITE latency of 1 clock cycle. - component single_port_ram is - generic ( - ADDR_WIDTH : natural := 8; - DATA_WIDTH : natural := 12; - MEMORY_DEPTH : natural := 256 - - ); - port ( - clk : in std_logic; - addr : in std_logic_vector(ADDR_WIDTH-1 downto 0); - wen : in std_logic; - ren : in std_logic; - wr_data : in std_logic_vector(DATA_WIDTH-1 downto 0); - rd_data : out std_logic_vector(DATA_WIDTH-1 downto 0) - ); - end component; - --*****CONSTANT DECLARATION***** + -- Max Serialized Payload Size in a UDP Stream (Bytes) [MAX_PAYLAOD(65536) - IPv4_HEADER(20) - UDP_HEADER(8) - RTPS_HEADER(20) - DATA_HEADER(24)] + constant UDP_MAX_SIZE_SERIALIZED : natural := 65464; + -- Highest Sequence Number of Publisher Data + constant PUB_SEQUENCENUMBER : SEQUENCENUMBER_TYPE := convert_to_double_word(to_unsigned(NUM_WRITERS, 64)); + -- Highest Sequence Number of Subscriber Data + constant SUB_SEQUENCENUMBER : SEQUENCENUMBER_TYPE := convert_to_double_word(to_unsigned(NUM_READERS, 64)); + -- Heartbeat/Liveliness Assertion Period + constant HEARTBEAT_PERIOD : DURATION_TYPE := work.rtps_package.min(MIN_ENDPOINT_LEASE_DURATION, PARTICIPANT_HEARTBEAT_PERIOD) - DURATION_DELTA; + + -- *PARTICIPANT MEMORY* + -- 4-Byte Word Size of a Participant Entry in Memory + constant PARTICIPANT_FRAME_SIZE : natural := 24; + -- Memory Size in 4-Byte Words + constant PARTICIPANT_MEMORY_SIZE : natural := MAX_REMOTE_PARTICIPANTS * PARTICIPANT_FRAME_SIZE; + -- Memory Address Width + constant PARTICIPANT_MEMORY_ADDR_WIDTH : natural := log2c(PARTICIPANT_MEMORY_SIZE); + -- Highest Memory Address + constant PARTICIPANT_MEMORY_MAX_ADDRESS : unsigned(PARTICIPANT_MEMORY_ADDR_WIDTH-1 downto 0) := to_unsigned(PARTICIPANT_MEMORY_SIZE-1, PARTICIPANT_MEMORY_ADDR_WIDTH); + -- Highest participant Frame Address + constant MAX_PARTICIPANT_ADDRESS : unsigned(PARTICIPANT_MEMORY_ADDR_WIDTH-1 downto 0) := PARTICIPANT_MEMORY_MAX_ADDRESS - PARTICIPANT_FRAME_SIZE + 1; + -- Address pointing to the beginning of the first Participant Data Frame + constant FIRST_PARTICIPANT_ADDRESS : unsigned(PARTICIPANT_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); + + -- *PARTICIPANT MEMORY FRAME FIELD FLAGS* + -- Flags mapping to the respective Participant Memory Frame Fields + constant PMF_FLAG_WIDTH : natural := 14; + constant PMF_NEXT_ADDR_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (0 => '1', others => '0'); + constant PMF_GUIDPREFIX_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (1 => '1', others => '0'); + constant PMF_META_IPV4_ADDR_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (2 => '1', others => '0'); + constant PMF_DEFAULT_IPV4_ADDR_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (3 => '1', others => '0'); + constant PMF_UDP_PORT_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (4 => '1', others => '0'); + constant PMF_SPDP_SEQ_NR_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (5 => '1', others => '0'); + constant PMF_LEASE_DURATION_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (6 => '1', others => '0'); + constant PMF_LEASE_DEADLINE_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (7 => '1', others => '0'); + constant PMF_EXTRA_FLAGS_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (8 => '1', others => '0'); + constant PMF_ACKNACK_RES_TIME_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (9 => '1', others => '0'); + constant PMF_HEARTBEAT_RES_TIME_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (10 => '1', others => '0'); + constant PMF_PUB_SEQ_NR_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (11 => '1', others => '0'); + constant PMF_SUB_SEQ_NR_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (12 => '1', others => '0'); + constant PMF_MES_SEQ_NR_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (13 => '1', others => '0'); + + -- *PARTICIPANT MEMORY FRAME FIELD OFFSETS* + constant PMF_NEXT_ADDR_OFFSET : natural := 0; + constant PMF_GUIDPREFIX_OFFSET : natural := 1; + constant PMF_META_IPV4_ADDR_OFFSET : natural := 4; + constant PMF_DEFAULT_IPV4_ADDR_OFFSET : natural := 5; + constant PMF_UDP_PORT_OFFSET : natural := 6; + constant PMF_SPDP_SEQ_NR_OFFSET : natural := 7; + constant PMF_LEASE_DURATION_OFFSET : natural := 9; + constant PMF_LEASE_DEADLINE_OFFSET : natural := 11; + constant PMF_EXTRA_FLAGS_OFFSET : natural := 13; + constant PMF_ACKNACK_RES_TIME_OFFSET : natural := 14; + constant PMF_HEARTBEAT_RES_TIME_OFFSET : natural := 16; + constant PMF_PUB_SEQ_NR_OFFSET : natural := 18; + constant PMF_SUB_SEQ_NR_OFFSET : natural := 20; + constant PMF_MES_SEQ_NR_OFFSET : natural := 22; + + -- *EXTRA FLAGS* -- Width of extra_flags signal - constant EXTRA_FLAGS_WIDTH : natural := 4; + constant EF_FLAG_WIDTH : natural := 3; + -- Signifies that the Message Data (Liveliness) should be sent + constant EF_MES_DATA_FLAG : std_logic_vector(0 to EF_FLAG_WIDTH-1) := (0 => '1', others => '0'); + -- Signifies that the Subscriber Data should be sent + constant EF_SUB_DATA_FLAG : std_logic_vector(0 to EF_FLAG_WIDTH-1) := (1 => '1', others => '0'); + -- Signifies that the Publisher Data should be sent + constant EF_PUB_DATA_FLAG : std_logic_vector(0 to EF_FLAG_WIDTH-1) := (2 => '1', others => '0'); + + -- *RECV FLAGS* + -- Width of the received array + constant RCVD_FLAG_WIDTH : natural := 9; + -- Signifies that the DOMAIN_TAG was received + constant RCVD_DOMAIN_TAG_FLAG : std_logic_vector(0 to RCVD_FLAG_WIDTH-1) := (0 => '1', others => '0'); + -- Signifies that the DURABILITY QoS was received + constant RCVD_DURABILITY_QOS_FLAG : std_logic_vector(0 to RCVD_FLAG_WIDTH-1) := (1 => '1', others => '0'); + -- Signifies that the PRESENTATION QoS was received + constant RCVD_PRESENTATION_QOS_FLAG : std_logic_vector(0 to RCVD_FLAG_WIDTH-1) := (2 => '1', others => '0'); + -- Signifies that the DEADLINE QoS was received + constant RCVD_DEADLINE_QOS_FLAG : std_logic_vector(0 to RCVD_FLAG_WIDTH-1) := (3 => '1', others => '0'); + -- Signifies that the LATENCY_BUDGET QoS was received + constant RCVD_LATENCY_BUDGET_QOS_FLAG : std_logic_vector(0 to RCVD_FLAG_WIDTH-1) := (4 => '1', others => '0'); + -- Signifies that the OWNERSHIP QoS was received + constant RCVD_OWNERSHIP_QOS_FLAG : std_logic_vector(0 to RCVD_FLAG_WIDTH-1) := (5 => '1', others => '0'); + -- Signifies that the LIVELINESS QoS was received + constant RCVD_LIVELINESS_QOS_FLAG : std_logic_vector(0 to RCVD_FLAG_WIDTH-1) := (6 => '1', others => '0'); + -- Signifies that the RELIABILITY QoS was received + constant RCVD_RELIABILITY_QOS_FLAG : std_logic_vector(0 to RCVD_FLAG_WIDTH-1) := (7 => '1', others => '0'); + -- Signifies that the DESTINATION_ORDER QoS was received + constant RCVD_DESTINATION_ORDER_QOS_FLAG : std_logic_vector(0 to RCVD_FLAG_WIDTH-1) := (8 => '1', others => '0'); --*****TYPE DECLARATION***** -- FSM states. Explained below in detail @@ -74,24 +133,22 @@ architecture arch of rtps_builtin_endpoint is PROCESS_ACKNACK_SEQUENCE_NUMBERS, FIND_PARTICIPANT_DEST, SEND_HEADER, SEND_PARTICIPANT_ANNOUNCEMENT, SEND_PUB_DATA, SEND_SUB_DATA, SEND_MES_MAN_LIVE, SEND_MES_GAP, SEND_MES_AUTO_LIVE, LIVELINESS_UPDATE, SKIP_PARAMETER, SKIP_PACKET); -- Memory FSM states. Explained below in detail - type MEM_STAGE_TYPE is (IDLE, SEARCH_PARTICIPANT, GET_PARTICIPANT_DATA, REMOVE_PARTICIPANT, FIND_PARTICIPANT_SLOT, - INSERT_PARTICIPANT, FIND_NEXT_PARTICIPANT, FIND_STALE_PARTICIPANT, UPDATE_PARTICIPANT); + type MEM_STAGE_TYPE is (IDLE, SEARCH_PARTICIPANT, GET_NEXT_PARTICIPANT, GET_PARTICIPANT_DATA, INSERT_PARTICIPANT, UPDATE_PARTICIPANT, REMOVE_PARTICIPANT, RESET_MEMORY); -- Memory FSM Opcodes -- OPCODE DESCRIPTION -- SEARCH_PARTICIPANT Search memory for Participant Entry with GUID Prefix equal to "guid" signal. - -- Set "addr_res" signal to Base Address of found Participant Entry or MAX Address if nothing found. - -- "mem_participant_data" contains memory Participant Data. - -- INSERT_PARTICIPANT Write Participant Data (contained in latches) to first empty Participant Slot. - -- UPDATE_PARTICIPANT Update the Participant Data of the Participant Entry pointed in "addr_res" according to the "update_participant_flags" flags. - -- REMOVE_PARTICIPANT Remove the Participant Entry pointed in "addr_res". - -- FIND_STALE_PARTICIPANT Find first Participant Entry with expired times (Lease Deadline, HEARTBEAT/ACKNACK Response/Suppression Timeout). - -- Set "addr_res" signal to Base Address of found Participant Entry or MAX Address if nothing found. - -- FIND_FIRST_PATICIPANT Find first occupied Participant Entry in memory. - -- Set "addr_res" signal to Base Address of found Participant Entry or MAX Address if nothing found. - -- FIND_NEXT_PARTICIPANT Find next occupied Participant Entry in memory from the Participant Entry pointed by "addr_res". - -- Set "addr_res" signal to Base Address of found Participant Entry or MAX Address if nothing found. - type MEM_OPCODE_TYPE is (NOP, SEARCH_PARTICIPANT, SEARCH_ENDPOINT, INSERT_PARTICIPANT, INSERT_ENDPOINT, UPDATE_PARTICIPANT, - REMOVE_PARTICIPANT, REMOVE_ENDPOINT, FIND_STALE_PARTICIPANT, FIND_FIRST_PATICIPANT, FIND_NEXT_PARTICIPANT); + -- Set "mem_addr_base" to Base Address of found Participant Entry or PARTICIPANT_MEMORY_MAX_ADDRESS if nothing found. + -- "participant_data" contains memory Participant Data according to "mem_field_flags". + -- INSERT_PARTICIPANT Write Participant Data to next avialable empty slot. + -- UPDATE_PARTICIPANT Update the Participant Data of the Participant Entry pointed by "mem_addr_base" according to the "mem_field_flags" flags. + -- REMOVE_PARTICIPANT Remove the Participant Entry pointed by "mem_addr_base". + -- GET_FIRST_PATICIPANT Get Participant Data of first participant according to "mem_field_flags". + -- "mem_addr_base" is set to the Address of the Participant, or PARTICIPANT_MEMORY_MAX_ADDRESS if no Participant in Memory + -- GET_NEXT_PARTICIPANT Get Participant Data of next participant (from the one pointed by "mem_addr_base") according to "mem_field_flags". + -- "mem_addr_base" is set to the Address of the Participant, or PARTICIPANT_MEMORY_MAX_ADDRESS if no Participant in Memory + -- GET_PATICIPANT Get Participant Data of participant pointed by "mem_addr_update" according to "mem_field_flags". + -- Already fetched Data of the same Participant is not modified + type MEM_OPCODE_TYPE is (NOP, SEARCH_PARTICIPANT, INSERT_PARTICIPANT, UPDATE_PARTICIPANT, GET_FIRST_PARTICIPANT, GET_NEXT_PARTICIPANT, REMOVE_PARTICIPANT, GET_PARTICIPANT); -- RTPS Data Submessage Content: -- * PDP Simple Participant Discovery Protocol Data -- * EDP Simple Endpoint Discovery Protocol Data @@ -101,11 +158,12 @@ architecture arch of rtps_builtin_endpoint is type STRING_CONTENT_TYPE is (TOPIC_NAME_TYPE, TYPE_NAME_TYPE, DOMAIN_TAG_TYPE); -- Record of all Participant Data stored in memory type PARTICIPANT_DATA_TYPE is record + guid_prefix : GUIDPREFIX_TYPE; meta_addr : std_logic_vector(IPv4_ADDRESS_WIDTH-1 downto 0); def_addr : std_logic_vector(IPv4_ADDRESS_WIDTH-1 downto 0); meta_port : std_logic_vector(UDP_PORT_WIDTH-1 downto 0); def_port : std_logic_vector(UDP_PORT_WIDTH-1 downto 0); - extra_flags : std_logic_vector(EXTRA_FLAGS_WIDTH-1 downto 0); + extra_flags : std_logic_vector(EF_FLAG_WIDTH-1 downto 0); lease_duration : DURATION_TYPE; lease_deadline : TIME_TYPE; heartbeat_res_time : TIME_TYPE; @@ -115,77 +173,9 @@ architecture arch of rtps_builtin_endpoint is sub_seq_nr : SEQUENCENUMBER_TYPE; mes_seq_nr : SEQUENCENUMBER_TYPE; end record; - - --*****CONSTANT DECLARATION***** - -- Max Serialized Payload Size in a UDP Stream (Bytes) [MAX_PAYLAOD(65536) - IPv4_HEADER(20) - UDP_HEADER(8) - RTPS_HEADER(20) - DATA_HEADER(24)] - constant UDP_MAX_SIZE_SERIALIZED : natural := 65464; - -- 4-Byte Word Size of a Participant Entry in Memory - constant PARTICIPANT_FRAME_SIZE : natural := 23; - -- Memory Size in 4-Byte Words - constant BUILTIN_BUFFER_SIZE : natural := MAX_REMOTE_PARTICIPANTS*PARTICIPANT_FRAME_SIZE; - -- Memory Address Width - constant BUILTIN_BUFFER_ADDR_WIDTH : natural := log2c(BUILTIN_BUFFER_SIZE); - -- Highest Memory Address - constant MAX_ADDRESS : unsigned(BUILTIN_BUFFER_ADDR_WIDTH-1 downto 0) := to_unsigned(BUILTIN_BUFFER_SIZE-1, BUILTIN_BUFFER_ADDR_WIDTH); - -- Highest participant Frame Address - constant MAX_PARTICIPANT_ADDRESS : unsigned(BUILTIN_BUFFER_ADDR_WIDTH-1 downto 0) := MAX_ADDRESS - PARTICIPANT_FRAME_SIZE + 1; - -- Address pointing to the beginning of the first Participant Data Frame - constant FIRST_PARTICIPANT_ADDRESS : unsigned(BUILTIN_BUFFER_ADDR_WIDTH-1 downto 0) := (others => '0'); - -- *UPDATE PARTICIPANT FLAG POSITIONS* - -- Width of the Update Participant Flag Signal - constant UPDATE_PARTICIPANT_FLAG_WIDTH : natural := 6; - -- Signifies that the main Participant Data are updated - constant PARTICIPANT_DATA_FLAG : natural := 0; - -- Signifies that the Lease Deadline of the Participant Data is updated - constant LEASE_DEADLINE_FLAG : natural := 1; - -- Signifies that the Extra Flags of the Participant Data are updated - constant EXTRA_FLAGS_FLAG : natural := 2; - -- Signifies that the ACKNACK Timeout Time of the Participant Data is updated - constant ACKNACK_RES_TIME_FLAG : natural := 3; - -- Signifies that the HEARTBEAT Timeout Time of the Participant Data is updated - constant HEARTBEAT_RES_TIME_FLAG : natural := 4; - -- Signifies that the remote Endpoint (Publisher/Subscriber/Message) Sequence Number of the Participant Data is updated - constant EDP_SEQ_NR_FLAG : natural := 5; - -- *EXTRA FLAG POSITIONS* - -- Signifies that the Publisher Data should be sent - constant PUB_DATA_FLAG : natural := 3; - -- Signifies that the Subscriber Data should be sent - constant SUB_DATA_FLAG : natural := 2; - -- Signifies that the Message Data (Liveliness) should be sent - constant MES_DATA_FLAG : natural := 1; - -- Signifies if the Reader Endpoint expects in-line QoS - constant EXPECTS_INLINE_QOS_FLAG : natural := 0; - -- Highest Sequence Number of Publisher Data - constant PUB_SEQUENCENUMBER : SEQUENCENUMBER_TYPE := convert_to_double_word(to_unsigned(NUM_WRITERS, 64)); - -- Highest Sequence Number of Subscriber Data - constant SUB_SEQUENCENUMBER : SEQUENCENUMBER_TYPE := convert_to_double_word(to_unsigned(NUM_READERS, 64)); - -- Heartbeat/Liveliness Assertion Period - constant HEARTBEAT_PERIOD : DURATION_TYPE := work.rtps_package.min(MIN_ENDPOINT_LEASE_DURATION, PARTICIPANT_HEARTBEAT_PERIOD) - DURATION_DELTA; - -- *RECV FLAGS* - -- Width of the received array - constant RCVD_WIDTH : natural := 9; - -- Signifies that the DOMAIN_TAG was received - constant DOMAIN_TAG_RCVD : natural := 0; - -- Signifies that the DURABILITY QoS was received - constant DURABILITY_QOS_RCVD_FLAG : natural := 1; - -- Signifies that the PRESENTATION QoS was received - constant PRESENTATION_QOS_RCVD_FLAG : natural := 2; - -- Signifies that the DEADLINE QoS was received - constant DEADLINE_QOS_RCVD_FLAG : natural := 3; - -- Signifies that the LATENCY_BUDGET QoS was received - constant LATENCY_BUDGET_QOS_RCVD_FLAG : natural := 4; - -- Signifies that the OWNERSHIP QoS was received - constant OWNERSHIP_QOS_RCVD_FLAG : natural := 5; - -- Signifies that the LIVELINESS QoS was received - constant LIVELINESS_QOS_RCVD_FLAG : natural := 6; - -- Signifies that the RELIABILITY QoS was received - constant RELIABILITY_QOS_RCVD_FLAG : natural := 7; - -- Signifies that the DESTINATION_ORDER QoS was received - constant DESTINATION_ORDER_QOS_RCVD_FLAG : natural := 8; - - - -- Constant for zero Participant Data - constant ZERO_PARTICIPANT_DATA : PARTICIPANT_DATA_TYPE := ( + -- Zero initialized Participant Data + constant ZERO_PARTICIPANT_DATA : PARTICIPANT_DATA_TYPE := ( + guid_prefix => GUIDPREFIX_UNKNOWN, meta_addr => IPv4_ADDRESS_INVALID, def_addr => IPv4_ADDRESS_INVALID, meta_port => UDP_PORT_INVALID, @@ -200,6 +190,33 @@ architecture arch of rtps_builtin_endpoint is sub_seq_nr => SEQUENCENUMBER_UNKNOWN, mes_seq_nr => SEQUENCENUMBER_UNKNOWN ); + type PARTICIPANT_LATCH_DATA_TYPE is record + guid_prefix : GUIDPREFIX_TYPE; + meta_addr : std_logic_vector(IPv4_ADDRESS_WIDTH-1 downto 0); + def_addr : std_logic_vector(IPv4_ADDRESS_WIDTH-1 downto 0); + meta_port : std_logic_vector(UDP_PORT_WIDTH-1 downto 0); + def_port : std_logic_vector(UDP_PORT_WIDTH-1 downto 0); + extra_flags : std_logic_vector(EF_FLAG_WIDTH-1 downto 0); + lease_duration : DURATION_TYPE; + lease_deadline : TIME_TYPE; + res_time : TIME_TYPE; + seq_nr : SEQUENCENUMBER_TYPE; + field_flags : std_logic_vector(0 to PMF_FLAG_WIDTH-1); + end record; + -- Zero initialized Participant Data + constant ZERO_PARTICIPANT_LATCH_DATA : PARTICIPANT_LATCH_DATA_TYPE := ( + guid_prefix => GUIDPREFIX_UNKNOWN, + meta_addr => IPv4_ADDRESS_INVALID, + def_addr => IPv4_ADDRESS_INVALID, + meta_port => UDP_PORT_INVALID, + def_port => UDP_PORT_INVALID, + extra_flags => (others => '0'), + lease_duration => DURATION_ZERO, + lease_deadline => TIME_INVALID, + res_time => TIME_INVALID, + seq_nr => SEQUENCENUMBER_UNKNOWN, + field_flags => (others => '0') + ); --*****SIGNAL DECLARATION***** @@ -207,8 +224,6 @@ architecture arch of rtps_builtin_endpoint is signal stage, stage_next : STAGE_TYPE := IDLE; -- FSM state latch. Used to transition dynamically to different states from the same state. signal return_stage, return_stage_next : STAGE_TYPE := IDLE; - -- Memory FSM State - signal mem_stage, mem_stage_next : MEM_STAGE_TYPE := IDLE; -- Intermediate input read signal. (Read from output port not allowed) signal rd_sig : std_logic := '0'; -- Signal used to reset the word counter @@ -247,41 +262,17 @@ architecture arch of rtps_builtin_endpoint is signal participant_match, participant_match_next : std_logic := '0'; -- Signifies if the Packet is comming from a Subscriber Endpoint signal is_subscriber, is_subscriber_next : std_logic := '0'; - -- Signal storing times for memory operations (Participant Lease Deadline, HEARTBEAT/ACKNACK Response/Suppression Time) - signal deadline, deadline_next : TIME_TYPE := (others => (others => '0')); -- Signifies that the read Locator is a Metatraffic Locator signal is_meta_addr, is_meta_addr_next : std_logic := '0'; -- General Purpose counter signal cnt, cnt_next : natural range 0 to max(23, STRING_WORD_ARRAY_TYPE'length) := 0; -- NOTE: In order to avoid synthesizing indexing for the full range of the OUTPUT_DATA_TYPE, we explicitly use counters constrained to the actual size -- Counter used to index the Participant Data - signal participant_data_cnt, participant_data_cnt_next : natural range 0 to PARTICIPANT_DATA.length-1 := 0; + signal participant_data_cnt, participant_data_cnt_next : natural range 0 to LOCAL_PARTICIPANT_DATA.length-1 := 0; -- Counter used to index the Publisher Data signal publisher_data_cnt, publisher_data_cnt_next : natural range 0 to work.math_pkg.max(WRITER_ENDPOINT_DATA.length-1, 0) := 0; -- Counter used to index the Subscriber Data signal subscriber_data_cnt, subscriber_data_cnt_next : natural range 0 to work.math_pkg.max(READER_ENDPOINT_DATA.length-1, 0) := 0; - -- Signals the start of a Memory Operation (Should be pulled high only when mem_op_done is high) - signal mem_op_start : std_logic := '0'; - -- Signals the end of a Memory Operation - signal mem_op_done : std_logic := '0'; - -- Opcode of the Memory Operation (Valid only when mem_op_start is high) - signal mem_opcode : MEM_OPCODE_TYPE := NOP; - -- Current Memory Address - signal mem_addr, mem_addr_next : unsigned(BUILTIN_BUFFER_ADDR_WIDTH-1 downto 0) := (others => '0'); - -- Base Memory Address of current Participant/Endpoint Frame - signal mem_addr_base, mem_addr_base_next : unsigned(BUILTIN_BUFFER_ADDR_WIDTH-1 downto 0) := (others => '0'); - -- Result Base Memory Address of Memory Operation - signal addr_res, addr_res_next : unsigned(BUILTIN_BUFFER_ADDR_WIDTH-1 downto 0) := (others => '0'); - -- Help signal used to reset the MAX Participant/Endpoint Memory Pointers - signal last_addr, last_addr_next : unsigned(BUILTIN_BUFFER_ADDR_WIDTH-1 downto 0) := (others => '0'); - -- Highest Participant Memory Address (Points to first Word of last occupied Participant Frame) - signal max_participant_addr, max_participant_addr_next : unsigned(BUILTIN_BUFFER_ADDR_WIDTH-1 downto 0) := (others => '0'); - -- Memory Data Read and Write Signals - signal mem_read_data, mem_write_data : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0'); - -- Memory Read and Write Enable Signals - signal mem_rd, mem_wr : std_logic := '0'; - -- General Purpose Counter (Memory FSM) - signal mem_cnt, mem_cnt_next : natural range 0 to 22 := 0; -- Signifies the next expected Sequence Number of the current relevant Message Type (Participant/Publisher/Subscriber/Message Data) signal next_seq_nr, next_seq_nr_next : SEQUENCENUMBER_TYPE := (others => (others => '0')); -- Latch used to store the first Sequence Number in ACKNACK/HEARTBEAT/GAP Messages @@ -290,20 +281,12 @@ architecture arch of rtps_builtin_endpoint is signal last_seq_nr, last_seq_nr_next : SEQUENCENUMBER_TYPE := (others => (others => '0')); -- Intermediate write enable signal. signal wr_sig : std_logic := '0'; - -- Signifies if we currently are resetting the MAX Participant/Endpoint Pointer - signal reset_max_pointer, reset_max_pointer_next : std_logic := '0'; - -- Signifies if we currently are doing a Participant Stale Entry Check (Used to start Stale Checks between packet handling) + -- Signifies if a Stale Endpoint Check is in progress signal stale_check, stale_check_next : std_logic := '0'; - -- Latch containing the GUID Prefix of the removed Participant from the memory, and the Enity ID of the last Orphan Endpoint found - signal mem_guidprefix, mem_guidprefix_next : GUIDPREFIX_TYPE := (others => (others => '0')); + -- Time of next Stale Endpoint Check + signal check_time, check_time_next : TIME_TYPE := TIME_INVALID; -- Toggle latching the "last_word_in" signal until reset signal last_word_in_latch, last_word_in_latch_next : std_logic := '0'; - -- Flags signifying which parts of the participant Data stored in memory to update - signal update_participant_flags, update_participant_flags_next : std_logic_vector(UPDATE_PARTICIPANT_FLAG_WIDTH-1 downto 0) := (others => '0'); - -- Latch for the Participant Data stored in memory - signal mem_participant_data, mem_participant_data_next : PARTICIPANT_DATA_TYPE := ZERO_PARTICIPANT_DATA; - -- Signifies if the marked Stale Participant had a Hertbeat Response/Suppression Delay Timeout - signal is_heartbeat_res, is_heartbeat_res_next : std_logic := '0'; -- Signal containing the HEARTBEAT/ACKNACK count of all built-in Endpoints signal count, count_next : unsigned(COUNT_WIDTH-1 downto 0) := (others => '0'); -- Toggle set when at least one Endpoint has asserted the "alive" signal, until reset @@ -339,17 +322,60 @@ architecture arch of rtps_builtin_endpoint is signal meta_port, meta_port_next : std_logic_vector(UDP_PORT_WIDTH-1 downto 0) := (others => '0'); -- Participant Lease Duration Latch signal lease_duration, lease_duration_next : DURATION_TYPE := (others => (others => '0')); - -- Extra Flags Latch - signal extra_flags, extra_flags_next : std_logic_vector(EXTRA_FLAGS_WIDTH-1 downto 0) := (others => '0'); -- General Purpose Long latch signal long_latch, long_latch_next : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); - -- General Purpose Long latch (For Memory FSM) - signal mem_long_latch, mem_long_latch_next : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); -- Contains flags that signify which PIDs where received. This is done in order to use the default value for -- not received elements. - signal rcvd, rcvd_next : std_logic_vector(RCVD_WIDTH-1 downto 0) := (others => '0'); + signal rcvd, rcvd_next : std_logic_vector(RCVD_FLAG_WIDTH-1 downto 0) := (others => '0'); + -- Signal containing the relevant Participant Memory Frame Fields of the Memory Operation + signal mem_field_flags : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (others => '0'); + -- Signal used to pass deadlines to the Memory FSM + signal deadline : TIME_TYPE := TIME_INVALID; + -- Signal used to pass extra flags to the Memory FSM + signal extra_flags : std_logic_vector(0 to EF_FLAG_WIDTH-1) := (others => '0'); + -- Signal used to pass Participant Pointers to the Memory Process + signal mem_addr_update : unsigned(PARTICIPANT_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); + -- Signal used to be pass Response Times to the Memory FSM + signal res_time : TIME_TYPE := TIME_INVALID; + -- Test signal used for testbench synchronisation + signal idle_sig : std_logic := '0'; + + -- *MEMORY PROCESS* + -- Memory FSM State + signal mem_stage, mem_stage_next : MEM_STAGE_TYPE := IDLE; + -- General Purpose Counter (Memory FSM) + signal mem_cnt, mem_cnt_next : natural range 0 to 46 := 0; + -- Signals the start of a Memory Operation (Should be pulled high only when mem_op_done is high) + signal mem_op_start : std_logic := '0'; + -- Signals the end of a Memory Operation + signal mem_op_done : std_logic := '0'; + -- Opcode of the Memory Operation (Valid only when mem_op_start is high) + signal mem_opcode : MEM_OPCODE_TYPE := NOP; + -- Base Memory Address of current Participant Frame + signal mem_addr_base, mem_addr_base_next : unsigned(PARTICIPANT_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); + -- Pointer to previous Participant Memory Frame Address + signal mem_prev_addr_base, mem_prev_addr_base_next : unsigned(PARTICIPANT_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); + -- Pointer to next Participant Memory Frame Address + signal mem_next_addr_base, mem_next_addr_base_next : unsigned(PARTICIPANT_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); + -- Head of Empty Participant List + signal mem_empty_head, mem_empty_head_next : unsigned(PARTICIPANT_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); + -- Head of Occupied Participant List + signal mem_occupied_head, mem_occupied_head_next : unsigned(PARTICIPANT_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); + -- Latch for the Participant Data stored in memory + signal participant_data, participant_data_next : PARTICIPANT_DATA_TYPE := ZERO_PARTICIPANT_DATA; + -- Latch for Participant Data from main FSM + signal participant_latch_data, participant_latch_data_next : PARTICIPANT_LATCH_DATA_TYPE := ZERO_PARTICIPANT_LATCH_DATA; + -- Participant Memory Flag Array denoting which participant_data Fields are up-to-date with the respective fields of the Participant (Pointed by mem_addr_base) + signal current_pmf, current_pmf_next : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (others => '0'); + -- *MEMORY CONTROL CONNECTION SIGNALS* + signal mem_addr : unsigned(PARTICIPANT_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); + signal mem_read_data, mem_write_data : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0'); + signal mem_ready_in, mem_valid_in : std_logic := '0'; + signal mem_ready_out, mem_valid_out : std_logic := '0'; + signal mem_read : std_logic := '0'; + signal mem_abort_read : std_logic := '0'; --*****ALIAS DEFINATION***** -- ENDPOINT FRAME HEADER @@ -374,22 +400,57 @@ architecture arch of rtps_builtin_endpoint is alias payload_flag : std_logic is flags(4); --*****FUNCTION DECLARATION***** + -- Return minimum of t1,t2,t3 or TIME_INVALID if t1,t2,t3 < t. + function min_time(t1, t2, t3, t : TIME_TYPE) return TIME_TYPE is + variable ret : TIME_TYPE := TIME_INVALID; + begin + if (not (t1 <= t)) then + ret := t1; + end if; + if (not (t2 <= t) and t2 < ret) then + ret := t2; + end if; + if (not (t3 <= t) and t3 < ret) then + ret := t3; + end if; + return ret; + end function; + + procedure assert_sn is + begin + if (message_type = EDP and is_subscriber = '0') then + assert (check_mask(current_pmf, PMF_PUB_SEQ_NR_FLAG)) severity FAILURE; + elsif (message_type = EDP and is_subscriber = '1') then + assert (check_mask(current_pmf, PMF_SUB_SEQ_NR_FLAG)) severity FAILURE; + elsif (message_type = MESSAGE) then + assert (check_mask(current_pmf, PMF_MES_SEQ_NR_FLAG)) severity FAILURE; + elsif (message_type = PDP) then + assert (check_mask(current_pmf, PMF_SPDP_SEQ_NR_FLAG)) severity FAILURE; + else + assert FALSE report "assert_sn: Unknown Message Type" severity FAILURE; + end if; + end procedure; begin --*****COMPONENT INSTANTIATION***** - ram_inst : single_port_ram + mem_ctrl_inst : entity work.mem_ctrl(arch) generic map ( - ADDR_WIDTH => BUILTIN_BUFFER_ADDR_WIDTH, - DATA_WIDTH => WORD_WIDTH, - MEMORY_DEPTH => BUILTIN_BUFFER_SIZE + ADDR_WIDTH => PARTICIPANT_MEMORY_ADDR_WIDTH, + DATA_WIDTH => WORD_WIDTH, + MEMORY_DEPTH => PARTICIPANT_MEMORY_SIZE, + MAX_BURST_LENGTH => PARTICIPANT_FRAME_SIZE ) port map ( clk => clk, + reset => reset or mem_abort_read, addr => std_logic_vector(mem_addr), - wen => mem_wr, - ren => mem_rd, - wr_data => mem_write_data, - rd_data => mem_read_data + read => mem_read, + ready_in => mem_ready_in, + valid_in => mem_valid_in, + data_in => mem_write_data, + ready_out => mem_ready_out, + valid_out => mem_valid_out, + data_out => mem_read_data ); @@ -437,7 +498,7 @@ begin endpoint_wr <= endpoint_mask; end if; when others => - rtps_wr <= wr_sig; + rtps_wr <= wr_sig; end case; end process; @@ -462,8 +523,7 @@ begin -- PROCESS_ACKNACK Parse RTPS ACKNACK Submessage -- PROCESS_ACKNACK_SEQUENCE_NUMBERS Process ACKNACK Sequence Numbers. Update stored Sequence Numbers if necessary. Set ACKNACK response timeout accordingly. -- FIND_PARTICIPANT_DEST Find next stored Participant to send Participant Announcement and Liveliness Assertion to. - -- PARTICIPANT_STALE_CHECK Check memory for remote stale Participant Entries (Lease Duration Exceeded, HEARTBEAT/ACKNACK timeout passed) - -- LATCH_REMOVED_GUIDPREFIX Store Participant GUID Prefix of removed Participant for Orphan Endpoint Search + -- PARTICIPANT_STALE_CHECK Check memory for remote stale Participant Entries (Lease Duration Exceeded, HEARTBEAT/ACKNACK timeout passed) and take appropriate action. -- PROCESS_PL Parse RTPS Parameter List -- CHECK_DEFAULT Match local endpoints against non-received QoS (default values) of remote -- LATCH_STRING_LENGTH Store String Length @@ -533,12 +593,9 @@ begin is_meta_addr_next <= is_meta_addr; cnt_next <= cnt; reader_flags_next <= reader_flags; - extra_flags_next <= extra_flags; stale_check_next <= stale_check; first_seq_nr_next <= first_seq_nr; last_seq_nr_next <= last_seq_nr; - update_participant_flags_next <= update_participant_flags; - deadline_next <= deadline; auto_live_seq_nr_next <= auto_live_seq_nr; man_live_seq_nr_next <= man_live_seq_nr; live_gap_start_next <= live_gap_start; @@ -556,6 +613,7 @@ begin count_next <= count; long_latch_next <= long_latch; rcvd_next <= rcvd; + check_time_next <= check_time; -- DEFAULT Unregistered rd_sig <= '0'; rd_guard := '0'; @@ -565,7 +623,12 @@ begin mem_op_start <= '0'; last_word_out <= '0'; reset_endpoint_alive <= '0'; + idle_sig <= '0'; data_out <= (others => '0'); + mem_field_flags <= (others => '0'); + extra_flags <= (others => '0'); + mem_addr_update <= PARTICIPANT_MEMORY_MAX_ADDRESS; + deadline <= TIME_INVALID; -- Last Word Latch Setter if (last_word_in = '1') then @@ -577,18 +640,18 @@ begin case (message_type) is -- Participant Data Sequence Number when PDP => - mem_seq_nr := mem_participant_data.spdp_seq_nr; + mem_seq_nr := participant_data.spdp_seq_nr; when EDP => -- Subscriber Data Sequence Number if (is_subscriber = '1') then - mem_seq_nr := mem_participant_data.sub_seq_nr; + mem_seq_nr := participant_data.sub_seq_nr; -- Publisher Data Sequence Number else - mem_seq_nr := mem_participant_data.pub_seq_nr; + mem_seq_nr := participant_data.pub_seq_nr; end if; -- Participant Message Data Sequence Number when MESSAGE => - mem_seq_nr := mem_participant_data.mes_seq_nr; + mem_seq_nr := participant_data.mes_seq_nr; when others => mem_seq_nr := SEQUENCENUMBER_UNKNOWN; end case; @@ -596,6 +659,7 @@ begin case(stage) is -- Initial/Idle State when IDLE => + idle_sig <= '1'; -- Participant Announcement Time Trigger if (time > announcement_time) then announcement_time_next <= time + PARTICIPANT_ANNOUNCEMENT_PERIOD; @@ -625,27 +689,32 @@ begin end if; heartbeat_time_next <= time + HEARTBEAT_PERIOD; -- Send Heartbeat and Liveliness Assertions to all stored Participants - mem_opcode <= FIND_FIRST_PATICIPANT; - mem_op_start <= '1'; - stage_next <= FIND_PARTICIPANT_DEST; + mem_op_start <= '1'; + mem_opcode <= GET_FIRST_PARTICIPANT; + mem_field_flags <= PMF_META_IPV4_ADDR_FLAG or PMF_UDP_PORT_FLAG; + stage_next <= FIND_PARTICIPANT_DEST; -- Increment the counter for the new Heartbeat Messages - count_next <= count + 1; + count_next <= count + 1; -- Mark this as liveliness assertion (Allows the "SEND_MES_AUTO_LIVE" stage to decide on return stage) is_live_assert_next <= '1'; end if; - -- Stale Entry search is initiated between every packet processing and when there is no packet to process - elsif (stale_check = '0' or empty = '1') then + -- Stale Check Timeout + elsif (check_time <= time) then + -- Memory Operation Guard if (mem_op_done = '1') then - mem_opcode <= FIND_STALE_PARTICIPANT; - mem_op_start <= '1'; - -- Stale Check Toggle (Setter) + mem_op_start <= '1'; + mem_opcode <= GET_FIRST_PARTICIPANT; + mem_field_flags <= PMF_LEASE_DEADLINE_FLAG or PMF_ACKNACK_RES_TIME_FLAG or PMF_HEARTBEAT_RES_TIME_FLAG; + stale_check_next <= '1'; stage_next <= PARTICIPANT_STALE_CHECK; + cnt_next <= 1; + + -- Reset Timeout + check_time_next <= TIME_INFINITE; end if; -- Process Packet - else - -- Stale Check Toggle (Resetter) - stale_check_next <= '0'; + elsif (empty = '0') then stage_next <= PACKET_HEADER; -- Reset Latches @@ -654,7 +723,6 @@ begin def_port_next <= (others => '0'); meta_port_next <= META_IPv4_MULTICAST_PORT; lease_duration_next <= DEFAULT_PARTICIPANT_LEASE_DURATION; - extra_flags_next <= (EXPECTS_INLINE_QOS_FLAG => DEFAULT_EXPECTS_INLINE_QOS, others => '0'); reader_flags_next <= (READER_EXPECTS_INLINE_QOS_FLAG => DEFAULT_EXPECTS_INLINE_QOS, READER_EXPECTS_HISTORICAL_DATA_FLAG => DEFAULT_EXPECTS_HISTORICAL_DATA_FLAG, READER_IS_BEST_EFFORT_FLAG => DEFAULT_IS_BEST_EFFORT_FLAG, others => '0'); rcvd_next <= (others => '0'); -- NOTE: We work with a "mark by default, and unmark on first missmatch" System. @@ -704,9 +772,6 @@ begin when 2 => guid_next(2) <= data_in; guid_next(3) <= (others => '0'); - -- Start Participant Search - mem_opcode <= SEARCH_PARTICIPANT; - mem_op_start <= '1'; stage_next <= PACKET_SRC_ENTITYID; when others => @@ -745,6 +810,11 @@ begin stage_next <= LATCH_SEQ_NR; cnt_next <= 0; + + -- Start Participant Search + mem_op_start <= '1'; + mem_opcode <= SEARCH_PARTICIPANT; + mem_field_flags <= PMF_SPDP_SEQ_NR_FLAG or PMF_DEFAULT_IPV4_ADDR_FLAG or PMF_UDP_PORT_FLAG; end if; when ENTITYID_SEDP_BUILTIN_PUBLICATIONS_ANNOUNCER => -- SANITY CHECK: Ignore if no Writers @@ -755,6 +825,11 @@ begin stage_next <= PROCESS_ACKNACK; --ACKNACK Processing cnt_next <= 0; + + -- Start Participant Search + mem_op_start <= '1'; + mem_opcode <= SEARCH_PARTICIPANT; + mem_field_flags <= PMF_ACKNACK_RES_TIME_FLAG or PMF_EXTRA_FLAGS_FLAG; end if; when ENTITYID_SEDP_BUILTIN_PUBLICATIONS_DETECTOR => -- SANITY CHECK: Ignore if no Readers @@ -767,15 +842,30 @@ begin when SID_HEARTBEAT => stage_next <= PROCESS_HEARTBEAT; -- HEARTBEAT Processing cnt_next <= 0; + + -- Start Participant Search + mem_op_start <= '1'; + mem_opcode <= SEARCH_PARTICIPANT; + mem_field_flags <= PMF_HEARTBEAT_RES_TIME_FLAG or PMF_PUB_SEQ_NR_FLAG; when SID_GAP => stage_next <= PROCESS_GAP; -- GAP Processing cnt_next <= 0; + + -- Start Participant Search + mem_op_start <= '1'; + mem_opcode <= SEARCH_PARTICIPANT; + mem_field_flags <= PMF_PUB_SEQ_NR_FLAG; when SID_DATA => stage_next <= LATCH_SEQ_NR; -- DATA Processing cnt_next <= 0; -- Unmark all Writers endpoint_mask_next <= ENDPOINT_READERS; + + -- Start Participant Search + mem_op_start <= '1'; + mem_opcode <= SEARCH_PARTICIPANT; + mem_field_flags <= PMF_PUB_SEQ_NR_FLAG or PMF_DEFAULT_IPV4_ADDR_FLAG or PMF_UDP_PORT_FLAG; when others => null; end case; @@ -788,6 +878,11 @@ begin stage_next <= PROCESS_ACKNACK; --ACKNACK Processing cnt_next <= 0; + + -- Start Participant Search + mem_op_start <= '1'; + mem_opcode <= SEARCH_PARTICIPANT; + mem_field_flags <= PMF_ACKNACK_RES_TIME_FLAG or PMF_EXTRA_FLAGS_FLAG; end if; when ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_DETECTOR => -- SANITY CHECK: Ignore if no Writers @@ -800,15 +895,30 @@ begin when SID_HEARTBEAT => stage_next <= PROCESS_HEARTBEAT; -- HEARTBEAT Processing cnt_next <= 0; + + -- Start Participant Search + mem_op_start <= '1'; + mem_opcode <= SEARCH_PARTICIPANT; + mem_field_flags <= PMF_HEARTBEAT_RES_TIME_FLAG or PMF_SUB_SEQ_NR_FLAG; when SID_GAP => stage_next <= PROCESS_GAP; -- GAP Processing cnt_next <= 0; + + -- Start Participant Search + mem_op_start <= '1'; + mem_opcode <= SEARCH_PARTICIPANT; + mem_field_flags <= PMF_SUB_SEQ_NR_FLAG; when SID_DATA => stage_next <= LATCH_SEQ_NR; -- DATA Processing cnt_next <= 0; -- Unmark all Readers endpoint_mask_next <= not ENDPOINT_READERS; + + -- Start Participant Search + mem_op_start <= '1'; + mem_opcode <= SEARCH_PARTICIPANT; + mem_field_flags <= PMF_SUB_SEQ_NR_FLAG or PMF_DEFAULT_IPV4_ADDR_FLAG or PMF_UDP_PORT_FLAG; when others => null; end case; @@ -822,6 +932,11 @@ begin stage_next <= PROCESS_ACKNACK; --ACKNACK Processing cnt_next <= 0; + + -- Start Participant Search + mem_op_start <= '1'; + mem_opcode <= SEARCH_PARTICIPANT; + mem_field_flags <= PMF_ACKNACK_RES_TIME_FLAG or PMF_EXTRA_FLAGS_FLAG; end if; end if; when ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER => @@ -834,15 +949,30 @@ begin when SID_HEARTBEAT => stage_next <= PROCESS_HEARTBEAT; -- HEARTBEAT Processing cnt_next <= 0; + + -- Start Participant Search + mem_op_start <= '1'; + mem_opcode <= SEARCH_PARTICIPANT; + mem_field_flags <= PMF_HEARTBEAT_RES_TIME_FLAG or PMF_MES_SEQ_NR_FLAG; when SID_GAP => stage_next <= PROCESS_GAP; -- GAP Processing cnt_next <= 0; + + -- Start Participant Search + mem_op_start <= '1'; + mem_opcode <= SEARCH_PARTICIPANT; + mem_field_flags <= PMF_MES_SEQ_NR_FLAG; when SID_DATA => stage_next <= LATCH_SEQ_NR; -- DATA Processing cnt_next <= 0; -- Unmark all Writers endpoint_mask_next <= ENDPOINT_READERS; + + -- Start Participant Search + mem_op_start <= '1'; + mem_opcode <= SEARCH_PARTICIPANT; + mem_field_flags <= PMF_MES_SEQ_NR_FLAG or PMF_DEFAULT_IPV4_ADDR_FLAG or PMF_UDP_PORT_FLAG; when others => null; end case; @@ -867,6 +997,11 @@ begin stage_next <= LATCH_SEQ_NR; cnt_next <= 0; + + -- Start Participant Search + mem_op_start <= '1'; + mem_opcode <= SEARCH_PARTICIPANT; + mem_field_flags <= PMF_SPDP_SEQ_NR_FLAG or PMF_DEFAULT_IPV4_ADDR_FLAG or PMF_UDP_PORT_FLAG; end if; when ENTITYID_SEDP_BUILTIN_PUBLICATIONS_DETECTOR => -- SANITY CHECK: Ignore if no Writers @@ -877,6 +1012,11 @@ begin stage_next <= PROCESS_ACKNACK; --ACKNACK Processing cnt_next <= 0; + + -- Start Participant Search + mem_op_start <= '1'; + mem_opcode <= SEARCH_PARTICIPANT; + mem_field_flags <= PMF_ACKNACK_RES_TIME_FLAG or PMF_EXTRA_FLAGS_FLAG; end if; when ENTITYID_SEDP_BUILTIN_PUBLICATIONS_ANNOUNCER => -- SANITY CHECK: Ignore if no Readers @@ -888,15 +1028,30 @@ begin when SID_HEARTBEAT => stage_next <= PROCESS_HEARTBEAT; -- HEARTBEAT Processing cnt_next <= 0; + + -- Start Participant Search + mem_op_start <= '1'; + mem_opcode <= SEARCH_PARTICIPANT; + mem_field_flags <= PMF_HEARTBEAT_RES_TIME_FLAG or PMF_PUB_SEQ_NR_FLAG; when SID_GAP => stage_next <= PROCESS_GAP; -- GAP Processing cnt_next <= 0; + + -- Start Participant Search + mem_op_start <= '1'; + mem_opcode <= SEARCH_PARTICIPANT; + mem_field_flags <= PMF_PUB_SEQ_NR_FLAG; when SID_DATA => stage_next <= LATCH_SEQ_NR; -- DATA Processing cnt_next <= 0; -- Unmark all Writers endpoint_mask_next <= ENDPOINT_READERS; + + -- Start Participant Search + mem_op_start <= '1'; + mem_opcode <= SEARCH_PARTICIPANT; + mem_field_flags <= PMF_PUB_SEQ_NR_FLAG or PMF_DEFAULT_IPV4_ADDR_FLAG or PMF_UDP_PORT_FLAG; when others => null; end case; @@ -909,6 +1064,11 @@ begin stage_next <= PROCESS_ACKNACK; --ACKNACK Processing cnt_next <= 0; + + -- Start Participant Search + mem_op_start <= '1'; + mem_opcode <= SEARCH_PARTICIPANT; + mem_field_flags <= PMF_ACKNACK_RES_TIME_FLAG or PMF_EXTRA_FLAGS_FLAG; end if; when ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_ANNOUNCER => -- SANITY CHECK: Ignore if no Writers @@ -921,15 +1081,30 @@ begin when SID_HEARTBEAT => stage_next <= PROCESS_HEARTBEAT; -- HEARTBEAT Processing cnt_next <= 0; + + -- Start Participant Search + mem_op_start <= '1'; + mem_opcode <= SEARCH_PARTICIPANT; + mem_field_flags <= PMF_HEARTBEAT_RES_TIME_FLAG or PMF_SUB_SEQ_NR_FLAG; when SID_GAP => stage_next <= PROCESS_GAP; -- GAP Processing cnt_next <= 0; + + -- Start Participant Search + mem_op_start <= '1'; + mem_opcode <= SEARCH_PARTICIPANT; + mem_field_flags <= PMF_SUB_SEQ_NR_FLAG; when SID_DATA => stage_next <= LATCH_SEQ_NR; -- DATA Processing cnt_next <= 0; -- Unmark all Readers endpoint_mask_next <= not ENDPOINT_READERS; + + -- Start Participant Search + mem_op_start <= '1'; + mem_opcode <= SEARCH_PARTICIPANT; + mem_field_flags <= PMF_SUB_SEQ_NR_FLAG or PMF_DEFAULT_IPV4_ADDR_FLAG or PMF_UDP_PORT_FLAG; when others => null; end case; @@ -943,6 +1118,11 @@ begin stage_next <= PROCESS_ACKNACK; --ACKNACK Processing cnt_next <= 0; + + -- Start Participant Search + mem_op_start <= '1'; + mem_opcode <= SEARCH_PARTICIPANT; + mem_field_flags <= PMF_ACKNACK_RES_TIME_FLAG or PMF_EXTRA_FLAGS_FLAG; end if; end if; when ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER => @@ -955,15 +1135,30 @@ begin when SID_HEARTBEAT => stage_next <= PROCESS_HEARTBEAT; -- HEARTBEAT Processing cnt_next <= 0; + + -- Start Participant Search + mem_op_start <= '1'; + mem_opcode <= SEARCH_PARTICIPANT; + mem_field_flags <= PMF_HEARTBEAT_RES_TIME_FLAG or PMF_MES_SEQ_NR_FLAG; when SID_GAP => stage_next <= PROCESS_GAP; -- GAP Processing cnt_next <= 0; + + -- Start Participant Search + mem_op_start <= '1'; + mem_opcode <= SEARCH_PARTICIPANT; + mem_field_flags <= PMF_MES_SEQ_NR_FLAG; when SID_DATA => stage_next <= LATCH_SEQ_NR; -- DATA Processing cnt_next <= 0; -- Unmark all Writers endpoint_mask_next <= ENDPOINT_READERS; + + -- Start Participant Search + mem_op_start <= '1'; + mem_opcode <= SEARCH_PARTICIPANT; + mem_field_flags <= PMF_MES_SEQ_NR_FLAG or PMF_DEFAULT_IPV4_ADDR_FLAG or PMF_UDP_PORT_FLAG; when others => null; end case; @@ -1144,18 +1339,27 @@ begin end case; end if; when PROCESS_GAP_SEQUENCE_NUMBERS => + -- Precondition: participant_data set (PMF_PUB_SEQ_NR_FLAG/PMF_SUB_SEQ_NR_FLAG/PMF_MES_SEQ_NR_FLAG) + assert_sn; + -- Wait for Sequence Number to be fetched from buffer if (mem_op_done = '1') then -- Sender known - if (addr_res /= MAX_ADDRESS) then + if (mem_addr_base /= PARTICIPANT_MEMORY_MAX_ADDRESS) then -- XXX: This logic relies on the sender marking continuous GAPs with the GAP Start Sequence Number and GAP End Sequence Number Set Base (i.e. the first bit in the bitmask should be 0/not in GAP) -- GAP only relevant if next expected sequence number in GAP if (first_seq_nr <= mem_seq_nr and last_seq_nr >= mem_seq_nr) then -- Store GAP end as last sequence number - next_seq_nr_next <= last_seq_nr + 1; - mem_opcode <= UPDATE_PARTICIPANT; - update_participant_flags_next <= (EDP_SEQ_NR_FLAG => '1', others => '0'); - mem_op_start <= '1'; + mem_op_start <= '1'; + mem_opcode <= UPDATE_PARTICIPANT; + if (message_type = EDP and is_subscriber = '0') then + mem_field_flags <= PMF_PUB_SEQ_NR_FLAG; + elsif (message_type = EDP and is_subscriber = '1') then + mem_field_flags <= PMF_SUB_SEQ_NR_FLAG; + else -- message_type = MESSAGE + mem_field_flags <= PMF_MES_SEQ_NR_FLAG; + end if; + next_seq_nr_next <= last_seq_nr + 1; end if; end if; -- DONE @@ -1183,41 +1387,69 @@ begin end case; end if; when PROCESS_HEARTBEAT_SEQUENCE_NUMBERS => + -- Precondition: participant_data set (PMF_HEARTBEAT_RES_TIME_FLAG, PMF_PUB_SEQ_NR_FLAG/PMF_SUB_SEQ_NR_FLAG/PMF_MES_SEQ_NR_FLAG) + assert (check_mask(current_pmf, PMF_HEARTBEAT_RES_TIME_FLAG)) severity FAILURE; + assert_sn; + -- Wait for Participant Search to finish if (mem_op_done = '1') then -- Participant in Buffer - if (addr_res /= MAX_ADDRESS) then + if (mem_addr_base /= PARTICIPANT_MEMORY_MAX_ADDRESS) then -- No scheduled Heartbeat Response - if (mem_participant_data.heartbeat_res_time = 0) then + if (participant_data.heartbeat_res_time = TIME_INVALID) then -- If current Sequence Number obsolete (removed from source history cache) if (first_seq_nr > mem_seq_nr and first_seq_nr <= last_seq_nr) then -- Store new expected Sequence Number and set Response Dealy - next_seq_nr_next <= first_seq_nr; - mem_opcode <= UPDATE_PARTICIPANT; - deadline_next <= time + PARTICIPANT_HEARTBEAT_RESPONSE_DELAY; + mem_op_start <= '1'; + mem_opcode <= UPDATE_PARTICIPANT; + if (message_type = EDP and is_subscriber = '0') then + mem_field_flags <= PMF_PUB_SEQ_NR_FLAG or PMF_HEARTBEAT_RES_TIME_FLAG; + elsif (message_type = EDP and is_subscriber = '1') then + mem_field_flags <= PMF_SUB_SEQ_NR_FLAG or PMF_HEARTBEAT_RES_TIME_FLAG; + else -- message_type = MESSAGE + mem_field_flags <= PMF_MES_SEQ_NR_FLAG or PMF_HEARTBEAT_RES_TIME_FLAG; + end if; + next_seq_nr_next <= first_seq_nr; + tmp_dw := time + PARTICIPANT_HEARTBEAT_RESPONSE_DELAY; + res_time <= tmp_dw; -- NOTE: Last Bit denotes if this is Response or Suppression Delay - deadline_next(1)(0) <= '0'; - update_participant_flags_next <= (EDP_SEQ_NR_FLAG => '1', HEARTBEAT_RES_TIME_FLAG => '1', others => '0'); - mem_op_start <= '1'; + res_time(1)(0) <= '0'; + -- XXX: Possible Worst Case Path (64-bit addition and comparison in same clock) + -- Update Check Time + if (tmp_dw < check_time) then + check_time_next <= tmp_dw; + end if; -- If new Sequence Number is available or Writer expects ACKNACK elsif (last_seq_nr >= mem_seq_nr or final_flag = '0') then -- Set Response Delay - mem_opcode <= UPDATE_PARTICIPANT; - deadline_next <= time + PARTICIPANT_HEARTBEAT_RESPONSE_DELAY; + mem_op_start <= '1'; + mem_opcode <= UPDATE_PARTICIPANT; + mem_field_flags <= PMF_HEARTBEAT_RES_TIME_FLAG; + tmp_dw := time + PARTICIPANT_HEARTBEAT_RESPONSE_DELAY; + res_time <= tmp_dw; -- NOTE: Last Bit denotes if this is Response or Suppression Delay - deadline_next(1)(0) <= '0'; - update_participant_flags_next <= (HEARTBEAT_RES_TIME_FLAG => '1', others => '0'); - mem_op_start <= '1'; + res_time(1)(0) <= '0'; + -- XXX: Possible Worst Case Path (64-bit addition and comparison in same clock) + -- Update Check Time + if (tmp_dw < check_time) then + check_time_next <= tmp_dw; + end if; end if; -- Currently in Heartbeat Response Delay - elsif (mem_participant_data.heartbeat_res_time(1)(0) = '0') then + elsif (participant_data.heartbeat_res_time(1)(0) = '0') then -- If current Sequence Number obsolete (removed from source history cache) if (first_seq_nr > mem_seq_nr and first_seq_nr <= last_seq_nr) then -- Store new expected Sequence Number - next_seq_nr_next <= first_seq_nr; - mem_opcode <= UPDATE_PARTICIPANT; - update_participant_flags_next <= (EDP_SEQ_NR_FLAG => '1', others => '0'); - mem_op_start <= '1'; + mem_op_start <= '1'; + mem_opcode <= UPDATE_PARTICIPANT; + if (message_type = EDP and is_subscriber = '0') then + mem_field_flags <= PMF_PUB_SEQ_NR_FLAG; + elsif (message_type = EDP and is_subscriber = '1') then + mem_field_flags <= PMF_SUB_SEQ_NR_FLAG; + else -- message_type = MESSAGE + mem_field_flags <= PMF_MES_SEQ_NR_FLAG; + end if; + next_seq_nr_next <= first_seq_nr; end if; end if; end if; @@ -1243,12 +1475,15 @@ begin end case; end if; when PROCESS_ACKNACK_SEQUENCE_NUMBERS => + -- Precondition: participant_data set (PMF_ACKNACK_RES_TIME_FLAG, PMF_EXTRA_FLAGS_FLAG) + assert (check_mask(current_pmf, PMF_ACKNACK_RES_TIME_FLAG or PMF_EXTRA_FLAGS_FLAG)) severity FAILURE; + -- Wait for Participant Search to finish if (mem_op_done = '1') then -- Participant in Buffer - if (addr_res /= MAX_ADDRESS) then + if (mem_addr_base /= PARTICIPANT_MEMORY_MAX_ADDRESS) then -- No scheduled Acknack Response - if (mem_participant_data.acknack_res_time = 0) then + if (participant_data.acknack_res_time = TIME_INVALID) then case (message_type) is when EDP => -- Subscriber Acknack @@ -1256,28 +1491,38 @@ begin -- If Reader has not ACKed all Publisher History Cache if (first_seq_nr <= PUB_SEQUENCENUMBER) then -- Set Acknack Response Time and Publisher Data as Acknack Response - mem_opcode <= UPDATE_PARTICIPANT; - deadline_next <= time + PARTICIPANT_ACKNACK_RESPONSE_DELAY; + mem_op_start <= '1'; + mem_opcode <= UPDATE_PARTICIPANT; + mem_field_flags <= PMF_EXTRA_FLAGS_FLAG or PMF_ACKNACK_RES_TIME_FLAG; + tmp_dw := time + PARTICIPANT_ACKNACK_RESPONSE_DELAY; + res_time <= tmp_dw; -- NOTE: Last Bit denotes if this is Response or Suppression Delay - deadline_next(1)(0) <= '0'; - extra_flags_next <= mem_participant_data.extra_flags; - extra_flags_next(PUB_DATA_FLAG) <= '1'; - update_participant_flags_next <= (EXTRA_FLAGS_FLAG => '1', ACKNACK_RES_TIME_FLAG => '1', others => '0'); - mem_op_start <= '1'; + res_time(1)(0) <= '0'; + extra_flags <= participant_data.extra_flags or EF_PUB_DATA_FLAG; + -- XXX: Possible Worst Case Path (64-bit addition and comparison in same clock) + -- Update Check Time + if (tmp_dw < check_time) then + check_time_next <= tmp_dw; + end if; end if; -- Publisher Acknack else -- If Reader has not ACKed all Subscriber History Cache if (first_seq_nr <= SUB_SEQUENCENUMBER) then -- Set Acknack Response Time and set Subscriber Data as Acknack Response - mem_opcode <= UPDATE_PARTICIPANT; - deadline_next <= time + PARTICIPANT_ACKNACK_RESPONSE_DELAY; + mem_op_start <= '1'; + mem_opcode <= UPDATE_PARTICIPANT; + mem_field_flags <= PMF_EXTRA_FLAGS_FLAG or PMF_ACKNACK_RES_TIME_FLAG; + tmp_dw := time + PARTICIPANT_ACKNACK_RESPONSE_DELAY; + res_time <= tmp_dw; -- NOTE: Last Bit denotes if this is Response or Suppression Delay - deadline_next(1)(0) <= '0'; - extra_flags_next <= mem_participant_data.extra_flags; - extra_flags_next(SUB_DATA_FLAG) <= '1'; - update_participant_flags_next <= (EXTRA_FLAGS_FLAG => '1', ACKNACK_RES_TIME_FLAG => '1', others => '0'); - mem_op_start <= '1'; + res_time(1)(0) <= '0'; + extra_flags <= participant_data.extra_flags or EF_SUB_DATA_FLAG; + -- XXX: Possible Worst Case Path (64-bit addition and comparison in same clock) + -- Update Check Time + if (tmp_dw < check_time) then + check_time_next <= tmp_dw; + end if; end if; end if; -- Message Acknack @@ -1286,65 +1531,67 @@ begin -- If Reader has not ACKed all Message History Cache if (first_seq_nr <= auto_live_seq_nr) then -- Set Acknack Response Time and set Message Data as Acknack Response - mem_opcode <= UPDATE_PARTICIPANT; - deadline_next <= time + PARTICIPANT_ACKNACK_RESPONSE_DELAY; + mem_op_start <= '1'; + mem_opcode <= UPDATE_PARTICIPANT; + mem_field_flags <= PMF_EXTRA_FLAGS_FLAG or PMF_ACKNACK_RES_TIME_FLAG; + tmp_dw := time + PARTICIPANT_ACKNACK_RESPONSE_DELAY; + res_time <= tmp_dw; -- NOTE: Last Bit denotes if this is Response or Suppression Delay - deadline_next(1)(0) <= '0'; - extra_flags_next <= mem_participant_data.extra_flags; - extra_flags_next(MES_DATA_FLAG) <= '1'; - update_participant_flags_next <= (EXTRA_FLAGS_FLAG => '1', ACKNACK_RES_TIME_FLAG => '1', others => '0'); - mem_op_start <= '1'; + res_time(1)(0) <= '0'; + extra_flags <= participant_data.extra_flags or EF_MES_DATA_FLAG; + -- XXX: Possible Worst Case Path (64-bit addition and comparison in same clock) + -- Update Check Time + if (tmp_dw < check_time) then + check_time_next <= tmp_dw; + end if; end if; when others => null; end case; -- Currently in Acknack Response Delay - elsif (mem_participant_data.acknack_res_time(1)(0) = '0') then + elsif (participant_data.acknack_res_time(1)(0) = '0') then case (message_type) is when EDP => -- Subscriber Acknack if (is_subscriber = '1') then -- Publisher Data not scheduled for response - if (mem_participant_data.extra_flags(PUB_DATA_FLAG) = '0') then + if (not check_mask(participant_data.extra_flags, EF_PUB_DATA_FLAG)) then -- If Reader has not ACKed all Publisher History Cache if (first_seq_nr <= PUB_SEQUENCENUMBER) then -- Set Publisher Data as Acknack Response - mem_opcode <= UPDATE_PARTICIPANT; - extra_flags_next <= mem_participant_data.extra_flags; - extra_flags_next(PUB_DATA_FLAG) <= '1'; - update_participant_flags_next <= (EXTRA_FLAGS_FLAG => '1', others => '0'); - mem_op_start <= '1'; + mem_op_start <= '1'; + mem_opcode <= UPDATE_PARTICIPANT; + mem_field_flags <= PMF_EXTRA_FLAGS_FLAG; + extra_flags <= participant_data.extra_flags or EF_PUB_DATA_FLAG; end if; end if; -- Publisher Acknack else -- Subscriber Data not scheduled for response - if (mem_participant_data.extra_flags(SUB_DATA_FLAG) = '0') then + if (not check_mask(participant_data.extra_flags, EF_SUB_DATA_FLAG)) then -- If Reader has not ACKed all Subscriber History Cache if (first_seq_nr <= SUB_SEQUENCENUMBER) then -- Set Subscriber Data as Acknack Response - mem_opcode <= UPDATE_PARTICIPANT; - extra_flags_next <= mem_participant_data.extra_flags; - extra_flags_next(SUB_DATA_FLAG) <= '1'; - update_participant_flags_next <= (EXTRA_FLAGS_FLAG => '1', others => '0'); - mem_op_start <= '1'; + mem_op_start <= '1'; + mem_opcode <= UPDATE_PARTICIPANT; + mem_field_flags <= PMF_EXTRA_FLAGS_FLAG; + extra_flags <= participant_data.extra_flags or EF_SUB_DATA_FLAG; end if; end if; end if; -- Message Acknack when MESSAGE => -- Message Data not scheduled for response - if (mem_participant_data.extra_flags(MES_DATA_FLAG) = '0') then + if (not check_mask(participant_data.extra_flags, EF_MES_DATA_FLAG)) then -- NOTE: "auto_live_seq_nr" always has the higher sequence number by design, so we just need to -- check against that -- If Reader has not ACKed all Message History Cache if (first_seq_nr <= auto_live_seq_nr) then -- Set Message Data as Acknack Response - mem_opcode <= UPDATE_PARTICIPANT; - extra_flags_next <= mem_participant_data.extra_flags; - extra_flags_next(MES_DATA_FLAG) <= '1'; - update_participant_flags_next <= (EXTRA_FLAGS_FLAG => '1', others => '0'); - mem_op_start <= '1'; + mem_op_start <= '1'; + mem_opcode <= UPDATE_PARTICIPANT; + mem_field_flags <= PMF_EXTRA_FLAGS_FLAG; + extra_flags <= participant_data.extra_flags or EF_MES_DATA_FLAG; end if; end if; when others => @@ -1359,7 +1606,7 @@ begin -- Wait for Next Participant to be Fetched if (mem_op_done = '1') then -- No more Participants - if (addr_res = MAX_ADDRESS) then + if (mem_addr_base = PARTICIPANT_MEMORY_MAX_ADDRESS) then -- DONE stage_next <= IDLE; else @@ -1369,104 +1616,152 @@ begin end if; end if; when PARTICIPANT_STALE_CHECK => + -- Preconditions (See Sub-states) + -- Wait for Stale Search to finish if (mem_op_done = '1') then - -- Found Stale Entry - if (addr_res /= MAX_ADDRESS) then - -- Participant Lease Expired - -- NOTE: The mem_participant_data is zero initialized on lease expiration, so we check the default address for zero - -- (since the default address should always be set) - if (mem_participant_data.def_addr = IPv4_ADDRESS_INVALID) then - -- Remove Participant - mem_opcode <= REMOVE_PARTICIPANT; + case (cnt) is + when 0 => mem_op_start <= '1'; - stage_next <= LATCH_REMOVED_GUIDPREFIX; - -- Response Time Reached - else - -- Heartbeat Response - if (is_heartbeat_res = '1') then - -- If Suppression Delay passed, zero the time - if(mem_participant_data.heartbeat_res_time(1)(0) = '1') then - -- Zero Heartbeat Response Time - mem_opcode <= UPDATE_PARTICIPANT; - deadline_next <= (others => (others => '0')); - update_participant_flags_next <= (HEARTBEAT_RES_TIME_FLAG => '1', others => '0'); - mem_op_start <= '1'; - -- DONE - stage_next <= IDLE; - -- If Response Delay Passed - else - -- Set Heartbeat Suppression Time - mem_opcode <= UPDATE_PARTICIPANT; - if (PARTICIPANT_HEARTBEAT_SUPPRESSION_DELAY /= 0) then - -- Set Heartbeat Suppression Time - deadline_next <= time + PARTICIPANT_HEARTBEAT_SUPPRESSION_DELAY; - -- NOTE: Last Bit denotes if this is Response or Suppression Delay - deadline_next(1)(0) <= '1'; + mem_opcode <= GET_NEXT_PARTICIPANT; + mem_field_flags <= PMF_LEASE_DEADLINE_FLAG or PMF_ACKNACK_RES_TIME_FLAG or PMF_HEARTBEAT_RES_TIME_FLAG; + cnt_next <= cnt + 1; + when 1 => + -- Precondition: participant_data set (PMF_LEASE_DEADLINE_FLAG, PMF_HEARTBEAT_RES_TIME_FLAG, PMF_ACKNACK_RES_TIME_FLAG) + assert (check_mask(current_pmf, PMF_LEASE_DEADLINE_FLAG or PMF_HEARTBEAT_RES_TIME_FLAG or PMF_ACKNACK_RES_TIME_FLAG)) severity FAILURE; + + -- Found Stale Entry + if (mem_addr_base /= PARTICIPANT_MEMORY_MAX_ADDRESS) then + + -- Lease Expiration + if (participant_data.lease_deadline /= TIME_INVALID and participant_data.lease_deadline <= time) then + mem_op_start <= '1'; + mem_opcode <= GET_PARTICIPANT; + mem_field_flags <= PMF_GUIDPREFIX_FLAG; + mem_addr_update <= mem_addr_base; + cnt_next <= cnt + 1; + -- HEARTBEAT Response Time + elsif (participant_data.heartbeat_res_time /= TIME_INVALID and participant_data.heartbeat_res_time <= time) then + -- Suppression Delay + if (participant_data.heartbeat_res_time(1)(0) = '1') then + mem_op_start <= '1'; + mem_opcode <= UPDATE_PARTICIPANT; + mem_field_flags <= PMF_HEARTBEAT_RES_TIME_FLAG; + res_time <= TIME_INVALID; + -- Response Delay else - -- Zero Heartbeat Response Time - deadline_next <= (others => (others => '0')); + mem_op_start <= '1'; + mem_opcode <= GET_PARTICIPANT; + mem_field_flags <= PMF_META_IPV4_ADDR_FLAG or PMF_UDP_PORT_FLAG or PMF_PUB_SEQ_NR_FLAG or PMF_SUB_SEQ_NR_FLAG or PMF_MES_SEQ_NR_FLAG; + mem_addr_update <= mem_addr_base; + + -- Send ACKNACK + stage_next <= SEND_HEADER; + return_stage_next <= SEND_ACKNACK; + cnt_next <= 0; + -- Increment Heartbeat/Acknack Counter + count_next <= count + 1; end if; - update_participant_flags_next <= (HEARTBEAT_RES_TIME_FLAG => '1', others => '0'); - mem_op_start <= '1'; - -- Send ACKNACK - -- Increment Heartbeat/Acknack Counter - count_next <= count + 1; - stage_next <= SEND_HEADER; - return_stage_next <= SEND_ACKNACK; - cnt_next <= 0; + + -- Update Check Time + if (participant_data.lease_deadline /= TIME_INVALID and participant_data.lease_deadline < check_time) then + check_time_next <= participant_data.lease_deadline; + end if; + -- ACKNACK Response Time + elsif (participant_data.acknack_res_time /= TIME_INVALID and participant_data.acknack_res_time <= time) then + -- Suppression Delay + if (participant_data.acknack_res_time(1)(0) = '1') then + mem_op_start <= '1'; + mem_opcode <= UPDATE_PARTICIPANT; + mem_field_flags <= PMF_ACKNACK_RES_TIME_FLAG; + res_time <= TIME_INVALID; + -- Response Delay + else + mem_op_start <= '1'; + mem_opcode <= GET_PARTICIPANT; + mem_field_flags <= PMF_META_IPV4_ADDR_FLAG or PMF_UDP_PORT_FLAG or PMF_EXTRA_FLAGS_FLAG; + mem_addr_update <= mem_addr_base; + + -- Send Requested Data + stage_next <= SEND_HEADER; + return_stage_next <= SEND_PUB_DATA; + cnt_next <= 0; + end if; + else + -- Continue Search + mem_op_start <= '1'; + mem_opcode <= GET_NEXT_PARTICIPANT; + mem_field_flags <= PMF_LEASE_DEADLINE_FLAG or PMF_ACKNACK_RES_TIME_FLAG or PMF_HEARTBEAT_RES_TIME_FLAG; + end if; + + -- NOTE: If the Lease Time expired, but one of the response times is less the check_time, the check_time will be updated + -- Update Check Time + -- XXX: Possible Worst Case Path (4 consecutive 64-bit comparisons in same clock) + tmp_dw := min_time(participant_data.lease_deadline, participant_data.heartbeat_res_time, participant_data.acknack_res_time, time); + if (tmp_dw < check_time) then + check_time_next <= tmp_dw; end if; - -- Acknack Response else - -- If Suppression Delay passed, zero the time - if(mem_participant_data.acknack_res_time(1)(0) = '1') then - -- Zero Acknack Response Time - mem_opcode <= UPDATE_PARTICIPANT; - deadline_next <= (others => (others => '0')); - update_participant_flags_next <= (ACKNACK_RES_TIME_FLAG => '1', others => '0'); - mem_op_start <= '1'; - -- DONE - stage_next <= IDLE; - -- If Response Delay Passed - else - mem_opcode <= UPDATE_PARTICIPANT; - if (PARTICIPANT_ACKNACK_SUPPRESSION_DELAY /= 0) then - -- Set Acknack Suppression Time - deadline_next <= time + PARTICIPANT_ACKNACK_SUPPRESSION_DELAY; - -- NOTE: Last Bit denotes if this is Response or Suppression Delay - deadline_next(1)(0) <= '1'; - else - -- Zero Acknack Response Time - deadline_next <= (others => (others => '0')); - end if; - -- Zero Data Response Flags - extra_flags_next <= mem_participant_data.extra_flags; - extra_flags_next(PUB_DATA_FLAG) <= '0'; - extra_flags_next(SUB_DATA_FLAG) <= '0'; - extra_flags_next(MES_DATA_FLAG) <= '0'; - update_participant_flags_next <= (EXTRA_FLAGS_FLAG => '1', ACKNACK_RES_TIME_FLAG => '1', others => '0'); - mem_op_start <= '1'; - -- Send Requested Data - stage_next <= SEND_HEADER; - return_stage_next <= SEND_PUB_DATA; - cnt_next <= 0; - end if; + -- Reset + stale_check_next <= '0'; + -- DONE + stage_next <= IDLE; end if; - end if; - -- No Stale Entry Found - else - -- DONE - stage_next <= IDLE; - end if; - end if; - when LATCH_REMOVED_GUIDPREFIX => - if (mem_op_done = '1') then - -- Help Stage needed to latch the GUID Prefix of the removed staled participant - guid_next(0) <= mem_guidprefix(0); - guid_next(1) <= mem_guidprefix(1); - guid_next(2) <= mem_guidprefix(2); - stage_next <= INFORM_ENDPOINTS_PARTICIPANT_UNMATCH; - cnt_next <= 0; + when 2 => + -- Precondition: participant_data set (PMF_GUIDPREFIX_FLAG) + assert (check_mask(current_pmf, PMF_GUIDPREFIX_FLAG)) severity FAILURE; + + -- Latch GUID Prefix + guid_next(0) <= participant_data.guid_prefix(0); + guid_next(1) <= participant_data.guid_prefix(1); + guid_next(2) <= participant_data.guid_prefix(2); + -- Remove Participant + mem_op_start <= '1'; + mem_opcode <= REMOVE_PARTICIPANT; + + stage_next <= INFORM_ENDPOINTS_PARTICIPANT_UNMATCH; + cnt_next <= 0; + when 3 => + mem_op_start <= '1'; + mem_opcode <= UPDATE_PARTICIPANT; + mem_field_flags <= PMF_HEARTBEAT_RES_TIME_FLAG; + if (PARTICIPANT_HEARTBEAT_SUPPRESSION_DELAY /= 0) then + -- Set Heartbeat Suppression Time + res_time <= time + PARTICIPANT_HEARTBEAT_SUPPRESSION_DELAY; + -- NOTE: Last Bit denotes if this is Response or Suppression Delay + res_time(1)(0) <= '1'; + else + -- Reset + res_time <= TIME_INVALID; + end if; + -- NOTE: We go back to the Comparison Sub-state to check for further deadlines. + -- The check_time is updated in that sub-state. + -- Continue + cnt_next <= 1; + when 4 => + -- Precondition: participant_data set (PMF_EXTRA_FLAGS_FLAG) + assert (check_mask(current_pmf, PMF_EXTRA_FLAGS_FLAG)) severity FAILURE; + + mem_op_start <= '1'; + mem_opcode <= UPDATE_PARTICIPANT; + mem_field_flags <= PMF_ACKNACK_RES_TIME_FLAG or PMF_EXTRA_FLAGS_FLAG; + extra_flags <= participant_data.extra_flags and (not (EF_PUB_DATA_FLAG or EF_SUB_DATA_FLAG or EF_MES_DATA_FLAG)); + if (PARTICIPANT_ACKNACK_SUPPRESSION_DELAY /= 0) then + -- Set Acknack Suppression Time + res_time <= time + PARTICIPANT_ACKNACK_SUPPRESSION_DELAY; + -- NOTE: Last Bit denotes if this is Response or Suppression Delay + res_time(1)(0) <= '1'; + else + -- Reset + res_time <= TIME_INVALID; + end if; + -- NOTE: We go back to the Comparison Sub-state to check for further deadlines. + -- The check_time is updated in that sub-state. + -- Continue + cnt_next <= 1; + when others => + null; + end case; end if; when PROCESS_PL => -- Input FIFO Guard @@ -1505,7 +1800,7 @@ begin -- Mark String contents (Needed for string comparison) string_content_next <= DOMAIN_TAG_TYPE; -- Mark reception of DOMAIN_TAG - rcvd_next(DOMAIN_TAG_RCVD) <= '1'; + rcvd_next <= rcvd or RCVD_DOMAIN_TAG_FLAG; end if; when PID_PROTOCOL_VERSION => -- Ignore in-line QoS @@ -1584,8 +1879,8 @@ begin -- Ignore in-line QoS -- Only relevant for Endpoint Discovery Protocol if(qos_flag = '0' and message_type = EDP) then - stage_next <= RXO_DURABILITY; - rcvd_next(DURABILITY_QOS_RCVD_FLAG) <= '1'; + stage_next <= RXO_DURABILITY; + rcvd_next <= rcvd or RCVD_DURABILITY_QOS_FLAG; end if; when PID_DEADLINE => -- Ignore in-line QoS @@ -1593,14 +1888,14 @@ begin if(qos_flag = '0' and message_type = EDP) then stage_next <= RXO_DEADLINE; cnt_next <= 0; - rcvd_next(DEADLINE_QOS_RCVD_FLAG) <= '1'; + rcvd_next <= rcvd or RCVD_DEADLINE_QOS_FLAG; end if; when PID_LIVELINESS => -- Ignore in-line QoS -- Only relevant for Endpoint Discovery Protocol if(qos_flag = '0' and message_type = EDP) then - stage_next <= RXO_LIVELINESS; - rcvd_next(LIVELINESS_QOS_RCVD_FLAG) <= '1'; + stage_next <= RXO_LIVELINESS; + rcvd_next <= rcvd or RCVD_LIVELINESS_QOS_FLAG; end if; when PID_RELIABILITY => -- Ignore in-line QoS @@ -1608,21 +1903,21 @@ begin if(qos_flag = '0' and message_type = EDP) then stage_next <= RXO_RELIABILITY; cnt_next <= 0; - rcvd_next(RELIABILITY_QOS_RCVD_FLAG) <= '1'; + rcvd_next <= rcvd or RCVD_RELIABILITY_QOS_FLAG; end if; when PID_DESTINATION_ORDER => -- Ignore in-line QoS -- Only relevant for Endpoint Discovery Protocol if(qos_flag = '0' and message_type = EDP) then - stage_next <= RXO_DESTINATION_ORDER; - rcvd_next(DESTINATION_ORDER_QOS_RCVD_FLAG) <= '1'; + stage_next <= RXO_DESTINATION_ORDER; + rcvd_next <= rcvd or RCVD_DESTINATION_ORDER_QOS_FLAG; end if; when PID_OWNERSHIP => -- Ignore in-line QoS -- Only relevant for Endpoint Discovery Protocol if(qos_flag = '0' and message_type = EDP) then stage_next <= RXO_OWNERSHIP; - rcvd_next(OWNERSHIP_QOS_RCVD_FLAG) <= '1'; + rcvd_next <= rcvd or RCVD_OWNERSHIP_QOS_FLAG; end if; when PID_PRESENTATION => -- Ignore in-line QoS @@ -1630,7 +1925,7 @@ begin if(qos_flag = '0' and message_type = EDP) then stage_next <= RXO_PRESENTATION; cnt_next <= 0; - rcvd_next(PRESENTATION_QOS_RCVD_FLAG) <= '1'; + rcvd_next <= rcvd or RCVD_PRESENTATION_QOS_FLAG; end if; when PID_PARTITION => -- Ignore in-line QoS @@ -1644,7 +1939,7 @@ begin if(qos_flag = '0' and message_type = EDP) then stage_next <= RXO_LATENCY_BUDGET; cnt_next <= 0; - rcvd_next(LATENCY_BUDGET_QOS_RCVD_FLAG) <= '1'; + rcvd_next <= rcvd or RCVD_LATENCY_BUDGET_QOS_FLAG; end if; when PID_UNICAST_LOCATOR => -- Ignore in-line QoS @@ -1798,8 +2093,8 @@ begin case (message_type) is when PDP => - -- Check Domain Tag against Default if necessary - if (rcvd(DOMAIN_TAG_RCVD) = '0' and DOMAIN_TAG /= DEFAULT_DOMAIN_TAG) then + -- Check Domain Tag against Default if necessary + if (not check_mask(rcvd, RCVD_DOMAIN_TAG_FLAG) and DOMAIN_TAG /= DEFAULT_DOMAIN_TAG) then participant_match_next <= '0'; end if; when EDP => @@ -1811,28 +2106,28 @@ begin tmp_default_qos_match := WRITER_DEFAULT_QOS_MATCH; end if; - if (rcvd(DURABILITY_QOS_RCVD_FLAG) = '0') then + if (not check_mask(rcvd, RCVD_DURABILITY_QOS_FLAG)) then tmp_endpoint_mask := tmp_endpoint_mask and tmp_default_qos_match.DURABILITY_QOS; end if; - if (rcvd(PRESENTATION_QOS_RCVD_FLAG) = '0') then + if (not check_mask(rcvd, RCVD_PRESENTATION_QOS_FLAG)) then tmp_endpoint_mask := tmp_endpoint_mask and tmp_default_qos_match.PRESENTATION_QOS; end if; - if (rcvd(DEADLINE_QOS_RCVD_FLAG) = '0') then + if (not check_mask(rcvd, RCVD_DEADLINE_QOS_FLAG)) then tmp_endpoint_mask := tmp_endpoint_mask and tmp_default_qos_match.DEADLINE_QOS; end if; - if (rcvd(LATENCY_BUDGET_QOS_RCVD_FLAG) = '0') then + if (not check_mask(rcvd, RCVD_LATENCY_BUDGET_QOS_FLAG)) then tmp_endpoint_mask := tmp_endpoint_mask and tmp_default_qos_match.LATENCY_BUDGET_QOS; end if; - if (rcvd(OWNERSHIP_QOS_RCVD_FLAG) = '0') then + if (not check_mask(rcvd, RCVD_OWNERSHIP_QOS_FLAG)) then tmp_endpoint_mask := tmp_endpoint_mask and tmp_default_qos_match.OWNERSHIP_QOS; end if; - if (rcvd(LIVELINESS_QOS_RCVD_FLAG) = '0') then + if (not check_mask(rcvd, RCVD_LIVELINESS_QOS_FLAG)) then tmp_endpoint_mask := tmp_endpoint_mask and tmp_default_qos_match.LIVELINESS_QOS; end if; - if (rcvd(RELIABILITY_QOS_RCVD_FLAG) = '0') then + if (not check_mask(rcvd, RCVD_RELIABILITY_QOS_FLAG)) then tmp_endpoint_mask := tmp_endpoint_mask and tmp_default_qos_match.RELIABILITY_QOS; end if; - if (rcvd(DESTINATION_ORDER_QOS_RCVD_FLAG) = '0') then + if (not check_mask(rcvd, RCVD_DESTINATION_ORDER_QOS_FLAG)) then tmp_endpoint_mask := tmp_endpoint_mask and tmp_default_qos_match.DESTINATION_ORDER_QOS; end if; @@ -1909,8 +2204,6 @@ begin stage_next <= SKIP_PACKET; end if; when 3 => - -- NOTE: Even though the mem_ctrl_prc is currently using the guid signal, it only uses the first - -- 3 words (GUIDPrefix) for the SEARCH_PARTICIPANT guid_next(3) <= data_in; -- DONE stage_next <= SKIP_PARAMETER; @@ -2002,7 +2295,6 @@ begin rd_guard := '1'; -- Latch 'expectsInlineQoS' - extra_flags_next(EXPECTS_INLINE_QOS_FLAG) <= data_in(24); reader_flags_next(READER_EXPECTS_INLINE_QOS_FLAG) <= data_in(24); -- DONE @@ -2287,16 +2579,26 @@ begin stage_next <= SKIP_PARAMETER; end if; when PARTICIPANT_MATCH_STAGE => + -- Precondition: participant_data set (PMF_SPDP_SEQ_NR_FLAG/PMF_PUB_SEQ_NR_FLAG/PMF_SUB_SEQ_NR_FLAG/PMF_MES_SEQ_NR_FLAG) + assert_sn; + -- Wait for Participant Search to finish if (mem_op_done = '1') then -- Participant not in Buffer - if (addr_res = MAX_ADDRESS) then + if (mem_addr_base = PARTICIPANT_MEMORY_MAX_ADDRESS) then -- Participant Match if (message_type = PDP and participant_match = '1') then -- Add participant in buffer - deadline_next <= time + lease_duration; - mem_opcode <= INSERT_PARTICIPANT; mem_op_start <= '1'; + mem_opcode <= INSERT_PARTICIPANT; + tmp_dw := time + lease_duration; + deadline <= tmp_dw; + -- XXX: Possible Worst Case Path (64-bit addition and comparison in same clock) + -- Update Check Time + if (tmp_dw < check_time) then + check_time_next <= tmp_dw; + end if; + -- DONE stage_next <= SKIP_PACKET; else @@ -2312,28 +2614,40 @@ begin -- Participant Unmatch if (participant_match = '0') then -- Remove participant from buffer - mem_opcode <= REMOVE_PARTICIPANT; mem_op_start <= '1'; + mem_opcode <= REMOVE_PARTICIPANT; -- Inform ENDPOINTS stage_next <= INFORM_ENDPOINTS_PARTICIPANT_UNMATCH; cnt_next <= 0; -- Participant remains matched else -- Update Participant Data and Lease - mem_opcode <= UPDATE_PARTICIPANT; - deadline_next <= time + lease_duration; - update_participant_flags_next <= (PARTICIPANT_DATA_FLAG => '1', LEASE_DEADLINE_FLAG => '1', EXTRA_FLAGS_FLAG => '1', others => '0'); - mem_op_start <= '1'; + mem_op_start <= '1'; + mem_opcode <= UPDATE_PARTICIPANT; + mem_field_flags <= PMF_META_IPV4_ADDR_FLAG or PMF_DEFAULT_IPV4_ADDR_FLAG or PMF_UDP_PORT_FLAG or PMF_SPDP_SEQ_NR_FLAG or PMF_LEASE_DURATION_FLAG or PMF_LEASE_DEADLINE_FLAG; + tmp_dw := time + lease_duration; + deadline <= tmp_dw; + -- XXX: Possible Worst Case Path (64-bit addition and comparison in same clock) + -- Update Check Time + if (tmp_dw < check_time) then + check_time_next <= tmp_dw; + end if; -- DONE - stage_next <= SKIP_PACKET; + stage_next <= SKIP_PACKET; end if; -- Old Sequence Number else -- Update Lease - mem_opcode <= UPDATE_PARTICIPANT; - deadline_next <= time + lease_duration; - update_participant_flags_next <= (LEASE_DEADLINE_FLAG => '1', others => '0'); - mem_op_start <= '1'; + mem_op_start <= '1'; + mem_opcode <= UPDATE_PARTICIPANT; + mem_field_flags <= PMF_LEASE_DEADLINE_FLAG; + tmp_dw := time + lease_duration; + deadline <= tmp_dw; + -- XXX: Possible Worst Case Path (64-bit addition and comparison in same clock) + -- Update Check Time + if (tmp_dw < check_time) then + check_time_next <= tmp_dw; + end if; -- DONE stage_next <= SKIP_PACKET; end if; @@ -2343,20 +2657,24 @@ begin -- Endpoint (Next Expected Sequence Number) elsif (message_type = EDP and mem_seq_nr = seq_nr) then -- Store new Sequence Number - mem_opcode <= UPDATE_PARTICIPANT; - update_participant_flags_next <= (EDP_SEQ_NR_FLAG => '1', others => '0'); - mem_op_start <= '1'; + mem_op_start <= '1'; + mem_opcode <= UPDATE_PARTICIPANT; + if (is_subscriber = '0') then + mem_field_flags <= PMF_PUB_SEQ_NR_FLAG; + else + mem_field_flags <= PMF_SUB_SEQ_NR_FLAG; + end if; -- At least one local Endpoint match if (endpoint_mask /= (endpoint_mask'range => '0')) then -- Propagate Matches to local Endpoints - stage_next <= INFORM_ENDPOINTS_MATCH; - cnt_next <= 0; + stage_next <= INFORM_ENDPOINTS_MATCH; + cnt_next <= 0; -- No local Endpoint matches else -- Propagate Matches to local Endpoints - stage_next <= INFORM_ENDPOINTS_UNMATCH; - cnt_next <= 0; + stage_next <= INFORM_ENDPOINTS_UNMATCH; + cnt_next <= 0; end if; else -- Ignore (Messages are handled in a dedicated stage) @@ -2365,58 +2683,64 @@ begin end if; end if; when INFORM_ENDPOINTS_MATCH => - -- Output FIFO Guard - if ((endpoint_mask and endpoint_full) = (endpoint_full'range => '0')) then - wr_sig <= '1'; - cnt_next <= cnt + 1; - - case (cnt) is - -- Match Opcode - when 0 => - data_out <= OPCODE_ENDPOINT_MATCH; - -- GUID Prefix 1/3 - when 1 => - data_out <= guid(0); - -- GUID Prefix 2/3 - when 2 => - data_out <= guid(1); - -- GUID Prefix 3/3 - when 3 => - data_out <= guid(2); - -- Entity ID - when 4 => - data_out <= guid(3); - -- IPv4 Address - when 5 => - -- If Endpoint did not set Address, use Participant Default - if (def_addr /= (def_addr'reverse_range => '0')) then - data_out <= def_addr; - else - data_out <= mem_participant_data.def_addr; - end if; - -- UDPv4 Port and Reader Flags - when 6 => - -- Default - data_out <= (others => '0'); - last_word_out <= '1'; - - -- If Endpoint did not set Port, use Participant Default - if (def_port /= (def_port'reverse_range => '0')) then - data_out(31 downto 16) <= def_port; - else - data_out(31 downto 16) <= mem_participant_data.def_port; - end if; - - if (is_subscriber = '1') then - data_out(15 downto 0) <= reader_flags; - end if; - - -- DONE - stage_next <= INFORM_ENDPOINTS_UNMATCH; - cnt_next <= 0; - when others => - null; - end case; + -- Precondition: participant_data set (PMF_DEFAULT_IPV4_ADDR_FLAG, PMF_UDP_PORT_FLAG) + assert (check_mask(current_pmf, PMF_DEFAULT_IPV4_ADDR_FLAG or PMF_UDP_PORT_FLAG)) severity FAILURE; + + -- Wait for Participant Data + if (mem_op_done = '1') then + -- Output FIFO Guard + if ((endpoint_mask and endpoint_full) = (endpoint_full'range => '0')) then + wr_sig <= '1'; + cnt_next <= cnt + 1; + + case (cnt) is + -- Match Opcode + when 0 => + data_out <= OPCODE_ENDPOINT_MATCH; + -- GUID Prefix 1/3 + when 1 => + data_out <= guid(0); + -- GUID Prefix 2/3 + when 2 => + data_out <= guid(1); + -- GUID Prefix 3/3 + when 3 => + data_out <= guid(2); + -- Entity ID + when 4 => + data_out <= guid(3); + -- IPv4 Address + when 5 => + -- If Endpoint did not set Address, use Participant Default + if (def_addr /= (def_addr'reverse_range => '0')) then + data_out <= def_addr; + else + data_out <= participant_data.def_addr; + end if; + -- UDPv4 Port and Reader Flags + when 6 => + -- Default + data_out <= (others => '0'); + last_word_out <= '1'; + + -- If Endpoint did not set Port, use Participant Default + if (def_port /= (def_port'reverse_range => '0')) then + data_out(31 downto 16) <= def_port; + else + data_out(31 downto 16) <= participant_data.def_port; + end if; + + if (is_subscriber = '1') then + data_out(15 downto 0) <= reader_flags; + end if; + + -- DONE + stage_next <= INFORM_ENDPOINTS_UNMATCH; + cnt_next <= 0; + when others => + null; + end case; + end if; end if; when INFORM_ENDPOINTS_UNMATCH => -- Output FIFO Guard @@ -2469,58 +2793,72 @@ begin data_out <= guid(2); last_word_out <= '1'; - -- DONE - stage_next <= SKIP_PACKET; + -- Currently in Stale Check + if (stale_check = '1') then + stage_next <= PARTICIPANT_STALE_CHECK; + cnt_next <= 0; + else + -- DONE + stage_next <= SKIP_PACKET; + end if; when others => null; end case; end if; when SEND_HEADER => - if (rtps_full = '0') then - wr_sig <= '1'; - cnt_next <= cnt + 1; - - case (cnt) is - -- OUTPUT HEADER - -- Src IPv4 Address - when 0 => - data_out <= DEFAULT_IPv4_ADDRESS; - -- Dest IPv4 Address - when 1 => - -- Set Default Multicast Announce Address if Participant Announcement - if (return_stage = SEND_PARTICIPANT_ANNOUNCEMENT) then - data_out <= DEFAULT_IPv4_META_ADDRESS; - else - data_out <= mem_participant_data.meta_addr; - end if; - -- Src and Dest UDPv4 Ports - when 2 => - -- Set Default Multicast Announce Port if Participant Announcement - if (return_stage = SEND_PARTICIPANT_ANNOUNCEMENT) then - data_out <= META_IPv4_UNICAST_PORT & META_IPv4_MULTICAST_PORT; - else - data_out <= META_IPv4_UNICAST_PORT & mem_participant_data.meta_port; - end if; - -- RTPS MESSAGE HEADER - when 3 => - data_out <= PROTOCOL_RTPS; - when 4 => - data_out <= PROTOCOLVERSION_2_4 & VENDORID; - when 5 => - data_out <= GUIDPREFIX(0); - when 6 => - data_out <= GUIDPREFIX(1); - when 7 => - data_out <= GUIDPREFIX(2); - -- Continue with respective RTPS Submessage - stage_next <= return_stage; - cnt_next <= 0; - participant_data_cnt_next <= 0; - publisher_data_cnt_next <= 0; - subscriber_data_cnt_next <= 0; - when others => - null; - end case; + -- Precondition: participant_data set (PMF_META_IPV4_ADDR_FLAG, PMF_UDP_PORT_FLAG) [if return_stage /= SEND_PARTICIPANT_ANNOUNCEMENT] + if (return_stage /= SEND_PARTICIPANT_ANNOUNCEMENT) then + assert (check_mask(current_pmf, PMF_META_IPV4_ADDR_FLAG or PMF_UDP_PORT_FLAG)) severity FAILURE; + end if; + + -- Wait for Participant Data + if (mem_op_done = '1') then + if (rtps_full = '0') then + wr_sig <= '1'; + cnt_next <= cnt + 1; + + case (cnt) is + -- OUTPUT HEADER + -- Src IPv4 Address + when 0 => + data_out <= DEFAULT_IPv4_ADDRESS; + -- Dest IPv4 Address + when 1 => + -- Set Default Multicast Announce Address if Participant Announcement + if (return_stage = SEND_PARTICIPANT_ANNOUNCEMENT) then + data_out <= DEFAULT_IPv4_META_ADDRESS; + else + data_out <= participant_data.meta_addr; + end if; + -- Src and Dest UDPv4 Ports + when 2 => + -- Set Default Multicast Announce Port if Participant Announcement + if (return_stage = SEND_PARTICIPANT_ANNOUNCEMENT) then + data_out <= META_IPv4_UNICAST_PORT & META_IPv4_MULTICAST_PORT; + else + data_out <= META_IPv4_UNICAST_PORT & participant_data.meta_port; + end if; + -- RTPS MESSAGE HEADER + when 3 => + data_out <= PROTOCOL_RTPS; + when 4 => + data_out <= PROTOCOLVERSION_2_4 & VENDORID; + when 5 => + data_out <= GUIDPREFIX(0); + when 6 => + data_out <= GUIDPREFIX(1); + when 7 => + data_out <= GUIDPREFIX(2); + -- Continue with respective RTPS Submessage + stage_next <= return_stage; + cnt_next <= 0; + participant_data_cnt_next <= 0; + publisher_data_cnt_next <= 0; + subscriber_data_cnt_next <= 0; + when others => + null; + end case; + end if; end if; when SEND_PARTICIPANT_ANNOUNCEMENT => if (rtps_full = '0') then @@ -2528,94 +2866,101 @@ begin participant_data_cnt_next <= participant_data_cnt + 1; -- Send Participant Data - data_out <= PARTICIPANT_DATA.data(participant_data_cnt); + data_out <= LOCAL_PARTICIPANT_DATA.data(participant_data_cnt); -- Exit Condition - if (participant_data_cnt = (PARTICIPANT_DATA.length-1)) then + if (participant_data_cnt = (LOCAL_PARTICIPANT_DATA.length-1)) then last_word_out <= '1'; -- DONE stage_next <= IDLE; end if; end if; when SEND_ACKNACK => - if (rtps_full = '0') then - wr_sig <= '1'; - cnt_next <= cnt + 1; - - case (cnt) is - -- ACKNACK RTPS SUBMESSAGE (Publication) - -- RTPS Submessage Header - when 0 => - data_out <= SID_ACKNACK & "00000010" & std_logic_vector(to_unsigned(24, 16)); - -- Reader Entity ID - when 1 => - data_out <= ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_DETECTOR; - -- Writer Entity ID - when 2 => - data_out <= ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_ANNOUNCER; - -- Sequence Number Set (Bitmap Base 1/2) - when 3 => - data_out <= std_logic_vector(mem_participant_data.pub_seq_nr(0)); - -- Sequence Number Set (Bitmap Base 2/2) - when 4 => - data_out <= std_logic_vector(mem_participant_data.pub_seq_nr(1)); - -- Sequence Number Set (NumBits) - when 5 => - data_out <= (others => '0'); - -- Count - when 6 => - data_out <= std_logic_vector(count); - -- ACKNACK RTPS SUBMESSAGE (Subscription) - -- RTPS Submessage Header - when 7 => - data_out <= SID_ACKNACK & "00000010" & std_logic_vector(to_unsigned(24, 16)); - -- Reader Entity ID - when 8 => - data_out <= ENTITYID_SEDP_BUILTIN_PUBLICATIONS_DETECTOR; - -- Writer Entity ID - when 9 => - data_out <= ENTITYID_SEDP_BUILTIN_PUBLICATIONS_ANNOUNCER; - -- Sequence Number Set (Bitmap Base 1/2) - when 10 => - data_out <= std_logic_vector(mem_participant_data.sub_seq_nr(0)); - -- Sequence Number Set (Bitmap Base 2/2) - when 11 => - data_out <= std_logic_vector(mem_participant_data.sub_seq_nr(1)); - -- Sequence Number Set (NumBits) - when 12 => - data_out <= (others => '0'); - -- Count - when 13 => - data_out <= std_logic_vector(count); - -- ACKNACK RTPS SUBMESSAGE (Message) - -- RTPS Submessage Header - when 14 => - data_out <= SID_ACKNACK & "00000010" & std_logic_vector(to_unsigned(24, 16)); - -- Reader Entity ID - when 15 => - data_out <= ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER; - -- Writer Entity ID - when 16 => - data_out <= ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER; - -- Sequence Number Set (Bitmap Base 1/2) - when 17 => - data_out <= std_logic_vector(mem_participant_data.mes_seq_nr(0)); - -- Sequence Number Set (Bitmap Base 2/2) - when 18 => - data_out <= std_logic_vector(mem_participant_data.mes_seq_nr(1)); - -- Sequence Number Set (NumBits) - when 19 => - data_out <= (others => '0'); - -- Count - when 20 => - data_out <= std_logic_vector(count); - last_word_out <= '1'; - - -- DONE - stage_next <= IDLE; - when others => - null; - end case; + -- Precondition: participant_data set (PMF_PUB_SEQ_NR_FLAG, PMF_SUB_SEQ_NR_FLAG, PMF_MES_SEQ_NR_FLAG) + assert (check_mask(current_pmf, PMF_PUB_SEQ_NR_FLAG or PMF_SUB_SEQ_NR_FLAG or PMF_MES_SEQ_NR_FLAG)) severity FAILURE; + + -- Wait for Participant Data + if (mem_op_done = '1') then + if (rtps_full = '0') then + wr_sig <= '1'; + cnt_next <= cnt + 1; + + case (cnt) is + -- ACKNACK RTPS SUBMESSAGE (Publication) + -- RTPS Submessage Header + when 0 => + data_out <= SID_ACKNACK & "00000010" & std_logic_vector(to_unsigned(24, 16)); + -- Reader Entity ID + when 1 => + data_out <= ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_DETECTOR; + -- Writer Entity ID + when 2 => + data_out <= ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_ANNOUNCER; + -- Sequence Number Set (Bitmap Base 1/2) + when 3 => + data_out <= std_logic_vector(participant_data.pub_seq_nr(0)); + -- Sequence Number Set (Bitmap Base 2/2) + when 4 => + data_out <= std_logic_vector(participant_data.pub_seq_nr(1)); + -- Sequence Number Set (NumBits) + when 5 => + data_out <= (others => '0'); + -- Count + when 6 => + data_out <= std_logic_vector(count); + -- ACKNACK RTPS SUBMESSAGE (Subscription) + -- RTPS Submessage Header + when 7 => + data_out <= SID_ACKNACK & "00000010" & std_logic_vector(to_unsigned(24, 16)); + -- Reader Entity ID + when 8 => + data_out <= ENTITYID_SEDP_BUILTIN_PUBLICATIONS_DETECTOR; + -- Writer Entity ID + when 9 => + data_out <= ENTITYID_SEDP_BUILTIN_PUBLICATIONS_ANNOUNCER; + -- Sequence Number Set (Bitmap Base 1/2) + when 10 => + data_out <= std_logic_vector(participant_data.sub_seq_nr(0)); + -- Sequence Number Set (Bitmap Base 2/2) + when 11 => + data_out <= std_logic_vector(participant_data.sub_seq_nr(1)); + -- Sequence Number Set (NumBits) + when 12 => + data_out <= (others => '0'); + -- Count + when 13 => + data_out <= std_logic_vector(count); + -- ACKNACK RTPS SUBMESSAGE (Message) + -- RTPS Submessage Header + when 14 => + data_out <= SID_ACKNACK & "00000010" & std_logic_vector(to_unsigned(24, 16)); + -- Reader Entity ID + when 15 => + data_out <= ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER; + -- Writer Entity ID + when 16 => + data_out <= ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER; + -- Sequence Number Set (Bitmap Base 1/2) + when 17 => + data_out <= std_logic_vector(participant_data.mes_seq_nr(0)); + -- Sequence Number Set (Bitmap Base 2/2) + when 18 => + data_out <= std_logic_vector(participant_data.mes_seq_nr(1)); + -- Sequence Number Set (NumBits) + when 19 => + data_out <= (others => '0'); + -- Count + when 20 => + data_out <= std_logic_vector(count); + last_word_out <= '1'; + + -- Continue + stage_next <= PARTICIPANT_STALE_CHECK; + cnt_next <= 3; + when others => + null; + end case; + end if; end if; when SEND_HEARTBEAT => if (rtps_full = '0') then @@ -2712,55 +3057,75 @@ begin end case; end if; when SEND_PUB_DATA => - -- If Publisher Data not scheduled for response or no Writers available, skip - if (mem_participant_data.extra_flags(PUB_DATA_FLAG) = '0' or NUM_WRITERS = 0) then - stage_next <= SEND_SUB_DATA; - -- Output FIFO Guard - elsif (rtps_full = '0') then - wr_sig <= '1'; - publisher_data_cnt_next <= publisher_data_cnt + 1; - - -- Send Publisher Data - data_out <= WRITER_ENDPOINT_DATA.data(publisher_data_cnt); - - -- Exit Condition - if (publisher_data_cnt = (WRITER_ENDPOINT_DATA.length-1)) then - last_word_out <= '1'; - -- If we still have Data to sent, continue - if (mem_participant_data.extra_flags(SUB_DATA_FLAG) = '1' or mem_participant_data.extra_flags(MES_DATA_FLAG) = '1') then - stage_next <= SEND_HEADER; - return_stage_next <= SEND_SUB_DATA; - cnt_next <= 0; - else - -- DONE - stage_next <= IDLE; + -- Precondition: participant_data set (PMF_EXTRA_FLAGS_FLAG) + assert (check_mask(current_pmf, PMF_EXTRA_FLAGS_FLAG)) severity FAILURE; + + -- Wait for Participant Data + if (mem_op_done = '1') then + -- If Publisher Data not scheduled for response or no Writers available, skip + if (not check_mask(participant_data.extra_flags, EF_PUB_DATA_FLAG) or NUM_WRITERS = 0) then + stage_next <= SEND_SUB_DATA; + -- Output FIFO Guard + elsif (rtps_full = '0') then + wr_sig <= '1'; + publisher_data_cnt_next <= publisher_data_cnt + 1; + + -- Send Publisher Data + data_out <= WRITER_ENDPOINT_DATA.data(publisher_data_cnt); + + -- Exit Condition + if (publisher_data_cnt = (WRITER_ENDPOINT_DATA.length-1)) then + last_word_out <= '1'; + -- If we still have Data to sent, continue + if (check_mask(participant_data.extra_flags, EF_SUB_DATA_FLAG) or check_mask(participant_data.extra_flags, EF_MES_DATA_FLAG)) then + stage_next <= SEND_HEADER; + return_stage_next <= SEND_SUB_DATA; + cnt_next <= 0; + -- Currently in Stale Check + elsif (stale_check = '1') then + stage_next <= PARTICIPANT_STALE_CHECK; + cnt_next <= 4; + else + -- DONE + stage_next <= IDLE; + end if; end if; end if; end if; when SEND_SUB_DATA => - -- If Subscriber Data not scheduled for response or no Readers available, skip - if (mem_participant_data.extra_flags(PUB_DATA_FLAG) = '0' or NUM_READERS = 0) then - stage_next <= SEND_MES_MAN_LIVE; - cnt_next <= 0; - -- Output FIFO Guard - elsif (rtps_full = '0') then - wr_sig <= '1'; - subscriber_data_cnt_next <= subscriber_data_cnt + 1; - - -- Send Subscriber Data - data_out <= READER_ENDPOINT_DATA.data(subscriber_data_cnt); - - -- Exit Condition - if (subscriber_data_cnt = (READER_ENDPOINT_DATA.length-1)) then - last_word_out <= '1'; - -- If we still have Data to sent, continue - if (mem_participant_data.extra_flags(MES_DATA_FLAG) = '1') then - stage_next <= SEND_HEADER; - return_stage_next <= SEND_MES_MAN_LIVE; - cnt_next <= 0; - else - -- DONE - stage_next <= IDLE; + -- Precondition: participant_data set (PMF_EXTRA_FLAGS_FLAG) + assert (check_mask(current_pmf, PMF_EXTRA_FLAGS_FLAG)) severity FAILURE; + + -- Wait for Participant Data + if (mem_op_done = '1') then + -- If Subscriber Data not scheduled for response or no Readers available, skip + if (not check_mask(participant_data.extra_flags, EF_PUB_DATA_FLAG) or NUM_READERS = 0) then + stage_next <= SEND_MES_MAN_LIVE; + cnt_next <= 0; + -- Output FIFO Guard + elsif (rtps_full = '0') then + wr_sig <= '1'; + subscriber_data_cnt_next <= subscriber_data_cnt + 1; + + -- Send Subscriber Data + data_out <= READER_ENDPOINT_DATA.data(subscriber_data_cnt); + + -- Exit Condition + if (subscriber_data_cnt = (READER_ENDPOINT_DATA.length-1)) then + last_word_out <= '1'; + -- If we still have Data to sent, continue + if (check_mask(participant_data.extra_flags, EF_MES_DATA_FLAG)) then + stage_next <= SEND_HEADER; + return_stage_next <= SEND_MES_MAN_LIVE; + cnt_next <= 0; + -- Currently in Stale Check + elsif (stale_check = '1') then + stage_next <= PARTICIPANT_STALE_CHECK; + cnt_next <= 4; + else + -- DONE + stage_next <= IDLE; + end if; end if; end if; end if; @@ -2907,9 +3272,14 @@ begin last_word_out <= '1'; -- If we are in the middle of a liveliness assertion, find the next Participant destination if (is_live_assert = '1') then - stage_next <= FIND_PARTICIPANT_DEST; - mem_opcode <= FIND_NEXT_PARTICIPANT; mem_op_start <= '1'; + mem_opcode <= GET_NEXT_PARTICIPANT; + mem_field_flags <= PMF_META_IPV4_ADDR_FLAG or PMF_UDP_PORT_FLAG; + stage_next <= FIND_PARTICIPANT_DEST; + -- Currently in Stale Check + elsif (stale_check = '1') then + stage_next <= PARTICIPANT_STALE_CHECK; + cnt_next <= 4; else -- DONE stage_next <= IDLE; @@ -2944,12 +3314,8 @@ begin -- Reset Parameter End parameter_end_next <= (others => '1'); - -- Stale Check Exit - if (stale_check = '1') then - -- DONE - stage_next <= IDLE; -- Consumed last word of Packet - elsif (last_word_in_latch = '1' and last_word_in = '0') then + if (last_word_in_latch = '1' and last_word_in = '0') then -- Reset Last Word In Latch last_word_in_latch_next <= '0'; -- DONE @@ -2972,7 +3338,7 @@ begin -- Force rd_sig low rd_sig <= '0'; -- Notify Endpoints of EOP - last_word_out <= '1'; -- TODO: Necessary? (We do not pass through input to output, so a EOP should not leave as "stranded" during a write out) + last_word_out <= '1'; -- TODO: Necessary? (We do not pass through input to output, so a EOP should not leave us "stranded" during a write out) -- Continue parsing next Packet stage_next <= IDLE; -- Reset Last Word In Latch @@ -2998,858 +3364,2169 @@ begin end if; end process; - - - -- Main State Machine - -- STATE DESCRIPTION - -- IDLE Idle state. Done Signal is pulled high and Memory FSM accepts new memory operations - -- SEARCH_PARTICIPANT See Memory OPCODE Description - -- GET_PARTICIPANT_DATA Latch the contents of the Participant Entry for use in the main FSM - -- INSERT_PARTICIPANT See Memory OPCODE Description - -- UPDATE_PARTICIPANT See Memory OPCODE Description - -- REMOVE_PARTICIPANT See Memory OPCODE Description - -- FIND_PARTICIPANT_SLOT Find first empty Participant Slot in memory - -- FIND_NEXT_PARTICIPANT See Memory OPCODE Description - -- FIND_STALE_PARTICIPANT See Memory OPCODE Description + -- *Participant Memory Process* + -- STATE DESCRIPTION + -- IDLE Idle State. Done Signal is pulled high and Memory FSM accepts new memory operations + -- SEARCH_PARTICIPANT See Memory OPCODE Description + -- GET_NEXT_PARTICIPANT See Memory OPCODE Description + -- GET_PARTICIPANT_DATA Latch specified Participant Data for use by main process + -- INSERT_PARTICIPANT See Memory OPCODE Description + -- UPDATE_PARTICIPANT See Memory OPCODE Description + -- REMOVE_PARTICIPANT See Memory OPCODE Description + -- RESET_MEMORY Reset Endpoint Memory to Empty State mem_ctrl_prc : process(all) - variable tmp : unsigned(mem_addr_base'range) := (others => '0'); - variable tmp2 : unsigned(mem_addr_base'range) := (others => '0'); - variable tmp3 : unsigned(mem_addr_base'range) := (others => '0'); - variable tmp_dw : DOUBLE_WORD_ARRAY := (others => (others => '0')); begin -- DEFAULT Registered mem_stage_next <= mem_stage; mem_addr_base_next <= mem_addr_base; - mem_addr_next <= mem_addr; - addr_res_next <= addr_res; + mem_empty_head_next <= mem_empty_head; + mem_occupied_head_next <= mem_occupied_head; + mem_next_addr_base_next <= mem_next_addr_base; + mem_prev_addr_base_next <= mem_prev_addr_base; mem_cnt_next <= mem_cnt; - last_addr_next <= last_addr; - mem_participant_data_next <= mem_participant_data; - is_heartbeat_res_next <= is_heartbeat_res; - mem_guidprefix_next <= mem_guidprefix; - max_participant_addr_next <= max_participant_addr; - reset_max_pointer_next <= reset_max_pointer; - mem_long_latch_next <= mem_long_latch; + participant_data_next <= participant_data; + participant_latch_data_next <= participant_latch_data; + current_pmf_next <= current_pmf; -- DEFAULT Unregistered - mem_write_data <= (others => '0'); - mem_op_done <= '0'; - mem_rd <= '0'; - mem_wr <= '0'; + mem_abort_read <= '0'; + mem_ready_out <= '0'; + mem_valid_in <= '0'; + mem_read <= '0'; + mem_op_done <= '0'; + mem_addr <= (others => '0'); + mem_write_data <= (others => '0'); case (mem_stage) is when IDLE => - mem_op_done <= '1'; - reset_max_pointer_next <= '0'; + mem_op_done <= '1'; if (mem_op_start = '1') then + -- Latch Signals needed for Mermory Operation (Use _next signals, because some signals are set in same clk) + participant_latch_data_next <= ( + guid_prefix => (guid_next(0), guid_next(1), guid_next(2)), + meta_addr => meta_addr, + def_addr => def_addr, + meta_port => meta_port, + def_port => def_port, + extra_flags => extra_flags, + lease_duration => lease_duration, + lease_deadline => deadline, + res_time => res_time, + seq_nr => next_seq_nr_next, + field_flags => mem_field_flags + ); + case(mem_opcode) is when SEARCH_PARTICIPANT => - mem_addr_base_next <= FIRST_PARTICIPANT_ADDRESS; - mem_addr_next <= FIRST_PARTICIPANT_ADDRESS; - mem_stage_next <= SEARCH_PARTICIPANT; - mem_cnt_next <= 0; + -- Reset Data + current_pmf_next <= mem_field_flags; + participant_data_next <= ZERO_PARTICIPANT_DATA; + + -- Memory Empty + if (mem_occupied_head = PARTICIPANT_MEMORY_MAX_ADDRESS) then + mem_addr_base_next <= PARTICIPANT_MEMORY_MAX_ADDRESS; + else + mem_prev_addr_base_next <= PARTICIPANT_MEMORY_MAX_ADDRESS; + mem_addr_base_next <= mem_occupied_head; + mem_stage_next <= SEARCH_PARTICIPANT; + mem_cnt_next <= 0; + end if; when INSERT_PARTICIPANT => - mem_addr_base_next <= FIRST_PARTICIPANT_ADDRESS; - mem_addr_next <= FIRST_PARTICIPANT_ADDRESS; - mem_stage_next <= FIND_PARTICIPANT_SLOT; - mem_cnt_next <= 0; + -- Memory Full + if (mem_empty_head = PARTICIPANT_MEMORY_MAX_ADDRESS) then + report "Memory Full, Ignoring Participant Data" severity NOTE; + else + -- Reset Data + current_pmf_next <= (others => '1'); + participant_data_next <= ZERO_PARTICIPANT_DATA; + + mem_prev_addr_base_next <= PARTICIPANT_MEMORY_MAX_ADDRESS; + mem_next_addr_base_next <= mem_occupied_head; + mem_addr_base_next <= mem_empty_head; + mem_stage_next <= INSERT_PARTICIPANT; + mem_cnt_next <= 0; + end if; when UPDATE_PARTICIPANT => - -- NOTE: We use the "_next" flag here, because it is not yet latched. - if (update_participant_flags_next(PARTICIPANT_DATA_FLAG) = '1') then - mem_stage_next <= UPDATE_PARTICIPANT; - mem_addr_next <= addr_res + 3; + mem_stage_next <= UPDATE_PARTICIPANT; + current_pmf_next <= current_pmf or mem_field_flags; + + if check_mask(mem_field_flags,PMF_META_IPV4_ADDR_FLAG) then mem_cnt_next <= 0; - elsif (update_participant_flags_next(LEASE_DEADLINE_FLAG) = '1') then - mem_stage_next <= UPDATE_PARTICIPANT; - mem_addr_next <= addr_res + 10; + elsif check_mask(mem_field_flags,PMF_DEFAULT_IPV4_ADDR_FLAG) then + mem_cnt_next <= 1; + elsif check_mask(mem_field_flags,PMF_UDP_PORT_FLAG) then + mem_cnt_next <= 2; + elsif check_mask(mem_field_flags,PMF_SPDP_SEQ_NR_FLAG) then + mem_cnt_next <= 3; + elsif check_mask(mem_field_flags,PMF_LEASE_DURATION_FLAG) then + mem_cnt_next <= 5; + elsif check_mask(mem_field_flags,PMF_LEASE_DEADLINE_FLAG) then mem_cnt_next <= 7; - elsif (update_participant_flags_next(EXTRA_FLAGS_FLAG) = '1') then - mem_stage_next <= UPDATE_PARTICIPANT; - mem_addr_next <= addr_res + 12; + elsif check_mask(mem_field_flags,PMF_EXTRA_FLAGS_FLAG) then mem_cnt_next <= 9; - elsif (update_participant_flags_next(ACKNACK_RES_TIME_FLAG) = '1') then - mem_stage_next <= UPDATE_PARTICIPANT; - mem_addr_next <= addr_res + 13; + elsif check_mask(mem_field_flags,PMF_ACKNACK_RES_TIME_FLAG) then mem_cnt_next <= 10; - elsif (update_participant_flags_next(HEARTBEAT_RES_TIME_FLAG) = '1') then - mem_stage_next <= UPDATE_PARTICIPANT; - mem_addr_next <= addr_res + 15; + elsif check_mask(mem_field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then mem_cnt_next <= 12; - elsif (update_participant_flags_next(EDP_SEQ_NR_FLAG) = '1') then - mem_stage_next <= UPDATE_PARTICIPANT; - mem_addr_next <= addr_res + 17; + elsif check_mask(mem_field_flags,PMF_PUB_SEQ_NR_FLAG) then mem_cnt_next <= 14; + elsif check_mask(mem_field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 16; + elsif check_mask(mem_field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 18; + else + -- DONE + mem_stage_next <= IDLE; + end if; + when GET_FIRST_PARTICIPANT => + -- Reset + current_pmf_next <= mem_field_flags; + participant_data_next <= ZERO_PARTICIPANT_DATA; + + -- No Instances available + if (mem_occupied_head = PARTICIPANT_MEMORY_MAX_ADDRESS) then + mem_addr_base_next <= PARTICIPANT_MEMORY_MAX_ADDRESS; + else + mem_prev_addr_base_next <= PARTICIPANT_MEMORY_MAX_ADDRESS; + mem_addr_base_next <= mem_occupied_head; + mem_stage_next <= GET_NEXT_PARTICIPANT; + mem_cnt_next <= 0; + end if; + when GET_NEXT_PARTICIPANT => + -- Reset + current_pmf_next <= mem_field_flags; + participant_data_next <= ZERO_PARTICIPANT_DATA; + + -- No Instances available + if (mem_next_addr_base = PARTICIPANT_MEMORY_MAX_ADDRESS) then + mem_addr_base_next <= PARTICIPANT_MEMORY_MAX_ADDRESS; + else + mem_prev_addr_base_next <= mem_addr_base; + mem_addr_base_next <= mem_next_addr_base; + mem_stage_next <= GET_NEXT_PARTICIPANT; + mem_cnt_next <= 0; end if; when REMOVE_PARTICIPANT => - mem_addr_next <= addr_res; - mem_stage_next <= REMOVE_PARTICIPANT; - mem_cnt_next <= 0; - when FIND_STALE_PARTICIPANT => - mem_addr_base_next <= FIRST_PARTICIPANT_ADDRESS; - mem_addr_next <= FIRST_PARTICIPANT_ADDRESS; - mem_stage_next <= FIND_STALE_PARTICIPANT; - mem_cnt_next <= 0; - when FIND_FIRST_PATICIPANT => - mem_addr_base_next <= FIRST_PARTICIPANT_ADDRESS; - mem_addr_next <= FIRST_PARTICIPANT_ADDRESS; - mem_stage_next <= FIND_NEXT_PARTICIPANT; - mem_cnt_next <= 0; - when FIND_NEXT_PARTICIPANT => - -- Memory Bound Guard - if (addr_res /= max_participant_addr) then - -- Reached End of Memory, No match - tmp := addr_res + PARTICIPANT_FRAME_SIZE; - mem_addr_base_next <= tmp; - mem_addr_next <= tmp; - mem_stage_next <= FIND_NEXT_PARTICIPANT; - mem_cnt_next <= 0; + -- Reset + current_pmf_next <= (others => '0'); + participant_data_next <= ZERO_PARTICIPANT_DATA; + + mem_stage_next <= REMOVE_PARTICIPANT; + mem_cnt_next <= 0; + when GET_PARTICIPANT => + mem_addr_base_next <= mem_addr_update; + if (mem_addr_base /= mem_addr_update) then + -- Reset + current_pmf_next <= mem_field_flags; + participant_data_next <= ZERO_PARTICIPANT_DATA; else - addr_res_next <= MAX_ADDRESS; + current_pmf_next <= current_pmf or mem_field_flags; + end if; + -- Get Instance Data + mem_stage_next <= GET_PARTICIPANT_DATA; + if check_mask(mem_field_flags,PMF_GUIDPREFIX_FLAG) then + mem_cnt_next <= 0; + elsif check_mask(mem_field_flags,PMF_META_IPV4_ADDR_FLAG) then + mem_cnt_next <= 3; + elsif check_mask(mem_field_flags,PMF_DEFAULT_IPV4_ADDR_FLAG) then + mem_cnt_next <= 4; + elsif check_mask(mem_field_flags,PMF_UDP_PORT_FLAG) then + mem_cnt_next <= 5; + elsif check_mask(mem_field_flags,PMF_SPDP_SEQ_NR_FLAG) then + mem_cnt_next <= 6; + elsif check_mask(mem_field_flags,PMF_LEASE_DURATION_FLAG) then + mem_cnt_next <= 8; + elsif check_mask(mem_field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 10; + elsif check_mask(mem_field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 12; + elsif check_mask(mem_field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 13; + elsif check_mask(mem_field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 15; + elsif check_mask(mem_field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 17; + elsif check_mask(mem_field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 19; + elsif check_mask(mem_field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 21; + else + -- DONE + mem_stage_next <= IDLE; end if; when others => null; end case; end if; when SEARCH_PARTICIPANT => - mem_rd <= '1'; - mem_cnt_next <= mem_cnt + 1; - mem_addr_next <= mem_addr + 1; - - -- Next Participant Frame Address - tmp := mem_addr_base + PARTICIPANT_FRAME_SIZE; case (mem_cnt) is - -- Preload + -- GET Next Participant when 0 => - null; - -- GUID Prefix 1/3 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_NEXT_ADDR_OFFSET; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- GET GUID Prefix 1/3 when 1 => - -- No Match - if (mem_read_data /= guid(0)) then - -- Reached End of Memory, No Match - if (mem_addr_base = max_participant_addr) then - addr_res_next <= MAX_ADDRESS; --No match - -- DONE - mem_stage_next <= IDLE; - else - -- Continue Search - mem_addr_next <= tmp; - mem_addr_base_next <= tmp; - mem_cnt_next <= 0; - end if; + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_GUIDPREFIX_OFFSET; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; end if; - -- GUID Prefix 2/3 + -- GET GUID Prefix 2/3 when 2 => - -- No Match - if (mem_read_data /= guid(1)) then - -- Reached End of Memory, No Match - if (mem_addr_base = max_participant_addr) then - addr_res_next <= MAX_ADDRESS; --No match - -- DONE - mem_stage_next <= IDLE; + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_GUIDPREFIX_OFFSET + 1; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- GET GUID Prefix 3/3 + when 3 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_GUIDPREFIX_OFFSET + 2; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- READ Next Participant + when 4 => + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + mem_next_addr_base_next <= resize(unsigned(mem_read_data),PARTICIPANT_MEMORY_ADDR_WIDTH); + mem_cnt_next <= mem_cnt + 1; + end if; + -- READ GUID Prefix 1/3 + when 5 => + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + -- No Match + if (mem_read_data /= participant_latch_data.guid_prefix(0)) then + mem_abort_read <= '1'; + -- Reached List Tail, No Match + if (mem_next_addr_base = PARTICIPANT_MEMORY_MAX_ADDRESS) then + mem_addr_base_next <= PARTICIPANT_MEMORY_MAX_ADDRESS; --No match + -- DONE + mem_stage_next <= IDLE; + else + -- Continue Search + mem_prev_addr_base_next <= mem_addr_base; + mem_addr_base_next <= mem_next_addr_base; + mem_cnt_next <= 0; + end if; else - -- Continue Search - mem_addr_next <= tmp; - mem_addr_base_next <= tmp; - mem_cnt_next <= 0; + mem_cnt_next <= mem_cnt + 1; end if; end if; - -- GUID Prefix 3/3 - when 3 => - -- No Match - if (mem_read_data /= guid(2)) then - -- Reached End of Memory, No Match - if (mem_addr_base = max_participant_addr) then - addr_res_next <= MAX_ADDRESS; --No match + -- READ GUID Prefix 2/3 + when 6 => + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + -- No Match + if (mem_read_data /= participant_latch_data.guid_prefix(1)) then + mem_abort_read <= '1'; + -- Reached List Tail, No Match + if (mem_next_addr_base = PARTICIPANT_MEMORY_MAX_ADDRESS) then + mem_addr_base_next <= PARTICIPANT_MEMORY_MAX_ADDRESS; --No match + -- DONE + mem_stage_next <= IDLE; + else + -- Continue Search + mem_prev_addr_base_next <= mem_addr_base; + mem_addr_base_next <= mem_next_addr_base; + mem_cnt_next <= 0; + end if; + else + mem_cnt_next <= mem_cnt + 1; + end if; + end if; + -- READ GUID Prefix 3/3 + when 7 => + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + -- No Match + if (mem_read_data /= participant_latch_data.guid_prefix(2)) then + -- Reached List Tail, No Match + if (mem_next_addr_base = PARTICIPANT_MEMORY_MAX_ADDRESS) then + mem_addr_base_next <= PARTICIPANT_MEMORY_MAX_ADDRESS; --No match + -- DONE + mem_stage_next <= IDLE; + else + -- Continue Search + mem_prev_addr_base_next <= mem_addr_base; + mem_addr_base_next <= mem_next_addr_base; + mem_cnt_next <= 0; + end if; + else + -- Get Participant Data + mem_stage_next <= GET_PARTICIPANT_DATA; + + if check_mask(participant_latch_data.field_flags,PMF_GUIDPREFIX_FLAG) then + mem_cnt_next <= 0; + elsif check_mask(participant_latch_data.field_flags,PMF_META_IPV4_ADDR_FLAG) then + mem_cnt_next <= 3; + elsif check_mask(participant_latch_data.field_flags,PMF_DEFAULT_IPV4_ADDR_FLAG) then + mem_cnt_next <= 4; + elsif check_mask(participant_latch_data.field_flags,PMF_UDP_PORT_FLAG) then + mem_cnt_next <= 5; + elsif check_mask(participant_latch_data.field_flags,PMF_SPDP_SEQ_NR_FLAG) then + mem_cnt_next <= 6; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DURATION_FLAG) then + mem_cnt_next <= 8; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 10; + elsif check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 12; + elsif check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 13; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 15; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 17; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 19; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 21; + else + -- DONE + mem_stage_next <= IDLE; + end if; + end if; + end if; + when others => + null; + end case; + when GET_NEXT_PARTICIPANT => + case (mem_cnt) is + -- GET Next Participant + when 0 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_NEXT_ADDR_OFFSET; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- READ Next Participant + when 1 => + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + mem_next_addr_base_next <= resize(unsigned(mem_read_data),PARTICIPANT_MEMORY_ADDR_WIDTH); + -- Get Instance Data + mem_stage_next <= GET_PARTICIPANT_DATA; + + if check_mask(participant_latch_data.field_flags,PMF_GUIDPREFIX_FLAG) then + mem_cnt_next <= 0; + elsif check_mask(participant_latch_data.field_flags,PMF_META_IPV4_ADDR_FLAG) then + mem_cnt_next <= 3; + elsif check_mask(participant_latch_data.field_flags,PMF_DEFAULT_IPV4_ADDR_FLAG) then + mem_cnt_next <= 4; + elsif check_mask(participant_latch_data.field_flags,PMF_UDP_PORT_FLAG) then + mem_cnt_next <= 5; + elsif check_mask(participant_latch_data.field_flags,PMF_SPDP_SEQ_NR_FLAG) then + mem_cnt_next <= 6; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DURATION_FLAG) then + mem_cnt_next <= 8; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 10; + elsif check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 12; + elsif check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 13; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 15; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 17; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 19; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 21; + else -- DONE mem_stage_next <= IDLE; - else - -- Continue Search - mem_addr_next <= tmp; - mem_addr_base_next <= tmp; - mem_cnt_next <= 0; end if; - -- Match - else - -- Fetch Participant Data - addr_res_next <= mem_addr_base; - mem_stage_next <= GET_PARTICIPANT_DATA; - mem_cnt_next <= 1; -- No preload needed end if; when others => null; end case; when GET_PARTICIPANT_DATA => - mem_rd <= '1'; - mem_cnt_next <= mem_cnt + 1; - mem_addr_next <= mem_addr + 1; - case (mem_cnt) is - -- Memory Preload + -- GET GUID Prefix 1/3 when 0 => - null; - -- Metatraffic IPv4 Address + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_GUIDPREFIX_OFFSET; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- GET GUID Prefix 2/3 when 1 => - mem_participant_data_next.meta_addr <= mem_read_data; - -- Default Endpoint IPv4 Address + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_GUIDPREFIX_OFFSET + 1; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- GET GUID Prefix 3/3 when 2 => - mem_participant_data_next.def_addr <= mem_read_data; - -- UDPv4 Ports + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_GUIDPREFIX_OFFSET + 2; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + if check_mask(participant_latch_data.field_flags,PMF_META_IPV4_ADDR_FLAG) then + mem_cnt_next <= 3; + elsif check_mask(participant_latch_data.field_flags,PMF_DEFAULT_IPV4_ADDR_FLAG) then + mem_cnt_next <= 4; + elsif check_mask(participant_latch_data.field_flags,PMF_UDP_PORT_FLAG) then + mem_cnt_next <= 5; + elsif check_mask(participant_latch_data.field_flags,PMF_SPDP_SEQ_NR_FLAG) then + mem_cnt_next <= 6; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DURATION_FLAG) then + mem_cnt_next <= 8; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 10; + elsif check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 12; + elsif check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 13; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 15; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 17; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 19; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 21; + else + mem_cnt_next <= 23; + end if; + end if; + -- GET Metatraffic IPv4 Address when 3 => - mem_participant_data_next.meta_port <= mem_read_data(31 downto 16); - mem_participant_data_next.def_port <= mem_read_data(15 downto 0); - -- SPDP Sequence Number 1/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_META_IPV4_ADDR_OFFSET; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + if check_mask(participant_latch_data.field_flags,PMF_DEFAULT_IPV4_ADDR_FLAG) then + mem_cnt_next <= 4; + elsif check_mask(participant_latch_data.field_flags,PMF_UDP_PORT_FLAG) then + mem_cnt_next <= 5; + elsif check_mask(participant_latch_data.field_flags,PMF_SPDP_SEQ_NR_FLAG) then + mem_cnt_next <= 6; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DURATION_FLAG) then + mem_cnt_next <= 8; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 10; + elsif check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 12; + elsif check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 13; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 15; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 17; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 19; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 21; + else + if check_mask(participant_latch_data.field_flags,PMF_GUIDPREFIX_FLAG) then + mem_cnt_next <= 23; + else + mem_cnt_next <= 26; + end if; + end if; + end if; + -- GET Default IPv4 Address when 4 => - mem_participant_data_next.spdp_seq_nr(0) <= unsigned(mem_read_data); - -- SPDP Sequence Number 2/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_DEFAULT_IPV4_ADDR_OFFSET; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + if check_mask(participant_latch_data.field_flags,PMF_UDP_PORT_FLAG) then + mem_cnt_next <= 5; + elsif check_mask(participant_latch_data.field_flags,PMF_SPDP_SEQ_NR_FLAG) then + mem_cnt_next <= 6; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DURATION_FLAG) then + mem_cnt_next <= 8; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 10; + elsif check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 12; + elsif check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 13; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 15; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 17; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 19; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 21; + else + if check_mask(participant_latch_data.field_flags,PMF_GUIDPREFIX_FLAG) then + mem_cnt_next <= 23; + elsif check_mask(participant_latch_data.field_flags,PMF_META_IPV4_ADDR_FLAG) then + mem_cnt_next <= 26; + else + mem_cnt_next <= 27; + end if; + end if; + end if; + -- GET UDP Ports when 5 => - mem_participant_data_next.spdp_seq_nr(1) <= unsigned(mem_read_data); - -- Lease Duration 1/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_UDP_PORT_OFFSET; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + if check_mask(participant_latch_data.field_flags,PMF_SPDP_SEQ_NR_FLAG) then + mem_cnt_next <= 6; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DURATION_FLAG) then + mem_cnt_next <= 8; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 10; + elsif check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 12; + elsif check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 13; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 15; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 17; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 19; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 21; + else + if check_mask(participant_latch_data.field_flags,PMF_GUIDPREFIX_FLAG) then + mem_cnt_next <= 23; + elsif check_mask(participant_latch_data.field_flags,PMF_META_IPV4_ADDR_FLAG) then + mem_cnt_next <= 26; + elsif check_mask(participant_latch_data.field_flags,PMF_DEFAULT_IPV4_ADDR_FLAG) then + mem_cnt_next <= 27; + else + mem_cnt_next <= 28; + end if; + end if; + end if; + -- GET SPDP Sequence Number 1/2 when 6 => - mem_participant_data_next.lease_duration(0) <= unsigned(mem_read_data); - -- Lease Duration 2/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_SPDP_SEQ_NR_OFFSET; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- GET SPDP Sequence Number 2/2 when 7 => - mem_participant_data_next.lease_duration(1) <= unsigned(mem_read_data); - -- Lease Deadline 1/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_SPDP_SEQ_NR_OFFSET + 1; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + if check_mask(participant_latch_data.field_flags,PMF_LEASE_DURATION_FLAG) then + mem_cnt_next <= 8; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 10; + elsif check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 12; + elsif check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 13; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 15; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 17; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 19; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 21; + else + if check_mask(participant_latch_data.field_flags,PMF_GUIDPREFIX_FLAG) then + mem_cnt_next <= 23; + elsif check_mask(participant_latch_data.field_flags,PMF_META_IPV4_ADDR_FLAG) then + mem_cnt_next <= 26; + elsif check_mask(participant_latch_data.field_flags,PMF_DEFAULT_IPV4_ADDR_FLAG) then + mem_cnt_next <= 27; + elsif check_mask(participant_latch_data.field_flags,PMF_UDP_PORT_FLAG) then + mem_cnt_next <= 28; + else + mem_cnt_next <= 29; + end if; + end if; + end if; + -- GET Lease Duration 1/2 when 8 => - mem_participant_data_next.lease_deadline(0) <= unsigned(mem_read_data); - -- Lease Deadline 2/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_LEASE_DURATION_OFFSET; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- GET Lease Duration 2/2 when 9 => - mem_participant_data_next.lease_deadline(1) <= unsigned(mem_read_data); - -- Extra Flags + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_LEASE_DURATION_OFFSET + 1; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + if check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 10; + elsif check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 12; + elsif check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 13; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 15; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 17; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 19; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 21; + else + if check_mask(participant_latch_data.field_flags,PMF_GUIDPREFIX_FLAG) then + mem_cnt_next <= 23; + elsif check_mask(participant_latch_data.field_flags,PMF_META_IPV4_ADDR_FLAG) then + mem_cnt_next <= 26; + elsif check_mask(participant_latch_data.field_flags,PMF_DEFAULT_IPV4_ADDR_FLAG) then + mem_cnt_next <= 27; + elsif check_mask(participant_latch_data.field_flags,PMF_UDP_PORT_FLAG) then + mem_cnt_next <= 28; + elsif check_mask(participant_latch_data.field_flags,PMF_SPDP_SEQ_NR_FLAG) then + mem_cnt_next <= 29; + else + mem_cnt_next <= 31; + end if; + end if; + end if; + -- GET Lease Deadline 1/2 when 10 => - mem_participant_data_next.extra_flags <= mem_read_data(EXTRA_FLAGS_WIDTH-1 downto 0); - -- ACKNACK Response/Suppression Time 1/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_LEASE_DEADLINE_OFFSET; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- GET Lease Deadline 2/2 when 11 => - mem_participant_data_next.acknack_res_time(0) <= unsigned(mem_read_data); - -- ACKNACK Response/Suppression Time 2/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_LEASE_DEADLINE_OFFSET + 1; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + if check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 12; + elsif check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 13; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 15; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 17; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 19; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 21; + else + if check_mask(participant_latch_data.field_flags,PMF_GUIDPREFIX_FLAG) then + mem_cnt_next <= 23; + elsif check_mask(participant_latch_data.field_flags,PMF_META_IPV4_ADDR_FLAG) then + mem_cnt_next <= 26; + elsif check_mask(participant_latch_data.field_flags,PMF_DEFAULT_IPV4_ADDR_FLAG) then + mem_cnt_next <= 27; + elsif check_mask(participant_latch_data.field_flags,PMF_UDP_PORT_FLAG) then + mem_cnt_next <= 28; + elsif check_mask(participant_latch_data.field_flags,PMF_SPDP_SEQ_NR_FLAG) then + mem_cnt_next <= 29; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DURATION_FLAG) then + mem_cnt_next <= 31; + else + mem_cnt_next <= 33; + end if; + end if; + end if; + -- GET Extra Flags when 12 => - mem_participant_data_next.acknack_res_time(1) <= unsigned(mem_read_data); - -- HEARTBEAT Response/Suppression Time 1/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_EXTRA_FLAGS_OFFSET; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + if check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 13; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 15; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 17; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 19; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 21; + else + if check_mask(participant_latch_data.field_flags,PMF_GUIDPREFIX_FLAG) then + mem_cnt_next <= 23; + elsif check_mask(participant_latch_data.field_flags,PMF_META_IPV4_ADDR_FLAG) then + mem_cnt_next <= 26; + elsif check_mask(participant_latch_data.field_flags,PMF_DEFAULT_IPV4_ADDR_FLAG) then + mem_cnt_next <= 27; + elsif check_mask(participant_latch_data.field_flags,PMF_UDP_PORT_FLAG) then + mem_cnt_next <= 28; + elsif check_mask(participant_latch_data.field_flags,PMF_SPDP_SEQ_NR_FLAG) then + mem_cnt_next <= 29; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DURATION_FLAG) then + mem_cnt_next <= 31; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 33; + else + mem_cnt_next <= 35; + end if; + end if; + end if; + -- GET ACKNACK Response Time 1/2 when 13 => - mem_participant_data_next.heartbeat_res_time(0) <= unsigned(mem_read_data); - -- HEARTBEAT Response/Suppression Time 2/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_ACKNACK_RES_TIME_OFFSET; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- GET ACKNACK Response Time 2/2 when 14 => - mem_participant_data_next.heartbeat_res_time(1) <= unsigned(mem_read_data); - -- Publication Sequence Number 1/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_ACKNACK_RES_TIME_OFFSET + 1; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + if check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 15; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 17; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 19; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 21; + else + if check_mask(participant_latch_data.field_flags,PMF_GUIDPREFIX_FLAG) then + mem_cnt_next <= 23; + elsif check_mask(participant_latch_data.field_flags,PMF_META_IPV4_ADDR_FLAG) then + mem_cnt_next <= 26; + elsif check_mask(participant_latch_data.field_flags,PMF_DEFAULT_IPV4_ADDR_FLAG) then + mem_cnt_next <= 27; + elsif check_mask(participant_latch_data.field_flags,PMF_UDP_PORT_FLAG) then + mem_cnt_next <= 28; + elsif check_mask(participant_latch_data.field_flags,PMF_SPDP_SEQ_NR_FLAG) then + mem_cnt_next <= 29; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DURATION_FLAG) then + mem_cnt_next <= 31; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 33; + elsif check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 35; + else + mem_cnt_next <= 36; + end if; + end if; + end if; + -- GET HEARTBEAT Response Time 1/2 when 15 => - mem_participant_data_next.pub_seq_nr(0) <= unsigned(mem_read_data); - -- Publication Sequence Number 2/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_HEARTBEAT_RES_TIME_OFFSET; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- GET HEARTBEAT Response Time 2/2 when 16 => - mem_participant_data_next.pub_seq_nr(1) <= unsigned(mem_read_data); - -- Subscription Sequence Number 1/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_HEARTBEAT_RES_TIME_OFFSET + 1; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + if check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 17; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 19; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 21; + else + if check_mask(participant_latch_data.field_flags,PMF_GUIDPREFIX_FLAG) then + mem_cnt_next <= 23; + elsif check_mask(participant_latch_data.field_flags,PMF_META_IPV4_ADDR_FLAG) then + mem_cnt_next <= 26; + elsif check_mask(participant_latch_data.field_flags,PMF_DEFAULT_IPV4_ADDR_FLAG) then + mem_cnt_next <= 27; + elsif check_mask(participant_latch_data.field_flags,PMF_UDP_PORT_FLAG) then + mem_cnt_next <= 28; + elsif check_mask(participant_latch_data.field_flags,PMF_SPDP_SEQ_NR_FLAG) then + mem_cnt_next <= 29; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DURATION_FLAG) then + mem_cnt_next <= 31; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 33; + elsif check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 35; + elsif check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 36; + else + mem_cnt_next <= 38; + end if; + end if; + end if; + -- GET Publication Sequence Number 1/2 when 17 => - mem_participant_data_next.sub_seq_nr(0) <= unsigned(mem_read_data); - -- Subscription Sequence Number 2/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_PUB_SEQ_NR_OFFSET; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- GET Publication Sequence Number 2/2 when 18 => - mem_participant_data_next.sub_seq_nr(1) <= unsigned(mem_read_data); - -- Participant Message Sequence Number 1/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_PUB_SEQ_NR_OFFSET + 1; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + if check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 19; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 21; + else + if check_mask(participant_latch_data.field_flags,PMF_GUIDPREFIX_FLAG) then + mem_cnt_next <= 23; + elsif check_mask(participant_latch_data.field_flags,PMF_META_IPV4_ADDR_FLAG) then + mem_cnt_next <= 26; + elsif check_mask(participant_latch_data.field_flags,PMF_DEFAULT_IPV4_ADDR_FLAG) then + mem_cnt_next <= 27; + elsif check_mask(participant_latch_data.field_flags,PMF_UDP_PORT_FLAG) then + mem_cnt_next <= 28; + elsif check_mask(participant_latch_data.field_flags,PMF_SPDP_SEQ_NR_FLAG) then + mem_cnt_next <= 29; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DURATION_FLAG) then + mem_cnt_next <= 31; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 33; + elsif check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 35; + elsif check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 36; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 38; + else + mem_cnt_next <= 40; + end if; + end if; + end if; + -- GET Subscription Sequence Number 1/2 when 19 => - mem_participant_data_next.mes_seq_nr(0) <= unsigned(mem_read_data); - -- Participant Message Sequence Number 2/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_SUB_SEQ_NR_OFFSET; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- GET Subscription Sequence Number 2/2 when 20 => - mem_participant_data_next.mes_seq_nr(1) <= unsigned(mem_read_data); - mem_rd <= '0'; - -- DONE - mem_stage_next <= IDLE; + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_SUB_SEQ_NR_OFFSET + 1; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + if check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 21; + else + if check_mask(participant_latch_data.field_flags,PMF_GUIDPREFIX_FLAG) then + mem_cnt_next <= 23; + elsif check_mask(participant_latch_data.field_flags,PMF_META_IPV4_ADDR_FLAG) then + mem_cnt_next <= 26; + elsif check_mask(participant_latch_data.field_flags,PMF_DEFAULT_IPV4_ADDR_FLAG) then + mem_cnt_next <= 27; + elsif check_mask(participant_latch_data.field_flags,PMF_UDP_PORT_FLAG) then + mem_cnt_next <= 28; + elsif check_mask(participant_latch_data.field_flags,PMF_SPDP_SEQ_NR_FLAG) then + mem_cnt_next <= 29; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DURATION_FLAG) then + mem_cnt_next <= 31; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 33; + elsif check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 35; + elsif check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 36; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 38; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 40; + else + mem_cnt_next <= 42; + end if; + end if; + end if; + -- GET Message Sequence Number 1/2 + when 21 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_MES_SEQ_NR_OFFSET; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- GET Message Sequence Number 2/2 + when 22 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_MES_SEQ_NR_OFFSET + 1; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + if check_mask(participant_latch_data.field_flags,PMF_GUIDPREFIX_FLAG) then + mem_cnt_next <= 23; + elsif check_mask(participant_latch_data.field_flags,PMF_META_IPV4_ADDR_FLAG) then + mem_cnt_next <= 26; + elsif check_mask(participant_latch_data.field_flags,PMF_DEFAULT_IPV4_ADDR_FLAG) then + mem_cnt_next <= 27; + elsif check_mask(participant_latch_data.field_flags,PMF_UDP_PORT_FLAG) then + mem_cnt_next <= 28; + elsif check_mask(participant_latch_data.field_flags,PMF_SPDP_SEQ_NR_FLAG) then + mem_cnt_next <= 29; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DURATION_FLAG) then + mem_cnt_next <= 31; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 33; + elsif check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 35; + elsif check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 36; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 38; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 40; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 42; + else + mem_cnt_next <= 44; + end if; + end if; + -- READ GUID Prefix 1/3 + when 23 => + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + participant_data_next.guid_prefix(0) <= mem_read_data; + mem_cnt_next <= mem_cnt + 1; + end if; + -- READ GUID Prefix 2/3 + when 24 => + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + participant_data_next.guid_prefix(1) <= mem_read_data; + mem_cnt_next <= mem_cnt + 1; + end if; + -- READ GUID Prefix 3/3 + when 25 => + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + participant_data_next.guid_prefix(2) <= mem_read_data; + + if check_mask(participant_latch_data.field_flags,PMF_META_IPV4_ADDR_FLAG) then + mem_cnt_next <= 26; + elsif check_mask(participant_latch_data.field_flags,PMF_DEFAULT_IPV4_ADDR_FLAG) then + mem_cnt_next <= 27; + elsif check_mask(participant_latch_data.field_flags,PMF_UDP_PORT_FLAG) then + mem_cnt_next <= 28; + elsif check_mask(participant_latch_data.field_flags,PMF_SPDP_SEQ_NR_FLAG) then + mem_cnt_next <= 29; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DURATION_FLAG) then + mem_cnt_next <= 31; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 33; + elsif check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 35; + elsif check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 36; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 38; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 40; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 42; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 44; + else + -- DONE + mem_stage_next <= IDLE; + end if; + end if; + -- READ Metatraffic IPv4 Address + when 26 => + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + participant_data_next.meta_addr <= mem_read_data; + + if check_mask(participant_latch_data.field_flags,PMF_DEFAULT_IPV4_ADDR_FLAG) then + mem_cnt_next <= 27; + elsif check_mask(participant_latch_data.field_flags,PMF_UDP_PORT_FLAG) then + mem_cnt_next <= 28; + elsif check_mask(participant_latch_data.field_flags,PMF_SPDP_SEQ_NR_FLAG) then + mem_cnt_next <= 29; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DURATION_FLAG) then + mem_cnt_next <= 31; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 33; + elsif check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 35; + elsif check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 36; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 38; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 40; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 42; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 44; + else + -- DONE + mem_stage_next <= IDLE; + end if; + end if; + -- READ Default IPv4 Address + when 27 => + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + participant_data_next.def_addr <= mem_read_data; + + if check_mask(participant_latch_data.field_flags,PMF_UDP_PORT_FLAG) then + mem_cnt_next <= 28; + elsif check_mask(participant_latch_data.field_flags,PMF_SPDP_SEQ_NR_FLAG) then + mem_cnt_next <= 29; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DURATION_FLAG) then + mem_cnt_next <= 31; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 33; + elsif check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 35; + elsif check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 36; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 38; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 40; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 42; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 44; + else + -- DONE + mem_stage_next <= IDLE; + end if; + end if; + -- READ UDP Ports + when 28 => + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + participant_data_next.meta_port <= mem_read_data(WORD_WIDTH-1 downto UDP_PORT_WIDTH); + participant_data_next.def_port <= mem_read_data(UDP_PORT_WIDTH-1 downto 0); + + if check_mask(participant_latch_data.field_flags,PMF_SPDP_SEQ_NR_FLAG) then + mem_cnt_next <= 29; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DURATION_FLAG) then + mem_cnt_next <= 31; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 33; + elsif check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 35; + elsif check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 36; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 38; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 40; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 42; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 44; + else + -- DONE + mem_stage_next <= IDLE; + end if; + end if; + -- READ SPDP Sequence Number 1/2 + when 29 => + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + participant_data_next.spdp_seq_nr(0) <= unsigned(mem_read_data); + mem_cnt_next <= mem_cnt + 1; + end if; + -- READ SPDP Sequence Number 2/2 + when 30 => + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + participant_data_next.spdp_seq_nr(1) <= unsigned(mem_read_data); + + if check_mask(participant_latch_data.field_flags,PMF_LEASE_DURATION_FLAG) then + mem_cnt_next <= 31; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 33; + elsif check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 35; + elsif check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 36; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 38; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 40; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 42; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 44; + else + -- DONE + mem_stage_next <= IDLE; + end if; + end if; + -- READ Lease Duration 1/2 + when 31 => + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + participant_data_next.lease_duration(0) <= unsigned(mem_read_data); + mem_cnt_next <= mem_cnt + 1; + end if; + -- READ Lease Duration 2/2 + when 32 => + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + participant_data_next.lease_duration(1) <= unsigned(mem_read_data); + + if check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 33; + elsif check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 35; + elsif check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 36; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 38; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 40; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 42; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 44; + else + -- DONE + mem_stage_next <= IDLE; + end if; + end if; + -- READ Lease Deadline 1/2 + when 33 => + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + participant_data_next.lease_deadline(0) <= unsigned(mem_read_data); + mem_cnt_next <= mem_cnt + 1; + end if; + -- READ Lease Deadline 2/2 + when 34 => + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + participant_data_next.lease_deadline(1) <= unsigned(mem_read_data); + + if check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 35; + elsif check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 36; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 38; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 40; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 42; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 44; + else + -- DONE + mem_stage_next <= IDLE; + end if; + end if; + -- READ Extra Flags + when 35 => + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + participant_data_next.extra_flags <= mem_read_data(EF_FLAG_WIDTH-1 downto 0); + + if check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 36; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 38; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 40; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 42; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 44; + else + -- DONE + mem_stage_next <= IDLE; + end if; + end if; + -- READ ACKNACK Response Time 1/2 + when 36 => + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + participant_data_next.acknack_res_time(0) <= unsigned(mem_read_data); + mem_cnt_next <= mem_cnt + 1; + end if; + -- READ ACKNACK Response Time 2/2 + when 37 => + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + participant_data_next.acknack_res_time(1) <= unsigned(mem_read_data); + + if check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 38; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 40; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 42; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 44; + else + -- DONE + mem_stage_next <= IDLE; + end if; + end if; + -- READ HEARTBEAT Response Time 1/2 + when 38 => + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + participant_data_next.heartbeat_res_time(0) <= unsigned(mem_read_data); + mem_cnt_next <= mem_cnt + 1; + end if; + -- READ HEARTBEAT Response Time 2/2 + when 39 => + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + participant_data_next.heartbeat_res_time(1) <= unsigned(mem_read_data); + + if check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 40; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 42; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 44; + else + -- DONE + mem_stage_next <= IDLE; + end if; + end if; + -- READ Publication Sequence Number 1/2 + when 40 => + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + participant_data_next.pub_seq_nr(0) <= unsigned(mem_read_data); + mem_cnt_next <= mem_cnt + 1; + end if; + -- READ Publication Sequence Number 2/2 + when 41 => + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + participant_data_next.pub_seq_nr(1) <= unsigned(mem_read_data); + + if check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 42; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 44; + else + -- DONE + mem_stage_next <= IDLE; + end if; + end if; + -- READ Subscription Sequence Number 1/2 + when 42 => + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + participant_data_next.sub_seq_nr(0) <= unsigned(mem_read_data); + mem_cnt_next <= mem_cnt + 1; + end if; + -- READ Subscription Sequence Number 2/2 + when 43 => + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + participant_data_next.sub_seq_nr(1) <= unsigned(mem_read_data); + + if check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 44; + else + -- DONE + mem_stage_next <= IDLE; + end if; + end if; + -- READ Message Sequence Number 1/2 + when 44 => + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + participant_data_next.mes_seq_nr(0) <= unsigned(mem_read_data); + mem_cnt_next <= mem_cnt + 1; + end if; + -- READ Message Sequence Number 2/2 + when 45 => + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + participant_data_next.mes_seq_nr(1) <= unsigned(mem_read_data); + + -- DONE + mem_stage_next <= IDLE; + end if; when others => null; end case; when INSERT_PARTICIPANT => - mem_wr <= '1'; - mem_addr_next <= mem_addr + 1; - mem_cnt_next <= mem_cnt + 1; + -- Precondition: mem_addr_base set case (mem_cnt) is - -- GUIDPrefix 1/3 + -- GET Next Pointer when 0 => - mem_write_data <= guid(0); - -- GUIDPrefix 2/3 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_NEXT_ADDR_OFFSET; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET Next Pointer when 1 => - mem_write_data <= guid(1); - -- GUIDPrefix 3/3 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_NEXT_ADDR_OFFSET; + mem_write_data <= std_logic_vector(resize(mem_occupied_head,WORD_WIDTH)); + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + -- Fix Occupied Head + mem_occupied_head_next <= mem_addr_base; + + mem_cnt_next <= mem_cnt + 1; + end if; + -- READ Next Pointer when 2 => - mem_write_data <= guid(2); - -- Metatraffic IPv4 Address + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + -- Fix Empty List Head + mem_empty_head_next <= resize(unsigned(mem_read_data),PARTICIPANT_MEMORY_ADDR_WIDTH); + + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET GUID Prefix 1/3 when 3 => - mem_write_data <= meta_addr; - -- Default Endpoint IPv4 Address + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_GUIDPREFIX_OFFSET; + mem_write_data <= participant_latch_data.guid_prefix(0); + participant_data_next.guid_prefix(0) <= participant_latch_data.guid_prefix(0); + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET GUID Prefix 2/3 when 4 => - mem_write_data <= def_addr; - -- UDPv4 Ports + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_GUIDPREFIX_OFFSET + 1; + mem_write_data <= participant_latch_data.guid_prefix(1); + participant_data_next.guid_prefix(1) <= participant_latch_data.guid_prefix(1); + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET GUID Prefix 3/3 when 5 => - mem_write_data <= meta_port & def_port; - -- SPDP Sequence Number 1/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_GUIDPREFIX_OFFSET + 2; + mem_write_data <= participant_latch_data.guid_prefix(2); + participant_data_next.guid_prefix(2) <= participant_latch_data.guid_prefix(2); + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET Metatraffic IPv4 Address when 6 => - mem_write_data <= std_logic_vector(next_seq_nr(0)); - -- SPDP Sequence Number 2/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_META_IPV4_ADDR_OFFSET; + mem_write_data <= participant_latch_data.meta_addr; + participant_data_next.meta_addr <= participant_latch_data.meta_addr; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET Default IPv4 Address when 7 => - mem_write_data <= std_logic_vector(next_seq_nr(1)); - -- Lease Duration 1/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_DEFAULT_IPV4_ADDR_OFFSET; + mem_write_data <= participant_latch_data.def_addr; + participant_data_next.def_addr <= participant_latch_data.def_addr; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET UDP Ports when 8 => - mem_write_data <= std_logic_vector(lease_duration(0)); - -- Lease Duration 2/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_UDP_PORT_OFFSET; + mem_write_data <= participant_latch_data.meta_port & participant_latch_data.def_port; + participant_data_next.meta_port <= participant_latch_data.meta_port; + participant_data_next.def_port <= participant_latch_data.def_port; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET SPDP Sequence Number 1/2 when 9 => - mem_write_data <= std_logic_vector(lease_duration(1)); - -- Lease Deadline 1/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_SPDP_SEQ_NR_OFFSET; + mem_write_data <= std_logic_vector(participant_latch_data.seq_nr(0)); + participant_data_next.spdp_seq_nr(0) <= participant_latch_data.seq_nr(0); + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET SPDP Sequence Number 2/2 when 10 => - mem_write_data <= std_logic_vector(deadline(0)); - -- Lease Deadline 2/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_SPDP_SEQ_NR_OFFSET + 1; + mem_write_data <= std_logic_vector(participant_latch_data.seq_nr(1)); + participant_data_next.spdp_seq_nr(1) <= participant_latch_data.seq_nr(1); + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET Lease Duration 1/2 when 11 => - mem_write_data <= std_logic_vector(deadline(1)); - -- Extra Flags + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_LEASE_DURATION_OFFSET; + mem_write_data <= std_logic_vector(participant_latch_data.lease_duration(0)); + participant_data_next.lease_duration(0) <= participant_latch_data.lease_duration(0); + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET Lease Duration 2/2 when 12 => - mem_write_data <= (others => '0'); - mem_write_data(EXTRA_FLAGS_WIDTH-1 downto 0) <= extra_flags; - -- ACKNACK Response/Suppression Time 1/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_LEASE_DURATION_OFFSET + 1; + mem_write_data <= std_logic_vector(participant_latch_data.lease_duration(1)); + participant_data_next.lease_duration(1) <= participant_latch_data.lease_duration(1); + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET Lease Deadline 1/2 when 13 => - mem_write_data <= (others => '0'); - -- ACKNACK Response/Suppression Time 2/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_LEASE_DEADLINE_OFFSET; + mem_write_data <= std_logic_vector(participant_latch_data.lease_deadline(0)); + participant_data_next.lease_deadline(0) <= participant_latch_data.lease_deadline(0); + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET Lease Deadline 2/2 when 14 => - mem_write_data <= (others => '0'); - -- HEARTBEAT Response/Suppression Time 1/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_LEASE_DEADLINE_OFFSET + 1; + mem_write_data <= std_logic_vector(participant_latch_data.lease_deadline(1)); + participant_data_next.lease_deadline(1) <= participant_latch_data.lease_deadline(1); + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET Extra Flags when 15 => - mem_write_data <= (others => '0'); - -- HEARTBEAT Response/Suppression Time 2/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_EXTRA_FLAGS_OFFSET; + mem_write_data <= (others => '0'); + mem_write_data(EF_FLAG_WIDTH-1 downto 0) <= participant_latch_data.extra_flags; + participant_data_next.extra_flags <= participant_latch_data.extra_flags; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET ACKNACK Response Time 1/2 when 16 => - mem_write_data <= (others => '0'); - -- Publication Sequence Number 1/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_ACKNACK_RES_TIME_OFFSET; + mem_write_data <= std_logic_vector(TIME_INVALID(0)); + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET ACKNACK Response Time 2/2 when 17 => - mem_write_data <= std_logic_vector(FIRST_SEQUENCENUMBER(0)); - -- Publication Sequence Number 2/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_ACKNACK_RES_TIME_OFFSET + 1; + mem_write_data <= std_logic_vector(TIME_INVALID(1)); + participant_data_next.acknack_res_time <= TIME_INVALID; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET HEARTBEAT Response Time 1/2 when 18 => - mem_write_data <= std_logic_vector(FIRST_SEQUENCENUMBER(1)); - -- Subscription Sequence Number 1/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_HEARTBEAT_RES_TIME_OFFSET; + mem_write_data <= std_logic_vector(TIME_INVALID(0)); + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET HEARTBEAT Response Time 2/2 when 19 => - mem_write_data <= std_logic_vector(FIRST_SEQUENCENUMBER(0)); - -- Subscription Sequence Number 2/2 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_HEARTBEAT_RES_TIME_OFFSET + 1; + mem_write_data <= std_logic_vector(TIME_INVALID(1)); + participant_data_next.heartbeat_res_time <= TIME_INVALID; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET Publication Sequence Number 1/2 when 20 => - mem_write_data <= std_logic_vector(FIRST_SEQUENCENUMBER(1)); - -- Participant Message Sequence Number 1/2 - when 21 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_PUB_SEQ_NR_OFFSET; mem_write_data <= std_logic_vector(FIRST_SEQUENCENUMBER(0)); - -- Participant Message Sequence Number 2/2 - when 22 => + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET Publication Sequence Number 2/2 + when 21 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_PUB_SEQ_NR_OFFSET + 1; mem_write_data <= std_logic_vector(FIRST_SEQUENCENUMBER(1)); - -- DONE - mem_stage_next <= IDLE; + participant_data_next.pub_seq_nr <= FIRST_SEQUENCENUMBER; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET Subscription Sequence Number 1/2 + when 22 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_SUB_SEQ_NR_OFFSET; + mem_write_data <= std_logic_vector(FIRST_SEQUENCENUMBER(0)); + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET Subscription Sequence Number 2/2 + when 23 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_SUB_SEQ_NR_OFFSET + 1; + mem_write_data <= std_logic_vector(FIRST_SEQUENCENUMBER(1)); + participant_data_next.sub_seq_nr <= FIRST_SEQUENCENUMBER; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET Message Sequence Number 1/2 + when 24 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_MES_SEQ_NR_OFFSET; + mem_write_data <= std_logic_vector(FIRST_SEQUENCENUMBER(0)); + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET Message Sequence Number 2/2 + when 25 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_MES_SEQ_NR_OFFSET + 1; + mem_write_data <= std_logic_vector(FIRST_SEQUENCENUMBER(1)); + participant_data_next.mes_seq_nr <= FIRST_SEQUENCENUMBER; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + -- DONE + mem_stage_next <= IDLE; + end if; when others => null; end case; when UPDATE_PARTICIPANT => - mem_cnt_next <= mem_cnt + 1; - mem_addr_next <= mem_addr + 1; - case (mem_cnt) is - -- Metatraffic IPv4 Address + -- SET Metatraffic IPv4 Address when 0 => - mem_write_data <= meta_addr; - if (update_participant_flags(PARTICIPANT_DATA_FLAG) = '1') then - mem_wr <= '1'; + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_META_IPV4_ADDR_OFFSET; + mem_write_data <= participant_latch_data.meta_addr; + participant_data_next.meta_addr <= participant_latch_data.meta_addr; + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + if check_mask(participant_latch_data.field_flags,PMF_DEFAULT_IPV4_ADDR_FLAG) then + mem_cnt_next <= 1; + elsif check_mask(participant_latch_data.field_flags,PMF_UDP_PORT_FLAG) then + mem_cnt_next <= 2; + elsif check_mask(participant_latch_data.field_flags,PMF_SPDP_SEQ_NR_FLAG) then + mem_cnt_next <= 3; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DURATION_FLAG) then + mem_cnt_next <= 5; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 7; + elsif check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 9; + elsif check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 10; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 12; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 14; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 16; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 18; + else + -- DONE + mem_stage_next <= IDLE; + end if; end if; - -- Default Endpoint IPv4 Address + -- SET Default IPv4 Address when 1 => - mem_write_data <= def_addr; - if (update_participant_flags(PARTICIPANT_DATA_FLAG) = '1') then - mem_wr <= '1'; + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_DEFAULT_IPV4_ADDR_OFFSET; + mem_write_data <= participant_latch_data.def_addr; + participant_data_next.def_addr <= participant_latch_data.def_addr; + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + if check_mask(participant_latch_data.field_flags,PMF_UDP_PORT_FLAG) then + mem_cnt_next <= 2; + elsif check_mask(participant_latch_data.field_flags,PMF_SPDP_SEQ_NR_FLAG) then + mem_cnt_next <= 3; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DURATION_FLAG) then + mem_cnt_next <= 5; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 7; + elsif check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 9; + elsif check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 10; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 12; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 14; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 16; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 18; + else + -- DONE + mem_stage_next <= IDLE; + end if; end if; - -- UDPv4 Ports + -- SET UDP Ports when 2 => - mem_write_data <= meta_port & def_port; - if (update_participant_flags(PARTICIPANT_DATA_FLAG) = '1') then - mem_wr <= '1'; + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_UDP_PORT_OFFSET; + mem_write_data <= participant_latch_data.meta_port & participant_latch_data.def_port; + participant_data_next.meta_port <= participant_latch_data.meta_port; + participant_data_next.def_port <= participant_latch_data.def_port; + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + if check_mask(participant_latch_data.field_flags,PMF_SPDP_SEQ_NR_FLAG) then + mem_cnt_next <= 3; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DURATION_FLAG) then + mem_cnt_next <= 5; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 7; + elsif check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 9; + elsif check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 10; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 12; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 14; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 16; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 18; + else + -- DONE + mem_stage_next <= IDLE; + end if; end if; - -- SPDP Sequence Number 1/2 + -- SET SPDP Sequence Number 1/2 when 3 => - mem_write_data <= std_logic_vector(next_seq_nr(0)); - if (update_participant_flags(PARTICIPANT_DATA_FLAG) = '1') then - mem_wr <= '1'; + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_SPDP_SEQ_NR_OFFSET; + mem_write_data <= std_logic_vector(participant_latch_data.seq_nr(0)); + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; end if; - -- SPDP Sequence Number 2/2 + -- SET SPDP Sequence Number 2/2 when 4 => - mem_write_data <= std_logic_vector(next_seq_nr(1)); - if (update_participant_flags(PARTICIPANT_DATA_FLAG) = '1') then - mem_wr <= '1'; + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_SPDP_SEQ_NR_OFFSET + 1; + mem_write_data <= std_logic_vector(participant_latch_data.seq_nr(1)); + participant_data_next.spdp_seq_nr <= participant_latch_data.seq_nr; + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + if check_mask(participant_latch_data.field_flags,PMF_LEASE_DURATION_FLAG) then + mem_cnt_next <= 5; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 7; + elsif check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 9; + elsif check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 10; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 12; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 14; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 16; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 18; + else + -- DONE + mem_stage_next <= IDLE; + end if; end if; - -- Lease Duration 1/2 + -- SET Lease Duration 1/2 when 5 => - mem_write_data <= std_logic_vector(lease_duration(0)); - if (update_participant_flags(PARTICIPANT_DATA_FLAG) = '1') then - mem_wr <= '1'; + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_LEASE_DURATION_OFFSET; + mem_write_data <= std_logic_vector(participant_latch_data.lease_duration(0)); + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; end if; - -- Lease Duration 2/2 + -- SET Lease Duration 2/2 when 6 => - mem_write_data <= std_logic_vector(lease_duration(1)); - if (update_participant_flags(PARTICIPANT_DATA_FLAG) = '1') then - mem_wr <= '1'; + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_LEASE_DURATION_OFFSET + 1; + mem_write_data <= std_logic_vector(participant_latch_data.lease_duration(1)); + participant_data_next.lease_duration <= participant_latch_data.lease_duration; + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + if check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 7; + elsif check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 9; + elsif check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 10; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 12; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 14; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 16; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 18; + else + -- DONE + mem_stage_next <= IDLE; + end if; end if; - -- If nothing else to update - if (update_participant_flags(5 downto 1) = (5 downto 1 => '0')) then - -- DONE - mem_stage_next <= IDLE; - end if; - -- Lease Deadline 1/2 + -- SET Lease Deadline 1/2 when 7 => - mem_write_data <= std_logic_vector(deadline(0)); - if (update_participant_flags(LEASE_DEADLINE_FLAG) = '1') then - mem_wr <= '1'; + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_LEASE_DEADLINE_OFFSET; + mem_write_data <= std_logic_vector(participant_latch_data.lease_deadline(0)); + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; end if; - -- Lease Deadline 2/2 + -- SET Lease Deadline 2/2 when 8 => - mem_write_data <= std_logic_vector(deadline(1)); - if (update_participant_flags(LEASE_DEADLINE_FLAG) = '1') then - mem_wr <= '1'; + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_LEASE_DEADLINE_OFFSET + 1; + mem_write_data <= std_logic_vector(participant_latch_data.lease_deadline(1)); + participant_data_next.lease_deadline <= participant_latch_data.lease_deadline; + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + if check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 9; + elsif check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 10; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 12; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 14; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 16; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 18; + else + -- DONE + mem_stage_next <= IDLE; + end if; end if; - -- If nothing else to update - if (update_participant_flags(5 downto 2) = (5 downto 2 => '0')) then - -- DONE - mem_stage_next <= IDLE; - end if; - -- Extra Flags + -- SET Extra Flags when 9 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_EXTRA_FLAGS_OFFSET; mem_write_data <= (others => '0'); - mem_write_data(EXTRA_FLAGS_WIDTH-1 downto 0) <= extra_flags; - if (update_participant_flags(EXTRA_FLAGS_FLAG) = '1') then - mem_wr <= '1'; + mem_write_data(EF_FLAG_WIDTH-1 downto 0) <= participant_latch_data.extra_flags; + participant_data_next.extra_flags <= participant_latch_data.extra_flags; + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + if check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 10; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 12; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 14; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 16; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 18; + else + -- DONE + mem_stage_next <= IDLE; + end if; end if; - -- If nothing else to update - if (update_participant_flags(5 downto 3) = (5 downto 3 => '0')) then - -- DONE - mem_stage_next <= IDLE; - end if; - -- ACKNACK DEADLINE 1/2 + -- SET ACKNACK Response Time 1/2 when 10 => - mem_write_data <= std_logic_vector(deadline(0)); - if (update_participant_flags(ACKNACK_RES_TIME_FLAG) = '1') then - mem_wr <= '1'; + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_ACKNACK_RES_TIME_OFFSET; + mem_write_data <= std_logic_vector(participant_latch_data.res_time(0)); + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; end if; - -- ACKNACK DEADLINE 2/2 + -- SET ACKNACK Response Time 2/2 when 11 => - mem_write_data <= std_logic_vector(deadline(1)); - if (update_participant_flags(ACKNACK_RES_TIME_FLAG) = '1') then - mem_wr <= '1'; + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_ACKNACK_RES_TIME_OFFSET + 1; + mem_write_data <= std_logic_vector(participant_latch_data.res_time(1)); + participant_data_next.acknack_res_time <= participant_latch_data.res_time; + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + if check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 12; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 14; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 16; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 18; + else + -- DONE + mem_stage_next <= IDLE; + end if; end if; - -- If nothing else to update - if (update_participant_flags(5 downto 4) = (5 downto 4 => '0')) then - -- DONE - mem_stage_next <= IDLE; - end if; - -- HEARTBEAT DEADLINE 1/2 + -- SET HEARTBEAT Response Time 1/2 when 12 => - mem_write_data <= std_logic_vector(deadline(0)); - if (update_participant_flags(HEARTBEAT_RES_TIME_FLAG) = '1') then - mem_wr <= '1'; + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_HEARTBEAT_RES_TIME_OFFSET; + mem_write_data <= std_logic_vector(participant_latch_data.res_time(0)); + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; end if; - -- HEARTBEAT DEADLINE 2/2 + -- SET HEARTBEAT Response Time 2/2 when 13 => - mem_write_data <= std_logic_vector(deadline(1)); - if (update_participant_flags(HEARTBEAT_RES_TIME_FLAG) = '1') then - mem_wr <= '1'; + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_HEARTBEAT_RES_TIME_OFFSET + 1; + mem_write_data <= std_logic_vector(participant_latch_data.res_time(1)); + participant_data_next.heartbeat_res_time <= participant_latch_data.res_time; + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + if check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 14; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 16; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 18; + else + -- DONE + mem_stage_next <= IDLE; + end if; end if; - -- If nothing else to update - if (update_participant_flags(5 downto 5) = (5 downto 5 => '0')) then + -- SET Publication Sequence Number 1/2 + when 14 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_PUB_SEQ_NR_OFFSET; + mem_write_data <= std_logic_vector(participant_latch_data.seq_nr(0)); + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET Publication Sequence Number 2/2 + when 15 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_PUB_SEQ_NR_OFFSET + 1; + mem_write_data <= std_logic_vector(participant_latch_data.seq_nr(1)); + participant_data_next.pub_seq_nr <= participant_latch_data.seq_nr; + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + if check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 16; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 18; + else + -- DONE + mem_stage_next <= IDLE; + end if; + end if; + -- SET Subscription Sequence Number 1/2 + when 16 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_SUB_SEQ_NR_OFFSET; + mem_write_data <= std_logic_vector(participant_latch_data.seq_nr(0)); + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET Subscription Sequence Number 2/2 + when 17 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_SUB_SEQ_NR_OFFSET + 1; + mem_write_data <= std_logic_vector(participant_latch_data.seq_nr(1)); + participant_data_next.sub_seq_nr <= participant_latch_data.seq_nr; + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + if check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 18; + else + -- DONE + mem_stage_next <= IDLE; + end if; + end if; + -- SET Message Sequence Number 1/2 + when 18 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_MES_SEQ_NR_OFFSET; + mem_write_data <= std_logic_vector(participant_latch_data.seq_nr(0)); + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET Message Sequence Number 2/2 + when 19 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_MES_SEQ_NR_OFFSET + 1; + mem_write_data <= std_logic_vector(participant_latch_data.seq_nr(1)); + participant_data_next.mes_seq_nr <= participant_latch_data.seq_nr; + -- Memory Flow Control Guard + if (mem_ready_in = '1') then -- DONE mem_stage_next <= IDLE; end if; - -- Publication Sequence Number 1/2 - when 14 => - mem_write_data <= std_logic_vector(next_seq_nr(0)); - if (update_participant_flags(EDP_SEQ_NR_FLAG) = '1' and message_type = EDP and is_subscriber = '0') then - mem_wr <= '1'; - end if; - -- Publication Sequence Number 2/2 - when 15 => - mem_write_data <= std_logic_vector(next_seq_nr(1)); - if (update_participant_flags(EDP_SEQ_NR_FLAG) = '1' and message_type = EDP and is_subscriber = '0') then - mem_wr <= '1'; - end if; - -- Subscription Sequence Number 1/2 - when 16 => - mem_write_data <= std_logic_vector(next_seq_nr(0)); - if (update_participant_flags(EDP_SEQ_NR_FLAG) = '1' and message_type = EDP and is_subscriber = '1') then - mem_wr <= '1'; - end if; - -- Subscription Sequence Number 2/2 - when 17 => - mem_write_data <= std_logic_vector(next_seq_nr(1)); - if (update_participant_flags(EDP_SEQ_NR_FLAG) = '1' and message_type = EDP and is_subscriber = '1') then - mem_wr <= '1'; - end if; - -- Participant Message Sequence Number 1/2 - when 18 => - mem_write_data <= std_logic_vector(next_seq_nr(0)); - if (update_participant_flags(EDP_SEQ_NR_FLAG) = '1' and message_type = MESSAGE) then - mem_wr <= '1'; - end if; - -- Participant Message Sequence Number 2/2 - when 19 => - mem_write_data <= std_logic_vector(next_seq_nr(1)); - if (update_participant_flags(EDP_SEQ_NR_FLAG) = '1' and message_type = MESSAGE) then - mem_wr <= '1'; - end if; - -- DONE - mem_stage_next <= IDLE; when others => null; end case; when REMOVE_PARTICIPANT => - mem_addr_next <= mem_addr + 1; - mem_cnt_next <= mem_cnt + 1; - - -- Latch Participant GUID Prefix, and then overwrite with GUIDPREFIX_UNKNOWN to mark slot empty - case (mem_cnt) is - -- Preload - when 0 => - mem_rd <= '1'; - -- GUID Prefix 1/3 - when 1 => - mem_rd <= '1'; - mem_guidprefix_next(0) <= mem_read_data; - -- GUID Prefix 2/3 - when 2 => - mem_rd <= '1'; - mem_guidprefix_next(1) <= mem_read_data; - -- GUID Prefix 3/3 - when 3 => - mem_rd <= '1'; - mem_guidprefix_next(2) <= mem_read_data; - mem_addr_next <= addr_res; - -- GUID Prefix 1/3 - when 4 => - mem_wr <= '1'; - mem_write_data <= GUIDPREFIX_UNKNOWN(0); - -- GUID Prefix 2/3 - when 5 => - mem_wr <= '1'; - mem_write_data <= GUIDPREFIX_UNKNOWN(1); - -- GUID Prefix 3/3 - when 6 => - mem_wr <= '1'; - mem_write_data <= GUIDPREFIX_UNKNOWN(2); - -- Reset MAX Participant Pointer - mem_addr_base_next <= FIRST_PARTICIPANT_ADDRESS; - mem_addr_next <= FIRST_PARTICIPANT_ADDRESS; - reset_max_pointer_next <= '1'; - last_addr_next <= (others => '0'); - mem_stage_next <= FIND_PARTICIPANT_SLOT; - mem_cnt_next <= 0; - when others => - null; - end case; - when FIND_PARTICIPANT_SLOT => - mem_rd <= '1'; - mem_addr_next <= mem_addr + 1; - mem_cnt_next <= mem_cnt + 1; - - -- Next Participant Frame Address - tmp := mem_addr_base + PARTICIPANT_FRAME_SIZE; + -- Precondition: mem_addr_base set, mem_prev_addr_base set case (mem_cnt) is - -- Preload + -- GET Next Participant when 0 => - null; - -- GUID Prefix 1/3 + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_NEXT_ADDR_OFFSET; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- READ Next Participant when 1 => - -- Slot Occupied - if (mem_read_data /= GUIDPREFIX_UNKNOWN(0)) then - if (mem_addr_base = max_participant_addr) then - -- We are in the middle of resetting the MAX Participant Pointer - if (reset_max_pointer = '1') then - -- No Change - mem_stage_next <= IDLE; - -- MEMORY FULL - elsif (max_participant_addr = MAX_PARTICIPANT_ADDRESS) then - report "Memory Full, Ignoring Participant Data" severity NOTE; - -- Ignore Insertion - mem_stage_next <= IDLE; - addr_res_next <= MAX_ADDRESS; - else - -- Extend Participant Memory Area - -- NOTE: "max_participant_addr" points to the first address of last participant frame - max_participant_addr_next <= tmp; - -- Populate Participant Slot - mem_stage_next <= INSERT_PARTICIPANT; - mem_addr_next <= tmp; - addr_res_next <= tmp; - mem_cnt_next <= 0; - end if; + mem_ready_out <= '1'; + + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + mem_next_addr_base_next <= resize(unsigned(mem_read_data),PARTICIPANT_MEMORY_ADDR_WIDTH); + + -- Removed Participant is List Head + if (mem_prev_addr_base = PARTICIPANT_MEMORY_MAX_ADDRESS) then + assert (mem_addr_base = mem_occupied_head) severity FAILURE; + + -- Fix Occupied Head + mem_occupied_head_next <= resize(unsigned(mem_read_data),PARTICIPANT_MEMORY_ADDR_WIDTH); + + mem_cnt_next <= mem_cnt + 2; -- Skip Next Step else - -- Latch last occupied Participant Slot - last_addr_next <= mem_addr_base; - -- Continue Search - mem_addr_next <= tmp; - mem_addr_base_next <= tmp; - mem_cnt_next <= 0; + mem_cnt_next <= mem_cnt + 1; end if; end if; - -- GUID Prefix 2/3 + -- SET Next Pointer (Previous Participant) when 2 => - -- Slot Occupied - if (mem_read_data /= GUIDPREFIX_UNKNOWN(1)) then - if (mem_addr_base = max_participant_addr) then - -- We are in the middle of resetting the MAX Participant Pointer - if (reset_max_pointer = '1') then - -- No Change - mem_stage_next <= IDLE; - -- MEMORY FULL - elsif (max_participant_addr = MAX_PARTICIPANT_ADDRESS) then - report "Memory Full, Ignoring Participant Data" severity NOTE; - -- Ignore Insertion - mem_stage_next <= IDLE; - addr_res_next <= MAX_ADDRESS; - else - -- Extend Participant Memory Area - -- NOTE: "max_participant_addr" points to the first address of last participant frame - max_participant_addr_next <= tmp; - -- Populate Participant Slot - mem_stage_next <= INSERT_PARTICIPANT; - mem_addr_next <= tmp; - addr_res_next <= tmp; - mem_cnt_next <= 0; - end if; - else - -- Latch last occupied Participant Slot - last_addr_next <= mem_addr_base; - -- Continue Search - mem_addr_next <= tmp; - mem_addr_base_next <= tmp; - mem_cnt_next <= 0; - end if; + -- Point Previous Participant to Next Participant (Remove current Participant from inbetween) + mem_valid_in <= '1'; + mem_addr <= mem_prev_addr_base + PMF_NEXT_ADDR_OFFSET; + mem_write_data <= std_logic_vector(resize(mem_next_addr_base,WORD_WIDTH)); + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; end if; - -- GUID Prefix 3/3 + -- SET Next Pointer (Current/Removed Instance) when 3 => - -- Slot Occupied - if (mem_read_data /= GUIDPREFIX_UNKNOWN(2)) then - if (mem_addr_base = max_participant_addr) then - -- We are in the middle of resetting the MAX Participant Pointer - if (reset_max_pointer = '1') then - -- No Change - mem_stage_next <= IDLE; - -- MEMORY FULL - elsif (max_participant_addr = MAX_PARTICIPANT_ADDRESS) then - report "Memory Full, Ignoring Participant Data" severity NOTE; - -- Ignore Insertion - mem_stage_next <= IDLE; - addr_res_next <= MAX_ADDRESS; - else - -- Extend Participant Memory Area - -- NOTE: "max_participant_addr" points to the first address of last participant frame - max_participant_addr_next <= tmp; - -- Populate Participant Slot - mem_stage_next <= INSERT_PARTICIPANT; - mem_addr_next <= tmp; - addr_res_next <= tmp; - mem_cnt_next <= 0; - end if; - else - -- Latch last occupied Participant Slot - last_addr_next <= mem_addr_base; - -- Continue Search - mem_addr_next <= tmp; - mem_addr_base_next <= tmp; - mem_cnt_next <= 0; - end if; - -- Slot Empty - else - if (reset_max_pointer = '1') then - -- Make sure to iterate through complete participant area - if (mem_addr_base = max_participant_addr) then - -- Reset Pointer to last occupied participant Slot - max_participant_addr_next <= last_addr; - -- DONE - mem_stage_next <= IDLE; - else - -- Continue Search - mem_addr_next <= tmp; - mem_addr_base_next <= tmp; - mem_cnt_next <= 0; - end if; - else - -- Populate Participant Slot - mem_stage_next <= INSERT_PARTICIPANT; - mem_addr_next <= mem_addr_base; - addr_res_next <= mem_addr_base; - mem_cnt_next <= 0; - end if; - end if; - when others => - null; - end case; - when FIND_NEXT_PARTICIPANT => - mem_rd <= '1'; - mem_cnt_next <= mem_cnt + 1; - mem_addr_next <= mem_addr + 1; - - -- Next Participant Frame Address - tmp := mem_addr_base + PARTICIPANT_FRAME_SIZE; - -- Beginning of Participant Data - tmp2 := mem_addr_base + 3; - - case (mem_cnt) is - -- Preload - when 0 => - null; - -- GUID Prefix 1/3 - when 1 => - -- Slot Occupied - if (mem_read_data /= GUIDPREFIX_UNKNOWN(0)) then - -- Get Participant Data - mem_addr_next <= tmp2; - addr_res_next <= mem_addr_base; - mem_stage_next <= GET_PARTICIPANT_DATA; - mem_cnt_next <= 0; - end if; - when 2 => - -- Slot Occupied - if (mem_read_data /= GUIDPREFIX_UNKNOWN(1)) then - -- Get Participant Data - mem_addr_next <= tmp2; - addr_res_next <= mem_addr_base; - mem_stage_next <= GET_PARTICIPANT_DATA; - mem_cnt_next <= 0; - end if; - when 3 => - -- Slot Occupied - if (mem_read_data /= GUIDPREFIX_UNKNOWN(2)) then - -- Get Participant Data - mem_addr_next <= tmp2; - addr_res_next <= mem_addr_base; - mem_stage_next <= GET_PARTICIPANT_DATA; - mem_cnt_next <= 0; - -- Slot Empty - else - -- Reached End of Memory, No Match - if (mem_addr_base = max_participant_addr) then - addr_res_next <= MAX_ADDRESS; --No match - -- DONE - mem_stage_next <= IDLE; - else - -- Continue Search - mem_addr_next <= tmp; - mem_addr_base_next <= tmp; - mem_cnt_next <= 0; - end if; - end if; - when others => - null; - end case; - when FIND_STALE_PARTICIPANT => - mem_rd <= '1'; - mem_cnt_next <= mem_cnt + 1; - mem_addr_next <= mem_addr + 1; - - -- Next Participant Frame Address - tmp := mem_addr_base + PARTICIPANT_FRAME_SIZE; - -- Beginning of Lease Deadline - tmp2 := mem_addr_base + 10; - -- Beginning of Participant Data - tmp3 := mem_addr_base + 3; - - case (mem_cnt) is - -- Preload - when 0 => - null; - -- GUID Prefix 1/3 - when 1 => - -- Slot Occupied - if (mem_read_data /= GUIDPREFIX_UNKNOWN(0)) then - -- Jump to Stale Check - mem_addr_next <= tmp2; - mem_cnt_next <= 4; - end if; - -- GUID Prefix 2/3 - when 2 => - -- Slot Occupied - if (mem_read_data /= GUIDPREFIX_UNKNOWN(1)) then - -- Jump to Stale Check - mem_addr_next <= tmp2; - mem_cnt_next <= 4; - end if; - -- GUID Prefix 3/3 - when 3 => - -- Slot Occupied - if (mem_read_data /= GUIDPREFIX_UNKNOWN(2)) then - -- Jump to Stale Check - mem_addr_next <= tmp2; - mem_cnt_next <= 4; - -- Slot Empty - else - -- Reached End of Memory, No Match - if (mem_addr_base = max_participant_addr) then - addr_res_next <= MAX_ADDRESS; --No match - -- DONE - mem_stage_next <= IDLE; - else - -- Continue Search - mem_addr_next <= tmp; - mem_addr_base_next <= tmp; - mem_cnt_next <= 0; - end if; - end if; - -- Preload - when 4 => - null; - -- Lease Deadline 1/2 - when 5 => - mem_long_latch_next <= mem_read_data; - -- Lease Deadline 2/2 - when 6 => - tmp_dw := (0 => unsigned(mem_long_latch), 1 => unsigned(mem_read_data)); - -- Lease Deadline passed - if (tmp_dw < time) then - -- Mark Participant as stale - addr_res_next <= mem_addr_base; - mem_participant_data_next <= ZERO_PARTICIPANT_DATA; + -- Point Current Instance to Empty List Head (Make Removed Instance Head of the Empty List) + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_NEXT_ADDR_OFFSET; + mem_write_data <= std_logic_vector(resize(mem_empty_head,WORD_WIDTH)); + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + -- Fix Empty List Head + mem_empty_head_next <= mem_addr_base; + -- Reset + mem_addr_base_next <= PARTICIPANT_MEMORY_MAX_ADDRESS; + -- DONE - mem_stage_next <= IDLE; + mem_stage_next <= IDLE; end if; - -- Extra Flags - when 7 => + when others => null; - -- ACKNACK Response/Suppression Time 1/2 - when 8 => - mem_long_latch_next <= mem_read_data; - -- ACKNACK Response/Suppression Time 2/2 - when 9 => - tmp_dw := (0 => unsigned(mem_long_latch), 1 => unsigned(mem_read_data)); - -- Acknack Response/Suppression Time passed - if (tmp_dw /= 0 and tmp_dw < time) then - -- Mark Participant and get Participant Data - addr_res_next <= mem_addr_base; - mem_addr_next <= tmp3; - -- Mark as ACKNACK Trigger - is_heartbeat_res_next <= '0'; - mem_stage_next <= GET_PARTICIPANT_DATA; - mem_cnt_next <= 0; - end if; - -- HEARTBEAT Response/Suppression Time 1/2 - when 10 => - mem_long_latch_next <= mem_read_data; - -- HEARTBEAT Response/Suppression Time 2/2 - when 11 => - tmp_dw := (0 => unsigned(mem_long_latch), 1 => unsigned(mem_read_data)); - -- Heartbeat Response/Suppression Time passed - if (tmp_dw /= 0 and tmp_dw < time) then - -- Mark Participant and get Participant Data - addr_res_next <= mem_addr_base; - mem_addr_next <= tmp3; - -- Mark as HEARTBEAT Trigger - is_heartbeat_res_next <= '1'; - mem_stage_next <= GET_PARTICIPANT_DATA; - mem_cnt_next <= 0; - -- Participant not Stale + end case; + when RESET_MEMORY => + case (mem_cnt) is + -- Initialize + when 0 => + mem_addr_base_next <= FIRST_PARTICIPANT_ADDRESS; + mem_cnt_next <= mem_cnt + 1; + -- Set Next Pointer + when 1 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_NEXT_ADDR_OFFSET; + if (mem_addr_base = MAX_PARTICIPANT_ADDRESS) then + mem_write_data <= std_logic_vector(resize(PARTICIPANT_MEMORY_MAX_ADDRESS,WORD_WIDTH)); else - -- Reached End of Memory, No Match - if (mem_addr_base = max_participant_addr) then - addr_res_next <= MAX_ADDRESS; --No match + mem_write_data <= std_logic_vector(resize(mem_addr_base + PARTICIPANT_FRAME_SIZE,WORD_WIDTH)); + end if; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + if (mem_addr_base = MAX_PARTICIPANT_ADDRESS) then -- DONE mem_stage_next <= IDLE; else - -- Continue Search - mem_addr_next <= tmp; - mem_addr_base_next <= tmp; - mem_cnt_next <= 0; + mem_addr_base_next <= mem_addr_base + PARTICIPANT_FRAME_SIZE; end if; end if; when others => @@ -3881,101 +5558,79 @@ begin if (reset = '1') then stage <= IDLE; return_stage <= IDLE; + mem_stage <= RESET_MEMORY; message_type <= NONE; string_content <= DOMAIN_TAG_TYPE; - mem_stage <= IDLE; - parameter_end <= (others => '1'); - opcode <= (others => '0'); - flags <= (others => '0'); - src_port <= (others => '0'); - src_addr <= (others => '0'); - src_entityid <= (others => '0'); - dest_entityid <= (others => '0'); - string_length <= (others => '0'); - compare_length <= (others => '0'); - endpoint_mask <= (others => '0'); - def_addr <= (others => '0'); - meta_addr <= (others => '0'); - def_port <= (others => '0'); - meta_port <= (others => '0'); - extra_flags <= (others => '0'); - update_participant_flags <= (others => '0'); - count <= (others => '0'); - mem_addr_base <= (others => '0'); - mem_addr <= (others => '0'); - addr_res <= (others => '0'); - last_addr <= (others => '0'); - long_latch <= (others => '0'); - mem_long_latch <= (others => '0'); - rcvd <= (others => '0'); - reader_flags <= (others => '0'); - max_participant_addr <= FIRST_PARTICIPANT_ADDRESS; - guid <= (others => (others => '0')); - mem_guidprefix <= (others => (others => '0')); - lease_duration <= (others => (others => '0')); - deadline <= (others => (others => '0')); + src_addr <= IPv4_ADDRESS_INVALID; + def_addr <= IPv4_ADDRESS_INVALID; + meta_addr <= IPv4_ADDRESS_INVALID; + src_port <= UDP_PORT_INVALID; + def_port <= UDP_PORT_INVALID; + meta_port <= UDP_PORT_INVALID; + guid <= GUID_UNKNOWN; + src_entityid <= ENTITYID_UNKNOWN; + dest_entityid <= ENTITYID_UNKNOWN; + mem_addr_base <= PARTICIPANT_MEMORY_MAX_ADDRESS; + mem_empty_head <= (others => '0'); + mem_occupied_head <= PARTICIPANT_MEMORY_MAX_ADDRESS; + mem_next_addr_base <= PARTICIPANT_MEMORY_MAX_ADDRESS; + mem_prev_addr_base <= PARTICIPANT_MEMORY_MAX_ADDRESS; + seq_nr <= SEQUENCENUMBER_UNKNOWN; + next_seq_nr <= SEQUENCENUMBER_UNKNOWN; + first_seq_nr <= SEQUENCENUMBER_UNKNOWN; + last_seq_nr <= SEQUENCENUMBER_UNKNOWN; + auto_live_seq_nr <= convert_to_double_word(to_unsigned(2, 64)); + man_live_seq_nr <= FIRST_SEQUENCENUMBER; + live_gap_start <= convert_to_double_word(to_unsigned(2, 64)); + live_gap_end <= FIRST_SEQUENCENUMBER; + lease_duration <= DURATION_ZERO; + check_time <= TIME_INVALID; announcement_time <= time + PARTICIPANT_ANNOUNCEMENT_PERIOD; heartbeat_time <= time + HEARTBEAT_PERIOD; - seq_nr <= (others => (others => '0')); - next_seq_nr <= (others => (others => '0')); - first_seq_nr <= (others => (others => '0')); - last_seq_nr <= (others => (others => '0')); - auto_live_seq_nr <= convert_to_double_word(to_unsigned(2, 64)); - man_live_seq_nr <= convert_to_double_word(to_unsigned(1, 64)); - live_gap_start <= convert_to_double_word(to_unsigned(2, 64)); - live_gap_end <= convert_to_double_word(to_unsigned(1, 64)); - mem_participant_data <= ZERO_PARTICIPANT_DATA; + participant_data <= ZERO_PARTICIPANT_DATA; + participant_latch_data <= ZERO_PARTICIPANT_LATCH_DATA; cnt <= 0; + mem_cnt <= 0; participant_data_cnt <= 0; publisher_data_cnt <= 0; subscriber_data_cnt <= 0; - mem_cnt <= 0; participant_match <= '0'; is_subscriber <= '0'; is_meta_addr <= '0'; stale_check <= '0'; is_live_assert <= '0'; - is_heartbeat_res <= '0'; - reset_max_pointer <= '0'; last_word_in_latch <= '0'; + parameter_end <= (others => '1'); + opcode <= (others => '0'); + flags <= (others => '0'); + string_length <= (others => '0'); + compare_length <= (others => '0'); + endpoint_mask <= (others => '0'); + count <= (others => '0'); + long_latch <= (others => '0'); + rcvd <= (others => '0'); + reader_flags <= (others => '0'); + current_pmf <= (others => '0'); else stage <= stage_next; return_stage <= return_stage_next; + mem_stage <= mem_stage_next; message_type <= message_type_next; string_content <= string_content_next; - mem_stage <= mem_stage_next; - opcode <= opcode_next; - flags <= flags_next; - src_port <= src_port_next; src_addr <= src_addr_next; - src_entityid <= src_entityid_next; - dest_entityid <= dest_entityid_next; - parameter_end <= parameter_end_next; - string_length <= string_length_next; - compare_length <= compare_length_next; - endpoint_mask <= endpoint_mask_next; def_addr <= def_addr_next; meta_addr <= meta_addr_next; + src_port <= src_port_next; def_port <= def_port_next; meta_port <= meta_port_next; - extra_flags <= extra_flags_next; - update_participant_flags <= update_participant_flags_next; - count <= count_next; - mem_addr_base <= mem_addr_base_next; - mem_addr <= mem_addr_next; - addr_res <= addr_res_next; - last_addr <= last_addr_next; - long_latch <= long_latch_next; - mem_long_latch <= mem_long_latch_next; - rcvd <= rcvd_next; - reader_flags <= reader_flags_next; - max_participant_addr <= max_participant_addr_next; guid <= guid_next; - mem_guidprefix <= mem_guidprefix_next; - lease_duration <= lease_duration_next; - deadline <= deadline_next; - announcement_time <= announcement_time_next; - heartbeat_time <= heartbeat_time_next; + src_entityid <= src_entityid_next; + dest_entityid <= dest_entityid_next; + mem_addr_base <= mem_addr_base_next; + mem_empty_head <= mem_empty_head_next; + mem_occupied_head <= mem_occupied_head_next; + mem_next_addr_base <= mem_next_addr_base_next; + mem_prev_addr_base <= mem_prev_addr_base_next; seq_nr <= seq_nr_next; next_seq_nr <= next_seq_nr_next; first_seq_nr <= first_seq_nr_next; @@ -3984,20 +5639,34 @@ begin man_live_seq_nr <= man_live_seq_nr_next; live_gap_start <= live_gap_start_next; live_gap_end <= live_gap_end_next; - mem_participant_data <= mem_participant_data_next; + lease_duration <= lease_duration_next; + check_time <= check_time_next; + announcement_time <= announcement_time_next; + heartbeat_time <= heartbeat_time_next; + participant_data <= participant_data_next; + participant_latch_data <= participant_latch_data_next; cnt <= cnt_next; + mem_cnt <= mem_cnt_next; participant_data_cnt <= participant_data_cnt_next; publisher_data_cnt <= publisher_data_cnt_next; subscriber_data_cnt <= subscriber_data_cnt_next; - mem_cnt <= mem_cnt_next; participant_match <= participant_match_next; is_subscriber <= is_subscriber_next; is_meta_addr <= is_meta_addr_next; stale_check <= stale_check_next; is_live_assert <= is_live_assert_next; - is_heartbeat_res <= is_heartbeat_res_next; - reset_max_pointer <= reset_max_pointer_next; last_word_in_latch <= last_word_in_latch_next; + parameter_end <= parameter_end_next; + opcode <= opcode_next; + flags <= flags_next; + string_length <= string_length_next; + compare_length <= compare_length_next; + endpoint_mask <= endpoint_mask_next; + count <= count_next; + long_latch <= long_latch_next; + rcvd <= rcvd_next; + reader_flags <= reader_flags_next; + current_pmf <= current_pmf_next; end if; end if; end process; diff --git a/src/rtps_config_package.vhd b/src/rtps_config_package.vhd index cbaae36..0c681f3 100644 --- a/src/rtps_config_package.vhd +++ b/src/rtps_config_package.vhd @@ -96,7 +96,7 @@ package rtps_config_package is end record; constant READER_ENDPOINT_DATA : OUTPUT_DATA_TYPE; --Deferred to package body constant WRITER_ENDPOINT_DATA : OUTPUT_DATA_TYPE; --Deferred to package body - constant PARTICIPANT_DATA : OUTPUT_DATA_TYPE; --Deferred to package body + constant LOCAL_PARTICIPANT_DATA : OUTPUT_DATA_TYPE; --Deferred to package body type STRING_WORD_ARRAY_TYPE is array (0 to (256/(WORD_WIDTH/8))-1) of std_logic_vector(WORD_WIDTH-1 downto 0); type ENDPOINT_STRING_TYPE is array (0 to NUM_ENDPOINTS-1) of STRING_WORD_ARRAY_TYPE; @@ -1015,7 +1015,7 @@ package body rtps_config_package is return ret; end function; - constant PARTICIPANT_DATA : OUTPUT_DATA_TYPE := gen_participant_data; + constant LOCAL_PARTICIPANT_DATA : OUTPUT_DATA_TYPE := gen_participant_data; -- Direction 0 : Offered <= Requested diff --git a/src/rtps_test_package.vhd b/src/rtps_test_package.vhd index b5e1c85..9f603cc 100644 --- a/src/rtps_test_package.vhd +++ b/src/rtps_test_package.vhd @@ -17,7 +17,7 @@ package rtps_test_package is -- Frame Sizes have to be specified, so that direct memory probing is possible -- rtps_builtin_endpoint Participant Frame Size - constant PARTICIPANT_FRAME_SIZE : natural := 23; + constant PARTICIPANT_FRAME_SIZE : natural := 24; -- rtps_reader Endpoint Frame Size (RELIABLE=TRUE) constant WRITER_ENDPOINT_FRAME_SIZE_A : natural := 12; -- rtps_reader Endpoint Frame Size (RELIABLE=FALSE) @@ -458,6 +458,17 @@ package rtps_test_package is -- pos ID (Memory Position) of Source Remote Writer -- output Destination of generated output procedure gen_add_cache_change_dds(ref : in CACHE_CHANGE_TYPE; lifespan_deadline : in TIME_TYPE; pos : in natural; output : inout TEST_PACKET_TYPE); + -- Generate a rtps_reader memory Participant Frame based on "ref". (A Version) + function gen_reader_endpoint_mem_frame_a (ref : ENDPOINT_DATA_TYPE) return TEST_READER_ENDPOINT_MEMORY_FRAME_TYPE_A; + -- Generate a rtps_reader memory Participant Frame based on "ref". (B Version) + function gen_reader_endpoint_mem_frame_b (ref : ENDPOINT_DATA_TYPE) return TEST_READER_ENDPOINT_MEMORY_FRAME_TYPE_B; + + + -- *RTPS WRITER* + -- Generate a rtps_writer memory Participant Frame based on "ref". (A Version) + function gen_writer_endpoint_mem_frame_a (ref : ENDPOINT_DATA_TYPE) return TEST_WRITER_ENDPOINT_MEMORY_FRAME_TYPE_A; + -- Generate a rtps_writer memory Participant Frame based on "ref". (B Version) + function gen_writer_endpoint_mem_frame_b (ref : ENDPOINT_DATA_TYPE) return TEST_WRITER_ENDPOINT_MEMORY_FRAME_TYPE_B; -- *RTPS_HANDLER* @@ -478,14 +489,6 @@ package rtps_test_package is -- *RTPS_BUILTIN_ENDPOINT* -- Generate a rtps_builtin_endpoint memory Participant Frame based on "ref". function gen_participant_mem_frame (ref : PARTICIPANT_DATA_TYPE) return TEST_PARTICIPANT_MEMORY_FRAME_TYPE; - -- Generate a rtps_writer memory Participant Frame based on "ref". (A Version) - function gen_writer_endpoint_mem_frame_a (ref : ENDPOINT_DATA_TYPE) return TEST_WRITER_ENDPOINT_MEMORY_FRAME_TYPE_A; - -- Generate a rtps_writer memory Participant Frame based on "ref". (B Version) - function gen_writer_endpoint_mem_frame_b (ref : ENDPOINT_DATA_TYPE) return TEST_WRITER_ENDPOINT_MEMORY_FRAME_TYPE_B; - -- Generate a rtps_reader memory Participant Frame based on "ref". (A Version) - function gen_reader_endpoint_mem_frame_a (ref : ENDPOINT_DATA_TYPE) return TEST_READER_ENDPOINT_MEMORY_FRAME_TYPE_A; - -- Generate a rtps_reader memory Participant Frame based on "ref". (B Version) - function gen_reader_endpoint_mem_frame_b (ref : ENDPOINT_DATA_TYPE) return TEST_READER_ENDPOINT_MEMORY_FRAME_TYPE_B; -- Writes a rtps_builtin_endpoint Endpoint Match Frame based on "ref" to "output" procedure gen_endpoint_match_frame( ref : in ENDPOINT_DATA_TYPE; output : inout TEST_PACKET_TYPE); -- Writes a rtps_builtin_endpoint Participant Match Frame based on "ref" to "output" @@ -1793,68 +1796,29 @@ package body rtps_test_package is ret(i).addr := start + i; case (i) is -- GUID Prefix 1/3 - when 0 => - if (ref.match = MATCH) then - ret(i).data := ref.guidPrefix(0); - else - ret(i).data := (others => '0'); - end if; - -- GUID Prefix 2/3 when 1 => - if (ref.match = MATCH) then - ret(i).data := ref.guidPrefix(1); - else - ret(i).data := (others => '0'); - end if; - -- GUID Prefix 3/3 + ret(i).data := ref.guidPrefix(0); + -- GUID Prefix 2/3 when 2 => - if (ref.match = MATCH) then - ret(i).data := ref.guidPrefix(2); - else - ret(i).data := (others => '0'); - end if; - -- METATRAFFIC IPv4 Address + ret(i).data := ref.guidPrefix(1); + -- GUID Prefix 3/3 when 3 => - if (ref.match = MATCH) then - ret(i).data := meta_loc.addr(IPv4_ADDRESS_WIDTH-1 downto 0); - else - ret(i).data := (others => '-'); - end if; - -- DEFAULT IPv4 Address + ret(i).data := ref.guidPrefix(2); + -- METATRAFFIC IPv4 Address when 4 => - if (ref.match = MATCH) then - ret(i).data := user_loc.addr(IPv4_ADDRESS_WIDTH-1 downto 0); - else - ret(i).data := (others => '-'); - end if; - -- METATRAFFIC & DEFAULT UDP Port + ret(i).data := meta_loc.addr(IPv4_ADDRESS_WIDTH-1 downto 0); + -- DEFAULT IPv4 Address when 5 => - if (ref.match = MATCH) then - ret(i).data := meta_loc.portn(UDP_PORT_WIDTH-1 downto 0) & user_loc.portn(UDP_PORT_WIDTH-1 downto 0); - else - ret(i).data := (others => '-'); - end if; + ret(i).data := user_loc.addr(IPv4_ADDRESS_WIDTH-1 downto 0); + -- METATRAFFIC & DEFAULT UDP Port + when 6 => + ret(i).data := meta_loc.portn(UDP_PORT_WIDTH-1 downto 0) & user_loc.portn(UDP_PORT_WIDTH-1 downto 0); -- Lease Duration 1/2 - when 8 => - if (ref.match = MATCH) then - ret(i).data := std_logic_vector(ref.leaseDuration(0)); - else - ret(i).data := (others => '-'); - end if; - -- Lease Duration 2/2 when 9 => - if (ref.match = MATCH) then - ret(i).data := std_logic_vector(ref.leaseDuration(1)); - else - ret(i).data := (others => '-'); - end if; - -- EXTRA FLAGS - when 12 => - if (ref.match = MATCH) then - ret(i).data := (0 => ref.expectsInlineQoS(0), others => '-'); - else - ret(i).data := (others => '-'); - end if; + ret(i).data := std_logic_vector(ref.leaseDuration(0)); + -- Lease Duration 2/2 + when 10 => + ret(i).data := std_logic_vector(ref.leaseDuration(1)); -- Other Fields Ignored when others => ret(i).data := (others => '-');