diff --git a/src/dds_endpoint.vhd b/src/dds_reader.vhd similarity index 92% rename from src/dds_endpoint.vhd rename to src/dds_reader.vhd index 9181d5a..ea39838 100644 --- a/src/dds_endpoint.vhd +++ b/src/dds_reader.vhd @@ -4,7 +4,7 @@ use ieee.numeric_std.all; -- TODO: Check if sample_cnt is always maintained (also with MAX_SAMPLES_PER_INSTANCE = LENGTH_UNLIMITED) -entity history_cache is +entity dds_reader is generic ( TIME_BASED_FILTER_QOS : DURATION_TYPE := DEFAULT_TIME_BASED_FILTER_QOS; MAX_INSTANCES : natural := DEFAULT_MAX_INSTANCES; @@ -17,32 +17,38 @@ entity history_cache is ORDERED_ACCESS : boolean := DEFAULT_ORDERED_ACCESS; ); port ( - clk : in std_logic; - reset : in std_logic; + -- SYSTEM + clk : in std_logic; + reset : in std_logic; + time : in TIME_TYPE; - start_rtps : in std_logic; - opcode_rtps : in HISTORY_CACHE_OPCODE_TYPE; - res_rtps : out HISTORY_CACHE_RESPOSNE_TYPE; - data_in_rtps : in std_logic_vector(WORD_WIDTH-1 downto 0); - valid_in_rtps : in std_logic; - ready_in_rtps : out std_logic; - last_word_in_rtps : in std_logic; + -- FROM RTPS ENDPOINT + start_rtps : in std_logic; + opcode_rtps : in HISTORY_CACHE_OPCODE_TYPE; + res_rtps : out HISTORY_CACHE_RESPOSNE_TYPE; + data_in_rtps : in std_logic_vector(WORD_WIDTH-1 downto 0); + valid_in_rtps : in std_logic; + ready_in_rtps : out std_logic; + last_word_in_rtps : in std_logic; - -- - start_dds : in std_logic; - ack_dds : out std_logic; - opcode_dds : in HISTORY_CACHE_OPCODE_TYPE; - instance_state_in : in std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); - view_state_in : in std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0); - sample_state_in : in std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0); - instance_handle_in : in INSTANCE_HANDLE_TYPE; - max_samples_in : in std_logic_vector(MAX_SAMPLES_WIDTH-1 downto 0); - next_sample : in std_logic; - get_data : in std_logic; - done_dds : out std_logic; - return_code_dds : out std_logic_vector(RETURN_CODE_WIDTH-1 downto 0); - - -- Sample Info + -- TO USER ENTITY + start_dds : in std_logic; + ack_dds : out std_logic; + opcode_dds : in HISTORY_CACHE_OPCODE_TYPE; + instance_state_in : in std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); + view_state_in : in std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0); + sample_state_in : in std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0); + instance_handle_in : in INSTANCE_HANDLE_TYPE; + max_samples_in : in std_logic_vector(MAX_SAMPLES_WIDTH-1 downto 0); + next_sample : in std_logic; + get_data : in std_logic; + done_dds : out std_logic; + return_code_dds : out std_logic_vector(RETURN_CODE_WIDTH-1 downto 0); + ready_out_dds : in std_logic; + valid_out_dds : out std_logic; + data_out_dds : out std_logic_vector(WORD_WIDTH-1 downto 0); + last_word_out_dds : out std_logic; + -- SAMPLE INFO si_sample_state : out std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0); si_view_state : out std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0); si_instance_state : out std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); @@ -56,19 +62,15 @@ entity history_cache is si_absolute_generation_count : out std_logic_vector(ABSOLUTE_GENERATION_COUNT_WIDTH-1 downto 0); si_valid_data : out std_logic; si_valid : out std_logic; - - ready_out_dds : in std_logic; - valid_out_dds : out std_logic; - data_out_dds : out std_logic_vector(WORD_WIDTH-1 downto 0); - last_word_out_dds : out std_logic; - + -- COMMUNICATION STATUS status : out std_logic_vector(STATUS_KIND_WIDTH-1 downto 0); ); end entity; -architecture arch of history_cache is +architecture arch of dds_reader is --*****CONSTANT DECLARATION***** + -- *SAMPLE MEMORY* -- Sample Info Memory Size in 4-Byte Words constant SAMPLE_MEMORY_SIZE : natural := TODO; -- Sample Info Memory Address Width @@ -78,6 +80,7 @@ architecture arch of history_cache is -- Highest Sample Info Frame Address constant MAX_SAMPLE_ADDRESS : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := SAMPLE_MEMORY_MAX_ADDRESS - SAMPLE_INFO_FRAME_SIZE + 1; + -- *PAYLOAD MEMORY* -- Payload Memory Size in 4-Byte Words constant PAYLOAD_MEMORY_SIZE : natural := TODO; -- Payload Memory Address Width @@ -87,6 +90,7 @@ architecture arch of history_cache is -- Highest Payload Frame Address constant MAX_PAYLOAD_ADDRESS : unsigned(PAYLOAD_MEMORY_ADDR_WIDTH-1 downto 0) := PAYLOAD_MEMORY_MAX_ADDRESS - PAYLOAD_FRAME_SIZE + 1; + -- *INSTANCE MEMORY* -- Instance Memory Size in 4-Byte Words constant INSTANCE_MEMORY_SIZE : natural := TODO; -- Instance Memory Address Width @@ -98,17 +102,8 @@ architecture arch of history_cache is -- Address pointing to the beginning of the first Instance Data Frame constant FIRST_INSTANCE_ADDRESS : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); - -- *INSTANCE MEMORY FRAME FIELD FLAGS* - constant IMF_FLAG_WIDTH : natural := 7; - constant IMF_KEY_HASH_FLAG : std_logic_vector(0 to IMF_FLAG_WIDTH-1) := (0 => 1, others => '0'); - constant IMF_STATUS_FLAG : std_logic_vector(0 to IMF_FLAG_WIDTH-1) := (1 => 1, others => '0'); - constant IMF_SAMPLE_CNT_FLAG : std_logic_vector(0 to IMF_FLAG_WIDTH-1) := (2 => 1, others => '0'); - constant IMF_DISPOSED_CNT_FLAG : std_logic_vector(0 to IMF_FLAG_WIDTH-1) := (3 => 1, others => '0'); - constant IMF_NO_WRITERS_CNT_FLAG : std_logic_vector(0 to IMF_FLAG_WIDTH-1) := (4 => 1, others => '0'); - constant IMF_IGNORE_DEADLINE_FLAG : std_logic_vector(0 to IMF_FLAG_WIDTH-1) := (5 => 1, others => '0'); - constant IMF_WRITER_BITMAP_FLAG : std_logic_vector(0 to IMF_FLAG_WIDTH-1) := (6 => 1, others => '0'); - -- *SAMPLE MEMORY FRAME FORMAT* + -- 4-Byte Word Offsets to Beginning of Respective Fields in the Endpoint Memory Frame constant SMF_STATUS_INFO_OFFSET : natural := 0; constant SMF_TIMESTAMP_OFFSET : natural := 1; constant SMF_LIFESPAN_DEADLINE_OFFSET : natural := 3; @@ -118,10 +113,14 @@ architecture arch of history_cache is constant SMF_NO_WRITERS_GEN_CNT_OFFSET : natural := 8; constant SMF_PREV_ADDR_OFFSET : natural := 9; constant SMF_NEXT_ADDR_OFFSET : natural := 10; + -- *PAYLOAD MEMORY FRAME FORMAT* + -- 4-Byte Word Offsets to Beginning of Respective Fields in the Endpoint Memory Frame constant PMF_NEXT_ADDR_OFFSET : natural := 0; constant PMF_PAYLOAD_OFFSET : natural := 1; + -- *INSTANCE MEMORY FRAME OFFSET* + -- 4-Byte Word Offsets to Beginning of Respective Fields in the Endpoint Memory Frame constant IMF_NEXT_ADDR_OFFSET : natural := 0; constant IMF_KEY_HASH_OFFSET : natural := 1; constant IMF_STATUS_INFO_OFFSET : natural := 5; @@ -131,11 +130,40 @@ architecture arch of history_cache is constant IMF_IGNORE_DEADLINE_OFFSET : natural := 9; constant IMF_WRITER_BITMAP_OFFSET : natural := IMF_IGNORE_DEADLINE_OFFSET+2 when (TIME_BASED_FILTER_QOS /= DURATION_ZERO) else IMF_NO_WRITERS_GEN_CNT_OFFSET+1; + -- *INSTANCE MEMORY FRAME FORMAT FLAGS* + -- Flags mapping to the respective Endpoint Memory Frame Fields + constant IMF_FLAG_WIDTH : natural := 7; + constant IMF_KEY_HASH_FLAG : std_logic_vector(0 to IMF_FLAG_WIDTH-1) := (0 => 1, others => '0'); + constant IMF_STATUS_FLAG : std_logic_vector(0 to IMF_FLAG_WIDTH-1) := (1 => 1, others => '0'); + constant IMF_SAMPLE_CNT_FLAG : std_logic_vector(0 to IMF_FLAG_WIDTH-1) := (2 => 1, others => '0'); + constant IMF_DISPOSED_CNT_FLAG : std_logic_vector(0 to IMF_FLAG_WIDTH-1) := (3 => 1, others => '0'); + constant IMF_NO_WRITERS_CNT_FLAG : std_logic_vector(0 to IMF_FLAG_WIDTH-1) := (4 => 1, others => '0'); + constant IMF_IGNORE_DEADLINE_FLAG : std_logic_vector(0 to IMF_FLAG_WIDTH-1) := (5 => 1, others => '0'); + constant IMF_WRITER_BITMAP_FLAG : std_logic_vector(0 to IMF_FLAG_WIDTH-1) := (6 => 1, others => '0'); + --*****TYPE DECLARATION***** -- FSM states. Explained below in detail - type STAGE_TYPE is (IDLE, TODO); - type INST_STAGE_TYPE is (IDLE, TODO); - type INSTANCE_OPCODE_TYPE is (NOP, TODO); + type STAGE_TYPE is (IDLE, UNKNOWN_OPERATION, ADD_SAMPLE_INFO, ADD_PAYLOAD_ADDRESS, ADD_PAYLOAD, NEXT_PAYLOAD_SLOT, ZERO_PAYLOAD, GET_KEY_HASH, INITIATE_INSTANCE_SEARCH, + FILTER_STAGE, UPDATE_INSTANCE, FINALIZE_PAYLOAD, PRE_SAMPLE_FINALIZE, FIND_POS, FIX_POINTERS, FINALIZE_SAMPLE, GET_OLDEST_SAMPLE_INSTANCE, FIND_OLDEST_INST_SAMPLE, + REMOVE_SAMPLE, POST_SAMPLE_REMOVE, SKIP_ADD_REJECT, SKIP_ADD_DROP, REMOVE_WRITER, REMOVE_STALE_INSTANCE, GET_NEXT_SAMPLE, PRE_CALCULATE, FINALIZE_SAMPLE_INFO, + GET_PAYLOAD, FIND_NEXT_INSTANCE, CHECK_INSTANCE, CHECK_LIFESPAN, GET_SAMPLE_REJECTED_STATUS, GET_REQUESTED_DEADLINE_MISSED_STATUS, CHECK_DEADLINE); + -- Instance Memory FSM states. Explained below in detail + type INST_STAGE_TYPE is (IDLE, SEARCH_INSTANCE_HASH, SEARCH_INSTANCE_ADDR, GET_NEXT_INSTANCE, GET_INSTANCE_DATA, FIND_POS, INSERT_INSTANCE, UPDATE_INSTANCE, + REMOVE_INSTANCE, UNMARK_INTANCES); + -- *Instance Memory Opcodes* + -- OPCODE DESCRIPTION + -- SEARCH_INSTANCE_HASH Search Instance based on Key Hash pointed by key_hash. + -- SEARCH_INSTANCE_ADDR Search Instance based on Instance Pointer pointed by inst_addr_update. [This is needed to mark the previous Instance for Instance Removal] + -- INSERT_INSTANCE Insert Instance to memory. The Instance is inserted in Key Hash Numerical Order. + -- UPDATE_INSTANCE Update Instance Data pointed by inst_addr_base. (inst_mem_fields specifies which Fields to update) + -- GET_FIRST_INSTANCE Get Instance Data of first Instance (Instance with smallest Key Hash Numerical Order). (inst_mem_fields specifies which Fields to get) + -- GET_NEXT_INSTANCE Get Instance Data of next Instance (from the Instance pointed by inst_addr_base) (inst_mem_fields specifies which Fields to get) + -- REMOVE_INSTANCE Remove Instance pointed by inst_addr_base + -- GET_INSTANCE Get Data of Instance pointed by inst_addr_update. (inst_mem_fields specifies which Fields to get) + -- UNMARK_INSTANCES Reset the MARK_FLAG of all stored Instances + type INSTANCE_OPCODE_TYPE is (SEARCH_INSTANCE_HASH, SEARCH_INSTANCE_ADDR, INSERT_INSTANCE, UPDATE_INSTANCE, GET_FIRST_INSTANCE, GET_NEXT_INSTANCE, REMOVE_INSTANCE, + GET_INSTANCE, UNMARK_INSTANCES); + -- Record of Instance Data type INSTANCE_DATA_TYPE is record key_hash : KEY_HASH_TYPE; status_info : std_logic_vector(WORD_WIDTH-1 downto 0); @@ -145,6 +173,7 @@ architecture arch of history_cache is ignore_deadline : TIME_TYPE; writer_bitmap : ENDPOINT_BITMAP_ARRAY_TYPE; end record; + -- Zero initialized Endpoint Data constant ZERO_INSTANCE_DATA : INSTANCE_DATA_TYPE := ( key_hash => (others => (others => '0')), status_info => (others => '0'), @@ -154,6 +183,7 @@ architecture arch of history_cache is ignore_deadline => TIME_INVALID, writer_bitmap => (others => (others => '0')) ); + -- Instance Data Latch used as temporal cache by Instance Memory FSM type INST_LATCH_DATA_TYPE is record key_hash : KEY_HASH_TYPE; status_info : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); @@ -164,6 +194,7 @@ architecture arch of history_cache is field_flags : std_logic_vector(0 to IMF_FLAG_WIDTH-1); addr : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0); end record; + -- Zero initialized Instance Data Latch constant ZERO_INST_LATCH_DATA : INST_LATCH_DATA_TYPE := ( key_hash => (others => (others => '0')), status_info => (others => '0'), @@ -176,6 +207,7 @@ architecture arch of history_cache is ); --*****SIGNAL DECLARATION + -- *SAMPLE MEMORY CONNECTION SIGNALS* signal sample_addr : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); signal sample_read : std_logic := '0'; signal sample_read_data, sample_write_data : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0'); @@ -183,6 +215,7 @@ architecture arch of history_cache is signal sample_ready_out, sample_valid_out : std_logic := '0'; signal sample_abort_read : std_logic := '0'; + -- *PAYLOAD MEMORY CONNECTION SIGNALS* signal payload_addr : unsigned(PAYLOAD_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); signal payload_read : std_logic := '0'; signal payload_read_data, payload_write_data : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0'); @@ -190,6 +223,7 @@ architecture arch of history_cache is signal payload_ready_out, payload_valid_out : std_logic := '0'; signal payload_abort_read : std_logic := '0'; + -- *INSTANCE MEMORY CONNECTION SIGNALS* signal inst_addr : unsigned(PAYLOAD_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); signal inst_read : std_logic := '0'; signal inst_read_data, inst_write_data : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0'); @@ -197,60 +231,132 @@ architecture arch of history_cache is signal inst_ready_out, inst_valid_out : std_logic := '0'; signal inst_abort_read : std_logic := '0'; - + -- *KEY HASH GENERATOR CONNECTION SIGNALS* signal khg_valid_in, khg_ready_in, khg_last_word_in, khg_valid_out, khg_ready_out, khg_last_word_out : std_logic := '0'; signal khg_data_in, khg_data_out : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0'); + signal khg_abort : std_logic := '0'; + -- *MAIN PROCESS* + -- FSM state signal stage, stage_next : STAGE_TYPE := IDLE; + -- General Purpose Counter signal cnt, cnt_next : natural range TODO := 0; - signal empty_sample_list_head, empty_sample_list_head_next : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); - signal empty_sample_list_tail, empty_sample_list_tail_next : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); - signal empty_payload_list_head, empty_payload_list_head_next : unsigned(PAYLOAD_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); - signal oldest_sample, oldest_sample_next : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); - signal newest_sample, newest_sample_next : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); - signal first_unread_sample, first_unread_sample_next : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); - signal payload_addr_latch_1, payload_addr_latch_1_next : unsigned(PAYLOAD_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); - signal payload_addr_latch_2, payload_addr_latch_2_next : unsigned(PAYLOAD_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); - signal sample_addr_latch_1, sample_addr_latch_1_next : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); - signal sample_addr_latch_2, sample_addr_latch_2_next : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); - signal sample_addr_latch_3, sample_addr_latch_3_next : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); - signal sample_addr_latch_4, sample_addr_latch_4_next : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); - signal ts_latch, ts_latch_next : TIME_TYPE := TIME_INVALID; - signal last_read_ts, last_read_ts_next : TIME_TYPE := TIME_INVALID; - signal long_latch, long_latch_next : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); - signal payload_mem_full, payload_mem_full_next : std_logic := '0'; - signal sample_mem_full, sample_mem_full_next : std_logic := '0'; - signal writer_pos, writer_pos_next : natural range TODO := 0; - signal writer_bitmap : ENDPOINT_BITMAP_ARRAY_TYPE; - signal status_info_update : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); - signal key_hash, key_hash_next : KEY_HASH_TYPE := (others => (others => '0')); - signal remove_oldest_sample, remove_oldest_sample_next : std_logic := '0'; - signal remove_oldest_inst_sample, remove_oldest_inst_sample_next : std_logic := '0'; - signal added_new_instance, added_new_instance_next : std_logic := '0'; - signal sample_status_info, sample_status_info_next : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); - signal gen_cnt : unsigned(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); - signal deadline : TIME_TYPE := TIME_INVALID; - signal inst_addr_update : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); - signal sample_cnt : unsigned(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); + -- Counter used to read/write Payload Fames signal cnt2, cnt2_next : natural range 0 to PAYLOAD_FRAME_SIZE := 0; + -- Counter used to read/write Payload Fames signal cnt3, cnt3_next : natural range 0 to PAYLOAD_FRAME_SIZE := 0; - - signal inst_op_start : std_logic := '0'; - signal inst_op_done : std_logic := '0'; - signal inst_opcode : INSTANCE_OPCODE_TYPE := NOP; - signal inst_stage, inst_stage_next : INST_STAGE_TYPE := IDLE; - signal inst_addr_base, inst_addr_base_next : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); - signal inst_next_addr_base, inst_next_addr_base_next : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); - signal inst_prev_addr_base, inst_prev_addr_base_next : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); - signal inst_empty_head, inst_empty_head_next : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); - signal inst_occupied_head, inst_occupied_head_next : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); - signal inst_latch_data, inst_latch_data_next : INST_LATCH_DATA_TYPE := ZERO_INST_LATCH_DATA; + -- Head of Empty Sample List + signal empty_sample_list_head, empty_sample_list_head_next : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); + -- Tail of Empty Sample List + signal empty_sample_list_tail, empty_sample_list_tail_next : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); + -- Head of Empty Payload List + signal empty_payload_list_head, empty_payload_list_head_next : unsigned(PAYLOAD_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); + -- Oldest Sample (Head of Occupied Sample List) + signal oldest_sample, oldest_sample_next : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); + -- Newest Sample (Tail of Occupied Sample List) + signal newest_sample, newest_sample_next : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); + -- Highest Timestamp of all READ Samples + signal last_read_ts, last_read_ts_next : TIME_TYPE := TIME_INVALID; + -- Denotes if the oldest Sample should be removed + signal remove_oldest_sample, remove_oldest_sample_next : std_logic := '0'; + -- Denotes if the oldest sample of the Instance with 'key_hash' should be removed + signal remove_oldest_inst_sample, remove_oldest_inst_sample_next : std_logic := '0'; + -- Denotes if a new Instance was inserted in the Instance Memory + signal added_new_instance, added_new_instance_next : std_logic := '0'; + -- Remote Writer Endpoint Bitmap Position + signal writer_pos, writer_pos_next : natural range TODO := 0; + -- Key Hash Latch + signal key_hash, key_hash_next : KEY_HASH_TYPE := (others => (others => '0')); + -- Source Timestamp Latch + signal ts_latch, ts_latch_next : TIME_TYPE := TIME_INVALID; + -- Sample Status Info Latch + signal sample_status_info, sample_status_info_next : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); + -- General Purpose Payload Pointer + signal payload_addr_latch_1, payload_addr_latch_1_next : unsigned(PAYLOAD_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); + -- General Purpose Payload Pointer + signal payload_addr_latch_2, payload_addr_latch_2_next : unsigned(PAYLOAD_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); + -- General Purpose Sample Pointer + signal sample_addr_latch_1, sample_addr_latch_1_next : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); + -- General Purpose Sample Pointer + signal sample_addr_latch_2, sample_addr_latch_2_next : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); + -- General Purpose Sample Pointer + signal sample_addr_latch_3, sample_addr_latch_3_next : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); + -- General Purpose Sample Pointer + signal sample_addr_latch_4, sample_addr_latch_4_next : unsigned(SAMPLE_MEMORY_ADDR_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'); + -- Signal used to pass Writer Bitmaps to Instance Memory Process + signal writer_bitmap : ENDPOINT_BITMAP_ARRAY_TYPE; + -- Signal used to pass Sample Status Infos to Instance Memory Process + signal status_info_update : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); + -- Signal used to pass Generation Counters to the Instance Memory Process + signal gen_cnt : unsigned(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); + -- Signal used to pass TIMEs to the Instance Memory Process + signal deadline : TIME_TYPE := TIME_INVALID; + -- Signal containing the relevant Instance Memory Frame Fields of the Instance Memory Operation signal inst_mem_fields : std_logic_vector(0 to IMF_FLAG_WIDTH-1) := (others => '0'); - signal inst_cnt, inst_cnt_next : natural range TODO := 0; - signal inst_cnt2, inst_cnt2_next : natural 0 to ENDPOINT_BITMAP_ARRAY_TYPE'length := 0; - signal inst_mem_full, inst_mem_full_next : std_logic := '0'; - signal inst_long_latch, inst_long_latch_next : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); + -- Signal used to pass Instance Pointers to the Instance Memory Process + signal inst_addr_update : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); + -- Signal used to pass Sample Counts to the Instance Memory Process + signal sample_cnt : unsigned(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); + -- Signals start of Instance Memory Operation + signal inst_op_start : std_logic := '0'; + -- Opcode of Instance Memory Operation (Valid only when inst_op_start is high) + signal inst_opcode : INSTANCE_OPCODE_TYPE := NOP; + -- Signals the end of an Instance Memory Operation + signal inst_op_done : std_logic := '0'; + -- Time of next Sample Lifespan Check + signal lifespan_time, lifespan_time_next : TIME_TYPE := TIME_ZERO; + -- Signifies if a Lifespan Check is in progress + signal is_lifespan_check, is_lifespan_check_next : std_logic := '0'; + -- Sample State Latch + signal sample_state, sample_state_next : std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0) := (others => '0'); + -- View State Latch + signal view_state, view_state_next : std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0) := (others => '0'); + -- Instance State Latch + signal instance_state, instance_state_next : std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0) := (others => '0'); + -- Instance Handle Latch + signal instance_handle, instance_handle_next : INSTANCE_HANDLE_TYPE := (others => '0'); + -- Max Samples Latch + signal max_samples, max_samples_next : unsigned(MAX_SAMPLES_WIDTH-1 downto 0) := (others => '0'); + -- General Purpose Instance Pointer + signal inst_addr_latch, inst_addr_latch_next : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); + -- Denotes the current length of the Collection + signal collection_cnt, collection_cnt_next : unsigned(MAX_SAMPLES_WIDTH-1 downto 0) := (others => '0'); + -- Denotes the current pre-calculated length of the Collection + signal collection_cnt_max, collection_cnt_max_next : unsigned(MAX_SAMPLES_WIDTH-1 downto 0) := (others => '0'); + -- Denotes the Generation Rank (For a collection of length collection_cnt_max) + signal collection_generation_rank, collection_generation_rank_next : unsigned(GENERATION_RANK_WIDTH-1 downto 0) := (others => '0'); + -- Number of NOT_ALIVE->ALIVE Transitions during reception of selected Sample + signal cur_generation_rank, cur_generation_rank_next : unsigned(GENERATION_RANK_WIDTH-1 downto 0) := (others => '0'); + -- Denotes if a TAKE operation is in progress + signal is_take, is_take_next : std_logic := '0'; + -- Denotes if the READ/TAKE operation applies to a single Instance + signal single_instance, single_instance_next : std_logic := '0'; + -- NOTE: We use this signal to prevent the costly Instance Marking in the case that we only need to ouptput next sample. + -- I.e. make READ_NEXT/TAKE_NEXT the fastest commands. + -- Denotes if the READ/TAKE operation applies only to a single sample + signal single_sample, single_sample_next : std_logic := '0'; + -- Denotes if the marks on Instances should be reset + signal unmark_instances, unmark_instances_next : std_logic := '0'; + -- Denotes if the READ/TAKE operation does not apply to a specific Instance + signal dynamic_next_instance, dynamic_next_instance_next : std_logic := '0'; + -- *COMMUNICATION STATUS* + signal status_sig, status_sig_next : std_logic_vector(STATUS_KIND_WIDTH-1 downto 0) := (others => '0'); + -- SAMPLE REJECT STATUS + signal sample_rej_cnt, sample_rej_cnt_next : unsigned(SAMPLE_REJECTED_STATUS_COUNT_WIDTH-1 downto 0) := (others => '0'); + signal sample_rej_cnt_change, sample_rej_cnt_change_next : unsigned(SAMPLE_REJECTED_STATUS_COUNT_WIDTH-1 downto 0) := (others => '0'); + signal sample_rej_last_reason, sample_rej_last_reason_next : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := (others =>'0'); + signal sample_rej_last_inst, sample_rej_last_inst_next : INSTANCE_HANDLE_TYPE := (others => (others => '0')); + -- REQUESTED DEADLINE MISSED STATUS + -- Time of next Deadline Miss Check + signal deadline_time, deadline_time_next : TIME_TYPE := TIME_ZERO; + signal deadline_miss_cnt, deadline_miss_cnt_next : unsigned(REQUESTED_DEADLINE_MISSED_STATUS_COUNT_WIDTH-1 downto 0) := (others => '0'); + signal deadline_miss_cnt_change, deadline_miss_cnt_change_next : unsigned(REQUESTED_DEADLINE_MISSED_STATUS_COUNT_WIDTH-1 downto 0) := (others => '0'); + signal deadline_miss_last_inst, deadline_miss_last_inst_next : INSTANCE_HANDLE_TYPE := (others => (others => '0')); + + -- *SAMPLE INFO* signal si_sample_state_sig, si_sample_state_sig_next : std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0) := (others => '0'); signal si_view_state_sig, si_view_state_sig_next : std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0) := (others => '0'); signal si_instance_state_sig, si_instance_state_sig_next : std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0) := (others => '0'); @@ -265,38 +371,29 @@ architecture arch of history_cache is signal si_valid_data_sig, si_valid_data_sig_next : std_logic := '0'; signal si_valid_sig, si_valid_sig_next : std_logic := '0'; - signal sample_state, sample_state_next : std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0) := (others => '0'); - signal view_state, view_state_next : std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0) := (others => '0'); - signal instance_state, instance_state_next : std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0) := (others => '0'); - signal instance_handle, instance_handle_next : INSTANCE_HANDLE_TYPE := (others => '0'); - signal max_samples, max_samples_next : unsigned(MAX_SAMPLES_WIDTH-1 downto 0) := (others => '0'); - signal inst_addr_latch, inst_addr_latch_next : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); - signal collection_cnt, collection_cnt_next : unsigned(MAX_SAMPLES_WIDTH-1 downto 0) := (others => '0'); - signal collection_cnt_max, collection_cnt_max_next : unsigned(MAX_SAMPLES_WIDTH-1 downto 0) := (others => '0'); - signal collection_generation_rank, collection_generation_rank_next : unsigned(GENERATION_RANK_WIDTH-1 downto 0) := (others => '0'); - signal cur_generation_rank, cur_generation_rank_next : unsigned(GENERATION_RANK_WIDTH-1 downto 0) := (others => '0'); - signal is_take, is_take_next : std_logic := '0'; - signal has_latched, has_lacthed_next : std_logic := '0'; - signal single_instance, single_instance_next : std_logic := '0'; - -- NOTE: We use this signal to prevent the costly Instance Marking in the case that we only need to ouptput next sample. - -- I.e. make READ_NEXT/TAKE_NEXT the fastest commands. - signal single_sample, single_sample_next : std_logic := '0'; - signal unmark_instances, unmark_instances_next : std_logic := '0'; - signal dynamic_next_instance, dynamic_next_instance_next : std_logic := '0'; - signal inst_data_variant : INSTANCE_DATA_VARIANT_TYPE := VAR_1; - signal abort_khg : std_logic := '0'; - signal lifespan_time, lifespan_time_next : TIME_TYPE := TIME_ZERO; - signal is_lifespan_check, is_lifespan_check_next : std_logic := '0'; - - signal status_sig, status_sig_next : std_logic_vector(STATUS_KIND_WIDTH-1 downto 0) := (others => '0'); - signal sample_rej_cnt, sample_rej_cnt_next : unsigned(SAMPLE_REJECTED_STATUS_COUNT_WIDTH-1 downto 0) := (others => '0'); - signal sample_rej_cnt_change, sample_rej_cnt_change_next : unsigned(SAMPLE_REJECTED_STATUS_COUNT_WIDTH-1 downto 0) := (others => '0'); - signal sample_rej_last_reason, sample_rej_last_reason_next : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := (others =>'0'); - signal sample_rej_last_inst, sample_rej_last_inst_next : INSTANCE_HANDLE_TYPE := (others => (others => '0')); - signal deadline_time, deadline_time_next : TIME_TYPE := TIME_ZERO; - signal deadline_miss_cnt, deadline_miss_cnt_next : unsigned(REQUESTED_DEADLINE_MISSED_STATUS_COUNT_WIDTH-1 downto 0) := (others => '0'); - signal deadline_miss_cnt_change, deadline_miss_cnt_change_next : unsigned(REQUESTED_DEADLINE_MISSED_STATUS_COUNT_WIDTH-1 downto 0) := (others => '0'); - signal deadline_miss_last_inst, deadline_miss_last_inst_next : INSTANCE_HANDLE_TYPE := (others => (others => '0')); + -- *INSTANCE MEMORY PROCESS* + -- Instance Memory FSM state + signal inst_stage, inst_stage_next : INST_STAGE_TYPE := IDLE; + -- Pointer to current relevant Instance Memory Frame Address + signal inst_addr_base, inst_addr_base_next : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); + -- Pointer to next Instance Memory Frame Address + signal inst_next_addr_base, inst_next_addr_base_next : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); + -- Pointer to previous Instacne Memory Address + signal inst_prev_addr_base, inst_prev_addr_base_next : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); + -- Head of Empty Instance List + signal inst_empty_head, inst_empty_head_next : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); + -- Head of Occupied Instance List + signal inst_occupied_head, inst_occupied_head_next : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); + -- Latch for Instance Data from main process + signal inst_latch_data, inst_latch_data_next : INST_LATCH_DATA_TYPE := ZERO_INST_LATCH_DATA; + -- Latch for Instance Data from memory + signal inst_data, inst_data_next : INSTANCE_DATA_TYPE := ZERO_INSTANCE_DATA; + -- General Purpose Counter + signal inst_cnt, inst_cnt_next : natural range TODO := 0; + -- Counter used to read/write the Writer Bitmap + signal inst_cnt2, inst_cnt2_next : natural 0 to ENDPOINT_BITMAP_ARRAY_TYPE'length := 0; + -- General Purpose Long Latch + signal inst_long_latch, inst_long_latch_next : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); --*****ALIAS DECLARATION***** alias prev_sample : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) is sample_addr_latch_1; @@ -332,6 +429,8 @@ architecture arch of history_cache is begin + --*****COMPONENT INSTANTIATION***** + sample_mem_ctrl_inst : entity work.mem_ctrl(arch) generic map ( ADDR_WIDTH => SAMPLE_MEMORY_ADDR_WIDTH, @@ -396,7 +495,7 @@ begin key_hash_generator_inst : entity work.key_hash_generator(arch) port ( clk => clk, - reset => reset or abort_khg, + reset => reset or khg_abort, data_in => khg_data_in, valid_in => khg_valid_in, ready_in => khg_ready_in, @@ -407,105 +506,139 @@ begin last_word_out => khg_last_word_out ); + -- *Main State Machine* + -- STATE DESCRIPTION + -- IDLE Idle State. Initiates Deadline Miss Checks, Lifespan Expiry Checks, RTPS Operation handling, and DDS Operation handling, in that priority order. + -- UNKNOWN_OPERATION Dummy State for not supported/unknown DDS Operations + -- ADD_SAMPLE_INFO Latch and store Cache Change (pre-payload) + -- ADD_PAYLOAD_ADDRESS Store payload pointer. + -- ADD_PAYLOAD Push payload to memory and key hash generator (as needed) + -- NEXT_PAYLOAD_SLOT Get pointer to next empty payload slot + -- ZERO_PAYLOAD Fill rest of payload slot with zeroes + -- GET_KEY_HASH Fetch the calculated key hash from the Key Hash Generator + -- INITIATE_INSTANCE_SEARCH Initiate Instance Search Memory Operation. This state is used to start the Search operation as soon as the required data is available + -- FILTER_STAGE This state decides if the RTPS Cache Change is accepted, dropped, or rejected. It also decides what sample (if any) has to be removed. + -- UPDATE_INSTANCE Update the Data of the Instance of the received saample (Cache Change) + -- FINALIZE_PAYLOAD Finalize the payload addition (Update pointers). + -- PRE_SAMPLE_FINALIZE Store Sample Info based on Instance Data + -- FIND_POS Find Sample List position based on DESTINATION_ORDER_QOS + -- FIX_POINTERS Update the List Pointers of the inserted Sample neighbours (First Step of Sample Addition Finalization) + -- FINALIZE_SAMPLE Update inserted sample and list pointers. (Second Step of Sample Addition Finalization) + -- GET_OLDEST_SAMPLE_INSTANCE Fetch the Instance Data of the oldest sample + -- FIND_OLDEST_INST_SAMPLE Find the oldest sample of a specific Instance + -- REMOVE_SAMPLE Remove sample and linked payload + -- POST_SAMPLE_REMOVE Update Instance Data of removed sample. If Instance Memory is full, and Instance is now eligible for removal, it is removed. + -- SKIP_ADD_REJECT Skip RTPS Cache Change and signal rejection to RTPS. + -- SKIP_ADD_DROP Skip RTPS Cache Change and signal acceptance to RTPS. + -- REMOVE_WRITER Unmark specified Writer Bitmap Position from all stored Instances. (Also updates Instance Data if necessary) + -- REMOVE_STALE_INSTANCE Find and remove the first eligible Instance in the memory + -- GET_NEXT_SAMPLE Find the next sample in the requested collection + -- PRE_CALCULATE Calculate ranks for the selected sample in the requested collection. + -- FINALIZE_SAMPLE_INFO Finalize the Sample Info Data, and present them. + -- GET_PAYLOAD Push linked Payload to output + -- FIND_NEXT_INSTANCE Find next Instance that passes requested masks + -- CHECK_INSTANCE Check if selected Instance passes requested masks + -- CHECK_LIFESPAN Check and remove samples with expired Lifespans + -- GET_SAMPLE_REJECTED_STATUS Return Sample Rejected Status + -- GET_REQUESTED_DEADLINE_MISSED_STATUS Return Requested Deadline Missed Status + -- CHECK_DEADLINE Check and Mark Instances with missed Deadlines parse_a_prc : process (all) variable tmp_dw : DOUBLE_WORD_ARRAY := (others => (others => '0')); variable tmp_bitmap : std_logic_vector(0 to ENDPOINT_BITMAP_WIDTH-1) := (others => '0'); variable tmp_update : std_logic_vector(0 to IMF_FLAG_WIDTH-1) := (others => '0'); variable tmp_bool : boolean := FALSE; begin - -- Default - stage_next <= stage; - res_rtps <= UNDEFINED; - sample_addr <= (others => '0'); - sample_write_data <= (others => '0'); - sample_read <= '0'; - sample_ready_out <= '0'; - sample_valid_in <= '0'; - sample_abort_read <= '0'; - payload_addr <= (others => '0'); - payload_write_data <= (others => '0'); - payload_read <= '0'; - payload_ready_out <= '0'; - payload_valid_in <= '0'; - payload_abort_read <= '0'; - ready_in_rtps <= '0'; - newest_sample_next <= newest_sample; - empty_payload_list_head_next <= empty_payload_list_head; - empty_sample_list_head_next <= empty_sample_list_head; - empty_sample_list_tail_next <= empty_sample_list_tail; - payload_addr_latch_1_next <= payload_addr_latch_1; - payload_addr_latch_2_next <= payload_addr_latch_2; - ts_latch_next <= ts_latch; - long_latch_next <= long_latch; - sample_addr_latch_1_next <= sample_addr_latch_1; - sample_addr_latch_2_next <= sample_addr_latch_2; - sample_addr_latch_3_next <= sample_addr_latch_3; - sample_addr_latch_4_next <= sample_addr_latch_4; - payload_mem_full_next <= payload_mem_full; - sample_mem_full_next <= sample_mem_full; - writer_pos_next <= writer_pos; - inst_opcode <= NOP; - key_hash_next <= key_hash; - sample_status_info_next <= sample_status_info; - inst_op_start <= '0'; - khg_last_word_in <= '0'; - khg_data_in <= (others => '0'); - khg_valid_in <= '0'; - khg_ready_out <= '0'; - writer_bitmap <= (others => '0'); - inst_addr_update <= (others => '0'); - remove_oldest_sample_next <= remove_oldest_sample; - remove_oldest_inst_sample_next <= remove_oldest_inst_sample; - added_new_instance_next <= added_new_instance; - si_sample_state_sig_next <= si_sample_state; - si_view_state_sig_next <= si_view_state_sig; - si_instance_state_sig_next <= si_instance_state_sig; - si_source_timestamp_sig_next <= si_source_timestamp_sig; - si_instance_handle_sig_next <= si_instance_handle_sig; - si_publication_handle_sig_next <= si_publication_handle_sig; + -- DEFAULT Registered + stage_next <= stage; + newest_sample_next <= newest_sample; + empty_payload_list_head_next <= empty_payload_list_head; + empty_sample_list_head_next <= empty_sample_list_head; + empty_sample_list_tail_next <= empty_sample_list_tail; + payload_addr_latch_1_next <= payload_addr_latch_1; + payload_addr_latch_2_next <= payload_addr_latch_2; + ts_latch_next <= ts_latch; + long_latch_next <= long_latch; + sample_addr_latch_1_next <= sample_addr_latch_1; + sample_addr_latch_2_next <= sample_addr_latch_2; + sample_addr_latch_3_next <= sample_addr_latch_3; + sample_addr_latch_4_next <= sample_addr_latch_4; + writer_pos_next <= writer_pos; + key_hash_next <= key_hash; + sample_status_info_next <= sample_status_info; + remove_oldest_sample_next <= remove_oldest_sample; + remove_oldest_inst_sample_next <= remove_oldest_inst_sample; + added_new_instance_next <= added_new_instance; + si_sample_state_sig_next <= si_sample_state; + si_view_state_sig_next <= si_view_state_sig; + si_instance_state_sig_next <= si_instance_state_sig; + si_source_timestamp_sig_next <= si_source_timestamp_sig; + si_instance_handle_sig_next <= si_instance_handle_sig; + si_publication_handle_sig_next <= si_publication_handle_sig; si_disposed_generation_count_sig_next <= si_disposed_generation_count_sig; si_no_writers_generation_count_sig_next <= si_no_writers_generation_count_sig; - si_sample_rank_sig_next <= si_sample_rank_sig; - si_generation_rank_sig_next <= si_generation_rank_sig; + si_sample_rank_sig_next <= si_sample_rank_sig; + si_generation_rank_sig_next <= si_generation_rank_sig; si_absolute_generation_count_sig_next <= si_absolute_generation_count_sig; - si_valid_data_sig_next <= si_valid_data_sig; - si_valid_sig_next <= si_valid_sig_next; - sample_state_next <= sample_state; - view_state_next <= view_state; - instance_state_next <= instance_state; - instance_handle_next <= instance_handle; - max_samples_next <= max_samples; - inst_addr_latch_1_next <= inst_addr_latch_1; - inst_addr_latch_2_next <= inst_addr_latch_2; - collection_cnt_next <= collection_cnt; - collection_cnt_max_next <= collection_cnt_max; - collection_generation_rank_next <= collection_generation_rank; - cur_generation_rank_next <= cur_generation_rank; - is_take_next <= is_take; - has_lacthed_next <= has_latched; - single_instance_next <= single_instance; - single_sample_next <= single_sample; - unmark_instances_next <= unmark_instances; - is_first_instance_sample_next <= is_first_instance_sample; - dynamic_next_instance_next <= dynamic_next_instance; - last_read_ts_next <= last_read_ts; - sample_rej_cnt_next <= sample_rej_cnt; - sample_rej_cnt_change_next <= sample_rej_cnt_change; - sample_rej_last_reason_next <= sample_rej_last_reason; - sample_rej_last_inst_next <= sample_rej_last_inst; - deadline_time_next <= deadline_time; - deadline_miss_cnt_next <= deadline_miss_cnt; - deadline_miss_cnt_change_next <= deadline_miss_cnt_change; - deadline_miss_last_inst_next <= deadline_miss_last_inst; - lifespan_time_next <= lifespan_time; - is_lifespan_check_next <= is_lifespan_check; - ack_dds <= '0'; - inst_data_variant <= VAR_1; - done_dds <= '0'; - abort_khg <= '0'; - return_code_dds <= RETCODE_UNSUPPORTED; - status_sig_next <= status_sig; - cnt2_next <= cnt2; + si_valid_data_sig_next <= si_valid_data_sig; + si_valid_sig_next <= si_valid_sig_next; + sample_state_next <= sample_state; + view_state_next <= view_state; + instance_state_next <= instance_state; + instance_handle_next <= instance_handle; + max_samples_next <= max_samples; + inst_addr_latch_1_next <= inst_addr_latch_1; + inst_addr_latch_2_next <= inst_addr_latch_2; + collection_cnt_next <= collection_cnt; + collection_cnt_max_next <= collection_cnt_max; + collection_generation_rank_next <= collection_generation_rank; + cur_generation_rank_next <= cur_generation_rank; + is_take_next <= is_take; + single_instance_next <= single_instance; + single_sample_next <= single_sample; + unmark_instances_next <= unmark_instances; + is_first_instance_sample_next <= is_first_instance_sample; + dynamic_next_instance_next <= dynamic_next_instance; + last_read_ts_next <= last_read_ts; + sample_rej_cnt_next <= sample_rej_cnt; + sample_rej_cnt_change_next <= sample_rej_cnt_change; + sample_rej_last_reason_next <= sample_rej_last_reason; + sample_rej_last_inst_next <= sample_rej_last_inst; + deadline_time_next <= deadline_time; + deadline_miss_cnt_next <= deadline_miss_cnt; + deadline_miss_cnt_change_next <= deadline_miss_cnt_change; + deadline_miss_last_inst_next <= deadline_miss_last_inst; + lifespan_time_next <= lifespan_time; + is_lifespan_check_next <= is_lifespan_check; + status_sig_next <= status_sig; + cnt2_next <= cnt2; + -- DEFAULT Unregistered + inst_opcode <= NOP; + res_rtps <= UNDEFINED; + return_code_dds <= RETCODE_UNSUPPORTED; + ack_dds <= '0'; + done_dds <= '0'; + khg_abort <= '0'; + inst_op_start <= '0'; + khg_last_word_in <= '0'; + khg_valid_in <= '0'; + khg_ready_out <= '0'; + sample_read <= '0'; + sample_ready_out <= '0'; + sample_valid_in <= '0'; + sample_abort_read <= '0'; + payload_read <= '0'; + payload_ready_out <= '0'; + payload_valid_in <= '0'; + payload_abort_read <= '0'; + ready_in_rtps <= '0'; + khg_data_in <= (others => '0'); + writer_bitmap <= (others => '0'); + inst_addr_update <= (others => '0'); + sample_addr <= (others => '0'); + sample_write_data <= (others => '0'); + payload_addr <= (others => '0'); + payload_write_data <= (others => '0'); + case (stage) is when IDLE => @@ -537,6 +670,7 @@ begin stage_next <= CHECK_LIFESPAN; cnt_next <= 0; end if; + -- RTPS Operation elsif (start_rtps = '1') then case (opcode_rtps) is when ADD_CHANGE => @@ -562,13 +696,15 @@ begin when others => null; end case; + -- Unmark Instances elsif (unmark_instances = '1') then -- Memory Operation Guard if (inst_op_done = '1') then inst_op_start <= '1'; - inst_opcode <= UNMARK_INTANCES; + inst_opcode <= UNMARK_INSTANCES; unmark_instances_next <= '0'; end if; + -- DDS Operation elsif (start_dds = '1') then -- Latch Input Signals sample_state_next <= sample_state_in; @@ -861,6 +997,7 @@ begin -- End of Payload Slot if (cnt2 = PAYLOAD_FRAME_SIZE-1) then stage_next <= NEXT_PAYLOAD_SLOT; + cnt_next <= 0; else -- Next Word cnt_next <= 0; @@ -940,7 +1077,7 @@ begin -- Reject Change stage_next <= SKIP_ADD_REJECT; -- Abort Key Hash Generation - abort_khg <= '1'; + khg_abort <= '1'; else -- Latch next Payload Slot and Continue cur_payload_next <= payload_read_data; @@ -1922,47 +2059,51 @@ begin when REMOVE_WRITER => -- Memory Operation Guard if (inst_op_done = '1') then - -- No More Instances - if (inst_addr_base = INSTANCE_MEMORY_MAX_ADDRESS) then - -- DONE - stage_next <= IDLE; - else - -- Convert Writer Bitmap to SLV - tmp_bitmap := to_endpoint_bitmap(inst_data.writer_bitmap); - - -- Remove Writer - tmp_bitmap(writer_pos) := '0'; - - -- NOTE: writer_bitmap is not latched, since the memory process is latching it at the - -- same clock cycle. - -- Convert Back - writer_bitmap <= from_endpoint_bitmap(tmp_bitmap); - - -- No More Writers for Instance - if (tmp_bitmap = (tmp_bitmap'range => '0')) then - status_info_update <= inst_data.status; - status_info_update(NOT_ALIVE_DISPOSED_FLAG) <= '0'; - status_info_update(NOT_ALIVE_NO_WRITERS_FLAG) <= '1'; - status_info_update(LIVELINESS_FLAG) <= '1'; + case (cnt) is + when 0 => + -- No More Instances + if (inst_addr_base = INSTANCE_MEMORY_MAX_ADDRESS) then + -- DONE + stage_next <= IDLE; + else + -- Convert Writer Bitmap to SLV + tmp_bitmap := to_endpoint_bitmap(inst_data.writer_bitmap); + + -- Remove Writer + tmp_bitmap(writer_pos) := '0'; + + -- NOTE: writer_bitmap is not latched, since the memory process is latching it at the + -- same clock cycle. + -- Convert Back + writer_bitmap <= from_endpoint_bitmap(tmp_bitmap); + + -- No More Writers for Instance + if (tmp_bitmap = (tmp_bitmap'range => '0')) then + status_info_update <= inst_data.status; + status_info_update(NOT_ALIVE_DISPOSED_FLAG) <= '0'; + status_info_update(NOT_ALIVE_NO_WRITERS_FLAG) <= '1'; + status_info_update(LIVELINESS_FLAG) <= '1'; + inst_op_start <= '1'; + inst_opcode <= UPDATE_INSTANCE; + inst_mem_fields <= IMF_STATUS_FLAG or IMF_WRITER_BITMAP_FLAG; + else + inst_op_start <= '1'; + inst_opcode <= UPDATE_INSTANCE; + inst_mem_fields <= IMF_WRITER_BITMAP_FLAG; + end if; + + -- Continue + cnt_next <= 1; + end if; + when 1 => inst_op_start <= '1'; - inst_opcode <= UPDATE_INSTANCE; + inst_opcode <= GET_NEXT_INSTANCE; inst_mem_fields <= IMF_STATUS_FLAG or IMF_WRITER_BITMAP_FLAG; - else - inst_op_start <= '1'; - inst_opcode <= UPDATE_INSTANCE; - inst_mem_fields <= IMF_WRITER_BITMAP_FLAG; - end if; - - stage_next <= GET_NEXT_INSTANCE; - end if; - end if; - when GET_NEXT_INSTANCE => - -- Wait for Operation to Complete - if (inst_op_done = '1') then - inst_op_start <= '1'; - inst_opcode <= GET_NEXT_INSTANCE; - inst_mem_fields <= IMF_STATUS_FLAG or IMF_WRITER_BITMAP_FLAG; - stage_next <= REMOVE_WRITER; + stage_next <= REMOVE_WRITER; + cnt_next <= 0; + when others => + null; + end case; end if; when REMOVE_STALE_INSTANCE => -- Wait for Instance Data @@ -3247,7 +3388,18 @@ begin end case; end process; - + -- *Instance Memory Process* + -- STATE DESCRIPTION + -- IDLE Idle State. Done Signal is pulled high and Memory FSM accepts new memory operations + -- SEARCH_INSTANCE_HASH See Memory OPCODE Description + -- SEARCH_INSTANCE_ADDR See Memory OPCODE Description + -- GET_NEXT_INSTANCE See Memory OPCODE Description + -- GET_INSTANCE_DATA Latch specified Instance Data for use by main process + -- FIND_POS Find List position of Instance to be added + -- INSERT_INSTANCE See Memory OPCODE Description + -- UPDATE_INSTANCE See Memory OPCODE Description + -- REMOVE_INSTANCE See Memory OPCODE Description + -- UNMARK_INTANCES See Memory OPCODE Description inst_ctrl_prc : process(all) begin -- DEFAULT Registered @@ -3260,7 +3412,6 @@ begin inst_prev_addr_base_next <= inst_prev_addr_base; inst_cnt_next <= inst_cnt; inst_cnt2_next <= inst_cnt2; - inst_mem_full_next <= inst_mem_full; inst_data_next <= inst_data; inst_long_latch_next <= inst_long_latch; -- DEFAULT Unregistered @@ -3326,7 +3477,6 @@ begin inst_cnt_next <= 0; when UPDATE_INSTANCE => inst_stage_next <= UPDATE_INSTANCE; - inst_addr_base_next <= inst_addr_update; if check_mask(inst_mem_fields.field_flag,IMF_STATUS_FLAG) then inst_cnt_next <= 0; elsif check_mask(inst_mem_fields.field_flag,IMF_SAMPLE_CNT_FLAG) then @@ -3409,11 +3559,11 @@ begin -- DONE inst_stage_next <= IDLE; end if; - when UNMARK_INTANCES => + when UNMARK_INSTANCES => -- Empty Memory Guard if (inst_occupied_head /= INSTANCE_MEMORY_MAX_ADDRESS) then inst_addr_base_next <= inst_occupied_head; - inst_stage_next <= UNMARK_INTANCES; + inst_stage_next <= UNMARK_INSTANCES; inst_cnt_next <= 0; end if; when others => @@ -4681,7 +4831,7 @@ begin when others => null; end case; - when UNMARK_INTANCES => + when UNMARK_INSTANCES => -- Precondition: inst_addr_base set case (inst_cnt) is