library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library osvvm; -- Utility Library
context osvvm.OsvvmContext;

use work.rtps_package.all;
use work.user_config.all;
use work.rtps_config_package.all;
use work.rtps_test_package.all;

-- This testbench tests the DDS handling of the DDS Reader. It tests the correctness of the DDS READ, TAKE, READ_NEXT_SAMPLE, TAKE_NEXT_SAMPLE, 
-- READ_INSTANCE, TAKE_INSTANCE, READ_NEXT_INSTANCE, TAKE_NEXT_INSTANCE Operations.
-- More specifically the testbench covers following tests:
-- TEST: READ [NO COMPATIBLE SAMPLES]
-- TEST: READ [NO SAMPLES]
-- TEST: READ [MAX_SAMPLES < SAMPLES]
-- TEST: READ [MAX_SAMPLES > SAMPLES]
-- TEST: TAKE [NO SAMPLES]
-- TEST: TAKE
-- TEST: READ [ANY SSTATE, ANY ISTATE, ANY VIEW]
-- TEST: READ [ANY SSTATE, ANY ISTATE, SPECIFIED VIEW]
-- TEST: READ [ANY SSTATE, SPECIFIED ISTATE, ANY VIEW]
-- TEST: READ [ANY SSTATE, SPECIFIED ISTATE, SPECIFIED VIEW]
-- TEST: READ [SPECIFIED SSTATE, ANY ISTATE, ANY VIEW]
-- TEST: READ [SPECIFIED SSTATE, ANY ISTATE, SPECIFIED VIEW]
-- TEST: READ [SPECIFIED SSTATE, SPECIFIED ISTATE, ANY VIEW]
-- TEST: READ [SPECIFIED SSTATE, SPECIFIED ISTATE, SPECIFIED VIEW]
-- TEST: READ_NEXT_SAMPLE [WITH UNREAD SAMPLE]
-- TEST: READ_NEXT_SAMPLE [WITHOUT UNREAD SAMPLE]
-- TEST: READ_NEXT_SAMPLE [NO SAMPLE]
-- TEST: TAKE_NEXT_SAMPLE [NO SAMPLE]
-- TEST: TAKE_NEXT_SAMPLE
-- TEST: READ_INSTANCE [UNKNOWN INSTANCE]
-- TEST: READ_INSTANCE [KNOWN INSTANCE, UNCOMPATIBLE SAMPLES]
-- TEST: READ_INSTANCE [KNOWN INSTANCE, COMPATIBLE SAMPLES]
-- TEST: READ_INSTANCE [NO SAMPLES]
-- TEST: TAKE_INSTANCE [NO SAMPLES]
-- TEST: TAKE_INSTANCE
-- TEST: READ_NEXT_INSTANCE [WITH SAMPLES, WITHOUT NEXT INSTANCE]
-- TEST: READ_NEXT_INSTANCE [WITH NEXT INSTANCE, UNCOMPATIBLE SAMPLES]
-- TEST: READ_NEXT_INSTANCE [WITH NEXT INSTANCE, COMPATIBLE SAMPLES]
-- TEST: READ_NEXT_INSTANCE [HANDLE_NIL]
-- TEST: READ_NEXT_INSTANCE [WITH NEXT INSTANCE, WITH COMPATIBLE SAMPLE, NOT DIRECT NEXT INSTANCE]
-- TEST: READ_NEXT_INSTANCE [NO SAMPLE]
-- TEST: TAKE_NEXT_INSTANCE [NO SAMPLE]
-- TEST: TAKE_NEXT_INSTANCE
-- TEST: GET ALL DATA WITH READ_NEXT_INSTANCE
-- TEST: READ MARKS SAMPLES AS READ
-- TEST: TAKE REMOVES SAMPLE
-- TEST: READ MODIFIES VIEW STATE [READ PREVIOUS GENERATION]
-- TEST: READ MODIFIES VIEW STATE [READ CURRENT GENERATION]
-- TEST: OUT OF ORDER SAMPLE AFTER DISPOSE

entity L0_dds_reader_test3_arzksto is
end entity;


architecture testbench of L0_dds_reader_test3_arzksto is
    
    -- *CONSTANT DECLARATION*
    constant MAX_REMOTE_ENDPOINTS   : natural := 3;
    
    -- *TYPE DECLARATION*
    type DDS_STAGE_TYPE is (IDLE, START, DONE, CHECK_SI, CHECK_DATA, WAIT_EOC);
    type RTPS_STAGE_TYPE is (IDLE, START, PUSH, DONE);
    
    -- *SIGNAL DECLARATION*
    signal clk : std_logic := '0';
    signal reset : std_logic := '1';
    signal check_time : TIME_TYPE := TIME_ZERO;
    signal start_rtps, start_dds, ack_rtps, ack_dds, done_rtps, done_dds : std_logic := '0';
    signal opcode_rtps : HISTORY_CACHE_OPCODE_TYPE := NOP;
    signal opcode_dds : DDS_READER_OPCODE_TYPE := NOP;
    signal ret_rtps : HISTORY_CACHE_RESPONSE_TYPE := ERROR;
    signal ready_in_rtps, valid_in_rtps, last_word_in_rtps : std_logic := '0';
    signal ready_out_dds, valid_out_dds, last_word_out_dds : std_logic := '0';
    signal data_in_rtps, data_out_dds : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0');
    signal get_data_dds, si_valid_data, si_valid, eoc : std_logic := '0';
    signal return_code_dds : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0) := (others => '0');
    signal status : std_logic_vector(STATUS_KIND_WIDTH-1 downto 0) := (others => '0');
    signal instance_state_dds, si_instance_state : std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0) := ANY_INSTANCE_STATE;
    signal view_state_dds, si_view_state : std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0) := ANY_VIEW_STATE;
    signal sample_state_dds, si_sample_state : std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0) := ANY_SAMPLE_STATE;
    signal instance_handle_dds, si_instance_handle : INSTANCE_HANDLE_TYPE := HANDLE_NIL;
    signal max_samples_dds : std_logic_vector(MAX_SAMPLES_WIDTH-1 downto 0) := (others => '0');
    signal si_source_timestamp : TIME_TYPE := TIME_INVALID;
    signal si_publication_handle : INSTANCE_HANDLE_TYPE := HANDLE_NIL;
    signal si_disposed_generation_count : std_logic_vector(DISPOSED_GENERATION_COUNT_WIDTH-1 downto 0) := (others => '0');
    signal si_no_writers_generation_count : std_logic_vector(NO_WRITERS_GENERATION_COUNT_WIDTH-1 downto 0) := (others => '0');
    signal si_sample_rank : std_logic_vector(SAMPLE_RANK_WIDTH-1 downto 0) := (others => '0');
    signal si_generation_rank : std_logic_vector(GENERATION_RANK_WIDTH-1 downto 0) := (others => '0');
    signal si_absolute_generation_rank: std_logic_vector(ABSOLUTE_GENERATION_COUNT_WIDTH-1 downto 0) := (others => '0');
    
    signal dds_start , dds_done , rtps_start, rtps_done : std_logic := '0';
    signal dds_cnt, dds_cnt2, rtps_cnt : natural := 0;
    signal dds_stage  : DDS_STAGE_TYPE := IDLE;
    signal rtps_stage : RTPS_STAGE_TYPE := IDLE;
    shared variable dds : DDS_READER_TEST_TYPE := DEFAULT_DDS_READER_TEST;
    shared variable rtps : RTPS_READER_TEST_TYPE := DEFAULT_RTPS_READER_TEST;
    shared variable mem : DDS_READER_MEM_TYPE := DEFAULT_DDS_READER_MEM;
    signal data_id, ret_id, sstate_id, vstate_id, istate_id, inst_id, ts_id, pub_id, dis_gen_cnt_id, no_w_gen_cnt_id, srank_id, grank_id, agrank_id, eoc_id, valid_id : AlertLogIDType;
    
    -- *FUNCTION DECLARATION*
    function extract_key_hash (payload : TEST_PACKET_TYPE) return INSTANCE_HANDLE_TYPE is
        variable ret : INSTANCE_HANDLE_TYPE := HANDLE_NIL;
    begin
        for i in 0 to 3 loop
            ret(i) := not payload.data(i);
        end loop;
        
        return ret;
    end function;
    
    function gen_sn(input : natural) return SEQUENCENUMBER_TYPE is
        variable ret : SEQUENCENUMBER_TYPE;
    begin
        ret(0)  := (others => '0');
        ret(1)  := unsigned(int(input, WORD_WIDTH));
        return ret;
    end function;
    
begin

    -- Unit Under Test
    uut : entity work.dds_reader(arch)
        generic map (
            TIME_BASED_FILTER_QOS       => DURATION_ZERO,
            DEADLINE_QOS                => DURATION_INFINITE,
            MAX_SAMPLES                 => std_logic_vector(to_unsigned(15,CDR_LONG_WIDTH)),
            MAX_INSTANCES               => std_logic_vector(to_unsigned(4,CDR_LONG_WIDTH)),
            MAX_SAMPLES_PER_INSTANCE    => std_logic_vector(to_unsigned(15,CDR_LONG_WIDTH)),
            HISTORY_QOS                 => KEEP_ALL_HISTORY_QOS,
            RELIABILITY_QOS             => RELIABLE_RELIABILITY_QOS,
            PRESENTATION_QOS            => TOPIC_PRESENTATION_QOS,
            DESTINATION_ORDER_QOS       => BY_SOURCE_TIMESTAMP_DESTINATION_ORDER_QOS,
            COHERENT_ACCESS             => FALSE,
            ORDERED_ACCESS              => TRUE,
            WITH_KEY                    => TRUE,
            PAYLOAD_FRAME_SIZE          => 11,
            MAX_REMOTE_ENDPOINTS        => MAX_REMOTE_ENDPOINTS
        )
        port map (
            clk                                     => clk,
            reset                                   => reset,
            time                                    => check_time,
            start_rtps                              => start_rtps,
            opcode_rtps                             => opcode_rtps,
            ack_rtps                                => ack_rtps,
            done_rtps                               => done_rtps,
            ret_rtps                                => ret_rtps,
            data_in_rtps                            => data_in_rtps,
            valid_in_rtps                           => valid_in_rtps,
            ready_in_rtps                           => ready_in_rtps,
            last_word_in_rtps                       => last_word_in_rtps,
            start_dds                               => start_dds,
            ack_dds                                 => ack_dds,
            opcode_dds                              => opcode_dds,
            instance_state_dds                      => instance_state_dds,
            view_state_dds                          => view_state_dds,
            sample_state_dds                        => sample_state_dds,
            instance_handle_dds                     => instance_handle_dds,
            max_samples_dds                         => max_samples_dds,
            get_data_dds                            => get_data_dds,
            done_dds                                => done_dds,
            return_code_dds                         => return_code_dds,
            ready_out_dds                           => ready_out_dds,
            valid_out_dds                           => valid_out_dds,
            data_out_dds                            => data_out_dds,
            last_word_out_dds                       => last_word_out_dds,
            sample_info.sample_state                => si_sample_state,
            sample_info.view_state                  => si_view_state,
            sample_info.instance_state              => si_instance_state,
            sample_info.source_timestamp            => si_source_timestamp,
            sample_info.instance_handle             => si_instance_handle,
            sample_info.publication_handle          => si_publication_handle,
            sample_info.disposed_generation_count   => si_disposed_generation_count,
            sample_info.no_writers_generation_count => si_no_writers_generation_count,
            sample_info.sample_rank                 => si_sample_rank,
            sample_info.generation_rank             => si_generation_rank,
            sample_info.absolute_generation_rank    => si_absolute_generation_rank,
            sample_info.valid_data                  => si_valid_data,
            sample_info_valid                       => si_valid,
            sample_info_ack                         => '1',
            eoc                                     => eoc,
            status                                  => status
        );
    
    stimulus_prc : process
        variable RV : RandomPType;
        variable cc : CACHE_CHANGE_TYPE := DEFAULT_CACHE_CHANGE;
        variable s  : SAMPLE_TYPE := DEFAULT_SAMPLE;
        variable kh1, kh2, kh3, kh4, kh5 : INSTANCE_HANDLE_TYPE := HANDLE_NIL;
        
        alias idle_sig is <<signal uut.idle_sig : std_logic>>;
        
        impure function gen_payload(key_hash : INSTANCE_HANDLE_TYPE; len : natural) return TEST_PACKET_TYPE is
            variable ret : TEST_PACKET_TYPE := EMPTY_TEST_PACKET;
        begin
            assert (len >= 4) report "Payload length has to be at least 16 Bytes long" severity FAILURE;
            
            for i in 0 to len-1 loop
                if (i < 4) then
                    -- NOTE: Beginning of payload is negated key to allow deterministic Key Hash generation from the kh_prc
                    ret.data(ret.length) := not key_hash(i);
                else
                    ret.data(ret.length) := RV.RandSlv(WORD_WIDTH);
                end if;
                ret.length  := ret.length + 1;
            end loop;
            ret.last(ret.length-1)  := '1';
            
            return ret;
        end function;
        
        impure function gen_key_hash return KEY_HASH_TYPE is
            variable ret : KEY_HASH_TYPE := KEY_HASH_NIL;
        begin
            for i in 0 to KEY_HASH_TYPE'length-1 loop
                ret(i) := RV.RandSlv(WORD_WIDTH);
            end loop;
            return ret;
        end function;
        
        procedure start_dds is
        begin
            dds_start   <= '1';
            wait until rising_edge(clk);
            dds_start   <= '0';
            wait until rising_edge(clk);
        end procedure;
        
        procedure start_rtps is
        begin
            rtps_start   <= '1';
            wait until rising_edge(clk);
            rtps_start   <= '0';
            wait until rising_edge(clk);
        end procedure;
        
        procedure wait_on_dds is
        begin
            if (dds_done  /= '1') then
                wait until dds_done  = '1';
            end if;
        end procedure;
        
        procedure wait_on_rtps is
        begin
            if (rtps_done /= '1') then
                wait until rtps_done = '1';
            end if;
        end procedure;
        
        procedure wait_on_completion is
        begin
            if (rtps_done /= '1' or dds_done  /= '1') then
                wait until rtps_done = '1' and dds_done  = '1';
            end if;
        end procedure;
        
        -- NOTE: This procedure waits until the idle_sig is high for at least
        --       two consecutive clock cycles.
        procedure wait_on_idle is
            variable first : boolean := TRUE;
        begin
            loop
                if (idle_sig /= '1') then
                    wait until idle_sig = '1';
                elsif (not first) then
                    exit;
                end if;
                wait until rising_edge(clk);
                wait until rising_edge(clk);
                first := FALSE;
            end loop;
        end procedure;
        
    begin
        
        SetAlertLogName("L0_dds_reader_test3_arzksto - (KEEP ALL, Reliable, Zero TIME_BASED_FILTER, Keyed, BY_SOURCE_TIMESTAMP_DESTINATION_ORDER_QOS, ACCESS SCOPE Topic, Ordered) - DDS Handling");
        SetAlertEnable(FAILURE, TRUE);
        SetAlertEnable(ERROR, TRUE);
        SetAlertEnable(WARNING, TRUE);
        SetLogEnable(DEBUG, TRUE);
        SetLogEnable(PASSED, FALSE);
        SetLogEnable(INFO, TRUE);
        RV.InitSeed(RV'instance_name);
        sstate_id       <= GetAlertLogID("Sample State", ALERTLOG_BASE_ID);
        vstate_id       <= GetAlertLogID("View State", ALERTLOG_BASE_ID);
        istate_id       <= GetAlertLogID("Instance State", ALERTLOG_BASE_ID);
        ts_id           <= GetAlertLogID("Source Timestamp", ALERTLOG_BASE_ID);
        inst_id         <= GetAlertLogID("Instance Handle", ALERTLOG_BASE_ID);
        pub_id          <= GetAlertLogID("Publication Hanlde", ALERTLOG_BASE_ID);
        dis_gen_cnt_id  <= GetAlertLogID("Disposed Generation Count", ALERTLOG_BASE_ID);
        no_w_gen_cnt_id <= GetAlertLogID("No Writers Generation Count", ALERTLOG_BASE_ID);
        srank_id        <= GetAlertLogID("Sample Rank", ALERTLOG_BASE_ID);
        grank_id        <= GetAlertLogID("Generation Rank", ALERTLOG_BASE_ID);
        agrank_id       <= GetAlertLogID("Absolute Generation Rank", ALERTLOG_BASE_ID);
        eoc_id          <= GetAlertLogID("End Of Collection", ALERTLOG_BASE_ID);
        valid_id        <= GetAlertLogID("Valid Data", ALERTLOG_BASE_ID);
        data_id         <= GetAlertLogID("Data Out", ALERTLOG_BASE_ID);
        ret_id          <= GetAlertLogID("Return Code", ALERTLOG_BASE_ID);
        
        -- Key Hashes
        kh1 := (x"F12C31DA", x"E3FE0F3F", x"01F36685", x"446518CA");
        kh2 := (x"BC070AC4", x"0BAB5811", x"14EA8D61", x"F669189B");
        kh3 := (x"0CEAB0C6", x"FA04B9AD", x"A96EB495", x"4E0EB999");
        kh4 := (x"A7EB605C", x"FF4BEF3A", x"3C5E8724", x"CCA0CA67");
        kh5 := gen_key_hash;
        
        
        Log("Initiating Test", INFO);
        Log("Current Time: 0s", INFO);
        check_time  <= TIME_ZERO;
        reset       <= '1';
        wait until rising_edge(clk);
        wait until rising_edge(clk);
        reset   <= '0';
        -- MEM: -
        -- ISTATE: -
        -- VIEW: -
        -- WRITER: -
        
        cc                  := DEFAULT_CACHE_CHANGE;
        cc.serialized_key   := TRUE;
        cc.kind             := NOT_ALIVE_DISPOSED;
        cc.instance         := kh4;
        cc.payload          := gen_payload(kh4,5);
        cc.src_timestamp    := gen_duration(7,0);
        
        Log("RTPS Operation ADD_CACHE_CHANGE [DISPOSE, Instance 4, Writer 2, ID 7] (ACCEPTED)", INFO);
        rtps            := DEFAULT_RTPS_READER_TEST;
        rtps.opcode     := ADD_CACHE_CHANGE;
        rtps.cc         := cc;
        rtps.writer_pos := 2;
        rtps.ret_code   := OK;
        s               := to_sample(cc,NOT_ALIVE_DISPOSED_INSTANCE_STATE);
        add_sample(s,mem, BY_SOURCE_TIMESTAMP_DESTINATION_ORDER_QOS);
        start_rtps;
        wait_on_rtps;
        wait_on_idle;
        -- MEM: I4S2-(7)
        -- ISTATE: I4:DISOSED
        -- VIEW: I4:NEW
        -- WRITER: W2:I4
        
        Log("Current Time: 1s", INFO);
        check_time  <= gen_duration(1,0);
        wait until rising_edge(clk);
        wait until rising_edge(clk);
        wait_on_idle;
        
        cc                  := DEFAULT_CACHE_CHANGE;
        cc.serialized_key   := FALSE;
        cc.kind             := ALIVE;
        cc.instance         := kh1;
        cc.payload          := gen_payload(kh1,10);
        cc.src_timestamp    := gen_duration(0,0);
        
        Log("RTPS Operation ADD_CACHE_CHANGE [KEY_HASH, Instance 1, Writer 0, Aligned Payload, ID 0] (ACCEPTED)", INFO);
        rtps            := DEFAULT_RTPS_READER_TEST;
        rtps.opcode     := ADD_CACHE_CHANGE;
        rtps.cc         := cc;
        rtps.writer_pos := 0;
        rtps.ret_code   := OK;
        s               := to_sample(cc,ALIVE_INSTANCE_STATE);
        add_sample(s,mem, BY_SOURCE_TIMESTAMP_DESTINATION_ORDER_QOS);
        start_rtps;
        wait_on_rtps;
        wait_on_idle;
        -- MEM: I1S1(0), I4S2-(7)
        -- ISTATE: I1:ALIVE, I4:DISOSED
        -- VIEW: I1:NEW, I4:NEW
        -- WRITER: W0:I1, W2:I4
        
        Log("Current Time: 2s", INFO);
        check_time  <= gen_duration(2,0);
        wait until rising_edge(clk);
        wait until rising_edge(clk);
        wait_on_idle;
        
        cc                  := DEFAULT_CACHE_CHANGE;
        cc.serialized_key   := TRUE;
        cc.kind             := NOT_ALIVE_DISPOSED;
        cc.instance         := kh1;
        cc.payload          := gen_payload(kh1,5);
        cc.src_timestamp    := gen_duration(1,0);
        
        Log("RTPS Operation ADD_CACHE_CHANGE [DISPOSE, Instance 1, Writer 0, ID 1] (ACCEPTED)", INFO);
        rtps            := DEFAULT_RTPS_READER_TEST;
        rtps.opcode     := ADD_CACHE_CHANGE;
        rtps.cc         := cc;
        rtps.writer_pos := 0;
        rtps.ret_code   := OK;
        s               := to_sample(cc,NOT_ALIVE_DISPOSED_INSTANCE_STATE);
        add_sample(s,mem, BY_SOURCE_TIMESTAMP_DESTINATION_ORDER_QOS);
        start_rtps;
        wait_on_rtps;
        wait_on_idle;
        -- MEM: I1S1(0), I1S2-(1), I4S2-(7)
        -- ISTATE: I1:DISPOSED, I4:DISOSED
        -- VIEW: I1:NEW, I4:NEW
        -- WRITER: W0:I1, W2:I4
        
        Log("Current Time: 3s", INFO);
        check_time  <= gen_duration(3,0);
        wait until rising_edge(clk);
        wait until rising_edge(clk);
        wait_on_idle;
        
        cc                  := DEFAULT_CACHE_CHANGE;
        cc.serialized_key   := FALSE;
        cc.kind             := ALIVE;
        cc.instance         := kh1;
        cc.payload          := gen_payload(kh1,10);
        cc.src_timestamp    := gen_duration(9,0);
        
        Log("RTPS Operation ADD_CACHE_CHANGE [KEY_HASH, Instance 1, Writer 0, Aligned Payload, ID 9] (ACCEPTED)", INFO);
        rtps            := DEFAULT_RTPS_READER_TEST;
        rtps.opcode     := ADD_CACHE_CHANGE;
        rtps.cc         := cc;
        rtps.writer_pos := 0;
        rtps.ret_code   := OK;
        s               := to_sample(cc,ALIVE_INSTANCE_STATE);
        add_sample(s,mem, BY_SOURCE_TIMESTAMP_DESTINATION_ORDER_QOS);
        start_rtps;
        wait_on_rtps;
        wait_on_idle;
        -- MEM: I1S1(0), I1S2-(1), I4S2-(7), I1S3(9)
        -- ISTATE: I1:ALIVE, I4:DISOSED
        -- VIEW: I1:NEW, I4:NEW
        -- WRITER: W0:I1, W2:I4
        
        Log("Current Time: 4s", INFO);
        check_time  <= gen_duration(4,0);
        wait until rising_edge(clk);
        wait until rising_edge(clk);
        wait_on_idle;
        
        cc                  := DEFAULT_CACHE_CHANGE;
        cc.serialized_key   := FALSE;
        cc.kind             := ALIVE;
        cc.instance         := kh4;
        cc.payload          := gen_payload(kh4,10);
        cc.src_timestamp    := gen_duration(4,0);
        
        Log("RTPS Operation ADD_CACHE_CHANGE [KEY_HASH, Instance 4, Writer 2, Aligned Payload, ID 4] (ACCEPTED)", INFO);
        rtps            := DEFAULT_RTPS_READER_TEST;
        rtps.opcode     := ADD_CACHE_CHANGE;
        rtps.cc         := cc;
        rtps.writer_pos := 2;
        rtps.ret_code   := OK;
        s               := to_sample(cc,NOT_ALIVE_DISPOSED_INSTANCE_STATE);
        add_sample(s,mem, BY_SOURCE_TIMESTAMP_DESTINATION_ORDER_QOS);
        start_rtps;
        wait_on_rtps;
        wait_on_idle;
        -- MEM: I1S1(0), I1S2-(1), I4S1(4), I4S2-(7), I1S3(9)
        -- ISTATE: I1:ALIVE, I4:DISOSED
        -- VIEW: I1:NEW, I4:NEW
        -- WRITER: W0:I1, W2:I4
        
        -- TEST: OUT OF ORDER SAMPLE AFTER DISPOSE
        
        Log("DDS Operation READ_INSTANCE [MAX_SAMPLES 20, ANY_SAMPLE_STATE, ALIVE_INSTANCE_STATE, ANY_VIEW_STATE, Instance 4] (No Data)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := READ_INSTANCE;
        dds.max_samples := 20;
        dds.sstate      := ANY_SAMPLE_STATE;
        dds.istate      := ALIVE_INSTANCE_STATE;
        dds.vstate      := ANY_VIEW_STATE;
        dds.inst        := kh4;
        dds.ret_code    := RETCODE_NO_DATA;
        start_dds;
        wait_on_dds;
        -- MEM: I1S1(0), I1S2-(1), I4S1(4), I4S2-(7), I1S3(9)
        -- ISTATE: I1:ALIVE, I4:DISOSED
        -- VIEW: I1:NEW, I4:NEW
        -- WRITER: W0:I1, W2:I4
        
        Log("Current Time: 5s", INFO);
        check_time  <= gen_duration(5,0);
        wait until rising_edge(clk);
        wait until rising_edge(clk);
        wait_on_idle;
        
        cc                  := DEFAULT_CACHE_CHANGE;
        cc.serialized_key   := FALSE;
        cc.kind             := ALIVE;
        cc.instance         := kh3;
        cc.payload          := gen_payload(kh3,10);
        cc.src_timestamp    := gen_duration(3,0);
        
        Log("RTPS Operation ADD_CACHE_CHANGE [KEY_HASH, Instance 3, Writer 2, Aligned Payload, ID 3] (ACCEPTED)", INFO);
        rtps            := DEFAULT_RTPS_READER_TEST;
        rtps.opcode     := ADD_CACHE_CHANGE;
        rtps.cc         := cc;
        rtps.writer_pos := 2;
        rtps.ret_code   := OK;
        s               := to_sample(cc,ALIVE_INSTANCE_STATE);
        add_sample(s,mem, BY_SOURCE_TIMESTAMP_DESTINATION_ORDER_QOS);
        start_rtps;
        wait_on_rtps;
        wait_on_idle;
        -- MEM: I1S1(0), I1S2-(1), I3S1(3), I4S1(4), I4S2-(7), I1S3(9)
        -- ISTATE: I1:ALIVE, I3:ALIVE, I4:DISOSED
        -- VIEW: I1:NEW, I3:NEW, I4:NEW
        -- WRITER: W0:I1, W2:I3,I4
        
        Log("Current Time: 6s", INFO);
        check_time  <= gen_duration(6,0);
        wait until rising_edge(clk);
        wait until rising_edge(clk);
        wait_on_idle;
        
        cc                  := DEFAULT_CACHE_CHANGE;
        cc.serialized_key   := FALSE;
        cc.kind             := ALIVE;
        cc.instance         := kh2;
        cc.payload          := gen_payload(kh2,10);
        cc.src_timestamp    := gen_duration(2,0);
        
        Log("RTPS Operation ADD_CACHE_CHANGE [KEY_HASH, Instance 2, Writer 1, Aligned Payload, ID 2] (ACCEPTED)", INFO);
        rtps            := DEFAULT_RTPS_READER_TEST;
        rtps.opcode     := ADD_CACHE_CHANGE;
        rtps.cc         := cc;
        rtps.writer_pos := 1;
        rtps.ret_code   := OK;
        s               := to_sample(cc,ALIVE_INSTANCE_STATE);
        add_sample(s,mem, BY_SOURCE_TIMESTAMP_DESTINATION_ORDER_QOS);
        start_rtps;
        wait_on_rtps;
        wait_on_idle;
        -- MEM: I1S1(0), I1S2-(1), I2S1(2), I3S1(3), I4S1(4), I4S2-(7), I1S3(9)
        -- ISTATE: I1:ALIVE, I2:ALIVE, I3:ALIVE, I4:DISOSED
        -- VIEW: I1:NEW, I2:NEW, I3:NEW, I4:NEW
        -- WRITER: W0:I1, W2:I3,I4
        
        Log("Current Time: 7s", INFO);
        check_time  <= gen_duration(7,0);
        wait until rising_edge(clk);
        wait until rising_edge(clk);
        wait_on_idle;
        
        cc                  := DEFAULT_CACHE_CHANGE;
        cc.serialized_key   := TRUE;
        cc.kind             := NOT_ALIVE_DISPOSED;
        cc.instance         := kh2;
        cc.payload          := gen_payload(kh2,5);
        cc.src_timestamp    := gen_duration(5,0);
        
        Log("RTPS Operation ADD_CACHE_CHANGE [DISPOSE, Instance 2, Writer 1, ID 5] (ACCEPTED)", INFO);
        rtps            := DEFAULT_RTPS_READER_TEST;
        rtps.opcode     := ADD_CACHE_CHANGE;
        rtps.cc         := cc;
        rtps.writer_pos := 1;
        rtps.ret_code   := OK;
        s               := to_sample(cc,NOT_ALIVE_DISPOSED_INSTANCE_STATE);
        add_sample(s,mem, BY_SOURCE_TIMESTAMP_DESTINATION_ORDER_QOS);
        start_rtps;
        wait_on_rtps;
        wait_on_idle;
        -- MEM: I1S1(0), I1S2-(1), I2S1(2), I3S1(3), I4S1(4), I2S2-(5), I4S2-(7), I1S3(9)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:ALIVE, I4:DISOSED
        -- VIEW: I1:NEW, I2:NEW, I3:NEW, I4:NEW
        -- WRITER: W0:I1, W2:I3,I4
        
        Log("Current Time: 8s", INFO);
        check_time  <= gen_duration(8,0);
        wait until rising_edge(clk);
        wait until rising_edge(clk);
        wait_on_idle;
        
        cc                  := DEFAULT_CACHE_CHANGE;
        cc.serialized_key   := TRUE;
        cc.kind             := NOT_ALIVE_DISPOSED;
        cc.instance         := kh3;
        cc.payload          := gen_payload(kh3,5);
        cc.src_timestamp    := gen_duration(6,0);
        
        Log("RTPS Operation ADD_CACHE_CHANGE [DISPOSE, Instance 3, Writer 2, ID 6] (ACCEPTED)", INFO);
        rtps            := DEFAULT_RTPS_READER_TEST;
        rtps.opcode     := ADD_CACHE_CHANGE;
        rtps.cc         := cc;
        rtps.writer_pos := 2;
        rtps.ret_code   := OK;
        s               := to_sample(cc,NOT_ALIVE_DISPOSED_INSTANCE_STATE);
        add_sample(s,mem, BY_SOURCE_TIMESTAMP_DESTINATION_ORDER_QOS);
        start_rtps;
        wait_on_rtps;
        wait_on_idle;
        -- MEM: I1S1(0), I1S2-(1), I2S1(2), I3S1(3), I4S1(4), I2S2-(5), I3S2-(6), I4S2-(7), I1S3(9)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:DISOSED
        -- VIEW: I1:NEW, I2:NEW, I3:NEW, I4:NEW
        -- WRITER: W0:I1, W2:I3,I4
        
        Log("Current Time: 9s", INFO);
        check_time  <= gen_duration(9,0);
        wait until rising_edge(clk);
        wait until rising_edge(clk);
        wait_on_idle;
        
        cc                  := DEFAULT_CACHE_CHANGE;
        cc.serialized_key   := FALSE;
        cc.kind             := ALIVE;
        cc.instance         := kh4;
        cc.payload          := gen_payload(kh4,10);
        cc.src_timestamp    := gen_duration(8,0);
        
        Log("RTPS Operation ADD_CACHE_CHANGE [KEY_HASH, Instance 4, Writer 2, Aligned Payload, ID 8] (ACCEPTED)", INFO);
        rtps            := DEFAULT_RTPS_READER_TEST;
        rtps.opcode     := ADD_CACHE_CHANGE;
        rtps.cc         := cc;
        rtps.writer_pos := 2;
        rtps.ret_code   := OK;
        s               := to_sample(cc,ALIVE_INSTANCE_STATE);
        add_sample(s,mem, BY_SOURCE_TIMESTAMP_DESTINATION_ORDER_QOS);
        start_rtps;
        wait_on_rtps;
        wait_on_idle;
        -- MEM: I1S1(0), I1S2-(1), I2S1(2), I3S1(3), I4S1(4), I2S2-(5), I3S2-(6), I4S2-(7), I4S3(8), I1S3(9)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NEW, I2:NEW, I3:NEW, I4:NEW
        -- WRITER: W0:I1, W2:I3,I4
        
        Log("Current Time: 10s", INFO);
        check_time  <= gen_duration(10,0);
        wait until rising_edge(clk);
        wait until rising_edge(clk);
        wait_on_idle;
        
        cc                  := DEFAULT_CACHE_CHANGE;
        cc.serialized_key   := FALSE;
        cc.kind             := ALIVE;
        cc.instance         := kh2;
        cc.payload          := gen_payload(kh2,10);
        cc.src_timestamp    := gen_duration(10,0);
        
        Log("RTPS Operation ADD_CACHE_CHANGE [KEY_HASH, Instance 2, Writer 1, Aligned Payload, ID 10] (ACCEPTED)", INFO);
        rtps            := DEFAULT_RTPS_READER_TEST;
        rtps.opcode     := ADD_CACHE_CHANGE;
        rtps.cc         := cc;
        rtps.writer_pos := 1;
        rtps.ret_code   := OK;
        s               := to_sample(cc,ALIVE_INSTANCE_STATE);
        add_sample(s,mem, BY_SOURCE_TIMESTAMP_DESTINATION_ORDER_QOS);
        start_rtps;
        wait_on_rtps;
        wait_on_idle;
        -- MEM: I1S1(0), I1S2-(1), I2S1(2), I3S1(3), I4S1(4), I2S2-(5), I3S2-(6), I4S2-(7), I4S3(8), I1S3(9), I2S3(10)
        -- ISTATE: I1:ALIVE, I2:ALIVE, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NEW, I2:NEW, I3:NEW, I4:NEW
        -- WRITER: W0:I1, W2:I3,I4
        
        Log("Current Time: 11s", INFO);
        check_time  <= gen_duration(11,0);
        wait until rising_edge(clk);
        wait until rising_edge(clk);
        wait_on_idle;
        
        cc                  := DEFAULT_CACHE_CHANGE;
        cc.serialized_key   := TRUE;
        cc.kind             := NOT_ALIVE_DISPOSED;
        cc.instance         := kh2;
        cc.payload          := gen_payload(kh2,5);
        cc.src_timestamp    := gen_duration(11,0);
        
        Log("RTPS Operation ADD_CACHE_CHANGE [DISPOSE, Instance 2, Writer 1, ID 11] (ACCEPTED)", INFO);
        rtps            := DEFAULT_RTPS_READER_TEST;
        rtps.opcode     := ADD_CACHE_CHANGE;
        rtps.cc         := cc;
        rtps.writer_pos := 1;
        rtps.ret_code   := OK;
        s               := to_sample(cc,NOT_ALIVE_DISPOSED_INSTANCE_STATE);
        add_sample(s,mem, BY_SOURCE_TIMESTAMP_DESTINATION_ORDER_QOS);
        start_rtps;
        wait_on_rtps;
        wait_on_idle;
        -- MEM: I1S1(0), I1S2-(1), I2S1(2), I3S1(3), I4S1(4), I2S2-(5), I3S2-(6), I4S2-(7), I4S3(8), I1S3(9), I2S3(10), I2S4-(11)
        -- ISTATE: I1:ALIVE, I2:DISPSOED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NEW, I2:NEW, I3:NEW, I4:NEW
        -- WRITER: W0:I1, W2:I3,I4
        
        -- TEST: READ [MAX_SAMPLES < SAMPLES]
        -- TEST: READ [ANY SSTATE, ANY ISTATE, ANY VIEW]
        
        Log("DDS Operation READ [MAX_SAMPLES 1, ANY_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE] (Expected ID0,ID1,ID2)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := READ;
        dds.max_samples := 3;
        dds.sstate      := ANY_SAMPLE_STATE;
        dds.istate      := ANY_INSTANCE_STATE;
        dds.vstate      := ANY_VIEW_STATE;
        start_dds;
        wait_on_dds;
        -- MEM: I1S1(0), I1S2-(1), I2S1(2), I3S1(3), I4S1(4), I2S2-(5), I3S2-(6), I4S2-(7), I4S3(8), I1S3(9), I2S3(10), I2S4-(11)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NEW, I2:NEW, I3:NEW, I4:NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: READ MARKS SAMPLES AS READ
        -- TEST: READ_NEXT_SAMPLE [WITH UNREAD SAMPLE]
        
        Log("DDS Operation READ_NEXT_SAMPLE (Expected ID3)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := READ_NEXT_SAMPLE;
        start_dds;
        wait_on_dds;
        -- MEM: I1S1(0), I1S2-(1), I2S1(2), I3S1(3), I4S1(4), I2S2-(5), I3S2-(6), I4S2-(7), I4S3(8), I1S3(9), I2S3(10), I2S4-(11)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NEW, I2:NEW, I3:NOT_NEW, I4:NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: READ_INSTANCE [KNOWN INSTANCE, COMPATIBLE SAMPLES]
        
        Log("DDS Operation READ_INSTANCE [MAX_SAMPLES 1, NOT_READ_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE, Instance 3] (Expected ID9)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := READ_INSTANCE;
        dds.max_samples := 1;
        dds.sstate      := NOT_READ_SAMPLE_STATE;
        dds.istate      := ANY_INSTANCE_STATE;
        dds.vstate      := ANY_VIEW_STATE;
        dds.inst        := kh1;
        start_dds;
        wait_on_dds;
        -- MEM: I1S1(0), I1S2-(1), I2S1(2), I3S1(3), I4S1(4), I2S2-(5), I3S2-(6), I4S2-(7), I4S3(8), I1S3(9), I2S3(10), I2S4-(11)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NEW, I3:NOT_NEW, I4:NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: READ_NEXT_INSTANCE [WITH NEXT INSTANCE, COMPATIBLE SAMPLES]
        
        Log("DDS Operation READ_NEXT_INSTANCE [MAX_SAMPLES 1, ANY_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE, Instance 3] (Expected ID4)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := READ_NEXT_INSTANCE;
        dds.max_samples := 1;
        dds.sstate      := ANY_SAMPLE_STATE;
        dds.istate      := ANY_INSTANCE_STATE;
        dds.vstate      := ANY_VIEW_STATE;
        dds.inst        := kh3;
        start_dds;
        wait_on_dds;
        -- MEM: I1S1(0), I1S2-(1), I2S1(2), I3S1(3), I4S1(4), I2S2-(5), I3S2-(6), I4S2-(7), I4S3(8), I1S3(9), I2S3(10), I2S4-(11)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NEW, I3:NOT_NEW, I4:NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: READ [SPECIFIED SSTATE, ANY ISTATE, ANY VIEW]
        -- TEST: READ [MAX_SAMPLES > SAMPLES]
        
        Log("DDS Operation READ [MAX_SAMPLES 20, READ_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE] (Expected ID0,ID1,ID2,ID3,ID4,ID9)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := READ;
        dds.max_samples := 20;
        dds.sstate      := READ_SAMPLE_STATE;
        dds.istate      := ANY_INSTANCE_STATE;
        dds.vstate      := ANY_VIEW_STATE;
        start_dds;
        wait_on_dds;
        -- MEM: I1S1(0), I1S2-(1), I2S1(2), I3S1(3), I4S1(4), I2S2-(5), I3S2-(6), I4S2-(7), I4S3(8), I1S3(9), I2S3(10), I2S4-(11)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NEW, I3:NOT_NEW, I4:NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: READ [SPECIFIED SSTATE, SPECIFIED ISTATE, ANY VIEW]
        
        Log("DDS Operation READ [MAX_SAMPLES 20, READ_SAMPLE_STATE, NOT_ALIVE_DISPOSED_INSTANCE_STATE, ANY_VIEW_STATE] (Expected ID2,ID3)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := READ;
        dds.max_samples := 20;
        dds.sstate      := READ_SAMPLE_STATE;
        dds.istate      := NOT_ALIVE_DISPOSED_INSTANCE_STATE;
        dds.vstate      := ANY_VIEW_STATE;
        start_dds;
        wait_on_dds;
        -- MEM: I1S1(0), I1S2-(1), I2S1(2), I3S1(3), I4S1(4), I2S2-(5), I3S2-(6), I4S2-(7), I4S3(8), I1S3(9), I2S3(10), I2S4-(11)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NEW, I3:NOT_NEW, I4:NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: READ [SPECIFIED SSTATE, ANY ISTATE, SPECIFIED VIEW]
        -- TEST: READ MODIFIES VIEW STATE [READ CURRENT GENERATION]
        -- TEST: READ MODIFIES VIEW STATE [READ PREVIOUS GENERATION]
        
        Log("DDS Operation READ [MAX_SAMPLES 20, READ_SAMPLE_STATE, ANY_INSTANCE_STATE, NEW_VIEW_STATE] (Expected ID2,ID4)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := READ;
        dds.max_samples := 20;
        dds.sstate      := READ_SAMPLE_STATE;
        dds.istate      := ANY_INSTANCE_STATE;
        dds.vstate      := NEW_VIEW_STATE;
        start_dds;
        wait_on_dds;
        -- MEM: I1S1(0), I1S2-(1), I2S1(2), I3S1(3), I4S1(4), I2S2-(5), I3S2-(6), I4S2-(7), I4S3(8), I1S3(9), I2S3(10), I2S4-(11)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NEW, I3:NOT_NEW, I4:NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: READ [SPECIFIED SSTATE, SPECIFIED ISTATE, SPECIFIED VIEW]
        
        Log("DDS Operation READ [MAX_SAMPLES 20, READ_SAMPLE_STATE, NOT_ALIVE_DISPOSED_INSTANCE_STATE, NEW_VIEW_STATE] (Expected ID2)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := READ;
        dds.max_samples := 20;
        dds.sstate      := READ_SAMPLE_STATE;
        dds.istate      := NOT_ALIVE_DISPOSED_INSTANCE_STATE;
        dds.vstate      := NEW_VIEW_STATE;
        start_dds;
        wait_on_dds;
        -- MEM: I1S1(0), I1S2-(1), I2S1(2), I3S1(3), I4S1(4), I2S2-(5), I3S2-(6), I4S2-(7), I4S3(8), I1S3(9), I2S3(10), I2S4-(11)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NEW, I3:NOT_NEW, I4:NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: READ [ANY SSTATE, ANY ISTATE, SPECIFIED VIEW]
        
        Log("DDS Operation READ [MAX_SAMPLES 20, ANY_SAMPLE_STATE, ANY_INSTANCE_STATE, NOT_NEW_VIEW_STATE] (Expected ID0,ID1,ID3,ID6,ID9)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := READ;
        dds.max_samples := 20;
        dds.sstate      := ANY_SAMPLE_STATE;
        dds.istate      := ANY_INSTANCE_STATE;
        dds.vstate      := NOT_NEW_VIEW_STATE;
        start_dds;
        wait_on_dds;
        -- MEM: I1S1(0), I1S2-(1), I2S1(2), I3S1(3), I4S1(4), I2S2-(5), I3S2-(6), I4S2-(7), I4S3(8), I1S3(9), I2S3(10), I2S4-(11)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NEW, I3:NOT_NEW, I4:NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: READ [ANY SSTATE, SPECIFIED ISTATE, SPECIFIED VIEW]
        
        Log("DDS Operation READ [MAX_SAMPLES 20, ANY_SAMPLE_STATE, NOT_ALIVE_DISPOSED_INSTANCE_STATE, NOT_NEW_VIEW_STATE] (Expected ID3,ID6)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := READ;
        dds.max_samples := 20;
        dds.sstate      := ANY_SAMPLE_STATE;
        dds.istate      := NOT_ALIVE_DISPOSED_INSTANCE_STATE;
        dds.vstate      := NOT_NEW_VIEW_STATE;
        start_dds;
        wait_on_dds;
        -- MEM: I1S1(0), I1S2-(1), I2S1(2), I3S1(3), I4S1(4), I2S2-(5), I3S2-(6), I4S2-(7), I4S3(8), I1S3(9), I2S3(10), I2S4-(11)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NEW, I3:NOT_NEW, I4:NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: READ [ANY SSTATE, SPECIFIED ISTATE, ANY VIEW]
        
        Log("DDS Operation READ [MAX_SAMPLES 20, ANY_SAMPLE_STATE, NOT_ALIVE_DISPOSED_INSTANCE_STATE, ANY_VIEW_STATE] (Expected ID2,ID3,ID5,ID6,ID10,ID11)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := READ;
        dds.max_samples := 20;
        dds.sstate      := ANY_SAMPLE_STATE;
        dds.istate      := NOT_ALIVE_DISPOSED_INSTANCE_STATE;
        dds.vstate      := ANY_VIEW_STATE;
        start_dds;
        wait_on_dds;
        -- MEM: I1S1(0), I1S2-(1), I2S1(2), I3S1(3), I4S1(4), I2S2-(5), I3S2-(6), I4S2-(7), I4S3(8), I1S3(9), I2S3(10), I2S4-(11)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: READ_INSTANCE [UNKNOWN INSTANCE]
        
        Log("DDS Operation READ_INSTANCE [MAX_SAMPLES 20, ANY_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE, Unknown Instance] (Bad Parameter)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := READ_INSTANCE;
        dds.max_samples := 20;
        dds.sstate      := ANY_SAMPLE_STATE;
        dds.istate      := ANY_INSTANCE_STATE;
        dds.vstate      := ANY_VIEW_STATE;
        dds.inst        := kh5;
        dds.ret_code    := RETCODE_BAD_PARAMETER;
        start_dds;
        wait_on_dds;
        -- MEM: I1S1(0), I1S2-(1), I2S1(2), I3S1(3), I4S1(4), I2S2-(5), I3S2-(6), I4S2-(7), I4S3(8), I1S3(9), I2S3(10), I2S4-(11)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: READ_INSTANCE [KNOWN INSTANCE, UNCOMPATIBLE SAMPLES]
        
        Log("DDS Operation READ_INSTANCE [MAX_SAMPLES 20, NOT_READ_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE, Instance 1] (No Data)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := READ_INSTANCE;
        dds.max_samples := 20;
        dds.sstate      := NOT_READ_SAMPLE_STATE;
        dds.istate      := ANY_INSTANCE_STATE;
        dds.vstate      := ANY_VIEW_STATE;
        dds.inst        := kh1;
        dds.ret_code    := RETCODE_NO_DATA;
        start_dds;
        wait_on_dds;
        -- MEM: I1S1(0), I1S2-(1), I2S1(2), I3S1(3), I4S1(4), I2S2-(5), I3S2-(6), I4S2-(7), I4S3(8), I1S3(9), I2S3(10), I2S4-(11)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: READ_NEXT_INSTANCE [WITH NEXT INSTANCE, UNCOMPATIBLE SAMPLES]
        
        Log("DDS Operation READ_NEXT_INSTANCE [MAX_SAMPLES 20, ANY_SAMPLE_STATE, NOT_ALIVE_DISPOSED_INSTANCE_STATE, ANY_VIEW_STATE, Instance 2] (No Data)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := READ_NEXT_INSTANCE;
        dds.max_samples := 20;
        dds.sstate      := ANY_SAMPLE_STATE;
        dds.istate      := NOT_ALIVE_DISPOSED_INSTANCE_STATE;
        dds.vstate      := ANY_VIEW_STATE;
        dds.inst        := kh2;
        dds.ret_code    := RETCODE_NO_DATA;
        start_dds;
        wait_on_dds;
        -- MEM: I1S1(0), I1S2-(1), I2S1(2), I3S1(3), I4S1(4), I2S2-(5), I3S2-(6), I4S2-(7), I4S3(8), I1S3(9), I2S3(10), I2S4-(11)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: READ_NEXT_INSTANCE [WITH NEXT INSTANCE, WITH COMPATIBLE SAMPLE, NOT DIRECT NEXT INSTANCE]
        
        Log("DDS Operation READ_NEXT_INSTANCE [MAX_SAMPLES 20, NOT_READ_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE, Instance 3] (Expected ID7,ID8)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := READ_NEXT_INSTANCE;
        dds.max_samples := 20;
        dds.sstate      := NOT_READ_SAMPLE_STATE;
        dds.istate      := ANY_INSTANCE_STATE;
        dds.vstate      := ANY_VIEW_STATE;
        dds.inst        := kh3;
        dds.ret_code    := RETCODE_OK;
        start_dds;
        wait_on_dds;
        -- MEM: I1S1(0), I1S2-(1), I2S1(2), I3S1(3), I4S1(4), I2S2-(5), I3S2-(6), I4S2-(7), I4S3(8), I1S3(9), I2S3(10), I2S4-(11)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NOT_NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: READ [NO COMPATIBLE SAMPLES]
        
        Log("DDS Operation READ [MAX_SAMPLES 20, ANY_SAMPLE_STATE, NOT_ALIVE_NO_WRITERS_INSTANCE_STATE, ANY_VIEW_STATE] (No Data)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := READ;
        dds.max_samples := 20;
        dds.sstate      := ANY_SAMPLE_STATE;
        dds.istate      := NOT_ALIVE_NO_WRITERS_INSTANCE_STATE;
        dds.vstate      := ANY_VIEW_STATE;
        dds.ret_code    := RETCODE_NO_DATA;
        start_dds;
        wait_on_dds;
        -- MEM: I1S1(0), I1S2-(1), I2S1(2), I3S1(3), I4S1(4), I2S2-(5), I3S2-(6), I4S2-(7), I4S3(8), I1S3(9), I2S3(10), I2S4-(11)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NOT_NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: READ_NEXT_SAMPLE [WITHOUT UNREAD SAMPLE]
        
        Log("DDS Operation READ_NEXT_SAMPLE (No Data)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := READ_NEXT_SAMPLE;
        dds.ret_code    := RETCODE_NO_DATA;
        start_dds;
        wait_on_dds;
        -- MEM: I1S1(0), I1S2-(1), I2S1(2), I3S1(3), I4S1(4), I2S2-(5), I3S2-(6), I4S2-(7), I4S3(8), I1S3(9), I2S3(10), I2S4-(11)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NOT_NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: TAKE
        
        Log("DDS Operation TAKE [MAX_SAMPLES 1, ANY_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE] (Expected ID0)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := TAKE;
        dds.max_samples := 1;
        dds.sstate      := ANY_SAMPLE_STATE;
        dds.istate      := ANY_INSTANCE_STATE;
        dds.vstate      := ANY_VIEW_STATE;
        dds.ret_code    := RETCODE_OK;
        start_dds;
        wait_on_dds;
        -- MEM: I1S2-(1), I2S1(2), I3S1(3), I4S1(4), I2S2-(5), I3S2-(6), I4S2-(7), I4S3(8), I1S3(9), I2S3(10), I2S4-(11)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NOT_NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: TAKE_INSTANCE
        
        Log("DDS Operation TAKE_INSTANCE [MAX_SAMPLES 1, ANY_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE, Instance 2] (Expected ID2)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := TAKE_INSTANCE;
        dds.max_samples := 1;
        dds.sstate      := ANY_SAMPLE_STATE;
        dds.istate      := ANY_INSTANCE_STATE;
        dds.vstate      := ANY_VIEW_STATE;
        dds.inst        := kh2;
        dds.ret_code    := RETCODE_OK;
        start_dds;
        wait_on_dds;
        -- MEM: I1S2-(1), I3S1(3), I4S1(4), I2S2-(5), I3S2-(6), I4S2-(7), I4S3(8), I1S3(9), I2S3(10), I2S4-(11)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NOT_NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: TAKE_NEXT_INSTANCE
        -- TEST: READ_NEXT_INSTANCE [HANDLE_NIL]
        
        Log("DDS Operation TAKE_NEXT_INSTANCE [MAX_SAMPLES 20, ANY_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE, HANDLE_NIL] (Expected ID3,ID6)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := TAKE_NEXT_INSTANCE;
        dds.max_samples := 20;
        dds.sstate      := ANY_SAMPLE_STATE;
        dds.istate      := ANY_INSTANCE_STATE;
        dds.vstate      := ANY_VIEW_STATE;
        dds.inst        := HANDLE_NIL;
        dds.ret_code    := RETCODE_OK;
        start_dds;
        wait_on_dds;
        -- MEM: I1S2-(1), I4S1(4), I2S2-(5), I4S2-(7), I4S3(8), I1S3(9), I2S3(10), I2S4-(11)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NOT_NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: TAKE REMOVES SAMPLE
        -- TEST: READ_INSTANCE [NO SAMPLES]
        
        Log("DDS Operation READ_INSTANCE [MAX_SAMPLES 20, ANY_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE, Instance 3] (No Data)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := READ_INSTANCE;
        dds.max_samples := 20;
        dds.sstate      := ANY_SAMPLE_STATE;
        dds.istate      := ANY_INSTANCE_STATE;
        dds.vstate      := ANY_VIEW_STATE;
        dds.inst        := kh3;
        dds.ret_code    := RETCODE_NO_DATA;
        start_dds;
        wait_on_dds;
        -- MEM: I1S2-(1), I4S1(4), I2S2-(5), I4S2-(7), I4S3(8), I1S3(9), I2S3(10), I2S4-(11)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NOT_NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        Log("DDS Operation TAKE_NEXT_INSTANCE [MAX_SAMPLES 20, ANY_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE, Instance 3] (Expected ID4,ID7,ID8)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := TAKE_NEXT_INSTANCE;
        dds.max_samples := 20;
        dds.sstate      := ANY_SAMPLE_STATE;
        dds.istate      := ANY_INSTANCE_STATE;
        dds.vstate      := ANY_VIEW_STATE;
        dds.inst        := kh3;
        dds.ret_code    := RETCODE_OK;
        start_dds;
        wait_on_dds;
        -- MEM: I1S2-(1), I2S2-(5), I1S3(9), I2S3(10), I2S4-(11)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NOT_NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: TAKE_INSTANCE [NO SAMPLES]
        
        Log("DDS Operation TAKE_INSTANCE [MAX_SAMPLES 20, ANY_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE, Instance 4] (No Data)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := TAKE_INSTANCE;
        dds.max_samples := 20;
        dds.sstate      := ANY_SAMPLE_STATE;
        dds.istate      := ANY_INSTANCE_STATE;
        dds.vstate      := ANY_VIEW_STATE;
        dds.inst        := kh4;
        dds.ret_code    := RETCODE_NO_DATA;
        start_dds;
        wait_on_dds;
        -- MEM: I1S2-(1), I2S2-(5), I1S3(9), I2S3(10), I2S4-(11)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NOT_NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        Log("DDS Operation TAKE_NEXT_INSTANCE [MAX_SAMPLES 20, ANY_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE, Instance 4] (Expected ID5,ID10,ID11)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := TAKE_NEXT_INSTANCE;
        dds.max_samples := 20;
        dds.sstate      := ANY_SAMPLE_STATE;
        dds.istate      := ANY_INSTANCE_STATE;
        dds.vstate      := ANY_VIEW_STATE;
        dds.inst        := kh4;
        dds.ret_code    := RETCODE_OK;
        start_dds;
        wait_on_dds;
        -- MEM: I1S2-(1), I1S3(9)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NOT_NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        Log("DDS Operation READ_INSTANCE [MAX_SAMPLES 20, ANY_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE, Instance 2] (No Data)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := READ_INSTANCE;
        dds.max_samples := 20;
        dds.sstate      := ANY_SAMPLE_STATE;
        dds.istate      := ANY_INSTANCE_STATE;
        dds.vstate      := ANY_VIEW_STATE;
        dds.inst        := kh2;
        dds.ret_code    := RETCODE_NO_DATA;
        start_dds;
        wait_on_dds;
        -- MEM: I1S2-(1), I1S3(9)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NOT_NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: READ_NEXT_INSTANCE [WITH SAMPLES, WITHOUT NEXT INSTANCE]
        
        Log("DDS Operation READ_NEXT_INSTANCE [MAX_SAMPLES 20, ANY_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE, Instance 1] (No Data)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := READ_NEXT_INSTANCE;
        dds.max_samples := 20;
        dds.sstate      := ANY_SAMPLE_STATE;
        dds.istate      := ANY_INSTANCE_STATE;
        dds.vstate      := ANY_VIEW_STATE;
        dds.inst        := kh1;
        dds.ret_code    := RETCODE_NO_DATA;
        start_dds;
        wait_on_dds;
        -- MEM: I1S2-(1), I1S3(9)
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NOT_NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        Log("DDS Operation TAKE_NEXT_INSTANCE [MAX_SAMPLES 20, ANY_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE, Instance 2] (Expected ID1,ID9)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := TAKE_NEXT_INSTANCE;
        dds.max_samples := 20;
        dds.sstate      := ANY_SAMPLE_STATE;
        dds.istate      := ANY_INSTANCE_STATE;
        dds.vstate      := ANY_VIEW_STATE;
        dds.inst        := kh2;
        dds.ret_code    := RETCODE_OK;
        start_dds;
        wait_on_dds;
        -- MEM: -
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NOT_NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: GET ALL DATA WITH READ_NEXT_INSTANCE
        -- TEST: READ [NO SAMPLES]
        
        Log("DDS Operation READ [MAX_SAMPLES 20, ANY_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE] (No Data)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := READ;
        dds.max_samples := 20;
        dds.sstate      := ANY_SAMPLE_STATE;
        dds.istate      := ANY_INSTANCE_STATE;
        dds.vstate      := ANY_VIEW_STATE;
        dds.ret_code    := RETCODE_NO_DATA;
        start_dds;
        wait_on_dds;
        -- MEM: -
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NOT_NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: TAKE [NO SAMPLES]
        
        Log("DDS Operation TAKE [MAX_SAMPLES 20, ANY_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE] (No Data)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := TAKE;
        dds.max_samples := 20;
        dds.sstate      := ANY_SAMPLE_STATE;
        dds.istate      := ANY_INSTANCE_STATE;
        dds.vstate      := ANY_VIEW_STATE;
        dds.ret_code    := RETCODE_NO_DATA;
        start_dds;
        wait_on_dds;
        -- MEM: -
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NOT_NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: READ_NEXT_INSTANCE [NO SAMPLE]
        
        Log("DDS Operation READ_NEXT_INSTANCE [MAX_SAMPLES 20, ANY_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE, HANDLE_NIL] (No Data)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := READ_NEXT_INSTANCE;
        dds.max_samples := 20;
        dds.sstate      := ANY_SAMPLE_STATE;
        dds.istate      := ANY_INSTANCE_STATE;
        dds.vstate      := ANY_VIEW_STATE;
        dds.inst        := HANDLE_NIL;
        dds.ret_code    := RETCODE_NO_DATA;
        start_dds;
        wait_on_dds;
        -- MEM: -
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NOT_NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: TAKE_NEXT_INSTANCE [NO SAMPLE]
        
        Log("DDS Operation TAKE_NEXT_INSTANCE [MAX_SAMPLES 20, ANY_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE, HANDLE_NIL] (No Data)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := TAKE_NEXT_INSTANCE;
        dds.max_samples := 20;
        dds.sstate      := ANY_SAMPLE_STATE;
        dds.istate      := ANY_INSTANCE_STATE;
        dds.vstate      := ANY_VIEW_STATE;
        dds.inst        := HANDLE_NIL;
        dds.ret_code    := RETCODE_NO_DATA;
        start_dds;
        wait_on_dds;
        -- MEM: -
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NOT_NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: READ_NEXT_SAMPLE [NO SAMPLE]
        
        Log("DDS Operation READ_NEXT_SAMPLE (No Data)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := READ_NEXT_SAMPLE;
        dds.ret_code    := RETCODE_NO_DATA;
        start_dds;
        wait_on_dds;
        -- MEM: -
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NOT_NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: TAKE_NEXT_SAMPLE [NO SAMPLE]
        
        Log("DDS Operation TAKE_NEXT_SAMPLE (No Data)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := TAKE_NEXT_SAMPLE;
        dds.ret_code    := RETCODE_NO_DATA;
        start_dds;
        wait_on_dds;
        -- MEM: -
        -- ISTATE: I1:ALIVE, I2:DISPOSED, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NOT_NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        Log("Current Time: 12s", INFO);
        check_time  <= gen_duration(12,0);
        wait until rising_edge(clk);
        wait until rising_edge(clk);
        wait_on_idle;
        
        cc                  := DEFAULT_CACHE_CHANGE;
        cc.serialized_key   := FALSE;
        cc.kind             := ALIVE;
        cc.instance         := kh2;
        cc.payload          := gen_payload(kh2,10);
        cc.src_timestamp    := gen_duration(12,0);
        
        Log("RTPS Operation ADD_CACHE_CHANGE [KEY_HASH, Instance 2, Writer 1, Aligned Payload, ID 12] (ACCEPTED)", INFO);
        rtps            := DEFAULT_RTPS_READER_TEST;
        rtps.opcode     := ADD_CACHE_CHANGE;
        rtps.cc         := cc;
        rtps.writer_pos := 1;
        rtps.ret_code   := OK;
        s               := to_sample(cc,ALIVE_INSTANCE_STATE);
        add_sample(s,mem, BY_RECEPTION_TIMESTAMP_DESTINATION_ORDER_QOS);
        start_rtps;
        wait_on_rtps;
        wait_on_idle;
        -- MEM: I2S5(12)
        -- ISTATE: I1:ALIVE, I2:ALIVE, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NEW, I3:NOT_NEW, I4:NOT_NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        -- TEST: TAKE_NEXT_SAMPLE
        
        Log("DDS Operation TAKE_NEXT_SAMPLE (Expected ID12)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := TAKE_NEXT_SAMPLE;
        dds.ret_code    := RETCODE_OK;
        start_dds;
        wait_on_dds;
        -- MEM: -
        -- ISTATE: I1:ALIVE, I2:ALIVE, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NOT_NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        Log("DDS Operation READ [MAX_SAMPLES 20, ANY_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE] (No Data)", INFO);
        dds             := DEFAULT_DDS_READER_TEST;
        dds.opcode      := READ;
        dds.max_samples := 20;
        dds.sstate      := ANY_SAMPLE_STATE;
        dds.istate      := ANY_INSTANCE_STATE;
        dds.vstate      := ANY_VIEW_STATE;
        dds.ret_code    := RETCODE_NO_DATA;
        start_dds;
        wait_on_dds;
        -- MEM: -
        -- ISTATE: I1:ALIVE, I2:ALIVE, I3:DISPOSED, I4:ALIVE
        -- VIEW: I1:NOT_NEW, I2:NOT_NEW, I3:NOT_NEW, I4:NOT_NEW
        -- WRITER: W0:I1, W1:I2, W2:I3,I4
        
        wait_on_completion;
        TranscriptOpen(RESULTS_FILE, APPEND_MODE);
        SetTranscriptMirror;
        ReportAlerts;
        TranscriptClose;
        std.env.stop;
        wait;
    end process;
    
    clock_prc : process
    begin
        clk <= '0';
        wait for 25 ns;
        clk <= '1';
        wait for 25 ns;
    end process;
    
    alert_prc : process(all)
    begin
        if rising_edge(clk) then
            -- TODO
        end if;
    end process;
    
    dds_prc : process(all)
        variable col : COLLECTION_TYPE := DEFAULT_COLLECTION;
    begin
        if rising_edge(clk) then
            dds_done    <= '0';
            case (dds_stage ) is
                when IDLE =>
                    if (dds_start  = '1') then
                        dds_stage   <= START;
                    else
                        dds_done    <= '1';
                    end if;
                when START =>
                    if (ack_dds = '1') then
                        dds_stage   <= DONE;
                        dds_cnt     <= 0;
                    end if;
                when DONE =>
                    if (done_dds = '1') then
                        AffirmIfEqual(ret_id, return_code_dds, dds.ret_code);
                        case (dds.ret_code) is
                            when RETCODE_OK =>
                                gen_collection(mem, col, dds, TOPIC_PRESENTATION_QOS, TRUE);
                                dds_stage   <= CHECK_SI;
                                dds_cnt     <= 0;
                            when others =>
                                dds_stage   <= IDLE;
                        end case;
                    end if;
                when CHECK_SI =>
                    if (si_valid = '1') then
                        Log("Read Sample ID" & to_string(to_integer(si_source_timestamp(0))), DEBUG);
                        AffirmIfEqual(sstate_id, si_sample_state, col.s(dds_cnt).sstate);
                        AffirmIfEqual(vstate_id, si_view_state, col.s(dds_cnt).vstate);
                        AffirmIfEqual(istate_id, si_instance_state, col.s(dds_cnt).istate);
                        AffirmIfEqual(ts_id, to_unsigned(si_source_timestamp), to_unsigned(col.s(dds_cnt).ts));
                        AffirmIfEqual(inst_id, to_unsigned(si_instance_handle), to_unsigned(col.s(dds_cnt).inst));
                        AffirmIfEqual(pub_id, to_unsigned(si_publication_handle), to_unsigned(HANDLE_NIL));
                        AffirmIfEqual(dis_gen_cnt_id, si_disposed_generation_count, std_logic_vector(to_unsigned(col.s(dds_cnt).dis_gen_cnt,WORD_WIDTH)));
                        AffirmIfEqual(no_w_gen_cnt_id, si_no_writers_generation_count, std_logic_vector(to_unsigned(col.s(dds_cnt).no_w_gen_cnt,WORD_WIDTH)));
                        AffirmIfEqual(srank_id, si_sample_rank, std_logic_vector(to_unsigned(col.s(dds_cnt).srank,WORD_WIDTH)));
                        AffirmIfEqual(grank_id, si_generation_rank, std_logic_vector(to_unsigned(col.s(dds_cnt).grank,WORD_WIDTH)));
                        AffirmIfEqual(agrank_id, si_absolute_generation_rank, std_logic_vector(to_unsigned(col.s(dds_cnt).agrank,WORD_WIDTH)));
                        if (si_valid_data = '1') then
                            AffirmIf(valid_id, col.s(dds_cnt).data /= EMPTY_TEST_PACKET, "Sample with Data not expected");
                            dds_stage   <= CHECK_DATA;
                            dds_cnt2    <= 0;
                        else
                            AffirmIf(valid_id, col.s(dds_cnt).data = EMPTY_TEST_PACKET, "Sample with Data expected");
                            if (dds_cnt = col.len-1) then
                                -- DONE
                                dds_stage   <= WAIT_EOC;
                            else
                                dds_cnt     <= dds_cnt + 1;
                            end if;
                        end if;
                    end if;
                    AffirmIf(eoc_id, eoc = '0', "EOC pulled high");
                when CHECK_DATA =>
                    if (valid_out_dds = '1') then
                        AffirmIfEqual(data_id, data_out_dds, col.s(dds_cnt).data.data(dds_cnt2));
                        dds_cnt2    <= dds_cnt2 + 1;
                        if (dds_cnt2  = col.s(dds_cnt).data.length-1) then
                            AlertIf(data_id, last_word_out_dds /= '1', "Last Word Signal not pulled High", ERROR);
                            if (dds_cnt = col.len-1) then
                                -- DONE
                                dds_stage   <= WAIT_EOC;
                            else
                                dds_stage   <= CHECK_SI;
                                dds_cnt     <= dds_cnt + 1;
                            end if;
                        end if;
                    end if;
                when WAIT_EOC =>
                    if (eoc = '1') then
                        dds_stage   <= IDLE;
                    end if;
            end case;
        end if;
        
        -- DEFAULT
        start_dds           <= '0';
        opcode_dds          <= NOP;
        instance_state_dds  <= ANY_INSTANCE_STATE;
        view_state_dds      <= ANY_VIEW_STATE;
        sample_state_dds    <= ANY_SAMPLE_STATE;
        instance_handle_dds <= HANDLE_NIL;
        max_samples_dds     <= (others => '0');
        get_data_dds        <= '0';
        ready_out_dds       <= '0';
        
        
        case (dds_stage ) is
            when START =>
                start_dds           <= '1';
                opcode_dds          <= dds.opcode;
                instance_state_dds  <= dds.istate;
                view_state_dds      <= dds.vstate;
                sample_state_dds    <= dds.sstate;
                instance_handle_dds <= dds.inst;
                max_samples_dds     <= std_logic_vector(to_unsigned(dds.max_samples, WORD_WIDTH));
            when CHECK_SI =>
                if (si_valid = '1' and si_valid_data = '1') then
                    get_data_dds    <= '1';
                end if;
            when CHECK_DATA =>
                ready_out_dds   <= '1';
            when others =>
                null;
        end case;
    end process;
    
    rtps_prc : process(all)
        variable stimulus : TEST_PACKET_TYPE := EMPTY_TEST_PACKET;
    begin
        if rising_edge(clk) then
            rtps_done    <= '0';
            case (rtps_stage) is
                when IDLE =>
                    if (rtps_start = '1') then
                        rtps_stage   <= START;
                    else
                        rtps_done    <= '1';
                    end if;
                when START =>
                    if (ack_rtps = '1') then
                        case (rtps.opcode) is
                            when ADD_CACHE_CHANGE =>
                                gen_add_cache_change_dds(rtps.cc, rtps.lifespan, rtps.writer_pos, stimulus);
                                rtps_stage  <= PUSH;
                            when others =>
                                rtps_stage  <= DONE;
                        end case;
                    end if;
                when PUSH =>
                    if (ready_in_rtps = '1') then
                        rtps_cnt    <= rtps_cnt + 1;
                        if (rtps_cnt = stimulus.length-1) then
                            rtps_stage  <= DONE;
                        end if;
                    end if;
                when DONE =>
                    if (done_rtps = '1') then
                        AffirmIfEqual(ret_id, HISTORY_CACHE_RESPONSE_TYPE'pos(ret_rtps), HISTORY_CACHE_RESPONSE_TYPE'pos(rtps.ret_code));
                        rtps_stage   <= IDLE;
                    end if;
            end case;
        end if;
        
        -- DEFAULT
        start_rtps          <= '0';
        opcode_rtps         <= NOP;
        valid_in_rtps       <= '0';
        last_word_in_rtps   <= '0';
        data_in_rtps        <= (others => '0');
        
        case (rtps_stage) is
            when START =>
                start_rtps  <= '1';
                opcode_rtps <= rtps.opcode;
                case (rtps.opcode) is
                    when REMOVE_WRITER =>
                        data_in_rtps    <= std_logic_vector(to_unsigned(rtps.writer_pos,WORD_WIDTH));
                    when others =>
                        null;
                end case;
            when PUSH =>
                valid_in_rtps       <= '1';
                data_in_rtps        <= stimulus.data(rtps_cnt);
                last_word_in_rtps   <= stimulus.last(rtps_cnt);
            when others =>
                null;
        end case;
    end process;
    
    watchdog : process
    begin
        wait for 1 ms;
        Alert("Test timeout", FAILURE);
        std.env.stop;
    end process;
    
end architecture;