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;
        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_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 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);
        instance_handle_dds             : in INSTANCE_HANDLE_TYPE;
        max_samples_dds                 : in std_logic_vector(MAX_SAMPLES_WIDTH-1 downto 0);
        get_data_dds                    : in std_logic;
        done_dds                        : out std_logic;
        return_code_dds                 : out std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
        ready_out_dds                   : in std_logic;
        valid_out_dds                   : out std_logic;
        data_out_dds                    : out std_logic_vector(WORD_WIDTH-1 downto 0);
        last_word_out_dds               : out std_logic;
        -- Sample Info
        si_sample_state                 : out std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0);
        si_view_state                   : out std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0);
        si_instance_state               : out std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0);
        si_source_timestamp             : out TIME_TYPE;
        si_instance_handle              : out INSTANCE_HANDLE_TYPE;
        si_publication_handle           : out PUBLICATION_HANDLE_TYPE;
        si_disposed_generation_count    : out std_logic_vector(DISPOSED_GENERATION_COUNT_WIDTH-1 downto 0);
        si_no_writers_generation_count  : out std_logic_vector(NO_WRITERS_GENERATION_COUNT_WIDTH-1 downto 0);
        si_sample_rank                  : out std_logic_vector(SAMPLE_RANK_WIDTH-1 downto 0);
        si_generation_rank              : out std_logic_vector(GENERATION_RANK_WIDTH-1 downto 0);
        si_absolute_generation_rank     : out std_logic_vector(ABSOLUTE_GENERATION_COUNT_WIDTH-1 downto 0);
        si_valid_data                   : out std_logic;
        si_valid                        : out std_logic;
        eoc                             : out std_logic;
        -- 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 := 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 := 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 := 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
    constant INSTANCE_MEMORY_MAX_ADDRESS: unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := to_unsigned(INSTANCE_MEMORY_SIZE-1, INSTANCE_MEMORY_ADDR_WIDTH);
    -- Highest Instance Frame Address
    constant MAX_INSTANCE_ADDRESS       : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := INSTANCE_MEMORY_MAX_ADDRESS - INSTANCE_FRAME_SIZE + 1;
    -- Address pointing to the beginning of the first Instance Data Frame
    constant FIRST_INSTANCE_ADDRESS     : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
    
    -- *SAMPLE MEMORY FRAME FORMAT*
    -- 4-Byte Word Offsets to Beginning of Respective Fields in the Endpoint Memory Frame
    constant SMF_STATUS_INFO_OFFSET         : natural := 0;
    constant SMF_TIMESTAMP_OFFSET           : natural := 1;
    constant SMF_LIFESPAN_DEADLINE_OFFSET   : natural := 3;
    constant SMF_PAYLOAD_ADDR_OFFSET        : natural := 5;
    constant SMF_INSTANCE_ADDR_OFFSET       : natural := 6;
    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
    constant PMF_NEXT_ADDR_OFFSET   : natural := 0;
    constant PMF_PAYLOAD_OFFSET     : natural := 1;
    
    -- *INSTANCE MEMORY FRAME OFFSET*
    -- 4-Byte Word Offsets to Beginning of Respective Fields in the Endpoint Memory Frame
    constant IMF_NEXT_ADDR_OFFSET           : natural := 0;
    constant IMF_KEY_HASH_OFFSET            : natural := 1;
    constant IMF_STATUS_INFO_OFFSET         : natural := 5;
    constant IMF_SAMPLE_CNT_OFFSET          : natural := 6;
    constant IMF_DISPOSED_GEN_CNT_OFFSET    : natural := 7;
    constant IMF_NO_WRITERS_GEN_CNT_OFFSET  : natural := 8;
    constant IMF_IGNORE_DEADLINE_OFFSET     : natural := 9;
    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');
    
    --*****TYPE DECLARATION*****
    -- FSM states. Explained below in detail
    type STAGE_TYPE is (IDLE, RETURN_DDS, RETURN_RTPS, 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_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_INSTANCES, RESET_MEMORY);
    -- *Instance Memory Opcodes*
    -- OPCODE                   DESCRIPTION
    -- SEARCH_INSTANCE_HASH     Search Instance based on Key Hash pointed by key_hash.
    -- SEARCH_INSTANCE_ADDR     Search Instance based on Instance Pointer pointed by inst_addr_update. [This is needed to mark the previous Instance for Instance Removal]
    -- INSERT_INSTANCE          Insert Instance to memory. The Instance is inserted in Key Hash Numerical Order.
    -- UPDATE_INSTANCE          Update Instance Data pointed by inst_addr_base. (inst_mem_fields specifies which Fields to update)
    -- GET_FIRST_INSTANCE       Get Instance Data of first Instance (Instance with smallest Key Hash Numerical Order). (inst_mem_fields specifies which Fields to get)
    -- GET_NEXT_INSTANCE        Get Instance Data of next Instance (from the Instance pointed by inst_addr_base) (inst_mem_fields specifies which Fields to get)
    -- REMOVE_INSTANCE          Remove Instance pointed by inst_addr_base
    -- GET_INSTANCE             Get Data of Instance pointed by inst_addr_update. (inst_mem_fields specifies which Fields to get)
    -- UNMARK_INSTANCES         Reset the MARK_FLAG of all stored Instances
    type INSTANCE_OPCODE_TYPE is (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, WORD_WIDTH)-1) of std_logic_vector(0 to WORD_WIDTH-1);
    constant ZERO_WRITER_BITMAP_ARRAY : WRITER_BITMAP_ARRAY_TYPE := (others => (others => '0'));
    constant WRITER_BITMAP_WIDTH : natural := WRITER_BITMAP_ARRAY_TYPE'length*WORD_WIDTH;
    -- Record of Instance Data
    type INSTANCE_DATA_TYPE is record
        key_hash            : KEY_HASH_TYPE;
        status_info         : std_logic_vector(WORD_WIDTH-1 downto 0);
        sample_cnt          : unsigned(WORD_WIDTH-1 downto 0);
        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       : WRITER_BITMAP_ARRAY_TYPE;
    end record;
    -- Zero initialized Endpoint Data
    constant ZERO_INSTANCE_DATA : INSTANCE_DATA_TYPE := (
        key_hash            => (others => (others => '0')),
        status_info         => (others => '0'),
        sample_cnt          => (others => '0'),
        disposed_gen_cnt    => (others => '0'),
        no_writers_gen_cnt  => (others => '0'),
        ignore_deadline     => TIME_INVALID,
        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      : unsigned(CDR_LONG_WIDTH-1 downto 0);
        gen_cnt         : unsigned(CDR_LONG_WIDTH-1 downto 0);
        deadline        : TIME_TYPE;
        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;
    -- Zero initialized Instance Data Latch
    constant ZERO_INST_LATCH_DATA : INST_LATCH_DATA_TYPE := (
        key_hash        => (others => (others => '0')),
        status_info     => (others => '0'),
        sample_cnt      => (others => '0'),
        gen_cnt         => (others => '0'),
        deadline        => TIME_INVALID,
        writer_bitmap   => ZERO_WRITER_BITMAP_ARRAY,
        field_flags     => (others => '0'),
        addr            => (others => '0')
    );
    
    --*****SIGNAL DECLARATION
    -- *SAMPLE MEMORY CONNECTION SIGNALS*
    signal sample_addr : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
    signal sample_read : std_logic := '0';
    signal sample_read_data, sample_write_data : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0');
    signal sample_ready_in, sample_valid_in : std_logic := '0';
    signal sample_ready_out, sample_valid_out : std_logic := '0';
    signal sample_abort_read : std_logic := '0';
    
    -- *PAYLOAD MEMORY CONNECTION SIGNALS*
    signal payload_addr : unsigned(PAYLOAD_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
    signal payload_read : std_logic := '0';
    signal payload_read_data, payload_write_data : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0');
    signal payload_ready_in, payload_valid_in : std_logic := '0';
    signal payload_ready_out, payload_valid_out : std_logic := '0';
    signal payload_abort_read : std_logic := '0';
    
    -- *INSTANCE MEMORY CONNECTION SIGNALS*
    signal inst_addr : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
    signal inst_read : std_logic := '0';
    signal inst_read_data, inst_write_data : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0');
    signal inst_ready_in, inst_valid_in : std_logic := '0';
    signal inst_ready_out, inst_valid_out : std_logic := '0';
    signal inst_abort_read : std_logic := '0';
    
    -- *MAIN PROCESS*
    -- FSM state
    signal stage, stage_next : STAGE_TYPE := IDLE;
    -- General Purpose Counter
    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
    signal cnt3, cnt3_next : natural range 0 to PAYLOAD_FRAME_SIZE := 0;
    -- Head of Empty Sample List
    signal empty_sample_list_head, empty_sample_list_head_next : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
    -- Tail of Empty Sample List
    signal empty_sample_list_tail, empty_sample_list_tail_next : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
    -- Head of Empty Payload List
    signal empty_payload_list_head, empty_payload_list_head_next : unsigned(PAYLOAD_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
    -- Oldest Sample (Head of Occupied Sample List)
    signal oldest_sample, oldest_sample_next : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
    -- Newest Sample (Tail of Occupied Sample List)
    signal newest_sample, newest_sample_next : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
    -- Highest Timestamp of all READ Samples
    signal last_read_ts, last_read_ts_next : TIME_TYPE := TIME_INVALID;
    -- Denotes if the oldest Sample should be removed
    signal remove_oldest_sample, remove_oldest_sample_next : std_logic := '0';
    -- Denotes if the oldest sample of the Instance with 'key_hash' should be removed
    signal remove_oldest_inst_sample, remove_oldest_inst_sample_next : std_logic := '0';
    -- Remote Writer Endpoint Bitmap Position
    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 := HANDLE_NIL;
    -- RTPS Return Code Latch
    signal rtps_return_code_latch, rtps_return_code_latch_next : HISTORY_CACHE_RESPONSE_TYPE := ERROR;
    -- DDS Return Code Latch
    signal dds_return_code_latch, dds_return_code_latch_next : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0) := RETCODE_ERROR;
    -- Source Timestamp Latch
    signal ts_latch, ts_latch_next : TIME_TYPE := TIME_INVALID;
    -- Lifespan Latch
    signal lifespan, lifespan_next : TIME_TYPE := TIME_INVALID;
    -- Sample Status Info Latch
    signal sample_status_info, sample_status_info_next : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0');
    -- General Purpose Payload Pointer
    signal payload_addr_latch_1, payload_addr_latch_1_next : unsigned(PAYLOAD_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
    -- General Purpose Payload Pointer
    signal payload_addr_latch_2, payload_addr_latch_2_next : unsigned(PAYLOAD_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
    -- General Purpose Sample Pointer
    signal sample_addr_latch_1, sample_addr_latch_1_next : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
    -- General Purpose Sample Pointer
    signal sample_addr_latch_2, sample_addr_latch_2_next : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
    -- General Purpose Sample Pointer
    signal sample_addr_latch_3, sample_addr_latch_3_next : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
    -- General Purpose Sample Pointer
    signal sample_addr_latch_4, sample_addr_latch_4_next : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
    -- General Purpose Sample Pointer
    signal sample_addr_latch_5, sample_addr_latch_5_next : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
    -- General Purpose Instance Pointer
    signal inst_addr_latch_1, inst_addr_latch_1_next : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
    -- General Purpose Instance Pointer
    signal inst_addr_latch_2, inst_addr_latch_2_next : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
    -- General Purpose Long Latch
    signal long_latch, long_latch_next : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0');
    -- Signal used to pass Writer Bitmaps to Instance Memory Process
    signal writer_bitmap : 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
    signal gen_cnt  : unsigned(CDR_LONG_WIDTH-1 downto 0) := (others => '0');
    -- Signal used to pass TIMEs to the Instance Memory Process
    signal deadline : TIME_TYPE := TIME_INVALID;
    -- Signal containing the relevant Instance Memory Frame Fields of the Instance Memory Operation
    signal inst_mem_fields : std_logic_vector(0 to IMF_FLAG_WIDTH-1) := (others => '0');
    -- Signal used to pass Instance Pointers to the Instance Memory Process
    signal inst_addr_update : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
    -- Signal used to pass Sample Counts to the Instance Memory Process
    signal sample_cnt : unsigned(CDR_LONG_WIDTH-1 downto 0) := (others => '0');
    -- Signals start of Instance Memory Operation
    signal inst_op_start : std_logic := '0';
    -- Opcode of Instance Memory Operation (Valid only when inst_op_start is high)
    signal inst_opcode  : INSTANCE_OPCODE_TYPE := NOP;
    -- Signals the end of an Instance Memory Operation
    signal inst_op_done : std_logic := '0';
    -- Time of next Sample Lifespan Check
    signal lifespan_time, lifespan_time_next : TIME_TYPE := TIME_ZERO;
    -- Signifies if a Lifespan Check is in progress
    signal is_lifespan_check, is_lifespan_check_next : std_logic := '0';
    -- Sample State Latch
    signal sample_state, sample_state_next : std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0) := (others => '0');
    -- View State Latch
    signal view_state, view_state_next : std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0) := (others => '0');
    -- Instance State Latch
    signal instance_state, instance_state_next : std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0) := (others => '0');
    -- Instance Handle Latch
    signal instance_handle, instance_handle_next : INSTANCE_HANDLE_TYPE := HANDLE_NIL;
    -- Max Samples Latch
    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
    signal collection_cnt_max, collection_cnt_max_next : unsigned(MAX_SAMPLES_WIDTH-1 downto 0) := (others => '0');
    -- Denotes the Generation Rank (For a collection of length collection_cnt_max)
    signal collection_generation_rank, collection_generation_rank_next : unsigned(GENERATION_RANK_WIDTH-1 downto 0) := (others => '0');
    -- Number of NOT_ALIVE->ALIVE Transitions during reception of selected Sample
    signal cur_generation_rank, cur_generation_rank_next : unsigned(GENERATION_RANK_WIDTH-1 downto 0) := (others => '0');
    -- Denotes if a TAKE operation is in progress
    signal is_take, is_take_next : std_logic := '0';
    -- Denotes if the READ/TAKE operation applies to a single Instance
    signal single_instance, single_instance_next : std_logic := '0';
    -- NOTE: We use this signal to prevent the costly Instance Marking in the case that we only need to ouptput next sample.
    --       I.e. make READ_NEXT/TAKE_NEXT the fastest commands.
    -- Denotes if the READ/TAKE operation applies only to a single sample
    signal single_sample, single_sample_next : std_logic := '0';
    -- Denotes if the marks on Instances should be reset
    signal unmark_instances_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 to_integer(unsigned(MAX_INSTANCES))-1 := 0;
    -- Test signal used for testbench synchronisation
    signal idle_sig : std_logic := '0';
    
    -- *COMMUNICATION STATUS*
    signal status_sig, status_sig_next : std_logic_vector(STATUS_KIND_WIDTH-1 downto 0) := (others => '0');
    -- SAMPLE REJECT STATUS
    signal sample_rej_cnt, sample_rej_cnt_next : unsigned(SAMPLE_REJECTED_STATUS_COUNT_WIDTH-1 downto 0) := (others => '0');
    signal sample_rej_cnt_change, sample_rej_cnt_change_next : unsigned(SAMPLE_REJECTED_STATUS_COUNT_WIDTH-1 downto 0) := (others => '0');
    signal sample_rej_last_reason, sample_rej_last_reason_next : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := (others =>'0');
    signal sample_rej_last_inst, sample_rej_last_inst_next : INSTANCE_HANDLE_TYPE := (others => (others => '0'));
    -- REQUESTED DEADLINE MISSED STATUS
    -- Time of next Deadline Miss Check
    signal deadline_time, deadline_time_next : TIME_TYPE := TIME_ZERO;
    signal deadline_miss_cnt, deadline_miss_cnt_next : unsigned(REQUESTED_DEADLINE_MISSED_STATUS_COUNT_WIDTH-1 downto 0) := (others => '0');
    signal deadline_miss_cnt_change, deadline_miss_cnt_change_next : unsigned(REQUESTED_DEADLINE_MISSED_STATUS_COUNT_WIDTH-1 downto 0) := (others => '0');
    signal deadline_miss_last_inst, deadline_miss_last_inst_next : INSTANCE_HANDLE_TYPE := (others => (others => '0'));
    
    -- *SAMPLE INFO*
    signal si_sample_state_sig, si_sample_state_sig_next : std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0) := (others => '0');
    signal si_view_state_sig, si_view_state_sig_next : std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0) := (others => '0');
    signal si_instance_state_sig, si_instance_state_sig_next : std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0) := (others => '0');
    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 := 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 : 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_rank_sig, si_absolute_generation_rank_sig_next : unsigned(ABSOLUTE_GENERATION_COUNT_WIDTH-1 downto 0) := (others => '0');
    signal si_valid_data_sig, si_valid_data_sig_next : std_logic := '0';
    signal si_valid_sig, si_valid_sig_next : std_logic := '0';
    
    -- *INSTANCE MEMORY PROCESS*
    -- Instance Memory FSM state
    signal inst_stage, inst_stage_next  : INST_STAGE_TYPE := IDLE;
    -- Pointer to current relevant Instance Memory Frame Address
    signal inst_addr_base, inst_addr_base_next : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
    -- Pointer to next Instance Memory Frame Address
    signal inst_next_addr_base, inst_next_addr_base_next : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
    -- Pointer to previous Instacne Memory Address
    signal inst_prev_addr_base, inst_prev_addr_base_next : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
    -- Head of Empty Instance List
    signal inst_empty_head, inst_empty_head_next : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
    -- Head of Occupied Instance List
    signal inst_occupied_head, inst_occupied_head_next : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
    -- Latch for Instance Data from main process
    signal inst_latch_data, inst_latch_data_next : INST_LATCH_DATA_TYPE := ZERO_INST_LATCH_DATA;
    -- 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, inst_data_next2 : INSTANCE_DATA_TYPE := ZERO_INSTANCE_DATA;
    -- General Purpose Counter
    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 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');
    -- Instance Memory Flag Array denoting which inst_data Fields are up-to-date with the respective fields of the Instance (Pointed by inst_addr_base)
    signal current_imf, current_imf_next : std_logic_vector(0 to IMF_FLAG_WIDTH-1) := (others => '0');
    
    --*****ALIAS DECLARATION*****
    alias prev_sample           : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) is sample_addr_latch_1;
    alias prev_sample_next      : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) is sample_addr_latch_1_next;
    alias sel_sample            : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) is sample_addr_latch_1;
    alias sel_sample_next       : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) is sample_addr_latch_1_next;
    alias next_sample           : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) is sample_addr_latch_2;
    alias next_sample_next      : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) is sample_addr_latch_2_next;
    alias cur_sample            : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) is sample_addr_latch_3;
    alias cur_sample_next       : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) is sample_addr_latch_3_next;
    alias sample_p1             : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) is sample_addr_latch_4;
    alias sample_p1_next        : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) is sample_addr_latch_4_next;
    alias sample_p2             : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) is sample_addr_latch_5;
    alias sample_p2_next        : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) is sample_addr_latch_5_next;
    alias cur_payload           : unsigned(PAYLOAD_MEMORY_ADDR_WIDTH-1 downto 0) is payload_addr_latch_1;
    alias cur_payload_next      : unsigned(PAYLOAD_MEMORY_ADDR_WIDTH-1 downto 0) is payload_addr_latch_1_next;
    alias next_payload          : unsigned(PAYLOAD_MEMORY_ADDR_WIDTH-1 downto 0) is payload_addr_latch_2;
    alias next_payload_next     : unsigned(PAYLOAD_MEMORY_ADDR_WIDTH-1 downto 0) is payload_addr_latch_2_next;    
    alias cur_inst              : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) is inst_addr_latch_1;
    alias cur_inst_next         : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) is inst_addr_latch_1_next;
    alias next_inst             : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) is inst_addr_latch_2;
    alias next_inst_next        : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) is inst_addr_latch_2_next;
    alias first_payload         : unsigned(PAYLOAD_MEMORY_ADDR_WIDTH-1 downto 0) is payload_addr_latch_2;
    alias first_payload_next    : unsigned(PAYLOAD_MEMORY_ADDR_WIDTH-1 downto 0) is payload_addr_latch_2_next;
    alias has_data              : std_logic is sample_status_info(SSI_PAYLOAD_FLAG);
    alias has_key_hash          : std_logic is sample_status_info(SSI_KEY_HASH_FLAG);
    
    -- *FUNCTION DECLARATION*
    
    function from_writer_bitmap_array (input : WRITER_BITMAP_ARRAY_TYPE) return std_logic_vector is
        variable ret : std_logic_vector(0 to WRITER_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_writer_bitmap_array (input : std_logic_vector(0 to WRITER_BITMAP_WIDTH-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;
    
begin
    
    --*****COMPONENT INSTANTIATION*****
    
    sample_mem_ctrl_inst : entity work.mem_ctrl(arch)
        generic map (
            ADDR_WIDTH          => SAMPLE_MEMORY_ADDR_WIDTH,
            DATA_WIDTH          => WORD_WIDTH,
            MEMORY_DEPTH        => SAMPLE_MEMORY_SIZE,
            MAX_BURST_LENGTH    => SAMPLE_FRAME_SIZE
        )
        port map (
            clk         => clk,
            reset       => reset or sample_abort_read,
            addr        => std_logic_vector(sample_addr),
            read        => sample_read,
            ready_in    => sample_ready_in,
            valid_in    => sample_valid_in,
            data_in     => sample_write_data,
            ready_out   => sample_ready_out,
            valid_out   => sample_valid_out,
            data_out    => sample_read_data
        );
    
    payload_mem_ctrl_inst : entity work.mem_ctrl(arch)
        generic map (
            ADDR_WIDTH          => PAYLOAD_MEMORY_ADDR_WIDTH,
            DATA_WIDTH          => WORD_WIDTH,
            MEMORY_DEPTH        => PAYLOAD_MEMORY_SIZE,
            MAX_BURST_LENGTH    => PAYLOAD_FRAME_SIZE
        )
        port map (
            clk         => clk,
            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,
            data_in     => payload_write_data,
            ready_out   => payload_ready_out,
            valid_out   => payload_valid_out,
            data_out    => payload_read_data
        );
    
    gen_instance_mem_ctrl_inst : if WITH_KEY generate
        instance_mem_ctrl_inst : entity work.mem_ctrl(arch)
            generic map (
                ADDR_WIDTH          => INSTANCE_MEMORY_ADDR_WIDTH,
                DATA_WIDTH          => WORD_WIDTH,
                MEMORY_DEPTH        => INSTANCE_MEMORY_SIZE,
                MAX_BURST_LENGTH    => INSTANCE_FRAME_SIZE
            )
            port map (
                clk         => clk,
                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_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                  <= std_logic_vector(si_sample_rank_sig);
    si_generation_rank              <= std_logic_vector(si_generation_rank_sig);
    si_absolute_generation_rank     <= std_logic_vector(si_absolute_generation_rank_sig);
    si_valid_data                   <= si_valid_data_sig;
    si_valid                        <= si_valid_sig;
    status                          <= status_sig;
    
    -- *Main State Machine*
    -- STATE                                DESCRIPTION
    -- IDLE                                 Idle State. Initiates Deadline Miss Checks, Lifespan Expiry Checks, RTPS Operation handling, and DDS Operation handling, in that priority order.
    -- RETURN_DDS                           Return latched DDS Return Code
    -- RETURN_RTPS                          Return latched RTPS Return Code
    -- ADD_SAMPLE_INFO                      Latch and store Cache Change (pre-payload)
    -- ADD_PAYLOAD_ADDRESS                  Store payload pointer.
    -- ADD_PAYLOAD                          Push payload to memory and key hash generator (as needed)
    -- NEXT_PAYLOAD_SLOT                    Get pointer to next empty payload slot
    -- ALIGN_PAYLOAD                        Store the offset of the actual payload in the last address of the last payload slot.
    -- GET_KEY_HASH                         Fetch the calculated key hash from the Key Hash Generator
    -- INITIATE_INSTANCE_SEARCH             Initiate Instance Search Memory Operation. This state is used to start the Search operation as soon as the required data is available
    -- FILTER_STAGE                         This state decides if the RTPS Cache Change is accepted, dropped, or rejected. It also decides what sample (if any) has to be removed.
    -- UPDATE_INSTANCE                      Update the Data of the Instance of the received saample (Cache Change)
    -- FINALIZE_PAYLOAD                     Finalize the payload addition (Update pointers).
    -- PRE_SAMPLE_FINALIZE                  Store Sample Info based on Instance Data
    -- FIND_POS                             Find Sample List position based on DESTINATION_ORDER_QOS
    -- FIX_POINTERS                         Update the List Pointers of the inserted Sample neighbours (First Step of Sample Addition Finalization)
    -- FINALIZE_SAMPLE                      Update inserted sample and list pointers. (Second Step of Sample Addition Finalization)
    -- GET_OLDEST_SAMPLE_INSTANCE           Fetch the Instance Data of the oldest sample
    -- FIND_OLDEST_INST_SAMPLE              Find the oldest sample of a specific Instance
    -- REMOVE_SAMPLE                        Remove sample and linked payload
    -- POST_SAMPLE_REMOVE                   Update Instance Data of removed sample. If Instance Memory is full, and Instance is now eligible for removal, it is removed.
    -- SKIP_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
    -- PRE_CALCULATE                        Calculate ranks for the selected sample in the requested collection.
    -- FINALIZE_SAMPLE_INFO                 Finalize the Sample Info Data, and present them.
    -- GET_PAYLOAD                          Push linked Payload to output
    -- FIND_NEXT_INSTANCE                   Find next Instance that passes requested masks
    -- CHECK_INSTANCE                       Check if selected Instance passes requested masks
    -- CHECK_LIFESPAN                       Check and remove samples with expired Lifespans
    -- GET_SAMPLE_REJECTED_STATUS           Return Sample Rejected Status
    -- GET_REQUESTED_DEADLINE_MISSED_STATUS Return Requested Deadline Missed Status
    -- CHECK_DEADLINE                       Check and Mark Instances with missed Deadlines
    -- RESET_SAMPLE_MEMORY                  Reset Sample Memory to Empty State
    -- 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 WRITER_BITMAP_WIDTH-1) := (others => '0');
        variable tmp_update : std_logic_vector(0 to IMF_FLAG_WIDTH-1) := (others => '0');
        variable tmp_bool   : boolean := FALSE;    
    begin
        -- DEFAULT Registered
        stage_next                              <= stage;
        newest_sample_next                      <= newest_sample;
        empty_payload_list_head_next            <= empty_payload_list_head;
        empty_sample_list_head_next             <= empty_sample_list_head;
        empty_sample_list_tail_next             <= empty_sample_list_tail;
        payload_addr_latch_1_next               <= payload_addr_latch_1;
        payload_addr_latch_2_next               <= payload_addr_latch_2;
        ts_latch_next                           <= ts_latch;
        long_latch_next                         <= long_latch;
        sample_addr_latch_1_next                <= sample_addr_latch_1;
        sample_addr_latch_2_next                <= sample_addr_latch_2;
        sample_addr_latch_3_next                <= sample_addr_latch_3;
        sample_addr_latch_4_next                <= sample_addr_latch_4;
        sample_addr_latch_5_next                <= sample_addr_latch_5;
        writer_pos_next                         <= writer_pos;
        key_hash_next                           <= key_hash;
        sample_status_info_next                 <= sample_status_info;
        remove_oldest_sample_next               <= remove_oldest_sample;
        remove_oldest_inst_sample_next          <= remove_oldest_inst_sample;
        si_sample_state_sig_next                <= si_sample_state;
        si_view_state_sig_next                  <= si_view_state_sig;
        si_instance_state_sig_next              <= si_instance_state_sig;
        si_source_timestamp_sig_next            <= si_source_timestamp_sig;    
        si_instance_handle_sig_next             <= si_instance_handle_sig;
        si_publication_handle_sig_next          <= si_publication_handle_sig;
        si_disposed_generation_count_sig_next   <= si_disposed_generation_count_sig;
        si_no_writers_generation_count_sig_next <= si_no_writers_generation_count_sig;
        si_sample_rank_sig_next                 <= si_sample_rank_sig;
        si_generation_rank_sig_next             <= si_generation_rank_sig;
        si_absolute_generation_rank_sig_next    <= si_absolute_generation_rank_sig;
        si_valid_data_sig_next                  <= si_valid_data_sig;
        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_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;
        collection_cnt_max_next                 <= collection_cnt_max;
        collection_generation_rank_next         <= collection_generation_rank;
        cur_generation_rank_next                <= cur_generation_rank;
        is_take_next                            <= is_take;
        single_instance_next                    <= single_instance;
        single_sample_next                      <= single_sample;
        unmark_instances_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;
        sample_rej_cnt_change_next              <= sample_rej_cnt_change;
        sample_rej_last_reason_next             <= sample_rej_last_reason;
        sample_rej_last_inst_next               <= sample_rej_last_inst;
        deadline_time_next                      <= deadline_time;
        deadline_miss_cnt_next                  <= deadline_miss_cnt;
        deadline_miss_cnt_change_next           <= deadline_miss_cnt_change;
        deadline_miss_last_inst_next            <= deadline_miss_last_inst;
        lifespan_time_next                      <= lifespan_time;
        is_lifespan_check_next                  <= is_lifespan_check;
        status_sig_next                         <= status_sig;
        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;
        rtps_return_code_latch_next             <= rtps_return_code_latch;
        dds_return_code_latch_next              <= dds_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';
        inst_op_start                           <= '0';
        sample_read                             <= '0';
        sample_ready_out                        <= '0';
        sample_valid_in                         <= '0';
        sample_abort_read                       <= '0';
        payload_read                            <= '0';
        payload_ready_out                       <= '0';
        payload_valid_in                        <= '0';
        payload_abort_read                      <= '0';
        ready_in_rtps                           <= '0';
        start_kh                                <= '0';
        abort_kh                                <= '0';
        ready_in_kh                             <= '0';
        valid_out_kh                            <= '0';
        last_word_out_kh                        <= '0';
        valid_out_dds                           <= '0';
        last_word_out_dds                       <= '0';
        idle_sig                                <= '0';
        eoc                                     <= '0';
        data_out_dds                            <= (others => '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');
        payload_addr                            <= (others => '0');
        payload_write_data                      <= (others => '0');
        
        
        case (stage) is
            when IDLE =>
                idle_sig    <= '1';
                -- Reset
                remove_oldest_inst_sample_next  <= '0';
                remove_oldest_sample_next       <= '0';
                is_take_next                    <= '0';
                key_hash_next                   <= HANDLE_NIL;
                
                
                -- DEADLINE QoS
                if (DEADLINE_QOS /= DURATION_INFINITE and deadline_time <= time) then
                    -- Reset Timeout
                    deadline_time_next  <= deadline_time + DEADLINE_QOS;
                    
                    -- Synthesis Guard
                    if (WITH_KEY) then
                        stage_next          <= CHECK_DEADLINE;
                        cnt_next            <= 0;
                    else
                        if (inst_data.status_info(ISI_LIVELINESS_FLAG) = '1') then
                            -- Reset Liveliness Flag
                            inst_data_next2.status_info(ISI_LIVELINESS_FLAG) <= '0';
                        else
                            -- Update Requested Deadline Missed Status
                            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;
                    end if;
                -- LIFESPAN QoS
                elsif (lifespan_time <= time) then
                    -- Reset Timeout
                    lifespan_time_next  <= TIME_INFINITE;
                    
                    -- Samples Available
                    if (oldest_sample /= SAMPLE_MEMORY_MAX_ADDRESS) then
                        cur_sample_next     <= oldest_sample;
                        stage_next          <= CHECK_LIFESPAN;
                        cnt_next            <= 0;
                    end if;
                -- RTPS Operation
                elsif (start_rtps = '1') then
                    case (opcode_rtps) is
                        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;
                                    rtps_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';
                            
                            -- Synthesis Guard
                            if (WITH_KEY) then
                                -- Latch Writer Pos
                                writer_pos_next     <= to_integer(unsigned(data_in_rtps));
                                stage_next          <= REMOVE_WRITER;
                                cnt_next            <= 2;
                            else
                                -- Convert Writer Bitmap to SLV
                                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_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_next2.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG)   <= '1';
                                end if;
                                
                                stage_next                  <= RETURN_RTPS;
                                rtps_return_code_latch_next <= OK;
                            end if;
                        when others =>
                            null;
                    end case;
                -- Unmark Instances
                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_flag_next   <= '0';
                    end if;
                -- DDS Operation
                elsif (start_dds = '1') then
                    -- Latch Input Signals
                    sample_state_next       <= sample_state_dds;
                    view_state_next         <= view_state_dds;
                    instance_state_next     <= instance_state;
                    max_samples_latch_next        <= unsigned(max_samples_dds);
                    
                    -- Reset
                    sel_sample_next                 <= SAMPLE_MEMORY_MAX_ADDRESS;
                    sample_p1_next                  <= SAMPLE_MEMORY_MAX_ADDRESS;
                    sample_p2_next                  <= SAMPLE_MEMORY_MAX_ADDRESS;
                    single_sample_next              <= '0';
                    single_instance_next            <= '0' when WITH_KEY else '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');
                    si_source_timestamp_sig_next    <= TIME_ZERO;
                    si_instance_handle_sig_next     <= HANDLE_NIL;
                    si_publication_handle_sig_next  <= (others => (others => '0'));
                    si_sample_rank_sig_next         <= (others => '0');
                    si_generation_rank_sig_next     <= (others => '0');
                    si_valid_data_sig_next          <= '0';
                    si_valid_sig_next               <= '0';
                    si_absolute_generation_rank_sig_next    <= (others => '0');
                    si_disposed_generation_count_sig_next   <= (others => '0');
                    si_no_writers_generation_count_sig_next <= (others => '0');
                    
                    case (opcode_dds) is
                        when READ =>
                            ack_dds             <= '1';
                            cur_sample_next     <= oldest_sample;
                            cur_inst_next       <= INSTANCE_MEMORY_MAX_ADDRESS;
                            stage_next          <= GET_NEXT_SAMPLE;
                            cnt_next            <= 0;
                        when TAKE =>
                            is_take_next        <= '1';
                            ack_dds             <= '1';
                            cur_sample_next     <= oldest_sample;
                            cur_inst_next       <= INSTANCE_MEMORY_MAX_ADDRESS;
                            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_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_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
                                ack_dds                 <= '1';
                                single_instance_next    <= '1';
                                cur_sample_next         <= oldest_sample;
                                key_hash_next           <= instance_handle_dds;
                                stage_next              <= CHECK_INSTANCE;
                                cnt_next                <= 0;
                            else
                                ack_dds                     <= '1';
                                stage_next                  <= RETURN_DDS;
                                dds_return_code_latch_next  <= RETCODE_ILLEGAL_OPERATION;
                            end if;
                        when TAKE_INSTANCE =>
                            -- Synthesis Guard
                            if (WITH_KEY) then
                                ack_dds                 <= '1';
                                is_take_next            <= '1';
                                single_instance_next    <= '1';
                                cur_sample_next         <= oldest_sample;
                                key_hash_next           <= instance_handle_dds;
                                stage_next              <= CHECK_INSTANCE;
                                cnt_next                <= 0;
                            else
                                ack_dds                     <= '1';
                                stage_next                  <= RETURN_DDS;
                                dds_return_code_latch_next  <= RETCODE_ILLEGAL_OPERATION;
                            end if;
                        when READ_NEXT_INSTANCE =>
                            -- Synthesis Guard
                            if (WITH_KEY) then
                                ack_dds                     <= '1';
                                single_instance_next        <= '1';
                                dynamic_next_instance_next  <= '1';
                                cur_sample_next             <= oldest_sample;
                                key_hash_next               <= instance_handle_dds;
                                stage_next                  <= FIND_NEXT_INSTANCE;
                                cnt_next                    <= 0;
                            else
                                ack_dds                     <= '1';
                                stage_next                  <= RETURN_DDS;
                                dds_return_code_latch_next  <= RETCODE_ILLEGAL_OPERATION;
                            end if;
                        when TAKE_NEXT_INSTANCE =>
                            -- Synthesis Guard
                            if (WITH_KEY) then
                                ack_dds                     <= '1';
                                is_take_next                <= '1';
                                single_instance_next        <= '1';
                                dynamic_next_instance_next  <= '1';
                                cur_sample_next             <= oldest_sample;
                                key_hash_next               <= instance_handle_dds;
                                stage_next                  <= FIND_NEXT_INSTANCE;
                                cnt_next                    <= 0;
                            else
                                ack_dds                     <= '1';
                                stage_next                  <= RETURN_DDS;
                                dds_return_code_latch_next  <= RETCODE_ILLEGAL_OPERATION;
                            end if;
                        when GET_SAMPLE_REJECTED_STATUS =>
                            ack_dds     <= '1';
                            stage_next  <= GET_SAMPLE_REJECTED_STATUS;
                            cnt_next    <= 0;
                        when GET_REQUESTED_DEADLINE_MISSED_STATUS =>
                            ack_dds     <= '1';
                            stage_next  <= GET_REQUESTED_DEADLINE_MISSED_STATUS;
                            cnt_next    <= 0;
                        when others =>
                            ack_dds                     <= '1';
                            stage_next                  <= RETURN_DDS;
                            dds_return_code_latch_next  <= RETCODE_UNSUPPORTED;
                    end case;
                end if;
            when RETURN_DDS =>
                done_dds        <= '1';
                return_code_dds <= dds_return_code_latch;
                
                -- DONE
                stage_next  <= IDLE;
            when RETURN_RTPS =>
                done_rtps   <= '1';
                ret_rtps    <= rtps_return_code_latch;
                
                -- DONE
                stage_next  <= IDLE;
            when ADD_SAMPLE_INFO =>
                -- Precondition: cur_sample set
                
                case (cnt) is
                    -- SET Status Info
                    when 0 =>
                        -- Input Guard
                        if (valid_in_rtps = '1') then
                            -- 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;
                            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(SSI_ALIGNED_FLAG)   <= data_in_rtps(SSI_PAYLOAD_FLAG);
                            -- Memory Flow Control Guard
                            if (sample_ready_in = '1') then
                                ready_in_rtps   <= '1';
                                cnt_next        <= cnt + 1;
                            end if;
                        end if;
                    -- SET Timestamp 1/2
                    when 1 =>
                        -- Input Guard
                        if (valid_in_rtps = '1') then
                            sample_valid_in     <= '1';
                            sample_addr         <= cur_sample + SMF_TIMESTAMP_OFFSET;
                            sample_write_data   <= data_in_rtps;
                            -- Latch Timestamp
                            ts_latch_next(0)    <= unsigned(data_in_rtps);
                            -- Memory Flow Control Guard
                            if (sample_ready_in = '1') then
                                ready_in_rtps   <= '1';
                                cnt_next        <= cnt + 1;
                            end if;
                        end if;
                    -- SET Timestamp 2/2
                    when 2 =>
                        -- Input Guard
                        if (valid_in_rtps = '1') then
                            sample_valid_in     <= '1';
                            sample_addr         <= cur_sample + SMF_TIMESTAMP_OFFSET + 1;
                            sample_write_data   <= data_in_rtps;
                            -- Latch Timestamp
                            ts_latch_next(1)    <= unsigned(data_in_rtps);
                            -- Memory Flow Control Guard
                            if (sample_ready_in = '1') then
                                ready_in_rtps   <= '1';
                                cnt_next        <= cnt + 1;
                                -- Synthesis Guard
                                if (DESTINATION_ORDER_QOS = BY_SOURCE_TIMESTAMP_DESTINATION_ORDER_QOS) then
                                    -- Check Timestamp
                                    tmp_dw  := (0 => ts_latch(0), 1 => unsigned(data_in_rtps));
                                    
                                    -- NOTE: Equal timestamps are still acceptable, as they are inserted after the
                                    --       last read sample.
                                    
                                    -- Timestamp is smaller than highest last read (Or is Invalid)
                                    if (tmp_dw = TIME_INVALID or (tmp_dw /= TIME_INVALID and tmp_dw < last_read_ts)) then
                                        -- Drop Sample
                                        rtps_return_code_latch_next <= OK;
                                        stage_next                  <= SKIP_AND_RETURN;
                                        cnt_next                    <= 0;
                                    end if;
                                end if;
                            end if;
                        end if;
                    -- SET Lifespan Deadline 1/2
                    when 3 =>
                        -- Input Guard
                        if (valid_in_rtps = '1') then
                            sample_valid_in     <= '1';
                            sample_addr         <= cur_sample + SMF_LIFESPAN_DEADLINE_OFFSET;
                            sample_write_data   <= data_in_rtps;
                            -- Latch Lifespan
                            lifespan_next(0)    <= unsigned(data_in_rtps);
                            -- Memory Flow Control Guard
                            if (sample_ready_in = '1') then
                                ready_in_rtps   <= '1';
                                cnt_next        <= cnt + 1;
                            end if;
                        end if;
                    -- SET Lifespan Deadline 2/2
                    when 4 =>
                        -- Input Guard
                        if (valid_in_rtps = '1') then
                            sample_valid_in     <= '1';
                            sample_addr         <= cur_sample + SMF_LIFESPAN_DEADLINE_OFFSET + 1;
                            sample_write_data   <= data_in_rtps;
                            -- Latch Lifespan
                            lifespan_next(1)    <= unsigned(data_in_rtps);
                            -- Memory Flow Control Guard
                            if (sample_ready_in = '1') then
                                ready_in_rtps   <= '1';
                                -- Skip Key Hash, if not available
                                if (has_key_hash = '0') then
                                    cnt_next  <= 9;
                                else
                                    cnt_next    <= cnt + 1;
                                end if;
                            end if;
                        end if;
                    -- Key Hash 1/4
                    when 5 =>
                        -- Input Guard
                        if (valid_in_rtps = '1') then
                            ready_in_rtps   <= '1';
                            -- Latch Input, but do not pass to Memory
                            key_hash_next(0)    <= data_in_rtps;
                            cnt_next            <= cnt + 1;
                        end if;
                    -- Key Hash 2/4
                    when 6 =>
                        -- Input Guard
                        if (valid_in_rtps = '1') then
                            ready_in_rtps   <= '1';
                            -- Latch Input, but do not pass to Memory
                            key_hash_next(1)    <= data_in_rtps;
                            cnt_next            <= cnt + 1;
                        end if;
                    -- Key Hash 3/4
                    when 7 =>
                        -- Input Guard
                        if (valid_in_rtps = '1') then
                            ready_in_rtps   <= '1';
                            -- Latch Input, but do not pass to Memory
                            key_hash_next(2)    <= data_in_rtps;
                            cnt_next            <= cnt + 1;
                        end if;
                    -- Key Hash 4/4
                    when 8 =>
                        -- Input Guard
                        if (valid_in_rtps = '1') then
                            ready_in_rtps   <= '1';
                            -- Latch Input, but do not pass to Memory
                            key_hash_next(3)    <= data_in_rtps;
                            cnt_next            <= cnt + 1;
                        end if;
                    -- Writer Endpoint Position
                    when 9 =>
                        -- Input Guard
                        if (valid_in_rtps = '1') then
                            ready_in_rtps   <= '1';
                            -- Latch Input, but do not pass to Memory
                            writer_pos_next <= to_integer(unsigned(data_in_rtps));
                            cnt_next        <= cnt + 1;
                        end if;
                    -- SET 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;
            when ADD_PAYLOAD =>
                -- Precondition (if has_data = '1'): cur_payload set (Current Slot)
                
                -- NOTE: This state is responsible for reading the payload and writing it through to the local payload memory
                --       and key hash generator (KHG). This state is taken on following cases:
                -- has_data     has_key_hash
                --    1              1          The payload is written to memory [Entered from INITIATE_INSTANCE_SEARCH]
                --    1              0          The payload is written to memory and the KHG at the same time (KHG controls the flow) [Entered from ADD_PAYLOAD_ADDRESS]
                --    0              0          There is no payload to write, but the input contains the key for the KHG [Entered from ADD_PAYLOAD_ADDRESS]
                
                case (cnt) is
                    -- Push to memory
                    when 0 =>
                        -- Input Guard
                        if (valid_in_rtps = '1') then
                            payload_valid_in    <= '1';
                            payload_addr        <= cur_payload + cnt2;
                            payload_write_data  <= data_in_rtps;
                            -- Memory Control Flow Guard
                            if (payload_ready_in = '1') then
                                -- Key Hash needs to be calculated
                                if (WITH_KEY and has_key_hash = '0') then
                                    cnt_next    <= cnt + 1;
                                else
                                    ready_in_rtps   <= '1';
                                    -- End of Payload
                                    if (last_word_in_rtps = '1') then
                                        -- End of Payload Slot
                                        if (cnt2 = PAYLOAD_FRAME_SIZE-1) then
                                            stage_next  <= FILTER_STAGE;
                                        else
                                            stage_next  <= ALIGN_PAYLOAD;
                                            cnt_next    <= 0;
                                        end if;
                                    else
                                        -- End of Payload Slot
                                        if (cnt2 = PAYLOAD_FRAME_SIZE-1) then
                                            stage_next  <= NEXT_PAYLOAD_SLOT;
                                            cnt_next    <= 0;    
                                        else
                                            -- Next Word
                                            cnt2_next   <= cnt2 + 1;
                                        end if;
                                    end if;
                                end if;
                            end if;
                        end if;
                    -- Push to KHG
                    when 1 =>
                        -- Synthesis Guard
                        if (WITH_KEY) then
                            -- Input Guard
                            if (valid_in_rtps = '1') then
                                valid_out_kh    <= '1';
                                data_out_kh     <= data_in_rtps;
                                
                                -- Output Guard
                                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-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-1) then
                                                stage_next  <= NEXT_PAYLOAD_SLOT;
                                                cnt_next    <= 0;
                                            else
                                                -- Next Word
                                                cnt_next    <= 0;
                                                cnt2_next   <= cnt2 + 1;
                                            end if;
                                        end if;
                                    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
                                        end if;
                                    end if;
                                end if;
                            end if;
                        end if;
                    when others =>
                        null;
                end case;
            when NEXT_PAYLOAD_SLOT =>
                -- Precondition: cur_payload set
                
                case (cnt) is
                    -- GET Next Pointer
                    when 0 =>
                        payload_valid_in    <= '1';
                        payload_addr        <= cur_payload + PMF_NEXT_ADDR_OFFSET;
                        payload_read        <= '1';
                        
                        -- Memory Control Flow Guard
                        if (payload_ready_in = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                    -- READ Next Pointer
                    when 1 =>
                        payload_ready_out   <= '1';
                        
                        -- Memory Control Flow Guard
                        if (payload_valid_out = '1') then
                            -- No Empty Payload Slots available
                            if (resize(unsigned(payload_read_data),PAYLOAD_MEMORY_ADDR_WIDTH) = PAYLOAD_MEMORY_MAX_ADDRESS) then
                                -- Reject Change
                                rtps_return_code_latch_next  <= REJECTED;
                                stage_next              <= SKIP_AND_RETURN;
                                cnt_next                <= 0;
                                -- Abort Key Hash Generation
                                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    <= resize(unsigned(payload_read_data),PAYLOAD_MEMORY_ADDR_WIDTH);
                                stage_next          <= ADD_PAYLOAD;
                                cnt_next            <= 0;
                                cnt2_next           <= 1;
                            end if;
                        end if;
                    when others =>
                        null;
                end case;
            when ALIGN_PAYLOAD =>
                case (cnt) is
                    -- Mark Payload as unaligned
                    when 0 =>
                        sample_valid_in     <= '1';
                        sample_addr         <= cur_sample + SMF_STATUS_INFO_OFFSET;
                        sample_write_data   <= sample_status_info;
                        sample_write_data(SSI_ALIGNED_FLAG) <= '0';
                        
                        -- Memory Control Flow Guard
                        if (sample_ready_in = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                    -- Store Payload End Offset
                    when 1 =>
                        payload_valid_in    <= '1';
                        payload_addr        <= cur_payload + PAYLOAD_FRAME_SIZE-1;
                        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;
                        end if;
                    when others =>
                        null;
                end case;
            when GET_KEY_HASH =>
                -- Synthesis Guard
                if (WITH_KEY) then
                    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 (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
                if (WITH_KEY) then
                    -- Memory Operation Guard
                    if (inst_op_done = '1') then
                        inst_op_start       <= '1';
                        inst_opcode         <= SEARCH_INSTANCE_HASH;
                        inst_mem_fields     <= IMF_STATUS_FLAG or IMF_SAMPLE_CNT_FLAG or IMF_DISPOSED_CNT_FLAG or IMF_NO_WRITERS_CNT_FLAG or IMF_IGNORE_DEADLINE_FLAG or IMF_WRITER_BITMAP_FLAG;
                        
                        -- Payload not yet stored
                        if (has_data = '1' and WITH_KEY and has_key_hash = '1') then
                            stage_next  <= ADD_PAYLOAD;
                            cnt_next    <= 0;
                            cnt2_next   <= 1;
                        else
                            stage_next    <= FILTER_STAGE;
                        end if;
                    end if;
                end if;
            when FILTER_STAGE =>
                -- Precondition: cur_sample set, inst_data set (IMF_IGNORE_DEADLINE_FLAG, IMF_SAMPLE_CNT_FLAG)
                
                -- Wait for Instance Search to finish
                if (not WITH_KEY or inst_op_done = '1') then
                    
                    -- Instance Found
                    if (not WITH_KEY or inst_addr_base /= INSTANCE_MEMORY_MAX_ADDRESS) then
                        -- Latch Instance Pointer
                        cur_inst_next   <= inst_addr_base;
                            
                        -- TIME_BASED_FILTER QOS
                        if (TIME_BASED_FILTER_QOS /= DURATION_ZERO and time < inst_data.ignore_deadline) then
                            -- Drop Change
                            done_rtps   <= '1';
                            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 = 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 <= 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;
                                sample_rej_last_inst_next   <= key_hash;
                            else
                                -- Accept Change (Remove Oldest Instance Sample)
                                remove_oldest_inst_sample_next  <= '1';
                                done_rtps   <= '1';
                                ret_rtps    <= OK;
                                stage_next  <= UPDATE_INSTANCE;
                            end if;
                        -- RESOURCE_LIMITS_QOS (MAX_SAMPLES)
                        elsif (empty_sample_list_head = empty_sample_list_tail) 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 <= 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
                                -- Accept Change (Remove Oldest Sample)
                                remove_oldest_sample_next   <= '1';
                                done_rtps   <= '1';
                                ret_rtps    <= OK;
                                stage_next  <= UPDATE_INSTANCE;
                            end if;
                        else
                            -- Accept Change
                            done_rtps   <= '1';
                            ret_rtps    <= OK;
                            stage_next  <= UPDATE_INSTANCE;
                        end if;
                    else -- (only WITH_KEY)
                        -- Latch Instance Pointer
                        cur_inst_next   <= inst_empty_head;
                        
                        -- Only Insert Sample/Instance if Instance is ALIVE
                        if (sample_status_info(SSI_DISPOSED_FLAG) = '1' or sample_status_info(SSI_UNREGISTERED_FLAG) = '1' or sample_status_info(SSI_FILTERED_FLAG) = '1') then
                            -- NOTE: Ignore Sample if Sample unregisters/disposes an instance that we do not know
                            -- Drop Change
                            done_rtps   <= '1';
                            ret_rtps    <= OK;
                            -- DONE
                            stage_next  <= IDLE;
                        -- RESOURCE_LIMITS_QOS (MAX_SAMPLES)
                        elsif (empty_sample_list_head = empty_sample_list_tail) 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 <= 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
                                -- RESOURCE_LIMITS_QOS (MAX_INSTANCES) (Instance Memory Full)
                                if (inst_empty_head = INSTANCE_MEMORY_MAX_ADDRESS) then
                                    -- No Stale Instances available
                                    if (stale_inst_cnt = 0) then
                                        -- Reject Change
                                        done_rtps   <= '1';
                                        ret_rtps    <= REJECTED;
                                        -- DONE
                                        stage_next  <= IDLE;
                                        -- 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_INSTANCES_LIMIT;
                                        sample_rej_last_inst_next   <= key_hash;
                                    else
                                        -- Accept Change (Remove Oldest Sample)
                                        remove_oldest_sample_next   <= '1';
                                        done_rtps   <= '1';
                                        ret_rtps    <= OK;
                                        
                                        -- Remove Stale Instance and Insert Instance
                                        inst_op_start   <= '1';
                                        inst_opcode     <= GET_FIRST_INSTANCE;
                                        inst_mem_fields <= IMF_SAMPLE_CNT_FLAG or IMF_WRITER_BITMAP_FLAG;
                                        stage_next      <= REMOVE_STALE_INSTANCE;
                                        cnt_next        <= 0;
                                    end if;
                                else
                                    -- Accept Change (Remove Oldest Sample)
                                    remove_oldest_sample_next   <= '1';
                                    done_rtps   <= '1';
                                    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              := (others => '0');
                                    tmp_bitmap(writer_pos)  := '1';
                                    writer_bitmap           <= to_writer_bitmap_array(tmp_bitmap);
                                    
                                    if (has_data = '1') then
                                        stage_next  <= FINALIZE_PAYLOAD;
                                        cnt_next    <= 0;
                                    else
                                        stage_next  <= PRE_SAMPLE_FINALIZE;
                                        cnt_next    <= 0;
                                    end if;
                                end if;
                            end if;
                        else
                            -- RESOURCE_LIMITS_QOS (MAX_INSTANCES) (Instance Memory Full)
                            if (inst_empty_head = INSTANCE_MEMORY_MAX_ADDRESS) then
                                -- No Stale Instances available
                                if (stale_inst_cnt = 0) then
                                    -- Reject Change
                                    done_rtps   <= '1';
                                    ret_rtps    <= REJECTED;
                                    -- DONE
                                    stage_next  <= IDLE;
                                    -- 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_INSTANCES_LIMIT;
                                    sample_rej_last_inst_next               <= key_hash;
                                else
                                    done_rtps   <= '1';
                                    ret_rtps    <= OK;
                                    
                                    -- Remove Stale Instance and Insert Instance
                                    inst_op_start   <= '1';
                                    inst_opcode     <= GET_FIRST_INSTANCE;
                                    inst_mem_fields <= IMF_SAMPLE_CNT_FLAG or IMF_WRITER_BITMAP_FLAG;
                                    stage_next      <= REMOVE_STALE_INSTANCE;
                                    cnt_next        <= 0;
                                end if;
                            else
                                -- Accept Change
                                done_rtps   <= '1';
                                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              := (others => '0');
                                tmp_bitmap(writer_pos)  := '1';
                                writer_bitmap           <= to_writer_bitmap_array(tmp_bitmap);
                                
                                if (has_data = '1') then
                                    stage_next  <= FINALIZE_PAYLOAD;
                                    cnt_next    <= 0;
                                else
                                    stage_next  <= PRE_SAMPLE_FINALIZE;
                                    cnt_next    <= 0;
                                end if;
                            end if;
                        end if;
                    end if;
                end if;
            when UPDATE_INSTANCE =>
                -- Precondition inst_data set (IMF_STATUS_FLAG, IMF_WRITER_BITMAP_FLAG, IMF_DISPOSED_CNT_FLAG, IMF_NO_WRITERS_CNT_FLAG, IMF_SAMPLE_CNT_FLAG, IMF_IGNORE_DEADLINE_FLAG)
                
                -- Mark if Sample is stored in memory
                tmp_bool    := TRUE;
                
                -- Memory Operation Guard
                if (not WITH_KEY or inst_op_done = '1') then
                    -- DEFAULT STATUS INFO (LIVELINESS)
                    if (WITH_KEY) then
                        tmp_update  := IMF_STATUS_FLAG;
                        status_info_update  <= inst_data.status_info;
                        status_info_update(ISI_LIVELINESS_FLAG) <= '1';
                    else
                        inst_data_next2.status_info(ISI_LIVELINESS_FLAG) <= '1';
                    end if;
                    
                    -- *WRITER BITMAP*
                    -- Convert Writer Bitmap to SLV
                    tmp_bitmap  := from_writer_bitmap_array(inst_data.writer_bitmap);
                    -- ALIVE/FILTERED/DISPOSE Operation
                    if (sample_status_info(SSI_UNREGISTERED_FLAG) /= '1') then
                        -- Write if Writer New for Instance
                        if (tmp_bitmap(writer_pos) /= '1') then
                            -- Insert Writer
                            tmp_bitmap(writer_pos)  := '1';
                            -- Convert Back
                            -- Synthesis Guard
                            if (WITH_KEY) then
                                writer_bitmap   <= to_writer_bitmap_array(tmp_bitmap);
                                tmp_update      := tmp_update or IMF_WRITER_BITMAP_FLAG;
                            else
                                inst_data_next2.writer_bitmap    <= to_writer_bitmap_array(tmp_bitmap);
                            end if;
                        end if;
                    else
                        -- Write if Writer New for Instance
                        if (tmp_bitmap(writer_pos) /= '0') then
                            -- Insert Writer
                            tmp_bitmap(writer_pos)  := '0';
                            -- Convert Back
                            -- Synthesis Guard
                            if (WITH_KEY) then
                                writer_bitmap   <= to_writer_bitmap_array(tmp_bitmap);
                                tmp_update      := tmp_update or IMF_WRITER_BITMAP_FLAG;
                            else
                                inst_data_next2.writer_bitmap    <= to_writer_bitmap_array(tmp_bitmap);
                            end if;
                        end if;
                    end if;
                    
                    -- *GENERATION COUNTERS / VIEW STATE*
                    -- NOT_ALIVE_DISPOSED -> ALIVE Transition
                    if (sample_status_info(SSI_DISPOSED_FLAG) = '0' and sample_status_info(SSI_UNREGISTERED_FLAG) = '0' and inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '1') then
                        -- Synthesis Guard
                        if (WITH_KEY) then
                            tmp_update  := tmp_update or IMF_DISPOSED_CNT_FLAG;
                            gen_cnt     <= inst_data.disposed_gen_cnt + 1;
                            status_info_update(ISI_VIEW_FLAG)   <= '0';
                        else
                            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 OR NOT_ALIVE_NO_WRITERS -> NOT_ALIVE_DISPOSED Transition
                    elsif (sample_status_info(SSI_UNREGISTERED_FLAG) = '0' and inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '1') then
                        -- Synthesis Guard
                        if (WITH_KEY) then
                            tmp_update := tmp_update or IMF_NO_WRITERS_CNT_FLAG;
                            gen_cnt     <= inst_data.no_writers_gen_cnt + 1;
                            status_info_update(ISI_VIEW_FLAG)   <= '0';
                        else
                            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;
                    
                    -- *STATUS INFO*
                    -- * -> NOT_ALIVE_DISPOSED Transition
                    if (sample_status_info(SSI_DISPOSED_FLAG) = '1') then
                        -- NOT_ALIVE_DISPOSED -> NOT_ALIVE_DISPOSED
                        if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '1') then
                            tmp_bool    := FALSE;
                        else
                            -- Synthesis Guard
                            if (WITH_KEY) then
                                status_info_update(ISI_NOT_ALIVE_DISPOSED_FLAG)     <= '1';
                                status_info_update(ISI_NOT_ALIVE_NO_WRITERS_FLAG)   <= '0';
                            else
                                inst_data_next2.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG)    <= '1';
                                inst_data_next2.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG)  <= '0';
                            end if;
                        end if;
                    -- * -> NOT_ALIVE_NO_WRITERS Transition
                    elsif (sample_status_info(SSI_UNREGISTERED_FLAG) = '1' and tmp_bitmap = (tmp_bitmap'range => '0')) then
                        -- NOT_ALIVE -> NOT_ALIVE_NO_WRITERS
                        if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '1' or inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '1') then
                            tmp_bool    := FALSE;
                        else
                            -- Synthesis Guard
                            if (WITH_KEY) then
                                status_info_update(ISI_NOT_ALIVE_DISPOSED_FLAG)     <= '0';
                                status_info_update(ISI_NOT_ALIVE_NO_WRITERS_FLAG)   <= '1';
                            else
                                inst_data_next2.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG)    <= '0';
                                inst_data_next2.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG)  <= '1';
                            end if;
                        end if;
                    -- * -> ALIVE Transition
                    elsif (sample_status_info(SSI_UNREGISTERED_FLAG) = '0' and  sample_status_info(SSI_DISPOSED_FLAG) = '0') then
                        -- ALIVE -> ALIVE
                        if (inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) /= '1' and inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) /= '1') then
                            -- Filtered Sample
                            if (sample_status_info(SSI_FILTERED_FLAG) = '1') then
                                tmp_bool    := FALSE;
                            else
                                assert (has_data = '1') severity FAILURE;
                            end if;
                        else
                            -- Synthesis Guard
                            if (WITH_KEY) then
                                status_info_update(ISI_NOT_ALIVE_DISPOSED_FLAG)     <= '0';
                                status_info_update(ISI_NOT_ALIVE_NO_WRITERS_FLAG)   <= '0';
                            else
                                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;
                        end if;
                    else
                        tmp_bool    := FALSE;
                    end if;
                    
                    -- *INSTANCE SAMPLE COUNT*
                    if (tmp_bool) then
                        -- Synthesis Guard
                        if (WITH_KEY) then
                            tmp_update  := tmp_update or IMF_SAMPLE_CNT_FLAG;
                            sample_cnt  <= inst_data.sample_cnt + 1;
                        else
                            inst_data_next2.sample_cnt   <= inst_data.sample_cnt + 1;
                        end if;
                    end if;
                    
                    -- *IGNORE DEADLINE*
                    if (TIME_BASED_FILTER_QOS /= DURATION_ZERO) then
                        -- Synthesis Guard
                        if (WITH_KEY) then
                            tmp_update := tmp_update or IMF_IGNORE_DEADLINE_FLAG;
                            deadline    <= time + TIME_BASED_FILTER_QOS;
                        else
                            inst_data_next2.ignore_deadline  <= time + TIME_BASED_FILTER_QOS;
                        end if;
                    end if;
                    
                    -- *STALE INSTANCE COUNT*
                    if (tmp_bool) then
                        -- Synthesis Guard
                        if (WITH_KEY) then
                            -- Instance was Stale
                            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.
                                stale_inst_cnt_next <= stale_inst_cnt - 1;
                            end if;
                        end if;
                    else
                        -- Synthesis Guard
                        if (WITH_KEY) then
                            -- Stale Instance Transition
                            if (inst_data.sample_cnt = 0 and inst_data.writer_bitmap /= ZERO_WRITER_BITMAP_ARRAY and tmp_bitmap = (tmp_bitmap'range => '0')) then
                                stale_inst_cnt_next <= stale_inst_cnt + 1;
                            end if;
                        end if;
                    end if;
                    
                    -- Synthesis Guard
                    if (WITH_KEY) then
                        -- UPDATE Instance
                        inst_op_start   <= '1';
                        inst_opcode     <= UPDATE_INSTANCE;
                        inst_mem_fields <= tmp_update;
                    end if;
                    
                    if (not tmp_bool) then
                        -- DONE (Drop Sample)
                        stage_next  <= IDLE;
                    elsif (has_data = '1') then
                        stage_next          <= FINALIZE_PAYLOAD;
                        cnt_next            <= 0;
                    else
                        stage_next          <= PRE_SAMPLE_FINALIZE;
                        cnt_next            <= 0;
                    end if;
                end if;
            when FINALIZE_PAYLOAD =>
                -- Precondition: cur_payload set
                
                case (cnt) is 
                    -- GET Next Pointer
                    when 0 =>
                        payload_valid_in    <= '1';
                        payload_addr        <= cur_payload + PMF_NEXT_ADDR_OFFSET;
                        payload_read        <= '1';
                        
                        -- Memory Control Flow Guard
                        if (payload_ready_in = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                    -- Next Pointer
                    when 1 =>
                        payload_valid_in    <= '1';
                        payload_addr        <= cur_payload + PMF_NEXT_ADDR_OFFSET;
                        -- Make current Slot the Tail
                        payload_write_data  <= std_logic_vector(resize(PAYLOAD_MEMORY_MAX_ADDRESS,WORD_WIDTH));
                        
                        -- Memory Control Flow Guard
                        if (payload_ready_in = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                    -- READ Next Pointer
                    when 2 =>
                        payload_ready_out   <= '1';
                        
                        -- Memory Control Flow Guard
                        if (payload_valid_out = '1') then
                            -- Fix New Empty List Head
                            empty_payload_list_head_next    <= resize(unsigned(payload_read_data),PAYLOAD_MEMORY_ADDR_WIDTH);
                            
                            stage_next        <= PRE_SAMPLE_FINALIZE;
                            cnt_next          <= 0;
                        end if;
                    when others =>
                        null;
                end case;
            when PRE_SAMPLE_FINALIZE =>
                -- Precondition: cur_sample set, inst_data set (IMF_DISPOSED_CNT_FLAG, IMF_NO_WRITERS_CNT_FLAG)
                
                -- Wait for instance Update to Complete
                if (not WITH_KEY or inst_op_done = '1') then
                
                    case (cnt) is
                        -- SET Disposed Generation Counter
                        when 0 =>
                            sample_valid_in <= '1';
                            sample_addr     <= cur_sample + SMF_DISPOSED_GEN_CNT_OFFSET;
                            
                            sample_write_data <= std_logic_vector(inst_data.disposed_gen_cnt);
                            
                            -- Memory Flow Control Guard
                            if (sample_ready_in = '1') then
                                cnt_next    <= cnt + 1;
                            end if;
                        -- SET No Writer Generation Counter
                        when 1 =>
                            sample_valid_in <= '1';
                            sample_addr     <= cur_sample + SMF_NO_WRITERS_GEN_CNT_OFFSET;
                            
                            sample_write_data <= std_logic_vector(inst_data.no_writers_gen_cnt);
                            
                            -- Memory Flow Control Guard
                            if (sample_ready_in = '1') then
                                -- First Sample
                                if (newest_sample = SAMPLE_MEMORY_MAX_ADDRESS) then
                                    stage_next          <= FINALIZE_SAMPLE;
                                    cur_sample_next     <= empty_sample_list_head;
                                    next_sample_next    <= SAMPLE_MEMORY_MAX_ADDRESS;
                                    prev_sample_next    <= SAMPLE_MEMORY_MAX_ADDRESS;
                                    cnt_next            <= 0;
                                elsif (DESTINATION_ORDER_QOS = BY_RECEPTION_TIMESTAMP_DESTINATION_ORDER_QOS) then
                                    stage_next          <= FIX_POINTERS;
                                    next_sample_next    <= SAMPLE_MEMORY_MAX_ADDRESS;
                                    prev_sample_next    <= newest_sample;
                                    cur_sample_next     <= newest_sample;
                                    cnt_next            <= 0;
                                else
                                    stage_next          <= FIND_POS;
                                    next_sample_next    <= SAMPLE_MEMORY_MAX_ADDRESS;
                                    prev_sample_next    <= newest_sample;
                                    cur_sample_next     <= newest_sample;
                                    cnt_next            <= 0;
                                end if;
                            end if;
                        when others =>
                            null;
                    end case;
                end if;
            when FIND_POS =>
                -- Synthesis Guard
                if (DESTINATION_ORDER_QOS /= BY_RECEPTION_TIMESTAMP_DESTINATION_ORDER_QOS) then
                    -- Precondition: cur_sample set
                    
                    cnt_next  <= cnt + 1;
                    
                    case (cnt) is
                        -- GET Timestamp 1/2
                        when 0 =>
                            sample_valid_in <= '1';
                            sample_addr     <= cur_sample + SMF_TIMESTAMP_OFFSET;
                            sample_read     <= '1';
                            
                            -- Memory Flow Control Guard
                            if (sample_ready_in = '1') then
                                cnt_next    <= cnt + 1;
                            end if;
                        -- GET Timestamp 2/2
                        when 1 =>
                            sample_valid_in <= '1';
                            sample_addr     <= cur_sample + SMF_TIMESTAMP_OFFSET + 1;
                            sample_read     <= '1';
                            
                            -- Memory Flow Control Guard
                            if (sample_ready_in = '1') then
                                cnt_next    <= cnt + 1;
                            end if;
                        -- GET Previous Sample
                        when 2 =>
                            sample_valid_in <= '1';
                            sample_addr     <= cur_sample + SMF_PREV_ADDR_OFFSET;
                            sample_read     <= '1';
                            
                            -- Memory Flow Control Guard
                            if (sample_ready_in = '1') then
                                cnt_next    <= cnt + 1;
                            end if;
                        -- READ Timestamp 1/2
                        when 3 =>
                            sample_ready_out    <= '1';
                            
                            -- Memory Flow Control Guard
                            if (sample_valid_out = '1') then
                                long_latch_next <= sample_read_data;
                                cnt_next        <= cnt + 1;
                            end if;
                        -- READ Timestamp 2/2
                        when 4 =>
                            sample_ready_out    <= '1';
                            
                            -- Memory Flow Control Guard
                            if (sample_valid_out = '1') then
                                tmp_dw  := (0 => unsigned(long_latch), 1 => unsigned(sample_read_data));
                                
                                -- Found position (After current slot)
                                if (ts_latch >= tmp_dw) then
                                    prev_sample_next    <= cur_sample;
                                    stage_next          <= FIX_POINTERS;
                                    cnt_next            <= 0;
                                    sample_abort_read   <= '1';
                                end if;
                            end if;
                        -- READ Previous Sample
                        when 5 =>
                            sample_ready_out    <= '1';
                            
                            if (sample_valid_out = '1') then
                                -- No previous Slot (Oldest Sample)
                                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
                                    
                                    prev_sample_next    <= SAMPLE_MEMORY_MAX_ADDRESS;
                                    next_sample_next    <= cur_sample;
                                    stage_next          <= FIX_POINTERS;
                                    cnt_next            <= 1; -- Skip to Previous Pointer Fix
                                else
                                    -- Continue Search
                                    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 =>
                -- Precondition: prev_sample set, next_sample set
                
                case (cnt) is
                    -- Next Pointer (Previous Sample)
                    when 0 =>
                        -- Fix Next Pointer
                        sample_valid_in     <= '1';
                        sample_addr         <= prev_sample + SMF_NEXT_ADDR_OFFSET;
                        sample_write_data   <= std_logic_vector(resize(empty_sample_list_head,WORD_WIDTH));
                        
                        -- Memory Flow Control Guard
                        if (sample_ready_in = '1') then
                            -- No next Slot (Newest Sample)
                            if (next_sample = SAMPLE_MEMORY_MAX_ADDRESS) then
                                assert (prev_sample = newest_sample) report "Next Sample is MAX_ADDRESS, but sample is not NEWEST (TAIL)" severity FAILURE;
                                
                                stage_next          <= FINALIZE_SAMPLE;
                                cur_sample_next     <= empty_sample_list_head;
                                cnt_next            <= 0;
                            else
                                cnt_next    <= 1;
                            end if;
                        end if;
                    -- Previous Pointer (Next Sample)
                    when 1 =>
                        -- Fix Previous Pointer
                        sample_valid_in     <= '1';
                        sample_addr         <= next_sample + SMF_PREV_ADDR_OFFSET;
                        sample_write_data   <= std_logic_vector(resize(empty_sample_list_head,WORD_WIDTH));
                        
                        -- Memory Flow Control Guard
                        if (sample_ready_in = '1') then
                            stage_next          <= FINALIZE_SAMPLE;
                            cur_sample_next     <= empty_sample_list_head;
                            cnt_next            <= 0;
                        end if;
                    when others =>
                        null;
                end case;
            when FINALIZE_SAMPLE =>
                -- Precondition: prev_sample set, next_sample set, cur_sample
                
                case (cnt) is
                    -- GET Next (Empty) Sample
                    when 0 =>
                        sample_valid_in <= '1';
                        sample_addr     <= cur_sample + SMF_NEXT_ADDR_OFFSET;
                        sample_read     <= '1';
                        -- Memory Flow Control Guard
                        if (sample_ready_in = '1') then
                            -- Synthesis Guard
                            if (WITH_KEY) then
                                cnt_next    <= cnt + 1;
                            else
                                cnt_next    <= cnt + 2;
                            end if;
                        end if;
                    -- SET Instance Pointer
                    when 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;
                    -- SET Previous Pointer
                    when 2 =>
                        -- Write Previous Pointer
                        sample_valid_in     <= '1';
                        sample_addr         <= cur_sample + SMF_PREV_ADDR_OFFSET;
                        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;
                    -- SET Next Pointer
                    when 3 =>
                        -- Write Next Pointer
                        sample_valid_in     <= '1';
                        sample_addr         <= cur_sample + SMF_NEXT_ADDR_OFFSET;
                        sample_write_data   <= std_logic_vector(resize(next_sample,WORD_WIDTH));
                        
                        -- Memory Flow Control Guard
                        if (sample_ready_in = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                        
                    -- READ Next (Empty) Sample
                    when 4 =>
                        sample_ready_out    <= '1';
                        
                        -- Memory Flow Control Guard
                        if (sample_valid_out = '1') then
                            
                            -- Fix new Empty List Head
                            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
                                newest_sample_next  <= cur_sample;
                                if (oldest_sample = SAMPLE_MEMORY_MAX_ADDRESS) then
                                    oldest_sample_next  <= cur_sample;
                                end if;
                            end if;
                            
                            -- Signal Data Available
                            status_sig_next <= status_sig and DATA_AVAILABLE_STATUS;
                            
                            -- Update Lifespan Check Time
                            if (lifespan /= TIME_INVALID and lifespan < lifespan_time) then
                                lifespan_next   <= lifespan;
                            end if;
                            
                            if (WITH_KEY and remove_oldest_inst_sample = '1') then
                                assert (oldest_sample /= SAMPLE_MEMORY_MAX_ADDRESS) severity FAILURE;
                                
                                cur_sample_next <= oldest_sample;
                                stage_next      <= FIND_OLDEST_INST_SAMPLE;
                                cnt_next        <= 0;
                            elsif (remove_oldest_sample = '1') then
                                assert (oldest_sample /= SAMPLE_MEMORY_MAX_ADDRESS) severity FAILURE;
                                
                                -- 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
                if (WITH_KEY) then
                    case (cnt) is
                        -- GET Instance Pointer (Oldest Sample)
                        when 0 =>
                            sample_valid_in <= '1';
                            sample_addr     <= oldest_sample + SMF_INSTANCE_ADDR_OFFSET;
                            sample_read     <= '1';
                            
                            -- Memory Flow Control Guard
                            if (sample_ready_in = '1') then
                                cnt_next    <= cnt + 1;
                            end if;
                        -- READ Instance Pointer (Oldest Sample)
                        when 1 =>
                            -- Memory Operation Guard
                            if (inst_op_done = '1') then
                                sample_ready_out    <= '1';
                                
                                -- Memory Flow Control Guard
                                if (sample_valid_out = '1') then
                                    cur_inst_next   <= resize(unsigned(sample_read_data),INSTANCE_MEMORY_ADDR_WIDTH);
                                    cur_sample_next <= oldest_sample;
                                    stage_next      <= REMOVE_SAMPLE;
                                    cnt_next        <= 0;
                                end if;
                            end if;
                        when others =>
                            null;
                    end case;
                end if;
            when FIND_OLDEST_INST_SAMPLE =>
                -- Precondition: cur_sample set
                
                -- Synthesis Guard
                if (WITH_KEY) then
                    case (cnt) is
                        -- GET Instance Pointer
                        when 0 =>
                            sample_valid_in <= '1';
                            sample_addr     <= cur_sample + SMF_INSTANCE_ADDR_OFFSET;
                            sample_read     <= '1';
                            
                            -- Memory Flow Control Guard
                            if (sample_ready_in = '1') then
                                cnt_next    <= cnt + 1;
                            end if;
                        -- GET Next Sample
                        when 1 =>
                            sample_valid_in <= '1';
                            sample_addr     <= cur_sample + SMF_NEXT_ADDR_OFFSET;
                            sample_read     <= '1';
                            
                            -- Memory Flow Control Guard
                            if (sample_ready_in = '1') then
                                cnt_next    <= cnt + 1;
                            end if;
                        -- READ Instance Pointer
                        when 2 =>
                            sample_ready_out    <= '1';
                            
                            -- Memory Flow Control Guard
                            if (sample_valid_out = '1') then
                                -- Oldest Instance Sample Found
                                if (resize(unsigned(sample_read_data),INSTANCE_MEMORY_ADDR_WIDTH) = cur_inst) then
                                    sample_abort_read   <= '1';
                                    stage_next          <= REMOVE_SAMPLE;
                                    cnt_next            <= 0;
                                else
                                    cnt_next    <= cnt + 1;
                                end if;
                            end if;
                        -- READ Next Sample
                        when 3 =>
                            sample_ready_out    <= '1';
                            
                            -- Memory Flow Control Guard
                            if (sample_valid_out = '1') then
                                cur_sample_next     <= resize(unsigned(sample_read_data),SAMPLE_MEMORY_ADDR_WIDTH);
                                cnt_next            <= 0;
                            end if;
                        when others =>
                            null;
                    end case;
                end if;
            when REMOVE_SAMPLE =>
                -- Precondition: cur_sample set, cur_inst set
                    
                case (cnt) is
                    -- GET Instance Data
                    when 0 => 
                        if (not WITH_KEY or (cur_inst = inst_addr_base and check_mask(current_imf, IMF_SAMPLE_CNT_FLAG or IMF_WRITER_BITMAP_FLAG))) then
                            cnt_next    <= cnt + 1;
                        else
                            -- Memory Operation Guard
                            if (inst_op_done = '1') then
                                inst_op_start       <= '1';
                                inst_opcode         <= GET_INSTANCE;
                                inst_mem_fields     <= IMF_SAMPLE_CNT_FLAG or IMF_WRITER_BITMAP_FLAG;
                                inst_addr_update    <= cur_inst;
                                cnt_next            <= cnt + 1;
                            end if;
                        end if;
                    -- GET Previous Sample
                    when 1 =>
                        sample_valid_in <= '1';
                        sample_addr     <= cur_sample + SMF_PREV_ADDR_OFFSET;
                        sample_read     <= '1';
                        
                        -- Memory Flow Control Guard
                        if (sample_ready_in = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                    -- GET Next Sample
                    when 2 =>
                        sample_valid_in <= '1';
                        sample_addr     <= cur_sample + SMF_NEXT_ADDR_OFFSET;
                        sample_read     <= '1';
                        
                        -- Memory Flow Control Guard
                        if (sample_ready_in = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                    -- GET Payload Pointer
                    when 3 =>
                        sample_valid_in <= '1';
                        sample_addr     <= cur_sample + SMF_PAYLOAD_ADDR_OFFSET;
                        sample_read     <= '1';
                        
                        -- Memory Flow Control Guard
                        if (sample_ready_in = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                    -- READ Previous Sample
                    when 4 =>
                        sample_ready_out    <= '1';
                        -- Memory Flow Control Guard
                        if (sample_valid_out = '1') then
                            prev_sample_next    <= resize(unsigned(sample_read_data),SAMPLE_MEMORY_ADDR_WIDTH);
                            cnt_next            <= cnt + 1;
                        end if;
                    -- READ Next Sample
                    when 5 =>
                        sample_ready_out    <= '1';
                        -- Memory Flow Control Guard
                        if (sample_valid_out = '1') then
                            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
                                empty_sample_list_head_next <= cur_sample;
                                empty_sample_list_tail_next <= cur_sample;
                                cnt_next    <= cnt + 2; --Skip Next Step
                            else
                                cnt_next    <= cnt + 1;
                            end if;
                        end if;
                    -- SET Next Pointer (Empty List Tail)
                    when 6 =>
                        -- Add Current Sample after Empty List Tail
                        sample_valid_in     <= '1';
                        sample_addr         <= empty_sample_list_tail + SMF_NEXT_ADDR_OFFSET;
                        sample_write_data   <= std_logic_vector(resize(cur_sample,WORD_WIDTH));
                        
                        -- Memory Flow Control Guard
                        if (sample_ready_in = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                    -- SET Next Pointer (Current Sample)
                    when 7 =>
                        -- Make Current Sample Empty List Tail
                        sample_valid_in     <= '1';
                        sample_addr         <= cur_sample + SMF_NEXT_ADDR_OFFSET;
                        sample_write_data   <= std_logic_vector(resize(SAMPLE_MEMORY_MAX_ADDRESS,WORD_WIDTH));
                        
                        -- Memory Flow Control Guard
                        if (sample_ready_in = '1') then
                            -- Fix Empty List Pointers
                            empty_sample_list_tail_next <= cur_sample;
                            
                            -- Current Sample is Newest (Occupied List Tail)
                            if (next_sample = SAMPLE_MEMORY_MAX_ADDRESS) then
                                assert (cur_sample = newest_sample) report "Next Sample is MAX_ADDR, but cur_sample /= newest_sample" severity FAILURE;
                                
                                -- Fix Newest Pointer
                                newest_sample_next  <= prev_sample;
                                
                                -- Current Sample is Oldest (List Head)
                                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;
                                    
                                    cnt_next    <= cnt + 3; -- Skip next 2 steps
                                else
                                    cnt_next    <= cnt + 2; -- Skip next step
                                end if;
                            else
                                cnt_next    <= cnt + 1;
                            end if;
                        end if;
                    -- SET Previous Address (Next Sample)
                    when 8 =>
                        -- Remove link to cur_sample
                        sample_valid_in     <= '1';
                        sample_addr         <= next_sample + SMF_PREV_ADDR_OFFSET;
                        sample_write_data   <= std_logic_vector(resize(prev_sample,WORD_WIDTH));
                        
                        -- Memory Flow Control Guard
                        if (sample_ready_in = '1') then
                            -- Current Sample is oldest sample (List Head)
                            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;
                                
                                -- Fix Oldest Pointer
                                oldest_sample_next  <= next_sample;
                                
                                cnt_next    <= cnt + 2; -- Skip next step
                            else
                                cnt_next    <= cnt + 1;
                            end if;
                        end if;
                    -- SET Next Address (Previous Sample)
                    when 9 =>
                        -- Remove link to cur_sample
                        sample_valid_in     <= '1';
                        sample_addr         <= prev_sample + SMF_NEXT_ADDR_OFFSET;
                        sample_write_data   <= std_logic_vector(resize(next_sample,WORD_WIDTH));
                        
                        -- Memory Flow Control Guard
                        if (sample_ready_in = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                    -- READ Payload Pointer
                    when 10 =>
                        sample_ready_out    <= '1';
                        
                        -- Memory Flow Control Guard
                        if (sample_valid_out = '1') then
                            cur_payload_next    <= resize(unsigned(sample_read_data),PAYLOAD_MEMORY_ADDR_WIDTH);
                            -- Sample has no Data
                            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
                                -- Fix Empty List Head
                                empty_payload_list_head_next    <= resize(unsigned(sample_read_data),PAYLOAD_MEMORY_ADDR_WIDTH);
                                
                                stage_next  <= POST_SAMPLE_REMOVE;
                            else
                                -- Latch First Payload Slot for later use
                                first_payload_next  <= resize(unsigned(sample_read_data),PAYLOAD_MEMORY_ADDR_WIDTH);
                                cnt_next    <= cnt + 1;
                            end if;
                        end if;
                    -- GET Next Payload
                    when 11 =>
                        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;
                    -- READ Next Payload
                    when 12 =>
                        payload_ready_out   <= '1';
                        
                        -- Memory Flow Control Guard
                        if (payload_valid_out = '1') then
                            -- Found Empty List Tail
                            if (resize(unsigned(payload_read_data),PAYLOAD_MEMORY_ADDR_WIDTH) = PAYLOAD_MEMORY_MAX_ADDRESS) then
                                cnt_next    <= cnt + 1;
                            else
                                cur_payload_next    <= resize(unsigned(payload_read_data),PAYLOAD_MEMORY_ADDR_WIDTH);
                                cnt_next            <= cnt - 1;
                            end if;
                        end if;
                    -- SET Next Payload Pointer (Last Payload of Current Sample)
                    when 13 =>
                        payload_valid_in    <= '1';
                        payload_addr        <= cur_payload + PMF_NEXT_ADDR_OFFSET;
                        payload_write_data  <= std_logic_vector(resize(empty_payload_list_head,WORD_WIDTH));
                        
                        -- Fix Empty List Head
                        empty_payload_list_head_next    <= first_payload;
                        
                        -- Memory Flow Control Guard
                        if (payload_ready_in = '1') then
                            stage_next  <= POST_SAMPLE_REMOVE;
                        end if;
                    when others =>
                        null;
                end case;
            when POST_SAMPLE_REMOVE =>
                -- Precondition: inst_data set (IMF_SAMPLE_CNT_FLAG, IMF_WRITER_BITMAP_FLAG)
                
                -- Memory Operation Guard
                if (not WITH_KEY or inst_op_done = '1') then
                    -- Synthesis Guard
                    if (WITH_KEY) then
                        -- Stale Instance Update
                        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;
                        
                        inst_op_start   <= '1';
                        inst_opcode     <= UPDATE_INSTANCE;
                        inst_mem_fields <= IMF_SAMPLE_CNT_FLAG;
                        sample_cnt      <= inst_data.sample_cnt - 1;
                    else
                        inst_data_next2.sample_cnt   <= inst_data.sample_cnt - 1;
                    end if;
                    
                    if (is_take = '1') then
                        -- cur_inst has no more samples in collection
                        if (si_sample_rank_sig = 0) then
                            -- Skipped Sample available
                            if (sample_p2 /= SAMPLE_MEMORY_MAX_ADDRESS) then
                                cur_sample_next <= sample_p2;
                            else
                                cur_sample_next <= sample_p1;
                            end if;
                            cur_inst_next   <= INSTANCE_MEMORY_MAX_ADDRESS;
                            sample_p2_next  <= SAMPLE_MEMORY_MAX_ADDRESS;
                        else
                            cur_sample_next <= sample_p1;
                        end if;
                        sample_p1_next  <= SAMPLE_MEMORY_MAX_ADDRESS;
                        sel_sample_next <= SAMPLE_MEMORY_MAX_ADDRESS;
                        -- Continue Processing
                        stage_next  <= GET_NEXT_SAMPLE;
                        cnt_next    <= 0;
                    elsif (is_lifespan_check = '1') then
                        -- Reached End of Samples
                        if (next_sample = SAMPLE_MEMORY_MAX_ADDRESS) then
                            -- DONE
                            stage_next  <= IDLE;
                        else
                            -- Continue Search
                            cur_sample_next     <= next_sample;
                            stage_next          <= CHECK_LIFESPAN;
                            cnt_next            <= 0;
                        end if;
                    else
                        -- DONE
                        stage_next  <= IDLE;
                    end if;
                end if;
            when SKIP_AND_RETURN =>
                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    <= cnt + 1;
                        end if;
                    -- Return Code
                    when 1 =>
                        done_rtps   <= '1';
                        ret_rtps    <= rtps_return_code_latch;
                        
                        -- DONE
                        stage_next      <= IDLE;
                    when others =>
                        null;
                end case;
            when REMOVE_WRITER =>
                -- Synthesis Guard
                if (WITH_KEY) then
                    -- Memory Operation Guard
                    if (inst_op_done = '1') then
                        case (cnt) is
                            when 0 =>
                                -- No More Instances
                                if (inst_addr_base = INSTANCE_MEMORY_MAX_ADDRESS) then
                                    -- DONE
                                    done_rtps   <= '1';
                                    ret_rtps    <= OK;
                                    stage_next  <= IDLE;
                                else
                                    -- Convert Writer Bitmap to SLV
                                    tmp_bitmap  := from_writer_bitmap_array(inst_data.writer_bitmap);
                                    
                                    -- Remove Writer
                                    tmp_bitmap(writer_pos) := '0';
                                    
                                    -- NOTE: writer_bitmap is not latched, since the memory process is latching it at the
                                    --       same clock cycle.
                                    -- Convert Back
                                    writer_bitmap   <= 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
                                        status_info_update                                  <= inst_data.status_info;
                                        status_info_update(ISI_NOT_ALIVE_NO_WRITERS_FLAG)   <= '1';
                                        inst_op_start   <= '1';
                                        inst_opcode     <= UPDATE_INSTANCE;
                                        inst_mem_fields <= IMF_STATUS_FLAG or IMF_WRITER_BITMAP_FLAG;
                                    else
                                        inst_op_start   <= '1';
                                        inst_opcode     <= UPDATE_INSTANCE;
                                        inst_mem_fields <= IMF_WRITER_BITMAP_FLAG;
                                    end if;
                                    
                                    -- Update Stale Instance Count
                                    if (tmp_bitmap = (tmp_bitmap'range => '0') and inst_data.sample_cnt = 0) then
                                        stale_inst_cnt_next <= stale_inst_cnt + 1;
                                    end if;
                                    
                                    -- Continue
                                    cnt_next    <= 1;
                                end if;
                            when 1 =>
                                inst_op_start   <= '1';
                                inst_opcode     <= GET_NEXT_INSTANCE;
                                inst_mem_fields <= IMF_STATUS_FLAG or IMF_SAMPLE_CNT_FLAG or IMF_WRITER_BITMAP_FLAG;
                                stage_next      <= REMOVE_WRITER;
                                cnt_next        <= 0;
                            when 2 =>
                                inst_op_start   <= '1';
                                inst_opcode     <= GET_FIRST_INSTANCE;
                                inst_mem_fields <= IMF_STATUS_FLAG or IMF_SAMPLE_CNT_FLAG or IMF_WRITER_BITMAP_FLAG;
                                stage_next      <= REMOVE_WRITER;
                                cnt_next        <= 0;
                            when others =>
                                null;
                        end case;
                    end if;
                end if;
            when REMOVE_STALE_INSTANCE =>
                -- Precondition: inst_data set (IMF_SAMPLE_CNT_FLAG, IMF_WRITER_BITMAP_FLAG)
                
                -- Synthesis Guard
                if (WITH_KEY) then
                    -- Wait for Instance Data
                    if (inst_op_done = '1') then
                        case (cnt) is
                            -- Find and Remove First Stale Instance
                            when 0 =>
                                -- Iterated through all Instances
                                if (inst_addr_base = INSTANCE_MEMORY_MAX_ADDRESS) then
                                    -- NOTE: We should enter this state only if there is at least one stale Instance to be removed, so we should never enter this branch.
                                    assert FALSE severity FAILURE;
                                    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_WRITER_BITMAP_ARRAY) then
                                        -- Remove Stale Instance
                                        inst_op_start   <= '1';
                                        inst_opcode     <= REMOVE_INSTANCE;
                                        -- Update Stale Instance Count
                                        stale_inst_cnt_next <= stale_inst_cnt - 1;
                                        
                                        cnt_next    <= cnt + 1;
                                        
                                    else
                                        -- Continue Search
                                        inst_op_start   <= '1';
                                        inst_opcode     <= GET_NEXT_INSTANCE;
                                        inst_mem_fields <= IMF_SAMPLE_CNT_FLAG or IMF_WRITER_BITMAP_FLAG;
                                    end if;
                                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              := (others => '0');
                                tmp_bitmap(writer_pos)  := '1';
                                writer_bitmap           <= to_writer_bitmap_array(tmp_bitmap);
                                
                                -- Latch Instance Pointer
                                cur_inst_next   <= inst_empty_head;
                                
                                if (has_data = '1') then
                                    stage_next          <= FINALIZE_PAYLOAD;
                                    cnt_next            <= 0;
                                else
                                    stage_next          <= PRE_SAMPLE_FINALIZE;
                                    cnt_next            <= 0;
                                end if;
                            when others =>
                                null;
                        end case;
                    end if;
                end if;
            when GET_NEXT_SAMPLE =>
                -- Precondition: cur_sample set, cur_inst set, si_sample_rank_sig set
                
                case (cnt) is
                    -- GET Next Sample
                    when 0 =>
                        sample_valid_in <= '1';
                        sample_addr     <= cur_sample + SMF_NEXT_ADDR_OFFSET;
                        sample_read     <= '1';
                        
                        -- Memory Control Flow Guard
                        if (sample_ready_in = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                    -- GET Status Info
                    when 1 =>
                        sample_valid_in <= '1';
                        sample_addr     <= cur_sample + SMF_STATUS_INFO_OFFSET;
                        sample_read     <= '1';
                        
                        -- Memory Control Flow Guard
                        if (sample_ready_in = '1') then
                            -- 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 =>
                        -- 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 3 =>
                        sample_ready_out    <= '1';
                        
                        -- Memory Control Flow Guard
                        if (sample_valid_out = '1') then
                            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
                                        tmp_bool    := FALSE;
                                    end if;
                                when NOT_READ_SAMPLE_STATE =>
                                    if (sample_read_data(SSI_READ_FLAG) /= '0') then
                                        tmp_bool    := FALSE;
                                    end if;
                                when ANY_SAMPLE_STATE =>
                                    null;
                                -- Uknown Sample State
                                when others =>
                                    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;
                            
                            -- Sample Passes Checks
                            if (tmp_bool) then
                                if (WITH_KEY) then
                                    cnt_next    <= cnt + 1;
                                else
                                    -- First Instance Sample
                                    -- NOTE: If sample rank is bigger than zero, we have already accepted the instance.
                                    if (si_sample_rank_sig = 0) then
                                        cnt_next    <= cnt + 3; --Skip to Check Instance State
                                    else
                                        -- Select Sample
                                        collection_cnt_next     <= collection_cnt + 1;
                                        sel_sample_next         <= cur_sample;
                                        -- Latch Next Sample (For resume purposes)
                                        sample_p1_next          <= next_sample;
                                        si_sample_rank_sig_next <= si_sample_rank_sig - 1;
                                        cnt_next    <= cnt + 4; --Skip all Instance Related States
                                    end if;
                                end if;
                            else
                                -- 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';
                                            -- Latch first skipped Sample
                                            if (sample_p2 = SAMPLE_MEMORY_MAX_ADDRESS) then
                                                sample_p2_next      <= cur_sample;
                                            end if;
                                        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;
                                        sel_sample_next         <= cur_sample;
                                        -- Latch Next Sample (For resume purposes)
                                        sample_p1_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
                                    -- 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 6 =>
                        -- Synthesis Guard
                        if (WITH_KEY) then
                            -- Memory Operation Guard
                            if (inst_op_done = '1') then
                                inst_op_start       <= '1';
                                inst_opcode         <= GET_INSTANCE;
                                inst_mem_fields     <= IMF_STATUS_FLAG;
                                inst_addr_update    <= next_inst;
                                cur_inst_next       <= next_inst;
                                cnt_next            <= cnt + 1;
                            end if;
                        end if;
                    -- Check Instance Data
                    when 7 =>
                        -- Wait for Instance Data
                        if (not WITH_KEY or inst_op_done = '1') then
                            -- DEFAULT
                            tmp_bool    := TRUE;
                            
                            -- Check Instance State
                            case (instance_state) is
                                when ALIVE_INSTANCE_STATE =>
                                    if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '1' or inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '1') then
                                        tmp_bool    := FALSE;
                                    end if;
                                when NOT_ALIVE_DISPOSED_INSTANCE_STATE =>
                                    if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '0') then
                                        tmp_bool    := FALSE;
                                    end if;
                                when NOT_ALIVE_NO_WRITERS_INSTANCE_STATE =>
                                    if (inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '0') then
                                        tmp_bool    := FALSE;
                                    end if;
                                when NOT_ALIVE_INSTANCE_STATE =>
                                    if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '0' and inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '0') then
                                        tmp_bool    := FALSE;
                                    end if;
                                when ANY_INSTANCE_STATE =>
                                    null;
                                when others =>
                                    tmp_bool    := FALSE;
                            end case;
                            
                            -- Check View State
                            case (view_state) is
                                when NEW_VIEW_STATE =>
                                    if (inst_data.status_info(ISI_VIEW_FLAG) = '1') then
                                        tmp_bool    := FALSE;
                                    end if;
                                when NOT_NEW_VIEW_STATE =>
                                    if (inst_data.status_info(ISI_VIEW_FLAG) = '0') then
                                        tmp_bool    := FALSE;
                                    end if;
                                when ANY_VIEW_STATE =>
                                    null;
                                when others =>
                                    tmp_bool    := FALSE;
                            end case;
                            
                            -- Check Instance Mark
                            if (inst_data.status_info(ISI_MARK_FLAG) = '1') then
                                -- Skip Marked Instance
                                tmp_bool    := FALSE;
                            end if;
                            
                            -- Instance Passes Checks
                            if (tmp_bool) then
                                -- Select Sample
                                collection_cnt_next     <= collection_cnt + 1;
                                collection_cnt_max_next <= collection_cnt + 1;
                                si_sample_rank_sig_next <= (others => '0');
                                cur_inst_next           <= next_inst;
                                sel_sample_next         <= cur_sample;
                                -- Latch Next Sample (For resume purposes)
                                sample_p1_next          <= next_sample;
                                cnt_next                <= cnt + 1;
                            else
                                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 8 =>
                        sample_valid_in <= '1';
                        sample_addr     <= cur_sample + SMF_TIMESTAMP_OFFSET;
                        sample_read     <= '1';
                        
                        -- Memory Control Flow Guard
                        if (sample_ready_in = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                    -- GET Timestamp 2/2
                    when 9 =>
                        sample_valid_in <= '1';
                        sample_addr     <= cur_sample + SMF_TIMESTAMP_OFFSET + 1;
                        sample_read     <= '1';
                        
                        -- Memory Control Flow Guard
                        if (sample_ready_in = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                    -- GET Payload Pointer
                    when 10 =>
                        sample_valid_in <= '1';
                        sample_addr     <= cur_sample + SMF_PAYLOAD_ADDR_OFFSET;
                        sample_read     <= '1';
                        
                        -- Memory Control Flow Guard
                        if (sample_ready_in = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                    -- GET Disposed Generation Count
                    when 11 =>
                        sample_valid_in <= '1';
                        sample_addr     <= cur_sample + SMF_DISPOSED_GEN_CNT_OFFSET;
                        sample_read     <= '1';
                        
                        -- Memory Control Flow Guard
                        if (sample_ready_in = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                    -- GET No Writers Generation Count
                    when 12 =>
                        sample_valid_in <= '1';
                        sample_addr     <= cur_sample + SMF_NO_WRITERS_GEN_CNT_OFFSET;
                        sample_read     <= '1';
                        
                        -- Memory Control Flow Guard
                        if (sample_ready_in = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                    -- READ Timestamp 1/2
                    when 13 =>
                        sample_ready_out    <= '1';
                        
                        -- Memory Control Flow Guard
                        if (sample_valid_out = '1') then
                            si_source_timestamp_sig_next(0) <= unsigned(sample_read_data);
                            cnt_next    <= cnt + 1;
                        end if;
                    -- 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    <= resize(unsigned(sample_read_data),PAYLOAD_MEMORY_ADDR_WIDTH);
                            cnt_next            <= cnt + 1;
                        end if;
                    -- READ Disposed Generation Count
                    when 16 =>
                        sample_ready_out    <= '1';
                        
                        -- Memory Control Flow Guard
                        if (sample_valid_out = '1') then
                            si_disposed_generation_count_sig_next   <= sample_read_data;
                            cnt_next    <= cnt + 1;
                        end if;
                    -- READ No Writers Generation Count
                    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                <= unsigned(si_disposed_generation_count_sig) + unsigned(sample_read_data);
                            if (si_sample_rank_sig = 0) then
                                -- Reset
                                collection_generation_rank_next     <= unsigned(si_disposed_generation_count_sig) + unsigned(sample_read_data);
                            end if;
                            cnt_next    <= cnt + 1;
                        end if;
                    -- Exit State
                    when 18 =>
                        -- Exit Condition (Sample Selected)
                        if (sel_sample /= SAMPLE_MEMORY_MAX_ADDRESS) then
                            -- Sample not marked as Read
                            if (sample_status_info(SSI_READ_FLAG) /= '1') then
                                -- Mark Sample as Read
                                sample_valid_in                     <= '1';
                                sample_addr                         <= cur_sample + SMF_STATUS_INFO_OFFSET;
                                sample_write_data                   <= sample_status_info;
                                sample_write_data(SSI_READ_FLAG)    <= '1';
                                -- 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_latch or next_sample = SAMPLE_MEMORY_MAX_ADDRESS) then
                                        stage_next  <= FINALIZE_SAMPLE_INFO;
                                        cnt_next    <= 0;
                                    else
                                        -- Calculate Instance Sample Ranks
                                        cur_sample_next <= next_sample;
                                        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_latch or next_sample = SAMPLE_MEMORY_MAX_ADDRESS) then
                                    stage_next  <= FINALIZE_SAMPLE_INFO;
                                    cnt_next    <= 0;
                                else
                                    -- Calculate Instance Sample Ranks
                                    cur_sample_next <= next_sample;
                                    stage_next      <= PRE_CALCULATE;
                                    cnt_next        <= 0;
                                end if;
                            end if;
                            
                            -- First Sample Selected
                            if (collection_cnt = 1) then
                                done_dds        <= '1';
                                return_code_dds <= RETCODE_OK;
                            end if;
                        else
                            -- End of Samples
                            if (next_sample = SAMPLE_MEMORY_MAX_ADDRESS) then
                                -- Collection Empty
                                if (collection_cnt = 0) then
                                    -- READ_NEXT_INSTANCE/TAKE_NEXT_INSTANCE Operation
                                    if (WITH_KEY and dynamic_next_instance = '1') then
                                        -- NOTE: We selected a compatible instance, but the instance has no compatible samples.
                                        --       Find next compatible instance.
                                        stage_next  <= FIND_NEXT_INSTANCE;
                                        cnt_next    <= 1;
                                    else
                                        done_dds        <= '1';
                                        return_code_dds <= RETCODE_NO_DATA;
                                        stage_next      <= IDLE;
                                    end if;
                                else
                                    -- Mark End of Collection
                                    eoc         <= '1';
                                    stage_next  <= IDLE;
                                    -- 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
                                        -- Unmark Instances
                                        unmark_instances_flag_next   <= '1';
                                    end if;
                                end if;
                            else
                                -- Continue Searching
                                cur_sample_next <= next_sample;
                                cnt_next        <= 0;
                            end if;
                        end if;
                    when others => 
                        null;
                end case;
            when PRE_CALCULATE =>
                -- Precondition: cur_sample set, cur_inst set
                
                cnt_next    <= cnt + 1;
                
                case (cnt) is
                    -- GET Next Sample
                    when 0 =>
                        sample_valid_in <= '1';
                        sample_addr     <= cur_sample + SMF_NEXT_ADDR_OFFSET;
                        sample_read     <= '1';
                        
                        -- Memory Control Flow Guard
                        if (sample_ready_in = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                    -- GET Status Info
                    when 1 =>
                        sample_valid_in <= '1';
                        sample_addr     <= cur_sample + SMF_STATUS_INFO_OFFSET;
                        sample_read     <= '1';
                        
                        -- Memory Control Flow Guard
                        if (sample_ready_in = '1') then
                            -- 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 =>
                        -- 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 =>
                        sample_valid_in <= '1';
                        sample_addr     <= cur_sample + SMF_DISPOSED_GEN_CNT_OFFSET;
                        sample_read     <= '1';
                        
                        -- Memory Control Flow Guard
                        if (sample_ready_in = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                    -- GET No Writers Generation Count
                    when 4 =>
                        sample_valid_in <= '1';
                        sample_addr     <= cur_sample + SMF_NO_WRITERS_GEN_CNT_OFFSET;
                        sample_read     <= '1';
                        
                        -- Memory Control Flow Guard
                        if (sample_ready_in = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                    -- READ Next Sample
                    when 5 =>
                        sample_ready_out    <= '1';
                        
                        -- Memory Control Flow Guard
                        if (sample_valid_out = '1') then
                            next_sample_next    <= resize(unsigned(sample_read_data),SAMPLE_MEMORY_ADDR_WIDTH);
                            cnt_next            <= cnt + 1;
                        end if;
                    -- READ Status Info
                    when 6 =>
                        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
                                        tmp_bool    := FALSE;
                                    end if;
                                when NOT_READ_SAMPLE_STATE =>
                                    if (sample_read_data(SSI_READ_FLAG) /= '0') then
                                        tmp_bool    := FALSE;
                                    end if;
                                when ANY_SAMPLE_STATE =>
                                    null;
                                -- Uknown Sample State
                                when others =>
                                    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 =>
                        -- 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
                                    -- 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;
                    -- READ Disposed Generation Count
                    when 8 =>
                        sample_ready_out    <= '1';
                        
                        -- Memory Control Flow Guard
                        if (sample_valid_out = '1') then
                            -- Calculate highest collection generation rank
                            collection_generation_rank_next <= unsigned(sample_read_data);
                            cnt_next    <= cnt + 1;
                        end if;
                    -- READ No Writers Generation Count
                    when 9 =>
                        sample_ready_out    <= '1';
                        
                        -- Memory Control Flow Guard
                        if (sample_valid_out = '1') then
                            -- Calculate highest collection generation rank
                            collection_generation_rank_next <= collection_generation_rank + unsigned(sample_read_data);
                            -- Skip Instance Check
                            cnt_next    <= cnt + 3;
                        end if;
                    -- Get Instance Data
                    when 10 =>
                        -- Synthesis Guard
                        if (WITH_KEY) then
                            -- Memory Operation Guard
                            if (inst_op_done = '1') then
                                inst_op_start       <= '1';
                                inst_opcode         <= GET_INSTANCE;
                                inst_mem_fields     <= IMF_STATUS_FLAG;
                                inst_addr_update    <= next_inst;
                                cnt_next            <= cnt + 1;
                            end if;
                        end if;
                    -- Check Instance Data
                    when 11 =>
                        -- Synthesis Guard
                        if (WITH_KEY) then
                            -- Wait for Instance Data
                            if (inst_op_done = '1') then
                                -- DEFAULT
                                tmp_bool    := TRUE;
                                
                                -- Check Instance State
                                case (instance_state) is
                                    when ALIVE_INSTANCE_STATE =>
                                        if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '1' or inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '1') then
                                            tmp_bool    := FALSE;
                                        end if;
                                    when NOT_ALIVE_DISPOSED_INSTANCE_STATE =>
                                        if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '0') then
                                            tmp_bool    := FALSE;
                                        end if;
                                    when NOT_ALIVE_NO_WRITERS_INSTANCE_STATE =>
                                        if (inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '0') then
                                            tmp_bool    := FALSE;
                                        end if;
                                    when NOT_ALIVE_INSTANCE_STATE =>
                                        if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '0' and inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '0') then
                                            tmp_bool    := FALSE;
                                        end if;
                                    when ANY_INSTANCE_STATE =>
                                        null;
                                    when others =>
                                        tmp_bool    := FALSE;
                                end case;
                                
                                -- Check View State
                                case (view_state) is
                                    when NEW_VIEW_STATE =>
                                        if (inst_data.status_info(ISI_VIEW_FLAG) = '1') then
                                            tmp_bool    := FALSE;
                                        end if;
                                    when NOT_NEW_VIEW_STATE =>
                                        if (inst_data.status_info(ISI_VIEW_FLAG) = '0') then
                                            tmp_bool    := FALSE;
                                        end if;
                                    when ANY_VIEW_STATE =>
                                        null;
                                    when others =>
                                        tmp_bool    := FALSE;
                                end case;
                                
                                -- Check Instance Mark
                                if (inst_data.status_info(ISI_MARK_FLAG) = '1') then
                                    -- Skip Marked Instance
                                    tmp_bool    := FALSE;
                                end if;
                                
                                -- Instance passes Checks
                                if (tmp_bool) then
                                    -- Count Sample
                                    collection_cnt_max_next <= collection_cnt_max + 1;
                                end if;
                                cnt_next    <= cnt + 1;
                            end if;
                        end if;
                    -- 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_latch) then
                            stage_next  <= FINALIZE_SAMPLE_INFO;
                            cnt_next    <= 0;
                        else
                            -- Continue with next Sample
                            cur_sample_next <= next_sample;
                            cnt_next        <= 0;
                        end if;
                    when others =>
                        null;
                end case;
            when FINALIZE_SAMPLE_INFO =>
                -- Precondition: cur_inst set
                
                case (cnt) is
                    -- Finalize Sample Info Data
                    when 0 =>
                        -- Wait for Instance Data
                        if (not WITH_KEY or inst_op_done = '1') then
                            -- Instance Data valid
                            if (not WITH_KEY or (inst_addr_base = cur_inst and check_mask(current_imf,IMF_STATUS_FLAG or IMF_KEY_HASH_FLAG or IMF_DISPOSED_CNT_FLAG or IMF_NO_WRITERS_CNT_FLAG))) then
                                
                                -- Sample Info View State
                                if (inst_data.status_info(ISI_VIEW_FLAG) = '0') then
                                    si_view_state_sig_next  <= NEW_VIEW_STATE;
                                else
                                    si_view_state_sig_next  <= NOT_NEW_VIEW_STATE;
                                end if;
                                
                                -- Sample Info Instance State
                                if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '1') then
                                    si_instance_state_sig_next  <= NOT_ALIVE_DISPOSED_INSTANCE_STATE;
                                elsif (inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '1') then
                                    si_instance_state_sig_next  <= NOT_ALIVE_NO_WRITERS_INSTANCE_STATE;
                                else
                                    si_instance_state_sig_next  <= ALIVE_INSTANCE_STATE;
                                end if;
                                
                                -- Sample Info Instance Handle
                                si_instance_handle_sig_next <= inst_data.key_hash;
                                
                                -- Sample Info Generation Rank
                                si_generation_rank_sig_next <= collection_generation_rank - cur_generation_rank;
                                
                                -- Sample Info Absolut Generation Rank
                                -- XXX: Possible Worst Case Path (2 32-bit Operations in same clock)
                                si_absolute_generation_rank_sig_next    <= (inst_data.disposed_gen_cnt + inst_data.no_writers_gen_cnt) - cur_generation_rank;
                                
                                -- Sample Info Valid Data
                                if (cur_payload /= PAYLOAD_MEMORY_MAX_ADDRESS) then
                                    si_valid_data_sig_next  <= '1';
                                else
                                    si_valid_data_sig_next  <= '0';
                                end if;
                                
                                si_valid_sig_next   <= '1';
                                cnt_next            <= 1;
                            else
                                -- Get Instance Data
                                inst_op_start       <= '1';
                                inst_opcode         <= GET_INSTANCE;
                                inst_mem_fields     <= IMF_KEY_HASH_FLAG or IMF_STATUS_FLAG or IMF_DISPOSED_CNT_FLAG or IMF_NO_WRITERS_CNT_FLAG;
                                inst_addr_update    <= cur_inst;
                            end if;
                        end if;
                    -- Present Data
                    when 1 =>
                        -- Synthesis Guard
                        if (DESTINATION_ORDER_QOS = BY_SOURCE_TIMESTAMP_DESTINATION_ORDER_QOS) then
                            -- Update Last Read Timestamp
                            if (si_source_timestamp_sig > last_read_ts) then
                                last_read_ts_next   <= si_source_timestamp_sig;
                            end if;
                        end if;
                        
                        -- Reset Data Available Status
                        status_sig_next <= status_sig and (not DATA_AVAILABLE_STATUS);
                        
                        -- Sample Data Request
                        if (get_data_dds = '1') then
                            stage_next  <= GET_PAYLOAD;
                            cnt_next    <= 0;
                        else
                            cnt_next    <= 2;
                            -- Invalidate Data
                            si_valid_sig_next   <= '0';
                        end if;
                    -- Post-Present Data
                    when 2 =>
                        -- Memory Operation Guard
                        if (not WITH_KEY or inst_op_done = '1') then
                            -- NOTE: If we have a presentation of consecutive same instance samples of multiple instances, we have to
                            --       mark the instances we have already handled, in order to prevent the GET_NEXT_SAMPLE state to
                            --       re-process them.
                            -- Last Sample of Instance in Collection
                            if (si_sample_rank_sig = 0) then
                                -- Synthesis Guard
                                if (WITH_KEY) then
                                    inst_op_start       <= '1';
                                    inst_opcode         <= UPDATE_INSTANCE;
                                    inst_mem_fields     <= IMF_STATUS_FLAG;
                                    status_info_update  <= inst_data.status_info;
                                    
                                    -- 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
                                        -- Mark Instance
                                        status_info_update(ISI_MARK_FLAG)   <= '1';
                                    end if;
                                    
                                    -- 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_rank_sig = 0) then
                                        -- Mark Instance as VIEWED
                                        status_info_update(ISI_VIEW_FLAG)   <= '1';
                                    end if;
                                else
                                    -- 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_rank_sig = 0) then
                                        -- Mark Instance as VIEWED
                                        inst_data_next2.status_info(ISI_VIEW_FLAG)   <= '1';
                                    end if;
                                end if;
                            end if;
                            
                            -- End of Collection
                            if (collection_cnt = max_samples_latch or (sample_p1 = SAMPLE_MEMORY_MAX_ADDRESS and sample_p2 = SAMPLE_MEMORY_MAX_ADDRESS) or (si_sample_rank_sig = 0 and single_instance = '1')) then
                                -- Mark End of Collection
                                eoc <= '1';
                                -- 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
                                    -- Unmark Instances
                                    unmark_instances_flag_next   <= '1';
                                end if;
                                
                                if (is_take = '1') then
                                    cur_sample_next <= sel_sample;
                                    stage_next      <= REMOVE_SAMPLE;
                                    cnt_next        <= 0;
                                    is_take_next    <= '0'; -- Return to IDLE from REMOVE
                                else
                                    -- DONE
                                    stage_next  <= IDLE;
                                end if;
                            else
                                if (is_take = '1') then
                                    -- Remove Sample
                                    cur_sample_next <= sel_sample;
                                    stage_next      <= REMOVE_SAMPLE;
                                    cnt_next        <= 0;
                                else
                                    -- cur_inst has no more samples in collection
                                    if (si_sample_rank_sig = 0) then
                                        -- Skipped Sample available
                                        if (sample_p2 /= SAMPLE_MEMORY_MAX_ADDRESS) then
                                            cur_sample_next <= sample_p2;
                                        else
                                            cur_sample_next <= sample_p1;
                                        end if;
                                        cur_inst_next   <= INSTANCE_MEMORY_MAX_ADDRESS;
                                        sample_p2_next  <= SAMPLE_MEMORY_MAX_ADDRESS;
                                    else
                                        cur_sample_next <= sample_p1;
                                    end if;
                                    sample_p1_next  <= SAMPLE_MEMORY_MAX_ADDRESS;
                                    sel_sample_next <= SAMPLE_MEMORY_MAX_ADDRESS;
                                    -- Continue Processing
                                    stage_next  <= GET_NEXT_SAMPLE;
                                    cnt_next    <= 0;
                                end if;
                            end if;
                        end if;
                    when others =>
                        null;
                end case;
            when GET_PAYLOAD =>
                -- Precondition: cur_payload set, sample_status_info set
                
                -- NOTE: We are using the Burst Capability of the Memory Controller as a FIFO which we
                --       fill and the output is directly reading. cnt is switching the memory reading states,
                --       cnt2 signals the offset of the payload read, and cnt3 signals how many Bytes have been
                --       requested but not yet claimed (i.e. how many Bytes are in the FIFO).
                
                -- DEFAULT
                tmp_bool    := FALSE;
                
                case (cnt) is
                    -- GET Next Pointer
                    when 0 =>
                        -- 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 =>
                        payload_ready_out   <= '1';
                        
                        -- Memory Flow Control Guard
                        if (payload_valid_out = '1') then
                            next_payload_next   <= resize(unsigned(payload_read_data),PAYLOAD_MEMORY_ADDR_WIDTH);
                            cnt2_next           <= 1;
                            
                            -- Last Payload Slot is unaligned
                            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 <= std_logic_vector(to_unsigned(PAYLOAD_FRAME_SIZE-1,CDR_LONG_WIDTH));
                            end if;
                        end if;
                    -- GET Payload Offset
                    when 2 =>
                        payload_valid_in    <= '1';
                        payload_addr        <= cur_payload + PAYLOAD_FRAME_SIZE-1;
                        payload_read        <= '1';
                        
                        -- Memory Flow Control Guard
                        if (payload_ready_in = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                    -- READ Payload Offset
                    when 3 =>
                        payload_ready_out   <= '1';
                        
                        -- Memory Flow Control Guard
                        if (payload_valid_out = '1') then
                            long_latch_next <= payload_read_data;
                            cnt_next        <= cnt + 1;
                        end if;
                    -- GET PAYLOAD
                    when 4 =>
                        payload_valid_in    <= '1';
                        payload_addr        <= cur_payload + cnt2;
                        payload_read        <= '1';
                        
                        -- Memory Flow Control Guard
                        if (payload_ready_in = '1') then
                            cnt3_next   <= cnt3 + 1;
                            tmp_bool    := TRUE;
                            -- End of Payload Slot
                            if (cnt2 = unsigned(long_latch)) then
                                -- End of Payload
                                if (next_payload = PAYLOAD_MEMORY_MAX_ADDRESS) then
                                    -- DONE (Wait for Output to finidh reading)
                                    cnt_next    <= cnt + 1;
                                else
                                    -- Next Payload Slot
                                    cur_payload_next    <= next_payload;
                                    cnt_next            <= 0;
                                end if;
                            else
                                cnt2_next   <= cnt2 + 1;
                            end if;
                        end if;
                    when others =>
                        null;
                end case;
                
                -- Data available for Output
                if (cnt3 /= 0) then
                    -- 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 = 5) then
                            last_word_out_dds   <= '1';
                        end if;
                        
                        -- DDS Read
                        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.
                            -- Increment in same clock cycle
                            if (tmp_bool) then
                                cnt3_next   <= cnt3; -- Override increment
                            else                            
                                cnt3_next   <= cnt3 - 1;
                                -- Exit Condition
                                if (cnt3 = 1 and cnt = 5) then
                                    -- Exit
                                    stage_next  <= FINALIZE_SAMPLE_INFO;
                                    cnt_next    <= 2;
                                    -- Invalidate Data
                                    si_valid_sig_next   <= '0';
                                end if;
                            end if;
                        end if;
                    end if;
                end if;
            when FIND_NEXT_INSTANCE =>
                -- Synthesis Guard
                if (WITH_KEY) then
                    -- Wait for Instance Data
                    if (inst_op_done = '1') then
                        case (cnt) is
                            when 0 =>
                                -- 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';
                                inst_opcode         <= GET_FIRST_INSTANCE;
                                inst_mem_fields     <= IMF_STATUS_FLAG or IMF_KEY_HASH_FLAG;
                                cnt_next            <= 2;
                            when 1 =>
                                -- 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';
                                inst_opcode         <= GET_NEXT_INSTANCE;
                                inst_mem_fields     <= IMF_STATUS_FLAG or IMF_KEY_HASH_FLAG;
                                cnt_next            <= 2;
                            when 2 =>
                                -- Instance Found
                                if (inst_addr_base /= SAMPLE_MEMORY_MAX_ADDRESS) then
                                    -- DEFAULT
                                    tmp_bool    := TRUE;
                                    
                                    -- 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
                                        tmp_bool    := FALSE;
                                    end if;
                                    
                                    -- Check Instance State
                                    case (instance_state) is
                                        when ALIVE_INSTANCE_STATE =>
                                            if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '1' or inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '1') then
                                                tmp_bool    := FALSE;
                                            end if;
                                        when NOT_ALIVE_DISPOSED_INSTANCE_STATE =>
                                            if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '0') then
                                                tmp_bool    := FALSE;
                                            end if;
                                        when NOT_ALIVE_NO_WRITERS_INSTANCE_STATE =>
                                            if (inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '0') then
                                                tmp_bool    := FALSE;
                                            end if;
                                        when NOT_ALIVE_INSTANCE_STATE =>
                                            if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '0' and inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '0') then
                                                tmp_bool    := FALSE;
                                            end if;
                                        when ANY_INSTANCE_STATE =>
                                            null;
                                        when others =>
                                            tmp_bool    := FALSE;
                                    end case;
                                    
                                    -- Check View State
                                    case (view_state) is
                                        when NEW_VIEW_STATE =>
                                            if (inst_data.status_info(ISI_VIEW_FLAG) = '1') then
                                                tmp_bool    := FALSE;
                                            end if;
                                        when NOT_NEW_VIEW_STATE =>
                                            if (inst_data.status_info(ISI_VIEW_FLAG) = '0') then
                                                tmp_bool    := FALSE;
                                            end if;
                                        when ANY_VIEW_STATE =>
                                            null;
                                        when others =>
                                            tmp_bool    := FALSE;
                                    end case;
                                    
                                    -- Instance Passes Checks
                                    if (tmp_bool) then
                                        cur_inst_next   <= inst_addr_base;
                                        stage_next      <= GET_NEXT_SAMPLE;
                                        cnt_next        <= 0;
                                        -- Reset
                                        sel_sample_next <= SAMPLE_MEMORY_MAX_ADDRESS;
                                        sample_p1_next  <= SAMPLE_MEMORY_MAX_ADDRESS;
                                        sample_p2_next  <= SAMPLE_MEMORY_MAX_ADDRESS;
                                    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';
                                        inst_opcode         <= GET_NEXT_INSTANCE;
                                        inst_mem_fields     <= IMF_STATUS_FLAG or IMF_KEY_HASH_FLAG;
                                    end if;
                                else
                                    -- DONE
                                    done_dds        <= '1';
                                    return_code_dds <= RETCODE_NO_DATA;
                                    stage_next      <= IDLE;
                                end if;
                            when others =>
                                null;
                        end case;
                    end if;
                end if;
            when CHECK_INSTANCE =>
                -- Synthesis Guard
                if (WITH_KEY) then
                    -- Wait for Instance Data
                    if (inst_op_done = '1') then
                        case (cnt) is
                            when 0 =>
                                -- 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';
                                inst_opcode         <= SEARCH_INSTANCE_HASH;
                                inst_mem_fields     <= IMF_STATUS_FLAG;
                                cnt_next            <= cnt + 1;
                            when 1 =>
                                -- Instance Found
                                if (inst_addr_base /= SAMPLE_MEMORY_MAX_ADDRESS) then
                                    -- DEFAULT
                                    tmp_bool    := TRUE;
                                    
                                    -- Check Instance State
                                    case (instance_state) is
                                        when ALIVE_INSTANCE_STATE =>
                                            if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '1' or inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '1') then
                                                tmp_bool    := FALSE;
                                            end if;
                                        when NOT_ALIVE_DISPOSED_INSTANCE_STATE =>
                                            if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '0') then
                                                tmp_bool    := FALSE;
                                            end if;
                                        when NOT_ALIVE_NO_WRITERS_INSTANCE_STATE =>
                                            if (inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '0') then
                                                tmp_bool    := FALSE;
                                            end if;
                                        when NOT_ALIVE_INSTANCE_STATE =>
                                            if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '0' and inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '0') then
                                                tmp_bool    := FALSE;
                                            end if;
                                        when ANY_INSTANCE_STATE =>
                                            null;
                                        when others =>
                                            tmp_bool    := FALSE;
                                    end case;
                                    
                                    -- Check View State
                                    case (view_state) is
                                        when NEW_VIEW_STATE =>
                                            if (inst_data.status_info(ISI_VIEW_FLAG) = '1') then
                                                tmp_bool    := FALSE;
                                            end if;
                                        when NOT_NEW_VIEW_STATE =>
                                            if (inst_data.status_info(ISI_VIEW_FLAG) = '0') then
                                                tmp_bool    := FALSE;
                                            end if;
                                        when ANY_VIEW_STATE =>
                                            null;
                                        when others =>
                                            tmp_bool    := FALSE;
                                    end case;
                                    
                                    -- Instance Passes Checks
                                    if (tmp_bool) then
                                        -- Get Instance Samples
                                        cur_inst_next   <= inst_addr_base;
                                        stage_next      <= GET_NEXT_SAMPLE;
                                        cnt_next        <= 0;    
                                    else
                                        -- DONE
                                        done_dds        <= '1';
                                        return_code_dds <= RETCODE_NO_DATA;
                                        stage_next      <= IDLE;
                                    end if;
                                else
                                    -- Given Instance does not exist
                                    -- DONE
                                    done_dds        <= '1';
                                    return_code_dds <= RETCODE_BAD_PARAMETER;
                                    stage_next      <= IDLE;
                                end if;
                            when others =>
                                null;
                        end case;
                    end if;
                end if;
            when CHECK_LIFESPAN =>
                -- Precondition: cur_sample set, 
                
                case (cnt) is
                    -- GET Next Sample
                    when 0 =>
                        sample_valid_in <= '1';
                        sample_addr     <= cur_sample + SMF_NEXT_ADDR_OFFSET;
                        sample_read     <= '1';
                        
                        -- Memory Control Flow Guard
                        if (sample_ready_in = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                    -- GET Lifespan 1/2
                    when 1 =>
                        sample_valid_in <= '1';
                        sample_addr     <= cur_sample + SMF_LIFESPAN_DEADLINE_OFFSET;
                        sample_read     <= '1';
                        
                        -- Memory Control Flow Guard
                        if (sample_ready_in = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                    -- GET Lifespan 2/2
                    when 2 =>
                        sample_valid_in <= '1';
                        sample_addr     <= cur_sample + SMF_LIFESPAN_DEADLINE_OFFSET + 1;
                        sample_read     <= '1';
                        
                        -- Memory Control Flow Guard
                        if (sample_ready_in = '1') then
                            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 =>
                        -- 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 =>
                        sample_ready_out    <= '1';
                        
                        -- Memory Control Flow Guard
                        if (sample_valid_out = '1') then
                            next_sample_next    <= resize(unsigned(sample_read_data),SAMPLE_MEMORY_ADDR_WIDTH);
                            cnt_next            <= cnt + 1;
                        end if;
                    -- READ Lifespan 1/2
                    when 5 =>
                        sample_ready_out    <= '1';
                        
                        -- Memory Control Flow Guard
                        if (sample_valid_out = '1') then
                            long_latch_next <= sample_read_data;
                            cnt_next        <= cnt + 1;
                        end if;
                    -- READ Lifespan 2/2
                    when 6 =>
                        sample_ready_out    <= '1';
                        
                        -- Memory Control Flow Guard
                        if (sample_valid_out = '1') then
                            tmp_dw  := (0 => unsigned(long_latch), 1 => unsigned(sample_read_data));
                        
                            -- Sample Lifespan Expired
                            if (tmp_dw /= TIME_INVALID and time >= tmp_dw) then
                                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';
                                
                                -- Update Check Time
                                if (tmp_dw /= TIME_INVALID and tmp_dw < lifespan_time) then
                                    lifespan_time_next  <= tmp_dw;
                                end if;
                                
                                -- Reached End of Samples
                                if (next_sample = SAMPLE_MEMORY_MAX_ADDRESS) then
                                    -- DONE
                                    stage_next  <= IDLE;
                                else
                                    -- Continue Search
                                    cur_sample_next <= next_sample;
                                    cnt_next        <= 0;
                                end if;
                            end if;
                        end if;
                    -- READ Instance Pointer
                    when 7 =>
                        -- Synthesis Guard
                        if (WITH_KEY) then
                            -- 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_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 => 
                        null;
                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 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 2 =>
                        data_out_dds    <= std_logic_vector(sample_rej_cnt_change);
                        valid_out_dds   <= '1';
                        if (ready_out_dds = '1') then
                            -- Reset
                            sample_rej_cnt_change_next  <= (others => '0');
                            cnt_next    <= cnt + 1;
                        end if;
                    -- Last Reason
                    when 3 =>
                        data_out_dds    <= sample_rej_last_reason;
                        valid_out_dds   <= '1';
                        if (ready_out_dds = '1') then
                            -- Reset
                            sample_rej_last_reason  <= NOT_REJECTED;
                            cnt_next    <= cnt + 1;
                        end if;
                    -- Last Instance Handle 1/4
                    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 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 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 7 =>
                        data_out_dds        <= sample_rej_last_inst(3);
                        valid_out_dds       <= '1';
                        last_word_out_dds   <= '1';
                        if (ready_out_dds = '1') then
                            -- Reset
                            status_sig_next <= status_sig and (not SAMPLE_REJECTED_STATUS);
                            
                            -- DONE
                            stage_next  <= IDLE;
                        end if;
                    when others =>
                        null;
                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 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 2 =>
                        data_out_dds    <= std_logic_vector(deadline_miss_cnt_change);
                        valid_out_dds   <= '1';
                        if (ready_out_dds = '1') then
                            -- Reset
                            deadline_miss_cnt_change_next   <= (others => '0');
                            cnt_next    <= cnt + 1;
                        end if;
                    -- Last Instance Handle 1/4
                    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 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 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 6 =>
                        data_out_dds        <= deadline_miss_last_inst(3);
                        valid_out_dds   <= '1';
                        last_word_out_dds   <= '1';
                        if (ready_out_dds = '1') then
                            -- Reset
                            status_sig_next <= status_sig and (not REQUESTED_DEADLINE_MISSED_STATUS);
                            
                            -- DONE
                            stage_next  <= IDLE;
                        end if;
                    when others =>
                        null;
                end case;
            when CHECK_DEADLINE =>
                -- Synthesis Guard
                if (WITH_KEY) then
                    -- Memory Operation Guard
                    if (inst_op_done = '1') then
                        case (cnt) is
                            -- Get First Instance
                            when 0 =>
                                inst_op_start       <= '1';
                                inst_opcode         <= GET_FIRST_INSTANCE;
                                inst_mem_fields     <= IMF_KEY_HASH_FLAG or IMF_STATUS_FLAG;
                                cnt_next    <= 2;
                            -- Get Next Instance
                            when 1 =>
                                inst_op_start       <= '1';
                                inst_opcode         <= GET_NEXT_INSTANCE;
                                inst_mem_fields     <= IMF_KEY_HASH_FLAG or IMF_STATUS_FLAG;
                                cnt_next    <= 2;
                            -- Check Instance
                            when 2 =>
                                -- Reached End of Instances
                                if (inst_addr_base = INSTANCE_MEMORY_MAX_ADDRESS) then
                                    -- DONE
                                    stage_next  <= IDLE;
                                else
                                    -- Instance received Sample
                                    if (inst_data.status_info(ISI_LIVELINESS_FLAG) = '1') then
                                        -- Reset Liveliness Flag
                                        inst_op_start       <= '1';
                                        inst_opcode         <= UPDATE_INSTANCE;
                                        inst_mem_fields     <= IMF_STATUS_FLAG;
                                        status_info_update  <= inst_data.status_info;
                                        status_info_update(ISI_LIVELINESS_FLAG) <= '0';
                                        cnt_next    <= 1;
                                    else
                                        -- Update Requested Deadline Missed Status
                                        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;
                                        cnt_next    <= 1;
                                    end if;
                                end if;
                            when others =>
                                null;
                        end case;
                    end if;
                end if;
            when RESET_SAMPLE_MEMORY =>
                case (cnt) is
                    -- Initialize
                    when 0 =>
                        prev_sample_next    <= SAMPLE_MEMORY_MAX_ADDRESS;
                        cur_sample_next     <= (others => '0');
                        cnt_next            <= cnt + 1;
                    -- Set Previous Pointer
                    when 1 =>
                        sample_valid_in     <= '1';
                        sample_addr         <= cur_sample + SMF_PREV_ADDR_OFFSET;
                        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;
                    -- Set Next Pointer
                    when 2 =>
                        sample_valid_in     <= '1';
                        sample_addr         <= cur_sample + SMF_NEXT_ADDR_OFFSET;
                        if (cur_sample = MAX_SAMPLE_ADDRESS) then
                            sample_write_data   <= std_logic_vector(resize(SAMPLE_MEMORY_MAX_ADDRESS,WORD_WIDTH));
                        else
                            sample_write_data   <= std_logic_vector(resize(cur_sample + SAMPLE_FRAME_SIZE,WORD_WIDTH));
                        end if;
                        
                        -- Memory Flow Control Guard
                        if (sample_ready_in = '1') then
                            if (cur_sample = MAX_SAMPLE_ADDRESS) then
                                -- DONE
                                stage_next  <= RESET_PAYLOAD_MEMORY;
                                cnt_next    <= 0;
                            else
                                -- Continue
                                cur_sample_next     <= cur_sample + SAMPLE_FRAME_SIZE;
                                prev_sample_next    <= cur_sample;
                                cnt_next            <= 1;
                            end if;
                        end if;
                    when others =>
                        null;
                end case;
            when RESET_PAYLOAD_MEMORY =>
                case (cnt) is
                    -- Initialize
                    when 0 =>
                        cur_payload_next    <= (others => '0');
                        cnt_next            <= cnt + 1;
                    -- Set Next Pointer
                    when 1 =>
                        payload_valid_in    <= '1';
                        payload_addr        <= cur_payload + PMF_NEXT_ADDR_OFFSET;
                        if (cur_payload = MAX_PAYLOAD_ADDRESS) then
                            payload_write_data  <= std_logic_vector(resize(PAYLOAD_MEMORY_MAX_ADDRESS,WORD_WIDTH));
                        else
                            payload_write_data  <= std_logic_vector(resize(cur_payload + PAYLOAD_FRAME_SIZE,WORD_WIDTH));
                        end if;
                        
                        -- Memory Flow Control Guard
                        if (payload_ready_in = '1') then
                            if (cur_payload = MAX_PAYLOAD_ADDRESS) then
                                -- DONE
                                stage_next  <= IDLE;
                            else
                                cur_payload_next    <= cur_payload + PAYLOAD_FRAME_SIZE;
                            end if;
                        end if;
                    when others =>
                        null;
                end case;
            when others =>
                null;
        end case;
    end process;
    
    gen_inst_ctrl_prc : if WITH_KEY generate
    
        -- *Instance Memory Process*
        -- STATE                    DESCRIPTION
        -- IDLE                     Idle State. Done Signal is pulled high and Memory FSM accepts new memory operations
        -- SEARCH_INSTANCE_HASH     See Memory OPCODE Description
        -- SEARCH_INSTANCE_ADDR     See Memory OPCODE Description
        -- GET_NEXT_INSTANCE        See Memory OPCODE Description
        -- GET_INSTANCE_DATA        Latch specified Instance Data for use by main process
        -- FIND_POS                 Find List position of Instance to be added
        -- INSERT_INSTANCE          See Memory OPCODE Description
        -- UPDATE_INSTANCE          See Memory OPCODE Description
        -- REMOVE_INSTANCE          See Memory OPCODE Description
        -- UNMARK_INTANCES          See Memory OPCODE Description
        -- RESET_MEMORY             Reset Endpoint Memory to Empty State
        inst_ctrl_prc : process(all)
        begin
            -- DEFAULT Registered
            inst_stage_next             <= inst_stage;
            inst_addr_base_next         <= inst_addr_base;
            inst_empty_head_next        <= inst_empty_head;
            inst_occupied_head_next     <= inst_occupied_head;
            inst_latch_data_next        <= inst_latch_data;
            inst_next_addr_base_next    <= inst_next_addr_base;
            inst_prev_addr_base_next    <= inst_prev_addr_base;
            inst_cnt_next               <= inst_cnt;
            inst_cnt2_next              <= inst_cnt2;
            inst_data_next              <= inst_data;
            inst_long_latch_next        <= inst_long_latch;
            current_imf_next            <= current_imf;
            -- DEFAULT Unregistered
            inst_abort_read     <= '0';
            inst_ready_out      <= '0';
            inst_valid_in       <= '0';
            inst_read           <= '0';
            inst_op_done        <= '0';
            inst_addr           <= (others => '0');
            inst_write_data     <= (others => '0');
            
            
            case (inst_stage) is
                when IDLE =>
                    inst_op_done    <= '1';
                    
                    if (inst_op_start = '1') then
                        -- Latch Signals needed for Mermory Operation (Use _next signals, because some signals are set in same clk)
                        inst_latch_data_next    <= (
                            key_hash        => key_hash_next,
                            status_info     => status_info_update,
                            sample_cnt      => sample_cnt,
                            gen_cnt         => gen_cnt,
                            deadline        => deadline,
                            writer_bitmap   => writer_bitmap,
                            field_flags     => inst_mem_fields,
                            addr            => inst_addr_update
                        );
                        
                        case(inst_opcode) is
                            when SEARCH_INSTANCE_HASH =>
                                -- Reset Data
                                current_imf_next    <= inst_mem_fields;
                                inst_data_next      <= ZERO_INSTANCE_DATA;
                                
                                -- No Instances avialable
                                if (inst_occupied_head = INSTANCE_MEMORY_MAX_ADDRESS) then
                                    inst_addr_base_next         <= INSTANCE_MEMORY_MAX_ADDRESS;
                                else
                                    inst_prev_addr_base_next    <= INSTANCE_MEMORY_MAX_ADDRESS;
                                    inst_addr_base_next         <= inst_occupied_head;
                                    inst_stage_next             <= SEARCH_INSTANCE_HASH;
                                    inst_cnt_next               <= 0;
                                end if;
                            when SEARCH_INSTANCE_ADDR =>
                                -- Reset Data
                                current_imf_next    <= inst_mem_fields;
                                inst_data_next      <= ZERO_INSTANCE_DATA;
                                
                                -- No Instances avialable
                                if (inst_occupied_head = INSTANCE_MEMORY_MAX_ADDRESS) then
                                    inst_addr_base_next         <= INSTANCE_MEMORY_MAX_ADDRESS;
                                else
                                    inst_prev_addr_base_next    <= INSTANCE_MEMORY_MAX_ADDRESS;
                                    inst_addr_base_next         <= inst_occupied_head;
                                    inst_stage_next             <= SEARCH_INSTANCE_ADDR;
                                    inst_cnt_next               <= 0;
                                end if;
                            when INSERT_INSTANCE =>
                                -- NOTE: Since this process has no way to communicate a failed insert to the main process, it has to be made sure
                                --       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;
                                
                                -- Reset Data
                                current_imf_next    <= (others => '1');
                                inst_data_next      <= ZERO_INSTANCE_DATA;
                                
                                -- First Instance
                                if (inst_occupied_head = INSTANCE_MEMORY_MAX_ADDRESS) then
                                    inst_prev_addr_base_next    <= INSTANCE_MEMORY_MAX_ADDRESS;
                                    inst_next_addr_base_next    <= INSTANCE_MEMORY_MAX_ADDRESS;
                                    inst_addr_base_next         <= inst_empty_head;
                                    inst_stage_next             <= INSERT_INSTANCE;
                                    inst_cnt_next               <= 1; -- Skip first Step
                                    inst_occupied_head_next     <= inst_empty_head;
                                else
                                    inst_prev_addr_base_next    <= INSTANCE_MEMORY_MAX_ADDRESS;
                                    inst_addr_base_next         <= inst_occupied_head;
                                    inst_stage_next             <= FIND_POS;
                                    inst_cnt_next               <= 0;
                                end if;
                            when UPDATE_INSTANCE =>
                                current_imf_next    <= current_imf or inst_mem_fields;
                                inst_stage_next     <= UPDATE_INSTANCE;
                                if check_mask(inst_mem_fields,IMF_STATUS_FLAG) then
                                    inst_cnt_next   <= 0;
                                elsif check_mask(inst_mem_fields,IMF_SAMPLE_CNT_FLAG) then
                                    inst_cnt_next   <= 1;
                                elsif check_mask(inst_mem_fields,IMF_DISPOSED_CNT_FLAG) then
                                    inst_cnt_next   <= 2;
                                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,IMF_IGNORE_DEADLINE_FLAG)) then
                                    inst_cnt_next   <= 4;
                                elsif check_mask(inst_mem_fields,IMF_WRITER_BITMAP_FLAG) then
                                    inst_cnt_next   <= 6;
                                    inst_cnt2_next  <= 0;
                                else
                                    -- DONE
                                    inst_stage_next <= IDLE;
                                end if;
                            when GET_FIRST_INSTANCE =>
                                -- Reset
                                current_imf_next    <= inst_mem_fields;
                                inst_data_next      <= ZERO_INSTANCE_DATA;
                                
                                -- No Instances available
                                if (inst_occupied_head = INSTANCE_MEMORY_MAX_ADDRESS) then
                                    inst_addr_base_next         <= INSTANCE_MEMORY_MAX_ADDRESS;
                                else
                                    inst_prev_addr_base_next    <= INSTANCE_MEMORY_MAX_ADDRESS;
                                    inst_addr_base_next         <= inst_occupied_head;
                                    inst_stage_next             <= GET_NEXT_INSTANCE;
                                    inst_cnt_next               <= 0;
                                end if;
                            when GET_NEXT_INSTANCE =>
                                -- Reset
                                current_imf_next    <= inst_mem_fields;
                                inst_data_next      <= ZERO_INSTANCE_DATA;
                                
                                -- No Instances available
                                if (inst_next_addr_base = INSTANCE_MEMORY_MAX_ADDRESS) then
                                    inst_addr_base_next   <= INSTANCE_MEMORY_MAX_ADDRESS;
                                else
                                    inst_prev_addr_base_next    <= inst_addr_base;
                                    inst_addr_base_next         <= inst_next_addr_base;
                                    inst_stage_next             <= GET_NEXT_INSTANCE;
                                    inst_cnt_next               <= 0;
                                end if;
                            when REMOVE_INSTANCE =>
                                -- Reset
                                current_imf_next    <= (others => '0');
                                inst_data_next      <= ZERO_INSTANCE_DATA;
                                
                                inst_stage_next <= REMOVE_INSTANCE;
                                inst_cnt_next   <= 0;
                            when GET_INSTANCE =>
                                inst_addr_base_next <= inst_addr_update;
                                if (inst_addr_base /= inst_addr_update) then
                                    -- Reset
                                    current_imf_next    <= inst_mem_fields;
                                    inst_data_next      <= ZERO_INSTANCE_DATA;
                                else
                                    current_imf_next    <= current_imf or inst_mem_fields;
                                end if;
                                -- Get Instance Data
                                inst_stage_next     <= GET_INSTANCE_DATA;
                                if check_mask(inst_mem_fields,IMF_KEY_HASH_FLAG) then
                                    inst_cnt_next   <= 0;
                                elsif check_mask(inst_mem_fields,IMF_STATUS_FLAG) then
                                    inst_cnt_next   <= 4;
                                elsif check_mask(inst_mem_fields,IMF_SAMPLE_CNT_FLAG) then
                                    inst_cnt_next   <= 5;
                                elsif check_mask(inst_mem_fields,IMF_DISPOSED_CNT_FLAG) then
                                    inst_cnt_next   <= 6;
                                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,IMF_IGNORE_DEADLINE_FLAG)) then
                                    inst_cnt_next   <= 8;
                                elsif check_mask(inst_mem_fields,IMF_WRITER_BITMAP_FLAG) then
                                    inst_cnt_next   <= 10;
                                    inst_cnt2_next  <= 0;
                                else
                                    -- DONE
                                    inst_stage_next <= IDLE;
                                end if;
                            when UNMARK_INSTANCES =>
                                -- Empty Memory Guard
                                if (inst_occupied_head /= INSTANCE_MEMORY_MAX_ADDRESS) then
                                    -- Reset
                                    inst_data_next      <= ZERO_INSTANCE_DATA;
                                    current_imf_next    <= (others => '0');
                                    
                                    inst_addr_base_next <= inst_occupied_head;
                                    inst_stage_next     <= UNMARK_INSTANCES;
                                    inst_cnt_next       <= 0;
                                end if;
                            when others =>
                                null;
                        end case;
                    end if;
                when SEARCH_INSTANCE_HASH =>
                    
                    case (inst_cnt) is
                        -- GET Next Instance
                        when 0 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_NEXT_ADDR_OFFSET;
                            inst_read       <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- GET Key Hash 1/4
                        when 1 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_KEY_HASH_OFFSET;
                            inst_read       <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- GET Key Hash 2/4
                        when 2 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_KEY_HASH_OFFSET + 1;
                            inst_read       <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- GET Key Hash 3/4
                        when 3 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_KEY_HASH_OFFSET + 2;
                            inst_read       <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- GET Key Hash 4/4
                        when 4 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_KEY_HASH_OFFSET + 3;
                            inst_read       <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- READ Next Instance
                        when 5 =>
                            inst_ready_out  <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_valid_out = '1') then
                                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
                        when 6 =>
                            inst_ready_out  <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_valid_out = '1') then
                                -- No Match
                                if (inst_read_data /= inst_latch_data.key_hash(0)) then
                                    inst_abort_read <= '1';
                                    -- Reached List Tail, No Match
                                    if (inst_next_addr_base = INSTANCE_MEMORY_MAX_ADDRESS) then
                                        inst_addr_base_next   <= INSTANCE_MEMORY_MAX_ADDRESS; --No match
                                        -- DONE
                                        inst_stage_next       <= IDLE;
                                    else
                                        -- Continue Search
                                        inst_prev_addr_base_next    <= inst_addr_base;
                                        inst_addr_base_next         <= inst_next_addr_base;
                                        inst_cnt_next               <= 0;
                                    end if;
                                else
                                    inst_cnt_next   <= inst_cnt + 1;
                                end if;
                            end if;
                        -- READ Key Hash 2/4
                        when 7 =>
                            inst_ready_out  <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_valid_out = '1') then
                                -- No Match
                                if (inst_read_data /= inst_latch_data.key_hash(1)) then
                                    inst_abort_read <= '1';
                                    -- Reached List Tail, No Match
                                    if (inst_next_addr_base = INSTANCE_MEMORY_MAX_ADDRESS) then
                                        inst_addr_base_next   <= INSTANCE_MEMORY_MAX_ADDRESS; --No match
                                        -- DONE
                                        inst_stage_next       <= IDLE;
                                    else
                                        -- Continue Search
                                        inst_prev_addr_base_next    <= inst_addr_base;
                                        inst_addr_base_next         <= inst_next_addr_base;
                                        inst_cnt_next               <= 0;
                                    end if;
                                else
                                    inst_cnt_next   <= inst_cnt + 1;
                                end if;
                            end if;
                        -- READ Key Hash 3/4
                        when 8 =>
                            inst_ready_out  <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_valid_out = '1') then
                                -- No Match
                                if (inst_read_data /= inst_latch_data.key_hash(2)) then
                                    inst_abort_read <= '1';
                                    -- Reached List Tail, No Match
                                    if (inst_next_addr_base = INSTANCE_MEMORY_MAX_ADDRESS) then
                                        inst_addr_base_next   <= INSTANCE_MEMORY_MAX_ADDRESS; --No match
                                        -- DONE
                                        inst_stage_next       <= IDLE;
                                    else
                                        -- Continue Search
                                        inst_prev_addr_base_next    <= inst_addr_base;
                                        inst_addr_base_next         <= inst_next_addr_base;
                                        inst_cnt_next               <= 0;
                                    end if;
                                else
                                    inst_cnt_next   <= inst_cnt + 1;
                                end if;
                            end if;
                        -- READ Key Hash 4/4
                        when 9 =>
                            inst_ready_out  <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_valid_out = '1') then
                                -- No Match
                                if (inst_read_data /= inst_latch_data.key_hash(3)) then
                                    -- Reached List Tail, No Match
                                    if (inst_next_addr_base = INSTANCE_MEMORY_MAX_ADDRESS) then
                                        inst_addr_base_next   <= INSTANCE_MEMORY_MAX_ADDRESS; --No match
                                        -- DONE
                                        inst_stage_next       <= IDLE;
                                    else
                                        -- Continue Search
                                        inst_prev_addr_base_next    <= inst_addr_base;
                                        inst_addr_base_next         <= inst_next_addr_base;
                                        inst_cnt_next               <= 0;
                                    end if;
                                else
                                    -- Get Instance Data
                                    inst_stage_next <= GET_INSTANCE_DATA;
                                    if check_mask(inst_latch_data.field_flags,IMF_KEY_HASH_FLAG) then
                                        inst_cnt_next   <= 0;
                                    elsif check_mask(inst_latch_data.field_flags,IMF_STATUS_FLAG) then
                                        inst_cnt_next   <= 4;
                                    elsif check_mask(inst_latch_data.field_flags,IMF_SAMPLE_CNT_FLAG) then
                                        inst_cnt_next   <= 5;
                                    elsif check_mask(inst_latch_data.field_flags,IMF_DISPOSED_CNT_FLAG) then
                                        inst_cnt_next   <= 6;
                                    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_flags,IMF_IGNORE_DEADLINE_FLAG)) then
                                        inst_cnt_next   <= 8;
                                    elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then
                                        inst_cnt_next   <= 10;
                                        inst_cnt2_next  <= 0;
                                    else
                                        -- DONE
                                        inst_stage_next <= IDLE;
                                    end if;
                                end if;
                            end if;
                        when others =>
                            null;
                    end case;
                when SEARCH_INSTANCE_ADDR =>
                    
                    case (inst_cnt) is
                        -- GET Next Instance
                        when 0 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_NEXT_ADDR_OFFSET;
                            inst_read       <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- READ Next Instance
                        when 1 =>
                            inst_ready_out  <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_valid_out = '1') then
                                inst_prev_addr_base_next  <= inst_addr_base;
                                inst_addr_base_next       <= resize(unsigned(inst_read_data),INSTANCE_MEMORY_ADDR_WIDTH);
                            
                                -- Match
                                if (resize(unsigned(inst_read_data),INSTANCE_MEMORY_ADDR_WIDTH) = inst_latch_data.addr) then
                                    -- Get Instance Data
                                    inst_stage_next <= GET_INSTANCE_DATA;
                                    if check_mask(inst_latch_data.field_flags,IMF_KEY_HASH_FLAG) then
                                        inst_cnt_next   <= 0;
                                    elsif check_mask(inst_latch_data.field_flags,IMF_STATUS_FLAG) then
                                        inst_cnt_next   <= 4;
                                    elsif check_mask(inst_latch_data.field_flags,IMF_SAMPLE_CNT_FLAG) then
                                        inst_cnt_next   <= 5;
                                    elsif check_mask(inst_latch_data.field_flags,IMF_DISPOSED_CNT_FLAG) then
                                        inst_cnt_next   <= 6;
                                    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_flags,IMF_IGNORE_DEADLINE_FLAG)) then
                                        inst_cnt_next   <= 8;
                                    elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then
                                        inst_cnt_next   <= 10;
                                        inst_cnt2_next  <= 0;
                                    else
                                        -- DONE
                                        inst_stage_next <= IDLE;
                                    end if;
                                -- No Match
                                else
                                    -- Reached List Tail, No Match
                                    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;
                                    else
                                        -- Continue Search
                                        inst_cnt_next   <= 0;
                                    end if;
                                end if;
                            end if;
                        when others =>
                            null;
                    end case;
                when GET_NEXT_INSTANCE =>
                    case (inst_cnt) is
                        -- GET next Instance
                        when 0 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_NEXT_ADDR_OFFSET;
                            inst_read       <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- READ Next Instance
                        when 1 =>
                            inst_ready_out  <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_valid_out = '1') then
                                inst_next_addr_base_next    <= resize(unsigned(inst_read_data),INSTANCE_MEMORY_ADDR_WIDTH);
                                -- Get Instance Data
                                inst_stage_next <= GET_INSTANCE_DATA;
                                if check_mask(inst_latch_data.field_flags,IMF_KEY_HASH_FLAG) then
                                    inst_cnt_next   <= 0;
                                elsif check_mask(inst_latch_data.field_flags,IMF_STATUS_FLAG) then
                                    inst_cnt_next   <= 4;
                                elsif check_mask(inst_latch_data.field_flags,IMF_SAMPLE_CNT_FLAG) then
                                    inst_cnt_next   <= 5;
                                elsif check_mask(inst_latch_data.field_flags,IMF_DISPOSED_CNT_FLAG) then
                                    inst_cnt_next   <= 6;
                                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_flags,IMF_IGNORE_DEADLINE_FLAG)) then
                                    inst_cnt_next   <= 8;
                                elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then
                                    inst_cnt_next   <= 10;
                                    inst_cnt2_next  <= 0;
                                else
                                    -- DONE
                                    inst_stage_next <= IDLE;
                                end if;
                            end if;
                        when others =>
                            null;
                    end case;
                when GET_INSTANCE_DATA =>
                    case (inst_cnt) is
                        -- GET Key Hash 1/4
                        when 0 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_KEY_HASH_OFFSET;
                            inst_read       <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- GET Key Hash 2/4
                        when 1 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_KEY_HASH_OFFSET + 1;
                            inst_read       <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- GET Key Hash 3/4
                        when 2 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_KEY_HASH_OFFSET + 2;
                            inst_read       <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- GET Key Hash 4/4
                        when 3 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_KEY_HASH_OFFSET + 3;
                            inst_read       <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                if check_mask(inst_latch_data.field_flags,IMF_STATUS_FLAG) then
                                    inst_cnt_next   <= 4;
                                elsif check_mask(inst_latch_data.field_flags,IMF_SAMPLE_CNT_FLAG) then
                                    inst_cnt_next   <= 5;
                                elsif check_mask(inst_latch_data.field_flags,IMF_DISPOSED_CNT_FLAG) then
                                    inst_cnt_next   <= 6;
                                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_flags,IMF_IGNORE_DEADLINE_FLAG)) then
                                    inst_cnt_next   <= 8;
                                elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then
                                    inst_cnt_next   <= 10;
                                    inst_cnt2_next  <= 0;
                                else
                                    inst_cnt_next   <= 11;
                                end if;
                            end if;
                        -- GET Status Info
                        when 4 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_STATUS_INFO_OFFSET;
                            inst_read       <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') 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_flags,IMF_DISPOSED_CNT_FLAG) then
                                    inst_cnt_next   <= 6;
                                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_flags,IMF_IGNORE_DEADLINE_FLAG)) then
                                    inst_cnt_next   <= 8;
                                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_flags,IMF_KEY_HASH_FLAG) then
                                        inst_cnt_next   <= 11;
                                    else
                                        inst_cnt_next   <= 15;
                                    end if;
                                end if;
                            end if;
                        -- GET Sample Count
                        when 5 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_SAMPLE_CNT_OFFSET;
                            inst_read       <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') 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_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_flags,IMF_IGNORE_DEADLINE_FLAG)) then
                                    inst_cnt_next   <= 8;
                                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_flags,IMF_KEY_HASH_FLAG) then
                                        inst_cnt_next   <= 11;
                                    elsif check_mask(inst_latch_data.field_flags,IMF_STATUS_FLAG) then
                                        inst_cnt_next   <= 15;
                                    else
                                        inst_cnt_next   <= 16;
                                    end if;
                                end if;
                            end if;
                        -- GET Disposed Generation Count
                        when 6 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_DISPOSED_GEN_CNT_OFFSET;
                            inst_read       <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') 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_flags,IMF_IGNORE_DEADLINE_FLAG)) then
                                    inst_cnt_next   <= 8;
                                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_flags,IMF_KEY_HASH_FLAG) then
                                        inst_cnt_next   <= 11;
                                    elsif check_mask(inst_latch_data.field_flags,IMF_STATUS_FLAG) then
                                        inst_cnt_next   <= 15;
                                    elsif check_mask(inst_latch_data.field_flags,IMF_SAMPLE_CNT_FLAG) then
                                        inst_cnt_next   <= 16;
                                    else
                                        inst_cnt_next   <= 17;
                                    end if;
                                end if;
                            end if;
                        -- GET No Writers Generation Count
                        when 7 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_NO_WRITERS_GEN_CNT_OFFSET;
                            inst_read       <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') 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_flags,IMF_WRITER_BITMAP_FLAG) then
                                    inst_cnt_next   <= 10;
                                    inst_cnt2_next  <= 0;
                                else
                                    if check_mask(inst_latch_data.field_flags,IMF_KEY_HASH_FLAG) then
                                        inst_cnt_next   <= 11;
                                    elsif check_mask(inst_latch_data.field_flags,IMF_STATUS_FLAG) then
                                        inst_cnt_next   <= 15;
                                    elsif check_mask(inst_latch_data.field_flags,IMF_SAMPLE_CNT_FLAG) then
                                        inst_cnt_next   <= 16;
                                    elsif check_mask(inst_latch_data.field_flags,IMF_DISPOSED_CNT_FLAG) then
                                        inst_cnt_next   <= 17;
                                    else
                                        inst_cnt_next   <= 18;
                                    end if;
                                end if;
                            end if;
                        -- GET Ignore Deadline 1/2
                        when 8 =>
                            -- Synthesis Guard
                            if (TIME_BASED_FILTER_QOS /= DURATION_ZERO) then
                                inst_valid_in   <= '1';
                                inst_addr       <= inst_addr_base + IMF_IGNORE_DEADLINE_OFFSET;
                                inst_read       <= '1';
                                
                                -- Memory Flow Control Guard
                                if (inst_ready_in = '1') then
                                    inst_cnt_next   <= inst_cnt + 1;
                                end if;
                            end if;
                        -- GET Ignore Deadline 2/2
                        when 9 =>
                            -- 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_read       <= '1';
                                
                                -- Memory Flow Control Guard
                                if (inst_ready_in = '1') 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_flags,IMF_KEY_HASH_FLAG) then
                                            inst_cnt_next   <= 11;
                                        elsif check_mask(inst_latch_data.field_flags,IMF_STATUS_FLAG) then
                                            inst_cnt_next   <= 15;
                                        elsif check_mask(inst_latch_data.field_flags,IMF_SAMPLE_CNT_FLAG) then
                                            inst_cnt_next   <= 16;
                                        elsif check_mask(inst_latch_data.field_flags,IMF_DISPOSED_CNT_FLAG) then
                                            inst_cnt_next   <= 17;
                                        elsif check_mask(inst_latch_data.field_flags,IMF_NO_WRITERS_CNT_FLAG) then
                                            inst_cnt_next   <= 18;
                                        else
                                            inst_cnt_next   <= 19;
                                        end if;
                                    end if;
                                end if;
                            end if;
                        -- GET Writer Bitmap
                        when 10 =>
                            -- XXX: Possible Worst case Path (2 Additions in same clock)
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_IGNORE_DEADLINE_OFFSET + inst_cnt2;
                            inst_read       <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                -- Exit Condition
                                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_flags,IMF_STATUS_FLAG) then
                                        inst_cnt_next   <= 15;
                                    elsif check_mask(inst_latch_data.field_flags,IMF_SAMPLE_CNT_FLAG) then
                                        inst_cnt_next   <= 16;
                                    elsif check_mask(inst_latch_data.field_flags,IMF_DISPOSED_CNT_FLAG) then
                                        inst_cnt_next   <= 17;
                                    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_flags,IMF_IGNORE_DEADLINE_FLAG)) then
                                        inst_cnt_next   <= 19;
                                    else
                                        inst_cnt_next   <= 21;
                                        inst_cnt2_next  <= 0;
                                    end if;
                                else
                                    inst_cnt2_next  <= inst_cnt2 + 1;
                                end if;
                            end if;
                        -- READ Key Hash 1/4
                        when 11 =>
                            inst_ready_out  <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_valid_out = '1') then
                                inst_data_next.key_hash(0)    <= inst_read_data;
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- READ Key Hash 2/4
                        when 12 =>
                            inst_ready_out  <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_valid_out = '1') then
                                inst_data_next.key_hash(1)    <= inst_read_data;
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- READ Key Hash 3/4
                        when 13 =>
                            inst_ready_out  <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_valid_out = '1') then
                                inst_data_next.key_hash(2)    <= inst_read_data;
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- READ Key Hash 4/4
                        when 14 =>
                            inst_ready_out  <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_valid_out = '1') then
                                inst_data_next.key_hash(3)    <= inst_read_data;
                                
                                if check_mask(inst_latch_data.field_flags,IMF_STATUS_FLAG) then
                                    inst_cnt_next   <= 15;
                                elsif check_mask(inst_latch_data.field_flags,IMF_SAMPLE_CNT_FLAG) then
                                    inst_cnt_next   <= 16;
                                elsif check_mask(inst_latch_data.field_flags,IMF_DISPOSED_CNT_FLAG) then
                                    inst_cnt_next   <= 17;
                                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_flags,IMF_IGNORE_DEADLINE_FLAG)) then
                                    inst_cnt_next   <= 19;
                                elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then
                                    inst_cnt_next   <= 21;
                                    inst_cnt2_next  <= 0;
                                else
                                    -- DONE
                                    inst_stage_next <= IDLE;
                                end if;
                            end if;
                        -- READ Status Info
                        when 15 =>
                            inst_ready_out  <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_valid_out = '1') then
                                inst_data_next.status_info    <= inst_read_data;
                                
                                if check_mask(inst_latch_data.field_flags,IMF_SAMPLE_CNT_FLAG) then
                                    inst_cnt_next   <= 16;
                                elsif check_mask(inst_latch_data.field_flags,IMF_DISPOSED_CNT_FLAG) then
                                    inst_cnt_next   <= 17;
                                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_flags,IMF_IGNORE_DEADLINE_FLAG)) then
                                    inst_cnt_next   <= 19;
                                elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then
                                    inst_cnt_next   <= 21;
                                    inst_cnt2_next  <= 0;
                                else
                                    -- DONE
                                    inst_stage_next <= IDLE;
                                end if;
                            end if;
                        -- READ Sample Count
                        when 16 =>
                            inst_ready_out  <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_valid_out = '1') then
                                inst_data_next.sample_cnt <= unsigned(inst_read_data);
                                
                                if check_mask(inst_latch_data.field_flags,IMF_DISPOSED_CNT_FLAG) then
                                    inst_cnt_next   <= 17;
                                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_flags,IMF_IGNORE_DEADLINE_FLAG)) then
                                    inst_cnt_next   <= 19;
                                elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then
                                    inst_cnt_next   <= 21;
                                    inst_cnt2_next  <= 0;
                                else
                                    -- DONE
                                    inst_stage_next <= IDLE;
                                end if;
                            end if;
                        -- READ Disposed Generation Count
                        when 17 =>
                            inst_ready_out  <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_valid_out = '1') then
                                inst_data_next.disposed_gen_cnt   <= unsigned(inst_read_data);
                                
                                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_flags,IMF_IGNORE_DEADLINE_FLAG)) then
                                    inst_cnt_next   <= 19;
                                elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then
                                    inst_cnt_next   <= 21;
                                    inst_cnt2_next  <= 0;
                                else
                                    -- DONE
                                    inst_stage_next <= IDLE;
                                end if;
                            end if;
                        -- READ No Writers Generation Count
                        when 18 =>
                            inst_ready_out  <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_valid_out = '1') then
                                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_flags,IMF_IGNORE_DEADLINE_FLAG)) then
                                    inst_cnt_next   <= 19;
                                elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then
                                    inst_cnt_next   <= 21;
                                    inst_cnt2_next  <= 0;
                                else
                                    -- DONE
                                    inst_stage_next <= IDLE;
                                end if;
                            end if;
                        -- READ Ignore Deadline 1/2
                        when 19 =>
                            inst_ready_out  <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_valid_out = '1') then
                                inst_data_next.ignore_deadline(0) <= unsigned(inst_read_data);
                                
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- READ Ignore Deadline 2/2
                        when 20 =>
                            inst_ready_out  <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_valid_out = '1') then
                                inst_data_next.ignore_deadline(1) <= unsigned(inst_read_data);
                                
                                if check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then
                                    inst_cnt_next   <= 21;
                                    inst_cnt2_next  <= 0;
                                else
                                    -- DONE
                                    inst_stage_next <= IDLE;
                                end if;
                            end if;
                        -- READ Writer Bitamp
                        when 21 =>
                            inst_ready_out  <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_valid_out = '1') then
                                inst_data_next.writer_bitmap(inst_cnt2)   <= inst_read_data;
                                -- Exit Condition
                                if (inst_cnt2 = WRITER_BITMAP_ARRAY_TYPE'length-1) then
                                    -- DONE
                                    inst_stage_next <= IDLE;
                                else
                                    inst_cnt2_next  <= inst_cnt2 + 1;
                                end if;
                            end if;
                    end case;
                when FIND_POS =>
                    -- NOTE: Instances are inserted in KEY_HASH numerical order.
                    
                    case (inst_cnt) is
                        -- GET Next Instance
                        when 0 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_NEXT_ADDR_OFFSET;
                            inst_read       <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- GET Key Hash 1/4
                        when 1 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_KEY_HASH_OFFSET;
                            inst_read       <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- GET Key Hash 2/4
                        when 2 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_KEY_HASH_OFFSET + 1;
                            inst_read       <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- GET Key Hash 3/4
                        when 3 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_KEY_HASH_OFFSET + 2;
                            inst_read       <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- GET Key Hash 4/4
                        when 4 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_KEY_HASH_OFFSET + 3;
                            inst_read       <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- READ Next Instance
                        when 5 =>
                            inst_ready_out  <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_valid_out = '1') then
                                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
                        when 6 =>
                            inst_ready_out  <= '1';
                            
                            -- 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) severity FAILURE;
                                        inst_occupied_head_next <= inst_empty_head;
                                        
                                        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_empty_head;
                                        inst_stage_next         <= INSERT_INSTANCE;
                                        inst_cnt_next           <= 0;
                                    end if;
                                -- BIGGER-THAN
                                elsif (inst_latch_data.key_hash(0) /= inst_read_data) then
                                    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
                        when 7 =>
                            inst_ready_out  <= '1';
                            
                            -- 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) severity FAILURE;
                                        inst_occupied_head_next <= inst_empty_head;
                                        
                                        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_empty_head;
                                        inst_stage_next         <= INSERT_INSTANCE;
                                        inst_cnt_next           <= 0;
                                    end if;
                                -- BIGGER-THAN
                                elsif (inst_latch_data.key_hash(1) /= inst_read_data) then
                                    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
                        when 8 =>
                            inst_ready_out  <= '1';
                            
                            -- 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) severity FAILURE;
                                        inst_occupied_head_next <= inst_empty_head;
                                        
                                        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_empty_head;
                                        inst_stage_next         <= INSERT_INSTANCE;
                                        inst_cnt_next           <= 0;
                                    end if;
                                -- BIGGER-THAN
                                elsif (inst_latch_data.key_hash(2) /= inst_read_data) then
                                    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 9 =>
                            inst_ready_out  <= '1';
                            
                            -- 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(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) severity FAILURE;
                                        inst_occupied_head_next <= inst_empty_head;
                                        
                                        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_empty_head;
                                        inst_stage_next         <= INSERT_INSTANCE;
                                        inst_cnt_next           <= 0;
                                    end if;
                                else
                                    assert (inst_latch_data.key_hash(3) /= inst_read_data) report "Duplicate Instance Detected" severity FAILURE;
                                    
                                    -- 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 (Only if first Step executed), inst_next_addr_base set
                    
                    case (inst_cnt) is
                        -- SET 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';
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- SET Next Pointer (New Instance)
                        when 2 =>
                            inst_valid_in   <= '1';
                            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 3 =>
                            inst_ready_out  <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_valid_out = '1') then
                                -- Fix Empty List Head
                                inst_empty_head_next    <= resize(unsigned(inst_read_data),INSTANCE_MEMORY_ADDR_WIDTH);
                                
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- Key Hash 1/4
                        when 4 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_KEY_HASH_OFFSET;
                            inst_write_data <= inst_latch_data.key_hash(0);
                            inst_data_next.key_hash(0)  <= inst_latch_data.key_hash(0);
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- Key Hash 2/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);
                            inst_data_next.key_hash(1)  <= inst_latch_data.key_hash(1);
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- Key Hash 3/4
                        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);
                            inst_data_next.key_hash(2)  <= inst_latch_data.key_hash(2);
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- Key Hash 4/4
                        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);
                            inst_data_next.key_hash(3)  <= inst_latch_data.key_hash(3);
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- Status Info
                        when 8 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_STATUS_INFO_OFFSET;
                            inst_write_data <= inst_latch_data.status_info;
                            inst_data_next.status_info  <= inst_latch_data.status_info;
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- Sample Count
                        when 9 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_SAMPLE_CNT_OFFSET;
                            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
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- Disposed Generation Count
                        when 10 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_DISPOSED_GEN_CNT_OFFSET;
                            inst_write_data <= (others => '0');
                            inst_data_next.disposed_gen_cnt <= (others => '0');
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- No Writers Generation Count
                        when 11 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_NO_WRITERS_GEN_CNT_OFFSET;
                            inst_write_data <= (others => '0');
                            inst_data_next.no_writers_gen_cnt   <= (others => '0');
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                if (TIME_BASED_FILTER_QOS /= DURATION_ZERO) then
                                    inst_cnt_next   <= inst_cnt + 1;
                                else
                                    inst_cnt_next   <= inst_cnt + 3;
                                    inst_cnt2_next  <= 0;
                                end if;
                            end if;
                            
                        -- Ignore Deadline 1/2
                        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 <= 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;
                                end if;
                            end if;
                        -- Ignore Deadline 2/2
                        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 <= 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
                                    inst_cnt_next   <= inst_cnt + 1;
                                    inst_cnt2_next  <= 0;
                                end if;
                            end if;
                        -- Writer Bitmap
                        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;
                            inst_write_data <= inst_latch_data.writer_bitmap(inst_cnt2);
                            inst_data_next.writer_bitmap    <= inst_latch_data.writer_bitmap;
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                -- Exit Condition
                                if (inst_cnt2 = WRITER_BITMAP_ARRAY_TYPE'length-1) then
                                    -- DONE
                                    inst_stage_next <= IDLE;
                                else
                                    inst_cnt2_next  <= inst_cnt2 + 1;
                                end if;
                            end if;
                        when others => 
                            null;
                    end case;
                when UPDATE_INSTANCE =>
                    case (inst_cnt) is
                        -- Status Info
                        when 0 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_STATUS_INFO_OFFSET;
                            inst_write_data <= inst_latch_data.status_info;
                            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_flags,IMF_SAMPLE_CNT_FLAG) then
                                    inst_cnt_next   <= 1;
                                elsif check_mask(inst_latch_data.field_flags,IMF_DISPOSED_CNT_FLAG) then
                                    inst_cnt_next   <= 2;
                                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_flags,IMF_IGNORE_DEADLINE_FLAG)) then
                                    inst_cnt_next   <= 4;
                                elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then
                                    inst_cnt_next   <= 6;
                                    inst_cnt2_next  <= 0;
                                else
                                    -- DONE
                                    inst_stage_next <= IDLE;
                                end if;
                            end if;
                        -- Sample Count
                        when 1 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_SAMPLE_CNT_OFFSET;
                            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_flags,IMF_DISPOSED_CNT_FLAG) then
                                    inst_cnt_next   <= 2;
                                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_flags,IMF_IGNORE_DEADLINE_FLAG)) then
                                    inst_cnt_next   <= 4;
                                elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then
                                    inst_cnt_next   <= 6;
                                    inst_cnt2_next  <= 0;
                                else
                                    -- DONE
                                    inst_stage_next <= IDLE;
                                end if;
                            end if;
                        -- Disposed Generation Count
                        when 2 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_DISPOSED_GEN_CNT_OFFSET;
                            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_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_flags,IMF_IGNORE_DEADLINE_FLAG)) then
                                    inst_cnt_next   <= 4;
                                elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then
                                    inst_cnt_next   <= 6;
                                    inst_cnt2_next  <= 0;
                                else
                                    -- DONE
                                    inst_stage_next <= IDLE;
                                end if;
                            end if;
                        -- No Writers Generation Count
                        when 3 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_NO_WRITERS_GEN_CNT_OFFSET;
                            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_flags,IMF_IGNORE_DEADLINE_FLAG)) then
                                    inst_cnt_next   <= 4;
                                elsif check_mask(inst_latch_data.field_flags,IMF_WRITER_BITMAP_FLAG) then
                                    inst_cnt_next   <= 6;
                                    inst_cnt2_next  <= 0;
                                else
                                    -- DONE
                                    inst_stage_next <= IDLE;
                                end if;
                            end if;
                        -- Ignore Deadline 1/2
                        when 4 =>
                            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.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;
                                end if;
                            end if;
                        -- Ignore Deadline 2/2
                        when 5 =>
                            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.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_flags,IMF_WRITER_BITMAP_FLAG) then
                                        inst_cnt_next   <= 6;
                                        inst_cnt2_next  <= 0;
                                    else
                                        -- DONE
                                        inst_stage_next <= IDLE;
                                    end if;
                                end if;
                            end if;
                        -- Writer Bitmap
                        when 6 =>
                            -- 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;
                            inst_write_data <= inst_latch_data.writer_bitmap(inst_cnt2);
                            inst_data_next.writer_bitmap    <= inst_latch_data.writer_bitmap;
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                -- Exit Condition
                                if (inst_cnt2 = WRITER_BITMAP_ARRAY_TYPE'length-1) then
                                    -- DONE
                                    inst_stage_next <= IDLE;
                                else
                                    inst_cnt2_next  <= inst_cnt2 + 1;
                                end if;
                            end if;
                        when others =>
                            null;
                    end case;
                when REMOVE_INSTANCE =>
                    -- Precondition: inst_addr_base set, inst_prev_addr_base set
                    
                    case (inst_cnt) is
                        -- GET Next Instance
                        when 0 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_NEXT_ADDR_OFFSET;
                            inst_read       <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- READ Next Instance
                        when 1 =>
                            inst_ready_out  <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_valid_out = '1') then
                                inst_next_addr_base_next    <= resize(unsigned(inst_read_data),INSTANCE_MEMORY_ADDR_WIDTH);
                                
                                -- Removed Instance is List Head
                                if (inst_prev_addr_base = INSTANCE_MEMORY_MAX_ADDRESS) then
                                    assert (inst_addr_base = inst_occupied_head) severity FAILURE;
                                    
                                    -- Fix Occupied Head
                                    inst_occupied_head_next <= resize(unsigned(inst_read_data),INSTANCE_MEMORY_ADDR_WIDTH);
                                    
                                    inst_cnt_next   <= inst_cnt + 2; -- Skip Next Step
                                else
                                    inst_cnt_next   <= inst_cnt + 1;
                                end if;
                            end if;
                        -- SET Next Pointer (Previous Instance)
                        when 2 =>
                            -- 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 <= 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;
                        -- SET Next Pointer (Current/Removed Instance)
                        when 3 =>
                            -- 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 <= std_logic_vector(resize(inst_empty_head,WORD_WIDTH));
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                -- Fix Empty List Head
                                inst_empty_head_next    <= inst_addr_base;
                                
                                -- Reset
                                inst_addr_base_next <= INSTANCE_MEMORY_MAX_ADDRESS;
                                
                                -- DONE
                                inst_stage_next     <= IDLE;
                            end if;
                        when others =>
                            null;
                    end case;
                when UNMARK_INSTANCES =>
                    -- Precondition: inst_addr_base set
                    
                    case (inst_cnt) is
                        -- GET Next Instance
                        when 0 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_NEXT_ADDR_OFFSET;
                            inst_read       <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- GET Status Info
                        when 1 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_STATUS_INFO_OFFSET;
                            inst_read       <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                inst_cnt_next   <= inst_cnt + 1;
                            end if;
                        -- READ Next Instance
                        when 2 =>
                            inst_ready_out  <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_valid_out = '1') then
                                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
                        when 3 =>
                            inst_ready_out  <= '1';
                            
                            -- Memory Flow Control Guard
                            if (inst_valid_out = '1') then
                                -- MARK Flag Set
                                if (inst_read_data(ISI_MARK_FLAG) = '1') then
                                    -- Latch Status Info (With MARK removed)
                                    inst_long_latch_next    <= inst_read_data;
                                    inst_long_latch_next(ISI_MARK_FLAG) <= '0';
                                    inst_cnt_next   <= inst_cnt + 1;
                                else
                                    -- End of Instances
                                    if (inst_next_addr_base = INSTANCE_MEMORY_MAX_ADDRESS) then
                                        -- DONE
                                        inst_stage_next <= IDLE;
                                    else
                                        -- Continue
                                        inst_addr_base_next <= inst_next_addr_base;
                                        inst_cnt_next       <= 0;
                                    end if;
                                end if;
                            end if;
                        -- Status Info
                        when 4 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_STATUS_INFO_OFFSET;
                            inst_write_data <= inst_long_latch;
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                -- End of Instances
                                if (inst_next_addr_base = INSTANCE_MEMORY_MAX_ADDRESS) then
                                    -- DONE
                                    inst_stage_next <= IDLE;
                                else
                                    -- Continue
                                    inst_addr_base_next <= inst_next_addr_base;
                                    inst_cnt_next       <= 0;
                                end if;
                            end if;
                        when others =>
                            null;
                    end case;
                when RESET_MEMORY =>
                    case (inst_cnt) is
                        -- Initialize
                        when 0 =>
                            inst_addr_base_next <= FIRST_INSTANCE_ADDRESS;
                            inst_cnt_next       <= inst_cnt + 1;
                        -- Set Next Pointer
                        when 1 =>
                            inst_valid_in   <= '1';
                            inst_addr       <= inst_addr_base + IMF_NEXT_ADDR_OFFSET;
                            if (inst_addr_base = MAX_INSTANCE_ADDRESS) then
                                inst_write_data <= std_logic_vector(resize(INSTANCE_MEMORY_MAX_ADDRESS,WORD_WIDTH));
                            else
                                inst_write_data <= std_logic_vector(resize(inst_addr_base + INSTANCE_FRAME_SIZE,WORD_WIDTH));
                            end if;
                            
                            -- Memory Flow Control Guard
                            if (inst_ready_in = '1') then
                                if (inst_addr_base = MAX_INSTANCE_ADDRESS) then
                                    -- DONE
                                    inst_stage_next <= IDLE;
                                else
                                    inst_addr_base_next <= inst_addr_base + INSTANCE_FRAME_SIZE;
                                end if;
                            end if;
                        when others =>
                            null;
                    end case;
                when others =>
                    null;
            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;
                empty_sample_list_head              <= FIRST_SAMPLE_ADDRESS;
                empty_sample_list_tail              <= MAX_SAMPLE_ADDRESS;
                empty_payload_list_head             <= FIRST_PAYLOAD_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;
                rtps_return_code_latch              <= ERROR;
                dds_return_code_latch               <= RETCODE_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';
                current_imf                         <= (others => '0');
                sample_addr_latch_1                 <= (others => '0');
                sample_addr_latch_2                 <= (others => '0');
                sample_addr_latch_3                 <= (others => '0');
                sample_addr_latch_4                 <= (others => '0');
                sample_addr_latch_5                 <= (others => '0');
                payload_addr_latch_1                <= (others => '0');
                payload_addr_latch_2                <= (others => '0');
                inst_addr_latch_1                   <= (others => '0');
                inst_addr_latch_2                   <= (others => '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_rank_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;
                empty_sample_list_head              <= empty_sample_list_head_next;
                empty_sample_list_tail              <= empty_sample_list_tail_next;
                empty_payload_list_head             <= empty_payload_list_head_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;
                rtps_return_code_latch              <= rtps_return_code_latch_next;
                dds_return_code_latch               <= dds_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_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_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;
                current_imf                         <= current_imf_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;
                sample_addr_latch_5                 <= sample_addr_latch_5_next;
                payload_addr_latch_1                <= payload_addr_latch_1_next;
                payload_addr_latch_2                <= payload_addr_latch_2_next;
                inst_addr_latch_1                   <= inst_addr_latch_1_next;
                inst_addr_latch_2                   <= inst_addr_latch_2_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_rank_sig     <= si_absolute_generation_rank_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;