Add Test 1 of DDS Reader

Test RTPS Operations ADD_CACHE_CHANGE, and REMOVE_WRITER of DDS Reader.
Port changes and code refoctoring in DDS Writer.
This commit is contained in:
Greek 2021-04-11 16:39:17 +02:00
parent c5239679d7
commit bac011905a
31 changed files with 14810 additions and 4741 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -765,6 +765,13 @@ Scenario 2: With SHARED ownership and destination order by SOURCE timestamp, re
associated with the instance would forget the source timestamp when the deletion occurs and if a different
DataWriter where to write the instance with an earlier timestamp the update would be incorrectly accepted.
https://community.rti.com/content/forum-topic/instance-resources-dispose-and-unregister
The instance has no known DataWriters that are writing it. This occurs when all the DataWriters that
were known (by the DataReader) to write the instance have either unregistered the instance or have left
the system (so they are no longer matched with the DataReader). Note that the instance could be on a
NOT_ALIVE_NO_WRITERS instance_state or a NOT_ALIVE_DISPOSED, depending on whether the instance was
disposed prior to losing all the DataWriters.
2.2.2.5.3.8 read (DDS)
Samples that contain no data do not count towards the limits imposed by the RESOURCE_LIMITS QoS policy.

View File

@ -78,6 +78,7 @@
* The current implementation will sent a second unregister/dispose Sample, if the user does the unregister/dispose operation a second time. Should we handle that specially?
* If a Keyed Reader receives a DATA Message with no Key hash and no Payload, it will drop it since there is no way to determine the instance (And the SN will never be accepted).
* If a Best Effort Remote Reader sends a ACKNACK, he will indirectly receive a lease deadline and may timeout (DoS Attack)
* Since the Instance Handle has to be Unique but also orderable, we could use the actual Instance Memory Base Address. Since the Instances are in a list, we also have implicitly an order to all registered Instances. [It may be necessary to add a PREV pointer to the IMF to better support the read_previous_isntance operation]
* Fast-RTPS does not follow DDSI-RTPS Specification
- Open Github Issue
@ -331,9 +332,33 @@ DESIGN DECISIONS
* The DDS Specification states that if after an Unregister Operation "the application wants to modify
(write or dispose) the instance, it has to register it again, or else use the special handle value
HANDLE_NIL". I do not have this prerequirement. it will return BAD_PARAMETER only if the Instance
HANDLE_NIL". I do not have this prerequirement. It will return BAD_PARAMETER only if the Instance
is not in the memory anymore.
* The DDS Specification is not entirely clear how to handle transition between the NOT_ALIVE states.
Going by the petri-net state-flowchart transitions between the NOT_ALIVE states are not allowed,
meaning that the first taken NOT_ALIVE state stays until the instance is reborn. But since the Disposal
of an Instance is of higher Information value, we should support transitioning from NOT_ALIVE_NO_WRITERS
to NOT_ALIVE_DISPOSED. This i.e. is done by transitioning to ALIVE and back to NOT_ALIVE_DISPOSED on the
same received sample (not_alive_generation_counter is incremented). This is also in accordance to the
protocol, since the writer that disposes the instance effectively (re-)registers the instance, meaning
that it now has a live writer again. On the other hand there is no transition from NOT_ALIVE_DISPOSED
to NOT_ALIVE_NO_WRITERS.
* Unregister/Dispose/Filtered Samples of unknown Instances are droped. Note that if a previous ALIVE
instance went to an NOT_ALIVE_NO_WRITERS state and was subsequently pushed out of the memory will
miss the transition to NOT_ALIVE_DISPOSED if a writer than decides to sent a Dispose Sample.
* The DDS Specification is not entirely clear on what happens in the DDS Reader on reception of
Meta Samples (Unregister/Dispose Samples). One simple solution would be to make Data-less Samples for
each received Meta-Sample. But since a meta-sample may not necessarily change the state to something
visible from the Sample info (e.g. Unregister on Instance with still alive Writers or Dispose from
another Writer on already disposed Instance), it does not seem practical. (In effect only the source
timestamp and publication handle of the Sample Info could be different).
Taking this into consideration, thsi DDS Reader implementation only generates data-less samples if
an Instance State is triggered. Filtered Cache Changes also do not produce any Samples visible to the
user (But affect internal state, like DEADLINE and LIVELINESS state).
PROTOCOL UNCOMPLIANCE
=====================
* Partition QoS

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,995 @@
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 RTPS handling of the DDS Reader. It tests the correctness of the RTPS ADD_CACHE_CHANGE, and REMOVE_WRITER Operations.
-- Implicitly some DDS Operations are also tested, since they are used for state checking.
-- More specifically the testbench covers following tests:
entity L0_dds_reader_test1_arznriu is
end entity;
architecture testbench of L0_dds_reader_test1_arznriu is
-- *CONSTANT DECLARATION*
constant MAX_REMOTE_ENDPOINTS : natural := 3;
-- *TYPE DECLARATION*
type DDS_STAGE_TYPE is (IDLE, START, DONE, CHECK_SI, CHECK_DATA);
type RTPS_STAGE_TYPE is (IDLE, START, PUSH, DONE);
type KH_STAGE_TYPE is (IDLE, READ_DATA, PUSH_KEY_HASH);
-- *SIGNAL DECLARATION*
signal clk : std_logic := '0';
signal reset : std_logic := '1';
signal check_time : TIME_TYPE := TIME_ZERO;
signal start_rtps, start_dds, start_kh, ack_rtps, ack_dds, ack_kh, done_rtps, done_dds : std_logic := '0';
signal opcode_rtps : HISTORY_CACHE_OPCODE_TYPE := NOP;
signal opcode_dds : DDS_READER_OPCODE_TYPE := NOP;
signal opcode_kh : KEY_HOLDER_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 ready_in_kh, ready_out_kh, valid_in_kh, valid_out_kh, last_word_in_kh, last_word_out_kh : std_logic := '0';
signal data_in_rtps, data_out_dds, data_in_kh, data_out_kh : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0');
signal get_data_dds, si_valid_data, si_valid, si_last, abort_kh : 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 : PUBLICATION_HANDLE_TYPE := (others => (others => '0'));
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, kh_cnt : natural := 0;
signal dds_stage : DDS_STAGE_TYPE := IDLE;
signal rtps_stage : RTPS_STAGE_TYPE := IDLE;
signal kh_stage : KH_STAGE_TYPE := IDLE;
signal kh_data : TEST_PACKET_TYPE := EMPTY_TEST_PACKET;
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, last_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(2,CDR_LONG_WIDTH)),
MAX_INSTANCES => std_logic_vector(to_unsigned(3,CDR_LONG_WIDTH)),
MAX_SAMPLES_PER_INSTANCE => std_logic_vector(to_unsigned(2,CDR_LONG_WIDTH)),
HISTORY_QOS => KEEP_ALL_HISTORY_QOS,
RELIABILITY_QOS => RELIABLE_RELIABILITY_QOS,
PRESENTATION_QOS => INSTANCE_PRESENTATION_QOS,
DESTINATION_ORDER_QOS => BY_RECEPTION_TIMESTAMP_DESTINATION_ORDER_QOS,
COHERENT_ACCESS => FALSE,
ORDERED_ACCESS => FALSE,
WITH_KEY => FALSE,
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_kh => start_kh,
opcode_kh => opcode_kh,
ack_kh => ack_kh,
data_in_kh => data_in_kh,
valid_in_kh => valid_in_kh,
ready_in_kh => ready_in_kh,
last_word_in_kh => last_word_in_kh,
data_out_kh => data_out_kh,
valid_out_kh => valid_out_kh,
ready_out_kh => ready_out_kh,
last_word_out_kh => last_word_out_kh,
abort_kh => abort_kh,
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,
si_sample_state => si_sample_state,
si_view_state => si_view_state,
si_instance_state => si_instance_state,
si_source_timestamp => si_source_timestamp,
si_instance_handle => si_instance_handle,
si_publication_handle => si_publication_handle,
si_disposed_generation_count => si_disposed_generation_count,
si_no_writers_generation_count => si_no_writers_generation_count,
si_sample_rank => si_sample_rank,
si_generation_rank => si_generation_rank,
si_absolute_generation_rank => si_absolute_generation_rank,
si_valid_data => si_valid_data,
si_valid => si_valid,
si_last => si_last,
status => status
);
stimulus_prc : process
variable RV : RandomPType;
variable kh1, kh2, kh3, kh4 : INSTANCE_HANDLE_TYPE := HANDLE_NIL;
variable cc1, cc2, cc3, cc4, cc : CACHE_CHANGE_TYPE := DEFAULT_CACHE_CHANGE;
variable s : SAMPLE_TYPE := DEFAULT_SAMPLE;
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 := (others => (others => '0'));
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;
begin
SetAlertLogName("dds_reader - (KEEP ALL, Reliable, Zero TIME_BASED_FILTER, Keyless, BY_RECEPTION_TIMESTAMP_DESTINATION_ORDER, ACCESS SCOPE Instance, Unordered) - Level 0 - RTPS Handling");
SetAlertEnable(FAILURE, TRUE);
SetAlertEnable(ERROR, TRUE);
SetAlertEnable(WARNING, TRUE);
SetLogEnable(DEBUG, FALSE);
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);
last_id <= GetAlertLogID("Last Sample", 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 := gen_key_hash;
Log("Initiating Test", INFO);
reset <= '1';
wait until rising_edge(clk);
wait until rising_edge(clk);
reset <= '0';
-- MEM: 0, 0
-- ISTATE: -
-- WRITER: -
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.payload := gen_payload(HANDLE_NIL,10);
cc.src_timestamp := gen_duration(1,0);
-- TEST: NORMAL ADD_CACHE_CHANGE
-- TEST: NORMAL SAMPLE
-- TEST: SAMPLE WITH ALIGNED PAYLOAD
Log("RTPS Operation ADD_CACHE_CHANGE [Writer 0, Aligned Payload] (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_RECEPTION_TIMESTAMP_DESTINATION_ORDER_QOS);
start_rtps;
wait_on_rtps;
-- MEM: S1, 0
-- ISTATE: ALIVE
-- WRITER: W0
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.payload := gen_payload(HANDLE_NIL,30);
cc.src_timestamp := gen_duration(2,0);
-- TEST: ADD SAMPLE BIGGER THAN AVAILABLE MEMORY SPACE
Log("RTPS Operation ADD_CACHE_CHANGE [Writer 0, Aligned Payload (3 Slots)] (REJECTED: Payload Memory exceeded)", INFO);
rtps := DEFAULT_RTPS_READER_TEST;
rtps.opcode := ADD_CACHE_CHANGE;
rtps.cc := cc;
rtps.writer_pos := 0;
rtps.ret_code := REJECTED;
start_rtps;
wait_on_rtps;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.payload := gen_payload(HANDLE_NIL,18);
cc.src_timestamp := gen_duration(2,0);
-- TEST: SAMPLE WITH UNALIGNED PAYLOAD [>1 SLOT]
Log("RTPS Operation ADD_CACHE_CHANGE [Writer 0, Unaligned Payload (2 Slots)] (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_RECEPTION_TIMESTAMP_DESTINATION_ORDER_QOS);
start_rtps;
wait_on_rtps;
-- MEM: S1, S2
-- ISTATE: ALIVE
-- WRITER: W0
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.payload := gen_payload(HANDLE_NIL,10);
cc.src_timestamp := gen_duration(3,0);
-- TEST: ADD SAMPLE ON MAX_SAMPLES
Log("RTPS Operation ADD_CACHE_CHANGE [Writer 0, Aligned Payload] (REJECTED: MAX_SAMPLES exceeded)", INFO);
rtps := DEFAULT_RTPS_READER_TEST;
rtps.opcode := ADD_CACHE_CHANGE;
rtps.cc := cc;
rtps.writer_pos := 0;
rtps.ret_code := REJECTED;
start_rtps;
wait_on_rtps;
-- VALIDATE STATE
Log("DDS Operation TAKE [MAX_SAMPLES 2, ANY_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE]", INFO);
dds := DEFAULT_DDS_READER_TEST;
dds.opcode := TAKE;
dds.max_samples := 2;
dds.sstate := ANY_SAMPLE_STATE;
dds.istate := ANY_INSTANCE_STATE;
dds.vstate := ANY_VIEW_STATE;
start_dds;
wait_on_dds;
-- MEM: 0, 0
-- ISTATE: ALIVE
-- WRITER: W0
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := NOT_ALIVE_DISPOSED;
cc.src_timestamp := gen_duration(3,0);
-- TEST: DISPOSE SAMPLE
Log("RTPS Operation ADD_CACHE_CHANGE [DISPOSE, Writer 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,NOT_ALIVE_DISPOSED_INSTANCE_STATE);
add_sample(s,mem, BY_RECEPTION_TIMESTAMP_DESTINATION_ORDER_QOS);
start_rtps;
wait_on_rtps;
-- MEM: S3-, 0
-- ISTATE: DISPOSED
-- WRITER: W0
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := NOT_ALIVE_DISPOSED;
cc.src_timestamp := gen_duration(4,0);
-- TEST: DISPOSE SAMPLE [NOT_ALIVE_DISPOSED INSTANCE]
Log("RTPS Operation ADD_CACHE_CHANGE [DISPOSE, Writer 0] (IGNORED)", INFO);
rtps := DEFAULT_RTPS_READER_TEST;
rtps.opcode := ADD_CACHE_CHANGE;
rtps.cc := cc;
rtps.writer_pos := 0;
rtps.ret_code := OK;
start_rtps;
wait_on_rtps;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE_FILTERED;
cc.src_timestamp := gen_duration(4,0);
-- TEST: FILTER SAMPLE
-- TEST: FILTER SAMPLE [NOT_ALIVE_DISPOSED INSTANCE]
Log("RTPS Operation ADD_CACHE_CHANGE [FILTERED, Writer 0] (IGNORED)", 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_RECEPTION_TIMESTAMP_DESTINATION_ORDER_QOS);
start_rtps;
wait_on_rtps;
-- MEM: S3-, S4-
-- ISTATE: ALIVE
-- WRITER: W0
-- VALIDATE STATE
Log("DDS Operation TAKE [MAX_SAMPLES 2, ANY_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE]", INFO);
dds := DEFAULT_DDS_READER_TEST;
dds.opcode := TAKE;
dds.max_samples := 2;
dds.sstate := ANY_SAMPLE_STATE;
dds.istate := ANY_INSTANCE_STATE;
dds.vstate := ANY_VIEW_STATE;
start_dds;
wait_on_dds;
-- MEM: 0, 0
-- ISTATE: ALIVE
-- WRITER: W0
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.payload := gen_payload(HANDLE_NIL,30);
cc.src_timestamp := gen_duration(5,0);
Log("RTPS Operation ADD_CACHE_CHANGE [Writer 0, Aligned Payload (3 Slots)] (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_RECEPTION_TIMESTAMP_DESTINATION_ORDER_QOS);
start_rtps;
wait_on_rtps;
-- MEM: S5++, 0
-- ISTATE: ALIVE
-- WRITER: W0
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.payload := gen_payload(HANDLE_NIL,10);
cc.src_timestamp := gen_duration(6,0);
-- TEST: ADD_CACHE_CHANGE ON PAYLOAD MEMORY FULL
Log("RTPS Operation ADD_CACHE_CHANGE [Writer 0, Aligned Payload] (REJECTED: Payload Memory Full)", INFO);
rtps := DEFAULT_RTPS_READER_TEST;
rtps.opcode := ADD_CACHE_CHANGE;
rtps.cc := cc;
rtps.writer_pos := 0;
rtps.ret_code := REJECTED;
start_rtps;
wait_on_rtps;
-- TEST: REMOVE_WRITER [UNKNOWN WRITER]
Log("RTPS Operation REMOVE_WRITER [Writer 1] (IGNORED)", INFO);
rtps := DEFAULT_RTPS_READER_TEST;
rtps.opcode := REMOVE_WRITER;
rtps.writer_pos := 1;
rtps.ret_code := OK;
start_rtps;
wait_on_rtps;
-- VALIDATE STATE
Log("DDS Operation TAKE [MAX_SAMPLES 1, ANY_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE]", 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;
start_dds;
wait_on_dds;
-- MEM: 0, 0
-- ISTATE: ALIVE
-- WRITER: W0
-- TEST: REMOVE_WRITER [KNOWN WRITER]
Log("RTPS Operation REMOVE_WRITER [Writer 0] (ACCEPTED)", INFO);
rtps := DEFAULT_RTPS_READER_TEST;
rtps.opcode := REMOVE_WRITER;
rtps.writer_pos := 0;
change_istate(HANDLE_NIL, NOT_ALIVE_NO_WRITERS_INSTANCE_STATE, mem);
rtps.ret_code := OK;
start_rtps;
wait_on_rtps;
-- MEM: S6-, 0
-- ISTATE: NO_WRITERS
-- WRITER: -
-- TEST: FILTER SAMPLE [NOT_ALIVE_NO_WRITERS INSTANCE]
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE_FILTERED;
cc.src_timestamp := gen_duration(7,0);
Log("RTPS Operation ADD_CACHE_CHANGE [FILTERED, Writer 1] (IGNORED)", 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;
-- MEM: S6-, S7-
-- ISTATE: ALIVE
-- WRITER: W1
-- VALIDATE STATE
Log("DDS Operation TAKE [MAX_SAMPLES 2, ANY_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE]", INFO);
dds := DEFAULT_DDS_READER_TEST;
dds.opcode := TAKE;
dds.max_samples := 2;
dds.sstate := ANY_SAMPLE_STATE;
dds.istate := ANY_INSTANCE_STATE;
dds.vstate := ANY_VIEW_STATE;
start_dds;
wait_on_dds;
-- MEM: 0, 0
-- ISTATE: ALIVE
-- WRITER: W1
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := NOT_ALIVE_UNREGISTERED;
cc.src_timestamp := gen_duration(8,0);
-- TEST: UNREGISTER SAMPLE [UNKNOWN WRITER]
Log("RTPS Operation ADD_CACHE_CHANGE [UNREGISTER, Writer 0] (IGNORED)", INFO);
rtps := DEFAULT_RTPS_READER_TEST;
rtps.opcode := ADD_CACHE_CHANGE;
rtps.cc := cc;
rtps.writer_pos := 0;
rtps.ret_code := OK;
start_rtps;
wait_on_rtps;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := NOT_ALIVE_UNREGISTERED;
cc.src_timestamp := gen_duration(8,0);
-- TEST: UNREGISTER SAMPLE [KNOWN WRITER]
Log("RTPS Operation ADD_CACHE_CHANGE [UNREGISTER, Writer 1] (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_NO_WRITERS_INSTANCE_STATE);
add_sample(s,mem, BY_RECEPTION_TIMESTAMP_DESTINATION_ORDER_QOS);
start_rtps;
wait_on_rtps;
-- MEM: S7-, 0
-- ISTATE: NO_WRITERS
-- WRITER: -
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := NOT_ALIVE_UNREGISTERED;
cc.src_timestamp := gen_duration(8,0);
-- TEST: UNREGISTER SAMPLE [NOT_ALIVE_NO_WRITERS INSTANCE]
Log("RTPS Operation ADD_CACHE_CHANGE [UNREGISTER, Writer 0] (IGNORED)", INFO);
rtps := DEFAULT_RTPS_READER_TEST;
rtps.opcode := ADD_CACHE_CHANGE;
rtps.cc := cc;
rtps.writer_pos := 0;
rtps.ret_code := OK;
start_rtps;
wait_on_rtps;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := NOT_ALIVE_DISPOSED;
cc.src_timestamp := gen_duration(8,0);
-- TEST: DISPOSE SAMPLE [NOT_ALIVE_NO_WRITERS INSTANCE]
Log("RTPS Operation ADD_CACHE_CHANGE [DISPOSE, Writer 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,NOT_ALIVE_DISPOSED_INSTANCE_STATE);
add_sample(s,mem, BY_RECEPTION_TIMESTAMP_DESTINATION_ORDER_QOS);
start_rtps;
wait_on_rtps;
-- MEM: S7-, S8-
-- ISTATE: DISPOSED
-- WRITER: W0
-- VALIDATE STATE
Log("DDS Operation TAKE [MAX_SAMPLES 2, ANY_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE]", INFO);
dds := DEFAULT_DDS_READER_TEST;
dds.opcode := TAKE;
dds.max_samples := 2;
dds.sstate := ANY_SAMPLE_STATE;
dds.istate := ANY_INSTANCE_STATE;
dds.vstate := ANY_VIEW_STATE;
start_dds;
wait_on_dds;
-- MEM: 0, 0
-- ISTATE: DISPOSED
-- WRITER: W0
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := NOT_ALIVE_UNREGISTERED;
cc.src_timestamp := gen_duration(9,0);
-- TEST: UNREGISTER SAMPLE [NOT_ALIVE_DISPOSED INSTANCE]
Log("RTPS Operation ADD_CACHE_CHANGE [UNREGISTER, Writer 0] (IGNORED)", INFO);
rtps := DEFAULT_RTPS_READER_TEST;
rtps.opcode := ADD_CACHE_CHANGE;
rtps.cc := cc;
rtps.writer_pos := 0;
rtps.ret_code := OK;
start_rtps;
wait_on_rtps;
-- MEM: 0, 0
-- ISTATE: DISPOSED
-- WRITER: -
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.payload := gen_payload(HANDLE_NIL,6);
cc.src_timestamp := gen_duration(9,0);
-- TEST: SAMPLE WITH UNALIGNED PAYLOAD [<1 SLOT]
Log("RTPS Operation ADD_CACHE_CHANGE [Writer 2, Unaligned Payload (1 Slot)] (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_RECEPTION_TIMESTAMP_DESTINATION_ORDER_QOS);
start_rtps;
wait_on_rtps;
-- MEM: S9, 0
-- ISTATE: ALIVE
-- WRITER: W2
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.payload := gen_payload(HANDLE_NIL,10);
cc.src_timestamp := gen_duration(5,0);
-- TEST: SAMPLE WITH EARLY TIMESTAMP [TIMESTAMP EARLIER THAN LAST READ]
Log("RTPS Operation ADD_CACHE_CHANGE [Writer 1, Aligned Payload] (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;
-- MEM: S9, S10
-- ISTATE: ALIVE
-- WRITER: W1, W2
-- VALIDATE STATE
Log("DDS Operation READ [MAX_SAMPLES 2, ANY_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE]", INFO);
dds := DEFAULT_DDS_READER_TEST;
dds.opcode := READ;
dds.max_samples := 2;
dds.sstate := ANY_SAMPLE_STATE;
dds.istate := ANY_INSTANCE_STATE;
dds.vstate := ANY_VIEW_STATE;
start_dds;
wait_on_dds;
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, INSTANCE_PRESENTATION_QOS, FALSE);
dds_stage <= CHECK_SI;
dds_cnt <= 0;
when others =>
dds_stage <= IDLE;
end case;
end if;
when CHECK_SI =>
if (si_valid = '1') then
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, convert_from_double_word(si_source_timestamp), convert_from_double_word(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 (dds_cnt = col.len-1) then
AffirmIf(last_id, si_last = '1', "Last Signal not pulled High");
else
AffirmIf(last_id, si_last = '0', "Last Signal pulled High");
end if;
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 <= IDLE;
else
dds_cnt <= dds_cnt + 1;
end if;
end if;
end if;
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 <= IDLE;
else
dds_stage <= CHECK_SI;
dds_cnt <= dds_cnt + 1;
end if;
end if;
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;
kh_prc : process (all)
variable tmp_key_hash : INSTANCE_HANDLE_TYPE := HANDLE_NIL;
begin
if rising_edge(clk) then
case (kh_stage) is
when IDLE =>
if (start_kh = '1') then
case (opcode_kh) is
when PUSH_DATA =>
kh_stage <= READ_DATA;
kh_cnt <= 0;
kh_data <= EMPTY_TEST_PACKET;
when PUSH_SERIALIZED_KEY =>
kh_stage <= READ_DATA;
kh_cnt <= 0;
kh_data <= EMPTY_TEST_PACKET;
when READ_KEY_HASH =>
kh_stage <= PUSH_KEY_HASH;
kh_cnt <= 0;
when others =>
Alert("Unexpected Key Holder Operation", FAILURE);
end case;
end if;
when READ_DATA =>
if (valid_out_kh = '1') then
kh_data.data(kh_cnt) <= data_out_kh;
kh_data.last(kh_cnt) <= last_word_out_kh;
kh_data.length <= kh_data.length + 1;
kh_cnt <= kh_cnt + 1;
if (last_word_out_kh = '1') then
kh_stage <= IDLE;
end if;
end if;
when PUSH_KEY_HASH =>
if (ready_in_kh = '1') then
kh_cnt <= kh_cnt + 1;
if (kh_cnt = INSTANCE_HANDLE_TYPE'length-1) then
kh_stage <= IDLE;
end if;
end if;
end case;
end if;
-- DEFAULT
ack_kh <= '0';
ready_out_kh <= '0';
valid_in_kh <= '0';
data_in_kh <= (others => '0');
last_word_in_kh <= '0';
case (kh_stage) is
when IDLE =>
if (start_kh = '1') then
ack_kh <= '1';
end if;
when READ_DATA =>
ready_out_kh <= '1';
when PUSH_KEY_HASH =>
valid_in_kh <= '1';
tmp_key_hash := extract_key_hash(kh_data);
data_in_kh <= tmp_key_hash(kh_cnt);
if (kh_cnt = INSTANCE_HANDLE_TYPE'length-1) then
last_word_in_kh <= '1';
end if;
end case;
end process;
watchdog : process
begin
wait for 1 ms;
Alert("Test timeout", FAILURE);
std.env.stop;
end process;
end architecture;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -19,29 +19,9 @@ architecture testbench of L0_dds_writer_test2_aik is
constant MAX_REMOTE_ENDPOINTS : natural := 3;
-- *TYPE DECLARATION*
type STIM_STAGE_TYPE is (IDLE, START, PUSH, DONE, CHECK);
type REF_STAGE_TYPE is (IDLE, START, DONE, CHECK);
type DDS_STAGE_TYPE is (IDLE, START, PUSH, DONE, CHECK);
type RTPS_STAGE_TYPE is (IDLE, START, DONE, CHECK);
type KH_STAGE_TYPE is (IDLE, READ_DATA, PUSH_KEY_HASH);
type RTPS_TEST_TYPE is record
opcode : HISTORY_CACHE_OPCODE_TYPE;
cc : CACHE_CHANGE_TYPE;
ret_code : HISTORY_CACHE_RESPONSE_TYPE;
end record;
constant DEFAULT_RTPS_TEST : RTPS_TEST_TYPE := (
opcode => NOP,
cc => DEFAULT_CACHE_CHANGE,
ret_code => OK
);
type DDS_TEST_TYPE is record
opcode : DDS_WRITER_OPCODE_TYPE;
cc : CACHE_CHANGE_TYPE;
ret_code : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
end record;
constant DEFAULT_DDS_TEST : DDS_TEST_TYPE := (
opcode => NOP,
cc => DEFAULT_CACHE_CHANGE,
ret_code => RETCODE_OK
);
-- *SIGNAL DECLARATION*
signal clk : std_logic := '0';
@ -65,14 +45,14 @@ architecture testbench of L0_dds_writer_test2_aik is
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 stim_start, stim_done, ref_start, ref_done : std_logic := '0';
signal stim_cnt, ref_cnt, kh_cnt : natural := 0;
signal stim_stage : STIM_STAGE_TYPE := IDLE;
signal ref_stage : REF_STAGE_TYPE := IDLE;
signal dds_start, dds_done, rtps_start, rtps_done : std_logic := '0';
signal dds_cnt, rtps_cnt, kh_cnt : natural := 0;
signal dds_stage : DDS_STAGE_TYPE := IDLE;
signal rtps_stage : RTPS_STAGE_TYPE := IDLE;
signal kh_stage : KH_STAGE_TYPE := IDLE;
signal kh_data : TEST_PACKET_TYPE := EMPTY_TEST_PACKET;
shared variable stimulus : DDS_TEST_TYPE := DEFAULT_DDS_TEST;
shared variable reference : RTPS_TEST_TYPE := DEFAULT_RTPS_TEST;
shared variable dds : DDS_WRITER_TEST_TYPE := DEFAULT_DDS_WRITER_TEST;
shared variable rtps : RTPS_WRITER_TEST_TYPE := DEFAULT_RTPS_WRITER_TEST;
signal inst_id, kind_id, sn_id, ts_id, data_id, ret_id : AlertLogIDType;
-- *FUNCTION DECLARATION*
@ -194,40 +174,40 @@ begin
return ret;
end function;
procedure start_stim is
procedure start_dds is
begin
stim_start <= '1';
dds_start <= '1';
wait until rising_edge(clk);
stim_start <= '0';
dds_start <= '0';
wait until rising_edge(clk);
end procedure;
procedure start_ref is
procedure start_rtps is
begin
ref_start <= '1';
rtps_start <= '1';
wait until rising_edge(clk);
ref_start <= '0';
rtps_start <= '0';
wait until rising_edge(clk);
end procedure;
procedure wait_on_stim is
procedure wait_on_dds is
begin
if (stim_done /= '1') then
wait until stim_done = '1';
if (dds_done /= '1') then
wait until dds_done = '1';
end if;
end procedure;
procedure wait_on_ref is
procedure wait_on_rtps is
begin
if (ref_done /= '1') then
wait until ref_done = '1';
if (rtps_done /= '1') then
wait until rtps_done = '1';
end if;
end procedure;
procedure wait_on_completion is
begin
if (ref_done /= '1' or stim_done /= '1') then
wait until ref_done = '1' and stim_done = '1';
if (rtps_done /= '1' or dds_done /= '1') then
wait until rtps_done = '1' and dds_done = '1';
end if;
end procedure;
@ -266,13 +246,14 @@ begin
-- Stored CC: 0, 0, 0, 0
Log("DDS Operation WAIT_FOR_ACKNOWLEDGEMENTS [max_wait 0s] (OK)", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := WAIT_FOR_ACKNOWLEDGEMENTS;
stimulus.ret_code := RETCODE_OK;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := WAIT_FOR_ACKNOWLEDGEMENTS;
dds.ret_code := RETCODE_OK;
max_wait_dds <= gen_duration(0,0);
start_stim;
wait_on_stim;
start_dds;
wait_on_dds;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh1;
@ -281,16 +262,17 @@ begin
cc.src_timestamp := gen_duration(1,0);
Log("DDS Operation WRITE [TS 1s, Instance 1, HANDLE_NIL, Aligned Payload] (ACCEPTED)", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := WRITE;
stimulus.cc := cc;
stimulus.cc.instance:= HANDLE_NIL;
stimulus.ret_code := RETCODE_OK;
start_stim;
wait_on_stim;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := WRITE;
dds.cc := cc;
dds.cc.instance:= HANDLE_NIL;
dds.ret_code := RETCODE_OK;
start_dds;
wait_on_dds;
cc1 := cc;
-- Stored CC: I1S1, 0, 0, 0
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh2;
@ -299,59 +281,59 @@ begin
cc.src_timestamp := gen_duration(2,0);
Log("DDS Operation WRITE [TS 2s, Instance 2, HANDLE_NIL, Aligned Payload] (ACCEPTED)", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := WRITE;
stimulus.cc := cc;
stimulus.cc.instance:= HANDLE_NIL;
stimulus.ret_code := RETCODE_OK;
start_stim;
wait_on_stim;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := WRITE;
dds.cc := cc;
dds.cc.instance:= HANDLE_NIL;
dds.ret_code := RETCODE_OK;
start_dds;
wait_on_dds;
cc2 := cc;
-- Stored CC: I1S1, I2S2, 0, 0
Log("DDS Operation WAIT_FOR_ACKNOWLEDGEMENTS [max_wait 0s] (TIMEOUT)", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := WAIT_FOR_ACKNOWLEDGEMENTS;
stimulus.ret_code := RETCODE_TIMEOUT;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := WAIT_FOR_ACKNOWLEDGEMENTS;
dds.ret_code := RETCODE_TIMEOUT;
max_wait_dds <= gen_duration(0,0);
start_stim;
wait_on_stim;
start_dds;
wait_on_dds;
Log("DDS Operation WAIT_FOR_ACKNOWLEDGEMENTS [max_wait 1s]", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := WAIT_FOR_ACKNOWLEDGEMENTS;
stimulus.ret_code := RETCODE_TIMEOUT;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := WAIT_FOR_ACKNOWLEDGEMENTS;
dds.ret_code := RETCODE_TIMEOUT;
max_wait_dds <= gen_duration(1,0);
start_stim;
start_dds;
Log("RTPS Operation ACK_CACHE_CHANGE SN 1", INFO);
reference := DEFAULT_RTPS_TEST;
reference.opcode := ACK_CACHE_CHANGE;
reference.cc := cc1;
start_ref;
wait_on_ref;
rtps := DEFAULT_RTPS_WRITER_TEST;
rtps.opcode := ACK_CACHE_CHANGE;
rtps.cc := cc1;
start_rtps;
wait_on_rtps;
Log("Current Time: 1s", INFO);
Log("WAIT_FOR_ACKNOWLEDGEMENTS Return (TIMEOUT)", INFO);
check_time <= gen_duration(1,0);
wait until rising_edge(clk);
wait_on_stim;
wait_on_dds;
Log("DDS Operation WAIT_FOR_ACKNOWLEDGEMENTS [max_wait 1s]", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := WAIT_FOR_ACKNOWLEDGEMENTS;
stimulus.ret_code := RETCODE_OK;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := WAIT_FOR_ACKNOWLEDGEMENTS;
dds.ret_code := RETCODE_OK;
max_wait_dds <= gen_duration(1,0);
start_stim;
start_dds;
Log("RTPS Operation ACK_CACHE_CHANGE SN 2", INFO);
Log("WAIT_FOR_ACKNOWLEDGEMENTS Return (OK)", INFO);
reference := DEFAULT_RTPS_TEST;
reference.opcode := ACK_CACHE_CHANGE;
reference.cc := cc2;
start_ref;
wait_on_ref;
wait_on_stim;
rtps := DEFAULT_RTPS_WRITER_TEST;
rtps.opcode := ACK_CACHE_CHANGE;
rtps.cc := cc2;
start_rtps;
wait_on_rtps;
wait_on_dds;
wait_on_completion;
TranscriptOpen(RESULTS_FILE, APPEND_MODE);
@ -377,42 +359,42 @@ begin
end if;
end process;
stim_prc : process(all)
dds_prc : process(all)
begin
if rising_edge(clk) then
stim_done <= '0';
case (stim_stage) is
dds_done <= '0';
case (dds_stage) is
when IDLE =>
if (stim_start = '1') then
stim_stage <= START;
if (dds_start = '1') then
dds_stage <= START;
else
stim_done <= '1';
dds_done <= '1';
end if;
when START =>
if (ack_dds = '1') then
case (stimulus.opcode) is
case (dds.opcode) is
when WAIT_FOR_ACKNOWLEDGEMENTS =>
stim_stage <= DONE;
stim_cnt <= 0;
dds_stage <= DONE;
dds_cnt <= 0;
when others =>
stim_stage <= PUSH;
stim_cnt <= 0;
dds_stage <= PUSH;
dds_cnt <= 0;
end case;
end if;
when PUSH =>
if (ready_in_dds = '1') then
stim_cnt <= stim_cnt + 1;
if (stim_cnt = stimulus.cc.payload.length-1) then
dds_cnt <= dds_cnt + 1;
if (dds_cnt = dds.cc.payload.length-1) then
-- DEFAULT
stim_stage <= DONE;
dds_stage <= DONE;
case (stimulus.opcode) is
case (dds.opcode) is
when REGISTER_INSTANCE =>
stim_stage <= CHECK;
stim_cnt <= 0;
dds_stage <= CHECK;
dds_cnt <= 0;
when LOOKUP_INSTANCE =>
stim_stage <= CHECK;
stim_cnt <= 0;
dds_stage <= CHECK;
dds_cnt <= 0;
when others =>
null;
end case;
@ -420,16 +402,16 @@ begin
end if;
when DONE =>
if (done_dds = '1') then
AffirmIfEqual(ret_id, return_code_dds, stimulus.ret_code);
stim_stage <= IDLE;
AffirmIfEqual(ret_id, return_code_dds, dds.ret_code);
dds_stage <= IDLE;
end if;
when CHECK =>
if (valid_out_dds = '1') then
AffirmIfEqual(data_id, data_out_dds, stimulus.cc.instance(stim_cnt));
stim_cnt <= stim_cnt + 1;
if (stim_cnt = 3) then
AffirmIfEqual(data_id, data_out_dds, dds.cc.instance(dds_cnt));
dds_cnt <= dds_cnt + 1;
if (dds_cnt = 3) then
AlertIf(data_id, last_word_out_dds /= '1', "Last Word Signal not pulled High", ERROR);
stim_stage <= IDLE;
dds_stage <= IDLE;
end if;
end if;
end case;
@ -437,6 +419,7 @@ begin
-- DEFAULT
start_dds <= '0';
opcode_dds <= NOP;
valid_in_dds <= '0';
last_word_in_dds <= '0';
data_in_dds <= (others => '0');
@ -444,16 +427,16 @@ begin
source_ts_dds <= TIME_INVALID;
ready_out_dds <= '0';
case (stim_stage) is
case (dds_stage) is
when START =>
start_dds <= '1';
opcode_dds <= stimulus.opcode;
instance_handle_dds <= stimulus.cc.instance;
source_ts_dds <= stimulus.cc.src_timestamp;
opcode_dds <= dds.opcode;
instance_handle_dds <= dds.cc.instance;
source_ts_dds <= dds.cc.src_timestamp;
when PUSH =>
valid_in_dds <= '1';
data_in_dds <= stimulus.cc.payload.data(stim_cnt);
last_word_in_dds <= stimulus.cc.payload.last(stim_cnt);
data_in_dds <= dds.cc.payload.data(dds_cnt);
last_word_in_dds <= dds.cc.payload.last(dds_cnt);
when CHECK =>
ready_out_dds <= '1';
when others =>
@ -461,54 +444,51 @@ begin
end case;
end process;
ref_prc : process(all)
rtps_prc : process(all)
begin
if rising_edge(clk) then
ref_done <= '0';
case (ref_stage) is
rtps_done <= '0';
case (rtps_stage) is
when IDLE =>
if (ref_start = '1') then
ref_stage <= START;
if (rtps_start = '1') then
rtps_stage <= START;
else
ref_done <= '1';
rtps_done <= '1';
end if;
when START =>
if (ack_rtps = '1') then
ref_stage <= DONE;
rtps_stage <= DONE;
end if;
when DONE =>
if (done_rtps = '1') then
-- DEFAULT
ref_stage <= IDLE;
rtps_stage <= IDLE;
AffirmIfEqual(ret_id, HISTORY_CACHE_RESPONSE_TYPE'pos(ret_rtps), HISTORY_CACHE_RESPONSE_TYPE'pos(reference.ret_code));
case (reference.opcode) is
AffirmIfEqual(ret_id, HISTORY_CACHE_RESPONSE_TYPE'pos(ret_rtps), HISTORY_CACHE_RESPONSE_TYPE'pos(rtps.ret_code));
case (rtps.opcode) is
when GET_CACHE_CHANGE =>
if (reference.ret_code = OK) then
AffirmIfEqual(inst_id, cc_instance_handle(0), reference.cc.instance(0));
AffirmIfEqual(inst_id, cc_instance_handle(1), reference.cc.instance(1));
AffirmIfEqual(inst_id, cc_instance_handle(2), reference.cc.instance(2));
AffirmIfEqual(inst_id, cc_instance_handle(3), reference.cc.instance(3));
AffirmIfEqual(kind_id, CACHE_CHANGE_KIND_TYPE'pos(cc_kind), CACHE_CHANGE_KIND_TYPE'pos(reference.cc.kind));
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(reference.cc.seq_nr));
AffirmIfEqual(ts_id, convert_from_double_word(cc_source_timestamp), convert_from_double_word(reference.cc.src_timestamp));
ref_stage <= CHECK;
ref_cnt <= 0;
if (rtps.ret_code = OK) then
AffirmIfEqual(inst_id, to_unsigned(cc_instance_handle), to_unsigned(rtps.cc.instance));
AffirmIfEqual(kind_id, CACHE_CHANGE_KIND_TYPE'pos(cc_kind), CACHE_CHANGE_KIND_TYPE'pos(rtps.cc.kind));
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(rtps.cc.seq_nr));
AffirmIfEqual(ts_id, convert_from_double_word(cc_source_timestamp), convert_from_double_word(rtps.cc.src_timestamp));
rtps_stage <= CHECK;
rtps_cnt <= 0;
end if;
when GET_MIN_SN =>
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(reference.cc.seq_nr));
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(rtps.cc.seq_nr));
when GET_MAX_SN =>
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(reference.cc.seq_nr));
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(rtps.cc.seq_nr));
when others =>
null;
end case;
end if;
when CHECK =>
if (valid_out_rtps = '1') then
AffirmIfEqual(data_id, last_word_out_rtps & data_out_rtps, reference.cc.payload.last(ref_cnt) & reference.cc.payload.data(ref_cnt));
ref_cnt <= ref_cnt + 1;
if (ref_cnt = reference.cc.payload.length-1) then
ref_stage <= IDLE;
AffirmIfEqual(data_id, last_word_out_rtps & data_out_rtps, rtps.cc.payload.last(rtps_cnt) & rtps.cc.payload.data(rtps_cnt));
rtps_cnt <= rtps_cnt + 1;
if (rtps_cnt = rtps.cc.payload.length-1) then
rtps_stage <= IDLE;
end if;
end if;
end case;
@ -516,17 +496,19 @@ begin
-- DEFAULT
start_rtps <= '0';
opcode_rtps <= NOP;
seq_nr_rtps <= SEQUENCENUMBER_UNKNOWN;
get_data_rtps <= '0';
ready_out_rtps <= '0';
case (ref_stage) is
case (rtps_stage) is
when START =>
start_rtps <= '1';
opcode_rtps <= reference.opcode;
seq_nr_rtps <= reference.cc.seq_nr;
opcode_rtps <= rtps.opcode;
seq_nr_rtps <= rtps.cc.seq_nr;
when DONE =>
if (done_rtps = '1') then
case (reference.opcode) is
case (rtps.opcode) is
when GET_CACHE_CHANGE =>
get_data_rtps <= '1';
when others =>

View File

@ -19,35 +19,9 @@ architecture testbench of L0_dds_writer_test3_aik is
constant MAX_REMOTE_ENDPOINTS : natural := 3;
-- *TYPE DECLARATION*
type STIM_STAGE_TYPE is (IDLE, START, PUSH, DONE, CHECK, CHECK_DEADLINE);
type REF_STAGE_TYPE is (IDLE, START, DONE, CHECK);
type DDS_STAGE_TYPE is (IDLE, START, PUSH, DONE, CHECK, CHECK_DEADLINE);
type RTPS_STAGE_TYPE is (IDLE, START, DONE, CHECK);
type KH_STAGE_TYPE is (IDLE, READ_DATA, PUSH_KEY_HASH);
type RTPS_TEST_TYPE is record
opcode : HISTORY_CACHE_OPCODE_TYPE;
cc : CACHE_CHANGE_TYPE;
ret_code : HISTORY_CACHE_RESPONSE_TYPE;
end record;
constant DEFAULT_RTPS_TEST : RTPS_TEST_TYPE := (
opcode => NOP,
cc => DEFAULT_CACHE_CHANGE,
ret_code => OK
);
type DDS_TEST_TYPE is record
opcode : DDS_WRITER_OPCODE_TYPE;
cc : CACHE_CHANGE_TYPE;
ret_code : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
count : natural;
change : natural;
instance : INSTANCE_HANDLE_TYPE;
end record;
constant DEFAULT_DDS_TEST : DDS_TEST_TYPE := (
opcode => NOP,
cc => DEFAULT_CACHE_CHANGE,
ret_code => RETCODE_OK,
count => 0,
change => 0,
instance => HANDLE_NIL
);
-- *SIGNAL DECLARATION*
signal clk : std_logic := '0';
@ -71,14 +45,14 @@ architecture testbench of L0_dds_writer_test3_aik is
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 stim_start, stim_done, ref_start, ref_done : std_logic := '0';
signal stim_cnt, ref_cnt, kh_cnt : natural := 0;
signal stim_stage : STIM_STAGE_TYPE := IDLE;
signal ref_stage : REF_STAGE_TYPE := IDLE;
signal dds_start, dds_done, rtps_start, rtps_done : std_logic := '0';
signal dds_cnt, rtps_cnt, kh_cnt : natural := 0;
signal dds_stage : DDS_STAGE_TYPE := IDLE;
signal rtps_stage : RTPS_STAGE_TYPE := IDLE;
signal kh_stage : KH_STAGE_TYPE := IDLE;
signal kh_data : TEST_PACKET_TYPE := EMPTY_TEST_PACKET;
shared variable stimulus : DDS_TEST_TYPE := DEFAULT_DDS_TEST;
shared variable reference : RTPS_TEST_TYPE := DEFAULT_RTPS_TEST;
shared variable dds : DDS_WRITER_TEST_TYPE := DEFAULT_DDS_WRITER_TEST;
shared variable rtps : RTPS_WRITER_TEST_TYPE := DEFAULT_RTPS_WRITER_TEST;
signal inst_id, kind_id, sn_id, ts_id, data_id, ret_id, status_id : AlertLogIDType;
-- *FUNCTION DECLARATION*
@ -202,40 +176,40 @@ begin
return ret;
end function;
procedure start_stim is
procedure start_dds is
begin
stim_start <= '1';
dds_start <= '1';
wait until rising_edge(clk);
stim_start <= '0';
dds_start <= '0';
wait until rising_edge(clk);
end procedure;
procedure start_ref is
procedure start_rtps is
begin
ref_start <= '1';
rtps_start <= '1';
wait until rising_edge(clk);
ref_start <= '0';
rtps_start <= '0';
wait until rising_edge(clk);
end procedure;
procedure wait_on_stim is
procedure wait_on_dds is
begin
if (stim_done /= '1') then
wait until stim_done = '1';
if (dds_done /= '1') then
wait until dds_done = '1';
end if;
end procedure;
procedure wait_on_ref is
procedure wait_on_rtps is
begin
if (ref_done /= '1') then
wait until ref_done = '1';
if (rtps_done /= '1') then
wait until rtps_done = '1';
end if;
end procedure;
procedure wait_on_completion is
begin
if (ref_done /= '1' or stim_done /= '1') then
wait until ref_done = '1' and stim_done = '1';
if (rtps_done /= '1' or dds_done /= '1') then
wait until rtps_done = '1' and dds_done = '1';
end if;
end procedure;
@ -300,6 +274,7 @@ begin
AffirmIf(status_id,(status and OFFERED_DEADLINE_MISSED_STATUS) /= OFFERED_DEADLINE_MISSED_STATUS, "Expected: 0", "Received 1");
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh1;
@ -307,16 +282,17 @@ begin
cc.seq_nr := gen_sn(1);
Log("DDS Operation WRITE [Instance 1, HANDLE_NIL, Aligned Payload] (ACCEPTED)", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := WRITE;
stimulus.cc := cc;
stimulus.cc.instance:= HANDLE_NIL;
stimulus.ret_code := RETCODE_OK;
start_stim;
wait_on_stim;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := WRITE;
dds.cc := cc;
dds.cc.instance:= HANDLE_NIL;
dds.ret_code := RETCODE_OK;
start_dds;
wait_on_dds;
cc1 := cc;
-- Stored CC: I1S1, 0, 0, 0
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh2;
@ -324,13 +300,13 @@ begin
cc.seq_nr := gen_sn(2);
Log("DDS Operation WRITE [Instance 2, HANDLE_NIL, Aligned Payload] (ACCEPTED)", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := WRITE;
stimulus.cc := cc;
stimulus.cc.instance:= HANDLE_NIL;
stimulus.ret_code := RETCODE_OK;
start_stim;
wait_on_stim;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := WRITE;
dds.cc := cc;
dds.cc.instance:= HANDLE_NIL;
dds.ret_code := RETCODE_OK;
start_dds;
wait_on_dds;
cc2 := cc;
-- Stored CC: I1S1, I2S2, 0, 0
@ -342,6 +318,7 @@ begin
AffirmIf(status_id,(status and OFFERED_DEADLINE_MISSED_STATUS) /= OFFERED_DEADLINE_MISSED_STATUS, "Expected: 0", "Received 1");
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh1;
@ -349,13 +326,13 @@ begin
cc.seq_nr := gen_sn(3);
Log("DDS Operation WRITE [Instance 1, Aligned Payload] (ACCEPTED)", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := WRITE;
stimulus.cc := cc;
stimulus.cc.instance:= HANDLE_NIL;
stimulus.ret_code := RETCODE_OK;
start_stim;
wait_on_stim;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := WRITE;
dds.cc := cc;
dds.cc.instance:= HANDLE_NIL;
dds.ret_code := RETCODE_OK;
start_dds;
wait_on_dds;
cc3 := cc;
-- Stored CC: I1S1, I2S2, I1S3, 0
@ -368,18 +345,19 @@ begin
AffirmIf(status_id,(status and OFFERED_DEADLINE_MISSED_STATUS) = OFFERED_DEADLINE_MISSED_STATUS, "Expected: 1", "Received 0");
Log("DDS Operation GET_OFFERED_DEADLINE_MISSED_STATUS (Expected: count 1, change 1, Instance 2)", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := GET_OFFERED_DEADLINE_MISSED_STATUS;
stimulus.ret_code := RETCODE_OK;
stimulus.count := 1;
stimulus.change := 1;
stimulus.instance := kh2;
start_stim;
wait_on_stim;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := GET_OFFERED_DEADLINE_MISSED_STATUS;
dds.ret_code := RETCODE_OK;
dds.count := 1;
dds.change := 1;
dds.inst := kh2;
start_dds;
wait_on_dds;
wait_on_idle;
AffirmIf(status_id,(status and OFFERED_DEADLINE_MISSED_STATUS) /= OFFERED_DEADLINE_MISSED_STATUS, "Expected: 0", "Received 1");
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh3;
@ -387,13 +365,13 @@ begin
cc.seq_nr := gen_sn(4);
Log("DDS Operation WRITE [Instance 3, Aligned Payload] (ACCEPTED)", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := WRITE;
stimulus.cc := cc;
stimulus.cc.instance:= HANDLE_NIL;
stimulus.ret_code := RETCODE_OK;
start_stim;
wait_on_stim;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := WRITE;
dds.cc := cc;
dds.cc.instance:= HANDLE_NIL;
dds.ret_code := RETCODE_OK;
start_dds;
wait_on_dds;
cc4 := cc;
-- Stored CC: I1S1, I2S2, I1S3, I3S4
@ -406,14 +384,14 @@ begin
AffirmIf(status_id,(status and OFFERED_DEADLINE_MISSED_STATUS) = OFFERED_DEADLINE_MISSED_STATUS, "Expected: 1", "Received 0");
Log("DDS Operation GET_OFFERED_DEADLINE_MISSED_STATUS (Expected: count 3, change 2, Instance 2)", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := GET_OFFERED_DEADLINE_MISSED_STATUS;
stimulus.ret_code := RETCODE_OK;
stimulus.count := 3;
stimulus.change := 2;
stimulus.instance := kh1;
start_stim;
wait_on_stim;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := GET_OFFERED_DEADLINE_MISSED_STATUS;
dds.ret_code := RETCODE_OK;
dds.count := 3;
dds.change := 2;
dds.inst := kh1;
start_dds;
wait_on_dds;
wait_on_idle;
AffirmIf(status_id,(status and OFFERED_DEADLINE_MISSED_STATUS) /= OFFERED_DEADLINE_MISSED_STATUS, "Expected: 0", "Received 1");
@ -435,14 +413,14 @@ begin
AffirmIf(status_id,(status and OFFERED_DEADLINE_MISSED_STATUS) = OFFERED_DEADLINE_MISSED_STATUS, "Expected: 1", "Received 0");
Log("DDS Operation GET_OFFERED_DEADLINE_MISSED_STATUS (Expected: count 3, change 2, Instance 2)", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := GET_OFFERED_DEADLINE_MISSED_STATUS;
stimulus.ret_code := RETCODE_OK;
stimulus.count := 9;
stimulus.change := 6;
stimulus.instance := kh1;
start_stim;
wait_on_stim;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := GET_OFFERED_DEADLINE_MISSED_STATUS;
dds.ret_code := RETCODE_OK;
dds.count := 9;
dds.change := 6;
dds.inst := kh1;
start_dds;
wait_on_dds;
wait_on_idle;
AffirmIf(status_id,(status and OFFERED_DEADLINE_MISSED_STATUS) /= OFFERED_DEADLINE_MISSED_STATUS, "Expected: 0", "Received 1");
@ -471,42 +449,42 @@ begin
end if;
end process;
stim_prc : process(all)
dds_prc : process(all)
begin
if rising_edge(clk) then
stim_done <= '0';
case (stim_stage) is
dds_done <= '0';
case (dds_stage) is
when IDLE =>
if (stim_start = '1') then
stim_stage <= START;
if (dds_start = '1') then
dds_stage <= START;
else
stim_done <= '1';
dds_done <= '1';
end if;
when START =>
if (ack_dds = '1') then
case (stimulus.opcode) is
case (dds.opcode) is
when GET_OFFERED_DEADLINE_MISSED_STATUS =>
stim_stage <= DONE;
stim_cnt <= 0;
dds_stage <= DONE;
dds_cnt <= 0;
when others =>
stim_stage <= PUSH;
stim_cnt <= 0;
dds_stage <= PUSH;
dds_cnt <= 0;
end case;
end if;
when PUSH =>
if (ready_in_dds = '1') then
stim_cnt <= stim_cnt + 1;
if (stim_cnt = stimulus.cc.payload.length-1) then
dds_cnt <= dds_cnt + 1;
if (dds_cnt = dds.cc.payload.length-1) then
-- DEFAULT
stim_stage <= DONE;
dds_stage <= DONE;
case (stimulus.opcode) is
case (dds.opcode) is
when REGISTER_INSTANCE =>
stim_stage <= CHECK;
stim_cnt <= 0;
dds_stage <= CHECK;
dds_cnt <= 0;
when LOOKUP_INSTANCE =>
stim_stage <= CHECK;
stim_cnt <= 0;
dds_stage <= CHECK;
dds_cnt <= 0;
when others =>
null;
end case;
@ -514,46 +492,46 @@ begin
end if;
when DONE =>
if (done_dds = '1') then
AffirmIfEqual(ret_id, return_code_dds, stimulus.ret_code);
case (stimulus.opcode) is
AffirmIfEqual(ret_id, return_code_dds, dds.ret_code);
case (dds.opcode) is
when GET_OFFERED_DEADLINE_MISSED_STATUS =>
if (stimulus.ret_code = RETCODE_OK) then
stim_stage <= CHECK_DEADLINE;
stim_cnt <= 0;
if (dds.ret_code = RETCODE_OK) then
dds_stage <= CHECK_DEADLINE;
dds_cnt <= 0;
else
stim_stage <= IDLE;
dds_stage <= IDLE;
end if;
when others =>
stim_stage <= IDLE;
dds_stage <= IDLE;
end case;
end if;
when CHECK =>
if (valid_out_dds = '1') then
AffirmIfEqual(data_id, data_out_dds, stimulus.cc.instance(stim_cnt));
stim_cnt <= stim_cnt + 1;
if (stim_cnt = 3) then
AffirmIfEqual(data_id, data_out_dds, dds.cc.instance(dds_cnt));
dds_cnt <= dds_cnt + 1;
if (dds_cnt = 3) then
AlertIf(data_id, last_word_out_dds /= '1', "Last Word Signal not pulled High", ERROR);
stim_stage <= IDLE;
dds_stage <= IDLE;
end if;
end if;
when CHECK_DEADLINE =>
if (valid_out_dds = '1') then
stim_cnt <= stim_cnt + 1;
case (stim_cnt) is
dds_cnt <= dds_cnt + 1;
case (dds_cnt) is
when 0 =>
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(to_unsigned(stimulus.count,CDR_LONG_WIDTH)));
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(to_unsigned(dds.count,CDR_LONG_WIDTH)));
when 1 =>
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(to_unsigned(stimulus.change,CDR_LONG_WIDTH)));
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(to_unsigned(dds.change,CDR_LONG_WIDTH)));
when 2 =>
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(stimulus.instance(0)));
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(dds.inst (0)));
when 3 =>
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(stimulus.instance(1)));
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(dds.inst (1)));
when 4 =>
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(stimulus.instance(2)));
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(dds.inst (2)));
when 5 =>
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(stimulus.instance(3)));
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(dds.inst (3)));
AlertIf(data_id, last_word_out_dds /= '1', "Last Word Signal not pulled High", ERROR);
stim_stage <= IDLE;
dds_stage <= IDLE;
when others =>
null;
end case;
@ -563,6 +541,7 @@ begin
-- DEFAULT
start_dds <= '0';
opcode_dds <= NOP;
valid_in_dds <= '0';
last_word_in_dds <= '0';
data_in_dds <= (others => '0');
@ -570,16 +549,16 @@ begin
source_ts_dds <= TIME_INVALID;
ready_out_dds <= '0';
case (stim_stage) is
case (dds_stage) is
when START =>
start_dds <= '1';
opcode_dds <= stimulus.opcode;
instance_handle_dds <= stimulus.cc.instance;
source_ts_dds <= stimulus.cc.src_timestamp;
opcode_dds <= dds.opcode;
instance_handle_dds <= dds.cc.instance;
source_ts_dds <= dds.cc.src_timestamp;
when PUSH =>
valid_in_dds <= '1';
data_in_dds <= stimulus.cc.payload.data(stim_cnt);
last_word_in_dds <= stimulus.cc.payload.last(stim_cnt);
data_in_dds <= dds.cc.payload.data(dds_cnt);
last_word_in_dds <= dds.cc.payload.last(dds_cnt);
when CHECK =>
ready_out_dds <= '1';
when CHECK_DEADLINE =>
@ -589,54 +568,54 @@ begin
end case;
end process;
ref_prc : process(all)
rtps_prc : process(all)
begin
if rising_edge(clk) then
ref_done <= '0';
case (ref_stage) is
rtps_done <= '0';
case (rtps_stage) is
when IDLE =>
if (ref_start = '1') then
ref_stage <= START;
if (rtps_start = '1') then
rtps_stage <= START;
else
ref_done <= '1';
rtps_done <= '1';
end if;
when START =>
if (ack_rtps = '1') then
ref_stage <= DONE;
rtps_stage <= DONE;
end if;
when DONE =>
if (done_rtps = '1') then
-- DEFAULT
ref_stage <= IDLE;
rtps_stage <= IDLE;
AffirmIfEqual(ret_id, HISTORY_CACHE_RESPONSE_TYPE'pos(ret_rtps), HISTORY_CACHE_RESPONSE_TYPE'pos(reference.ret_code));
case (reference.opcode) is
AffirmIfEqual(ret_id, HISTORY_CACHE_RESPONSE_TYPE'pos(ret_rtps), HISTORY_CACHE_RESPONSE_TYPE'pos(rtps.ret_code));
case (rtps.opcode) is
when GET_CACHE_CHANGE =>
if (reference.ret_code = OK) then
AffirmIfEqual(inst_id, cc_instance_handle(0), reference.cc.instance(0));
AffirmIfEqual(inst_id, cc_instance_handle(1), reference.cc.instance(1));
AffirmIfEqual(inst_id, cc_instance_handle(2), reference.cc.instance(2));
AffirmIfEqual(inst_id, cc_instance_handle(3), reference.cc.instance(3));
AffirmIfEqual(kind_id, CACHE_CHANGE_KIND_TYPE'pos(cc_kind), CACHE_CHANGE_KIND_TYPE'pos(reference.cc.kind));
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(reference.cc.seq_nr));
AffirmIfEqual(ts_id, convert_from_double_word(cc_source_timestamp), convert_from_double_word(reference.cc.src_timestamp));
ref_stage <= CHECK;
ref_cnt <= 0;
if (rtps.ret_code = OK) then
AffirmIfEqual(inst_id, cc_instance_handle(0), rtps.cc.instance(0));
AffirmIfEqual(inst_id, cc_instance_handle(1), rtps.cc.instance(1));
AffirmIfEqual(inst_id, cc_instance_handle(2), rtps.cc.instance(2));
AffirmIfEqual(inst_id, cc_instance_handle(3), rtps.cc.instance(3));
AffirmIfEqual(kind_id, CACHE_CHANGE_KIND_TYPE'pos(cc_kind), CACHE_CHANGE_KIND_TYPE'pos(rtps.cc.kind));
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(rtps.cc.seq_nr));
AffirmIfEqual(ts_id, convert_from_double_word(cc_source_timestamp), convert_from_double_word(rtps.cc.src_timestamp));
rtps_stage <= CHECK;
rtps_cnt <= 0;
end if;
when GET_MIN_SN =>
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(reference.cc.seq_nr));
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(rtps.cc.seq_nr));
when GET_MAX_SN =>
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(reference.cc.seq_nr));
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(rtps.cc.seq_nr));
when others =>
null;
end case;
end if;
when CHECK =>
if (valid_out_rtps = '1') then
AffirmIfEqual(data_id, last_word_out_rtps & data_out_rtps, reference.cc.payload.last(ref_cnt) & reference.cc.payload.data(ref_cnt));
ref_cnt <= ref_cnt + 1;
if (ref_cnt = reference.cc.payload.length-1) then
ref_stage <= IDLE;
AffirmIfEqual(data_id, last_word_out_rtps & data_out_rtps, rtps.cc.payload.last(rtps_cnt) & rtps.cc.payload.data(rtps_cnt));
rtps_cnt <= rtps_cnt + 1;
if (rtps_cnt = rtps.cc.payload.length-1) then
rtps_stage <= IDLE;
end if;
end if;
end case;
@ -644,17 +623,19 @@ begin
-- DEFAULT
start_rtps <= '0';
opcode_rtps <= NOP;
seq_nr_rtps <= SEQUENCENUMBER_UNKNOWN;
get_data_rtps <= '0';
ready_out_rtps <= '0';
case (ref_stage) is
case (rtps_stage) is
when START =>
start_rtps <= '1';
opcode_rtps <= reference.opcode;
seq_nr_rtps <= reference.cc.seq_nr;
opcode_rtps <= rtps.opcode;
seq_nr_rtps <= rtps.cc.seq_nr;
when DONE =>
if (done_rtps = '1') then
case (reference.opcode) is
case (rtps.opcode) is
when GET_CACHE_CHANGE =>
get_data_rtps <= '1';
when others =>

View File

@ -19,35 +19,9 @@ architecture testbench of L0_dds_writer_test3_ain is
constant MAX_REMOTE_ENDPOINTS : natural := 3;
-- *TYPE DECLARATION*
type STIM_STAGE_TYPE is (IDLE, START, PUSH, DONE, CHECK, CHECK_DEADLINE);
type REF_STAGE_TYPE is (IDLE, START, DONE, CHECK);
type DDS_STAGE_TYPE is (IDLE, START, PUSH, DONE, CHECK, CHECK_DEADLINE);
type RTPS_STAGE_TYPE is (IDLE, START, DONE, CHECK);
type KH_STAGE_TYPE is (IDLE, READ_DATA, PUSH_KEY_HASH);
type RTPS_TEST_TYPE is record
opcode : HISTORY_CACHE_OPCODE_TYPE;
cc : CACHE_CHANGE_TYPE;
ret_code : HISTORY_CACHE_RESPONSE_TYPE;
end record;
constant DEFAULT_RTPS_TEST : RTPS_TEST_TYPE := (
opcode => NOP,
cc => DEFAULT_CACHE_CHANGE,
ret_code => OK
);
type DDS_TEST_TYPE is record
opcode : DDS_WRITER_OPCODE_TYPE;
cc : CACHE_CHANGE_TYPE;
ret_code : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
count : natural;
change : natural;
instance : INSTANCE_HANDLE_TYPE;
end record;
constant DEFAULT_DDS_TEST : DDS_TEST_TYPE := (
opcode => NOP,
cc => DEFAULT_CACHE_CHANGE,
ret_code => RETCODE_OK,
count => 0,
change => 0,
instance => HANDLE_NIL
);
-- *SIGNAL DECLARATION*
signal clk : std_logic := '0';
@ -71,14 +45,14 @@ architecture testbench of L0_dds_writer_test3_ain is
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 stim_start, stim_done, ref_start, ref_done : std_logic := '0';
signal stim_cnt, ref_cnt, kh_cnt : natural := 0;
signal stim_stage : STIM_STAGE_TYPE := IDLE;
signal ref_stage : REF_STAGE_TYPE := IDLE;
signal dds_start, dds_done, rtps_start, rtps_done : std_logic := '0';
signal dds_cnt, rtps_cnt, kh_cnt : natural := 0;
signal dds_stage : DDS_STAGE_TYPE := IDLE;
signal rtps_stage : RTPS_STAGE_TYPE := IDLE;
signal kh_stage : KH_STAGE_TYPE := IDLE;
signal kh_data : TEST_PACKET_TYPE := EMPTY_TEST_PACKET;
shared variable stimulus : DDS_TEST_TYPE := DEFAULT_DDS_TEST;
shared variable reference : RTPS_TEST_TYPE := DEFAULT_RTPS_TEST;
shared variable dds : DDS_WRITER_TEST_TYPE := DEFAULT_DDS_WRITER_TEST;
shared variable rtps : RTPS_WRITER_TEST_TYPE := DEFAULT_RTPS_WRITER_TEST;
signal inst_id, kind_id, sn_id, ts_id, data_id, ret_id, status_id : AlertLogIDType;
-- *FUNCTION DECLARATION*
@ -202,40 +176,40 @@ begin
return ret;
end function;
procedure start_stim is
procedure start_dds is
begin
stim_start <= '1';
dds_start <= '1';
wait until rising_edge(clk);
stim_start <= '0';
dds_start <= '0';
wait until rising_edge(clk);
end procedure;
procedure start_ref is
procedure start_rtps is
begin
ref_start <= '1';
rtps_start <= '1';
wait until rising_edge(clk);
ref_start <= '0';
rtps_start <= '0';
wait until rising_edge(clk);
end procedure;
procedure wait_on_stim is
procedure wait_on_dds is
begin
if (stim_done /= '1') then
wait until stim_done = '1';
if (dds_done /= '1') then
wait until dds_done = '1';
end if;
end procedure;
procedure wait_on_ref is
procedure wait_on_rtps is
begin
if (ref_done /= '1') then
wait until ref_done = '1';
if (rtps_done /= '1') then
wait until rtps_done = '1';
end if;
end procedure;
procedure wait_on_completion is
begin
if (ref_done /= '1' or stim_done /= '1') then
wait until ref_done = '1' and stim_done = '1';
if (rtps_done /= '1' or dds_done /= '1') then
wait until rtps_done = '1' and dds_done = '1';
end if;
end procedure;
@ -301,17 +275,18 @@ begin
AffirmIf(status_id,(status and OFFERED_DEADLINE_MISSED_STATUS) = OFFERED_DEADLINE_MISSED_STATUS, "Expected: 1", "Received 0");
Log("DDS Operation GET_OFFERED_DEADLINE_MISSED_STATUS (Expected: count 3, change 2, Instance 2)", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := GET_OFFERED_DEADLINE_MISSED_STATUS;
stimulus.ret_code := RETCODE_OK;
stimulus.count := 1;
stimulus.change := 1;
start_stim;
wait_on_stim;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := GET_OFFERED_DEADLINE_MISSED_STATUS;
dds.ret_code := RETCODE_OK;
dds.count := 1;
dds.change := 1;
start_dds;
wait_on_dds;
wait_on_idle;
AffirmIf(status_id,(status and OFFERED_DEADLINE_MISSED_STATUS) /= OFFERED_DEADLINE_MISSED_STATUS, "Expected: 0", "Received 1");
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh1;
@ -319,13 +294,13 @@ begin
cc.seq_nr := gen_sn(1);
Log("DDS Operation WRITE [Aligned Payload] (ACCEPTED)", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := WRITE;
stimulus.cc := cc;
stimulus.cc.instance:= HANDLE_NIL;
stimulus.ret_code := RETCODE_OK;
start_stim;
wait_on_stim;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := WRITE;
dds.cc := cc;
dds.cc.instance:= HANDLE_NIL;
dds.ret_code := RETCODE_OK;
start_dds;
wait_on_dds;
cc1 := cc;
-- Stored CC: I1S1, 0, 0, 0
@ -354,13 +329,13 @@ begin
AffirmIf(status_id,(status and OFFERED_DEADLINE_MISSED_STATUS) = OFFERED_DEADLINE_MISSED_STATUS, "Expected: 1", "Received 0");
Log("DDS Operation GET_OFFERED_DEADLINE_MISSED_STATUS (Expected: count 3, change 2, Instance 2)", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := GET_OFFERED_DEADLINE_MISSED_STATUS;
stimulus.ret_code := RETCODE_OK;
stimulus.count := 3;
stimulus.change := 2;
start_stim;
wait_on_stim;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := GET_OFFERED_DEADLINE_MISSED_STATUS;
dds.ret_code := RETCODE_OK;
dds.count := 3;
dds.change := 2;
start_dds;
wait_on_dds;
wait_on_idle;
AffirmIf(status_id,(status and OFFERED_DEADLINE_MISSED_STATUS) /= OFFERED_DEADLINE_MISSED_STATUS, "Expected: 0", "Received 1");
@ -389,42 +364,42 @@ begin
end if;
end process;
stim_prc : process(all)
dds_prc : process(all)
begin
if rising_edge(clk) then
stim_done <= '0';
case (stim_stage) is
dds_done <= '0';
case (dds_stage) is
when IDLE =>
if (stim_start = '1') then
stim_stage <= START;
if (dds_start = '1') then
dds_stage <= START;
else
stim_done <= '1';
dds_done <= '1';
end if;
when START =>
if (ack_dds = '1') then
case (stimulus.opcode) is
case (dds.opcode) is
when GET_OFFERED_DEADLINE_MISSED_STATUS =>
stim_stage <= DONE;
stim_cnt <= 0;
dds_stage <= DONE;
dds_cnt <= 0;
when others =>
stim_stage <= PUSH;
stim_cnt <= 0;
dds_stage <= PUSH;
dds_cnt <= 0;
end case;
end if;
when PUSH =>
if (ready_in_dds = '1') then
stim_cnt <= stim_cnt + 1;
if (stim_cnt = stimulus.cc.payload.length-1) then
dds_cnt <= dds_cnt + 1;
if (dds_cnt = dds.cc.payload.length-1) then
-- DEFAULT
stim_stage <= DONE;
dds_stage <= DONE;
case (stimulus.opcode) is
case (dds.opcode) is
when REGISTER_INSTANCE =>
stim_stage <= CHECK;
stim_cnt <= 0;
dds_stage <= CHECK;
dds_cnt <= 0;
when LOOKUP_INSTANCE =>
stim_stage <= CHECK;
stim_cnt <= 0;
dds_stage <= CHECK;
dds_cnt <= 0;
when others =>
null;
end case;
@ -432,46 +407,46 @@ begin
end if;
when DONE =>
if (done_dds = '1') then
AffirmIfEqual(ret_id, return_code_dds, stimulus.ret_code);
case (stimulus.opcode) is
AffirmIfEqual(ret_id, return_code_dds, dds.ret_code);
case (dds.opcode) is
when GET_OFFERED_DEADLINE_MISSED_STATUS =>
if (stimulus.ret_code = RETCODE_OK) then
stim_stage <= CHECK_DEADLINE;
stim_cnt <= 0;
if (dds.ret_code = RETCODE_OK) then
dds_stage <= CHECK_DEADLINE;
dds_cnt <= 0;
else
stim_stage <= IDLE;
dds_stage <= IDLE;
end if;
when others =>
stim_stage <= IDLE;
dds_stage <= IDLE;
end case;
end if;
when CHECK =>
if (valid_out_dds = '1') then
AffirmIfEqual(data_id, data_out_dds, stimulus.cc.instance(stim_cnt));
stim_cnt <= stim_cnt + 1;
if (stim_cnt = 3) then
AffirmIfEqual(data_id, data_out_dds, dds.cc.instance(dds_cnt));
dds_cnt <= dds_cnt + 1;
if (dds_cnt = 3) then
AlertIf(data_id, last_word_out_dds /= '1', "Last Word Signal not pulled High", ERROR);
stim_stage <= IDLE;
dds_stage <= IDLE;
end if;
end if;
when CHECK_DEADLINE =>
if (valid_out_dds = '1') then
stim_cnt <= stim_cnt + 1;
case (stim_cnt) is
dds_cnt <= dds_cnt + 1;
case (dds_cnt) is
when 0 =>
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(to_unsigned(stimulus.count,CDR_LONG_WIDTH)));
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(to_unsigned(dds.count,CDR_LONG_WIDTH)));
when 1 =>
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(to_unsigned(stimulus.change,CDR_LONG_WIDTH)));
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(to_unsigned(dds.change,CDR_LONG_WIDTH)));
when 2 =>
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(stimulus.instance(0)));
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(dds.inst (0)));
when 3 =>
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(stimulus.instance(1)));
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(dds.inst (1)));
when 4 =>
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(stimulus.instance(2)));
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(dds.inst (2)));
when 5 =>
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(stimulus.instance(3)));
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(dds.inst (3)));
AlertIf(data_id, last_word_out_dds /= '1', "Last Word Signal not pulled High", ERROR);
stim_stage <= IDLE;
dds_stage <= IDLE;
when others =>
null;
end case;
@ -481,6 +456,7 @@ begin
-- DEFAULT
start_dds <= '0';
opcode_dds <= NOP;
valid_in_dds <= '0';
last_word_in_dds <= '0';
data_in_dds <= (others => '0');
@ -488,16 +464,16 @@ begin
source_ts_dds <= TIME_INVALID;
ready_out_dds <= '0';
case (stim_stage) is
case (dds_stage) is
when START =>
start_dds <= '1';
opcode_dds <= stimulus.opcode;
instance_handle_dds <= stimulus.cc.instance;
source_ts_dds <= stimulus.cc.src_timestamp;
opcode_dds <= dds.opcode;
instance_handle_dds <= dds.cc.instance;
source_ts_dds <= dds.cc.src_timestamp;
when PUSH =>
valid_in_dds <= '1';
data_in_dds <= stimulus.cc.payload.data(stim_cnt);
last_word_in_dds <= stimulus.cc.payload.last(stim_cnt);
data_in_dds <= dds.cc.payload.data(dds_cnt);
last_word_in_dds <= dds.cc.payload.last(dds_cnt);
when CHECK =>
ready_out_dds <= '1';
when CHECK_DEADLINE =>
@ -507,54 +483,54 @@ begin
end case;
end process;
ref_prc : process(all)
rtps_prc : process(all)
begin
if rising_edge(clk) then
ref_done <= '0';
case (ref_stage) is
rtps_done <= '0';
case (rtps_stage) is
when IDLE =>
if (ref_start = '1') then
ref_stage <= START;
if (rtps_start = '1') then
rtps_stage <= START;
else
ref_done <= '1';
rtps_done <= '1';
end if;
when START =>
if (ack_rtps = '1') then
ref_stage <= DONE;
rtps_stage <= DONE;
end if;
when DONE =>
if (done_rtps = '1') then
-- DEFAULT
ref_stage <= IDLE;
rtps_stage <= IDLE;
AffirmIfEqual(ret_id, HISTORY_CACHE_RESPONSE_TYPE'pos(ret_rtps), HISTORY_CACHE_RESPONSE_TYPE'pos(reference.ret_code));
case (reference.opcode) is
AffirmIfEqual(ret_id, HISTORY_CACHE_RESPONSE_TYPE'pos(ret_rtps), HISTORY_CACHE_RESPONSE_TYPE'pos(rtps.ret_code));
case (rtps.opcode) is
when GET_CACHE_CHANGE =>
if (reference.ret_code = OK) then
AffirmIfEqual(inst_id, cc_instance_handle(0), reference.cc.instance(0));
AffirmIfEqual(inst_id, cc_instance_handle(1), reference.cc.instance(1));
AffirmIfEqual(inst_id, cc_instance_handle(2), reference.cc.instance(2));
AffirmIfEqual(inst_id, cc_instance_handle(3), reference.cc.instance(3));
AffirmIfEqual(kind_id, CACHE_CHANGE_KIND_TYPE'pos(cc_kind), CACHE_CHANGE_KIND_TYPE'pos(reference.cc.kind));
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(reference.cc.seq_nr));
AffirmIfEqual(ts_id, convert_from_double_word(cc_source_timestamp), convert_from_double_word(reference.cc.src_timestamp));
ref_stage <= CHECK;
ref_cnt <= 0;
if (rtps.ret_code = OK) then
AffirmIfEqual(inst_id, cc_instance_handle(0), rtps.cc.instance(0));
AffirmIfEqual(inst_id, cc_instance_handle(1), rtps.cc.instance(1));
AffirmIfEqual(inst_id, cc_instance_handle(2), rtps.cc.instance(2));
AffirmIfEqual(inst_id, cc_instance_handle(3), rtps.cc.instance(3));
AffirmIfEqual(kind_id, CACHE_CHANGE_KIND_TYPE'pos(cc_kind), CACHE_CHANGE_KIND_TYPE'pos(rtps.cc.kind));
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(rtps.cc.seq_nr));
AffirmIfEqual(ts_id, convert_from_double_word(cc_source_timestamp), convert_from_double_word(rtps.cc.src_timestamp));
rtps_stage <= CHECK;
rtps_cnt <= 0;
end if;
when GET_MIN_SN =>
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(reference.cc.seq_nr));
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(rtps.cc.seq_nr));
when GET_MAX_SN =>
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(reference.cc.seq_nr));
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(rtps.cc.seq_nr));
when others =>
null;
end case;
end if;
when CHECK =>
if (valid_out_rtps = '1') then
AffirmIfEqual(data_id, last_word_out_rtps & data_out_rtps, reference.cc.payload.last(ref_cnt) & reference.cc.payload.data(ref_cnt));
ref_cnt <= ref_cnt + 1;
if (ref_cnt = reference.cc.payload.length-1) then
ref_stage <= IDLE;
AffirmIfEqual(data_id, last_word_out_rtps & data_out_rtps, rtps.cc.payload.last(rtps_cnt) & rtps.cc.payload.data(rtps_cnt));
rtps_cnt <= rtps_cnt + 1;
if (rtps_cnt = rtps.cc.payload.length-1) then
rtps_stage <= IDLE;
end if;
end if;
end case;
@ -562,17 +538,19 @@ begin
-- DEFAULT
start_rtps <= '0';
opcode_rtps <= NOP;
seq_nr_rtps <= SEQUENCENUMBER_UNKNOWN;
get_data_rtps <= '0';
ready_out_rtps <= '0';
case (ref_stage) is
case (rtps_stage) is
when START =>
start_rtps <= '1';
opcode_rtps <= reference.opcode;
seq_nr_rtps <= reference.cc.seq_nr;
opcode_rtps <= rtps.opcode;
seq_nr_rtps <= rtps.cc.seq_nr;
when DONE =>
if (done_rtps = '1') then
case (reference.opcode) is
case (rtps.opcode) is
when GET_CACHE_CHANGE =>
get_data_rtps <= '1';
when others =>

View File

@ -19,35 +19,9 @@ architecture testbench of L0_dds_writer_test4_aik is
constant MAX_REMOTE_ENDPOINTS : natural := 3;
-- *TYPE DECLARATION*
type STIM_STAGE_TYPE is (IDLE, START, PUSH, DONE, CHECK, CHECK_LIVELINESS);
type REF_STAGE_TYPE is (IDLE, START, DONE, CHECK);
type DDS_STAGE_TYPE is (IDLE, START, PUSH, DONE, CHECK, CHECK_LIVELINESS);
type RTPS_STAGE_TYPE is (IDLE, START, DONE, CHECK);
type KH_STAGE_TYPE is (IDLE, READ_DATA, PUSH_KEY_HASH);
type RTPS_TEST_TYPE is record
opcode : HISTORY_CACHE_OPCODE_TYPE;
cc : CACHE_CHANGE_TYPE;
ret_code : HISTORY_CACHE_RESPONSE_TYPE;
end record;
constant DEFAULT_RTPS_TEST : RTPS_TEST_TYPE := (
opcode => NOP,
cc => DEFAULT_CACHE_CHANGE,
ret_code => OK
);
type DDS_TEST_TYPE is record
opcode : DDS_WRITER_OPCODE_TYPE;
cc : CACHE_CHANGE_TYPE;
ret_code : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
count : natural;
change : natural;
assertion : std_logic;
end record;
constant DEFAULT_DDS_TEST : DDS_TEST_TYPE := (
opcode => NOP,
cc => DEFAULT_CACHE_CHANGE,
ret_code => RETCODE_OK,
count => 0,
change => 0,
assertion => '0'
);
-- *SIGNAL DECLARATION*
signal clk : std_logic := '0';
@ -71,14 +45,14 @@ architecture testbench of L0_dds_writer_test4_aik is
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 stim_start, stim_done, ref_start, ref_done : std_logic := '0';
signal stim_cnt, ref_cnt, kh_cnt : natural := 0;
signal stim_stage : STIM_STAGE_TYPE := IDLE;
signal ref_stage : REF_STAGE_TYPE := IDLE;
signal dds_start, dds_done, rtps_start, rtps_done : std_logic := '0';
signal dds_cnt, rtps_cnt, kh_cnt : natural := 0;
signal dds_stage : DDS_STAGE_TYPE := IDLE;
signal rtps_stage : RTPS_STAGE_TYPE := IDLE;
signal kh_stage : KH_STAGE_TYPE := IDLE;
signal kh_data : TEST_PACKET_TYPE := EMPTY_TEST_PACKET;
shared variable stimulus : DDS_TEST_TYPE := DEFAULT_DDS_TEST;
shared variable reference : RTPS_TEST_TYPE := DEFAULT_RTPS_TEST;
shared variable dds : DDS_WRITER_TEST_TYPE := DEFAULT_DDS_WRITER_TEST;
shared variable rtps : RTPS_WRITER_TEST_TYPE := DEFAULT_RTPS_WRITER_TEST;
signal inst_id, kind_id, sn_id, ts_id, data_id, ret_id, status_id, assert_id : AlertLogIDType;
-- *FUNCTION DECLARATION*
@ -202,40 +176,40 @@ begin
return ret;
end function;
procedure start_stim is
procedure start_dds is
begin
stim_start <= '1';
dds_start <= '1';
wait until rising_edge(clk);
stim_start <= '0';
dds_start <= '0';
wait until rising_edge(clk);
end procedure;
procedure start_ref is
procedure start_rtps is
begin
ref_start <= '1';
rtps_start <= '1';
wait until rising_edge(clk);
ref_start <= '0';
rtps_start <= '0';
wait until rising_edge(clk);
end procedure;
procedure wait_on_stim is
procedure wait_on_dds is
begin
if (stim_done /= '1') then
wait until stim_done = '1';
if (dds_done /= '1') then
wait until dds_done = '1';
end if;
end procedure;
procedure wait_on_ref is
procedure wait_on_rtps is
begin
if (ref_done /= '1') then
wait until ref_done = '1';
if (rtps_done /= '1') then
wait until rtps_done = '1';
end if;
end procedure;
procedure wait_on_completion is
begin
if (ref_done /= '1' or stim_done /= '1') then
wait until ref_done = '1' and stim_done = '1';
if (rtps_done /= '1' or dds_done /= '1') then
wait until rtps_done = '1' and dds_done = '1';
end if;
end procedure;
@ -300,13 +274,13 @@ begin
AffirmIf(status_id,(status and LIVELINESS_LOST_STATUS) = LIVELINESS_LOST_STATUS, "Expected: 1", "Received 0");
Log("DDS Operation GET_LIVELINESS_LOST_STATUS (Expected: count 1, change 1)", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := GET_LIVELINESS_LOST_STATUS;
stimulus.ret_code := RETCODE_OK;
stimulus.count := 1;
stimulus.change := 1;
start_stim;
wait_on_stim;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := GET_LIVELINESS_LOST_STATUS;
dds.ret_code := RETCODE_OK;
dds.count := 1;
dds.change := 1;
start_dds;
wait_on_dds;
wait_on_idle;
AffirmIf(status_id,(status and LIVELINESS_LOST_STATUS) /= LIVELINESS_LOST_STATUS, "Expected: 0", "Received 1");
@ -319,6 +293,7 @@ begin
AffirmIf(status_id,(status and LIVELINESS_LOST_STATUS) /= LIVELINESS_LOST_STATUS, "Expected: 0", "Received 1");
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh1;
@ -326,13 +301,13 @@ begin
cc.seq_nr := gen_sn(1);
Log("DDS Operation WRITE [Instance 1, HANDLE_NIL, Aligned Payload] (ACCEPTED)", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := WRITE;
stimulus.cc := cc;
stimulus.cc.instance:= HANDLE_NIL;
stimulus.ret_code := RETCODE_OK;
start_stim;
wait_on_stim;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := WRITE;
dds.cc := cc;
dds.cc.instance:= HANDLE_NIL;
dds.ret_code := RETCODE_OK;
start_dds;
wait_on_dds;
cc1 := cc;
-- Stored CC: I1S1, 0, 0, 0
@ -352,6 +327,7 @@ begin
AffirmIf(status_id,(status and LIVELINESS_LOST_STATUS) /= LIVELINESS_LOST_STATUS, "Expected: 0", "Received 1");
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := TRUE;
cc.kind := NOT_ALIVE_DISPOSED;
cc.instance := kh1;
@ -359,12 +335,12 @@ begin
cc.seq_nr := gen_sn(2);
Log("DDS Operation DISPOSE [Instance 1] (ACCEPTED)", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := DISPOSE;
stimulus.cc := cc;
stimulus.ret_code := RETCODE_OK;
start_stim;
wait_on_stim;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := DISPOSE;
dds.cc := cc;
dds.ret_code := RETCODE_OK;
start_dds;
wait_on_dds;
cc2 := cc;
-- Stored CC: I1S1, I1S2, 0, 0
@ -384,6 +360,7 @@ begin
AffirmIf(status_id,(status and LIVELINESS_LOST_STATUS) /= LIVELINESS_LOST_STATUS, "Expected: 0", "Received 1");
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := TRUE;
cc.kind := NOT_ALIVE_UNREGISTERED;
cc.instance := kh1;
@ -391,12 +368,12 @@ begin
cc.seq_nr := gen_sn(3);
Log("DDS Operation UNREGISTER_INSTANCE [Instance 1] (ACCEPTED)", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := UNREGISTER_INSTANCE;
stimulus.cc := cc;
stimulus.ret_code := RETCODE_OK;
start_stim;
wait_on_stim;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := UNREGISTER_INSTANCE;
dds.cc := cc;
dds.ret_code := RETCODE_OK;
start_dds;
wait_on_dds;
cc3 := cc;
-- Stored CC: I1S1, I1S2, I1S3, 0
@ -425,13 +402,13 @@ begin
AffirmIf(status_id,(status and LIVELINESS_LOST_STATUS) = LIVELINESS_LOST_STATUS, "Expected: 1", "Received 0");
Log("DDS Operation GET_LIVELINESS_LOST_STATUS (Expected: count 3, change 2)", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := GET_LIVELINESS_LOST_STATUS;
stimulus.ret_code := RETCODE_OK;
stimulus.count := 3;
stimulus.change := 2;
start_stim;
wait_on_stim;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := GET_LIVELINESS_LOST_STATUS;
dds.ret_code := RETCODE_OK;
dds.count := 3;
dds.change := 2;
start_dds;
wait_on_dds;
wait_on_idle;
AffirmIf(status_id,(status and LIVELINESS_LOST_STATUS) /= LIVELINESS_LOST_STATUS, "Expected: 0", "Received 1");
@ -445,12 +422,12 @@ begin
AffirmIf(status_id,(status and LIVELINESS_LOST_STATUS) /= LIVELINESS_LOST_STATUS, "Expected: 0", "Received 1");
Log("DDS Operation ASSERT_LIVELINESS (OK)", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := ASSERT_LIVELINESS;
stimulus.ret_code := RETCODE_OK;
stimulus.assertion := '1';
start_stim;
wait_on_stim;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := ASSERT_LIVELINESS;
dds.ret_code := RETCODE_OK;
dds.assertion := '1';
start_dds;
wait_on_dds;
Log("Current Time: 7s", INFO);
check_time <= gen_duration(7,0);
@ -484,45 +461,45 @@ begin
end if;
end process;
stim_prc : process(all)
dds_prc : process(all)
begin
if rising_edge(clk) then
stim_done <= '0';
case (stim_stage) is
dds_done <= '0';
case (dds_stage) is
when IDLE =>
if (stim_start = '1') then
stim_stage <= START;
if (dds_start = '1') then
dds_stage <= START;
else
stim_done <= '1';
dds_done <= '1';
end if;
when START =>
if (ack_dds = '1') then
case (stimulus.opcode) is
case (dds.opcode) is
when GET_LIVELINESS_LOST_STATUS =>
stim_stage <= DONE;
stim_cnt <= 0;
dds_stage <= DONE;
dds_cnt <= 0;
when ASSERT_LIVELINESS =>
stim_stage <= DONE;
stim_cnt <= 0;
dds_stage <= DONE;
dds_cnt <= 0;
when others =>
stim_stage <= PUSH;
stim_cnt <= 0;
dds_stage <= PUSH;
dds_cnt <= 0;
end case;
end if;
when PUSH =>
if (ready_in_dds = '1') then
stim_cnt <= stim_cnt + 1;
if (stim_cnt = stimulus.cc.payload.length-1) then
dds_cnt <= dds_cnt + 1;
if (dds_cnt = dds.cc.payload.length-1) then
-- DEFAULT
stim_stage <= DONE;
dds_stage <= DONE;
case (stimulus.opcode) is
case (dds.opcode) is
when REGISTER_INSTANCE =>
stim_stage <= CHECK;
stim_cnt <= 0;
dds_stage <= CHECK;
dds_cnt <= 0;
when LOOKUP_INSTANCE =>
stim_stage <= CHECK;
stim_cnt <= 0;
dds_stage <= CHECK;
dds_cnt <= 0;
when others =>
null;
end case;
@ -530,41 +507,41 @@ begin
end if;
when DONE =>
if (done_dds = '1') then
AffirmIfEqual(ret_id, return_code_dds, stimulus.ret_code);
case (stimulus.opcode) is
AffirmIfEqual(ret_id, return_code_dds, dds.ret_code);
case (dds.opcode) is
when GET_LIVELINESS_LOST_STATUS =>
if (stimulus.ret_code = RETCODE_OK) then
stim_stage <= CHECK_LIVELINESS;
stim_cnt <= 0;
if (dds.ret_code = RETCODE_OK) then
dds_stage <= CHECK_LIVELINESS;
dds_cnt <= 0;
else
stim_stage <= IDLE;
dds_stage <= IDLE;
end if;
when ASSERT_LIVELINESS =>
AffirmIfEqual(assert_id, liveliness_assertion, stimulus.assertion);
stim_stage <= IDLE;
AffirmIfEqual(assert_id, liveliness_assertion, dds.assertion);
dds_stage <= IDLE;
when others =>
stim_stage <= IDLE;
dds_stage <= IDLE;
end case;
end if;
when CHECK =>
if (valid_out_dds = '1') then
AffirmIfEqual(data_id, data_out_dds, stimulus.cc.instance(stim_cnt));
stim_cnt <= stim_cnt + 1;
if (stim_cnt = 3) then
AffirmIfEqual(data_id, data_out_dds, dds.cc.instance(dds_cnt));
dds_cnt <= dds_cnt + 1;
if (dds_cnt = 3) then
AlertIf(data_id, last_word_out_dds /= '1', "Last Word Signal not pulled High", ERROR);
stim_stage <= IDLE;
dds_stage <= IDLE;
end if;
end if;
when CHECK_LIVELINESS =>
if (valid_out_dds = '1') then
stim_cnt <= stim_cnt + 1;
case (stim_cnt) is
dds_cnt <= dds_cnt + 1;
case (dds_cnt) is
when 0 =>
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(to_unsigned(stimulus.count,CDR_LONG_WIDTH)));
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(to_unsigned(dds.count,CDR_LONG_WIDTH)));
when 1 =>
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(to_unsigned(stimulus.change,CDR_LONG_WIDTH)));
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(to_unsigned(dds.change,CDR_LONG_WIDTH)));
AlertIf(data_id, last_word_out_dds /= '1', "Last Word Signal not pulled High", ERROR);
stim_stage <= IDLE;
dds_stage <= IDLE;
when others =>
null;
end case;
@ -574,6 +551,7 @@ begin
-- DEFAULT
start_dds <= '0';
opcode_dds <= NOP;
valid_in_dds <= '0';
last_word_in_dds <= '0';
data_in_dds <= (others => '0');
@ -581,16 +559,16 @@ begin
source_ts_dds <= TIME_INVALID;
ready_out_dds <= '0';
case (stim_stage) is
case (dds_stage) is
when START =>
start_dds <= '1';
opcode_dds <= stimulus.opcode;
instance_handle_dds <= stimulus.cc.instance;
source_ts_dds <= stimulus.cc.src_timestamp;
opcode_dds <= dds.opcode;
instance_handle_dds <= dds.cc.instance;
source_ts_dds <= dds.cc.src_timestamp;
when PUSH =>
valid_in_dds <= '1';
data_in_dds <= stimulus.cc.payload.data(stim_cnt);
last_word_in_dds <= stimulus.cc.payload.last(stim_cnt);
data_in_dds <= dds.cc.payload.data(dds_cnt);
last_word_in_dds <= dds.cc.payload.last(dds_cnt);
when CHECK =>
ready_out_dds <= '1';
when CHECK_LIVELINESS =>
@ -600,54 +578,54 @@ begin
end case;
end process;
ref_prc : process(all)
rtps_prc : process(all)
begin
if rising_edge(clk) then
ref_done <= '0';
case (ref_stage) is
rtps_done <= '0';
case (rtps_stage) is
when IDLE =>
if (ref_start = '1') then
ref_stage <= START;
if (rtps_start = '1') then
rtps_stage <= START;
else
ref_done <= '1';
rtps_done <= '1';
end if;
when START =>
if (ack_rtps = '1') then
ref_stage <= DONE;
rtps_stage <= DONE;
end if;
when DONE =>
if (done_rtps = '1') then
-- DEFAULT
ref_stage <= IDLE;
rtps_stage <= IDLE;
AffirmIfEqual(ret_id, HISTORY_CACHE_RESPONSE_TYPE'pos(ret_rtps), HISTORY_CACHE_RESPONSE_TYPE'pos(reference.ret_code));
case (reference.opcode) is
AffirmIfEqual(ret_id, HISTORY_CACHE_RESPONSE_TYPE'pos(ret_rtps), HISTORY_CACHE_RESPONSE_TYPE'pos(rtps.ret_code));
case (rtps.opcode) is
when GET_CACHE_CHANGE =>
if (reference.ret_code = OK) then
AffirmIfEqual(inst_id, cc_instance_handle(0), reference.cc.instance(0));
AffirmIfEqual(inst_id, cc_instance_handle(1), reference.cc.instance(1));
AffirmIfEqual(inst_id, cc_instance_handle(2), reference.cc.instance(2));
AffirmIfEqual(inst_id, cc_instance_handle(3), reference.cc.instance(3));
AffirmIfEqual(kind_id, CACHE_CHANGE_KIND_TYPE'pos(cc_kind), CACHE_CHANGE_KIND_TYPE'pos(reference.cc.kind));
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(reference.cc.seq_nr));
AffirmIfEqual(ts_id, convert_from_double_word(cc_source_timestamp), convert_from_double_word(reference.cc.src_timestamp));
ref_stage <= CHECK;
ref_cnt <= 0;
if (rtps.ret_code = OK) then
AffirmIfEqual(inst_id, cc_instance_handle(0), rtps.cc.instance(0));
AffirmIfEqual(inst_id, cc_instance_handle(1), rtps.cc.instance(1));
AffirmIfEqual(inst_id, cc_instance_handle(2), rtps.cc.instance(2));
AffirmIfEqual(inst_id, cc_instance_handle(3), rtps.cc.instance(3));
AffirmIfEqual(kind_id, CACHE_CHANGE_KIND_TYPE'pos(cc_kind), CACHE_CHANGE_KIND_TYPE'pos(rtps.cc.kind));
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(rtps.cc.seq_nr));
AffirmIfEqual(ts_id, convert_from_double_word(cc_source_timestamp), convert_from_double_word(rtps.cc.src_timestamp));
rtps_stage <= CHECK;
rtps_cnt <= 0;
end if;
when GET_MIN_SN =>
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(reference.cc.seq_nr));
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(rtps.cc.seq_nr));
when GET_MAX_SN =>
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(reference.cc.seq_nr));
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(rtps.cc.seq_nr));
when others =>
null;
end case;
end if;
when CHECK =>
if (valid_out_rtps = '1') then
AffirmIfEqual(data_id, last_word_out_rtps & data_out_rtps, reference.cc.payload.last(ref_cnt) & reference.cc.payload.data(ref_cnt));
ref_cnt <= ref_cnt + 1;
if (ref_cnt = reference.cc.payload.length-1) then
ref_stage <= IDLE;
AffirmIfEqual(data_id, last_word_out_rtps & data_out_rtps, rtps.cc.payload.last(rtps_cnt) & rtps.cc.payload.data(rtps_cnt));
rtps_cnt <= rtps_cnt + 1;
if (rtps_cnt = rtps.cc.payload.length-1) then
rtps_stage <= IDLE;
end if;
end if;
end case;
@ -655,17 +633,19 @@ begin
-- DEFAULT
start_rtps <= '0';
opcode_rtps <= NOP;
seq_nr_rtps <= SEQUENCENUMBER_UNKNOWN;
get_data_rtps <= '0';
ready_out_rtps <= '0';
case (ref_stage) is
case (rtps_stage) is
when START =>
start_rtps <= '1';
opcode_rtps <= reference.opcode;
seq_nr_rtps <= reference.cc.seq_nr;
opcode_rtps <= rtps.opcode;
seq_nr_rtps <= rtps.cc.seq_nr;
when DONE =>
if (done_rtps = '1') then
case (reference.opcode) is
case (rtps.opcode) is
when GET_CACHE_CHANGE =>
get_data_rtps <= '1';
when others =>

View File

@ -19,29 +19,9 @@ architecture testbench of L0_dds_writer_test5_afk is
constant MAX_REMOTE_ENDPOINTS : natural := 3;
-- *TYPE DECLARATION*
type STIM_STAGE_TYPE is (IDLE, START, PUSH, DONE, CHECK);
type REF_STAGE_TYPE is (IDLE, START, DONE, CHECK);
type DDS_STAGE_TYPE is (IDLE, START, PUSH, DONE, CHECK);
type RTPS_STAGE_TYPE is (IDLE, START, DONE, CHECK);
type KH_STAGE_TYPE is (IDLE, READ_DATA, PUSH_KEY_HASH);
type RTPS_TEST_TYPE is record
opcode : HISTORY_CACHE_OPCODE_TYPE;
cc : CACHE_CHANGE_TYPE;
ret_code : HISTORY_CACHE_RESPONSE_TYPE;
end record;
constant DEFAULT_RTPS_TEST : RTPS_TEST_TYPE := (
opcode => NOP,
cc => DEFAULT_CACHE_CHANGE,
ret_code => OK
);
type DDS_TEST_TYPE is record
opcode : DDS_WRITER_OPCODE_TYPE;
cc : CACHE_CHANGE_TYPE;
ret_code : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
end record;
constant DEFAULT_DDS_TEST : DDS_TEST_TYPE := (
opcode => NOP,
cc => DEFAULT_CACHE_CHANGE,
ret_code => RETCODE_OK
);
-- *SIGNAL DECLARATION*
signal clk : std_logic := '0';
@ -65,14 +45,14 @@ architecture testbench of L0_dds_writer_test5_afk is
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 stim_start, stim_done, ref_start, ref_done : std_logic := '0';
signal stim_cnt, ref_cnt, kh_cnt : natural := 0;
signal stim_stage : STIM_STAGE_TYPE := IDLE;
signal ref_stage : REF_STAGE_TYPE := IDLE;
signal dds_start, dds_done, rtps_start, rtps_done : std_logic := '0';
signal dds_cnt, rtps_cnt, kh_cnt : natural := 0;
signal dds_stage : DDS_STAGE_TYPE := IDLE;
signal rtps_stage : RTPS_STAGE_TYPE := IDLE;
signal kh_stage : KH_STAGE_TYPE := IDLE;
signal kh_data : TEST_PACKET_TYPE := EMPTY_TEST_PACKET;
shared variable stimulus : DDS_TEST_TYPE := DEFAULT_DDS_TEST;
shared variable reference : RTPS_TEST_TYPE := DEFAULT_RTPS_TEST;
shared variable dds : DDS_WRITER_TEST_TYPE := DEFAULT_DDS_WRITER_TEST;
shared variable rtps : RTPS_WRITER_TEST_TYPE := DEFAULT_RTPS_WRITER_TEST;
signal inst_id, kind_id, sn_id, ts_id, data_id, ret_id, status_id, assert_id : AlertLogIDType;
-- *FUNCTION DECLARATION*
@ -196,40 +176,40 @@ begin
return ret;
end function;
procedure start_stim is
procedure start_dds is
begin
stim_start <= '1';
dds_start <= '1';
wait until rising_edge(clk);
stim_start <= '0';
dds_start <= '0';
wait until rising_edge(clk);
end procedure;
procedure start_ref is
procedure start_rtps is
begin
ref_start <= '1';
rtps_start <= '1';
wait until rising_edge(clk);
ref_start <= '0';
rtps_start <= '0';
wait until rising_edge(clk);
end procedure;
procedure wait_on_stim is
procedure wait_on_dds is
begin
if (stim_done /= '1') then
wait until stim_done = '1';
if (dds_done /= '1') then
wait until dds_done = '1';
end if;
end procedure;
procedure wait_on_ref is
procedure wait_on_rtps is
begin
if (ref_done /= '1') then
wait until ref_done = '1';
if (rtps_done /= '1') then
wait until rtps_done = '1';
end if;
end procedure;
procedure wait_on_completion is
begin
if (ref_done /= '1' or stim_done /= '1') then
wait until ref_done = '1' and stim_done = '1';
if (rtps_done /= '1' or dds_done /= '1') then
wait until rtps_done = '1' and dds_done = '1';
end if;
end procedure;
@ -283,6 +263,7 @@ begin
wait_on_idle;
-- Stored CC: 0, 0, 0, 0
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh1;
@ -290,16 +271,17 @@ begin
cc.seq_nr := gen_sn(1);
Log("DDS Operation WRITE [Instance 1, HANDLE_NIL, Aligned Payload] (ACCEPTED)", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := WRITE;
stimulus.cc := cc;
stimulus.cc.instance:= HANDLE_NIL;
stimulus.ret_code := RETCODE_OK;
start_stim;
wait_on_stim;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := WRITE;
dds.cc := cc;
dds.cc.instance:= HANDLE_NIL;
dds.ret_code := RETCODE_OK;
start_dds;
wait_on_dds;
cc1 := cc;
-- Stored CC: I1S1, 0, 0, 0
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh2;
@ -307,13 +289,13 @@ begin
cc.seq_nr := gen_sn(2);
Log("DDS Operation WRITE [Instance 2, HANDLE_NIL, Aligned Payload] (ACCEPTED)", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := WRITE;
stimulus.cc := cc;
stimulus.cc.instance:= HANDLE_NIL;
stimulus.ret_code := RETCODE_OK;
start_stim;
wait_on_stim;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := WRITE;
dds.cc := cc;
dds.cc.instance:= HANDLE_NIL;
dds.ret_code := RETCODE_OK;
start_dds;
wait_on_dds;
cc2 := cc;
-- Stored CC: I1S1, I2S2, 0, 0
@ -323,6 +305,7 @@ begin
wait until rising_edge(clk);
wait_on_idle;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh1;
@ -330,16 +313,17 @@ begin
cc.seq_nr := gen_sn(3);
Log("DDS Operation WRITE [Instance 1, HANDLE_NIL, Aligned Payload] (ACCEPTED)", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := WRITE;
stimulus.cc := cc;
stimulus.cc.instance:= HANDLE_NIL;
stimulus.ret_code := RETCODE_OK;
start_stim;
wait_on_stim;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := WRITE;
dds.cc := cc;
dds.cc.instance:= HANDLE_NIL;
dds.ret_code := RETCODE_OK;
start_dds;
wait_on_dds;
cc3 := cc;
-- Stored CC: I1S1, I2S2, I1S3, 0
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh1;
@ -347,14 +331,15 @@ begin
cc.seq_nr := gen_sn(4);
Log("DDS Operation WRITE [Instance 1, HANDLE_NIL, Aligned Payload] (REJECTED: MAX_SAMPLES_PER_INSTANCE exceeded)", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := WRITE;
stimulus.cc := cc;
stimulus.cc.instance:= HANDLE_NIL;
stimulus.ret_code := RETCODE_OUT_OF_RESOURCES;
start_stim;
wait_on_stim;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := WRITE;
dds.cc := cc;
dds.cc.instance:= HANDLE_NIL;
dds.ret_code := RETCODE_OUT_OF_RESOURCES;
start_dds;
wait_on_dds;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := TRUE;
cc.kind := NOT_ALIVE_UNREGISTERED;
cc.instance := kh2;
@ -362,12 +347,12 @@ begin
cc.seq_nr := gen_sn(4);
Log("DDS Operation UNREGISTER_INSTANCE [Instance 2] (ACCEPTED)", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := UNREGISTER_INSTANCE;
stimulus.cc := cc;
stimulus.ret_code := RETCODE_OK;
start_stim;
wait_on_stim;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := UNREGISTER_INSTANCE;
dds.cc := cc;
dds.ret_code := RETCODE_OK;
start_dds;
wait_on_dds;
cc4 := cc;
-- Stored CC: I1S1, I2S2, I1S3, I2S4
@ -381,19 +366,20 @@ begin
-- VALIDATE STATE
Log("RTPS Operation GET_MIN_SN (Expected SN 3)", INFO);
reference := DEFAULT_RTPS_TEST;
reference.opcode := GET_MIN_SN;
reference.cc.seq_nr := gen_sn(3);
start_ref;
wait_on_ref;
rtps := DEFAULT_RTPS_WRITER_TEST;
rtps.opcode := GET_MIN_SN;
rtps.cc.seq_nr := gen_sn(3);
start_rtps;
wait_on_rtps;
Log("RTPS Operation GET_MAX_SN (Expected SN 4)", INFO);
reference := DEFAULT_RTPS_TEST;
reference.opcode := GET_MAX_SN;
reference.cc.seq_nr := gen_sn(4);
start_ref;
wait_on_ref;
rtps := DEFAULT_RTPS_WRITER_TEST;
rtps.opcode := GET_MAX_SN;
rtps.cc.seq_nr := gen_sn(4);
start_rtps;
wait_on_rtps;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh1;
@ -401,16 +387,17 @@ begin
cc.seq_nr := gen_sn(5);
Log("DDS Operation WRITE [Instance 1, HANDLE_NIL, Aligned Payload] (ACCEPTED)", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := WRITE;
stimulus.cc := cc;
stimulus.cc.instance:= HANDLE_NIL;
stimulus.ret_code := RETCODE_OK;
start_stim;
wait_on_stim;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := WRITE;
dds.cc := cc;
dds.cc.instance:= HANDLE_NIL;
dds.ret_code := RETCODE_OK;
start_dds;
wait_on_dds;
cc1 := cc;
-- Stored CC: I1S5, 0, I1S3, I2S4
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh3;
@ -418,13 +405,13 @@ begin
cc.seq_nr := gen_sn(6);
Log("DDS Operation WRITE [Instance 3, HANDLE_NIL, Aligned Payload] (REJECTED: MAX_INSTANCES exceeded)", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := WRITE;
stimulus.cc := cc;
stimulus.cc.instance:= HANDLE_NIL;
stimulus.ret_code := RETCODE_OUT_OF_RESOURCES;
start_stim;
wait_on_stim;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := WRITE;
dds.cc := cc;
dds.cc.instance:= HANDLE_NIL;
dds.ret_code := RETCODE_OUT_OF_RESOURCES;
start_dds;
wait_on_dds;
Log("Current Time: 3s", INFO);
check_time <= gen_duration(3,0);
@ -436,19 +423,20 @@ begin
-- VALIDATE STATE
Log("RTPS Operation GET_MIN_SN (Expected SN 5)", INFO);
reference := DEFAULT_RTPS_TEST;
reference.opcode := GET_MIN_SN;
reference.cc.seq_nr := gen_sn(5);
start_ref;
wait_on_ref;
rtps := DEFAULT_RTPS_WRITER_TEST;
rtps.opcode := GET_MIN_SN;
rtps.cc.seq_nr := gen_sn(5);
start_rtps;
wait_on_rtps;
Log("RTPS Operation GET_MAX_SN (Expected SN 5)", INFO);
reference := DEFAULT_RTPS_TEST;
reference.opcode := GET_MAX_SN;
reference.cc.seq_nr := gen_sn(5);
start_ref;
wait_on_ref;
rtps := DEFAULT_RTPS_WRITER_TEST;
rtps.opcode := GET_MAX_SN;
rtps.cc.seq_nr := gen_sn(5);
start_rtps;
wait_on_rtps;
cc := DEFAULT_CACHE_CHANGE;
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh3;
@ -456,13 +444,13 @@ begin
cc.seq_nr := gen_sn(6);
Log("DDS Operation WRITE [Instance 3, HANDLE_NIL, Aligned Payload] (ACCEPTED)", INFO);
stimulus := DEFAULT_DDS_TEST;
stimulus.opcode := WRITE;
stimulus.cc := cc;
stimulus.cc.instance:= HANDLE_NIL;
stimulus.ret_code := RETCODE_OK;
start_stim;
wait_on_stim;
dds := DEFAULT_DDS_WRITER_TEST;
dds.opcode := WRITE;
dds.cc := cc;
dds.cc.instance:= HANDLE_NIL;
dds.ret_code := RETCODE_OK;
start_dds;
wait_on_dds;
cc2 := cc;
-- Stored CC: I1S5, I3S6, 0, 0
@ -490,39 +478,39 @@ begin
end if;
end process;
stim_prc : process(all)
dds_prc : process(all)
begin
if rising_edge(clk) then
stim_done <= '0';
case (stim_stage) is
dds_done <= '0';
case (dds_stage) is
when IDLE =>
if (stim_start = '1') then
stim_stage <= START;
if (dds_start = '1') then
dds_stage <= START;
else
stim_done <= '1';
dds_done <= '1';
end if;
when START =>
if (ack_dds = '1') then
case (stimulus.opcode) is
case (dds.opcode) is
when others =>
stim_stage <= PUSH;
stim_cnt <= 0;
dds_stage <= PUSH;
dds_cnt <= 0;
end case;
end if;
when PUSH =>
if (ready_in_dds = '1') then
stim_cnt <= stim_cnt + 1;
if (stim_cnt = stimulus.cc.payload.length-1) then
dds_cnt <= dds_cnt + 1;
if (dds_cnt = dds.cc.payload.length-1) then
-- DEFAULT
stim_stage <= DONE;
dds_stage <= DONE;
case (stimulus.opcode) is
case (dds.opcode) is
when REGISTER_INSTANCE =>
stim_stage <= CHECK;
stim_cnt <= 0;
dds_stage <= CHECK;
dds_cnt <= 0;
when LOOKUP_INSTANCE =>
stim_stage <= CHECK;
stim_cnt <= 0;
dds_stage <= CHECK;
dds_cnt <= 0;
when others =>
null;
end case;
@ -530,19 +518,19 @@ begin
end if;
when DONE =>
if (done_dds = '1') then
AffirmIfEqual(ret_id, return_code_dds, stimulus.ret_code);
case (stimulus.opcode) is
AffirmIfEqual(ret_id, return_code_dds, dds.ret_code);
case (dds.opcode) is
when others =>
stim_stage <= IDLE;
dds_stage <= IDLE;
end case;
end if;
when CHECK =>
if (valid_out_dds = '1') then
AffirmIfEqual(data_id, data_out_dds, stimulus.cc.instance(stim_cnt));
stim_cnt <= stim_cnt + 1;
if (stim_cnt = 3) then
AffirmIfEqual(data_id, data_out_dds, dds.cc.instance(dds_cnt));
dds_cnt <= dds_cnt + 1;
if (dds_cnt = 3) then
AlertIf(data_id, last_word_out_dds /= '1', "Last Word Signal not pulled High", ERROR);
stim_stage <= IDLE;
dds_stage <= IDLE;
end if;
end if;
end case;
@ -550,6 +538,7 @@ begin
-- DEFAULT
start_dds <= '0';
opcode_dds <= NOP;
valid_in_dds <= '0';
last_word_in_dds <= '0';
data_in_dds <= (others => '0');
@ -557,16 +546,16 @@ begin
source_ts_dds <= TIME_INVALID;
ready_out_dds <= '0';
case (stim_stage) is
case (dds_stage) is
when START =>
start_dds <= '1';
opcode_dds <= stimulus.opcode;
instance_handle_dds <= stimulus.cc.instance;
source_ts_dds <= stimulus.cc.src_timestamp;
opcode_dds <= dds.opcode;
instance_handle_dds <= dds.cc.instance;
source_ts_dds <= dds.cc.src_timestamp;
when PUSH =>
valid_in_dds <= '1';
data_in_dds <= stimulus.cc.payload.data(stim_cnt);
last_word_in_dds <= stimulus.cc.payload.last(stim_cnt);
data_in_dds <= dds.cc.payload.data(dds_cnt);
last_word_in_dds <= dds.cc.payload.last(dds_cnt);
when CHECK =>
ready_out_dds <= '1';
when others =>
@ -574,54 +563,51 @@ begin
end case;
end process;
ref_prc : process(all)
rtps_prc : process(all)
begin
if rising_edge(clk) then
ref_done <= '0';
case (ref_stage) is
rtps_done <= '0';
case (rtps_stage) is
when IDLE =>
if (ref_start = '1') then
ref_stage <= START;
if (rtps_start = '1') then
rtps_stage <= START;
else
ref_done <= '1';
rtps_done <= '1';
end if;
when START =>
if (ack_rtps = '1') then
ref_stage <= DONE;
rtps_stage <= DONE;
end if;
when DONE =>
if (done_rtps = '1') then
-- DEFAULT
ref_stage <= IDLE;
rtps_stage <= IDLE;
AffirmIfEqual(ret_id, HISTORY_CACHE_RESPONSE_TYPE'pos(ret_rtps), HISTORY_CACHE_RESPONSE_TYPE'pos(reference.ret_code));
case (reference.opcode) is
AffirmIfEqual(ret_id, HISTORY_CACHE_RESPONSE_TYPE'pos(ret_rtps), HISTORY_CACHE_RESPONSE_TYPE'pos(rtps.ret_code));
case (rtps.opcode) is
when GET_CACHE_CHANGE =>
if (reference.ret_code = OK) then
AffirmIfEqual(inst_id, cc_instance_handle(0), reference.cc.instance(0));
AffirmIfEqual(inst_id, cc_instance_handle(1), reference.cc.instance(1));
AffirmIfEqual(inst_id, cc_instance_handle(2), reference.cc.instance(2));
AffirmIfEqual(inst_id, cc_instance_handle(3), reference.cc.instance(3));
AffirmIfEqual(kind_id, CACHE_CHANGE_KIND_TYPE'pos(cc_kind), CACHE_CHANGE_KIND_TYPE'pos(reference.cc.kind));
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(reference.cc.seq_nr));
AffirmIfEqual(ts_id, convert_from_double_word(cc_source_timestamp), convert_from_double_word(reference.cc.src_timestamp));
ref_stage <= CHECK;
ref_cnt <= 0;
if (rtps.ret_code = OK) then
AffirmIfEqual(inst_id, to_unsigned(cc_instance_handle), to_unsigned(rtps.cc.instance));
AffirmIfEqual(kind_id, CACHE_CHANGE_KIND_TYPE'pos(cc_kind), CACHE_CHANGE_KIND_TYPE'pos(rtps.cc.kind));
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(rtps.cc.seq_nr));
AffirmIfEqual(ts_id, convert_from_double_word(cc_source_timestamp), convert_from_double_word(rtps.cc.src_timestamp));
rtps_stage <= CHECK;
rtps_cnt <= 0;
end if;
when GET_MIN_SN =>
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(reference.cc.seq_nr));
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(rtps.cc.seq_nr));
when GET_MAX_SN =>
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(reference.cc.seq_nr));
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(rtps.cc.seq_nr));
when others =>
null;
end case;
end if;
when CHECK =>
if (valid_out_rtps = '1') then
AffirmIfEqual(data_id, last_word_out_rtps & data_out_rtps, reference.cc.payload.last(ref_cnt) & reference.cc.payload.data(ref_cnt));
ref_cnt <= ref_cnt + 1;
if (ref_cnt = reference.cc.payload.length-1) then
ref_stage <= IDLE;
AffirmIfEqual(data_id, last_word_out_rtps & data_out_rtps, rtps.cc.payload.last(rtps_cnt) & rtps.cc.payload.data(rtps_cnt));
rtps_cnt <= rtps_cnt + 1;
if (rtps_cnt = rtps.cc.payload.length-1) then
rtps_stage <= IDLE;
end if;
end if;
end case;
@ -629,17 +615,19 @@ begin
-- DEFAULT
start_rtps <= '0';
opcode_rtps <= NOP;
seq_nr_rtps <= SEQUENCENUMBER_UNKNOWN;
get_data_rtps <= '0';
ready_out_rtps <= '0';
case (ref_stage) is
case (rtps_stage) is
when START =>
start_rtps <= '1';
opcode_rtps <= reference.opcode;
seq_nr_rtps <= reference.cc.seq_nr;
opcode_rtps <= rtps.opcode;
seq_nr_rtps <= rtps.cc.seq_nr;
when DONE =>
if (done_rtps = '1') then
case (reference.opcode) is
case (rtps.opcode) is
when GET_CACHE_CHANGE =>
get_data_rtps <= '1';
when others =>

View File

@ -0,0 +1,57 @@
-- TEST: NORMAL ADD_CACHE_CHANGE
-- TEST: ADD_CACHE_CHANGE ON PAYLOAD MEMORY FULL
-- TEST: REMOVE_WRITER [UNKNOWN WRITER]
-- TEST: REMOVE_WRITER [KNOWN WRITER (1 Instance)]
-- TEST: REMOVE_WRITER [KNOWN WRITER (>1 Instances)]
-- TEST: SAMPLE WITH ALIGNED PAYLOAD
-- TEST: SAMPLE WITH UNALIGNED PAYLOAD [>1 SLOT]
-- TEST: SAMPLE WITH UNALIGNED PAYLOAD [<1 SLOT]
-- TEST: NORMAL SAMPLE [KNOWN INSTANCE]
-- TEST: NORMAL SAMPLE [UNKNOWN INSTANCE]
-- TEST: UNREGISTER SAMPLE [KNOWN INSTANCE, KNOWN WRITER]
-- TEST: UNREGISTER SAMPLE [KNOWN INSTANCE, UNKNOWN WRITER]
-- TEST: UNREGISTER SAMPLE [UNKNOWN INSTANCE]
-- TEST: UNREGISTER SAMPLE [NOT_ALIVE_NO_WRITERS INSTANCE]
-- TEST: UNREGISTER SAMPLE [NOT_ALIVE_DISPOSED INSTANCE]
-- TEST: UNREGISTER SAMPLE [NOT_ALIVE_DISPOSED INSTANCE, STALE INSTANCE TRANSITION]
-- TEST: DISPOSE SAMPLE [KNOWN INSTANCE]
-- TEST: DISPOSE SAMPLE [UNKNOWN INSTANCE]
-- TEST: DISPOSE SAMPLE [NOT_ALIVE_NO_WRITERS INSTANCE]
-- TEST: DISPOSE SAMPLE [NOT_ALIVE_DISPOSED INSTANCE]
-- TEST: FILTER SAMPLE [KNOWN INSTANCE]
-- TEST: FILTER SAMPLE [UNKNOWN INSTANCE]
-- TEST: FILTER SAMPLE [NOT_ALIVE_DISPOSED INSTANCE]
-- TEST: FILTER SAMPLE [NOT_ALIVE_NO_WRITERS INSTANCE]
-- TEST: SAMPLE WITH KEY_HASH
-- TEST: SAMPLE WITHOUT KEY_HASH
-- TEST: SAMPLE WITH SERIALIZED KEY [WITH KEY_HASH]
-- TEST: SAMPLE WITH SERIALIZED KEY [WITHOUT KEY_HASH]
-- TEST: SAMPLE WITH EARLY TIMESTAMP [TIMESTAMP EARLIER THAN LAST READ]
-- TEST: TEST SAMPLE WITH SERIALIZED KEY EFFECT ON PAYLOAD MEMORY FULLNESS
-- TEST: ADD SAMPLE ON MAX_SAMPLES_PER_INSTANCE
-- TEST: ADD SAMPLE ON MAX_SAMPLES [KNOWN INSTANCE]
-- TEST: ADD SAMPLE ON MAX_SAMPLES [UNKNOWN INSTANCE]
-- TEST: ADD SAMPLE ON MAX_INSTANCES [UNKOWN INSTANCE, WITH STALE INSTANCE]
-- TEST: ADD SAMPLE ON MAX_INSTANCES [UNKOWN INSTANCE, WITHOUT STALE INSTANCE]
-- TEST: ADD SAMPLE ON MAX_INSTANCES [UNKOWN INSTANCE, WITHOUT STALE INSTANCE, WITH EMPTY INSTANCE]
-- TEST: ADD SAMPLE ON MAX_INSTANCES [UNKOWN INSTANCE, NOT_ALIVE_DISPOSED & STALE INSTANCE]
-- TEST: ADD SAMPLE ON MAX_SAMPLES & MAX_INSTANCES [UNKNOWN INSTANCE, WITH STALE INSTANCE]
-- TEST: ADD SAMPLE ON MAX_SAMPLES & MAX_INSTANCES [UNKNOWN INSTANCE, WITHOUT STALE INSTANCE]
-- TEST: WRITER_BITMAP SPLIT
-- TEST: ADD SAMPLE BIGGER THAN AVAILABLE MEMORY SPACE
-- TEST: ADD SAMPLE ON PAYLOAD MEMORY FULL & MAX_SAMPLES_PER_INSTANCE (Induce Double Remove)

View File

@ -73,7 +73,7 @@
-- TEST: ADD SAMPLE ON MAX_SAMPLES & MAX_INSTANCES [UNKNOWN INSTANCE,WITH STALE INSTANCE (>0 SAMPLES)]
-- TEST: ADD SAMPLE ON MAX_SAMPLES & MAX_INSTANCES [UNKNOWN INSTANCE,WITH STALE INSTANCE, WITH ACKed SAMPLE]
-- TEST: ADD SAMPLE ON PAYLOAD FULL & MAX_INSTANCES [UNKNOWN INSTANCE,WITH ACKed SAMPLES,WITH STALE INSTANCE (>= 1 SAMPLE)] (Induce Double Remove)
-- TEST: ADD SAMPLE ON PAYLOAD MEMORY FULL & MAX_INSTANCES [UNKNOWN INSTANCE,WITH ACKed SAMPLES,WITH STALE INSTANCE (>= 1 SAMPLE)] (Induce Double Remove)
-- TEST: ADD SAMPLE BIGGER THAN AVAILABLE MEMORY SPACE [WITH ACKed SAMPLES]

View File

@ -19,6 +19,7 @@ analyze ../rtps_out.vhd
analyze ../rtps_reader.vhd
analyze ../rtps_writer.vhd
analyze ../dds_writer.vhd
analyze ../dds_reader.vhd
#analyze Level_0/L0_rtps_handler_test1.vhd
#analyze Level_0/L0_rtps_handler_test2.vhd
#analyze Level_0/L0_rtps_builtin_endpoint_test1.vhd
@ -62,7 +63,13 @@ analyze ../dds_writer.vhd
#analyze Level_0/L0_dds_writer_test3_aik.vhd
#analyze Level_0/L0_dds_writer_test3_ain.vhd
#analyze Level_0/L0_dds_writer_test4_aik.vhd
analyze Level_0/L0_dds_writer_test5_afk.vhd
#analyze Level_0/L0_dds_writer_test5_afk.vhd
analyze Level_0/L0_dds_reader_test1_arzkriu.vhd
analyze Level_0/L0_dds_reader_test1_lrzkriu.vhd
analyze Level_0/L0_dds_reader_test1_lbzkriu.vhd
analyze Level_0/L0_dds_reader_test1_abzkriu.vhd
analyze Level_0/L0_dds_reader_test1_arznriu.vhd
analyze Level_0/L0_dds_reader_test1_arzksiu.vhd
#simulate L0_rtps_handler_test1
#simulate L0_rtps_handler_test2
@ -107,4 +114,10 @@ analyze Level_0/L0_dds_writer_test5_afk.vhd
#simulate L0_dds_writer_test3_aik
#simulate L0_dds_writer_test3_ain
#simulate L0_dds_writer_test4_aik
simulate L0_dds_writer_test5_afk
#simulate L0_dds_writer_test5_afk
simulate L0_dds_reader_test1_arzkriu
#simulate L0_dds_reader_test1_lrzkriu
#simulate L0_dds_reader_test1_lbzkriu
#simulate L0_dds_reader_test1_abzkriu
#simulate L0_dds_reader_test1_arznriu
#simulate L0_dds_reader_test1_arzksiu

File diff suppressed because it is too large Load Diff

View File

@ -84,7 +84,7 @@ architecture arch of dds_writer is
--*****CONSTANT DECLARATION*****
-- *SAMPLE MEMORY*
-- 4-Byte Word Size of a Remote Endpoint Entry in Memory
-- 4-Byte Word Size of a Sample Info Entry in Memory
function gen_frame_size(lifespan : DURATION_TYPE; WITH_KEY : boolean) return natural is
variable ret : natural := 0;
begin
@ -123,7 +123,7 @@ architecture arch of dds_writer is
constant FIRST_PAYLOAD_ADDRESS : unsigned(PAYLOAD_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
-- *INSTANCE MEMORY*
-- 4-Byte Word Size of a Remote Endpoint Entry in Memory
-- 4-Byte Word Size of a Instance Entry in Memory
constant INSTANCE_FRAME_SIZE : natural := 8;
-- Instance Memory Size in 4-Byte Words
constant INSTANCE_MEMORY_SIZE : natural := to_integer(unsigned(MAX_INSTANCES)) * INSTANCE_FRAME_SIZE;
@ -149,14 +149,14 @@ architecture arch of dds_writer is
return ret;
end function;
constant SMF_PAYLOAD_ADDR_OFFSET : natural := gen_smf_payload_addr_offset(LIFESPAN_QOS);
function gen_smf_instance_addr_offset(WITH_KEY : boolean) return natural is
constant SMF_INSTANCE_ADDR_OFFSET : natural := SMF_PAYLOAD_ADDR_OFFSET + 1;
function gen_smf_prev_addr_offset(WITH_KEY : boolean) return natural is
variable ret : natural := 0;
begin
ret := (SMF_PAYLOAD_ADDR_OFFSET + 1) when WITH_KEY else SMF_PAYLOAD_ADDR_OFFSET;
ret := (SMF_INSTANCE_ADDR_OFFSET + 1) when WITH_KEY else SMF_INSTANCE_ADDR_OFFSET;
return ret;
end function;
constant SMF_INSTANCE_ADDR_OFFSET : natural := gen_smf_instance_addr_offset(WITH_KEY);
constant SMF_PREV_ADDR_OFFSET : natural := SMF_INSTANCE_ADDR_OFFSET + 1;
constant SMF_PREV_ADDR_OFFSET : natural := gen_smf_prev_addr_offset(WITH_KEY);
constant SMF_NEXT_ADDR_OFFSET : natural := SMF_PREV_ADDR_OFFSET + 1;
-- *PAYLOAD MEMORY FRAME FORMAT*
@ -416,8 +416,6 @@ architecture arch of dds_writer is
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 13 := 0;
-- Counter used to read/write the Writer Bitmap
signal inst_cnt2, inst_cnt2_next : natural range 0 to ENDPOINT_BITMAP_ARRAY_TYPE'length := 0;
-- General Purpose Long Latch
signal inst_long_latch, inst_long_latch_next : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0');
@ -569,8 +567,6 @@ begin
-- RESET_PAYLOAD_MEMORY Reset Payload Memory to Empty State
parse_a_prc : process (all)
variable tmp_dw : DOUBLE_WORD_ARRAY := (others => (others => '0'));
variable tmp_bitmap : std_logic_vector(0 to ENDPOINT_BITMAP_WIDTH-1) := (others => '0');
variable tmp_update : std_logic_vector(0 to IMF_FLAG_WIDTH-1) := (others => '0');
variable tmp_bool : boolean := FALSE;
begin
-- DEFAULT Registered
@ -903,7 +899,7 @@ begin
if (global_ack_cnt /= 0) then
-- Accept Change (Remove Oldest ACKed Sample)
-- Remove Oldest ACKed Sample
remove_oldest_sample_next <= '1';
remove_ack_sample_next <= '1';
@ -958,7 +954,7 @@ begin
ack_dds <= '0';
if (global_ack_cnt /= 0) then
-- Accept Change (Remove Oldest ACKed Sample)
-- Remove Oldest ACKed Sample
remove_oldest_sample_next <= '1';
remove_ack_sample_next <= '1';
@ -1013,7 +1009,7 @@ begin
ack_dds <= '0';
if (global_ack_cnt /= 0) then
-- Accept Change (Remove Oldest ACKed Sample)
-- Remove Oldest ACKed Sample
remove_oldest_sample_next <= '1';
remove_ack_sample_next <= '1';
@ -2207,258 +2203,177 @@ begin
when REMOVE_SAMPLE =>
-- Precondition: cur_sample set
-- Wait for Instance Search to finish
if (not WITH_KEY or inst_op_done = '1') then
case (cnt) is
-- GET Status Info
when 0 =>
sample_valid_in <= '1';
sample_addr <= cur_sample + SMF_STATUS_INFO_OFFSET;
sample_read <= '1';
case (cnt) is
-- GET Status Info
when 0 =>
sample_valid_in <= '1';
sample_addr <= cur_sample + SMF_STATUS_INFO_OFFSET;
sample_read <= '1';
-- Memory Flow Control Guard
if (sample_ready_in = '1') then
cnt_next <= cnt + 1;
end if;
-- GET Previous Pointer
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 Previous Pointer
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 Pointer
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 Next Pointer
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;
-- 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 Status Info
when 4 =>
sample_ready_out <= '1';
-- Memory Flow Control Guard
if (sample_valid_out = '1') then
-- Latch Sample Status Info (For POST_SAMPLE_REMOVE State)
sample_status_info_next <= sample_read_data;
cnt_next <= cnt + 1;
end if;
-- READ Previous Pointer
when 5 =>
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 Pointer
when 6 =>
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);
-- Memory Flow Control Guard
if (sample_ready_in = '1') then
cnt_next <= cnt + 1;
end if;
-- READ Status Info
when 4 =>
sample_ready_out <= '1';
-- Memory Flow Control Guard
if (sample_valid_out = '1') then
-- Latch Sample Status Info (For POST_SAMPLE_REMOVE State)
sample_status_info_next <= sample_read_data;
cnt_next <= cnt + 1;
end if;
-- READ Previous Pointer
when 5 =>
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 Pointer
when 6 =>
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 7 =>
-- 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
when 8 =>
-- 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
-- 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;
-- Current Sample is Newest (Occupied List Tail)
if (next_sample = SAMPLE_MEMORY_MAX_ADDRESS) then
assert (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) severity FAILURE;
assert (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;
cnt_next <= cnt + 2; --Skip Next Step
else
cnt_next <= cnt + 1;
end if;
-- SET Previous Pointer (Next Sample)
when 9 =>
-- 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));
end if;
-- SET Next Pointer (Empty List Tail)
when 7 =>
-- 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
-- Current Sample is oldest sample (List Head)
-- Memory Flow Control Guard
if (sample_ready_in = '1') then
cnt_next <= cnt + 1;
end if;
-- SET Next Pointer
when 8 =>
-- 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) 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 (cur_sample = oldest_sample) severity FAILURE;
assert (newest_sample = oldest_sample) severity FAILURE;
-- NOTE: Sample Memory Empty (newest_sample also set to MAX_ADDR)
-- Fix Oldest Pointer
oldest_sample_next <= next_sample;
oldest_sample_next <= SAMPLE_MEMORY_MAX_ADDRESS;
cnt_next <= cnt + 3; -- Skip next 2 steps
else
cnt_next <= cnt + 2; -- Skip next step
else
cnt_next <= cnt + 1;
end if;
end if;
-- SET Next Pointer (Previous Sample)
when 10 =>
-- 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
else
cnt_next <= cnt + 1;
end if;
-- READ Payload Pointer
when 11 =>
sample_ready_out <= '1';
end if;
-- SET Previous Pointer (Next Sample)
when 9 =>
-- 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_valid_out = '1') then
-- Update Global Sample Count
global_sample_cnt_next <= global_sample_cnt - 1;
-- 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;
-- Update Global ACK Count
-- Sample was ACKed
if (sample_status_info(SSI_ACK_FLAG) = '1') then
global_ack_cnt_next <= global_ack_cnt - 1;
end if;
-- Fix Oldest Pointer
oldest_sample_next <= next_sample;
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
-- Orphan Sample Removal in progress
if (orphan_samples = '1') then
-- End of Samples
if (next_sample = SAMPLE_MEMORY_MAX_ADDRESS) then
-- DONE
orphan_samples_next <= '0';
stage_next <= IDLE;
else
-- Continue
stage_next <= REMOVE_ORPHAN_SAMPLES;
cur_sample_next <= next_sample;
cnt_next <= 0;
end if;
else
stage_next <= POST_SAMPLE_REMOVE;
end if;
-- 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);
-- Orphan Sample Removal in progress
if (orphan_samples = '1') then
-- End of Samples
if (next_sample = SAMPLE_MEMORY_MAX_ADDRESS) then
-- DONE
orphan_samples_next <= '0';
stage_next <= IDLE;
else
-- Continue
stage_next <= REMOVE_ORPHAN_SAMPLES;
cur_sample_next <= next_sample;
cnt_next <= 0;
end if;
else
stage_next <= POST_SAMPLE_REMOVE;
end if;
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 12 =>
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 + 2; -- Skip next step
else
cnt_next <= cnt + 1;
end if;
-- READ Next Payload
when 13 =>
payload_ready_out <= '1';
end if;
-- SET Next Pointer (Previous Sample)
when 10 =>
-- 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 (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;
-- Memory Flow Control Guard
if (sample_ready_in = '1') then
cnt_next <= cnt + 1;
end if;
-- READ Payload Pointer
when 11 =>
sample_ready_out <= '1';
-- Memory Flow Control Guard
if (sample_valid_out = '1') then
-- Update Global Sample Count
global_sample_cnt_next <= global_sample_cnt - 1;
-- Update Global ACK Count
-- Sample was ACKed
if (sample_status_info(SSI_ACK_FLAG) = '1') then
global_ack_cnt_next <= global_ack_cnt - 1;
end if;
-- Next Payload Pointer (Last Payload of Current Sample)
when 14 =>
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
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
-- Orphan Sample Removal in progress
if (orphan_samples = '1') then
-- End of Samples
@ -2475,11 +2390,88 @@ begin
else
stage_next <= POST_SAMPLE_REMOVE;
end if;
-- 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);
-- Orphan Sample Removal in progress
if (orphan_samples = '1') then
-- End of Samples
if (next_sample = SAMPLE_MEMORY_MAX_ADDRESS) then
-- DONE
orphan_samples_next <= '0';
stage_next <= IDLE;
else
-- Continue
stage_next <= REMOVE_ORPHAN_SAMPLES;
cur_sample_next <= next_sample;
cnt_next <= 0;
end if;
else
stage_next <= POST_SAMPLE_REMOVE;
end if;
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;
when others =>
null;
end case;
end if;
end if;
-- GET Next Payload
when 12 =>
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 13 =>
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 14 =>
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
-- Orphan Sample Removal in progress
if (orphan_samples = '1') then
-- End of Samples
if (next_sample = SAMPLE_MEMORY_MAX_ADDRESS) then
-- DONE
orphan_samples_next <= '0';
stage_next <= IDLE;
else
-- Continue
stage_next <= REMOVE_ORPHAN_SAMPLES;
cur_sample_next <= next_sample;
cnt_next <= 0;
end if;
else
stage_next <= POST_SAMPLE_REMOVE;
end if;
end if;
when others =>
null;
end case;
when POST_SAMPLE_REMOVE =>
-- Precondition: inst_data set (Status Info, Sample Count, ACK Count)
@ -3526,7 +3518,6 @@ begin
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;
-- DEFAULT Unregistered
@ -4409,7 +4400,6 @@ begin
global_ack_cnt <= 0;
stale_inst_cnt <= 0;
inst_cnt <= 0;
inst_cnt2 <= 0;
remove_oldest_sample <= '0';
remove_oldest_inst_sample <= '0';
remove_ack_sample <= '0';
@ -4480,7 +4470,6 @@ begin
global_ack_cnt <= global_ack_cnt_next;
stale_inst_cnt <= stale_inst_cnt_next;
inst_cnt <= inst_cnt_next;
inst_cnt2 <= inst_cnt2_next;
remove_oldest_sample <= remove_oldest_sample_next;
remove_oldest_inst_sample <= remove_oldest_inst_sample_next;
remove_ack_sample <= remove_ack_sample_next;

View File

@ -1768,6 +1768,8 @@ begin
-- Ignore
null;
when PID_SENTINEL =>
parameter_end_next <= (others => '1');
-- If Processing in-line QoS until now, start processing data
if(qos_flag = '1') then
-- Override QoS Flag
@ -1777,7 +1779,6 @@ begin
else
stage_next <= CHECK_DEFAULT;
end if;
when PID_LIST_END =>
-- TODO
null;

View File

@ -488,6 +488,8 @@ package rtps_package is
function min(L, R : DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY;
function max(L, R : DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY;
function to_integer(dw : DOUBLE_WORD_ARRAY) return integer;
function to_unsigned(input : KEY_HASH_TYPE) return unsigned;
function to_unsigned(input : GUID_TYPE) return unsigned;
end package;
package body rtps_package is
@ -691,4 +693,22 @@ package body rtps_package is
return ret;
end function;
function to_unsigned(input : KEY_HASH_TYPE) return unsigned is
variable ret : unsigned(KEY_HASH_WIDTH-1 downto 0) := (others => '0');
begin
for i in 0 to KEY_HASH_TYPE'length-1 loop
ret(((KEY_HASH_TYPE'length-i)*WORD_WIDTH)-1 downto (KEY_HASH_TYPE'length-1-i)*WORD_WIDTH) := unsigned(input(i));
end loop;
return ret;
end function;
function to_unsigned(input : GUID_TYPE) return unsigned is
variable ret : unsigned(GUID_WIDTH-1 downto 0) := (others => '0');
begin
for i in 0 to GUID_TYPE'length-1 loop
ret(((GUID_TYPE'length-i)*WORD_WIDTH)-1 downto (GUID_TYPE'length-1-i)*WORD_WIDTH) := unsigned(input(i));
end loop;
return ret;
end function;
end package body;

View File

@ -227,7 +227,95 @@ package rtps_test_package is
payload : TEST_PACKET_TYPE;
end record;
constant DEFAULT_CACHE_CHANGE : CACHE_CHANGE_TYPE; -- Defeered to Package Body
constant DEFAULT_CACHE_CHANGE : CACHE_CHANGE_TYPE; -- Deferred to Package Body
type SAMPLE_TYPE is record
inst : INSTANCE_HANDLE_TYPE;
data : TEST_PACKET_TYPE;
sstate : std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0);
istate : std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0);
vstate : std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0);
dis_gen_cnt : natural;
no_w_gen_cnt : natural;
srank : natural;
grank : natural;
agrank : natural;
ts : TIME_TYPE;
end record;
constant DEFAULT_SAMPLE : SAMPLE_TYPE; -- Deferred to Package Body
type SAMPLE_ARRAY_TYPE is array (0 to 10) of SAMPLE_TYPE;
type COLLECTION_TYPE is record
s : SAMPLE_ARRAY_TYPE;
len : natural;
end record;
constant DEFAULT_COLLECTION : COLLECTION_TYPE; -- Deferred to Package Body
type INSTANCE_CACHE_TYPE is record
inst : INSTANCE_HANDLE_TYPE;
istate : std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0);
vstate : std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0);
dis_gen_cnt : natural;
no_w_gen_cnt : natural;
end record;
constant DEFAULT_INSTANCE_CACHE_TYPE : INSTANCE_CACHE_TYPE; -- Deferred to Package Body
type INSTANCE_CACHE_ARRAY_TYPE is array (0 to 10) of INSTANCE_CACHE_TYPE;
type DDS_READER_MEM_TYPE is record
s : SAMPLE_ARRAY_TYPE;
slen : natural;
inst : INSTANCE_CACHE_ARRAY_TYPE;
ilen : natural;
end record;
constant DEFAULT_DDS_READER_MEM : DDS_READER_MEM_TYPE; -- Deferred to Package Body
type DDS_READER_TEST_TYPE is record
opcode : DDS_READER_OPCODE_TYPE;
sstate : std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0);
istate : std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0);
vstate : std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0);
max_samples : natural;
inst : INSTANCE_HANDLE_TYPE;
ret_code : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
end record;
constant DEFAULT_DDS_READER_TEST : DDS_READER_TEST_TYPE; -- Deferred to Package Body
type RTPS_WRITER_TEST_TYPE is record
opcode : HISTORY_CACHE_OPCODE_TYPE;
cc : CACHE_CHANGE_TYPE;
ret_code : HISTORY_CACHE_RESPONSE_TYPE;
end record;
constant DEFAULT_RTPS_WRITER_TEST : RTPS_WRITER_TEST_TYPE; -- Deferred to Package Body
type RTPS_READER_TEST_TYPE is record
opcode : HISTORY_CACHE_OPCODE_TYPE;
cc : CACHE_CHANGE_TYPE;
lifespan : DURATION_TYPE;
writer_pos : natural;
ret_code : HISTORY_CACHE_RESPONSE_TYPE;
end record;
constant DEFAULT_RTPS_READER_TEST : RTPS_READER_TEST_TYPE; -- Deferred to Package Body
type DDS_WRITER_TEST_TYPE is record
opcode : DDS_WRITER_OPCODE_TYPE;
cc : CACHE_CHANGE_TYPE;
ret_code : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
count : natural;
change : natural;
inst : INSTANCE_HANDLE_TYPE;
assertion : std_logic;
end record;
constant DEFAULT_DDS_WRITER_TEST : DDS_WRITER_TEST_TYPE; -- Deferred to Package Body
function test_memory_match (A,B : TEST_MEMORY_TYPE) return boolean;
function to_string (input : TEST_MEMORY_TYPE) return string;
@ -276,6 +364,17 @@ package rtps_test_package is
function int(n : integer; width : natural) return std_logic_vector;
function to_string1 (input : std_logic_vector) return string;
--procedure add_instance(inst : inout INSTANCE_HANDLE_TYPE; mem : inout DDS_READER_MEM_TYPE);
function to_sample(cc : CACHE_CHANGE_TYPE; istate : std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0)) return SAMPLE_TYPE;
procedure change_istate(inst : INSTANCE_HANDLE_TYPE; istate : in std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); mem : inout DDS_READER_MEM_TYPE);
procedure add_sample(sample : inout SAMPLE_TYPE; mem : inout DDS_READER_MEM_TYPE; DESTINATION_ORDER_QOS : in std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0));
procedure remove_sample(ind : in natural; mem : inout DDS_READER_MEM_TYPE);
procedure remove_inst(inst : in INSTANCE_HANDLE_TYPE; mem : inout DDS_READER_MEM_TYPE);
--function check_instance(istate : std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); vstate : std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0); mem : DDS_READER_MEM_TYPE; inst : INSTANCE_HANDLE_TYPE) return boolean;
--function find_instance(mem : DDS_READER_MEM_TYPE; inst : INSTANCE_HANDLE_TYPE) return natural;
--procedure gen_collection (mem : inout DDS_READER_MEM_TYPE; col : inout COLLECTION_TYPE; inst : INSTANCE_HANDLE_TYPE; sstate : in std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0); istate : in std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); vstate : in std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0); max_samples : in natural; remove : in boolean; sort : in boolean);
procedure gen_collection (mem : inout DDS_READER_MEM_TYPE; col : inout COLLECTION_TYPE; opcode : in DDS_READER_TEST_TYPE; PRESENTATION_QOS : in std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0); ordered : in boolean);
-- NOTE: This assume a specific sending order (Multicast before Unicast)!
function get_loc (ref : PARTICIPANT_DATA_TYPE; meta : boolean) return LOCATOR_TYPE;
function get_loc (ref : ENDPOINT_DATA_TYPE) return LOCATOR_TYPE;
@ -524,6 +623,74 @@ package body rtps_test_package is
payload => EMPTY_TEST_PACKET
);
constant DEFAULT_SAMPLE : SAMPLE_TYPE := (
inst => HANDLE_NIL,
data => EMPTY_TEST_PACKET,
sstate => NOT_READ_SAMPLE_STATE,
istate => ALIVE_INSTANCE_STATE,
vstate => NEW_VIEW_STATE,
dis_gen_cnt => 0,
no_w_gen_cnt => 0,
srank => 0,
grank => 0,
agrank => 0,
ts => TIME_INVALID
);
constant DEFAULT_COLLECTION : COLLECTION_TYPE := (
s => (others => DEFAULT_SAMPLE),
len => 0
);
constant DEFAULT_INSTANCE_CACHE_TYPE : INSTANCE_CACHE_TYPE := (
inst => HANDLE_NIL,
istate => ALIVE_INSTANCE_STATE,
vstate => NEW_VIEW_STATE,
dis_gen_cnt => 0,
no_w_gen_cnt => 0
);
constant DEFAULT_DDS_READER_MEM : DDS_READER_MEM_TYPE := (
s => (others => DEFAULT_SAMPLE),
slen => 0,
inst => (others => DEFAULT_INSTANCE_CACHE_TYPE),
ilen => 0
);
constant DEFAULT_DDS_READER_TEST : DDS_READER_TEST_TYPE := (
opcode => NOP,
sstate => ANY_SAMPLE_STATE,
istate => ANY_INSTANCE_STATE,
vstate => ANY_VIEW_STATE,
max_samples => 1,
inst => HANDLE_NIL,
ret_code => RETCODE_OK
);
constant DEFAULT_RTPS_WRITER_TEST : RTPS_WRITER_TEST_TYPE := (
opcode => NOP,
cc => DEFAULT_CACHE_CHANGE,
ret_code => OK
);
constant DEFAULT_RTPS_READER_TEST : RTPS_READER_TEST_TYPE := (
opcode => NOP,
cc => DEFAULT_CACHE_CHANGE,
lifespan => DURATION_INFINITE,
writer_pos => 0,
ret_code => OK
);
constant DEFAULT_DDS_WRITER_TEST : DDS_WRITER_TEST_TYPE := (
opcode => NOP,
cc => DEFAULT_CACHE_CHANGE,
ret_code => RETCODE_OK,
count => 0,
change => 0,
inst => HANDLE_NIL,
assertion => '0'
);
-- *PACKAGE INTERNAL HELPER FUNCTIONS*
procedure store_byte(in_off : in natural range 0 to 3; input : in std_logic_vector(WORD_WIDTH-1 downto 0); out_off : in natural range 0 to 3; output : inout TEST_PACKET_TYPE) is
@ -2619,4 +2786,374 @@ package body rtps_test_package is
return "wr: " & to_string(input(0 to NUM_ENDPOINTS-1)) & ", last_word: " & to_string(input(NUM_ENDPOINTS)) & ", data: " & to_hstring(input(NUM_ENDPOINTS+1 to input'length-1));
end function;
procedure add_instance(inst : in INSTANCE_HANDLE_TYPE; mem : inout DDS_READER_MEM_TYPE) is
variable ind : natural := 0;
begin
-- Find Position
ind := mem.ilen;
for i in 0 to mem.ilen-1 loop
if (to_unsigned(inst) < to_unsigned(mem.inst(i).inst)) then
ind := i;
exit;
end if;
end loop;
-- Move elements to make Space
for i in mem.ilen-1 downto ind loop
mem.inst(i+1) := mem.inst(i);
end loop;
-- Insert at desired index
mem.inst(ind) := DEFAULT_INSTANCE_CACHE_TYPE;
mem.inst(ind).inst := inst;
mem.ilen := mem.ilen + 1;
end procedure;
function to_sample(cc : CACHE_CHANGE_TYPE; istate : std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0)) return SAMPLE_TYPE is
variable ret : SAMPLE_TYPE := DEFAULT_SAMPLE;
begin
ret.inst := cc.instance;
if (not cc.serialized_key) then
ret.data := cc.payload;
end if;
ret.ts := cc.src_timestamp;
ret.istate := istate;
return ret;
end function;
procedure change_istate(inst : in INSTANCE_HANDLE_TYPE; istate : in std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); mem : inout DDS_READER_MEM_TYPE) is
begin
-- Check Instance State
for i in 0 to mem.ilen-1 loop
-- Instance Found
if (inst = mem.inst(i).inst) then
case (istate) is
when ALIVE_INSTANCE_STATE =>
case (mem.inst(i).istate) is
when NOT_ALIVE_DISPOSED_INSTANCE_STATE =>
mem.inst(i).dis_gen_cnt := mem.inst(i).dis_gen_cnt + 1;
mem.inst(i).istate := ALIVE_INSTANCE_STATE;
mem.inst(i).vstate := NEW_VIEW_STATE;
when NOT_ALIVE_NO_WRITERS_INSTANCE_STATE =>
mem.inst(i).no_w_gen_cnt := mem.inst(i).no_w_gen_cnt + 1;
mem.inst(i).istate := ALIVE_INSTANCE_STATE;
mem.inst(i).vstate := NEW_VIEW_STATE;
when others =>
null;
end case;
when NOT_ALIVE_DISPOSED_INSTANCE_STATE =>
case (mem.inst(i).istate) is
when ALIVE_INSTANCE_STATE =>
mem.inst(i).istate := NOT_ALIVE_DISPOSED_INSTANCE_STATE;
when NOT_ALIVE_NO_WRITERS_INSTANCE_STATE =>
mem.inst(i).istate := NOT_ALIVE_DISPOSED_INSTANCE_STATE;
mem.inst(i).no_w_gen_cnt := mem.inst(i).no_w_gen_cnt + 1;
mem.inst(i).vstate := NEW_VIEW_STATE;
when others =>
null;
end case;
when NOT_ALIVE_NO_WRITERS_INSTANCE_STATE =>
case (mem.inst(i).istate) is
when ALIVE_INSTANCE_STATE =>
mem.inst(i).istate := NOT_ALIVE_NO_WRITERS_INSTANCE_STATE;
when others =>
null;
end case;
when others =>
null;
end case;
exit;
end if;
end loop;
end procedure;
procedure add_sample(sample : inout SAMPLE_TYPE; mem : inout DDS_READER_MEM_TYPE; DESTINATION_ORDER_QOS : in std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0)) is
variable found : boolean := FALSE;
variable ind : natural := 0;
begin
-- Zero Meta Data
sample.dis_gen_cnt := 0;
sample.no_w_gen_cnt := 0;
sample.srank := 0;
sample.grank := 0;
sample.agrank := 0;
sample.sstate := NOT_READ_SAMPLE_STATE;
change_istate(sample.inst, sample.istate, mem);
-- Check Instance State
for i in 0 to mem.ilen-1 loop
-- Instance Found
if (sample.inst = mem.inst(i).inst) then
found := TRUE;
sample.vstate := mem.inst(i).vstate;
sample.dis_gen_cnt := mem.inst(i).dis_gen_cnt;
sample.no_w_gen_cnt := mem.inst(i).no_w_gen_cnt;
exit;
end if;
end loop;
-- New Instance
if (not found) then
add_instance(sample.inst, mem);
end if;
-- Add Sample
ind := mem.slen;
case (DESTINATION_ORDER_QOS) is
when BY_RECEPTION_TIMESTAMP_DESTINATION_ORDER_QOS =>
-- Insert at End of Array
mem.s(ind) := sample;
when BY_SOURCE_TIMESTAMP_DESTINATION_ORDER_QOS =>
-- Find Position
for i in 0 to mem.slen-1 loop
if (sample.ts > mem.s(i).ts) then
ind := i;
exit;
end if;
end loop;
-- Move elements to make Space
for i in mem.slen-1 downto ind loop
mem.s(i+1) := mem.s(i);
end loop;
-- Insert at desired index
mem.s(ind) := sample;
when others =>
assert FALSE report "Unkown DESTINATION_ORDER_QOS" severity FAILURE;
end case;
mem.slen := mem.slen + 1;
end procedure;
procedure remove_sample(ind : in natural; mem : inout DDS_READER_MEM_TYPE) is
begin
assert (ind < mem.slen) report "Index is out of Bounds" severity FAILURE;
assert (mem.slen /= 0) report "Remove on empty array" severity FAILURE;
-- NOTE: Assumes i+1 is in bounds
for i in ind to mem.slen-1 loop
mem.s(i) := mem.s(i+1);
end loop;
mem.slen := mem.slen - 1;
end procedure;
procedure remove_inst(inst : in INSTANCE_HANDLE_TYPE; mem : inout DDS_READER_MEM_TYPE) is
variable ind : natural := 0;
begin
assert (mem.ilen /= 0) report "Remove on empty array" severity FAILURE;
ind := mem.ilen;
for i in 0 to mem.ilen-1 loop
-- Instance Found
if (mem.inst(i).inst = inst) then
ind := i;
exit;
end if;
end loop;
if (ind /= mem.ilen) then
-- NOTE: Assumes i+1 is in bounds
for i in ind to mem.ilen-1 loop
mem.inst(i) := mem.inst(i+1);
end loop;
mem.ilen := mem.ilen - 1;
end if;
end procedure;
function check_instance(istate : std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); vstate : std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0); mem : DDS_READER_MEM_TYPE; inst : INSTANCE_HANDLE_TYPE) return boolean is
begin
for i in 0 to mem.ilen-1 loop
-- Instance Found
if (inst = mem.inst(i).inst) then
if (((mem.inst(i).istate and istate) /= (istate'range => '0')) and ((mem.inst(i).vstate and vstate) /= (vstate'range => '0'))) then
return TRUE;
end if;
end if;
end loop;
return FALSE;
end function;
function find_instance(mem : DDS_READER_MEM_TYPE; inst : INSTANCE_HANDLE_TYPE) return natural is
begin
for i in 0 to mem.ilen-1 loop
-- Instance Found
if (inst = mem.inst(i).inst) then
return i;
end if;
end loop;
assert FALSE report "Instance not in Memory" severity FAILURE;
end function;
procedure gen_collection (mem : inout DDS_READER_MEM_TYPE; col : inout COLLECTION_TYPE; inst : INSTANCE_HANDLE_TYPE; sstate : in std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0); istate : in std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); vstate : in std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0); max_samples : in natural; remove : in boolean; sort : in boolean) is
variable i,j : natural := 0;
variable tmp_inst : INSTANCE_HANDLE_TYPE := HANDLE_NIL;
variable tmp_col : COLLECTION_TYPE := DEFAULT_COLLECTION;
variable rank, mrsic_gen, mrs_gen : natural := 0;
variable done : std_logic_vector(0 to max_samples-1) := (others => '0');
variable no_inst : boolean := FALSE;
begin
col := DEFAULT_COLLECTION;
i := 0;
loop
-- Sample is in Collection
if (((mem.s(i).sstate and sstate) /= (sstate'range => '0')) and check_instance(istate, vstate, mem, mem.s(i).inst) and ((inst /= HANDLE_NIL and inst = mem.s(i).inst) or inst = HANDLE_NIL)) then
col.s(col.len) := mem.s(i);
col.s(col.len).istate := mem.inst(find_instance(mem,mem.s(i).inst)).istate;
col.s(col.len).vstate := mem.inst(find_instance(mem,mem.s(i).inst)).vstate;
col.len := col.len + 1;
-- Change READ STATE
mem.s(i).sstate := READ_SAMPLE_STATE;
-- Remove Sample
if (remove) then
remove_sample(i, mem);
-- NOTE: We do not increment the loop invariant
else
i := i + 1;
end if;
else
i := i + 1;
end if;
-- Loop Exit Condition
if (i >= mem.slen or col.len >= max_samples) then
exit;
end if;
end loop;
if (col.len = 0) then
report "Empty Collection" severity NOTE;
return;
end if;
-- No Instances (WITH_KEY=FALSE testing)
if (col.s(0).inst = HANDLE_NIL) then
no_inst := TRUE;
end if;
-- Sort
if (sort and not no_inst) then
i := 1;
j := 1;
tmp_inst := col.s(0).inst;
tmp_col := DEFAULT_COLLECTION;
tmp_col.len := col.len;
tmp_col.s(0):= col.s(0);
col.s(0) := DEFAULT_SAMPLE;
loop
-- Select Next Instance
if (tmp_inst = HANDLE_NIL) then
if (col.s(i).inst /= HANDLE_NIL) then
tmp_inst := col.s(i).inst;
i := 0; --Reset
end if;
elsif (col.s(i).inst = tmp_inst) then
tmp_col.s(j) := col.s(i);
col.s(i) := DEFAULT_SAMPLE;
j := j + 1;
end if;
i := i + 1;
-- DONE
if (j >= col.len) then
col := tmp_col;
exit;
-- Reset Index
elsif (i >= col.len) then
i := 0;
tmp_inst := HANDLE_NIL;
end if;
end loop;
end if;
-- Calculate Ranks
i := col.len-1;
tmp_inst := col.s(i).inst;
j := find_instance(mem,tmp_inst);
rank := 1;
mrs_gen := mem.inst(j).dis_gen_cnt + mem.inst(j).no_w_gen_cnt;
mrsic_gen := col.s(i).dis_gen_cnt + col.s(i).no_w_gen_cnt;
col.s(i).agrank := mrs_gen - mrsic_gen;
if (mrs_gen - mrsic_gen = 0) then
-- Change VIEW STATE
mem.inst(j).vstate := NOT_NEW_VIEW_STATE;
end if;
done(col.len-1 to done'length-1) := (others => '1');
-- Single Sample
if (col.len-1 = 0) then
return;
else
loop
i := i - 1;
-- Select Next Instance
if (not no_inst and tmp_inst = HANDLE_NIL) then
if (done(i) = '0') then
tmp_inst := col.s(i).inst;
j := find_instance(mem, tmp_inst);
-- Reset
rank := 1;
mrs_gen := mem.inst(j).dis_gen_cnt + mem.inst(j).no_w_gen_cnt;
mrsic_gen := col.s(i).dis_gen_cnt + col.s(i).no_w_gen_cnt;
col.s(i).agrank := mrs_gen - mrsic_gen;
if (mrs_gen - mrsic_gen = 0) then
-- Change VIEW STATE
mem.inst(j).vstate := NOT_NEW_VIEW_STATE;
end if;
done(i) := '1';
end if;
elsif (done(i) = '0' and col.s(i).inst = tmp_inst) then
col.s(i).srank := rank;
rank := rank + 1;
col.s(i).grank := mrsic_gen - (col.s(i).dis_gen_cnt + col.s(i).no_w_gen_cnt);
col.s(i).agrank := mrs_gen - (col.s(i).dis_gen_cnt + col.s(i).no_w_gen_cnt);
done(i) := '1';
end if;
-- Exit Condition
if (done = (done'range => '1')) then
exit;
-- Reset
elsif (i = 0) then
tmp_inst := HANDLE_NIL;
i := col.len-1;
end if;
end loop;
end if;
end procedure;
procedure gen_collection (mem : inout DDS_READER_MEM_TYPE; col : inout COLLECTION_TYPE; opcode : in DDS_READER_TEST_TYPE; PRESENTATION_QOS : in std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0); ordered : in boolean) is
variable sort : boolean := FALSE;
variable tmp_inst : INSTANCE_HANDLE_TYPE := HANDLE_NIL;
begin
col := DEFAULT_COLLECTION;
sort := TRUE when (not ordered or PRESENTATION_QOS = INSTANCE_PRESENTATION_QOS) else FALSE;
case (opcode.opcode) is
when READ =>
gen_collection(mem, col, HANDLE_NIL, opcode.sstate, opcode.istate, opcode.vstate, opcode.max_samples, FALSE, sort);
when TAKE =>
gen_collection(mem, col, HANDLE_NIL, opcode.sstate, opcode.istate, opcode.vstate, opcode.max_samples, TRUE, sort);
when READ_NEXT_SAMPLE =>
gen_collection(mem, col, HANDLE_NIL, NOT_READ_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE, 1, FALSE, FALSE);
when TAKE_NEXT_SAMPLE =>
gen_collection(mem, col, HANDLE_NIL, NOT_READ_SAMPLE_STATE, ANY_INSTANCE_STATE, ANY_VIEW_STATE, 1, TRUE, FALSE);
when READ_INSTANCE =>
gen_collection(mem, col, opcode.inst, opcode.sstate, opcode.istate, opcode.vstate, opcode.max_samples, FALSE, sort);
when TAKE_INSTANCE =>
gen_collection(mem, col, opcode.inst, opcode.sstate, opcode.istate, opcode.vstate, opcode.max_samples, TRUE, sort);
when READ_NEXT_INSTANCE =>
tmp_inst := mem.inst(find_instance(mem,opcode.inst)+1).inst;
if (tmp_inst /= HANDLE_NIL) then
gen_collection(mem, col, tmp_inst, opcode.sstate, opcode.istate, opcode.vstate, opcode.max_samples, FALSE, sort);
end if;
when TAKE_NEXT_INSTANCE =>
tmp_inst := mem.inst(find_instance(mem,opcode.inst)+1).inst;
if (tmp_inst /= HANDLE_NIL) then
gen_collection(mem, col, tmp_inst, opcode.sstate, opcode.istate, opcode.vstate, opcode.max_samples, TRUE, sort);
end if;
when others =>
assert FALSE report "Unknown DDS Reader Operation" severity FAILURE;
end case;
end procedure;
end package body;