diff --git a/VHDL-2008.txt b/VHDL-2008.txt index e289d24..f7b8a06 100644 --- a/VHDL-2008.txt +++ b/VHDL-2008.txt @@ -3,3 +3,6 @@ Quartus 18.1 Unsupported * Unconstrained arrays in records (Supported in Pro) * Vectors in aggregate statements e.g. V := ("0000", others => '1'); +* Unary logical operators +* Referencing generics in generic lists +* \ No newline at end of file diff --git a/doc/Altera/qts_qii51007.pdf b/doc/Altera/qts_qii51007.pdf new file mode 100644 index 0000000..a715d96 Binary files /dev/null and b/doc/Altera/qts_qii51007.pdf differ diff --git a/doc/Altera/ug_ram.pdf b/doc/Altera/ug_ram.pdf new file mode 100644 index 0000000..feef960 Binary files /dev/null and b/doc/Altera/ug_ram.pdf differ diff --git a/src/rtps_builtin_endpoint.vhd b/src/rtps_builtin_endpoint.vhd index 04151bb..a23eaae 100644 --- a/src/rtps_builtin_endpoint.vhd +++ b/src/rtps_builtin_endpoint.vhd @@ -24,7 +24,7 @@ entity rtps_builtin_endpoint is rtps_wr : out std_logic; rtps_full : in std_logic; last_word_out : out std_logic; - alive : in std_logic_vector(0 to MAX_ENDPOINTS-1); + alive : in std_logic_vector(0 to MAX_ENDPOINTS-1) ); end entity; @@ -38,7 +38,7 @@ architecture arch of rtps_builtin_endpoint is generic ( ADDR_WIDTH : natural := 8; DATA_WIDTH : natural := 12; - MEMORY_SIZE : natural := DATA_WIDTH*(2**ADDR_WIDTH) + MEMORY_DEPTH : natural := 256 ); port ( @@ -61,9 +61,9 @@ architecture arch of rtps_builtin_endpoint is CHECK_SRC_ENTITYID, LATCH_SEQ_NR, PROCESS_DATA, PROCESS_MESSAGE, PROCESS_GAP, PROCESS_GAP_SEQUENCE_NUMBERS, PROCESS_PL, LATCH_STRING_LENGTH, COMPARE_STRING, RXO_DURABILITY, RXO_DEADLINE, RXO_LIVELINESS, RXO_LEASE_DURATION, LATCH_LEASE_DURATION, RXO_RELIABILITY, RXO_DESTINATION_ORDER, RXO_OWNERSHIP, RXO_PRESENTATION, RXO_PARTITION, MATCH_DOMAIN_ID, MATCH_PROTOCOL_VERSION, - LATCH_LOCATOR, LATCH_EXPECTS_INLINE_QOS, LATCH_GUID, CHECK_REMOTE_BUILTIN_ENDPOINTS, PARTICIPANT_MATCH_STAGE, + LATCH_LOCATOR, LATCH_EXPECTS_INLINE_QOS, MATCH_GUID, CHECK_REMOTE_BUILTIN_ENDPOINTS, PARTICIPANT_MATCH_STAGE, INITIATE_ENDPOINT_SEARCH, ENDPOINT_MATCH_STAGE, FIND_ORPHAN_ENDPOINT, PURGE_ORPHAN_ENDPOINT, INFORM_ENDPOINTS_MATCH, - INFORM_ENDPOINTS_UNMATCH, STALE_CHECK, LATCH_REMOVED_GUIDPREFIX, PROCESS_HEARTBEAT, PROCESS_HEARTBEAT_SEQUENCE_NUMBERS, + INFORM_ENDPOINTS_UNMATCH, PARTICIPANT_STALE_CHECK, LATCH_REMOVED_GUIDPREFIX, PROCESS_HEARTBEAT, PROCESS_HEARTBEAT_SEQUENCE_NUMBERS, SEND_ACKNACK, SEND_HEARTBEAT, PROCESS_ACKNACK, 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); @@ -120,8 +120,8 @@ architecture arch of rtps_builtin_endpoint is end record; --*****CONSTANT DECLARATION***** - -- Memory Size in Bytes - constant BUILTIN_BUFFER_SIZE : natural := MAX_REMOTE_PARTICIPANTS*PARTICIPANT_FRAME_SIZE*4; + -- Memory Size in 32-bit 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 @@ -158,6 +158,8 @@ architecture arch of rtps_builtin_endpoint is constant SUB_SEQUENCE_NR : DOUBLE_WORD_ARRAY := convert_to_double_word(to_unsigned(NUM_READERS, 64)); -- Constant for Sequence Number 1 constant SEQUENCE_NR_START : DOUBLE_WORD_ARRAY := convert_to_double_word(to_unsigned(1, 64)); + -- Heartbeat/Liveliness Assertion Period + constant HEARTBEAT_PERIOD : DOUBLE_WORD_ARRAY := work.rtps_package.min(MIN_ENDPOINT_LEASE_DURATION, PARTICIPANT_HEARTBEAT_PERIOD) - DURATION_DELTA; -- Constant for zero Participant Data constant ZERO_PARTICIPANT_DATA : PARTICIPANT_DATA_TYPE := ( meta_addr => (others => '0'), @@ -202,7 +204,7 @@ architecture arch of rtps_builtin_endpoint is -- Destination Entity ID Latch signal dest_entityid, dest_entityid_next : std_logic_vector(31 downto 0) := (others => '0'); -- Source GUID Latch - signal guid, guid_next : GUID_ARRAY_TYPE := (others => (others => '0')); + signal guid, guid_next : GUID_TYPE := (others => (others => '0')); -- RTPS DATA Submessage Sequence Number Latch signal seq_nr, seq_nr_next : DOUBLE_WORD_ARRAY := (others => (others => '0')); -- Word aligned End of Parameter @@ -237,9 +239,9 @@ architecture arch of rtps_builtin_endpoint is -- Counter used to index the Participant Data signal participant_data_cnt, participant_data_cnt_next : natural range 0 to PARTICIPANT_DATA.length-1 := 0; -- Counter used to index the Publisher Data - signal publisher_data_cnt, publisher_data_cnt_next : natural range 0 to WRITER_ENDPOINT_DATA.length-1 := 0; + 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 READER_ENDPOINT_DATA.length-1 := 0; + 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 @@ -274,6 +276,8 @@ architecture arch of rtps_builtin_endpoint is signal last_seq_nr, last_seq_nr_next : DOUBLE_WORD_ARRAY := (others => (others => '0')); -- Signifies if we currently do a Orphan Endpoint Search (Endpoint whose parent Participant was removed) signal is_orphan_search, is_orphan_search_next : std_logic := '0'; + -- Intermediate write enable signal. + signal wr_sig : std_logic := '0'; -- Intermediate Output Signal signal output_sig : std_logic_vector(31 downto 0) := (others => '0'); -- Signifies if we currently are resetting the MAX Participant/Endpoint Pointer @@ -281,7 +285,7 @@ architecture arch of rtps_builtin_endpoint is -- Signifies if we currently are doing a Participant Stale Entry Check (Used to start Stale Checks between packet handling) signal stale_check, stale_check_next : std_logic := '0'; -- Latch containing the GUID Prefix of the removed Participant from the memory - signal mem_guidprefix, mem_guidprefix_next : GUIDPREFIX_ARRAY_TYPE : (others => (others => '0')); + signal mem_guidprefix, mem_guidprefix_next : GUIDPREFIX_TYPE := (others => (others => '0')); -- 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 @@ -300,7 +304,6 @@ architecture arch of rtps_builtin_endpoint is signal reset_endpoint_alive : std_logic := '0'; -- NOTE: The "auto_live_seq_nr" is always higher than "man_live_seq_nr" -- Contains the highest Sequence Number for automatic liveliness updates - -- TODO: Make sure sequences are initialized correctly signal auto_live_seq_nr, auto_live_seq_nr_next : DOUBLE_WORD_ARRAY := (others => (others => '0')); -- Contains the highest Sequence Number for manual by participant liveliness updates signal man_live_seq_nr, man_live_seq_nr_next : DOUBLE_WORD_ARRAY := (others => (others => '0')); @@ -358,12 +361,12 @@ architecture arch of rtps_builtin_endpoint is --*****FUNCTION DECLARATION***** -- Converts std_logic_vector to ENDPOINT_BITMASK_ARRAY - function convert_to_bitmask_array (bitmask : std_logic_vector) return ENDPOINT_BITMASK_ARRAY is - variable ret : ENDPOINT_BITMASK_ARRAY := (others => (others => '0')); + function convert_to_bitmask_array (bitmask : std_logic_vector) return ENDPOINT_BITMASK_ARRAY_TYPE is + variable ret : ENDPOINT_BITMASK_ARRAY_TYPE := (others => (others => '0')); begin ret := (others => (others => '0')); - for i in 0 to ENDPOINT_BITMASK_ARRAY'length-1 loop - if (i = ENDPOINT_BITMASK_ARRAY'length-1) then + for i in 0 to ENDPOINT_BITMASK_ARRAY_TYPE'length-1 loop + if (i /= ENDPOINT_BITMASK_ARRAY_TYPE'length-1) then ret(i) := bitmask(i*32 to i*32+31); else ret(i)(0 to (bitmask'length mod 32)-1) := bitmask(i*32 to i*32+(bitmask'length mod 32)-1); @@ -373,12 +376,12 @@ architecture arch of rtps_builtin_endpoint is end function; -- Converts ENDPOINT_BITMASK_ARRAY to std_logic_vector - function convert_from_bitmask_array (bitmask : ENDPOINT_BITMASK_ARRAY, len : natural) return std_logic_vector is + function convert_from_bitmask_array (bitmask : ENDPOINT_BITMASK_ARRAY_TYPE; len : natural) return std_logic_vector is variable ret : std_logic_vector(0 to len-1) := (others => '0'); begin ret := (others => '0'); - for i in 0 to ENDPOINT_BITMASK_ARRAY'length-1 loop - if (i = ENDPOINT_BITMASK_ARRAY'length-1) then + for i in 0 to ENDPOINT_BITMASK_ARRAY_TYPE'length-1 loop + if (i /= ENDPOINT_BITMASK_ARRAY_TYPE'length-1) then ret(i*32 to i*32+31) := bitmask(i); else ret(i*32 to i*32+(len mod 32)-1) := bitmask(i)(0 to (len mod 32)-1); @@ -387,18 +390,39 @@ architecture arch of rtps_builtin_endpoint is return ret; end function; + -- Returns the 'data' argument either as is, or with reversed Byte order, depending on the + -- 'endianness' argument. + function endian_swap( endianness : std_logic; + data :std_logic_vector) return std_logic_vector is + variable ret : std_logic_vector(data'range); + begin + -- Assert that Data Signal is Byte aligned + assert (data'length mod 8 = 0) severity failure; + -- Little Endian + if (endianness = '1') then + -- Reverse byte Order + for i in 0 to (data'length/8)-1 loop + ret(i*8+8-1 downto i*8) := data(((data'length/8)-1-i)*8+8-1 downto ((data'length/8)-1-i)*8); + end loop; + -- Big Endian + else + ret := data; + end if; + return ret; + end function; + begin --*****COMPONENT INSTANTIATION***** - ram_inst : single_port_ram is + ram_inst : single_port_ram generic map ( ADDR_WIDTH => BUILTIN_BUFFER_ADDR_WIDTH, DATA_WIDTH => 32, - MEMORY_SIZE => BUILTIN_BUFFER_SIZE + MEMORY_DEPTH => BUILTIN_BUFFER_SIZE ) port map ( clk => clk, - addr => mem_addr, + addr => std_logic_vector(mem_addr), wen => mem_wr, ren => mem_rd, wr_data => mem_write_data, @@ -418,7 +442,7 @@ begin if (endian_flag = '1') then -- Endian Swap for i in 0 to 3 loop - data_in_swapped(i*8+8-1 downto i*8) <= data((3-i)*8+8-1 downto (3-i)*8); + data_in_swapped(i*8+8-1 downto i*8) <= data_in((3-i)*8+8-1 downto (3-i)*8); end loop; end if; end process; @@ -433,8 +457,7 @@ begin if (reset = '1' or reset_endpoint_alive = '1') then endpoint_alive <= '0'; -- Set Endpoint Alive Signal, if at least one endpoint asserts liveliness - -- XXX: VHDL-2008 unary logic operator - elsif (or alive = '1') then + elsif (alive /= (alive'range => '0')) then endpoint_alive <= '1'; end if; end if; @@ -479,8 +502,8 @@ begin -- Memory Operation in progress else seq_prc_done_next <= '0'; - mem_seq_nr_next <= (others => '0'); - next_seq_nr_next <= (others => '0'); + mem_seq_nr_next <= (others => (others => '0')); + next_seq_nr_next <= (others => (others => '0')); end if; end process; @@ -488,7 +511,7 @@ begin output_prc : process(all) begin -- Data Signal - for i in 0 to NUM_DOMAIN-1 loop + for i in 0 to MAX_ENDPOINTS-1 loop endpoint_output(i) <= output_sig; end loop; rtps_output <= output_sig; @@ -535,7 +558,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. - -- STALE_CHECK Check memory for remote stale Participant Entries (Lease Duration Exceeded, HEARTBEAT/ACKNACK timeout passed) + -- 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 -- FIND_ORPHAN_ENDPOINT Search for Orphan (whose parent Participant was removed) Endpoints in memory -- PURGE_ORPHAN_ENDPOINT Remove Orphan Endpoint from memory @@ -584,15 +607,17 @@ begin flags_next <= flags; src_port_next <= src_port; src_addr_next <= src_addr; + guid_next <= guid; src_entityid_next <= src_entityid; dest_entityid_next <= dest_entityid; parameter_end_next <= parameter_end; message_type_next <= message_type; string_length_next <= string_length; + compare_length_next <= compare_length; endpoint_mask_next <= endpoint_mask; endpoint_match_next <= endpoint_match; endpoint_unmatch_next <= endpoint_unmatch; - participant_match_next <= participant_match_next; + participant_match_next <= participant_match; is_subscriber_next <= is_subscriber; lease_duration_next <= lease_duration; def_addr_next <= def_addr; @@ -601,7 +626,7 @@ begin meta_port_next <= meta_port; is_meta_addr_next <= is_meta_addr; cnt_next <= cnt; - expects_inline_qos_set_next <= expects_inline_qos_set; + expects_inline_qos_set_next <= expects_inline_qos_set; is_orphan_search_next <= is_orphan_search; extra_flags_next <= extra_flags; stale_check_next <= stale_check; @@ -620,6 +645,9 @@ begin participant_data_cnt_next <= participant_data_cnt; publisher_data_cnt_next <= publisher_data_cnt; subscriber_data_cnt_next <= subscriber_data_cnt; + seq_nr_next <= seq_nr; + last_word_in_latch_next <= last_word_in_latch; + count_next <= count; -- DEFAULT Unregistered rd_sig <= '0'; reset_read_cnt <= '0'; @@ -633,9 +661,6 @@ begin -- Last Word Latch Setter if (last_word_in = '1') then last_word_in_latch_next <= '1'; - -- TODO: Also set in LATCH_REMOVED_GUIDPREFIX to exit from SKIP_PACKET stage - else - last_word_in_latch_next <= last_word_in_latch; end if; -- TODO: Reset Latches @@ -645,7 +670,7 @@ begin when IDLE => -- Participant Announcement Time Trigger if (time > announcement_time) then - announcement_time_next <= time + TODO; + announcement_time_next <= time + PARTICIPANT_ANNOUNCEMENT_PERIOD; stage_next <= SEND_HEADER; return_stage_next <= SEND_PARTICIPANT_ANNOUNCEMENT; -- Heartbeat Time Trigger @@ -669,7 +694,7 @@ begin auto_live_seq_nr_next <= auto_live_seq_nr + 1; live_gap_end_next <= live_gap_end + 1; end if; - heartbeat_time_next <= time + TODO; + heartbeat_time_next <= time + HEARTBEAT_PERIOD; -- Send Heartbeat and Liveliness Assertions to all stored Participants mem_opcode <= FIND_FIRST_PATICIPANT; mem_op_start <= '1'; @@ -686,7 +711,7 @@ begin mem_op_start <= '1'; -- Stale Check Toggle (Setter) stale_check_next <= '1'; - stage_next <= STALE_CHECK; + stage_next <= PARTICIPANT_STALE_CHECK; end if; -- Process Packet else @@ -1172,13 +1197,13 @@ begin -- Latch Sequence Numbers case (cnt) is when 0 => - first_seq_nr_next(0) <= data_in_swapped; + first_seq_nr_next(0) <= unsigned(data_in_swapped); when 1 => - first_seq_nr_next(1) <= data_in_swapped; + first_seq_nr_next(1) <= unsigned(data_in_swapped); when 2 => - last_seq_nr_next(0) <= data_in_swapped; + last_seq_nr_next(0) <= unsigned(data_in_swapped); when 3 => - last_seq_nr_next(1) <= data_in_swapped; + last_seq_nr_next(1) <= unsigned(data_in_swapped); -- NOTE: Rest of GAP Message is ignored stage_next <= PROCESS_GAP_SEQUENCE_NUMBERS; when others => @@ -1213,13 +1238,13 @@ begin -- Latch Sequence Numbers case (cnt) is when 0 => - first_seq_nr_next(0) <= data_in_swapped; + first_seq_nr_next(0) <= unsigned(data_in_swapped); when 1 => - first_seq_nr_next(1) <= data_in_swapped; + first_seq_nr_next(1) <= unsigned(data_in_swapped); when 2 => - last_seq_nr_next(0) <= data_in_swapped; + last_seq_nr_next(0) <= unsigned(data_in_swapped); when 3 => - last_seq_nr_next(1) <= data_in_swapped; + last_seq_nr_next(1) <= unsigned(data_in_swapped); stage_next <= PROCESS_HEARTBEAT_SEQUENCE_NUMBERS; when others => null; @@ -1239,7 +1264,7 @@ begin mem_opcode <= UPDATE_PARTICIPANT; deadline_next <= time + PARTICIPANT_HEARTBEAT_RESPONSE_DELAY; -- NOTE: Last Bit denotes if this is Response or Suppression Delay - deadline_next(0) <= '0'; + 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'; -- If new Sequence Number is available or Writer expects ACKNACK @@ -1248,12 +1273,12 @@ begin mem_opcode <= UPDATE_PARTICIPANT; deadline_next <= time + PARTICIPANT_HEARTBEAT_RESPONSE_DELAY; -- NOTE: Last Bit denotes if this is Response or Suppression Delay - deadline_next(0) <= '0'; + deadline_next(1)(0) <= '0'; update_participant_flags_next <= (HEARTBEAT_RES_TIME_FLAG => '1', others => '0'); mem_op_start <= '1'; end if; -- Currently in Heartbeat Response Delay - elsif (mem_participant_data.heartbeat_res_time(0) = '0') then + elsif (mem_participant_data.heartbeat_res_time(1)(0) = '0') then -- If current Sequence Number obsolete (removed from source history cache) if (first_seq_nr > next_seq_nr) then -- Store new expected Sequence Number -1 @@ -1276,11 +1301,11 @@ begin -- NOTE: Because we always sent the entire history cache, we only need to look at the SequenceNumberSetBase to determine if we need to sent data or not case (cnt) is when 1 => - first_seq_nr_next(0) <= data_in_swapped; + first_seq_nr_next(0) <= unsigned(data_in_swapped); when 2 => - first_seq_nr_next(1) <= data_in_swapped; + first_seq_nr_next(1) <= unsigned(data_in_swapped); - stage_next <= PROCESS_ACKNACK_SEQUENCE_NUMBERS + stage_next <= PROCESS_ACKNACK_SEQUENCE_NUMBERS; when others => null; end case; @@ -1302,7 +1327,7 @@ begin mem_opcode <= UPDATE_PARTICIPANT; deadline_next <= time + PARTICIPANT_ACKNACK_RESPONSE_DELAY; -- NOTE: Last Bit denotes if this is Response or Suppression Delay - deadline_next(0) <= '0'; + 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'); @@ -1316,7 +1341,7 @@ begin mem_opcode <= UPDATE_PARTICIPANT; deadline_next <= time + PARTICIPANT_ACKNACK_RESPONSE_DELAY; -- NOTE: Last Bit denotes if this is Response or Suppression Delay - deadline_next(0) <= '0'; + 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'); @@ -1332,7 +1357,7 @@ begin mem_opcode <= UPDATE_PARTICIPANT; deadline_next <= time + PARTICIPANT_ACKNACK_RESPONSE_DELAY; -- NOTE: Last Bit denotes if this is Response or Suppression Delay - deadline_next(0) <= '0'; + 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'); @@ -1342,13 +1367,13 @@ begin null; end case; -- Currently in Acknack Response Delay - elsif (mem_participant_data.acknack_res_time(0) = '0') then + elsif (mem_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)) then + if (mem_participant_data.extra_flags(PUB_DATA_FLAG) = '0') then -- If Reader has not ACKed all Publisher History Cache if (first_seq_nr <= PUB_SEQUENCE_NR) then -- Set Publisher Data as Acknack Response @@ -1362,7 +1387,7 @@ begin -- Publisher Acknack else -- Subscriber Data not scheduled for response - if (mem_participant_data.extra_flags(SUB_DATA_FLAG)) then + if (mem_participant_data.extra_flags(SUB_DATA_FLAG) = '0') then -- If Reader has not ACKed all Subscriber History Cache if (first_seq_nr <= SUB_SEQUENCE_NR) then -- Set Subscriber Data as Acknack Response @@ -1373,10 +1398,11 @@ begin mem_op_start <= '1'; 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)) then + if (mem_participant_data.extra_flags(MES_DATA_FLAG) = '0') 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 @@ -1408,9 +1434,9 @@ begin stage_next <= SEND_HEADER; return_stage_next <= SEND_HEARTBEAT; cnt_next <= 0; - end if + end if; end if; - when STALE_CHECK => + when PARTICIPANT_STALE_CHECK => -- Wait for Stale Search to finish if (mem_op_done = '1') then -- Found Stale Entry @@ -1428,11 +1454,11 @@ begin -- Heartbeat Response if (is_heartbeat_res = '1') then -- If Suppression Delay passed, zero the time - if(mem_participant_data.heartbeat_res_time(0) = '1') then + if(mem_participant_data.heartbeat_res_time(1)(0) = '1') then -- Zero Heartbeat Response Time mem_opcode <= UPDATE_PARTICIPANT; - deadline_next <= (others => '0'); - update_participant_flags_next <= (HEARTBEAT_RES_TIME_FLAG_FLAG => '1', others => '0'); + deadline_next <= (others => (others => '0')); + update_participant_flags_next <= (HEARTBEAT_RES_TIME_FLAG => '1', others => '0'); mem_op_start <= '1'; -- DONE stage_next <= IDLE; @@ -1444,12 +1470,12 @@ begin -- Set Heartbeat Suppression Time deadline_next <= time + PARTICIPANT_HEARTBEAT_SUPPRESSION_DELAY; -- NOTE: Last Bit denotes if this is Response or Suppression Delay - deadline_next(0) <= '1'; + deadline_next(1)(0) <= '1'; else -- Zero Heartbeat Response Time - deadline_next <= (others => '0'); + deadline_next <= (others => (others => '0')); end if; - update_participant_flags_next <= (HEARTBEAT_RES_TIME_FLAG_FLAG => '1', others => '0'); + update_participant_flags_next <= (HEARTBEAT_RES_TIME_FLAG => '1', others => '0'); mem_op_start <= '1'; -- Send ACKNACK -- Increment Heartbeat/Acknack Counter @@ -1461,10 +1487,10 @@ begin -- Acknack Response else -- If Suppression Delay passed, zero the time - if(mem_participant_data.acknack_res_time(0) = '1') then + if(mem_participant_data.acknack_res_time(1)(0) = '1') then -- Zero Acknack Response Time mem_opcode <= UPDATE_PARTICIPANT; - deadline_next <= (others => '0'); + deadline_next <= (others => (others => '0')); update_participant_flags_next <= (ACKNACK_RES_TIME_FLAG => '1', others => '0'); mem_op_start <= '1'; -- DONE @@ -1476,10 +1502,10 @@ begin -- Set Acknack Suppression Time deadline_next <= time + PARTICIPANT_ACKNACK_SUPPRESSION_DELAY; -- NOTE: Last Bit denotes if this is Response or Suppression Delay - deadline_next(0) <= '1'; + deadline_next(1)(0) <= '1'; else -- Zero Acknack Response Time - deadline_next <= (others => '0'); + deadline_next <= (others => (others => '0')); end if; -- Zero Data Response Flags extra_flags_next <= mem_participant_data.extra_flags; @@ -1489,7 +1515,8 @@ begin 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_DATA; + stage_next <= SEND_HEADER; + return_stage_next <= SEND_PUB_DATA; cnt_next <= 0; end if; end if; @@ -1572,7 +1599,7 @@ begin if(qos_flag = '0' and message_type = PDP) then stage_next <= LATCH_STRING_LENGTH; -- Mark String contents (Needed for string comparison) - string_content <= DOMAIN_TAG; + string_content_next <= DOMAIN_TAG; end if; when PID_PROTOCOL_VERSION => -- Ignore in-line QoS @@ -1637,7 +1664,7 @@ begin if(qos_flag = '0' and message_type = EDP) then stage_next <= LATCH_STRING_LENGTH; -- Mark String contents (Needed for string comparison) - string_content <= TOPIC_NAME; + string_content_next <= TOPIC_NAME; end if; when PID_TYPE_NAME => -- Ignore in-line QoS @@ -1645,7 +1672,7 @@ begin if(qos_flag = '0' and message_type = EDP) then stage_next <= LATCH_STRING_LENGTH; -- Mark String contents (Needed for string comparison) - string_content <= TYPE_NAME; + string_content_next <= TYPE_NAME; end if; when PID_DURABILITY => -- Ignore in-line QoS @@ -1873,7 +1900,7 @@ begin end if; end loop; when DOMAIN_TAG => - if (data_in /= DOMAIN_TAG(cnt)) then + if (data_in /= work.rtps_package.DOMAIN_TAG(cnt)) then participant_match_next <= '0'; end if; when others => @@ -1884,7 +1911,7 @@ begin -- End of String (Exit Condition) if ((compare_length & "00") >= string_length) then -- DONE - stage_next => SKIP_PARAMETER; + stage_next <= SKIP_PARAMETER; end if; end if; when MATCH_GUID => @@ -1959,17 +1986,17 @@ begin when 1 => -- Latch Source Port if (is_meta_addr = '0') then - def_port <= data_in_swapped(def_port'length-1 downto 0); + def_port_next <= data_in_swapped(def_port'length-1 downto 0); else - meta_port <= data_in_swapped(meta_port'length-1 downto 0); + meta_port_next <= data_in_swapped(meta_port'length-1 downto 0); end if; -- Locator Addr (IPv4) when 5 => -- Latch Src Addr if (is_meta_addr = '0') then - def_addr <= data_in_swapped; + def_addr_next <= data_in_swapped; else - meta_addr <= data_in_swapped; + meta_addr_next <= data_in_swapped; end if; -- DONE stage_next <= SKIP_PARAMETER; @@ -1998,9 +2025,9 @@ begin -- Latch Lease Duration case (cnt) is when 0 => - lease_duration_next(0) <= data_in_swapped; + lease_duration_next(0) <= unsigned(data_in_swapped); when 1 => - lease_duration_next(1) <= data_in_swapped; + lease_duration_next(1) <= unsigned(data_in_swapped); -- DONE stage_next <= SKIP_PARAMETER; when others => @@ -2046,12 +2073,12 @@ begin for i in 0 to MAX_ENDPOINTS-1 loop -- data-in is Subscriber-Requested if (is_subscriber = '1') then - if (data_in_swapped > ENDPOINT_DURABILITY(i)) then + if (unsigned(data_in_swapped) > unsigned(ENDPOINT_DURABILITY(i))) then endpoint_mask_next(i) <= '0'; end if; -- data-in is Publisher-Offered else - if (data_in_swapped < ENDPOINT_DURABILITY(i)) then + if (unsigned(data_in_swapped) < unsigned(ENDPOINT_DURABILITY(i))) then endpoint_mask_next(i) <= '0'; end if; end if; @@ -2072,12 +2099,12 @@ begin for i in 0 to MAX_ENDPOINTS-1 loop -- data-in is Subscriber-Requested if (is_subscriber = '1') then - if (data_in_swapped < ENDPOINT_DEADLINE(i)(0)) then + if (unsigned(data_in_swapped) < ENDPOINT_DEADLINE(i)(0)) then endpoint_mask_next(i) <= '0'; end if; -- data-in is Publisher-Offered else - if (data_in_swapped > ENDPOINT_DEADLINE(i)(0)) then + if (unsigned(data_in_swapped) > ENDPOINT_DEADLINE(i)(0)) then endpoint_mask_next(i) <= '0'; end if; end if; @@ -2088,12 +2115,12 @@ begin for i in 0 to MAX_ENDPOINTS-1 loop -- data-in is Subscriber-Requested if (is_subscriber = '1') then - if (data_in_swapped < ENDPOINT_DEADLINE(i)(1)) then + if (unsigned(data_in_swapped) < ENDPOINT_DEADLINE(i)(1)) then endpoint_mask_next(i) <= '0'; end if; -- data-in is Publisher-Offered else - if (data_in_swapped > ENDPOINT_DEADLINE(i)(1)) then + if (unsigned(data_in_swapped) > ENDPOINT_DEADLINE(i)(1)) then endpoint_mask_next(i) <= '0'; end if; end if; @@ -2114,12 +2141,12 @@ begin for i in 0 to MAX_ENDPOINTS-1 loop -- data-in is Subscriber-Requested if (is_subscriber = '1') then - if (data_in_swapped > ENDPOINT_LIVELINESS(i)) then + if (unsigned(data_in_swapped) > unsigned(ENDPOINT_LIVELINESS(i))) then endpoint_mask_next(i) <= '0'; end if; -- data-in is Publisher-Offered else - if (data_in_swapped < ENDPOINT_LIVELINESS(i)) then + if (unsigned(data_in_swapped) < unsigned(ENDPOINT_LIVELINESS(i))) then endpoint_mask_next(i) <= '0'; end if; end if; @@ -2141,12 +2168,12 @@ begin for i in 0 to MAX_ENDPOINTS-1 loop -- data-in is Subscriber-Requested if (is_subscriber = '1') then - if (data_in_swapped > ENDPOINT_LEASE_DURATION(i)(0)) then + if (unsigned(data_in_swapped) > ENDPOINT_LEASE_DURATION(i)(0)) then endpoint_mask_next(i) <= '0'; end if; -- data-in is Publisher-Offered else - if (data_in_swapped < ENDPOINT_LIVELINESS(i)(0)) then + if (unsigned(data_in_swapped) < ENDPOINT_LEASE_DURATION(i)(0)) then endpoint_mask_next(i) <= '0'; end if; end if; @@ -2157,12 +2184,12 @@ begin for i in 0 to MAX_ENDPOINTS-1 loop -- data-in is Subscriber-Requested if (is_subscriber = '1') then - if (data_in_swapped > ENDPOINT_LEASE_DURATION(i)(1)) then + if (unsigned(data_in_swapped) > ENDPOINT_LEASE_DURATION(i)(1)) then endpoint_mask_next(i) <= '0'; end if; -- data-in is Publisher-Offered else - if (data_in_swapped < ENDPOINT_LIVELINESS(i)(1)) then + if (unsigned(data_in_swapped) < ENDPOINT_LEASE_DURATION(i)(1)) then endpoint_mask_next(i) <= '0'; end if; end if; @@ -2183,12 +2210,12 @@ begin for i in 0 to MAX_ENDPOINTS-1 loop -- data-in is Subscriber-Requested if (is_subscriber = '1') then - if (data_in_swapped > ENDPOINT_RELIABILITY(i)) then + if (unsigned(data_in_swapped) > unsigned(ENDPOINT_RELIABILITY(i))) then endpoint_mask_next(i) <= '0'; end if; -- data-in is Publisher-Offered else - if (data_in_swapped < ENDPOINT_RELIABILITY(i)) then + if (unsigned(data_in_swapped) < unsigned(ENDPOINT_RELIABILITY(i))) then endpoint_mask_next(i) <= '0'; end if; end if; @@ -2208,12 +2235,12 @@ begin for i in 0 to MAX_ENDPOINTS-1 loop -- data-in is Subscriber-Requested if (is_subscriber = '1') then - if (data_in_swapped > ENDPOINT_DESTINATION_ORDER(i)) then + if (unsigned(data_in_swapped) > unsigned(ENDPOINT_DESTINATION_ORDER(i))) then endpoint_mask_next(i) <= '0'; end if; -- data-in is Publisher-Offered else - if (data_in_swapped < ENDPOINT_DESTINATION_ORDER(i)) then + if (unsigned(data_in_swapped) < unsigned(ENDPOINT_DESTINATION_ORDER(i))) then endpoint_mask_next(i) <= '0'; end if; end if; @@ -2248,12 +2275,12 @@ begin for i in 0 to MAX_ENDPOINTS-1 loop -- data-in is Subscriber-Requested if (is_subscriber = '1') then - if (data_in_swapped > ENDPOINT_PRESENTATION(i)) then + if (unsigned(data_in_swapped) > unsigned(ENDPOINT_PRESENTATION(i))) then endpoint_mask_next(i) <= '0'; end if; -- data-in is Publisher-Offered else - if (data_in_swapped < ENDPOINT_PRESENTATION(i)) then + if (unsigned(data_in_swapped) < unsigned(ENDPOINT_PRESENTATION(i))) then endpoint_mask_next(i) <= '0'; end if; end if; @@ -2553,7 +2580,7 @@ begin cnt_next <= 0; participant_data_cnt_next <= 0; publisher_data_cnt_next <= 0; - subscriber_data_cnt <= 0; + subscriber_data_cnt_next <= 0; when others => null; end case; @@ -2600,7 +2627,7 @@ begin output_sig <= (others => '0'); -- Count when 6 => - output_sig <= count; + output_sig <= std_logic_vector(count); -- ACKNACK RTPS SUBMESSAGE (Subscription) -- RTPS Submessage Header when 7 => @@ -2622,7 +2649,7 @@ begin output_sig <= (others => '0'); -- Count when 13 => - output_sig <= count; + output_sig <= std_logic_vector(count); -- ACKNACK RTPS SUBMESSAGE (Message) -- RTPS Submessage Header when 14 => @@ -2644,7 +2671,7 @@ begin output_sig <= (others => '0'); -- Count when 20 => - output_sig <= count; + output_sig <= std_logic_vector(count); last_word_out <= '1'; -- DONE @@ -2683,7 +2710,7 @@ begin output_sig <= std_logic_vector(PUB_SEQUENCE_NR(1)); -- Count when 7 => - output_sig <= count; + output_sig <= std_logic_vector(count); -- HEARTBEAT RTPS SUBMESSAGE (Subscription) -- RTPS Submessage Header when 8 => @@ -2708,7 +2735,7 @@ begin output_sig <= std_logic_vector(SUB_SEQUENCE_NR(1)); -- Count when 15 => - output_sig <= count; + output_sig <= std_logic_vector(count); -- HEARTBEAT RTPS SUBMESSAGE (Message) -- RTPS Submessage Header when 16 => @@ -2733,7 +2760,7 @@ begin output_sig <= std_logic_vector(auto_live_seq_nr(1)); -- Count when 23 => - output_sig <= count; + output_sig <= std_logic_vector(count); -- If manual and automatic sequence numbers are not consecutive, we have only asserted the automatic liveliness if (live_gap_start /= auto_live_seq_nr) then stage_next <= SEND_MES_AUTO_LIVE; @@ -2837,7 +2864,7 @@ begin output_sig <= GUIDPREFIX(1); -- GUID Prefix 3/3 when 9 => - output_sig <= GUIDPREFIX(3); + output_sig <= GUIDPREFIX(2); -- Participant Message Kind when 10 => output_sig <= PARTICIPANT_MESSAGE_DATA_KIND_MANUAL_LIVELINESS_UPDATE; @@ -2932,7 +2959,7 @@ begin output_sig <= GUIDPREFIX(1); -- GUID Prefix 3/3 when 9 => - output_sig <= GUIDPREFIX(3); + output_sig <= GUIDPREFIX(2); -- Participant Message Kind when 10 => output_sig <= PARTICIPANT_MESSAGE_DATA_KIND_AUTOMATIC_LIVELINESS_UPDATE; @@ -3023,7 +3050,12 @@ begin mem_participant_data_next <= mem_participant_data; is_heartbeat_res_next <= is_heartbeat_res; endpoint_mask_array_next <= endpoint_mask_array; + max_participant_addr_next <= max_participant_addr; + max_endpoint_addr_next <= max_endpoint_addr; + reset_max_pointer_next <= reset_max_pointer; + mem_guidprefix_next <= mem_guidprefix; -- DEFAULT Unregistered + mem_write_data <= (others => '0'); mem_op_done <= '0'; mem_rd <= '0'; mem_wr <= '0'; @@ -3132,25 +3164,25 @@ begin -- No Match if (mem_read_data /= guid(0)) then -- Continue Search - mem_addr_next <= tmp; - mem_addr_base <= tmp; - mem_cnt_next <= 0; + mem_addr_next <= tmp; + mem_addr_base_next <= tmp; + mem_cnt_next <= 0; end if; when 2 => -- No Match if (mem_read_data /= guid(1)) then -- Continue Search - mem_addr_next <= tmp; - mem_addr_base <= tmp; - mem_cnt_next <= 0; + mem_addr_next <= tmp; + mem_addr_base_next <= tmp; + mem_cnt_next <= 0; end if; when 3 => -- No Match if (mem_read_data /= guid(2)) then -- Continue Search - mem_addr_next <= tmp; - mem_addr_base <= tmp; - mem_cnt_next <= 0; + mem_addr_next <= tmp; + mem_addr_base_next <= tmp; + mem_cnt_next <= 0; -- Match else -- Fetch Participant Data @@ -3185,36 +3217,36 @@ begin -- Ignore Entity ID if Orphan Search if (is_orphan_search = '0' and mem_read_data /= guid(3)) then -- Continue Search - mem_addr_next <= tmp; - mem_addr_base <= tmp; - mem_cnt_next <= 0; + mem_addr_next <= tmp; + mem_addr_base_next <= tmp; + mem_cnt_next <= 0; end if; -- GUID Prefix 1/3 when 2 => -- No Match if (mem_read_data /= guid(0)) then -- Continue Search - mem_addr_next <= tmp; - mem_addr_base <= tmp; - mem_cnt_next <= 0; + mem_addr_next <= tmp; + mem_addr_base_next <= tmp; + mem_cnt_next <= 0; end if; -- GUID Prefix 2/3 when 3 => -- No Match if (mem_read_data /= guid(1)) then -- Continue Search - mem_addr_next <= tmp; - mem_addr_base <= tmp; - mem_cnt_next <= 0; + mem_addr_next <= tmp; + mem_addr_base_next <= tmp; + mem_cnt_next <= 0; end if; -- GUID Prefix 3/3 when 4 => -- No Match if (mem_read_data /= guid(2)) then -- Continue Search - mem_addr_next <= tmp; - mem_addr_base <= tmp; - mem_cnt_next <= 0; + mem_addr_next <= tmp; + mem_addr_base_next <= tmp; + mem_cnt_next <= 0; -- Match Found else mem_stage_next <= GET_ENDPOINT_MASK; @@ -3349,10 +3381,10 @@ begin mem_write_data <= std_logic_vector(lease_duration(1)); -- Lease Deadline 1/2 when 10 => - mem_write_data <= std_logic_vector(lease_deadline(0)); + mem_write_data <= std_logic_vector(deadline(0)); -- Lease Deadline 2/2 when 11 => - mem_write_data <= std_logic_vector(lease_deadline(1)); + mem_write_data <= std_logic_vector(deadline(1)); -- Extra Flags when 12 => mem_write_data <= (others => '0'); @@ -3472,13 +3504,13 @@ begin end if; -- Lease Deadline 1/2 when 7 => - mem_write_data <= std_logic_vector(lease_deadline(0)); + mem_write_data <= std_logic_vector(deadline(0)); if (update_participant_flags(LEASE_DEADLINE_FLAG) = '1') then mem_wr <= '1'; end if; -- Lease Deadline 2/2 when 8 => - mem_write_data <= std_logic_vector(lease_deadline(1)); + mem_write_data <= std_logic_vector(deadline(1)); if (update_participant_flags(LEASE_DEADLINE_FLAG) = '1') then mem_wr <= '1'; end if; @@ -3501,13 +3533,13 @@ begin end if; -- ACKNACK DEADLINE 1/2 when 10 => - mem_write_data <= std_logic_vector(acknack_res_time(0)); + mem_write_data <= std_logic_vector(deadline(0)); if (update_participant_flags(ACKNACK_RES_TIME_FLAG) = '1') then mem_wr <= '1'; end if; -- ACKNACK DEADLINE 2/2 when 11 => - mem_write_data <= std_logic_vector(acknack_res_time(1)); + mem_write_data <= std_logic_vector(deadline(1)); if (update_participant_flags(ACKNACK_RES_TIME_FLAG) = '1') then mem_wr <= '1'; end if; @@ -3518,13 +3550,13 @@ begin end if; -- HEARTBEAT DEADLINE 1/2 when 12 => - mem_write_data <= std_logic_vector(heartbeat_res_time(0)); + mem_write_data <= std_logic_vector(deadline(0)); if (update_participant_flags(HEARTBEAT_RES_TIME_FLAG) = '1') then mem_wr <= '1'; end if; -- HEARTBEAT DEADLINE 2/2 when 13 => - mem_write_data <= std_logic_vector(heartbeat_res_time(1)); + mem_write_data <= std_logic_vector(deadline(1)); if (update_participant_flags(HEARTBEAT_RES_TIME_FLAG) = '1') then mem_wr <= '1'; end if; @@ -3613,15 +3645,15 @@ begin -- GUID Prefix 1/3 when 4 => mem_wr <= '1'; - mem_write_data <= GUIDPREFIX_UNKNOWN_ARRAY(0); + mem_write_data <= GUIDPREFIX_UNKNOWN(0); -- GUID Prefix 2/3 when 5 => mem_wr <= '1'; - mem_write_data <= GUIDPREFIX_UNKNOWN_ARRAY(1); + mem_write_data <= GUIDPREFIX_UNKNOWN(1); -- GUID Prefix 3/3 when 6 => mem_wr <= '1'; - mem_write_data <= GUIDPREFIX_UNKNOWN_ARRAY(2); + mem_write_data <= GUIDPREFIX_UNKNOWN(2); -- Reset MAX Participant Pointer mem_addr_base_next <= FIRST_PARTICIPANT_ADDRESS; mem_addr_next <= FIRST_PARTICIPANT_ADDRESS; @@ -3636,7 +3668,7 @@ begin mem_wr <= '1'; -- Overtwrite EntityID with ENTITYID_UNKNOWN to mark slot as empty - mem_write_data <= ENTITYID_UNKNOWN; + mem_write_data <= ENTITYID_UNKNOWN; -- Reset MAX Participant Pointer mem_addr_base_next <= FIRST_ENDPOINT_ADDRESS; mem_addr_next <= FIRST_ENDPOINT_ADDRESS; @@ -3682,7 +3714,7 @@ begin -- GUID Prefix 1/3 when 1 => -- Slot Occupied - if (mem_read_data /= GUIDPREFIX_UNKNOWN_ARRAY(0)) then + if (mem_read_data /= GUIDPREFIX_UNKNOWN(0)) then -- Continue Search mem_addr_next <= tmp; mem_addr_base_next <= tmp; @@ -3693,7 +3725,7 @@ begin -- GUID Prefix 2/3 when 2 => -- Slot Occupied - if (mem_read_data /= GUIDPREFIX_UNKNOWN_ARRAY(1)) then + if (mem_read_data /= GUIDPREFIX_UNKNOWN(1)) then -- Continue Search mem_addr_next <= tmp; mem_addr_base_next <= tmp; @@ -3704,7 +3736,7 @@ begin -- GUID Prefix 3/3 when 3 => -- Slot Occupied - if (mem_read_data /= GUIDPREFIX_UNKNOWN_ARRAY(2)) then + if (mem_read_data /= GUIDPREFIX_UNKNOWN(2)) then -- Continue Search mem_addr_next <= tmp; mem_addr_base_next <= tmp; @@ -3755,7 +3787,7 @@ begin else -- Extend Participant Memory Area -- NOTE: "max_endpoint_addr" points to the beginning of the last endpoint frame - max_endpoint_addr <= mem_addr_base; + max_endpoint_addr_next <= mem_addr_base; -- Populate Endpoint Slot mem_stage_next <= INSERT_ENDPOINT; mem_cnt_next <= 0; @@ -3805,7 +3837,7 @@ begin -- GUID Prefix 1/3 when 1 => -- Slot Occupied - if (mem_read_data /= GUIDPREFIX_UNKNOWN_ARRAY(0)) then + if (mem_read_data /= GUIDPREFIX_UNKNOWN(0)) then -- Get Participant Data mem_addr_next <= tmp2; addr_res_next <= mem_addr_base; @@ -3814,7 +3846,7 @@ begin end if; when 2 => -- Slot Occupied - if (mem_read_data /= GUIDPREFIX_UNKNOWN_ARRAY(1)) then + if (mem_read_data /= GUIDPREFIX_UNKNOWN(1)) then -- Get Participant Data mem_addr_next <= tmp2; addr_res_next <= mem_addr_base; @@ -3823,7 +3855,7 @@ begin end if; when 3 => -- Slot Occupied - if (mem_read_data /= GUIDPREFIX_UNKNOWN_ARRAY(2)) then + if (mem_read_data /= GUIDPREFIX_UNKNOWN(2)) then -- Get Participant Data mem_addr_next <= tmp2; addr_res_next <= mem_addr_base; @@ -3863,7 +3895,7 @@ begin -- GUID Prefix 1/3 when 1 => -- Slot Occupied - if (mem_read_data /= GUIDPREFIX_UNKNOWN_ARRAY(0)) then + if (mem_read_data /= GUIDPREFIX_UNKNOWN(0)) then -- Jumpt to Stale Check mem_addr_next <= tmp2; mem_cnt_next <= 4; @@ -3871,7 +3903,7 @@ begin -- GUID Prefix 2/3 when 2 => -- Slot Occupied - if (mem_read_data /= GUIDPREFIX_UNKNOWN_ARRAY(1)) then + if (mem_read_data /= GUIDPREFIX_UNKNOWN(1)) then -- Jumpt to Stale Check mem_addr_next <= tmp2; mem_cnt_next <= 4; @@ -3879,7 +3911,7 @@ begin -- GUID Prefix 3/3 when 3 => -- Slot Occupied - if (mem_read_data /= GUIDPREFIX_UNKNOWN_ARRAY(2)) then + if (mem_read_data /= GUIDPREFIX_UNKNOWN(2)) then -- Jumpt to Stale Check mem_addr_next <= tmp2; mem_cnt_next <= 4; @@ -3999,10 +4031,10 @@ begin if (reset = '1') then stage <= IDLE; return_stage <= IDLE; - opcode <= NOP; message_type <= NONE; string_content <= DOMAIN_TAG; mem_stage <= IDLE; + opcode <= (others => '0'); flags <= (others => '0'); src_port <= (others => '0'); src_addr <= (others => '0'); @@ -4010,6 +4042,7 @@ begin dest_entityid <= (others => '0'); parameter_end <= (others => '0'); string_length <= (others => '0'); + compare_length <= (others => '0'); endpoint_mask <= (others => '0'); endpoint_match <= (others => '0'); endpoint_unmatch <= (others => '0'); @@ -4018,16 +4051,22 @@ begin 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'); - update_participant_flags <= (others => '0'); + max_participant_addr <= (others => '0'); + max_endpoint_addr <= (others => '0'); + guid <= (others => (others => '0')); + mem_guidprefix <= (others => (others => '0')); endpoint_mask_array <= (others => (others => '0')); lease_duration <= (others => (others => '0')); deadline <= (others => (others => '0')); announcement_time <= (others => (others => '0')); heartbeat_time <= (others => (others => '0')); + seq_nr <= (others => (others => '0')); mem_seq_nr <= (others => (others => '0')); next_seq_nr <= (others => (others => '0')); first_seq_nr <= (others => (others => '0')); @@ -4051,13 +4090,15 @@ begin stale_check <= '0'; is_live_assert <= '0'; is_heartbeat_res <= '0'; + reset_max_pointer <= '0'; + last_word_in_latch <= '0'; else stage <= stage_next; return_stage <= return_stage_next; - opcode <= opcode_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; @@ -4065,6 +4106,7 @@ begin 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; endpoint_match <= endpoint_match_next; endpoint_unmatch <= endpoint_unmatch_next; @@ -4073,16 +4115,22 @@ begin 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; - update_participant_flags <= update_participant_flags_next; + max_participant_addr <= max_participant_addr_next; + max_endpoint_addr <= max_endpoint_addr_next; + guid <= guid_next; + mem_guidprefix <= mem_guidprefix_next; endpoint_mask_array <= endpoint_mask_array_next; lease_duration <= lease_duration_next; deadline <= deadline_next; announcement_time <= announcement_time_next; heartbeat_time <= heartbeat_time_next; + seq_nr <= seq_nr_next; mem_seq_nr <= mem_seq_nr_next; next_seq_nr <= next_seq_nr_next; first_seq_nr <= first_seq_nr_next; @@ -4106,6 +4154,8 @@ begin 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; end if; end if; end process; diff --git a/src/rtps_package.vhd b/src/rtps_package.vhd index 96ff24f..6b01f20 100644 --- a/src/rtps_package.vhd +++ b/src/rtps_package.vhd @@ -129,8 +129,11 @@ package rtps_package is constant DURATION_DELTA : DOUBLE_WORD_ARRAY := (to_unsigned(0,32),to_unsigned(429496730,32)); --100 ms - constant DEFAULT_PARTICIPANT_LEASE_DURATION : DOUBLE_WORD_ARRAY := (to_unsigned(100,32),to_unsigned(0,32)); + constant DEFAULT_PARTICIPANT_LEASE_DURATION : DOUBLE_WORD_ARRAY := (to_unsigned(100,32),to_unsigned(0,32)); -- 100s + constant PARTICIPANT_ANNOUNCEMENT_PERIOD : DOUBLE_WORD_ARRAY := (to_unsigned(30,32),to_unsigned(0,32)); -- 30s constant PARTICIPANT_LEASE_DURATION : DOUBLE_WORD_ARRAY := DEFAULT_PARTICIPANT_LEASE_DURATION; + constant MIN_ENDPOINT_LEASE_DURATION : DOUBLE_WORD_ARRAY; -- Deferred to package Body + -- NOTE: The buffer will not only store participants, but also endpoint data -- Used to determine the size of the builtin endpoint buffer @@ -193,7 +196,7 @@ package rtps_package is constant PID_HISTORY : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0040"; constant PID_RESOURCE_LIMITS : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0041"; constant PID_OWNERSHIP : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"001f"; - constant PID_OWNERSHIP_STRENGTH : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"001e"; + constant PID_OWNERSHIP_STRENGTH : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0006"; constant PID_PRESENTATION : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0021"; constant PID_PARTITION : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0029"; constant PID_TIME_BASED_FILTER : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0004"; @@ -357,7 +360,7 @@ package rtps_package is constant OPCODE_LIVELINESS_UPDATE : std_logic_vector(ENDPOINT_MATCH_OPCODE_WIDTH-1 downto 0) := x"55000002"; type USER_ENDPOINT_OUTPUT is array (0 to MAX_ENDPOINTS-1) of std_logic_vector(31 downto 0); - type ENDPOINT_BITMASK_ARRAY_TYPE is array (0 to ENDPOINT_BITMASK_SIZE-1) of std_logic_vector(31 downto 0); + type ENDPOINT_BITMASK_ARRAY_TYPE is array (0 to ENDPOINT_BITMASK_SIZE-1) of std_logic_vector(0 to 31); type WORD_ARRAY_TYPE is array (natural range <>) of std_logic_vector(31 downto 0); type OUTPUT_DATA_TYPE is record @@ -397,6 +400,8 @@ package rtps_package is function "-" (L,R: DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY; function "-" (L: DOUBLE_WORD_ARRAY; R: natural) return DOUBLE_WORD_ARRAY; function "-" (L: natural; R: DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY; + function min(L, R : DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY; + function max(L, R : DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY; end package; @@ -454,14 +459,37 @@ package body rtps_package is constant GUIDPREFIX : GUIDPREFIX_TYPE := gen_guidprefix; + function find_min_lease_duration return DOUBLE_WORD_ARRAY is + variable ret : DOUBLE_WORD_ARRAY := (others => (others => '0')); + begin + ret := DURATION_INFINITE; + -- Sanity Check + if (NUM_WRITERS = 0) then + return ret; + end if; + + -- Iterate through writers + for i in NUM_READERS to MAX_ENDPOINTS-1 loop + -- Do not consider "MANUAL_BY_TOPIC" Liveliness + if (ENDPOINT_LIVELINESS(i) /= MANUAL_BY_TOPIC_LIVELINESS_QOS) then + -- Find Minimum Lease Duration + if (ENDPOINT_LEASE_DURATION(i) < ret) then + ret := ENDPOINT_LEASE_DURATION(i); + end if; + end if; + end loop; + return ret; + end function; + + constant MIN_ENDPOINT_LEASE_DURATION : DOUBLE_WORD_ARRAY := find_min_lease_duration; + -- TODO: Use unconstraint string as input function convert_string (str : string(1 to 256)) return STRING_SLV_WORD_TYPE is variable ret : STRING_SLV_WORD_TYPE := (others => (others => '0')); begin ret := (others => (others => '0')); for i in 0 to ret'length-1 loop - ret(i) := std_logic_vector(to_unsigned(character'POS(str(1)), 8)) & std_logic_vector(to_unsigned(character'POS(str(2)), 8)) & std_logic_vector(to_unsigned(character'POS(str(3)), 8)) & std_logic_vector(to_unsigned(character'POS(str(4)), 8)); - --ret(i) := std_logic_vector(to_unsigned(character'POS(str((i*4)+1)), 8)) & std_logic_vector(to_unsigned(character'POS(str((i*4)+2)), 8)) & std_logic_vector(to_unsigned(character'POS(str((i*4)+3)), 8)) & std_logic_vector(to_unsigned(character'POS(str((i*4)+4)), 8)); + ret(i) := std_logic_vector(to_unsigned(character'POS(str((i*4)+1)), 8)) & std_logic_vector(to_unsigned(character'POS(str((i*4)+2)), 8)) & std_logic_vector(to_unsigned(character'POS(str((i*4)+3)), 8)) & std_logic_vector(to_unsigned(character'POS(str((i*4)+4)), 8)); end loop; return ret; end function; @@ -1105,4 +1133,26 @@ package body rtps_package is return convert_to_double_word(L - convert_from_double_word(R)); end function; + function min(L, R : DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY is + variable ret : DOUBLE_WORD_ARRAY; + begin + if L < R then + ret := L; + else + ret := R; + end if; + return ret; + end function; + + function max(L, R : DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY is + variable ret : DOUBLE_WORD_ARRAY; + begin + if L > R then + ret := L; + else + ret := R; + end if; + return ret; + end function; + end package body; diff --git a/src/single_port_ram.vhd b/src/single_port_ram.vhd index 7e98255..81aabf1 100644 --- a/src/single_port_ram.vhd +++ b/src/single_port_ram.vhd @@ -2,15 +2,14 @@ library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; -Library xpm; -use xpm.vcomponents.all; +LIBRARY altera_mf; +USE altera_mf.altera_mf_components.all; entity single_port_ram is generic ( - ADDR_WIDTH : integer := 8; - DATA_WIDTH : integer := 12; - MEMORY_SIZE : integer := DATA_WIDTH*(2**ADDR_WIDTH) - + ADDR_WIDTH : natural := 8; + DATA_WIDTH : natural := 12; + MEMORY_DEPTH : natural := 256 ); port ( clk : in std_logic; @@ -26,41 +25,30 @@ architecture arch of single_port_ram is begin - xpm_memory_spram_inst : xpm_memory_spram + altsyncram_component : altsyncram generic map ( - ADDR_WIDTH_A => ADDR_WIDTH, - AUTO_SLEEP_TIME => 0, - BYTE_WRITE_WIDTH_A => DATA_WIDTH, - ECC_MODE => "no_ecc", - MEMORY_INIT_FILE => "none", - MEMORY_INIT_PARAM => "0", - MEMORY_OPTIMIZATION => "true", - MEMORY_PRIMITIVE => "auto", - MEMORY_SIZE => MEMORY_SIZE, - MESSAGE_CONTROL => 0, - READ_DATA_WIDTH_A => DATA_WIDTH, - READ_LATENCY_A => 1, - READ_RESET_VALUE_A => "0", - RST_MODE_A => "SYNC", - USE_MEM_INIT => 1, - WAKEUP_TIME => "disable_sleep", - WRITE_DATA_WIDTH_A => DATA_WIDTH, - WRITE_MODE_A => "read_first" + clock_enable_input_a => "BYPASS", + clock_enable_output_a => "BYPASS", + intended_device_family => "Cyclone V", + lpm_hint => "ENABLE_RUNTIME_MOD=NO", + lpm_type => "altsyncram", + numwords_a => MEMORY_DEPTH, + operation_mode => "SINGLE_PORT", + outdata_aclr_a => "NONE", + outdata_reg_a => "UNREGISTERED", + power_up_uninitialized => "FALSE", + read_during_write_mode_port_a => "DONT_CARE", + widthad_a => ADDR_WIDTH, + width_a => DATA_WIDTH, + width_byteena_a => 1 ) port map ( - dbiterra => open, - douta => rd_data, - sbiterra => open, - addra => addr, - clka => clk, - dina => wr_data, - ena => (ren or wen), - injectdbiterra => '0', - injectsbiterra => '0', - regcea => '1', - rsta => '0', - sleep => '0', - wea => (others => wen) --1-bit Vector + address_a => addr, + clock0 => clk, + data_a => wr_data, + rden_a => ren, + wren_a => wen, + q_a => rd_data ); end architecture; diff --git a/syn/DE10-Nano/top.qsf b/syn/DE10-Nano/top.qsf index 092a3b9..58e194d 100644 --- a/syn/DE10-Nano/top.qsf +++ b/syn/DE10-Nano/top.qsf @@ -38,7 +38,7 @@ set_global_assignment -name FAMILY "Cyclone V" set_global_assignment -name DEVICE 5CSEBA6U23I7 -set_global_assignment -name TOP_LEVEL_ENTITY test +set_global_assignment -name TOP_LEVEL_ENTITY rtps_builtin_endpoint set_global_assignment -name ORIGINAL_QUARTUS_VERSION 18.1.0 set_global_assignment -name PROJECT_CREATION_TIME_DATE "12:05:11 MAY 29, 2020" set_global_assignment -name LAST_QUARTUS_VERSION "18.1.0 Lite Edition" @@ -51,6 +51,8 @@ set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top +set_global_assignment -name VHDL_FILE ../../src/single_port_ram.vhd -hdl_version VHDL_2008 +set_global_assignment -name VHDL_FILE ../../src/rtps_builtin_endpoint.vhd -hdl_version VHDL_2008 set_global_assignment -name VHDL_FILE ../../src/rtps_package.vhd -hdl_version VHDL_2008 set_global_assignment -name VHDL_FILE ../../src/test_package.vhd -hdl_version VHDL_2008 set_global_assignment -name VHDL_FILE ../../src/test.vhd -hdl_version VHDL_2008