From c5239679d72d3e5a2d7db863a11348f2b7be5387 Mon Sep 17 00:00:00 2001 From: Greek Date: Wed, 31 Mar 2021 19:17:57 +0200 Subject: [PATCH] Port changes and fix syntax of DDS Reader --- src/REF.txt | 3 +- src/dds_reader.vhd | 2049 +++++++++++++++++++++-------------- src/rtps_config_package.vhd | 26 +- 3 files changed, 1253 insertions(+), 825 deletions(-) diff --git a/src/REF.txt b/src/REF.txt index af7c70d..0ca00dc 100644 --- a/src/REF.txt +++ b/src/REF.txt @@ -417,7 +417,7 @@ READER +-------------------------------------------------------------+ 05| PAYLOAD_ADDRESS | +-------------------------------------------------------------+ -06| INSTANCE_ADDRESS | +06| INSTANCE_ADDRESS | [only if WITH_KEY] +-------------------------------------------------------------+ 07| DISPOSED_GENERATION_COUNT | +-------------------------------------------------------------+ @@ -548,6 +548,7 @@ K...Key Hash available F...FilteredFlag (1:1 PID_STATUS_INFO Mapping) U...UnregisteredFlag (1:1 PID_STATUS_INFO Mapping) D...DisposedFlag (1:1 PID_STATUS_INFO Mapping) +NOTE: If P=0 and K=0, the Payload contains the Serialized Key INSTANCE MEMORY =============== diff --git a/src/dds_reader.vhd b/src/dds_reader.vhd index 3c9659a..1155396 100644 --- a/src/dds_reader.vhd +++ b/src/dds_reader.vhd @@ -2,42 +2,62 @@ library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; +use work.math_pkg.all; +use work.rtps_package.all; +use work.user_config.all; +use work.rtps_config_package.all; + -- TODO: Check if sample_cnt is always maintained (also with MAX_SAMPLES_PER_INSTANCE = LENGTH_UNLIMITED) entity dds_reader is generic ( - TIME_BASED_FILTER_QOS : DURATION_TYPE := DEFAULT_TIME_BASED_FILTER_QOS; - MAX_INSTANCES : natural := DEFAULT_MAX_INSTANCES; - MAX_SAMPLES_PER_INSTANCE : natural := DEFAULT_MAX_SAMPLES_PER_INSTANCE; - HISTORY_QOS : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := DEFAULT_HISTORY_QOS; - RELIABILITY_QOS : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := DEFAULT_RELIABILTY_QOS; - PRESENTATION_QOS : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := DEFAULT_PRESENTATION_QOS; - DESTINATION_ORDER_QOS : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := DEFAULT_DESTINATION_ORDER_QOS; - COHERENT_ACCESS : boolean := DEFAULT_COHERENT_ACCESS; - ORDERED_ACCESS : boolean := DEFAULT_ORDERED_ACCESS; - WITH_KEY : boolean := FALSE; -- TODO: Default + TIME_BASED_FILTER_QOS : DURATION_TYPE; + DEADLINE_QOS : DURATION_TYPE; + MAX_INSTANCES : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + MAX_SAMPLES_PER_INSTANCE : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + MAX_SAMPLES : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + HISTORY_QOS : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0); + RELIABILITY_QOS : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0); + PRESENTATION_QOS : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0); + DESTINATION_ORDER_QOS : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0); + COHERENT_ACCESS : boolean; + ORDERED_ACCESS : boolean; + WITH_KEY : boolean; + PAYLOAD_FRAME_SIZE : natural; + MAX_REMOTE_ENDPOINTS : natural := 50 ); port ( -- SYSTEM clk : in std_logic; reset : in std_logic; time : in TIME_TYPE; - -- FROM RTPS ENDPOINT start_rtps : in std_logic; opcode_rtps : in HISTORY_CACHE_OPCODE_TYPE; ack_rtps : out std_logic; done_rtps : out std_logic; - ret_rtps : out HISTORY_CACHE_RESPOSNE_TYPE; + ret_rtps : out HISTORY_CACHE_RESPONSE_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; - + -- TO/FROM KEY_HOLDER + start_kh : out std_logic; + opcode_kh : out KEY_HOLDER_OPCODE_TYPE; + ack_kh : in std_logic; + data_in_kh : in std_logic_vector(WORD_WIDTH-1 downto 0); + valid_in_kh : in std_logic; + ready_in_kh : out std_logic; + last_word_in_kh : in std_logic; + data_out_kh : out std_logic_vector(WORD_WIDTH-1 downto 0); + valid_out_kh : out std_logic; + ready_out_kh : in std_logic; + last_word_out_kh : out std_logic; + abort_kh : out std_logic; -- TO USER ENTITY start_dds : in std_logic; ack_dds : out std_logic; - opcode_dds : in HISTORY_CACHE_OPCODE_TYPE; + opcode_dds : in DDS_READER_OPCODE_TYPE; instance_state_dds : in std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); view_state_dds : in std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0); sample_state_dds : in std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0); @@ -50,7 +70,7 @@ entity dds_reader is 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 + -- 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); @@ -64,37 +84,67 @@ entity dds_reader 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; - -- COMMUNICATION STATUS - status : out std_logic_vector(STATUS_KIND_WIDTH-1 downto 0); + -- Communication Status + status : out std_logic_vector(STATUS_KIND_WIDTH-1 downto 0) ); end entity; architecture arch of dds_reader is --*****CONSTANT DECLARATION***** + -- NOTE: Because we need to first determine the Instance before making the ACCEPT/REJECT/DROP decision + -- we need to latch the cache change first, calculate the Key Hash if necessary, fetch the associated + -- Instance, and then decide on it. This in effect means that we always need an extra slot in sample and + -- payload memory that is only used as a latch. -- *SAMPLE MEMORY* + -- 4-Byte Word Size of a Sample Info Entry in Memory + function gen_sample_frame_size(WITH_KEY : boolean) return natural is + variable ret : natural := 0; + begin + if (WITH_KEY) then + return 11; + else + return 10; + end if; + end function; + constant SAMPLE_FRAME_SIZE : natural := gen_sample_frame_size(WITH_KEY); -- Sample Info Memory Size in 4-Byte Words - constant SAMPLE_MEMORY_SIZE : natural := TODO; + constant SAMPLE_MEMORY_SIZE : natural := to_integer(unsigned(MAX_SAMPLES)+1) * SAMPLE_FRAME_SIZE; -- Sample Info Memory Address Width constant SAMPLE_MEMORY_ADDR_WIDTH : natural := log2c(SAMPLE_MEMORY_SIZE); -- Highest Sample Info Memory Address constant SAMPLE_MEMORY_MAX_ADDRESS : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := to_unsigned(SAMPLE_MEMORY_SIZE-1, SAMPLE_MEMORY_ADDR_WIDTH); -- Highest Sample Info Frame Address constant MAX_SAMPLE_ADDRESS : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := SAMPLE_MEMORY_MAX_ADDRESS - SAMPLE_FRAME_SIZE + 1; + -- Address pointing to the beginning of the first Sample Data Frame + constant FIRST_SAMPLE_ADDRESS : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); -- *PAYLOAD MEMORY* -- Payload Memory Size in 4-Byte Words - constant PAYLOAD_MEMORY_SIZE : natural := TODO; + constant PAYLOAD_MEMORY_SIZE : natural := to_integer(unsigned(MAX_SAMPLES)+1) * PAYLOAD_FRAME_SIZE; -- Payload Memory Address Width constant PAYLOAD_MEMORY_ADDR_WIDTH : natural := log2c(PAYLOAD_MEMORY_SIZE); -- Highest Payload Memory Address constant PAYLOAD_MEMORY_MAX_ADDRESS : unsigned(PAYLOAD_MEMORY_ADDR_WIDTH-1 downto 0) := to_unsigned(PAYLOAD_MEMORY_SIZE-1, PAYLOAD_MEMORY_ADDR_WIDTH); -- Highest Payload Frame Address constant MAX_PAYLOAD_ADDRESS : unsigned(PAYLOAD_MEMORY_ADDR_WIDTH-1 downto 0) := PAYLOAD_MEMORY_MAX_ADDRESS - PAYLOAD_FRAME_SIZE + 1; + -- Address pointing to the beginning of the first Payload Data Frame + constant FIRST_PAYLOAD_ADDRESS : unsigned(PAYLOAD_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); -- *INSTANCE MEMORY* + -- 4-Byte Word Size of a Instance Entry in Memory + function gen_inst_frame_size(time_based_filter : DURATION_TYPE) return natural is + variable ret : natural := 0; + begin + if (time_based_filter = DURATION_ZERO) then + return 9 + round_div(MAX_REMOTE_ENDPOINTS, WORD_WIDTH); + else + return 11 + round_div(MAX_REMOTE_ENDPOINTS, WORD_WIDTH); + end if; + end function; + constant INSTANCE_FRAME_SIZE : natural := gen_inst_frame_size(TIME_BASED_FILTER_QOS); -- Instance Memory Size in 4-Byte Words - constant INSTANCE_MEMORY_SIZE : natural := TODO; + constant INSTANCE_MEMORY_SIZE : natural := to_integer(unsigned(MAX_INSTANCES)) * INSTANCE_FRAME_SIZE; -- Instance Memory Address Width constant INSTANCE_MEMORY_ADDR_WIDTH : natural := log2c(INSTANCE_MEMORY_SIZE); -- Highest Instance Memory Address @@ -111,10 +161,16 @@ architecture arch of dds_reader is constant SMF_LIFESPAN_DEADLINE_OFFSET : natural := 3; constant SMF_PAYLOAD_ADDR_OFFSET : natural := 5; constant SMF_INSTANCE_ADDR_OFFSET : natural := 6; - constant SMF_DISPOSED_GEN_CNT_OFFSET : natural := 7; - constant SMF_NO_WRITERS_GEN_CNT_OFFSET : natural := 8; - constant SMF_PREV_ADDR_OFFSET : natural := 9; - constant SMF_NEXT_ADDR_OFFSET : natural := 10; + function gen_smf_disposed_gen_cnt_offset(WITH_KEY : boolean) return natural is + variable ret : natural := 0; + begin + ret := (SMF_INSTANCE_ADDR_OFFSET + 1) when WITH_KEY else SMF_INSTANCE_ADDR_OFFSET; + return ret; + end function; + constant SMF_DISPOSED_GEN_CNT_OFFSET : natural := gen_smf_disposed_gen_cnt_offset(WITH_KEY); + constant SMF_NO_WRITERS_GEN_CNT_OFFSET : natural := SMF_DISPOSED_GEN_CNT_OFFSET + 1; + constant SMF_PREV_ADDR_OFFSET : natural := SMF_NO_WRITERS_GEN_CNT_OFFSET + 1; + constant SMF_NEXT_ADDR_OFFSET : natural := SMF_PREV_ADDR_OFFSET + 1; -- *PAYLOAD MEMORY FRAME FORMAT* -- 4-Byte Word Offsets to Beginning of Respective Fields in the Endpoint Memory Frame @@ -130,29 +186,35 @@ architecture arch of dds_reader is constant IMF_DISPOSED_GEN_CNT_OFFSET : natural := 7; constant IMF_NO_WRITERS_GEN_CNT_OFFSET : natural := 8; 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; + function gen_imf_writer_bitmap_offset(time_based_filter : DURATION_TYPE) return natural is + variable ret : natural := 0; + begin + ret := IMF_IGNORE_DEADLINE_OFFSET+2 when (time_based_filter /= DURATION_ZERO) else IMF_IGNORE_DEADLINE_OFFSET; + return ret; + end function; + constant IMF_WRITER_BITMAP_OFFSET : natural := gen_imf_writer_bitmap_offset(TIME_BASED_FILTER_QOS); -- *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'); + 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, UNKNOWN_OPERATION, ADD_SAMPLE_INFO, ADD_PAYLOAD_ADDRESS, ADD_PAYLOAD, NEXT_PAYLOAD_SLOT, ALIGN_PAYLOAD, GET_KEY_HASH, INITIATE_INSTANCE_SEARCH, FILTER_STAGE, UPDATE_INSTANCE, FINALIZE_PAYLOAD, PRE_SAMPLE_FINALIZE, FIND_POS, FIX_POINTERS, FINALIZE_SAMPLE, 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, + REMOVE_SAMPLE, POST_SAMPLE_REMOVE, SKIP_AND_RETURN, 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, RESET_SAMPLE_MEMORY, RESET_PAYLOAD_MEMORY); -- 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); + REMOVE_INSTANCE, UNMARK_INSTANCES, RESET_MEMORY); -- *Instance Memory Opcodes* -- OPCODE DESCRIPTION -- SEARCH_INSTANCE_HASH Search Instance based on Key Hash pointed by key_hash. @@ -164,8 +226,10 @@ architecture arch of dds_reader is -- 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, + type INSTANCE_OPCODE_TYPE is (NOP, SEARCH_INSTANCE_HASH, SEARCH_INSTANCE_ADDR, INSERT_INSTANCE, UPDATE_INSTANCE, GET_FIRST_INSTANCE, GET_NEXT_INSTANCE, REMOVE_INSTANCE, GET_INSTANCE, UNMARK_INSTANCES); + type WRITER_BITMAP_ARRAY_TYPE is array (0 to round_div(MAX_REMOTE_ENDPOINTS-1, WORD_WIDTH)-1) of std_logic_vector(0 to WORD_WIDTH-1); + constant ZERO_WRITER_BITMAP_ARRAY : WRITER_BITMAP_ARRAY_TYPE := (others => (others => '0')); -- Record of Instance Data type INSTANCE_DATA_TYPE is record key_hash : KEY_HASH_TYPE; @@ -174,7 +238,7 @@ architecture arch of dds_reader is disposed_gen_cnt : unsigned(WORD_WIDTH-1 downto 0); no_writers_gen_cnt : unsigned(WORD_WIDTH-1 downto 0); ignore_deadline : TIME_TYPE; - writer_bitmap : ENDPOINT_BITMAP_ARRAY_TYPE; + writer_bitmap : WRITER_BITMAP_ARRAY_TYPE; end record; -- Zero initialized Endpoint Data constant ZERO_INSTANCE_DATA : INSTANCE_DATA_TYPE := ( @@ -184,16 +248,16 @@ architecture arch of dds_reader is disposed_gen_cnt => (others => '0'), no_writers_gen_cnt => (others => '0'), ignore_deadline => TIME_INVALID, - writer_bitmap => (others => (others => '0')) + writer_bitmap => ZERO_WRITER_BITMAP_ARRAY ); -- 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); - sample_cnt : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); - gen_cnt : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + sample_cnt : unsigned(CDR_LONG_WIDTH-1 downto 0); + gen_cnt : unsigned(CDR_LONG_WIDTH-1 downto 0); deadline : TIME_TYPE; - writer_bitmap : std_logic_vector(0 to ENDPOINT_BITMAP_WIDTH-1); + writer_bitmap : WRITER_BITMAP_ARRAY_TYPE; field_flags : std_logic_vector(0 to IMF_FLAG_WIDTH-1); addr : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0); end record; @@ -204,7 +268,7 @@ architecture arch of dds_reader is sample_cnt => (others => '0'), gen_cnt => (others => '0'), deadline => TIME_INVALID, - writer_bitmap => (others => (others => '0')), + writer_bitmap => ZERO_WRITER_BITMAP_ARRAY, field_flags => (others => '0'), addr => (others => '0') ); @@ -234,16 +298,11 @@ architecture arch of dds_reader 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 cnt, cnt_next : natural range 0 to 18 := 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 @@ -265,9 +324,11 @@ architecture arch of dds_reader is -- 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'; -- Remote Writer Endpoint Bitmap Position - signal writer_pos, writer_pos_next : natural range TODO := 0; + signal writer_pos, writer_pos_next : natural range 0 to MAX_REMOTE_ENDPOINTS-1 := 0; -- Key Hash Latch - signal key_hash, key_hash_next : KEY_HASH_TYPE := (others => (others => '0')); + signal key_hash, key_hash_next : KEY_HASH_TYPE := HANDLE_NIL; + -- Return Code Latch + signal return_code_latch, return_code_latch_next : HISTORY_CACHE_RESPONSE_TYPE := ERROR; -- Source Timestamp Latch signal ts_latch, ts_latch_next : TIME_TYPE := TIME_INVALID; -- Lifespan Latch @@ -293,7 +354,7 @@ architecture arch of dds_reader is -- 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 writer_bitmap : WRITER_BITMAP_ARRAY_TYPE := ZERO_WRITER_BITMAP_ARRAY; -- 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 @@ -323,9 +384,9 @@ architecture arch of dds_reader is -- 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'); + signal instance_handle, instance_handle_next : INSTANCE_HANDLE_TYPE := HANDLE_NIL; -- Max Samples Latch - signal max_samples, max_samples_next : unsigned(MAX_SAMPLES_WIDTH-1 downto 0) := (others => '0'); + signal max_samples_latch, max_samples_latch_next : unsigned(MAX_SAMPLES_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 @@ -343,11 +404,11 @@ architecture arch of dds_reader is -- 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'; + signal unmark_instances_flag, unmark_instances_flag_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'; -- Signal containing the number of currently stale Instances - signal stale_inst_cnt, stale_inst_cnt_next : natural range 0 to MAX_INSTANCES := 0; + signal stale_inst_cnt, stale_inst_cnt_next : natural range 0 to to_integer(unsigned(MAX_INSTANCES))-1 := 0; -- *COMMUNICATION STATUS* signal status_sig, status_sig_next : std_logic_vector(STATUS_KIND_WIDTH-1 downto 0) := (others => '0'); @@ -368,10 +429,10 @@ architecture arch of dds_reader is 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'); signal si_source_timestamp_sig, si_source_timestamp_sig_next : TIME_TYPE := TIME_INVALID; - signal si_instance_handle_sig, si_instance_handle_sig_next : INSTANCE_HANDLE_TYPE := (others => (others => '0')); + signal si_instance_handle_sig, si_instance_handle_sig_next : INSTANCE_HANDLE_TYPE := HANDLE_NIL; signal si_publication_handle_sig, si_publication_handle_sig_next : PUBLICATION_HANDLE_TYPE := (others => (others => '0')); - signal si_disposed_generation_count_sig, si_disposed_generation_count_sig_next : unsigned(DISPOSED_GENERATION_COUNT_WIDTH-1 downto 0) := (others => '0'); - signal si_no_writers_generation_count_sig, si_no_writers_generation_count_sig_next : unsigned(NO_WRITERS_GENERATION_COUNT_WIDTH-1 downto 0) := (others => '0'); + signal si_disposed_generation_count_sig, si_disposed_generation_count_sig_next : std_logic_vector(DISPOSED_GENERATION_COUNT_WIDTH-1 downto 0) := (others => '0'); + signal si_no_writers_generation_count_sig, si_no_writers_generation_count_sig_next : std_logic_vector(NO_WRITERS_GENERATION_COUNT_WIDTH-1 downto 0) := (others => '0'); signal si_sample_rank_sig, si_sample_rank_sig_next : unsigned(SAMPLE_RANK_WIDTH-1 downto 0) := (others => '0'); signal si_generation_rank_sig, si_generation_rank_sig_next : unsigned(GENERATION_RANK_WIDTH-1 downto 0) := (others => '0'); signal si_absolute_generation_count_sig, si_absolute_generation_count_sig_next : unsigned(ABSOLUTE_GENERATION_COUNT_WIDTH-1 downto 0) := (others => '0'); @@ -393,12 +454,14 @@ architecture arch of dds_reader is 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; + -- NOTE: The next signal is driven by the inst_ctrl_prc. In case WITH_KEY is FALSE, no inst_ctrl_prc is generated and the inst_data is + -- set by the main process directly by drivng the next2 signal. The sync_prc is responsible for latching the corrct next signal. -- Latch for Instance Data from memory - signal inst_data, inst_data_next : INSTANCE_DATA_TYPE := ZERO_INSTANCE_DATA; + signal inst_data, inst_data_next, inst_data_next2 : INSTANCE_DATA_TYPE := ZERO_INSTANCE_DATA; -- General Purpose Counter - signal inst_cnt, inst_cnt_next : natural range TODO := 0; + signal inst_cnt, inst_cnt_next : natural range 0 to 21 := 0; -- Counter used to read/write the Writer Bitmap - signal inst_cnt2, inst_cnt2_next : natural 0 to ENDPOINT_BITMAP_ARRAY_TYPE'length := 0; + signal inst_cnt2, inst_cnt2_next : natural range 0 to WRITER_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'); @@ -429,7 +492,25 @@ architecture arch of dds_reader is variable ret : unsigned((KEY_HASH_WIDTH*WORD_WIDTH)-1 downto 0) := (others => '0'); begin for i in 0 to KEY_HASH_WIDTH-1 loop - ret(((KEY_HASH_WIDTH-i)*WORD_WIDTH)-1 downto (KEY_HASH_WIDTH-1-i)*WORD_WIDTH) := input(i); + ret(((KEY_HASH_WIDTH-i)*WORD_WIDTH)-1 downto (KEY_HASH_WIDTH-1-i)*WORD_WIDTH) := unsigned(input(i)); + end loop; + return ret; + end function; + + function from_writer_bitmap_array (input : WRITER_BITMAP_ARRAY_TYPE) return std_logic_vector is + variable ret : std_logic_vector(0 to MAX_REMOTE_ENDPOINTS-1) := (others => '0'); + begin + for i in 0 to input'length-1 loop + ret(i*WORD_WIDTH to ((i+1)*WORD_WIDTH)-1) := input(i); + end loop; + return ret; + end function; + + function to_writer_bitmap_array (input : std_logic_vector(0 to MAX_REMOTE_ENDPOINTS-1)) return WRITER_BITMAP_ARRAY_TYPE is + variable ret : WRITER_BITMAP_ARRAY_TYPE := ZERO_WRITER_BITMAP_ARRAY; + begin + for i in 0 to ret'length-1 loop + ret(i) := input(i*WORD_WIDTH to ((i+1)*WORD_WIDTH)-1); end loop; return ret; end function; @@ -467,8 +548,8 @@ begin ) port map ( clk => clk, - reset => reset or sample_abort_read, - addr => std_logic_vector(sample_addr), + reset => reset or payload_abort_read, + addr => std_logic_vector(payload_addr), read => payload_read, ready_in => payload_ready_in, valid_in => payload_valid_in, @@ -488,43 +569,29 @@ begin ) port map ( clk => clk, - reset => reset or sample_abort_read, - addr => std_logic_vector(sample_addr), - read => instance_read, - ready_in => instance_ready_in, - valid_in => instance_valid_in, - data_in => instance_write_data, - ready_out => instance_ready_out, - valid_out => instance_valid_out, - data_out => instance_read_data - ); - - key_hash_generator_inst : entity work.key_hash_generator(arch) - port ( - clk => clk, - reset => reset or khg_abort, - data_in => khg_data_in, - valid_in => khg_valid_in, - ready_in => khg_ready_in, - last_word_in => khg_last_word_in, - data_out => khg_data_out, - valid_out => khg_valid_out, - ready_out => khg_ready_out, - last_word_out => khg_last_word_out + reset => reset or inst_abort_read, + addr => std_logic_vector(inst_addr), + read => inst_read, + ready_in => inst_ready_in, + valid_in => inst_valid_in, + data_in => inst_write_data, + ready_out => inst_ready_out, + valid_out => inst_valid_out, + data_out => inst_read_data ); end generate; si_sample_state <= si_sample_state_sig; si_view_state <= si_view_state_sig; - si_instance_state <= si_instance_handle_sig; + si_instance_state <= si_instance_state_sig; si_source_timestamp <= si_source_timestamp_sig; si_instance_handle <= si_instance_handle_sig; si_publication_handle <= si_publication_handle_sig; si_disposed_generation_count <= si_disposed_generation_count_sig; si_no_writers_generation_count <= si_no_writers_generation_count_sig; - si_sample_rank <= si_sample_rank_sig; - si_generation_rank <= si_generation_rank_sig; - si_absolute_generation_count <= si_absolute_generation_count_sig; + si_sample_rank <= std_logic_vector(si_sample_rank_sig); + si_generation_rank <= std_logic_vector(si_generation_rank_sig); + si_absolute_generation_count <= std_logic_vector(si_absolute_generation_count_sig); si_valid_data <= si_valid_data_sig; si_valid <= si_valid_sig; status <= status_sig; @@ -551,8 +618,7 @@ begin -- FIND_OLDEST_INST_SAMPLE Find the oldest sample of a specific Instance -- REMOVE_SAMPLE Remove sample and linked payload -- POST_SAMPLE_REMOVE Update Instance Data of removed sample. If Instance Memory is full, and Instance is now eligible for removal, it is removed. - -- SKIP_ADD_REJECT Skip RTPS Cache Change and signal rejection to RTPS. - -- SKIP_ADD_DROP Skip RTPS Cache Change and signal acceptance to RTPS. + -- SKIP_AND_RETURN Skip DDS Input and return latched Return Code -- REMOVE_WRITER Unmark specified Writer Bitmap Position from all stored Instances. (Also updates Instance Data if necessary) -- REMOVE_STALE_INSTANCE Find and remove the first eligible Instance in the memory -- GET_NEXT_SAMPLE Find the next sample in the requested collection @@ -569,7 +635,7 @@ begin -- RESET_PAYLOAD_MEMORY Reset Payload Memory to Empty State 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_bitmap : std_logic_vector(0 to MAX_REMOTE_ENDPOINTS-1) := (others => '0'); variable tmp_update : std_logic_vector(0 to IMF_FLAG_WIDTH-1) := (others => '0'); variable tmp_bool : boolean := FALSE; begin @@ -604,12 +670,12 @@ begin 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; + si_valid_sig_next <= si_valid_sig; 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; + max_samples_latch_next <= max_samples_latch; inst_addr_latch_1_next <= inst_addr_latch_1; inst_addr_latch_2_next <= inst_addr_latch_2; collection_cnt_next <= collection_cnt; @@ -619,8 +685,7 @@ begin 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; + unmark_instances_flag_next <= unmark_instances_flag; dynamic_next_instance_next <= dynamic_next_instance; last_read_ts_next <= last_read_ts; sample_rej_cnt_next <= sample_rej_cnt; @@ -634,22 +699,24 @@ begin lifespan_time_next <= lifespan_time; is_lifespan_check_next <= is_lifespan_check; status_sig_next <= status_sig; + cnt_next <= cnt; cnt2_next <= cnt2; + cnt3_next <= cnt3; lifespan_next <= lifespan; stale_inst_cnt_next <= stale_inst_cnt; + inst_data_next2 <= inst_data; + oldest_sample_next <= oldest_sample; + return_code_latch_next <= return_code_latch; -- DEFAULT Unregistered inst_opcode <= NOP; + opcode_kh <= NOP; ret_rtps <= ERROR; return_code_dds <= RETCODE_UNSUPPORTED; ack_dds <= '0'; done_dds <= '0'; ack_rtps <= '0'; done_rtps <= '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'; @@ -659,8 +726,13 @@ begin payload_valid_in <= '0'; payload_abort_read <= '0'; ready_in_rtps <= '0'; - khg_data_in <= (others => '0'); - writer_bitmap <= (others => '0'); + start_kh <= '0'; + abort_kh <= '0'; + ready_in_kh <= '0'; + valid_out_kh <= '0'; + last_word_out_kh <= '0'; + data_out_kh <= (others => '0'); + writer_bitmap <= ZERO_WRITER_BITMAP_ARRAY; inst_addr_update <= (others => '0'); sample_addr <= (others => '0'); sample_write_data <= (others => '0'); @@ -674,6 +746,7 @@ begin remove_oldest_inst_sample_next <= '0'; remove_oldest_sample_next <= '0'; is_take_next <= '0'; + key_hash_next <= HANDLE_NIL; -- DEADLINE QoS @@ -688,10 +761,10 @@ begin else if (inst_data.status_info(ISI_LIVELINESS_FLAG) = '1') then -- Reset Liveliness Flag - inst_data_next.status_info(ISI_LIVELINESS_FLAG) <= '0'; + inst_data_next2.status_info(ISI_LIVELINESS_FLAG) <= '0'; else -- Update Requested Deadline Missed Status - status_sig_next(REQUESTED_DEADLINE_MISSED_STATUS) <= '1'; + status_sig_next <= status_sig and REQUESTED_DEADLINE_MISSED_STATUS; deadline_miss_cnt_next <= deadline_miss_cnt + 1; deadline_miss_cnt_change_next <= deadline_miss_cnt_change + 1; end if; @@ -710,15 +783,37 @@ begin -- RTPS Operation elsif (start_rtps = '1') then case (opcode_rtps) is - when ADD_CHANGE => - -- NOTE: Because we need to first determine the Instance before making the ACCEPT/REJECT/DROP decision - -- we need to latch the cache change first, calculate the Key Hash if necessary, fetch the associated - -- Instance, and then decide on it. This in effect means that we always need an extra slot in sample and - -- payload memory that is only used as a latch. - ack_rtps <= '1'; - stage_next <= ADD_SAMPLE_INFO; - cur_sample_next <= empty_sample_list_head; - cnt_next <= 0; + when ADD_CACHE_CHANGE => + -- NOTE: We have to explicitly check the Payload Memory, as it may be "unaligned" with our Sample Memory + -- (Sample Memory has available Slot, but Payload Memory not) + -- Payload Memory Full + if (empty_payload_list_head = PAYLOAD_MEMORY_MAX_ADDRESS) then + if (HISTORY_QOS = KEEP_ALL_HISTORY_QOS and RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS) then + ack_rtps <= '1'; + -- Reject Change + stage_next <= SKIP_AND_RETURN; + cnt_next <= 0; + return_code_latch_next <= REJECTED; + else + assert (oldest_sample /= SAMPLE_MEMORY_MAX_ADDRESS) severity FAILURE; + -- Do not ACK Operation + ack_dds <= '0'; + + remove_oldest_sample_next <= '1'; + if (WITH_KEY) then + stage_next <= GET_OLDEST_SAMPLE_INSTANCE; + cnt_next <= 0; + else + cur_sample_next <= oldest_sample; + stage_next <= REMOVE_SAMPLE; + cnt_next <= 0; + end if; + end if; + else + ack_rtps <= '1'; + stage_next <= ADD_SAMPLE_INFO; + cur_sample_next <= empty_sample_list_head; + cnt_next <= 0; end if; when REMOVE_WRITER => ack_rtps <= '1'; @@ -731,29 +826,29 @@ begin cnt_next <= 2; else -- Convert Writer Bitmap to SLV - tmp_bitmap := from_endpoint_bitmap_array(inst_data.writer_bitmap); + tmp_bitmap := from_writer_bitmap_array(inst_data.writer_bitmap); -- Remove Writer tmp_bitmap(to_integer(unsigned(data_in_rtps))) := '0'; -- Convert Back - inst_data_next.writer_bitmap <= to_endpoint_bitmap_array(tmp_bitmap); + inst_data_next2.writer_bitmap <= to_writer_bitmap_array(tmp_bitmap); -- NOT_ALIVE_NO_WRITERS Transition if (tmp_bitmap = (tmp_bitmap'range => '0') and inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '0') then - inst_data_next.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) <= '1'; + inst_data_next2.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) <= '1'; end if; end if; when others => null; end case; -- Unmark Instances - elsif (WITH_KEY and unmark_instances = '1') then + elsif (WITH_KEY and unmark_instances_flag = '1') then -- Memory Operation Guard if (inst_op_done = '1') then inst_op_start <= '1'; inst_opcode <= UNMARK_INSTANCES; - unmark_instances_next <= '0'; + unmark_instances_flag_next <= '0'; end if; -- DDS Operation elsif (start_dds = '1') then @@ -761,14 +856,13 @@ begin sample_state_next <= sample_state_dds; view_state_next <= view_state_dds; instance_state_next <= instance_state; - max_samples_next <= unsigned(max_samples_dds); + max_samples_latch_next <= unsigned(max_samples_dds); -- Reset single_sample_next <= '0'; single_instance_next <= '0' when WITH_KEY else '1'; - collection_cnt_next <= 0; - collection_cnt_max_next <= 0; - is_first_instance_sample_next <= '1'; + collection_cnt_next <= (others => '0'); + collection_cnt_max_next <= (others => '0'); si_sample_state_sig_next <= (others => '0'); si_view_state_sig_next <= (others => '0'); si_instance_state_sig_next <= (others => '0'); @@ -798,28 +892,28 @@ begin stage_next <= GET_NEXT_SAMPLE; cnt_next <= 0; when READ_NEXT_SAMPLE => - ack_dds <= '1'; - single_sample_next <= '1'; - cur_sample_next <= oldest_sample; - cur_inst_next <= INSTANCE_MEMORY_MAX_ADDRESS; - sample_state_next <= NOT_READ_SAMPLE_STATE; - view_state_next <= ANY_VIEW_STATE; - instance_state_next <= ALIVE_INSTANCE_STATE; - max_samples_next <= to_unsigned(1, max_samples'length); - stage_next <= GET_NEXT_SAMPLE; - cnt_next <= 0; + ack_dds <= '1'; + single_sample_next <= '1'; + cur_sample_next <= oldest_sample; + cur_inst_next <= INSTANCE_MEMORY_MAX_ADDRESS; + sample_state_next <= NOT_READ_SAMPLE_STATE; + view_state_next <= ANY_VIEW_STATE; + instance_state_next <= ALIVE_INSTANCE_STATE; + max_samples_latch_next <= to_unsigned(1, max_samples_latch'length); + stage_next <= GET_NEXT_SAMPLE; + cnt_next <= 0; when TAKE_NEXT_SAMPLE => - ack_dds <= '1'; - is_take_next <= '1'; - single_sample_next <= '1'; - cur_sample_next <= oldest_sample; - cur_inst_next <= INSTANCE_MEMORY_MAX_ADDRESS; - sample_state_next <= NOT_READ_SAMPLE_STATE; - view_state_next <= ANY_VIEW_STATE; - instance_state_next <= ALIVE_INSTANCE_STATE; - max_samples_next <= to_unsigned(1, max_samples'length); - stage_next <= GET_NEXT_SAMPLE; - cnt_next <= 0; + ack_dds <= '1'; + is_take_next <= '1'; + single_sample_next <= '1'; + cur_sample_next <= oldest_sample; + cur_inst_next <= INSTANCE_MEMORY_MAX_ADDRESS; + sample_state_next <= NOT_READ_SAMPLE_STATE; + view_state_next <= ANY_VIEW_STATE; + instance_state_next <= ALIVE_INSTANCE_STATE; + max_samples_latch_next <= to_unsigned(1, max_samples_latch'length); + stage_next <= GET_NEXT_SAMPLE; + cnt_next <= 0; when READ_INSTANCE => -- Synthesis Guard if (WITH_KEY) then @@ -903,16 +997,17 @@ begin case (cnt) is -- Status Info when 0 => - -- NOTE: The PAYLOAD_FLAG, ALIGNED_FLAG, and KEY_HASH_FLAG are set by the RTPS Reader + -- NOTE: The PAYLOAD_FLAG and KEY_HASH_FLAG are set by the RTPS Reader -- NOTE: The ALIGNED_FLAG is set by default. if actual Payload is not aligned, need to reset. sample_valid_in <= '1'; sample_addr <= cur_sample + SMF_STATUS_INFO_OFFSET; - sample_write_data <= data_in_rtps; - -- Initialize local status bits + sample_write_data <= data_in_rtps; sample_write_data(SSI_READ_FLAG) <= '0'; + sample_write_data(SSI_ALIGNED_FLAG) <= data_in_rtps(SSI_PAYLOAD_FLAG); -- Latch Status Info - sample_status_info_next <= data_in_rtps; - sample_status_info_next(SSI_READ_FLAG) <= '0'; + sample_status_info_next <= data_in_rtps; + sample_status_info_next(SSI_READ_FLAG) <= '0'; + sample_status_info_next(SSI_ALIGNED_FLAG) <= data_in_rtps(SSI_PAYLOAD_FLAG); -- Memory Flow Control Guard if (sample_ready_in = '1') then ready_in_rtps <= '1'; @@ -924,7 +1019,7 @@ begin sample_addr <= cur_sample + SMF_TIMESTAMP_OFFSET; sample_write_data <= data_in_rtps; -- Latch Timestamp - ts_latch_next(0) <= data_in_rtps; + ts_latch_next(0) <= unsigned(data_in_rtps); -- Memory Flow Control Guard if (sample_ready_in = '1') then ready_in_rtps <= '1'; @@ -936,7 +1031,7 @@ begin sample_addr <= cur_sample + SMF_TIMESTAMP_OFFSET + 1; sample_write_data <= data_in_rtps; -- Latch Timestamp - ts_latch_next(1) <= data_in_rtps; + ts_latch_next(1) <= unsigned(data_in_rtps); -- Memory Flow Control Guard if (sample_ready_in = '1') then ready_in_rtps <= '1'; @@ -952,7 +1047,9 @@ begin -- Timestamp is smaller than highest last read (Or is Invalid) if (tmp_dw /= TIME_INVALID or tmp_dw < last_read_ts) then -- Drop Sample - stage_next <= SKIP_ADD_DROP; + return_code_latch_next <= OK; + stage_next <= SKIP_AND_RETURN; + cnt_next <= 0; end if; end if; end if; @@ -962,7 +1059,7 @@ begin sample_addr <= cur_sample + SMF_LIFESPAN_DEADLINE_OFFSET; sample_write_data <= data_in_rtps; -- Latch Lifespan - lifespan_next(0) <= data_in_rtps; + lifespan_next(0) <= unsigned(data_in_rtps); -- Memory Flow Control Guard if (sample_ready_in = '1') then ready_in_rtps <= '1'; @@ -974,7 +1071,7 @@ begin sample_addr <= cur_sample + SMF_LIFESPAN_DEADLINE_OFFSET + 1; sample_write_data <= data_in_rtps; -- Latch Lifespan - lifespan_next(1) <= data_in_rtps; + lifespan_next(1) <= unsigned(data_in_rtps); -- Memory Flow Control Guard if (sample_ready_in = '1') then ready_in_rtps <= '1'; @@ -1008,42 +1105,69 @@ begin -- Writer Endpoint Position when 9 => -- Latch Input, but do not pass to Memory - writer_pos_next <= to_integer(unsigned(data_in_rtps)); - stage_next <= ADD_PAYLOAD_ADDRESS; + writer_pos_next <= to_integer(unsigned(data_in_rtps)); + cnt_next <= cnt + 1; + -- Payload Address + when 10 => + assert (empty_payload_list_head /= PAYLOAD_MEMORY_MAX_ADDRESS) severity FAILURE; + sample_valid_in <= '1'; + sample_addr <= cur_sample + SMF_PAYLOAD_ADDR_OFFSET; + if (has_data = '1') then + -- Store Payload Address + sample_write_data <= std_logic_vector(resize(empty_payload_list_head, WORD_WIDTH)); + + cur_payload_next <= empty_payload_list_head; + else + -- Mark Sample with no Payload + sample_write_data <= std_logic_vector(resize(PAYLOAD_MEMORY_MAX_ADDRESS, WORD_WIDTH)); + end if; + + -- Memory Flow Control Guard + if (sample_ready_in = '1') then + -- If Key Hash is available, start the Instance Search first + if (WITH_KEY and has_key_hash = '1') then + stage_next <= INITIATE_INSTANCE_SEARCH; + -- Key Hash Needs to be Calculated + elsif (WITH_KEY and has_key_hash = '0') then + cnt_next <= cnt + 1; + elsif (has_data = '1') then + assert (not WITH_KEY) severity FAILURE; + stage_next <= ADD_PAYLOAD; + cnt_next <= 0; + cnt2_next <= 1; + else -- has_data = '0' + assert (not WITH_KEY) severity FAILURE; + stage_next <= FILTER_STAGE; + end if; + end if; + -- Initiate KH Operation + when 11 => + -- Synthesis Guard + if (WITH_KEY) then + start_kh <= '1'; + -- Payload is Serialized Key + if (has_data = '0') then + opcode_kh <= PUSH_SERIALIZED_KEY; + else + opcode_kh <= PUSH_DATA; + end if; + + if (ack_kh = '1') then + -- Payload is Serialized Key + if (has_data = '0') then + stage_next <= ADD_PAYLOAD; + cnt_next <= 1; + else + stage_next <= ADD_PAYLOAD; + cnt_next <= 0; + cnt2_next <= 1; + end if; + end if; + end if; when others => null; end case; end if; - when ADD_PAYLOAD_ADDRESS => - -- Precondition: cur_sample set - - sample_valid_in <= '1'; - sample_addr <= cur_sample + SMF_PAYLOAD_ADDR_OFFSET; - if (has_data = '1') then - -- Store Payload Address - sample_write_data <= empty_payload_list_head; - - cur_payload_next <= empty_payload_list_head; - else - -- Mark Sample with no Payload - sample_write_data <= PAYLOAD_MEMORY_MAX_ADDRESS; - end if; - - -- Memory Flow Control Guard - if (sample_ready_in = '1') then - -- If Key Hash is available, start the Instance Search first - if (WITH_KEY and has_key_hash = '1') then - stage_next <= INITIATE_INSTANCE_SEARCH; - elsif (has_data = '1') then - stage_next <= ADD_PAYLOAD; - cnt_next <= 0; - elsif (has_data = '0' and (WITH_KEY and has_key_hash = '0')) then - stage_next <= ADD_PAYLOAD; - cnt_next <= 1; - else -- has_data = '0' and (not WITH_KEY) - stage_next <= FILTER_STAGE; - end if; - end if; when ADD_PAYLOAD => -- Precondition (if has_data = '1'): cur_payload set (Current Slot) @@ -1076,6 +1200,7 @@ begin stage_next <= FILTER_STAGE; else stage_next <= ALIGN_PAYLOAD; + cnt_next <= 0; end if; else -- End of Payload Slot @@ -1096,26 +1221,30 @@ begin if (WITH_KEY) then -- Input Guard if (valid_in_rtps = '1') then - khg_valid_in <= '1'; - khg_data_in <= data_in_rtps; + valid_out_kh <= '1'; + data_out_kh <= data_in_rtps; -- Output Guard - if (khg_ready_in = '1') then + if (ready_out_kh = '1') then ready_in_rtps <= '1'; + if (has_data = '1') then -- End of Payload if (last_word_in_rtps = '1') then + last_word_out_kh <= '1'; -- End of Payload Slot - if (cnt2 = PAYLOAD_FRAME_SIZE) then + if (cnt2 = PAYLOAD_FRAME_SIZE-1) then -- Fetch the Key Hash stage_next <= GET_KEY_HASH; cnt_next <= 0; + cnt2_next <= 0; else stage_next <= ALIGN_PAYLOAD; + cnt_next <= 0; end if; else -- End of Payload Slot - if (cnt2 = PAYLOAD_FRAME_SIZE) then + if (cnt2 = PAYLOAD_FRAME_SIZE-1) then stage_next <= NEXT_PAYLOAD_SLOT; cnt_next <= 0; else @@ -1127,9 +1256,11 @@ begin else -- End of Payload if (last_word_in_rtps = '1') then + last_word_out_kh <= '1'; -- Fetch the Key Hash stage_next <= GET_KEY_HASH; cnt_next <= 0; + cnt2_next <= 0; else -- Next Word cnt_next <= 1; -- Same Sub-state @@ -1162,14 +1293,22 @@ begin -- Memory Control Flow Guard if (payload_valid_out = '1') then -- No Empty Payload Slots available - if (payload_read_data = PAYLOAD_MEMORY_MAX_ADDRESS) then + if (resize(unsigned(payload_read_data),PAYLOAD_MEMORY_ADDR_WIDTH) = PAYLOAD_MEMORY_MAX_ADDRESS) then -- Reject Change - stage_next <= SKIP_ADD_REJECT; + return_code_latch_next <= REJECTED; + stage_next <= SKIP_AND_RETURN; + cnt_next <= 0; -- Abort Key Hash Generation - khg_abort <= '1'; + abort_kh <= '1'; + -- Update Sample Reject Status + status_sig_next <= status_sig and SAMPLE_REJECTED_STATUS; + sample_rej_cnt_next <= sample_rej_cnt + 1; + sample_rej_cnt_change_next <= sample_rej_cnt_change + 1; + sample_rej_last_reason_next <= REJECTED_BY_SAMPLES_LIMIT; + sample_rej_last_inst_next <= key_hash; else -- Latch next Payload Slot and Continue - cur_payload_next <= payload_read_data; + cur_payload_next <= resize(unsigned(payload_read_data),PAYLOAD_MEMORY_ADDR_WIDTH); stage_next <= ADD_PAYLOAD; cnt_next <= 0; cnt2_next <= 1; @@ -1195,13 +1334,14 @@ begin when 1 => payload_valid_in <= '1'; payload_addr <= cur_payload + PAYLOAD_FRAME_SIZE-1; - payload_write_data <= to_unsigned(cnt2, WORD_WIDTH); + payload_write_data <= std_logic_vector(to_unsigned(cnt2, WORD_WIDTH)); -- Memory Control Flow Guard if (payload_ready_in = '1') then if (WITH_KEY and has_key_hash = '0') then stage_next <= GET_KEY_HASH; cnt_next <= 0; + cnt2_next <= 0; else stage_next <= FILTER_STAGE; end if; @@ -1212,20 +1352,34 @@ begin when GET_KEY_HASH => -- Synthesis Guard if (WITH_KEY) then - khg_ready_out <= '1'; + case (cnt) is + -- Initiate READ Operation + when 0 => + start_kh <= '1'; + opcode_kh <= READ_KEY_HASH; + + if (ack_kh = '1') then + cnt_next <= cnt + 1; + end if; + -- READ Key Hash + when 1 => + ready_in_kh <= '1'; - if (khg_valid_out = '1') then - cnt_next <= cnt + 1; - - -- Latch Key Hash - key_hash_next(cnt) <= khg_data_out; - - -- Exit Condition - if (khg_last_word_out = '1') then - -- DONE - stage_next <= INITIATE_INSTANCE_SEARCH; - end if; - end if; + if (valid_in_kh = '1') then + cnt2_next <= cnt2 + 1; + + -- Latch Key Hash + key_hash_next(cnt2) <= data_in_kh; + + -- Exit Condition + if (last_word_in_kh = '1') then + -- DONE + stage_next <= INITIATE_INSTANCE_SEARCH; + end if; + end if; + when others => + null; + end case; end if; when INITIATE_INSTANCE_SEARCH => -- Synthesis Guard @@ -1238,8 +1392,9 @@ begin -- Payload not yet stored if (has_data = '1' and WITH_KEY and has_key_hash = '1') then - stage_next <= ADD_PAYLOAD; - cnt_next <= 0; + stage_next <= ADD_PAYLOAD; + cnt_next <= 0; + cnt2_next <= 1; else stage_next <= FILTER_STAGE; end if; @@ -1263,14 +1418,14 @@ begin ret_rtps <= OK; stage_next <= IDLE; -- RESOURCE_LIMITS_QOS (MAX_SAMPLES_PER_INSTANCE) - elsif (WITH_KEY and MAX_SAMPLES_PER_INSTANCE /= LENGTH_UNLIMITED and inst_data.sample_cnt = MAX_SAMPLES_PER_INSTANCE) then + elsif (WITH_KEY and MAX_SAMPLES_PER_INSTANCE /= LENGTH_UNLIMITED and inst_data.sample_cnt = unsigned(MAX_SAMPLES_PER_INSTANCE)) then if (HISTORY_QOS = KEEP_ALL_HISTORY_QOS and RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS) then -- Reject Change done_rtps <= '1'; ret_rtps <= REJECTED; stage_next <= IDLE; -- Update Sample Reject Status - status_sig_next(SAMPLE_REJECTED_STATUS) <= '1'; + status_sig_next <= status_sig and SAMPLE_REJECTED_STATUS; sample_rej_cnt_next <= sample_rej_cnt + 1; sample_rej_cnt_change_next <= sample_rej_cnt_change + 1; sample_rej_last_reason_next <= REJECTED_BY_SAMPLES_PER_INSTANCE_LIMIT; @@ -1290,7 +1445,7 @@ begin ret_rtps <= REJECTED; stage_next <= IDLE; -- Update Sample Reject Status - status_sig_next(SAMPLE_REJECTED_STATUS) <= '1'; + status_sig_next <= status_sig and SAMPLE_REJECTED_STATUS; sample_rej_cnt_next <= sample_rej_cnt + 1; sample_rej_cnt_change_next <= sample_rej_cnt_change + 1; sample_rej_last_reason_next <= REJECTED_BY_SAMPLES_LIMIT; @@ -1328,7 +1483,7 @@ begin ret_rtps <= REJECTED; stage_next <= IDLE; -- Update Sample Reject Status - status_sig_next(SAMPLE_REJECTED_STATUS) <= '1'; + status_sig_next <= status_sig and SAMPLE_REJECTED_STATUS; sample_rej_cnt_next <= sample_rej_cnt + 1; sample_rej_cnt_change_next <= sample_rej_cnt_change + 1; sample_rej_last_reason_next <= REJECTED_BY_SAMPLES_LIMIT; @@ -1344,7 +1499,7 @@ begin -- DONE stage_next <= IDLE; -- Update Sample Reject Status - status_sig_next(SAMPLE_REJECTED_STATUS) <= '1'; + status_sig_next <= status_sig and SAMPLE_REJECTED_STATUS; sample_rej_cnt_next <= sample_rej_cnt + 1; sample_rej_cnt_change_next <= sample_rej_cnt_change + 1; sample_rej_last_reason_next <= REJECTED_BY_INSTANCES_LIMIT; @@ -1369,13 +1524,14 @@ begin ret_rtps <= OK; -- Insert New Instance - inst_op_start <= '1'; - inst_opcode <= INSERT_INSTANCE; - status_info_update <= (ISI_LIVELINESS_FLAG => '1', others => '0'); - sample_cnt <= to_unsigned(1, WORD_WIDTH); - deadline <= (time + TIME_BASED_FILTER_QOS) when (TIME_BASED_FILTER_QOS /= DURATION_ZERO) else TIME_INVALID; - tmp_bitmap := (writer_pos => '1', others => '0'); - writer_bitmap <= to_endpoint_bitmap_array(tmp_bitmap); + inst_op_start <= '1'; + inst_opcode <= INSERT_INSTANCE; + status_info_update <= (ISI_LIVELINESS_FLAG => '1', others => '0'); + sample_cnt <= to_unsigned(1, WORD_WIDTH); + deadline <= (time + TIME_BASED_FILTER_QOS) when (TIME_BASED_FILTER_QOS /= DURATION_ZERO) else TIME_INVALID; + tmp_bitmap := (others => '0'); + tmp_bitmap(writer_pos) := '1'; + writer_bitmap <= to_writer_bitmap_array(tmp_bitmap); if (has_data = '1') then stage_next <= FINALIZE_PAYLOAD; @@ -1397,7 +1553,7 @@ begin -- DONE stage_next <= IDLE; -- Update Sample Reject Status - status_sig_next(SAMPLE_REJECTED_STATUS) <= '1'; + status_sig_next <= status_sig and SAMPLE_REJECTED_STATUS; sample_rej_cnt_next <= sample_rej_cnt + 1; sample_rej_cnt_change_next <= sample_rej_cnt_change + 1; sample_rej_last_reason_next <= REJECTED_BY_INSTANCES_LIMIT; @@ -1408,13 +1564,14 @@ begin ret_rtps <= OK; -- Insert New Instance - inst_op_start <= '1'; - inst_opcode <= INSERT_INSTANCE; - status_info_update <= (ISI_LIVELINESS_FLAG => '1', others = '0'); - sample_cnt <= to_unsigned(1, WORD_WIDTH); - deadline <= (time + TIME_BASED_FILTER_QOS) when (TIME_BASED_FILTER_QOS /= DURATION_ZERO) else TIME_INVALID; - tmp_bitmap := (writer_pos => '1', others => '0'); - writer_bitmap <= to_endpoint_bitmap_array(tmp_bitmap); + inst_op_start <= '1'; + inst_opcode <= INSERT_INSTANCE; + status_info_update <= (ISI_LIVELINESS_FLAG => '1', others => '0'); + sample_cnt <= to_unsigned(1, WORD_WIDTH); + deadline <= (time + TIME_BASED_FILTER_QOS) when (TIME_BASED_FILTER_QOS /= DURATION_ZERO) else TIME_INVALID; + tmp_bitmap := (others => '0'); + tmp_bitmap(writer_pos) := '1'; + writer_bitmap <= to_writer_bitmap_array(tmp_bitmap); if (has_data = '1') then stage_next <= FINALIZE_PAYLOAD; @@ -1430,13 +1587,14 @@ begin ret_rtps <= OK; -- Insert New Instance - inst_op_start <= '1'; - inst_opcode <= INSERT_INSTANCE; - status_info_update <= (ISI_LIVELINESS_FLAG => '1', others => '0'); - sample_cnt <= to_unsigned(1, WORD_WIDTH); - deadline <= (time + TIME_BASED_FILTER_QOS) when (TIME_BASED_FILTER_QOS /= DURATION_ZERO) else TIME_INVALID; - tmp_bitmap := (writer_pos => '1', others => '0'); - writer_bitmap <= to_endpoint_bitmap_array(tmp_bitmap); + inst_op_start <= '1'; + inst_opcode <= INSERT_INSTANCE; + status_info_update <= (ISI_LIVELINESS_FLAG => '1', others => '0'); + sample_cnt <= to_unsigned(1, WORD_WIDTH); + deadline <= (time + TIME_BASED_FILTER_QOS) when (TIME_BASED_FILTER_QOS /= DURATION_ZERO) else TIME_INVALID; + tmp_bitmap := (others => '0'); + tmp_bitmap(writer_pos) := '1'; + writer_bitmap <= to_writer_bitmap_array(tmp_bitmap); if (has_data = '1') then stage_next <= FINALIZE_PAYLOAD; @@ -1459,7 +1617,7 @@ begin status_info_update <= inst_data.status_info; status_info_update(ISI_LIVELINESS_FLAG) <= '1'; else - inst_data_next.status_info(ISI_LIVELINESS_FLAG) <= '1'; + inst_data_next2.status_info(ISI_LIVELINESS_FLAG) <= '1'; end if; @@ -1472,24 +1630,24 @@ begin if (WITH_KEY) then status_info_update(ISI_NOT_ALIVE_DISPOSED_FLAG) <= '1'; else - inst_data_next.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) <= '1'; + inst_data_next2.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) <= '1'; end if; end if; -- Instance UNREGISTERED elsif (sample_status_info(SSI_UNREGISTERED_FLAG) = '1') then -- WRITER BITMAP -- Convert Writer Bitmap to SLV - tmp_bitmap := from_endpoint_bitmap_array(inst_data.writer_bitmap); + tmp_bitmap := from_writer_bitmap_array(inst_data.writer_bitmap); -- Remove Writer tmp_bitmap(writer_pos) := '0'; -- Convert Back -- Synthesis Guard if (WITH_KEY) then - writer_bitmap <= to_endpoint_bitmap_array(tmp_bitmap); + writer_bitmap <= to_writer_bitmap_array(tmp_bitmap); tmp_update := tmp_update or IMF_WRITER_BITMAP_FLAG; else - inst_data_next.writer_bitmap <= to_endpoint_bitmap_array(tmp_bitmap); + inst_data_next2.writer_bitmap <= to_writer_bitmap_array(tmp_bitmap); end if; -- ALIVE -> NOT_ALIVE_NO_WRITERS Transition @@ -1499,7 +1657,7 @@ begin if (WITH_KEY) then status_info_update(ISI_NOT_ALIVE_NO_WRITERS_FLAG) <= '1'; else - inst_data_next.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) <= '1'; + inst_data_next2.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) <= '1'; end if; end if; -- Instance ALIVE/FILTERED @@ -1510,8 +1668,8 @@ begin status_info_update(ISI_NOT_ALIVE_DISPOSED_FLAG) <= '0'; status_info_update(ISI_NOT_ALIVE_NO_WRITERS_FLAG) <= '0'; else - inst_data_next.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) <= '0'; - inst_data_next.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) <= '0'; + inst_data_next2.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) <= '0'; + inst_data_next2.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) <= '0'; end if; @@ -1524,8 +1682,8 @@ begin gen_cnt <= inst_data.disposed_gen_cnt + 1; status_info_update(ISI_VIEW_FLAG) <= '0'; else - inst_data_next.disposed_gen_cnt <= inst_data.disposed_gen_cnt + 1; - inst_data_next.status_info(ISI_VIEW_FLAG) <= '0'; + inst_data_next2.disposed_gen_cnt <= inst_data.disposed_gen_cnt + 1; + inst_data_next2.status_info(ISI_VIEW_FLAG) <= '0'; end if; -- NOT_ALIVE_NO_WRITERS -> ALIVE Transition elsif (inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '1') then @@ -1535,14 +1693,14 @@ begin gen_cnt <= inst_data.no_writers_gen_cnt + 1; status_info_update(ISI_VIEW_FLAG) <= '0'; else - inst_data_next.no_writers_gen_cnt <= inst_data.no_writers_gen_cnt + 1; - inst_data_next.status_info(ISI_VIEW_FLAG) <= '0'; + inst_data_next2.no_writers_gen_cnt <= inst_data.no_writers_gen_cnt + 1; + inst_data_next2.status_info(ISI_VIEW_FLAG) <= '0'; end if; end if; -- WRITER BITMAP -- Convert Writer Bitmap to SLV - tmp_bitmap := from_endpoint_bitmap_array(inst_data.writer_bitmap); + tmp_bitmap := from_writer_bitmap_array(inst_data.writer_bitmap); -- Write if Writer New for Instance if (tmp_bitmap(writer_pos) /= '1') then -- Insert Writer @@ -1550,10 +1708,10 @@ begin -- Convert Back -- Synthesis Guard if (WITH_KEY) then - writer_bitmap <= to_endpoint_bitmap_array(tmp_bitmap); + writer_bitmap <= to_writer_bitmap_array(tmp_bitmap); tmp_update := tmp_update or IMF_WRITER_BITMAP_FLAG; else - inst_data_next.writer_bitmap <= to_endpoint_bitmap_array(tmp_bitmap); + inst_data_next2.writer_bitmap <= to_writer_bitmap_array(tmp_bitmap); end if; end if; end if; @@ -1564,7 +1722,7 @@ begin tmp_update := tmp_update or IMF_SAMPLE_CNT_FLAG; sample_cnt <= inst_data.sample_cnt + 1; else - inst_data_next.sample_cnt <= inst_data.sample_cnt + 1; + inst_data_next2.sample_cnt <= inst_data.sample_cnt + 1; end if; -- IGNORE DEADLINE @@ -1574,7 +1732,7 @@ begin tmp_update := tmp_update or IMF_IGNORE_DEADLINE_FLAG; deadline <= time + TIME_BASED_FILTER_QOS; else - inst_data_next.ignore_deadline <= time + TIME_BASED_FILTER_QOS; + inst_data_next2.ignore_deadline <= time + TIME_BASED_FILTER_QOS; end if; end if; @@ -1582,7 +1740,7 @@ begin if (WITH_KEY) then -- STALE INSTANCE COUNT -- Instance was Stale - if (inst_data.sample_cnt = 0 and inst_data.writer_bitmap = ZERO_ENDPOINT_BITMAP_ARRAY) then + if (inst_data.sample_cnt = 0 and inst_data.writer_bitmap = ZERO_WRITER_BITMAP_ARRAY) then assert (stale_inst_cnt /= 0) severity FAILURE; -- NOTE: The UPDATE_INSTANCE state is only taken if a new Sample is added to an existing Instance. -- Since Instances with Samples are not stale, we have to unmark the Instance. @@ -1621,7 +1779,7 @@ begin payload_valid_in <= '1'; payload_addr <= cur_payload + PMF_NEXT_ADDR_OFFSET; -- Make current Slot the Tail - payload_write_data <= PAYLOAD_MEMORY_MAX_ADDRESS; + payload_write_data <= std_logic_vector(resize(PAYLOAD_MEMORY_MAX_ADDRESS,WORD_WIDTH)); -- Memory Control Flow Guard if (payload_ready_in = '1') then @@ -1634,7 +1792,7 @@ begin -- Memory Control Flow Guard if (payload_valid_out = '1') then -- Fix New Empty List Head - empty_payload_list_head_next <= payload_read_data; + empty_payload_list_head_next <= resize(unsigned(payload_read_data),PAYLOAD_MEMORY_ADDR_WIDTH); stage_next <= PRE_SAMPLE_FINALIZE; cnt_next <= 0; @@ -1654,7 +1812,7 @@ begin sample_valid_in <= '1'; sample_addr <= cur_sample + SMF_DISPOSED_GEN_CNT_OFFSET; - sample_write_data <= inst_data.disposed_gen_cnt; + sample_write_data <= std_logic_vector(inst_data.disposed_gen_cnt); -- Memory Flow Control Guard if (sample_ready_in = '1') then @@ -1665,7 +1823,7 @@ begin sample_valid_in <= '1'; sample_addr <= cur_sample + SMF_NO_WRITERS_GEN_CNT_OFFSET; - sample_write_data <= inst_data.no_writers_gen_cnt; + sample_write_data <= std_logic_vector(inst_data.no_writers_gen_cnt); -- Memory Flow Control Guard if (sample_ready_in = '1') then @@ -1765,7 +1923,7 @@ begin if (sample_valid_out = '1') then -- No previous Slot (Oldest Sample) - if (sample_read_data = PAYLOAD_MEMORY_MAX_ADDRESS) then + if (resize(unsigned(sample_read_data),PAYLOAD_MEMORY_ADDR_WIDTH) = PAYLOAD_MEMORY_MAX_ADDRESS) then assert (prev_sample = oldest_sample) report "Previous Sample is MAX_ADDR, but sample is not OLDEST (HEAD)" severity FAILURE; -- NOTE: Sample is added to HEAD of List @@ -1776,11 +1934,13 @@ begin cnt_next <= 1; -- Skip to Previous Pointer Fix else -- Continue Search - cur_sample_next <= sample_read_data; + cur_sample_next <= resize(unsigned(sample_read_data),SAMPLE_MEMORY_ADDR_WIDTH); next_sample_next <= cur_sample; cnt_next <= 0; end if; end if; + when others => + null; end case; end if; when FIX_POINTERS => @@ -1792,7 +1952,7 @@ begin -- Fix Next Pointer sample_valid_in <= '1'; sample_addr <= prev_sample + SMF_NEXT_ADDR_OFFSET; - sample_write_data <= empty_sample_list_head; + sample_write_data <= std_logic_vector(resize(empty_sample_list_head,WORD_WIDTH)); -- Memory Flow Control Guard if (sample_ready_in = '1') then @@ -1812,7 +1972,7 @@ begin -- Fix Previous Pointer sample_valid_in <= '1'; sample_addr <= next_sample + SMF_PREV_ADDR_OFFSET; - sample_write_data <= empty_sample_list_head; + sample_write_data <= std_logic_vector(resize(empty_sample_list_head,WORD_WIDTH)); -- Memory Flow Control Guard if (sample_ready_in = '1') then @@ -1834,36 +1994,44 @@ begin sample_read <= '1'; -- Memory Flow Control Guard if (sample_ready_in = '1') then - cnt_next <= cnt + 1; + -- Synthesis Guard + if (WITH_KEY) then + cnt_next <= cnt + 1; + else + cnt_next <= cnt + 2; + end if; end if; - -- Instance Pointer + -- SET Instance Pointer when 1 => - -- Write Instance Pointer - sample_valid_in <= '1'; - sample_addr <= cur_sample + SMF_INSTANCE_ADDR_OFFSET; - sample_write_data <= cur_inst; - - -- Memory Flow Control Guard - if (sample_ready_in = '1') then - cnt_next <= cnt + 1; + -- Synthesis Guard + if (WITH_KEY) then + -- Write Instance Pointer + sample_valid_in <= '1'; + sample_addr <= cur_sample + SMF_INSTANCE_ADDR_OFFSET; + sample_write_data <= std_logic_vector(resize(cur_inst,WORD_WIDTH)); + + -- Memory Flow Control Guard + if (sample_ready_in = '1') then + cnt_next <= cnt + 1; + end if; end if; - -- Previous Pointer + -- SET Previous Pointer when 2 => -- Write Previous Pointer sample_valid_in <= '1'; sample_addr <= cur_sample + SMF_PREV_ADDR_OFFSET; - sample_write_data <= prev_sample; + sample_write_data <= std_logic_vector(resize(prev_sample,WORD_WIDTH)); -- Memory Flow Control Guard if (sample_ready_in = '1') then cnt_next <= cnt + 1; end if; - -- Next Pointer + -- SET Next Pointer when 3 => -- Write Next Pointer sample_valid_in <= '1'; sample_addr <= cur_sample + SMF_NEXT_ADDR_OFFSET; - sample_write_data <= next_sample; + sample_write_data <= std_logic_vector(resize(next_sample,WORD_WIDTH)); -- Memory Flow Control Guard if (sample_ready_in = '1') then @@ -1878,7 +2046,7 @@ begin if (sample_valid_out = '1') then -- Fix new Empty List Head - empty_sample_list_head_next <= sample_read_data; + empty_sample_list_head_next <= resize(unsigned(sample_read_data),SAMPLE_MEMORY_ADDR_WIDTH); -- If newest Sample is now previous, select current sample as new newest if (newest_sample = prev_sample) then @@ -1886,7 +2054,7 @@ begin end if; -- Signal Data Available - status_sig_next(DATA_AVAILABLE_STATUS) <= '1'; + status_sig_next <= status_sig and DATA_AVAILABLE_STATUS; -- Update Lifespan Check Time if (lifespan /= TIME_INVALID and lifespan < lifespan_time) then @@ -1900,15 +2068,19 @@ begin -- Synthesis Guard if (WITH_KEY) then stage_next <= GET_OLDEST_SAMPLE_INSTANCE; + cnt_next <= 0; else cur_sample_next <= oldest_sample; stage_next <= REMOVE_SAMPLE; + cnt_next <= 0; end if; else -- DONE stage_next <= IDLE; end if; end if; + when others => + null; end case; when GET_OLDEST_SAMPLE_INSTANCE => -- Synthesis Guard @@ -1938,10 +2110,11 @@ begin inst_op_start <= '1'; inst_opcode <= SEARCH_INSTANCE_ADDR; inst_mem_fields <= IMF_SAMPLE_CNT_FLAG or IMF_WRITER_BITMAP_FLAG; - inst_addr_update <= sample_read_data; + inst_addr_update <= resize(unsigned(sample_read_data),INSTANCE_MEMORY_ADDR_WIDTH); - cur_sample_next <= oldest_sample; - stage_next <= REMOVE_SAMPLE; + cur_sample_next <= oldest_sample; + stage_next <= REMOVE_SAMPLE; + cnt_next <= 0; end if; end if; when others => @@ -1975,13 +2148,13 @@ begin cnt_next <= cnt + 1; end if; -- READ Instance Pointer - when 1 => + when 2 => sample_ready_out <= '1'; -- Memory Flow Control Guard if (sample_valid_out = '1') then -- Oldest Instance Sample Found - if (sample_read_data = cur_inst) then + if (resize(unsigned(sample_read_data),INSTANCE_MEMORY_ADDR_WIDTH) = cur_inst) then stage_next <= REMOVE_SAMPLE; sample_abort_read <= '1'; else @@ -1989,12 +2162,12 @@ begin end if; end if; -- READ Next Sample - when 2 => + when 3 => sample_ready_out <= '1'; -- Memory Flow Control Guard if (sample_valid_out = '1') then - cur_sample_next <= sample_read_data; + cur_sample_next <= resize(unsigned(sample_read_data),SAMPLE_MEMORY_ADDR_WIDTH); cnt_next <= 0; end if; when others => @@ -2043,7 +2216,7 @@ begin sample_ready_out <= '1'; -- Memory Flow Control Guard if (sample_valid_out = '1') then - prev_sample_next <= sample_read_data; + prev_sample_next <= resize(unsigned(sample_read_data),SAMPLE_MEMORY_ADDR_WIDTH); cnt_next <= cnt + 1; end if; -- READ Next Sample @@ -2051,7 +2224,7 @@ begin sample_ready_out <= '1'; -- Memory Flow Control Guard if (sample_valid_out = '1') then - next_sample_next <= sample_read_data; + next_sample_next <= resize(unsigned(sample_read_data),SAMPLE_MEMORY_ADDR_WIDTH); -- Sample Memory Full if (empty_sample_list_head = SAMPLE_MEMORY_MAX_ADDRESS) then @@ -2067,7 +2240,7 @@ begin -- Add Current Sample after Empty List Tail sample_valid_in <= '1'; sample_addr <= empty_sample_list_tail + SMF_NEXT_ADDR_OFFSET; - sample_write_data <= cur_sample; + sample_write_data <= std_logic_vector(resize(cur_sample,WORD_WIDTH)); -- Memory Flow Control Guard if (sample_ready_in = '1') then @@ -2078,7 +2251,7 @@ begin -- Make Current Sample Empty List Tail sample_valid_in <= '1'; sample_addr <= cur_sample + SMF_NEXT_ADDR_OFFSET; - sample_write_data <= INSTANCE_MEMORY_MAX_ADDRESS; + sample_write_data <= std_logic_vector(resize(INSTANCE_MEMORY_MAX_ADDRESS,WORD_WIDTH)); -- Memory Flow Control Guard if (sample_ready_in = '1') then @@ -2096,10 +2269,10 @@ begin if (prev_sample = SAMPLE_MEMORY_MAX_ADDRESS) then assert (cur_sample = oldest_sample) report "Previous Sample is MAX_ADDR, but cur_sample /= oldest_sample" severity FAILURE; assert (newest_sample = oldest_sample) report "Previous and Next Sample is MAX_ADDR, but cur_sample /= newest_sample /= oldest_sample" severity FAILURE; + -- NOTE: Sample Memory Empty (newest_sample also set to MAX_ADDR) -- Fix Oldest Pointer oldest_sample_next <= SAMPLE_MEMORY_MAX_ADDRESS; - -- NOTE: Sample Memory Empty (newest_sample also set to MAX_ADDR) cnt_next <= cnt + 3; -- Skip next 2 steps else @@ -2114,7 +2287,7 @@ begin -- Remove link to cur_sample sample_valid_in <= '1'; sample_addr <= next_sample + SMF_PREV_ADDR_OFFSET; - sample_write_data <= prev_sample; + sample_write_data <= std_logic_vector(resize(prev_sample,WORD_WIDTH)); -- Memory Flow Control Guard if (sample_ready_in = '1') then @@ -2123,7 +2296,7 @@ begin assert (cur_sample = oldest_sample) report "Previous Sample is MAX_ADDR, but cur_sample /= oldest_sample" severity FAILURE; -- Fix Oldest Pointer - oldest_sample_next <= SAMPLE_MEMORY_MAX_ADDRESS; + oldest_sample_next <= next_sample; cnt_next <= cnt + 2; -- Skip next step else @@ -2135,7 +2308,7 @@ begin -- Remove link to cur_sample sample_valid_in <= '1'; sample_addr <= prev_sample + SMF_NEXT_ADDR_OFFSET; - sample_write_data <= next_sample; + sample_write_data <= std_logic_vector(resize(next_sample,WORD_WIDTH)); -- Memory Flow Control Guard if (sample_ready_in = '1') then @@ -2147,17 +2320,17 @@ begin -- Memory Flow Control Guard if (sample_valid_out = '1') then - cur_payload_next <= sample_read_data; + cur_payload_next <= resize(unsigned(sample_read_data),PAYLOAD_MEMORY_ADDR_WIDTH); -- Sample has no Data - if (sample_read_data = PAYLOAD_MEMORY_MAX_ADDRESS) then + if (resize(unsigned(sample_read_data),PAYLOAD_MEMORY_ADDR_WIDTH) = PAYLOAD_MEMORY_MAX_ADDRESS) then stage_next <= POST_SAMPLE_REMOVE; -- Payload Memory Full elsif (empty_payload_list_head = PAYLOAD_MEMORY_MAX_ADDRESS) then - empty_payload_list_head_next <= sample_read_data; + empty_payload_list_head_next <= resize(unsigned(sample_read_data),PAYLOAD_MEMORY_ADDR_WIDTH); stage_next <= POST_SAMPLE_REMOVE; else - empty_payload_list_head_next <= sample_read_data; + empty_payload_list_head_next <= resize(unsigned(sample_read_data),PAYLOAD_MEMORY_ADDR_WIDTH); cnt_next <= cnt + 1; end if; end if; @@ -2178,10 +2351,10 @@ begin -- Memory Flow Control Guard if (payload_valid_out = '1') then -- Found Empty List Tail - if (payload_read_data = PAYLOAD_MEMORY_MAX_ADDRESS) then + if (resize(unsigned(payload_read_data),PAYLOAD_MEMORY_ADDR_WIDTH) = PAYLOAD_MEMORY_MAX_ADDRESS) then cnt_next <= cnt + 1; else - cur_payload_next <= payload_read_data; + cur_payload_next <= resize(unsigned(payload_read_data),PAYLOAD_MEMORY_ADDR_WIDTH); cnt_next <= cnt - 1; end if; end if; @@ -2189,7 +2362,7 @@ begin when 12 => payload_valid_in <= '1'; payload_addr <= cur_payload + PMF_NEXT_ADDR_OFFSET; - payload_write_data <= empty_payload_list_head; + payload_write_data <= std_logic_vector(resize(empty_payload_list_head,WORD_WIDTH)); -- Memory Flow Control Guard if (payload_ready_in = '1') then @@ -2205,7 +2378,7 @@ begin -- Synthesis Guard if (WITH_KEY) then -- Stale Instance Update - if (inst_data.sample_cnt = 1 and inst_data.writer_bitmap = ZERO_ENDPOINT_BITMAP_ARRAY) then + if (inst_data.sample_cnt = 1 and inst_data.writer_bitmap = ZERO_WRITER_BITMAP_ARRAY) then stale_inst_cnt_next <= stale_inst_cnt - 1; end if; @@ -2214,7 +2387,7 @@ begin inst_mem_fields <= IMF_SAMPLE_CNT_FLAG; sample_cnt <= inst_data.sample_cnt - 1; else - inst_data_next.sample_cnt <= inst_data.sample_cnt - 1; + inst_data_next2.sample_cnt <= inst_data.sample_cnt - 1; end if; if (is_take = '1') then @@ -2238,44 +2411,22 @@ begin stage_next <= IDLE; end if; end if; - when SKIP_ADD_REJECT => + when SKIP_AND_RETURN => case (cnt) is -- SKIP READ when 0 => - ready_in_rtps <= '1'; + ready_in_rtps <= '1'; -- Wait until last word from input - if (last_word_in_rtps = '1') then - cnt_next <= 1; + if (last_word_in_rtps = '1') then + cnt_next <= cnt + 1; end if; - -- REJECT SAMPLE + -- Return Code when 1 => done_rtps <= '1'; - ret_rtps <= REJECTED; - stage_next <= IDLE; - -- TODO: Add a new Reject Status? (E.g. REJECTED_BY_PAYLOAD_LIMIT?, or UNSPECIFIED REJECT?) - -- Update Sample Reject Status - status_sig_next(SAMPLE_REJECTED_STATUS) <= '1'; - sample_rej_cnt_next <= sample_rej_cnt + 1; - sample_rej_cnt_change_next <= sample_rej_cnt_change + 1; - sample_rej_last_reason_next <= REJECTED_BY_SAMPLES_LIMIT; - sample_rej_last_inst_next <= key_hash; - when others => - null; - end case; - when SKIP_ADD_DROP => - case (cnt) is - -- SKIP READ - when 0 => - ready_in_rtps <= '1'; - -- Wait until last word from input - if (last_word_in_rtps = '1') then - cnt_next <= 1; - end if; - -- DROP SAMPLE - when 1 => - done_rtps <= '1'; - ret_rtps <= OK; - stage_next <= IDLE; + ret_rtps <= return_code_latch; + + -- DONE + stage_next <= IDLE; when others => null; end case; @@ -2292,7 +2443,7 @@ begin stage_next <= IDLE; else -- Convert Writer Bitmap to SLV - tmp_bitmap := from_endpoint_bitmap_array(inst_data.writer_bitmap); + tmp_bitmap := from_writer_bitmap_array(inst_data.writer_bitmap); -- Remove Writer tmp_bitmap(writer_pos) := '0'; @@ -2300,7 +2451,7 @@ begin -- NOTE: writer_bitmap is not latched, since the memory process is latching it at the -- same clock cycle. -- Convert Back - writer_bitmap <= to_endpoint_bitmap_array(tmp_bitmap); + writer_bitmap <= to_writer_bitmap_array(tmp_bitmap); -- NOT_ALIVE_NO_WRITERS Transition if (tmp_bitmap = (tmp_bitmap'range => '0') and inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '0') then @@ -2355,7 +2506,7 @@ begin stage_next <= IDLE; else -- Found Stale Instance (No Samples and No Active Writers) - if (inst_data.sample_cnt = 0 and inst_data.writer_bitmap = ZERO_ENDPOINT_BITMAP_ARRAY) then + if (inst_data.sample_cnt = 0 and inst_data.writer_bitmap = ZERO_WRITER_BITMAP_ARRAY) then -- Remove Stale Instance inst_op_start <= '1'; inst_opcode <= REMOVE_INSTANCE; @@ -2373,13 +2524,14 @@ begin end if; -- Insert New Instance when 1 => - inst_op_start <= '1'; - inst_opcode <= INSERT_INSTANCE; - status_info_update <= (ISI_LIVELINESS_FLAG => '1', others => '0'); - sample_cnt <= to_unsigned(1, WORD_WIDTH); - deadline <= (time + TIME_BASED_FILTER_QOS) when (TIME_BASED_FILTER_QOS /= DURATION_ZERO) else TIME_INVALID; - tmp_bitmap := (writer_pos => '1', others => '0'); - writer_bitmap <= to_endpoint_bitmap_array(tmp_bitmap); + inst_op_start <= '1'; + inst_opcode <= INSERT_INSTANCE; + status_info_update <= (ISI_LIVELINESS_FLAG => '1', others => '0'); + sample_cnt <= to_unsigned(1, WORD_WIDTH); + deadline <= (time + TIME_BASED_FILTER_QOS) when (TIME_BASED_FILTER_QOS /= DURATION_ZERO) else TIME_INVALID; + tmp_bitmap := (others => '0'); + tmp_bitmap(writer_pos) := '1'; + writer_bitmap <= to_writer_bitmap_array(tmp_bitmap); -- Latch Instance Pointer cur_inst_next <= inst_empty_head; @@ -2418,120 +2570,145 @@ begin -- Memory Control Flow Guard if (sample_ready_in = '1') then - cnt_next <= cnt + 1; + -- Synthesis Guard + if (WITH_KEY) then + cnt_next <= cnt + 1; + else + cnt_next <= cnt + 2; -- Skip Next Step + end if; end if; -- GET Instance Pointer when 2 => - sample_valid_in <= '1'; - sample_addr <= cur_sample + SMF_INSTANCE_ADDR_OFFSET; - sample_read <= '1'; - - -- Memory Control Flow Guard - if (sample_ready_in = '1') then - cnt_next <= cnt + 1; + -- Synthesis Guard + if (WITH_KEY) then + sample_valid_in <= '1'; + sample_addr <= cur_sample + SMF_INSTANCE_ADDR_OFFSET; + sample_read <= '1'; + + -- Memory Control Flow Guard + if (sample_ready_in = '1') then + cnt_next <= cnt + 1; + end if; end if; -- READ Next Sample - sample_ready_out <= '1'; - - -- Memory Control Flow Guard - if (sample_valid_out = '1') then - next_sample_next <= sample_read_data; - cnt_next <= cnt + 1; - end if; - -- READ Status Info when 3 => sample_ready_out <= '1'; -- Memory Control Flow Guard if (sample_valid_out = '1') then - -- DEFAULT - cnt_next <= cnt + 1; - - -- Latch Sample Status Info - sample_status_info_next <= sample_read_data; + next_sample_next <= resize(unsigned(sample_read_data),SAMPLE_MEMORY_ADDR_WIDTH); + cnt_next <= cnt + 1; + end if; + -- READ Status Info + when 4 => + sample_ready_out <= '1'; + + -- Memory Control Flow Guard + if (sample_valid_out = '1') then + tmp_bool := TRUE; -- Check Sample State case (sample_state) is when READ_SAMPLE_STATE => if (sample_read_data(SSI_READ_FLAG) /= '1') then - -- Sample not in collection, Skip Sample - cnt_next <= 17; - sample_abort_read <= '1'; + tmp_bool := FALSE; end if; when NOT_READ_SAMPLE_STATE => if (sample_read_data(SSI_READ_FLAG) /= '0') then - -- Sample not in collection, Skip Sample - cnt_next <= 17; - sample_abort_read <= '1'; + tmp_bool := FALSE; end if; when ANY_SAMPLE_STATE => null; -- Uknown Sample State when others => - -- Sample not in collection, Skip Sample - cnt_next <= 17; - sample_abort_read <= '1'; + tmp_bool := FALSE; end case; + -- Latch Sample Status Info + sample_status_info_next <= sample_read_data; + if (sample_read_data(SSI_READ_FLAG) = '1') then si_sample_state_sig_next <= READ_SAMPLE_STATE; else si_sample_state_sig_next <= NOT_READ_SAMPLE_STATE; end if; - end if; - -- READ Instance Pointer - when 4 => - sample_ready_out <= '1'; - - -- Memory Control Flow Guard - if (sample_valid_out = '1') then - -- Instance pre-selected - if (cur_inst /= INSTANCE_MEMORY_MAX_ADDRESS) then - -- Sample has different Instance - if (WITH_KEY and cur_inst /= sample_read_data) then - -- Consecutive Instance Sample Order - if (not ORDERED_ACCESS or PRESENTATION_QOS = INSTANCE_PRESENTATION_QOS) then - -- Skip Sample - cnt_next <= 17; - sample_abort_read <= '1'; - else - -- Get Instance Data - next_inst_next <= sample_read_data; - cnt_next <= cnt + 1; - end if; + + -- Sample Passes Checks + if (tmp_bool) then + if (WITH_KEY) then + cnt_next <= cnt + 1; else - -- Select Sample - collection_cnt_next <= collection_cnt + 1; - first_sample_next <= cur_sample; - -- Latch Next Sample (For resume purposes) - second_sample_next <= next_sample; - -- First Instance Sample - -- NOTE: This state only enters with a sample rank of 0 and cur_inst set, when the - -- first sample of the instance has not yet been selected + -- NOTE: If sample rank is bigger than zero, we have already accepted the instance. if (si_sample_rank_sig = 0) then - -- Reset - collection_cnt_max_next <= collection_cnt + 1; + cnt_next <= cnt + 3; --Skip to Check Instance State else - si_sample_rank_sig <= si_sample_rank_sig - 1; + -- Select Sample + collection_cnt_next <= collection_cnt + 1; + first_sample_next <= cur_sample; + -- Latch Next Sample (For resume purposes) + second_sample_next <= next_sample; + si_sample_rank_sig_next <= si_sample_rank_sig - 1; + cnt_next <= cnt + 4; --Skip all Instance Related States end if; - - -- Skip Instance Operation - cnt_next <= cnt + 3; end if; else - -- Get Instance Data - next_inst_next <= sample_read_data; - -- Synthesis Guard - if (WITH_KEY) then - cnt_next <= cnt + 1; + -- Sample not in collection, Skip Sample + cnt_next <= 18; + sample_abort_read <= '1'; + end if; + end if; + -- READ Instance Pointer + when 5 => + -- Synthesis Guard + if (WITH_KEY) then + sample_ready_out <= '1'; + + -- Memory Control Flow Guard + if (sample_valid_out = '1') then + -- Instance pre-selected + if (cur_inst /= INSTANCE_MEMORY_MAX_ADDRESS) then + -- Sample has different Instance + if (cur_inst /= resize(unsigned(sample_read_data),INSTANCE_MEMORY_ADDR_WIDTH)) then + -- Consecutive Instance Sample Order + if (not ORDERED_ACCESS or PRESENTATION_QOS = INSTANCE_PRESENTATION_QOS) then + -- Skip Sample + cnt_next <= 18; + sample_abort_read <= '1'; + else + -- Get Instance Data + next_inst_next <= resize(unsigned(sample_read_data),INSTANCE_MEMORY_ADDR_WIDTH); + cnt_next <= cnt + 1; + end if; + else + -- Select Sample + collection_cnt_next <= collection_cnt + 1; + first_sample_next <= cur_sample; + -- Latch Next Sample (For resume purposes) + second_sample_next <= next_sample; + + -- First Instance Sample + -- NOTE: This state only enters with a sample rank of 0 and cur_inst set, when the + -- first sample of the instance has not yet been selected + if (si_sample_rank_sig = 0) then + -- Reset + collection_cnt_max_next <= collection_cnt + 1; + else + si_sample_rank_sig_next <= si_sample_rank_sig - 1; + end if; + + -- Skip Instance Operation + cnt_next <= cnt + 3; + end if; else - cnt_next <= cnt + 2; + -- Get Instance Data + next_inst_next <= resize(unsigned(sample_read_data),INSTANCE_MEMORY_ADDR_WIDTH); + cnt_next <= cnt + 1; end if; end if; end if; -- Get Instance Data - when 5 => + when 6 => -- Synthesis Guard if (WITH_KEY) then -- Memory Operation Guard @@ -2544,7 +2721,7 @@ begin end if; end if; -- Check Instance Data - when 6 => + when 7 => -- Wait for Instance Data if (not WITH_KEY or inst_op_done = '1') then -- DEFAULT @@ -2601,20 +2778,27 @@ begin -- Select Sample collection_cnt_next <= collection_cnt + 1; collection_cnt_max_next <= collection_cnt + 1; - si_sample_rank_sig <= (others => '0'); + si_sample_rank_sig_next <= (others => '0'); cur_inst_next <= next_inst; first_sample_next <= cur_sample; -- Latch Next Sample (For resume purposes) second_sample_next <= next_sample; cnt_next <= cnt + 1; else - -- Skip Sample - cnt_next <= 17; - sample_abort_read <= '1'; + if (WITH_KEY) then + -- Skip Sample + cnt_next <= 18; + sample_abort_read <= '1'; + else + -- Instance does not pass Checks + done_dds <= '1'; + return_code_dds <= RETCODE_NO_DATA; + stage_next <= IDLE; + end if; end if; end if; -- GET Timestamp 1/2 - when 7 => + when 8 => sample_valid_in <= '1'; sample_addr <= cur_sample + SMF_TIMESTAMP_OFFSET; sample_read <= '1'; @@ -2624,7 +2808,7 @@ begin cnt_next <= cnt + 1; end if; -- GET Timestamp 2/2 - when 8 => + when 9 => sample_valid_in <= '1'; sample_addr <= cur_sample + SMF_TIMESTAMP_OFFSET + 1; sample_read <= '1'; @@ -2634,7 +2818,7 @@ begin cnt_next <= cnt + 1; end if; -- GET Payload Pointer - when 9 => + when 10 => sample_valid_in <= '1'; sample_addr <= cur_sample + SMF_PAYLOAD_ADDR_OFFSET; sample_read <= '1'; @@ -2644,7 +2828,7 @@ begin cnt_next <= cnt + 1; end if; -- GET Disposed Generation Count - when 10 => + when 11 => sample_valid_in <= '1'; sample_addr <= cur_sample + SMF_DISPOSED_GEN_CNT_OFFSET; sample_read <= '1'; @@ -2654,7 +2838,7 @@ begin cnt_next <= cnt + 1; end if; -- GET No Writers Generation Count - when 11 => + when 12 => sample_valid_in <= '1'; sample_addr <= cur_sample + SMF_STATUS_INFO_OFFSET; sample_read <= '1'; @@ -2664,35 +2848,35 @@ begin cnt_next <= cnt + 1; end if; -- READ Timestamp 1/2 - when 12 => - sample_ready_out <= '1'; - - -- Memory Control Flow Guard - if (sample_valid_out = '1') then - si_source_timestamp_sig_next(0) <= sample_read_data; - cnt_next <= cnt + 1; - end if; - -- READ Timestamp 2/2 when 13 => sample_ready_out <= '1'; -- Memory Control Flow Guard if (sample_valid_out = '1') then - si_source_timestamp_sig_next(1) <= sample_read_data; + si_source_timestamp_sig_next(0) <= unsigned(sample_read_data); cnt_next <= cnt + 1; end if; - -- READ Payload Pointer + -- READ Timestamp 2/2 when 14 => sample_ready_out <= '1'; + -- Memory Control Flow Guard + if (sample_valid_out = '1') then + si_source_timestamp_sig_next(1) <= unsigned(sample_read_data); + cnt_next <= cnt + 1; + end if; + -- READ Payload Pointer + when 15 => + sample_ready_out <= '1'; + -- Memory Control Flow Guard if (sample_valid_out = '1') then -- Latch Payload Address - cur_payload_next <= sample_read_data; + cur_payload_next <= resize(unsigned(sample_read_data),PAYLOAD_MEMORY_ADDR_WIDTH); cnt_next <= cnt + 1; end if; -- READ Disposed Generation Count - when 15 => + when 16 => sample_ready_out <= '1'; -- Memory Control Flow Guard @@ -2701,19 +2885,19 @@ begin cnt_next <= cnt + 1; end if; -- READ No Writers Generation Count - when 16 => + when 17 => sample_ready_out <= '1'; -- Memory Control Flow Guard if (sample_valid_out = '1') then si_no_writers_generation_count_sig_next <= sample_read_data; - cur_generation_rank_next <= si_disposed_generation_count_sig + sample_read_data; + cur_generation_rank_next <= unsigned(si_disposed_generation_count_sig) + unsigned(sample_read_data); -- Calculate highest collection generation rank - collection_generation_rank_next <= si_disposed_generation_count_sig + sample_read_data; + collection_generation_rank_next <= unsigned(si_disposed_generation_count_sig) + unsigned(sample_read_data); cnt_next <= cnt + 1; end if; -- Exit State - when 17 => + when 18 => -- Reached End of Samples if (next_sample = SAMPLE_MEMORY_MAX_ADDRESS) then -- Exit Condition (Sample Selected) @@ -2770,22 +2954,24 @@ begin -- Memory Control Flow Guard if (sample_ready_in = '1') then -- Pre-Calculation already done for selected Instance (Or not necessary) - if (si_sample_rank_sig /= 0 or collection_cnt_max = max_samples) then + if (si_sample_rank_sig /= 0 or collection_cnt_max = max_samples_latch) then stage_next <= FINALIZE_SAMPLE_INFO; cnt_next <= 0; else -- Calculate Instance Sample Ranks - stage_next <= PRE_CALCULATE; + stage_next <= PRE_CALCULATE; + cnt_next <= 0; end if; end if; else -- Pre-Calculation already done for selected Instance (Or not necessary) - if (si_sample_rank_sig /= 0 or collection_cnt_max = max_samples) then + if (si_sample_rank_sig /= 0 or collection_cnt_max = max_samples_latch) then stage_next <= FINALIZE_SAMPLE_INFO; cnt_next <= 0; else -- Calculate Instance Sample Ranks - stage_next <= PRE_CALCULATE; + stage_next <= PRE_CALCULATE; + cnt_next <= 0; end if; end if; end if; @@ -2817,17 +3003,25 @@ begin -- Memory Control Flow Guard if (sample_ready_in = '1') then - cnt_next <= cnt + 1; + -- Synthesis Guard + if (WITH_KEY) then + cnt_next <= cnt + 1; + else + cnt_next <= cnt + 2; --Skip Next Step + end if; end if; -- GET Instance Pointer when 2 => - sample_valid_in <= '1'; - sample_addr <= cur_sample + SMF_INSTANCE_ADDR_OFFSET; - sample_read <= '1'; - - -- Memory Control Flow Guard - if (sample_ready_in = '1') then - cnt_next <= cnt + 1; + -- Synthesis Guard + if (WITH_KEY) then + sample_valid_in <= '1'; + sample_addr <= cur_sample + SMF_INSTANCE_ADDR_OFFSET; + sample_read <= '1'; + + -- Memory Control Flow Guard + if (sample_ready_in = '1') then + cnt_next <= cnt + 1; + end if; end if; -- GET Disposed Generation Count when 3 => @@ -2855,7 +3049,7 @@ begin -- Memory Control Flow Guard if (sample_valid_out = '1') then - next_sample_next <= sample_read_data; + next_sample_next <= resize(unsigned(sample_read_data),SAMPLE_MEMORY_ADDR_WIDTH); cnt_next <= cnt + 1; end if; -- READ Status Info @@ -2864,55 +3058,68 @@ begin -- Memory Control Flow Guard if (sample_valid_out = '1') then - -- DEFAULT - cnt_next <= cnt + 1; + tmp_bool := TRUE; -- Check Sample State case (sample_state) is when READ_SAMPLE_STATE => if (sample_read_data(SSI_READ_FLAG) /= '1') then - -- Skip Sample - cnt_next <= 12; - sample_abort_read <= '1'; + tmp_bool := FALSE; end if; when NOT_READ_SAMPLE_STATE => if (sample_read_data(SSI_READ_FLAG) /= '0') then - -- Skip Sample - cnt_next <= 12; - sample_abort_read <= '1'; + tmp_bool := FALSE; end if; when ANY_SAMPLE_STATE => null; -- Uknown Sample State when others => - -- Skip Sample - cnt_next <= 12; - sample_abort_read <= '1'; + tmp_bool := FALSE; end case; + + -- Sample Passes Checks + if (tmp_bool) then + -- Synthesis Guard + if (WITH_KEY) then + cnt_next <= cnt + 1; + else + -- Count Sample (No need to check Instance) + collection_cnt_max_next <= collection_cnt_max + 1; + si_sample_rank_sig_next <= si_sample_rank_sig + 1; + cnt_next <= cnt + 2; --Skip Next Step + end if; + else + -- Skip Sample + cnt_next <= 12; + sample_abort_read <= '1'; + end if; end if; -- READ Instance Pointer when 7 => - sample_ready_out <= '1'; - - -- Memory Control Flow Guard - if (sample_valid_out = '1') then - -- Same Instance - if (not WITH_KEY or sample_read_data = cur_inst) then - -- Count Sample (No need to check Instance) - collection_cnt_max_next <= collection_cnt_max + 1; - si_sample_rank_sig_next <= si_sample_rank_sig + 1; - - cnt_next <= cnt + 1; - else - -- Consecutive Instance Sample Order - if (not ORDERED_ACCESS or PRESENTATION_QOS = INSTANCE_PRESENTATION_QOS or single_instance = '1') then - -- Skip Sample - cnt_next <= 12; - sample_abort_read <= '1'; + -- Synthesis Guard + if (WITH_KEY) then + sample_ready_out <= '1'; + + -- Memory Control Flow Guard + if (sample_valid_out = '1') then + -- Same Instance + if (resize(unsigned(sample_read_data),INSTANCE_MEMORY_ADDR_WIDTH) = cur_inst) then + -- Count Sample (No need to check Instance) + collection_cnt_max_next <= collection_cnt_max + 1; + si_sample_rank_sig_next <= si_sample_rank_sig + 1; + + cnt_next <= cnt + 1; else - -- Check New Instance - cnt_next <= cnt + 3; - sample_abort_read <= '1'; + -- Consecutive Instance Sample Order + if (not ORDERED_ACCESS or PRESENTATION_QOS = INSTANCE_PRESENTATION_QOS or single_instance = '1') then + -- Skip Sample + cnt_next <= 12; + sample_abort_read <= '1'; + else + -- Check New Instance + cnt_next <= cnt + 3; + sample_abort_read <= '1'; + end if; end if; end if; end if; @@ -2923,7 +3130,7 @@ begin -- Memory Control Flow Guard if (sample_valid_out = '1') then -- Calculate highest collection generation rank - collection_generation_rank_next <= sample_read_data; + collection_generation_rank_next <= unsigned(sample_read_data); cnt_next <= cnt + 1; end if; -- READ No Writers Generation Count @@ -2933,7 +3140,7 @@ begin -- Memory Control Flow Guard if (sample_valid_out = '1') then -- Calculate highest collection generation rank - collection_generation_rank_next <= collection_generation_rank + sample_read_data; + collection_generation_rank_next <= collection_generation_rank + unsigned(sample_read_data); -- Skip Instance Check cnt_next <= cnt + 3; end if; @@ -3016,7 +3223,7 @@ begin -- Exit State when 12 => -- Exit Condition (Reached End of Samples or Collection Fully Precalculated) - if (next_sample = SAMPLE_MEMORY_MAX_ADDRESS or collection_cnt_max = max_samples) then + if (next_sample = SAMPLE_MEMORY_MAX_ADDRESS or collection_cnt_max = max_samples_latch) then stage_next <= FINALIZE_SAMPLE_INFO; cnt_next <= 0; else @@ -3063,7 +3270,7 @@ begin -- Sample Info Absolut Generation Rank -- XXX: Possible Worst Case Path (2 32-bit Operations in same clock) - si_generation_rank_sig_next <= (inst_data.disposed_gen_cnt + inst_data.no_writers_gen_cnt) - cur_generation_rank; + si_absolute_generation_count_sig_next <= (inst_data.disposed_gen_cnt + inst_data.no_writers_gen_cnt) - cur_generation_rank; -- Sample Info Valid Data if (cur_payload /= PAYLOAD_MEMORY_MAX_ADDRESS) then @@ -3096,7 +3303,7 @@ begin end if; -- Reset Data Available Status - status_sig_next(DATA_AVAILABLE_STATUS) <= '0'; + status_sig_next <= status_sig and (not DATA_AVAILABLE_STATUS); -- Sample Data Request if (get_data_dds = '1') then @@ -3124,9 +3331,9 @@ begin -- Consecutive Instance Sample Order of multiple Instances if ((not ORDERED_ACCESS or PRESENTATION_QOS = INSTANCE_PRESENTATION_QOS) and single_instance = '0' and single_sample = '0') then -- Completed Collection - if (collection_cnt = max_samples) then + if (collection_cnt = max_samples_latch) then -- Unmark Instances - unmark_instances_next <= '1'; + unmark_instances_flag_next <= '1'; else -- Mark Instance status_info_update(ISI_MARK_FLAG) <= '1'; @@ -3142,20 +3349,21 @@ begin -- Instance is NOT_VIEWED and sample is from last generation of Instance if (inst_data.status_info(ISI_VIEW_FLAG) = '0' and si_absolute_generation_count_sig = 0) then -- Mark Instance as VIEWED - inst_data_next.status_info(ISI_VIEW_FLAG) <= '1'; + inst_data_next2.status_info(ISI_VIEW_FLAG) <= '1'; end if; end if; end if; -- Collection Completed - if (collection_cnt = max_samples) then + if (collection_cnt = max_samples_latch) then done_dds <= '1'; return_code_dds <= RETCODE_OK; is_take_next <= '0'; -- Return to IDLE from REMOVE if (is_take = '1') then - stage_next <= REMOVE_SAMPLE; cur_sample_next <= first_sample; + stage_next <= REMOVE_SAMPLE; + cnt_next <= 0; else -- DONE stage_next <= IDLE; @@ -3184,8 +3392,9 @@ begin if (is_take = '1') then -- Remove Sample - stage_next <= REMOVE_SAMPLE; - cur_sample_next <= first_sample; + cur_sample_next <= first_sample; + stage_next <= REMOVE_SAMPLE; + cnt_next <= 0; else -- Continue Processing cur_sample <= second_sample; @@ -3211,13 +3420,18 @@ begin case (cnt) is -- GET Next Pointer when 0 => - payload_valid_in <= '1'; - payload_addr <= cur_payload + PMF_NEXT_ADDR_OFFSET; - payload_read <= '1'; - - -- Memory Flow Control Guard - if (payload_ready_in = '1') then - cnt_next <= cnt + 1; + -- NOTE: We have to make sure that no pending Reads are in the Memory Controler Buffer, + -- else the Next Payload Pointer cannot be read. + -- No Pending Reads + if (cnt3 = 0) then + payload_valid_in <= '1'; + payload_addr <= cur_payload + PMF_NEXT_ADDR_OFFSET; + payload_read <= '1'; + + -- Memory Flow Control Guard + if (payload_ready_in = '1') then + cnt_next <= cnt + 1; + end if; end if; -- READ Next Pointer when 1 => @@ -3225,15 +3439,15 @@ begin -- Memory Flow Control Guard if (payload_valid_out = '1') then - next_payload_next <= payload_read_data; - cnt2 <= 1; + next_payload_next <= resize(unsigned(payload_read_data),PAYLOAD_MEMORY_ADDR_WIDTH); + cnt2_next <= 1; -- Last Payload Slot is unaligned - if (payload_read_data = PAYLOAD_MEMORY_MAX_ADDRESS and sample_status_info(SSI_ALIGNED_FLAG) = '0') then - cnt_next <= cnt + 1 + if (resize(unsigned(payload_read_data),PAYLOAD_MEMORY_ADDR_WIDTH) = PAYLOAD_MEMORY_MAX_ADDRESS and sample_status_info(SSI_ALIGNED_FLAG) = '0') then + cnt_next <= cnt + 1; else cnt_next <= cnt + 3; - long_latch_next <= PAYLOAD_FRAME_SIZE-1; + long_latch_next <= std_logic_vector(to_unsigned(PAYLOAD_FRAME_SIZE-1,CDR_LONG_WIDTH)); end if; end if; -- GET Payload Offset @@ -3289,14 +3503,15 @@ begin -- Memory Flow Control Guard if (payload_valid_out = '1') then valid_out_dds <= '1'; + data_out_dds <= payload_read_data; -- End of Payload - if (cnt3 = 1 and cnt = 4) then + if (cnt3 = 1 and cnt = 5) then last_word_out_dds <= '1'; end if; -- DDS Read - if (ready_out_dds = '1') then + if (ready_out_dds = '1') then payload_ready_out <= '1'; -- NOTE: We are using the tmp_bool variable to signal if there is an increment -- on the same clock cycle. @@ -3309,11 +3524,10 @@ begin end if; end if; -- Finished Reading - elsif (cnt = 4) then + elsif (cnt = 5) then assert (cnt3 = 0) severity FAILURE; -- DONE - stage_next <= FINALIZE_SAMPLE_INFO; - cnt_next <= 2; + stage_next <= IDLE; end if; when FIND_NEXT_INSTANCE => -- Synthesis Guard @@ -3341,7 +3555,7 @@ begin -- Check Instance Handle (Key Hash) -- XXX: Posible Worst Case Path (128-bit Comparison) - if (to_unsigned(inst_data.key_hash) =< to_unsigned(key_hash)) then + if (to_unsigned(inst_data.key_hash) <= to_unsigned(key_hash)) then tmp_bool := FALSE; end if; @@ -3389,6 +3603,7 @@ begin if (tmp_bool) then cur_inst <= inst_addr_base; stage_next <= GET_NEXT_SAMPLE; + cnt_next <= 0; else -- NOTE: The Generation Counters are not used directly in this state, but will be needed by the FINALIZE_SAMPLE_INFO state. inst_op_start <= '1'; @@ -3469,6 +3684,7 @@ begin -- Get Instance Samples cur_inst <= inst_addr_base; stage_next <= GET_NEXT_SAMPLE; + cnt_next <= 0; else -- DONE done_dds <= '1'; @@ -3519,17 +3735,24 @@ begin -- Memory Control Flow Guard if (sample_ready_in = '1') then - cnt_next <= cnt + 1; + if (WITH_KEY) then + cnt_next <= cnt + 1; + else + cnt_next <= cnt + 2; --Skip Next Step + end if; end if; -- GET Instance Pointer when 3 => - sample_valid_in <= '1'; - sample_addr <= cur_sample + SMF_INSTANCE_ADDR_OFFSET; - sample_read <= '1'; - - -- Memory Control Flow Guard - if (sample_ready_in = '1') then - cnt_next <= cnt + 1; + -- Synthesis Guard + if (WITH_KEY) then + sample_valid_in <= '1'; + sample_addr <= cur_sample + SMF_INSTANCE_ADDR_OFFSET; + sample_read <= '1'; + + -- Memory Control Flow Guard + if (sample_ready_in = '1') then + cnt_next <= cnt + 1; + end if; end if; -- READ Next Sample when 4 => @@ -3537,7 +3760,7 @@ begin -- Memory Control Flow Guard if (sample_valid_out = '1') then - next_sample_next <= sample_read_data; + next_sample_next <= resize(unsigned(sample_read_data),SAMPLE_MEMORY_ADDR_WIDTH); cnt_next <= cnt + 1; end if; -- READ Lifespan 1/2 @@ -3559,7 +3782,13 @@ begin -- Sample Lifespan Expired if (tmp_dw /= TIME_INVALID and time >= tmp_dw) then - cnt_next <= cnt + 1; + if (WITH_KEY) then + cnt_next <= cnt + 1; + else + -- Remove Sample + stage_next <= REMOVE_SAMPLE; + cnt_next <= 0; + end if; else sample_abort_read <= '1'; @@ -3581,21 +3810,24 @@ begin end if; -- READ Instance Pointer when 7 => - -- Memory Operation Guard - if (inst_op_done = '1') then - sample_ready_out <= '1'; - - -- Memory Control Flow Guard - if (sample_valid_out = '1') then - -- Fetch Instance Data - inst_op_start <= '1'; - inst_opcode <= GET_INSTANCE; - inst_mem_fields <= IMF_SAMPLE_CNT_FLAG or IMF_WRITER_BITMAP_FLAG; - inst_addr_update <= sample_read_data; + -- Synthesis Guard + if (WITH_KEY) then + -- Memory Operation Guard + if (inst_op_done = '1') then + sample_ready_out <= '1'; - -- Remove Sample - stage_next <= REMOVE_SAMPLE; - cnt_next <= 0; + -- Memory Control Flow Guard + if (sample_valid_out = '1') then + -- Fetch Instance Data + inst_op_start <= '1'; + inst_opcode <= GET_INSTANCE; + inst_mem_fields <= IMF_STATUS_FLAG or IMF_SAMPLE_CNT_FLAG or IMF_WRITER_BITMAP_FLAG; + inst_addr_update <= resize(unsigned(sample_read_data),INSTANCE_MEMORY_ADDR_WIDTH); + + -- Remove Sample + stage_next <= REMOVE_SAMPLE; + cnt_next <= 0; + end if; end if; end if; when others => @@ -3603,16 +3835,21 @@ begin end case; when GET_SAMPLE_REJECTED_STATUS => case (cnt) is + -- Return Code + when 0 => + done_dds <= '1'; + return_code_dds <= RETCODE_OK; + cnt_next <= cnt + 1; -- Total Count - when 0 => - data_out_dds <= sample_rej_cnt; + when 1 => + data_out_dds <= std_logic_vector(sample_rej_cnt); valid_out_dds <= '1'; if (ready_out_dds = '1') then cnt_next <= cnt + 1; end if; -- Total Count Change - when 1 => - data_out_dds <= sample_rej_cnt_change; + when 2 => + data_out_dds <= std_logic_vector(sample_rej_cnt_change); valid_out_dds <= '1'; if (ready_out_dds = '1') then -- Reset @@ -3620,7 +3857,7 @@ begin cnt_next <= cnt + 1; end if; -- Last Reason - when 2 => + when 3 => data_out_dds <= sample_rej_last_reason; valid_out_dds <= '1'; if (ready_out_dds = '1') then @@ -3629,41 +3866,34 @@ begin cnt_next <= cnt + 1; end if; -- Last Instance Handle 1/4 - when 3 => + when 4 => data_out_dds <= sample_rej_last_inst(0); valid_out_dds <= '1'; if (ready_out_dds = '1') then cnt_next <= cnt + 1; end if; -- Last Instance Handle 2/4 - when 4 => + when 5 => data_out_dds <= sample_rej_last_inst(1); valid_out_dds <= '1'; if (ready_out_dds = '1') then cnt_next <= cnt + 1; end if; -- Last Instance Handle 3/4 - when 5 => + when 6 => data_out_dds <= sample_rej_last_inst(2); valid_out_dds <= '1'; if (ready_out_dds = '1') then cnt_next <= cnt + 1; end if; -- Last Instance Handle 4/4 - when 6 => + when 7 => data_out_dds <= sample_rej_last_inst(3); valid_out_dds <= '1'; last_word_out_dds <= '1'; - if (ready_out_dds = '1') then - cnt_next <= cnt + 1; - end if; - -- Return Code - when 7 => - done_dds <= '1'; - return_code_dds <= RETCODE_OK; if (ready_out_dds = '1') then -- Reset - status_sig_next(SAMPLE_REJECTED_STATUS) <= '0'; + status_sig_next <= status_sig and (not SAMPLE_REJECTED_STATUS); -- DONE stage_next <= IDLE; @@ -3673,16 +3903,21 @@ begin end case; when GET_REQUESTED_DEADLINE_MISSED_STATUS => case (cnt) is + -- Return Code + when 0 => + done_dds <= '1'; + return_code_dds <= RETCODE_OK; + cnt_next <= cnt + 1; -- Total Count - when 0 => - data_out_dds <= deadline_miss_cnt; + when 1 => + data_out_dds <= std_logic_vector(deadline_miss_cnt); valid_out_dds <= '1'; if (ready_out_dds = '1') then cnt_next <= cnt + 1; end if; -- Total Count Change - when 1 => - data_out_dds <= deadline_miss_cnt_change; + when 2 => + data_out_dds <= std_logic_vector(deadline_miss_cnt_change); valid_out_dds <= '1'; if (ready_out_dds = '1') then -- Reset @@ -3690,41 +3925,34 @@ begin cnt_next <= cnt + 1; end if; -- Last Instance Handle 1/4 - when 2 => + when 3 => data_out_dds <= deadline_miss_last_inst(0); valid_out_dds <= '1'; if (ready_out_dds = '1') then cnt_next <= cnt + 1; end if; -- Last Instance Handle 2/4 - when 3 => + when 4 => data_out_dds <= deadline_miss_last_inst(1); valid_out_dds <= '1'; if (ready_out_dds = '1') then cnt_next <= cnt + 1; end if; -- Last Instance Handle 3/4 - when 4 => + when 5 => data_out_dds <= deadline_miss_last_inst(2); valid_out_dds <= '1'; if (ready_out_dds = '1') then cnt_next <= cnt + 1; end if; -- Last Instance Handle 4/4 - when 5 => + when 6 => data_out_dds <= deadline_miss_last_inst(3); valid_out_dds <= '1'; last_word_out_dds <= '1'; - if (ready_out_dds = '1') then - cnt_next <= cnt + 1; - end if; - -- Return Code - when 6 => - done_dds <= '1'; - return_code_dds <= RETCODE_OK; if (ready_out_dds = '1') then -- Reset - status_sig_next(REQUESTED_DEADLINE_MISSED_STATUS) <= '0'; + status_sig_next <= status_sig and (not REQUESTED_DEADLINE_MISSED_STATUS); -- DONE stage_next <= IDLE; @@ -3768,7 +3996,7 @@ begin cnt_next <= 1; else -- Update Requested Deadline Missed Status - status_sig_next(REQUESTED_DEADLINE_MISSED_STATUS) <= '1'; + status_sig_next <= status_sig and REQUESTED_DEADLINE_MISSED_STATUS; deadline_miss_cnt_next <= deadline_miss_cnt + 1; deadline_miss_cnt_change_next <= deadline_miss_cnt_change + 1; deadline_miss_last_inst_next <= inst_data.key_hash; @@ -3791,7 +4019,7 @@ begin when 1 => sample_valid_in <= '1'; sample_addr <= cur_sample + SMF_PREV_ADDR_OFFSET; - sample_write_data <= prev_sample; + sample_write_data <= std_logic_vector(resize(prev_sample,WORD_WIDTH)); -- Memory Flow Control Guard if (sample_ready_in = '1') then @@ -3802,9 +4030,9 @@ begin sample_valid_in <= '1'; sample_addr <= cur_sample + SMF_NEXT_ADDR_OFFSET; if (cur_sample = MAX_SAMPLE_ADDRESS) then - sample_write_data <= SAMPLE_MEMORY_MAX_ADDRESS; + sample_write_data <= std_logic_vector(resize(SAMPLE_MEMORY_MAX_ADDRESS,WORD_WIDTH)); else - sample_write_data <= cur_sample + SAMPLE_FRAME_SIZE; + sample_write_data <= std_logic_vector(resize(cur_sample + SAMPLE_FRAME_SIZE,WORD_WIDTH)); end if; -- Memory Flow Control Guard @@ -3834,9 +4062,9 @@ begin payload_valid_in <= '1'; payload_addr <= cur_payload + PMF_NEXT_ADDR_OFFSET; if (cur_payload = MAX_PAYLOAD_ADDRESS) then - payload_write_data <= PAYLOAD_MEMORY_MAX_ADDRESS; + payload_write_data <= std_logic_vector(resize(PAYLOAD_MEMORY_MAX_ADDRESS,WORD_WIDTH)); else - payload_write_data <= cur_payload + PAYLOAD_FRAME_SIZE; + payload_write_data <= std_logic_vector(resize(cur_payload + PAYLOAD_FRAME_SIZE,WORD_WIDTH)); end if; -- Memory Flow Control Guard @@ -3894,7 +4122,7 @@ begin inst_write_data <= (others => '0'); - case (mem_stage) is + case (inst_stage) is when IDLE => inst_op_done <= '1'; @@ -3943,22 +4171,31 @@ begin -- by the main process that the operation can succeed (Memory is available) assert (inst_empty_head /= INSTANCE_MEMORY_MAX_ADDRESS) report "Instance Insertion while memory Full" severity FAILURE; - inst_addr_base_next <= inst_occupied_head; - inst_stage_next <= FIND_POS; - inst_cnt_next <= 0; + -- First Instance + if (inst_occupied_head = INSTANCE_MEMORY_MAX_ADDRESS) then + inst_addr_base_next <= inst_empty_head; + inst_stage_next <= INSERT_INSTANCE; + inst_cnt_next <= 1; -- Skip first Step + else + inst_addr_base_next <= inst_occupied_head; + inst_stage_next <= FIND_POS; + inst_cnt_next <= 0; + end if; + -- TODO: Set Instance Data + -- TODO: Fix Instance Insertion/Deletion (List Pointers) when UPDATE_INSTANCE => inst_stage_next <= UPDATE_INSTANCE; - if check_mask(inst_mem_fields.field_flag,IMF_STATUS_FLAG) then + if check_mask(inst_mem_fields,IMF_STATUS_FLAG) then inst_cnt_next <= 0; - elsif check_mask(inst_mem_fields.field_flag,IMF_SAMPLE_CNT_FLAG) then + elsif check_mask(inst_mem_fields,IMF_SAMPLE_CNT_FLAG) then inst_cnt_next <= 1; - elsif check_mask(inst_mem_fields.field_flag,IMF_DISPOSED_CNT_FLAG) then + elsif check_mask(inst_mem_fields,IMF_DISPOSED_CNT_FLAG) then inst_cnt_next <= 2; - elsif check_mask(inst_mem_fields.field_flag,IMF_NO_WRITERS_CNT_FLAG) then + elsif check_mask(inst_mem_fields,IMF_NO_WRITERS_CNT_FLAG) then inst_cnt_next <= 3; - elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_mem_fields.field_flag,IMF_IGNORE_DEADLINE_FLAG)) then + elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_mem_fields,IMF_IGNORE_DEADLINE_FLAG)) then inst_cnt_next <= 4; - elsif check_mask(inst_mem_fields.field_flag,IMF_WRITER_BITMAP_FLAG) then + elsif check_mask(inst_mem_fields,IMF_WRITER_BITMAP_FLAG) then inst_cnt_next <= 6; inst_cnt2_next <= 0; else @@ -3975,19 +4212,19 @@ begin -- Get Instance Data inst_stage_next <= GET_INSTANCE_DATA; inst_data_next <= ZERO_INSTANCE_DATA; - if check_mask(inst_mem_fields.field_flag,IMF_KEY_HASH_FLAG) then + if check_mask(inst_mem_fields,IMF_KEY_HASH_FLAG) then inst_cnt_next <= 0; - elsif check_mask(inst_mem_fields.field_flag,IMF_STATUS_FLAG) then + elsif check_mask(inst_mem_fields,IMF_STATUS_FLAG) then inst_cnt_next <= 4; - elsif check_mask(inst_mem_fields.field_flag,IMF_SAMPLE_CNT_FLAG) then + elsif check_mask(inst_mem_fields,IMF_SAMPLE_CNT_FLAG) then inst_cnt_next <= 5; - elsif check_mask(inst_mem_fields.field_flag,IMF_DISPOSED_CNT_FLAG) then + elsif check_mask(inst_mem_fields,IMF_DISPOSED_CNT_FLAG) then inst_cnt_next <= 6; - elsif check_mask(inst_mem_fields.field_flag,IMF_NO_WRITERS_CNT_FLAG) then + elsif check_mask(inst_mem_fields,IMF_NO_WRITERS_CNT_FLAG) then inst_cnt_next <= 7; - elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_mem_fields.field_flag,IMF_IGNORE_DEADLINE_FLAG)) then + elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_mem_fields,IMF_IGNORE_DEADLINE_FLAG)) then inst_cnt_next <= 8; - elsif check_mask(inst_mem_fields.field_flag,IMF_WRITER_BITMAP_FLAG) then + elsif check_mask(inst_mem_fields,IMF_WRITER_BITMAP_FLAG) then inst_cnt_next <= 10; inst_cnt2_next <= 0; else @@ -4013,19 +4250,19 @@ begin -- Get Instance Data inst_stage_next <= GET_INSTANCE_DATA; inst_data_next <= ZERO_INSTANCE_DATA; - if check_mask(inst_mem_fields.field_flag,IMF_KEY_HASH_FLAG) then + if check_mask(inst_mem_fields,IMF_KEY_HASH_FLAG) then inst_cnt_next <= 0; - elsif check_mask(inst_mem_fields.field_flag,IMF_STATUS_FLAG) then + elsif check_mask(inst_mem_fields,IMF_STATUS_FLAG) then inst_cnt_next <= 4; - elsif check_mask(inst_mem_fields.field_flag,IMF_SAMPLE_CNT_FLAG) then + elsif check_mask(inst_mem_fields,IMF_SAMPLE_CNT_FLAG) then inst_cnt_next <= 5; - elsif check_mask(inst_mem_fields.field_flag,IMF_DISPOSED_CNT_FLAG) then + elsif check_mask(inst_mem_fields,IMF_DISPOSED_CNT_FLAG) then inst_cnt_next <= 6; - elsif check_mask(inst_mem_fields.field_flag,IMF_NO_WRITERS_CNT_FLAG) then + elsif check_mask(inst_mem_fields,IMF_NO_WRITERS_CNT_FLAG) then inst_cnt_next <= 7; - elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_mem_fields.field_flag,IMF_IGNORE_DEADLINE_FLAG)) then + elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_mem_fields,IMF_IGNORE_DEADLINE_FLAG)) then inst_cnt_next <= 8; - elsif check_mask(inst_mem_fields.field_flag,IMF_WRITER_BITMAP_FLAG) then + elsif check_mask(inst_mem_fields,IMF_WRITER_BITMAP_FLAG) then inst_cnt_next <= 10; inst_cnt2_next <= 0; else @@ -4102,7 +4339,7 @@ begin -- Memory Flow Control Guard if (inst_valid_out = '1') then - inst_next_addr_base_next <= inst_read_data; + inst_next_addr_base_next <= resize(unsigned(inst_read_data),INSTANCE_MEMORY_ADDR_WIDTH); inst_cnt_next <= inst_cnt + 1; end if; -- READ Key Hash 1/4 @@ -4201,19 +4438,19 @@ begin -- Get Instance Data inst_stage_next <= GET_INSTANCE_DATA; inst_data_next <= ZERO_INSTANCE_DATA; - if check_mask(inst_latch_data.field_flag,IMF_KEY_HASH_FLAG) then + if check_mask(inst_latch_data.field_flags,IMF_KEY_HASH_FLAG) then inst_cnt_next <= 0; - elsif check_mask(inst_latch_data.field_flag,IMF_STATUS_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_STATUS_FLAG) then inst_cnt_next <= 4; - elsif check_mask(inst_latch_data.field_flag,IMF_SAMPLE_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_SAMPLE_CNT_FLAG) then inst_cnt_next <= 5; - elsif check_mask(inst_latch_data.field_flag,IMF_DISPOSED_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_DISPOSED_CNT_FLAG) then inst_cnt_next <= 6; - elsif check_mask(inst_latch_data.field_flag,IMF_NO_WRITERS_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_NO_WRITERS_CNT_FLAG) then inst_cnt_next <= 7; - elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flag,IMF_IGNORE_DEADLINE_FLAG)) then + elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flags,IMF_IGNORE_DEADLINE_FLAG)) then inst_cnt_next <= 8; - elsif check_mask(inst_latch_data.field_flag,IMF_WRITER_BITMAP_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then inst_cnt_next <= 10; inst_cnt2_next <= 0; else @@ -4245,26 +4482,26 @@ begin -- Memory Flow Control Guard if (inst_valid_out = '1') then inst_prev_addr_base_next <= inst_addr_base; - inst_addr_base_next <= inst_read_data; + inst_addr_base_next <= resize(unsigned(inst_read_data),INSTANCE_MEMORY_ADDR_WIDTH); -- Match - if (inst_read_data = inst_latch_data.addr) then + if (resize(unsigned(inst_read_data),INSTANCE_MEMORY_ADDR_WIDTH) = inst_latch_data.addr) then -- Get Instance Data inst_stage_next <= GET_INSTANCE_DATA; inst_data_next <= ZERO_INSTANCE_DATA; - if check_mask(inst_latch_data.field_flag,IMF_KEY_HASH_FLAG) then + if check_mask(inst_latch_data.field_flags,IMF_KEY_HASH_FLAG) then inst_cnt_next <= 0; - elsif check_mask(inst_latch_data.field_flag,IMF_STATUS_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_STATUS_FLAG) then inst_cnt_next <= 4; - elsif check_mask(inst_latch_data.field_flag,IMF_SAMPLE_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_SAMPLE_CNT_FLAG) then inst_cnt_next <= 5; - elsif check_mask(inst_latch_data.field_flag,IMF_DISPOSED_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_DISPOSED_CNT_FLAG) then inst_cnt_next <= 6; - elsif check_mask(inst_latch_data.field_flag,IMF_NO_WRITERS_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_NO_WRITERS_CNT_FLAG) then inst_cnt_next <= 7; - elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flag,IMF_IGNORE_DEADLINE_FLAG)) then + elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flags,IMF_IGNORE_DEADLINE_FLAG)) then inst_cnt_next <= 8; - elsif check_mask(inst_latch_data.field_flag,IMF_WRITER_BITMAP_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then inst_cnt_next <= 10; inst_cnt2_next <= 0; else @@ -4274,7 +4511,7 @@ begin -- No Match else -- Reached List Tail, No Match - if (inst_read_data = INSTANCE_MEMORY_MAX_ADDRESS) then + if (resize(unsigned(inst_read_data),INSTANCE_MEMORY_ADDR_WIDTH) = INSTANCE_MEMORY_MAX_ADDRESS) then inst_addr_base_next <= INSTANCE_MEMORY_MAX_ADDRESS; --No match -- DONE inst_stage_next <= IDLE; @@ -4305,23 +4542,23 @@ begin -- Memory Flow Control Guard if (inst_valid_out = '1') then - inst_next_addr_base_next <= inst_read_data; + inst_next_addr_base_next <= resize(unsigned(inst_read_data),INSTANCE_MEMORY_ADDR_WIDTH); -- Get Instance Data inst_stage_next <= GET_INSTANCE_DATA; inst_data_next <= ZERO_INSTANCE_DATA; - if check_mask(inst_latch_data.field_flag,IMF_KEY_HASH_FLAG) then + if check_mask(inst_latch_data.field_flags,IMF_KEY_HASH_FLAG) then inst_cnt_next <= 0; - elsif check_mask(inst_latch_data.field_flag,IMF_STATUS_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_STATUS_FLAG) then inst_cnt_next <= 4; - elsif check_mask(inst_latch_data.field_flag,IMF_SAMPLE_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_SAMPLE_CNT_FLAG) then inst_cnt_next <= 5; - elsif check_mask(inst_latch_data.field_flag,IMF_DISPOSED_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_DISPOSED_CNT_FLAG) then inst_cnt_next <= 6; - elsif check_mask(inst_latch_data.field_flag,IMF_NO_WRITERS_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_NO_WRITERS_CNT_FLAG) then inst_cnt_next <= 7; - elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flag,IMF_IGNORE_DEADLINE_FLAG)) then + elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flags,IMF_IGNORE_DEADLINE_FLAG)) then inst_cnt_next <= 8; - elsif check_mask(inst_latch_data.field_flag,IMF_WRITER_BITMAP_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then inst_cnt_next <= 10; inst_cnt2_next <= 0; else @@ -4372,17 +4609,17 @@ begin -- Memory Flow Control Guard if (inst_ready_in = '1') then - if check_mask(inst_latch_data.field_flag,IMF_STATUS_FLAG) then + if check_mask(inst_latch_data.field_flags,IMF_STATUS_FLAG) then inst_cnt_next <= 4; - elsif check_mask(inst_latch_data.field_flag,IMF_SAMPLE_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_SAMPLE_CNT_FLAG) then inst_cnt_next <= 5; - elsif check_mask(inst_latch_data.field_flag,IMF_DISPOSED_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_DISPOSED_CNT_FLAG) then inst_cnt_next <= 6; - elsif check_mask(inst_latch_data.field_flag,IMF_NO_WRITERS_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_NO_WRITERS_CNT_FLAG) then inst_cnt_next <= 7; - elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flag,IMF_IGNORE_DEADLINE_FLAG)) then + elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flags,IMF_IGNORE_DEADLINE_FLAG)) then inst_cnt_next <= 8; - elsif check_mask(inst_latch_data.field_flag,IMF_WRITER_BITMAP_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then inst_cnt_next <= 10; inst_cnt2_next <= 0; else @@ -4397,19 +4634,19 @@ begin -- Memory Flow Control Guard if (inst_ready_in = '1') then - if check_mask(inst_latch_data.field_flag,IMF_SAMPLE_CNT_FLAG) then + if check_mask(inst_latch_data.field_flags,IMF_SAMPLE_CNT_FLAG) then inst_cnt_next <= 5; - elsif check_mask(inst_latch_data.field_flag,IMF_DISPOSED_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_DISPOSED_CNT_FLAG) then inst_cnt_next <= 6; - elsif check_mask(inst_latch_data.field_flag,IMF_NO_WRITERS_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_NO_WRITERS_CNT_FLAG) then inst_cnt_next <= 7; - elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flag,IMF_IGNORE_DEADLINE_FLAG)) then + elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flags,IMF_IGNORE_DEADLINE_FLAG)) then inst_cnt_next <= 8; - elsif check_mask(inst_latch_data.field_flag,IMF_WRITER_BITMAP_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then inst_cnt_next <= 10; inst_cnt2_next <= 0; else - if check_mask(inst_latch_data.field_flag,IMF_KEY_HASH_FLAG) then + if check_mask(inst_latch_data.field_flags,IMF_KEY_HASH_FLAG) then inst_cnt_next <= 11; else inst_cnt_next <= 15; @@ -4424,19 +4661,19 @@ begin -- Memory Flow Control Guard if (inst_ready_in = '1') then - if check_mask(inst_latch_data.field_flag,IMF_DISPOSED_CNT_FLAG) then + if check_mask(inst_latch_data.field_flags,IMF_DISPOSED_CNT_FLAG) then inst_cnt_next <= 6; - elsif check_mask(inst_latch_data.field_flag,IMF_NO_WRITERS_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_NO_WRITERS_CNT_FLAG) then inst_cnt_next <= 7; - elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flag,IMF_IGNORE_DEADLINE_FLAG)) then + elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flags,IMF_IGNORE_DEADLINE_FLAG)) then inst_cnt_next <= 8; - elsif check_mask(inst_latch_data.field_flag,IMF_WRITER_BITMAP_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then inst_cnt_next <= 10; inst_cnt2_next <= 0; else - if check_mask(inst_latch_data.field_flag,IMF_KEY_HASH_FLAG) then + if check_mask(inst_latch_data.field_flags,IMF_KEY_HASH_FLAG) then inst_cnt_next <= 11; - elsif check_mask(inst_latch_data.field_flag,IMF_STATUS_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_STATUS_FLAG) then inst_cnt_next <= 15; else inst_cnt_next <= 16; @@ -4451,19 +4688,19 @@ begin -- Memory Flow Control Guard if (inst_ready_in = '1') then - if check_mask(inst_latch_data.field_flag,IMF_NO_WRITERS_CNT_FLAG) then + if check_mask(inst_latch_data.field_flags,IMF_NO_WRITERS_CNT_FLAG) then inst_cnt_next <= 7; - elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flag,IMF_IGNORE_DEADLINE_FLAG)) then + elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flags,IMF_IGNORE_DEADLINE_FLAG)) then inst_cnt_next <= 8; - elsif check_mask(inst_latch_data.field_flag,IMF_WRITER_BITMAP_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then inst_cnt_next <= 10; inst_cnt2_next <= 0; else - if check_mask(inst_latch_data.field_flag,IMF_KEY_HASH_FLAG) then + if check_mask(inst_latch_data.field_flags,IMF_KEY_HASH_FLAG) then inst_cnt_next <= 11; - elsif check_mask(inst_latch_data.field_flag,IMF_STATUS_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_STATUS_FLAG) then inst_cnt_next <= 15; - elsif check_mask(inst_latch_data.field_flag,IMF_SAMPLE_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_SAMPLE_CNT_FLAG) then inst_cnt_next <= 16; else inst_cnt_next <= 17; @@ -4478,19 +4715,19 @@ begin -- Memory Flow Control Guard if (inst_ready_in = '1') then - if (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flag,IMF_IGNORE_DEADLINE_FLAG)) then + if (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flags,IMF_IGNORE_DEADLINE_FLAG)) then inst_cnt_next <= 8; - elsif check_mask(inst_latch_data.field_flag,IMF_WRITER_BITMAP_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then inst_cnt_next <= 10; inst_cnt2_next <= 0; else - if check_mask(inst_latch_data.field_flag,IMF_KEY_HASH_FLAG) then + if check_mask(inst_latch_data.field_flags,IMF_KEY_HASH_FLAG) then inst_cnt_next <= 11; - elsif check_mask(inst_latch_data.field_flag,IMF_STATUS_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_STATUS_FLAG) then inst_cnt_next <= 15; - elsif check_mask(inst_latch_data.field_flag,IMF_SAMPLE_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_SAMPLE_CNT_FLAG) then inst_cnt_next <= 16; - elsif check_mask(inst_latch_data.field_flag,IMF_DISPOSED_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_DISPOSED_CNT_FLAG) then inst_cnt_next <= 17; else inst_cnt_next <= 18; @@ -4520,19 +4757,19 @@ begin -- Memory Flow Control Guard if (inst_ready_in = '1') then - if check_mask(inst_latch_data.field_flag,IMF_WRITER_BITMAP_FLAG) then + if check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then inst_cnt_next <= 10; inst_cnt2_next <= 0; else - if check_mask(inst_latch_data.field_flag,IMF_KEY_HASH_FLAG) then + if check_mask(inst_latch_data.field_flags,IMF_KEY_HASH_FLAG) then inst_cnt_next <= 11; - elsif check_mask(inst_latch_data.field_flag,IMF_STATUS_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_STATUS_FLAG) then inst_cnt_next <= 15; - elsif check_mask(inst_latch_data.field_flag,IMF_SAMPLE_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_SAMPLE_CNT_FLAG) then inst_cnt_next <= 16; - elsif check_mask(inst_latch_data.field_flag,IMF_DISPOSED_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_DISPOSED_CNT_FLAG) then inst_cnt_next <= 17; - elsif check_mask(inst_latch_data.field_flag,IMF_NO_WRITERS_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_NO_WRITERS_CNT_FLAG) then inst_cnt_next <= 18; else inst_cnt_next <= 19; @@ -4550,18 +4787,18 @@ begin -- Memory Flow Control Guard if (inst_ready_in = '1') then -- Exit Condition - if (inst_cnt2 = ENDPOINT_BITMAP_ARRAY_TYPE'length-1) then - if check_mask(inst_latch_data.field_flag,IMF_KEY_HASH_FLAG) then + if (inst_cnt2 = WRITER_BITMAP_ARRAY_TYPE'length-1) then + if check_mask(inst_latch_data.field_flags,IMF_KEY_HASH_FLAG) then inst_cnt_next <= 11; - elsif check_mask(inst_latch_data.field_flag,IMF_STATUS_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_STATUS_FLAG) then inst_cnt_next <= 15; - elsif check_mask(inst_latch_data.field_flag,IMF_SAMPLE_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_SAMPLE_CNT_FLAG) then inst_cnt_next <= 16; - elsif check_mask(inst_latch_data.field_flag,IMF_DISPOSED_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_DISPOSED_CNT_FLAG) then inst_cnt_next <= 17; - elsif check_mask(inst_latch_data.field_flag,IMF_NO_WRITERS_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_NO_WRITERS_CNT_FLAG) then inst_cnt_next <= 18; - elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flag,IMF_IGNORE_DEADLINE_FLAG)) then + elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flags,IMF_IGNORE_DEADLINE_FLAG)) then inst_cnt_next <= 19; else inst_cnt_next <= 21; @@ -4577,7 +4814,7 @@ begin -- Memory Flow Control Guard if (inst_valid_out = '1') then - inst_latch_data_next.key_hash(0) <= inst_read_data; + inst_data_next.key_hash(0) <= inst_read_data; inst_cnt_next <= inst_cnt + 1; end if; -- READ Key Hash 2/4 @@ -4586,7 +4823,7 @@ begin -- Memory Flow Control Guard if (inst_valid_out = '1') then - inst_latch_data_next.key_hash(1) <= inst_read_data; + inst_data_next.key_hash(1) <= inst_read_data; inst_cnt_next <= inst_cnt + 1; end if; -- READ Key Hash 3/4 @@ -4595,7 +4832,7 @@ begin -- Memory Flow Control Guard if (inst_valid_out = '1') then - inst_latch_data_next.key_hash(2) <= inst_read_data; + inst_data_next.key_hash(2) <= inst_read_data; inst_cnt_next <= inst_cnt + 1; end if; -- READ Key Hash 4/4 @@ -4604,19 +4841,19 @@ begin -- Memory Flow Control Guard if (inst_valid_out = '1') then - inst_latch_data_next.key_hash(3) <= inst_read_data; + inst_data_next.key_hash(3) <= inst_read_data; - if check_mask(inst_latch_data.field_flag,IMF_STATUS_FLAG) then + if check_mask(inst_latch_data.field_flags,IMF_STATUS_FLAG) then inst_cnt_next <= 15; - elsif check_mask(inst_latch_data.field_flag,IMF_SAMPLE_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_SAMPLE_CNT_FLAG) then inst_cnt_next <= 16; - elsif check_mask(inst_latch_data.field_flag,IMF_DISPOSED_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_DISPOSED_CNT_FLAG) then inst_cnt_next <= 17; - elsif check_mask(inst_latch_data.field_flag,IMF_NO_WRITERS_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_NO_WRITERS_CNT_FLAG) then inst_cnt_next <= 18; - elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flag,IMF_IGNORE_DEADLINE_FLAG)) then + elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flags,IMF_IGNORE_DEADLINE_FLAG)) then inst_cnt_next <= 19; - elsif check_mask(inst_latch_data.field_flag,IMF_WRITER_BITMAP_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then inst_cnt_next <= 21; inst_cnt2_next <= 0; else @@ -4630,17 +4867,17 @@ begin -- Memory Flow Control Guard if (inst_valid_out = '1') then - inst_latch_data_next.status_info <= inst_read_data; + inst_data_next.status_info <= inst_read_data; - if check_mask(inst_latch_data.field_flag,IMF_SAMPLE_CNT_FLAG) then + if check_mask(inst_latch_data.field_flags,IMF_SAMPLE_CNT_FLAG) then inst_cnt_next <= 16; - elsif check_mask(inst_latch_data.field_flag,IMF_DISPOSED_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_DISPOSED_CNT_FLAG) then inst_cnt_next <= 17; - elsif check_mask(inst_latch_data.field_flag,IMF_NO_WRITERS_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_NO_WRITERS_CNT_FLAG) then inst_cnt_next <= 18; - elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flag,IMF_IGNORE_DEADLINE_FLAG)) then + elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flags,IMF_IGNORE_DEADLINE_FLAG)) then inst_cnt_next <= 19; - elsif check_mask(inst_latch_data.field_flag,IMF_WRITER_BITMAP_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then inst_cnt_next <= 21; inst_cnt2_next <= 0; else @@ -4654,15 +4891,15 @@ begin -- Memory Flow Control Guard if (inst_valid_out = '1') then - inst_latch_data_next.sample_cnt <= inst_read_data; + inst_data_next.sample_cnt <= unsigned(inst_read_data); - if check_mask(inst_latch_data.field_flag,IMF_DISPOSED_CNT_FLAG) then + if check_mask(inst_latch_data.field_flags,IMF_DISPOSED_CNT_FLAG) then inst_cnt_next <= 17; - elsif check_mask(inst_latch_data.field_flag,IMF_NO_WRITERS_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_NO_WRITERS_CNT_FLAG) then inst_cnt_next <= 18; - elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flag,IMF_IGNORE_DEADLINE_FLAG)) then + elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flags,IMF_IGNORE_DEADLINE_FLAG)) then inst_cnt_next <= 19; - elsif check_mask(inst_latch_data.field_flag,IMF_WRITER_BITMAP_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then inst_cnt_next <= 21; inst_cnt2_next <= 0; else @@ -4676,13 +4913,13 @@ begin -- Memory Flow Control Guard if (inst_valid_out = '1') then - inst_latch_data_next.disposed_gen_cnt <= inst_read_data; + inst_data_next.disposed_gen_cnt <= unsigned(inst_read_data); - if check_mask(inst_latch_data.field_flag,IMF_NO_WRITERS_CNT_FLAG) then + if check_mask(inst_latch_data.field_flags,IMF_NO_WRITERS_CNT_FLAG) then inst_cnt_next <= 18; - elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flag,IMF_IGNORE_DEADLINE_FLAG)) then + elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flags,IMF_IGNORE_DEADLINE_FLAG)) then inst_cnt_next <= 19; - elsif check_mask(inst_latch_data.field_flag,IMF_WRITER_BITMAP_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then inst_cnt_next <= 21; inst_cnt2_next <= 0; else @@ -4696,11 +4933,11 @@ begin -- Memory Flow Control Guard if (inst_valid_out = '1') then - inst_latch_data_next.no_writers_gen_cnt <= inst_read_data; + inst_data_next.no_writers_gen_cnt <= unsigned(inst_read_data); - if (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flag,IMF_IGNORE_DEADLINE_FLAG)) then + if (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flags,IMF_IGNORE_DEADLINE_FLAG)) then inst_cnt_next <= 19; - elsif check_mask(inst_latch_data.field_flag,IMF_WRITER_BITMAP_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then inst_cnt_next <= 21; inst_cnt2_next <= 0; else @@ -4714,7 +4951,7 @@ begin -- Memory Flow Control Guard if (inst_valid_out = '1') then - inst_latch_data_next.ignore_deadline(0) <= inst_read_data; + inst_data_next.ignore_deadline(0) <= unsigned(inst_read_data); inst_cnt_next <= inst_cnt + 1; end if; @@ -4724,9 +4961,9 @@ begin -- Memory Flow Control Guard if (inst_valid_out = '1') then - inst_latch_data_next.ignore_deadline(1) <= inst_read_data; + inst_data_next.ignore_deadline(1) <= unsigned(inst_read_data); - if check_mask(inst_latch_data.field_flag,IMF_WRITER_BITMAP_FLAG) then + if check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then inst_cnt_next <= 21; inst_cnt2_next <= 0; else @@ -4740,9 +4977,9 @@ begin -- Memory Flow Control Guard if (inst_valid_out = '1') then - inst_latch_data_next.writer_bitmap(inst_cnt2) <= inst_read_data; + inst_data_next.writer_bitmap(inst_cnt2) <= inst_read_data; -- Exit Condition - if (inst_cnt2 = ENDPOINT_BITMAP_ARRAY_TYPE'length-1) then + if (inst_cnt2 = WRITER_BITMAP_ARRAY_TYPE'length-1) then -- DONE inst_stage_next <= IDLE; else @@ -4753,8 +4990,6 @@ begin when FIND_POS => -- NOTE: Instances are inserted in KEY_HASH numerical order. - -- TODO: Handle inst_next_addr_base = MAX_ADDR - case (inst_cnt) is -- GET Next Instance when 0 => @@ -4812,7 +5047,7 @@ begin -- Memory Flow Control Guard if (inst_valid_out = '1') then - inst_next_addr_base_next <= inst_read_data; + inst_next_addr_base_next <= resize(unsigned(inst_read_data),INSTANCE_MEMORY_ADDR_WIDTH); inst_cnt_next <= inst_cnt + 1; end if; -- READ Key Hash 1/4 @@ -4821,29 +5056,40 @@ begin -- Memory Flow Control Guard if (inst_valid_out = '1') then + inst_cnt_next <= inst_cnt + 1; -- Found Position (Before Current Instance) if (inst_latch_data.key_hash(0) < inst_read_data) then inst_next_addr_base_next <= inst_addr_base; + inst_abort_read <= '1'; -- Occupied List Head if (inst_prev_addr_base = INSTANCE_MEMORY_MAX_ADDRESS) then - assert (inst_addr_base = inst_occupied_head) + assert (inst_addr_base = inst_occupied_head) severity FAILURE; inst_occupied_head_next <= inst_empty_head; inst_addr_base_next <= inst_empty_head; inst_stage_next <= INSERT_INSTANCE; - cnt_next <= 1; -- Skip First Step + inst_cnt_next <= 1; -- Skip First Step else - inst_addr_base_next <= inst_prev_addr_base; + inst_addr_base_next <= inst_empty_head; inst_stage_next <= INSERT_INSTANCE; - cnt_next <= 0; + inst_cnt_next <= 0; end if; -- BIGGER-THAN elsif (inst_latch_data.key_hash(0) /= inst_read_data) then - -- Continue - inst_prev_addr_base_next <= inst_addr_base; - inst_addr_base_next <= inst_next_addr_base; - cnt_next <= 0; - inst_abort_read <= '1'; + inst_abort_read <= '1'; + -- End of Instances + if (inst_next_addr_base = INSTANCE_MEMORY_MAX_ADDRESS) then + inst_next_addr_base_next <= INSTANCE_MEMORY_MAX_ADDRESS; + inst_prev_addr_base_next <= inst_addr_base; + inst_addr_base_next <= inst_empty_head; + inst_stage_next <= INSERT_INSTANCE; + inst_cnt_next <= 0; + else + -- Continue + inst_prev_addr_base_next <= inst_addr_base; + inst_addr_base_next <= inst_next_addr_base; + inst_cnt_next <= 0; + end if; end if; end if; -- READ Key Hash 2/4 @@ -4852,29 +5098,40 @@ begin -- Memory Flow Control Guard if (inst_valid_out = '1') then + inst_cnt_next <= inst_cnt + 1; -- Found Position (Before Current Instance) if (inst_latch_data.key_hash(1) < inst_read_data) then inst_next_addr_base_next <= inst_addr_base; + inst_abort_read <= '1'; -- Occupied List Head if (inst_prev_addr_base = INSTANCE_MEMORY_MAX_ADDRESS) then - assert (inst_addr_base = inst_occupied_head) + assert (inst_addr_base = inst_occupied_head) severity FAILURE; inst_occupied_head_next <= inst_empty_head; inst_addr_base_next <= inst_empty_head; inst_stage_next <= INSERT_INSTANCE; - cnt_next <= 1; -- Skip First Step + inst_cnt_next <= 1; -- Skip First Step else - inst_addr_base_next <= inst_prev_addr_base; + inst_addr_base_next <= inst_empty_head; inst_stage_next <= INSERT_INSTANCE; - cnt_next <= 0; + inst_cnt_next <= 0; end if; -- BIGGER-THAN elsif (inst_latch_data.key_hash(1) /= inst_read_data) then - -- Continue - inst_prev_addr_base_next <= inst_addr_base; - inst_addr_base_next <= inst_next_addr_base; - cnt_next <= 0; inst_abort_read <= '1'; + -- End of Instances + if (inst_next_addr_base = INSTANCE_MEMORY_MAX_ADDRESS) then + inst_next_addr_base_next <= INSTANCE_MEMORY_MAX_ADDRESS; + inst_prev_addr_base_next <= inst_addr_base; + inst_addr_base_next <= inst_empty_head; + inst_stage_next <= INSERT_INSTANCE; + inst_cnt_next <= 0; + else + -- Continue + inst_prev_addr_base_next <= inst_addr_base; + inst_addr_base_next <= inst_next_addr_base; + inst_cnt_next <= 0; + end if; end if; end if; -- READ Key Hash 3/4 @@ -4883,71 +5140,102 @@ begin -- Memory Flow Control Guard if (inst_valid_out = '1') then + inst_cnt_next <= inst_cnt + 1; -- Found Position (Before Current Instance) if (inst_latch_data.key_hash(2) < inst_read_data) then inst_next_addr_base_next <= inst_addr_base; + inst_abort_read <= '1'; -- Occupied List Head if (inst_prev_addr_base = INSTANCE_MEMORY_MAX_ADDRESS) then - assert (inst_addr_base = inst_occupied_head) + assert (inst_addr_base = inst_occupied_head) severity FAILURE; inst_occupied_head_next <= inst_empty_head; inst_addr_base_next <= inst_empty_head; inst_stage_next <= INSERT_INSTANCE; - cnt_next <= 1; -- Skip First Step + inst_cnt_next <= 1; -- Skip First Step else - inst_addr_base_next <= inst_prev_addr_base; + inst_addr_base_next <= inst_empty_head; inst_stage_next <= INSERT_INSTANCE; - cnt_next <= 0; + inst_cnt_next <= 0; end if; -- BIGGER-THAN elsif (inst_latch_data.key_hash(2) /= inst_read_data) then - -- Continue - inst_prev_addr_base_next <= inst_addr_base; - inst_addr_base_next <= inst_next_addr_base; - cnt_next <= 0; inst_abort_read <= '1'; + -- End of Instances + if (inst_next_addr_base = INSTANCE_MEMORY_MAX_ADDRESS) then + inst_next_addr_base_next <= INSTANCE_MEMORY_MAX_ADDRESS; + inst_prev_addr_base_next <= inst_addr_base; + inst_addr_base_next <= inst_empty_head; + inst_stage_next <= INSERT_INSTANCE; + inst_cnt_next <= 0; + else + -- Continue + inst_prev_addr_base_next <= inst_addr_base; + inst_addr_base_next <= inst_next_addr_base; + inst_cnt_next <= 0; + end if; end if; end if; -- Key Hash 4/4 - when 5 => + when 9 => inst_ready_out <= '1'; -- Memory Flow Control Guard if (inst_valid_out = '1') then - -- Found Position + inst_cnt_next <= inst_cnt + 1; + -- Found Position (Before Current Instance) if (inst_latch_data.key_hash(3) < inst_read_data) then inst_next_addr_base_next <= inst_addr_base; -- Occupied List Head if (inst_prev_addr_base = INSTANCE_MEMORY_MAX_ADDRESS) then - assert (inst_addr_base = inst_occupied_head) + assert (inst_addr_base = inst_occupied_head) severity FAILURE; inst_occupied_head_next <= inst_empty_head; inst_addr_base_next <= inst_empty_head; inst_stage_next <= INSERT_INSTANCE; - cnt_next <= 1; -- Skip First Step + inst_cnt_next <= 1; -- Skip First Step else - inst_addr_base_next <= inst_prev_addr_base; + inst_addr_base_next <= inst_empty_head; inst_stage_next <= INSERT_INSTANCE; - cnt_next <= 0; + inst_cnt_next <= 0; end if; else - assert (inst_latch_data.key_hash(3) /= inst_read_data) report "Doublicate Instance Detected" severity FAILURE; + assert (inst_latch_data.key_hash(3) /= inst_read_data) report "Duplicate Instance Detected" severity FAILURE; - -- Continue - inst_prev_addr_base_next <= inst_addr_base; - inst_addr_base_next <= inst_next_addr_base; - cnt_next <= 0; + -- End of Instances + if (inst_next_addr_base = INSTANCE_MEMORY_MAX_ADDRESS) then + inst_next_addr_base_next <= INSTANCE_MEMORY_MAX_ADDRESS; + inst_prev_addr_base_next <= inst_addr_base; + inst_addr_base_next <= inst_empty_head; + inst_stage_next <= INSERT_INSTANCE; + inst_cnt_next <= 0; + else + -- Continue + inst_prev_addr_base_next <= inst_addr_base; + inst_addr_base_next <= inst_next_addr_base; + inst_cnt_next <= 0; + end if; end if; end if; when others => null; end case; when INSERT_INSTANCE => - -- Precondition: inst_addr_base set, inst_prev_addr_base set + -- Precondition: inst_addr_base set, inst_prev_addr_base set (Only if first Step executed), inst_next_addr_base set case (inst_cnt) is - -- GET Next Pointer + -- Next Pointer (Previous Instance) when 0 => + inst_valid_in <= '1'; + inst_addr <= inst_prev_addr_base + IMF_NEXT_ADDR_OFFSET; + inst_write_data <= std_logic_vector(resize(inst_addr_base,WORD_WIDTH)); + + -- Memory Flow Control Guard + if (inst_ready_in = '1') then + inst_cnt_next <= inst_cnt + 1; + end if; + -- GET Next Pointer + when 1 => inst_valid_in <= '1'; inst_addr <= inst_addr_base + IMF_NEXT_ADDR_OFFSET; inst_read <= '1'; @@ -4961,29 +5249,29 @@ begin inst_cnt_next <= inst_cnt + 1; end if; end if; - -- Next Pointer (Previous Instance) - when 1 => + -- Next Pointer (New Instance) + when 2 => inst_valid_in <= '1'; - inst_addr <= inst_prev_addr_base + IMF_NEXT_ADDR_OFFSET; - inst_write_data <= inst_addr_base; + inst_addr <= inst_addr_base + IMF_NEXT_ADDR_OFFSET; + inst_write_data <= std_logic_vector(resize(inst_next_addr_base,WORD_WIDTH)); -- Memory Flow Control Guard if (inst_ready_in = '1') then inst_cnt_next <= inst_cnt + 1; end if; -- READ Next Pointer - when 2 => + when 3 => inst_ready_out <= '1'; -- Memory Flow Control Guard if (inst_valid_out = '1') then -- Fix Empty List Head - inst_empty_head_next <= inst_read_data; + inst_empty_head_next <= resize(unsigned(inst_read_data),INSTANCE_MEMORY_ADDR_WIDTH); - -- TODO + inst_cnt_next <= inst_cnt + 1; end if; -- Key Hash 1/4 - when 3 => + when 4 => inst_valid_in <= '1'; inst_addr <= inst_addr_base + IMF_KEY_HASH_OFFSET; inst_write_data <= inst_latch_data.key_hash(0); @@ -4993,7 +5281,7 @@ begin inst_cnt_next <= inst_cnt + 1; end if; -- Key Hash 2/4 - when 4 => + when 5 => inst_valid_in <= '1'; inst_addr <= inst_addr_base + IMF_KEY_HASH_OFFSET + 1; inst_write_data <= inst_latch_data.key_hash(1); @@ -5003,7 +5291,7 @@ begin inst_cnt_next <= inst_cnt + 1; end if; -- Key Hash 3/4 - when 5 => + when 6 => inst_valid_in <= '1'; inst_addr <= inst_addr_base + IMF_KEY_HASH_OFFSET + 2; inst_write_data <= inst_latch_data.key_hash(2); @@ -5013,7 +5301,7 @@ begin inst_cnt_next <= inst_cnt + 1; end if; -- Key Hash 4/4 - when 6 => + when 7 => inst_valid_in <= '1'; inst_addr <= inst_addr_base + IMF_KEY_HASH_OFFSET + 3; inst_write_data <= inst_latch_data.key_hash(3); @@ -5023,7 +5311,7 @@ begin inst_cnt_next <= inst_cnt + 1; end if; -- Status Info - when 7 => + when 8 => inst_valid_in <= '1'; inst_addr <= inst_addr_base + IMF_STATUS_INFO_OFFSET; inst_write_data <= inst_latch_data.status_info; @@ -5033,17 +5321,17 @@ begin inst_cnt_next <= inst_cnt + 1; end if; -- Sample Count - when 8 => + when 9 => inst_valid_in <= '1'; inst_addr <= inst_addr_base + IMF_SAMPLE_CNT_OFFSET; - inst_write_data <= inst_latch_data.sample_cnt; + inst_write_data <= std_logic_vector(inst_latch_data.sample_cnt); -- Memory Flow Control Guard if (inst_ready_in = '1') then inst_cnt_next <= inst_cnt + 1; end if; -- Disposed Generation Count - when 9 => + when 10 => inst_valid_in <= '1'; inst_addr <= inst_addr_base + IMF_DISPOSED_GEN_CNT_OFFSET; inst_write_data <= (others => '0'); @@ -5053,7 +5341,7 @@ begin inst_cnt_next <= inst_cnt + 1; end if; -- No Writers Generation Count - when 10 => + when 11 => inst_valid_in <= '1'; inst_addr <= inst_addr_base + IMF_NO_WRITERS_GEN_CNT_OFFSET; inst_write_data <= (others => '0'); @@ -5069,12 +5357,12 @@ begin end if; -- Ignore Deadline 1/2 - when 11 => + when 12 => -- Synthesis Guard if (TIME_BASED_FILTER_QOS /= DURATION_ZERO) then inst_valid_in <= '1'; inst_addr <= inst_addr_base + IMF_IGNORE_DEADLINE_OFFSET; - inst_write_data <= inst_latch_data.deadline(0); + inst_write_data <= std_logic_vector(inst_latch_data.deadline(0)); -- Memory Flow Control Guard if (inst_ready_in = '1') then @@ -5082,12 +5370,12 @@ begin end if; end if; -- Ignore Deadline 2/2 - when 12 => + when 13 => -- Synthesis Guard if (TIME_BASED_FILTER_QOS /= DURATION_ZERO) then inst_valid_in <= '1'; inst_addr <= inst_addr_base + IMF_IGNORE_DEADLINE_OFFSET + 1; - inst_write_data <= inst_latch_data.deadline(1); + inst_write_data <= std_logic_vector(inst_latch_data.deadline(1)); -- Memory Flow Control Guard if (inst_ready_in = '1') then @@ -5096,7 +5384,7 @@ begin end if; end if; -- Writer Bitmap - when 13 => + when 14 => -- XXX: Possible Worst case Path (2 Additions in same clock) inst_valid_in <= '1'; inst_addr <= inst_addr_base + IMF_WRITER_BITMAP_OFFSET + inst_cnt2; @@ -5105,7 +5393,7 @@ begin -- Memory Flow Control Guard if (inst_ready_in = '1') then -- Exit Condition - if (inst_cnt2 = ENDPOINT_BITMAP_ARRAY_TYPE'length-1) then + if (inst_cnt2 = WRITER_BITMAP_ARRAY_TYPE'length-1) then -- DONE inst_stage_next <= IDLE; else @@ -5125,15 +5413,15 @@ begin inst_data_next.status_info <= inst_latch_data.status_info; -- Memory Flow Control Guard if (inst_ready_in = '1') then - if check_mask(inst_latch_data.field_flag,IMF_SAMPLE_CNT_FLAG) then + if check_mask(inst_latch_data.field_flags,IMF_SAMPLE_CNT_FLAG) then inst_cnt_next <= 1; - elsif check_mask(inst_latch_data.field_flag,IMF_DISPOSED_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_DISPOSED_CNT_FLAG) then inst_cnt_next <= 2; - elsif check_mask(inst_latch_data.field_flag,IMF_NO_WRITERS_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_NO_WRITERS_CNT_FLAG) then inst_cnt_next <= 3; - elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flag,IMF_IGNORE_DEADLINE_FLAG)) then + elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flags,IMF_IGNORE_DEADLINE_FLAG)) then inst_cnt_next <= 4; - elsif check_mask(inst_latch_data.field_flag,IMF_WRITER_BITMAP_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then inst_cnt_next <= 6; inst_cnt2_next <= 0; else @@ -5145,17 +5433,17 @@ begin when 1 => inst_valid_in <= '1'; inst_addr <= inst_addr_base + IMF_SAMPLE_CNT_OFFSET; - inst_write_data <= inst_latch_data.sample_cnt; + inst_write_data <= std_logic_vector(inst_latch_data.sample_cnt); inst_data_next.sample_cnt <= inst_latch_data.sample_cnt; -- Memory Flow Control Guard if (inst_ready_in = '1') then - if check_mask(inst_latch_data.field_flag,IMF_DISPOSED_CNT_FLAG) then + if check_mask(inst_latch_data.field_flags,IMF_DISPOSED_CNT_FLAG) then inst_cnt_next <= 2; - elsif check_mask(inst_latch_data.field_flag,IMF_NO_WRITERS_CNT_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_NO_WRITERS_CNT_FLAG) then inst_cnt_next <= 3; - elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flag,IMF_IGNORE_DEADLINE_FLAG)) then + elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flags,IMF_IGNORE_DEADLINE_FLAG)) then inst_cnt_next <= 4; - elsif check_mask(inst_latch_data.field_flag,IMF_WRITER_BITMAP_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then inst_cnt_next <= 6; inst_cnt2_next <= 0; else @@ -5167,15 +5455,15 @@ begin when 2 => inst_valid_in <= '1'; inst_addr <= inst_addr_base + IMF_DISPOSED_GEN_CNT_OFFSET; - inst_write_data <= inst_latch_data.gen_cnt; + inst_write_data <= std_logic_vector(inst_latch_data.gen_cnt); inst_data_next.disposed_gen_cnt <= inst_latch_data.gen_cnt; -- Memory Flow Control Guard if (inst_ready_in = '1') then - if check_mask(inst_latch_data.field_flag,IMF_NO_WRITERS_CNT_FLAG) then + if check_mask(inst_latch_data.field_flags,IMF_NO_WRITERS_CNT_FLAG) then inst_cnt_next <= 3; - elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flag,IMF_IGNORE_DEADLINE_FLAG)) then + elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flags,IMF_IGNORE_DEADLINE_FLAG)) then inst_cnt_next <= 4; - elsif check_mask(inst_latch_data.field_flag,IMF_WRITER_BITMAP_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then inst_cnt_next <= 6; inst_cnt2_next <= 0; else @@ -5187,13 +5475,13 @@ begin when 3 => inst_valid_in <= '1'; inst_addr <= inst_addr_base + IMF_NO_WRITERS_GEN_CNT_OFFSET; - inst_write_data <= inst_latch_data.gen_cnt; + inst_write_data <= std_logic_vector(inst_latch_data.gen_cnt); inst_data_next.no_writers_gen_cnt <= inst_latch_data.gen_cnt; -- Memory Flow Control Guard if (inst_ready_in = '1') then - if (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flag,IMF_IGNORE_DEADLINE_FLAG)) then + if (TIME_BASED_FILTER_QOS /= DURATION_ZERO and check_mask(inst_latch_data.field_flags,IMF_IGNORE_DEADLINE_FLAG)) then inst_cnt_next <= 4; - elsif check_mask(inst_latch_data.field_flag,IMF_WRITER_BITMAP_FLAG) then + elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then inst_cnt_next <= 6; inst_cnt2_next <= 0; else @@ -5206,8 +5494,8 @@ begin if (TIME_BASED_FILTER_QOS /= DURATION_ZERO) then inst_valid_in <= '1'; inst_addr <= inst_addr_base + IMF_IGNORE_DEADLINE_OFFSET; - inst_write_data <= std_logic_vector(inst_latch_data.ignore_deadline(0)); - inst_data_next.deadline <= inst_latch_data.ignore_deadline(0); + inst_write_data <= std_logic_vector(inst_latch_data.deadline(0)); + inst_data_next.ignore_deadline(0) <= inst_latch_data.deadline(0); -- Memory Flow Control Guard if (inst_ready_in = '1') then inst_cnt_next <= inst_cnt + 1; @@ -5218,11 +5506,11 @@ begin if (TIME_BASED_FILTER_QOS /= DURATION_ZERO) then inst_valid_in <= '1'; inst_addr <= inst_addr_base + IMF_IGNORE_DEADLINE_OFFSET + 1; - inst_write_data <= std_logic_vector(inst_latch_data.ignore_deadline(0)); - inst_data_next.deadline <= inst_latch_data.ignore_deadline(0); + inst_write_data <= std_logic_vector(inst_latch_data.deadline(1)); + inst_data_next.ignore_deadline(1) <= inst_latch_data.deadline(1); -- Memory Flow Control Guard if (inst_ready_in = '1') then - if check_mask(inst_latch_data.field_flag,IMF_WRITER_BITMAP_FLAG) then + if check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then inst_cnt_next <= 6; inst_cnt2_next <= 0; else @@ -5241,7 +5529,7 @@ begin -- Memory Flow Control Guard if (inst_ready_in = '1') then -- Exit Condition - if (inst_cnt2 = ENDPOINT_BITMAP_ARRAY_TYPE'length-1) then + if (inst_cnt2 = WRITER_BITMAP_ARRAY_TYPE'length-1) then -- DONE inst_stage_next <= IDLE; else @@ -5271,7 +5559,7 @@ begin -- Memory Flow Control Guard if (inst_valid_out = '1') then - inst_next_addr_base_next <= inst_read_data; + inst_next_addr_base_next <= resize(unsigned(inst_read_data),INSTANCE_MEMORY_ADDR_WIDTH); inst_cnt_next <= inst_cnt + 1; end if; -- Next Pointer (Previous Instance) @@ -5279,7 +5567,7 @@ begin -- Point Previous instance to Next Instance (Remove current Instance from inbetween) inst_valid_in <= '1'; inst_addr <= inst_prev_addr_base + IMF_NEXT_ADDR_OFFSET; - inst_write_data <= inst_next_addr_base; + inst_write_data <= std_logic_vector(resize(inst_next_addr_base,WORD_WIDTH)); -- Memory Flow Control Guard if (inst_ready_in = '1') then @@ -5290,7 +5578,7 @@ begin -- Point Current Instance to Empty List Head (Make Removed Instance Head of the Empty List) inst_valid_in <= '1'; inst_addr <= inst_addr_base + IMF_NEXT_ADDR_OFFSET; - inst_write_data <= inst_empty_head; + inst_write_data <= std_logic_vector(resize(inst_empty_head,WORD_WIDTH)); -- Memory Flow Control Guard if (inst_ready_in = '1') then @@ -5337,7 +5625,7 @@ begin -- Memory Flow Control Guard if (inst_valid_out = '1') then - inst_next_addr_base_next <= inst_read_data; + inst_next_addr_base_next <= resize(unsigned(inst_read_data),INSTANCE_MEMORY_ADDR_WIDTH); inst_cnt_next <= inst_cnt + 1; end if; -- READ Status Info @@ -5396,9 +5684,9 @@ begin inst_valid_in <= '1'; inst_addr <= inst_addr_base + IMF_NEXT_ADDR_OFFSET; if (inst_addr_base = MAX_INSTANCE_ADDRESS) then - inst_write_data <= INSTANCE_MEMORY_MAX_ADDRESS; + inst_write_data <= std_logic_vector(resize(INSTANCE_MEMORY_MAX_ADDRESS,WORD_WIDTH)); else - inst_write_data <= inst_addr_base + INSTANCE_FRAME_SIZE; + inst_write_data <= std_logic_vector(resize(inst_addr_base + INSTANCE_FRAME_SIZE,WORD_WIDTH)); end if; -- Memory Flow Control Guard @@ -5418,4 +5706,167 @@ begin end case; end process; end generate; + + sync_prc : process(clk) + begin + if rising_edge(clk) then + if (reset = '1') then + stage <= RESET_SAMPLE_MEMORY; + inst_stage <= RESET_MEMORY; + newest_sample <= SAMPLE_MEMORY_MAX_ADDRESS; + oldest_sample <= SAMPLE_MEMORY_MAX_ADDRESS; + sample_addr_latch_1 <= SAMPLE_MEMORY_MAX_ADDRESS; + sample_addr_latch_2 <= SAMPLE_MEMORY_MAX_ADDRESS; + sample_addr_latch_3 <= SAMPLE_MEMORY_MAX_ADDRESS; + sample_addr_latch_4 <= SAMPLE_MEMORY_MAX_ADDRESS; + empty_sample_list_head <= FIRST_SAMPLE_ADDRESS; + empty_sample_list_tail <= MAX_SAMPLE_ADDRESS; + payload_addr_latch_1 <= PAYLOAD_MEMORY_MAX_ADDRESS; + payload_addr_latch_2 <= PAYLOAD_MEMORY_MAX_ADDRESS; + empty_payload_list_head <= FIRST_PAYLOAD_ADDRESS; + inst_addr_latch_1 <= INSTANCE_MEMORY_MAX_ADDRESS; + inst_addr_latch_2 <= INSTANCE_MEMORY_MAX_ADDRESS; + inst_addr_base <= INSTANCE_MEMORY_MAX_ADDRESS; + inst_occupied_head <= INSTANCE_MEMORY_MAX_ADDRESS; + inst_next_addr_base <= INSTANCE_MEMORY_MAX_ADDRESS; + inst_prev_addr_base <= INSTANCE_MEMORY_MAX_ADDRESS; + inst_empty_head <= FIRST_INSTANCE_ADDRESS; + key_hash <= HANDLE_NIL; + si_instance_handle_sig <= HANDLE_NIL; + si_publication_handle_sig <= (others => (others => '0')); + instance_handle <= HANDLE_NIL; + sample_rej_last_inst <= HANDLE_NIL; + ts_latch <= TIME_INVALID; + lifespan_time <= TIME_INVALID; + lifespan <= TIME_INVALID; + si_source_timestamp_sig <= TIME_INVALID; + last_read_ts <= TIME_ZERO; + deadline_time <= time + DEADLINE_QOS; + si_sample_state_sig <= ANY_SAMPLE_STATE; + sample_state <= ANY_SAMPLE_STATE; + si_view_state_sig <= ANY_VIEW_STATE; + view_state <= ANY_VIEW_STATE; + si_instance_state_sig <= ANY_INSTANCE_STATE; + instance_state <= ANY_INSTANCE_STATE; + inst_data <= ZERO_INSTANCE_DATA; + inst_latch_data <= ZERO_INST_LATCH_DATA; + sample_rej_last_reason <= NOT_REJECTED; + return_code_latch <= ERROR; + writer_pos <= 0; + cnt <= 0; + cnt2 <= 0; + cnt3 <= 0; + inst_cnt <= 0; + inst_cnt2 <= 0; + stale_inst_cnt <= 0; + is_lifespan_check <= '0'; + remove_oldest_sample <= '0'; + remove_oldest_inst_sample <= '0'; + si_valid_data_sig <= '0'; + si_valid_sig <= '0'; + is_take <= '0'; + single_instance <= '0'; + single_sample <= '0'; + unmark_instances_flag <= '0'; + dynamic_next_instance <= '0'; + long_latch <= (others => '0'); + sample_status_info <= (others => '0'); + si_disposed_generation_count_sig <= (others => '0'); + si_no_writers_generation_count_sig <= (others => '0'); + si_sample_rank_sig <= (others => '0'); + si_generation_rank_sig <= (others => '0'); + si_absolute_generation_count_sig <= (others => '0'); + max_samples_latch <= (others => '0'); + collection_cnt <= (others => '0'); + collection_cnt_max <= (others => '0'); + collection_generation_rank <= (others => '0'); + cur_generation_rank <= (others => '0'); + sample_rej_cnt <= (others => '0'); + sample_rej_cnt_change <= (others => '0'); + deadline_miss_cnt <= (others => '0'); + deadline_miss_cnt_change <= (others => '0'); + deadline_miss_last_inst <= HANDLE_NIL; + status_sig <= (others => '0'); + inst_long_latch <= (others => '0'); + else + stage <= stage_next; + inst_stage <= inst_stage_next; + newest_sample <= newest_sample_next; + oldest_sample <= oldest_sample_next; + sample_addr_latch_1 <= sample_addr_latch_1_next; + sample_addr_latch_2 <= sample_addr_latch_2_next; + sample_addr_latch_3 <= sample_addr_latch_3_next; + sample_addr_latch_4 <= sample_addr_latch_4_next; + empty_sample_list_head <= empty_payload_list_head_next; + empty_sample_list_tail <= empty_sample_list_tail_next; + payload_addr_latch_1 <= payload_addr_latch_1_next; + payload_addr_latch_2 <= payload_addr_latch_2_next; + empty_payload_list_head <= empty_payload_list_head_next; + inst_addr_latch_1 <= inst_addr_latch_1_next; + inst_addr_latch_2 <= inst_addr_latch_2_next; + inst_addr_base <= inst_addr_base_next; + inst_occupied_head <= inst_occupied_head_next; + inst_next_addr_base <= inst_next_addr_base_next; + inst_prev_addr_base <= inst_prev_addr_base_next; + inst_empty_head <= inst_empty_head_next; + key_hash <= key_hash_next; + si_instance_handle_sig <= si_instance_handle_sig_next; + si_publication_handle_sig <= si_publication_handle_sig_next; + instance_handle <= instance_handle_next; + sample_rej_last_inst <= sample_rej_last_inst_next; + ts_latch <= ts_latch_next; + lifespan_time <= lifespan_time_next; + lifespan <= lifespan_next; + si_source_timestamp_sig <= si_source_timestamp_sig_next; + last_read_ts <= last_read_ts_next; + deadline_time <= deadline_time_next; + si_sample_state_sig <= si_sample_state_sig_next; + sample_state <= sample_state_next; + si_view_state_sig <= si_view_state_sig_next; + view_state <= view_state_next; + si_instance_state_sig <= si_instance_state_sig_next; + instance_state <= instance_state_next; + inst_data <= inst_data_next when WITH_KEY else inst_data_next2; + inst_latch_data <= inst_latch_data_next; + sample_rej_last_reason <= sample_rej_last_reason_next; + return_code_latch <= return_code_latch_next; + writer_pos <= writer_pos_next; + cnt <= cnt_next; + cnt2 <= cnt2_next; + cnt3 <= cnt3_next; + inst_cnt <= inst_cnt_next; + inst_cnt2 <= inst_cnt2_next; + stale_inst_cnt <= stale_inst_cnt_next; + is_lifespan_check <= is_lifespan_check_next; + remove_oldest_sample <= remove_oldest_inst_sample_next; + remove_oldest_inst_sample <= remove_oldest_inst_sample_next; + si_valid_data_sig <= si_valid_data_sig_next; + si_valid_sig <= si_valid_data_sig_next; + is_take <= is_take_next; + single_instance <= single_instance_next; + single_sample <= single_sample_next; + unmark_instances_flag <= unmark_instances_flag_next; + dynamic_next_instance <= dynamic_next_instance_next; + long_latch <= long_latch_next; + sample_status_info <= sample_status_info_next; + si_disposed_generation_count_sig <= si_disposed_generation_count_sig_next; + si_no_writers_generation_count_sig <= si_no_writers_generation_count_sig_next; + si_sample_rank_sig <= si_sample_rank_sig_next; + si_generation_rank_sig <= si_generation_rank_sig_next; + si_absolute_generation_count_sig <= si_absolute_generation_count_sig_next; + max_samples_latch <= max_samples_latch_next; + collection_cnt <= collection_cnt_next; + collection_cnt_max <= collection_cnt_max_next; + collection_generation_rank <= collection_generation_rank_next; + cur_generation_rank <= cur_generation_rank_next; + sample_rej_cnt <= sample_rej_cnt_next; + sample_rej_cnt_change <= sample_rej_cnt_change_next; + deadline_miss_cnt <= deadline_miss_cnt_next; + deadline_miss_cnt_change <= deadline_miss_cnt_change_next; + deadline_miss_last_inst <= deadline_miss_last_inst_next; + status_sig <= status_sig_next; + inst_long_latch <= inst_long_latch_next; + end if; + end if; + end process; end architecture; \ No newline at end of file diff --git a/src/rtps_config_package.vhd b/src/rtps_config_package.vhd index a7035a4..9cc831e 100644 --- a/src/rtps_config_package.vhd +++ b/src/rtps_config_package.vhd @@ -46,6 +46,7 @@ package rtps_config_package is type KEY_GENERATOR_OPCODE_TYPE is (NOP, WRITE_PAYLOAD, READ_KEY, READ_SIZE); type HISTORY_CACHE_RESPONSE_TYPE is (OK, REJECTED, INVALID, ERROR); type DDS_WRITER_OPCODE_TYPE is (NOP, REGISTER_INSTANCE, WRITE, DISPOSE, UNREGISTER_INSTANCE, LOOKUP_INSTANCE, WAIT_FOR_ACKNOWLEDGEMENTS, GET_OFFERED_DEADLINE_MISSED_STATUS, ASSERT_LIVELINESS, GET_LIVELINESS_LOST_STATUS); + type DDS_READER_OPCODE_TYPE is (NOP, READ, TAKE, READ_NEXT_SAMPLE, TAKE_NEXT_SAMPLE, READ_INSTANCE, TAKE_INSTANCE, READ_NEXT_INSTANCE, TAKE_NEXT_INSTANCE, GET_SAMPLE_REJECTED_STATUS, GET_REQUESTED_DEADLINE_MISSED_STATUS); -- Sample Status Info Flags constant SSI_DISPOSED_FLAG : natural := STATUS_INFO_DISPOSED_FLAG; @@ -120,13 +121,6 @@ package rtps_config_package is type RTPS_OUT_DATA_TYPE is array (0 to NUM_ENDPOINTS) of std_logic_vector(WORD_WIDTH-1 downto 0); - constant ENDPOINT_BITMAP_WIDTH : natural := 1; -- TODO - type ENDPOINT_BITMAP_ARRAY_TYPE is array (0 to round_div(ENDPOINT_BITMAP_WIDTH, WORD_WIDTH)-1) of std_logic_vector(0 to WORD_WIDTH-1); - constant ZERO_ENDPOINT_BITMAP_ARRAY : ENDPOINT_BITMAP_ARRAY_TYPE := (others => (others => '0')); - - function from_endpoint_bitmap_array (input : ENDPOINT_BITMAP_ARRAY_TYPE) return std_logic_vector; - function to_endpoint_bitmap_array (input : std_logic_vector(0 to ENDPOINT_BITMAP_WIDTH-1)) return ENDPOINT_BITMAP_ARRAY_TYPE; - -- Swap "data" to Big Endian representation. function endian_swap(swap : std_logic; data : std_logic_vector) return std_logic_vector; function endian_swap(swap : std_logic; data : unsigned) return unsigned; @@ -1195,24 +1189,6 @@ package body rtps_config_package is return ret; end function; - function from_endpoint_bitmap_array (input : ENDPOINT_BITMAP_ARRAY_TYPE) return std_logic_vector is - variable ret : std_logic_vector(0 to ENDPOINT_BITMAP_WIDTH-1) := (others => '0'); - begin - for i in 0 to input'length-1 loop - ret(i*WORD_WIDTH to ((i+1)*WORD_WIDTH)-1) := input(i); - end loop; - return ret; - end function; - - function to_endpoint_bitmap_array (input : std_logic_vector(0 to ENDPOINT_BITMAP_WIDTH-1)) return ENDPOINT_BITMAP_ARRAY_TYPE is - variable ret : ENDPOINT_BITMAP_ARRAY_TYPE := (others => (others => '0')); - begin - for i in 0 to ret'length-1 loop - ret(i) := input(i*WORD_WIDTH to ((i+1)*WORD_WIDTH)-1); - end loop; - return ret; - end function; - function check_mask(flags : std_logic_vector; mask : std_logic_vector) return boolean is begin assert (flags'length = mask'length) report "Flag and mask Signal have unequal length" severity FAILURE;