Add Test3 of DDS Writer

Test Deadline Handling of DDS Writer.
Test GET_OFFERED_DEADLINE_MISSED_STATUS DDS Operation.
This commit is contained in:
Greek 2021-03-29 12:19:06 +02:00
parent 069657ee3b
commit 7c2978e863
6 changed files with 1755 additions and 31 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,754 @@
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;
entity L0_dds_writer_test3_aik is
end entity;
architecture testbench of L0_dds_writer_test3_aik is
-- *CONSTANT DECLARATION*
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 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
);
type DEADLINE_TEST_TYPE is record
count : natural;
change : natural;
instance : INSTANCE_HANDLE_TYPE;
end record;
constant DEFAULT_DEADLINE_TEST : DEADLINE_TEST_TYPE := (
count => 0,
change => 0,
instance => HANDLE_NIL
);
-- *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_WRITER_OPCODE_TYPE := NOP;
signal opcode_kh : KEY_HOLDER_OPCODE_TYPE := NOP;
signal ret_rtps : HISTORY_CACHE_RESPONSE_TYPE := ERROR;
signal seq_nr_rtps, cc_seq_nr : SEQUENCENUMBER_TYPE := SEQUENCENUMBER_UNKNOWN;
signal ready_out_rtps, valid_out_rtps, last_word_out_rtps : std_logic := '0';
signal ready_in_dds, ready_out_dds, valid_in_dds, valid_out_dds, last_word_in_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_out_rtps, data_in_dds, data_out_dds, data_in_kh, data_out_kh : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0');
signal get_data_rtps, liveliness_assertion, data_available, abort_kh : std_logic := '0';
signal cc_source_timestamp, source_ts_dds : TIME_TYPE := TIME_INVALID;
signal cc_kind : CACHE_CHANGE_KIND_TYPE := ALIVE;
signal cc_instance_handle, instance_handle_dds : INSTANCE_HANDLE_TYPE := HANDLE_NIL;
signal max_wait_dds : DURATION_TYPE := DURATION_INFINITE;
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 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 deadline_ref : DEADLINE_TEST_TYPE := DEFAULT_DEADLINE_TEST;
signal inst_id, kind_id, sn_id, ts_id, data_id, ret_id, status_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_writer(arch)
generic map(
HISTORY_QOS => KEEP_ALL_HISTORY_QOS,
DEADLINE_QOS => gen_duration(1,0),
LIFESPAN_QOS => DURATION_INFINITE,
LEASE_DURATION => DURATION_INFINITE,
WITH_KEY => TRUE,
MAX_SAMPLES => std_logic_vector(to_unsigned(4,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)),
PAYLOAD_FRAME_SIZE => 11
)
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,
seq_nr_rtps => seq_nr_rtps,
get_data_rtps => get_data_rtps,
data_out_rtps => data_out_rtps,
valid_out_rtps => valid_out_rtps,
ready_out_rtps => ready_out_rtps,
last_word_out_rtps => last_word_out_rtps,
liveliness_assertion => liveliness_assertion,
data_available => data_available,
cc_instance_handle => cc_instance_handle,
cc_kind => cc_kind,
cc_source_timestamp => cc_source_timestamp,
cc_seq_nr => cc_seq_nr,
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_handle_dds => instance_handle_dds,
source_ts_dds => source_ts_dds,
max_wait_dds => max_wait_dds,
done_dds => done_dds,
return_code_dds => return_code_dds,
ready_in_dds => ready_in_dds,
valid_in_dds => valid_in_dds,
data_in_dds => data_in_dds,
last_word_in_dds => last_word_in_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,
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;
alias idle_sig is <<signal uut.idle_sig : std_logic>>;
impure function gen_payload(key_hash : INSTANCE_HANDLE_TYPE; len : natural) return TEST_PACKET_TYPE is
variable ret : TEST_PACKET_TYPE := EMPTY_TEST_PACKET;
begin
assert (len >= 4) report "Payload length has to be at least 16 Bytes long" severity FAILURE;
for i in 0 to len-1 loop
if (i < 4) then
-- NOTE: Beginning of payload is negated key to allow deterministic Key Hash generation from the kh_prc
ret.data(ret.length) := not key_hash(i);
else
ret.data(ret.length) := RV.RandSlv(WORD_WIDTH);
end if;
ret.length := ret.length + 1;
end loop;
ret.last(ret.length-1) := '1';
return ret;
end function;
impure function gen_key_hash return KEY_HASH_TYPE is
variable ret : KEY_HASH_TYPE := (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_stim is
begin
stim_start <= '1';
wait until rising_edge(clk);
stim_start <= '0';
wait until rising_edge(clk);
end procedure;
procedure start_ref is
begin
ref_start <= '1';
wait until rising_edge(clk);
ref_start <= '0';
wait until rising_edge(clk);
end procedure;
procedure wait_on_stim is
begin
if (stim_done /= '1') then
wait until stim_done = '1';
end if;
end procedure;
procedure wait_on_ref is
begin
if (ref_done /= '1') then
wait until ref_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';
end if;
end procedure;
-- NOTE: This procedure waits until the idle_sig is high for at least
-- two consecutive clock cycles.
procedure wait_on_idle is
begin
loop
if (idle_sig /= '1') then
wait until idle_sig = '1';
else
exit;
end if;
wait until rising_edge(clk);
wait until rising_edge(clk);
end loop;
end procedure;
begin
SetAlertLogName("dds_writer - (KEEP ALL, Infinite Lifespan, Keyed) - Level 0 - Deadline Handling");
SetAlertEnable(FAILURE, TRUE);
SetAlertEnable(ERROR, TRUE);
SetAlertEnable(WARNING, TRUE);
SetLogEnable(DEBUG, FALSE);
SetLogEnable(PASSED, FALSE);
SetLogEnable(INFO, TRUE);
RV.InitSeed(RV'instance_name);
inst_id <= GetAlertLogID("Instance", ALERTLOG_BASE_ID);
kind_id <= GetAlertLogID("Cache Change Kind", ALERTLOG_BASE_ID);
sn_id <= GetAlertLogID("SequenceNumber", ALERTLOG_BASE_ID);
ts_id <= GetAlertLogID("TimeStamp", ALERTLOG_BASE_ID);
data_id <= GetAlertLogID("Data Out", ALERTLOG_BASE_ID);
ret_id <= GetAlertLogID("Return Code", ALERTLOG_BASE_ID);
status_id <= GetAlertLogID("Communication Status", ALERTLOG_BASE_ID);
-- Key Hashes
kh1 := gen_key_hash;
kh2 := gen_key_hash;
kh3 := gen_key_hash;
kh4 := gen_key_hash;
Log("Initiating Test", INFO);
Log("Current Time: 0s", INFO);
check_time <= TIME_ZERO;
reset <= '1';
wait until rising_edge(clk);
wait until rising_edge(clk);
reset <= '0';
wait_on_idle;
-- Stored CC: 0, 0, 0, 0
AffirmIf(status_id,(status and OFFERED_DEADLINE_MISSED_STATUS) /= OFFERED_DEADLINE_MISSED_STATUS, "Expected: 0", "Received 1");
Log("Current Time: 1s", INFO);
check_time <= gen_duration(1,0);
wait until rising_edge(clk);
wait until rising_edge(clk);
wait_on_idle;
AffirmIf(status_id,(status and OFFERED_DEADLINE_MISSED_STATUS) /= OFFERED_DEADLINE_MISSED_STATUS, "Expected: 0", "Received 1");
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh1;
cc.payload := gen_payload(kh1,10);
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;
cc1 := cc;
-- Stored CC: I1S1, 0, 0, 0
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh2;
cc.payload := gen_payload(kh2,10);
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;
cc2 := cc;
-- Stored CC: I1S1, I2S2, 0, 0
Log("Current Time: 2s", INFO);
check_time <= gen_duration(2,0);
wait until rising_edge(clk);
wait until rising_edge(clk);
wait_on_idle;
AffirmIf(status_id,(status and OFFERED_DEADLINE_MISSED_STATUS) /= OFFERED_DEADLINE_MISSED_STATUS, "Expected: 0", "Received 1");
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh1;
cc.payload := gen_payload(kh1,10);
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;
cc3 := cc;
-- Stored CC: I1S1, I2S2, I1S3, 0
Log("Current Time: 3s", INFO);
check_time <= gen_duration(3,0);
wait until rising_edge(clk);
wait until rising_edge(clk);
wait_on_idle;
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;
deadline_ref := DEFAULT_DEADLINE_TEST;
deadline_ref.count := 1;
deadline_ref.change := 1;
deadline_ref.instance := kh2;
start_stim;
wait_on_stim;
wait_on_idle;
AffirmIf(status_id,(status and OFFERED_DEADLINE_MISSED_STATUS) /= OFFERED_DEADLINE_MISSED_STATUS, "Expected: 0", "Received 1");
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh3;
cc.payload := gen_payload(kh3,10);
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;
cc4 := cc;
-- Stored CC: I1S1, I2S2, I1S3, I3S4
Log("Current Time: 4s", INFO);
check_time <= gen_duration(4,0);
wait until rising_edge(clk);
wait until rising_edge(clk);
wait_on_idle;
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;
deadline_ref := DEFAULT_DEADLINE_TEST;
deadline_ref.count := 3;
deadline_ref.change := 2;
deadline_ref.instance := kh1;
start_stim;
wait_on_stim;
wait_on_idle;
AffirmIf(status_id,(status and OFFERED_DEADLINE_MISSED_STATUS) /= OFFERED_DEADLINE_MISSED_STATUS, "Expected: 0", "Received 1");
Log("Current Time: 5s", INFO);
check_time <= gen_duration(5,0);
wait until rising_edge(clk);
wait until rising_edge(clk);
wait_on_idle;
AffirmIf(status_id,(status and OFFERED_DEADLINE_MISSED_STATUS) = OFFERED_DEADLINE_MISSED_STATUS, "Expected: 1", "Received 0");
Log("Current Time: 6s", INFO);
check_time <= gen_duration(6,0);
wait until rising_edge(clk);
wait until rising_edge(clk);
wait_on_idle;
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;
deadline_ref := DEFAULT_DEADLINE_TEST;
deadline_ref.count := 9;
deadline_ref.change := 6;
deadline_ref.instance := kh1;
start_stim;
wait_on_stim;
wait_on_idle;
AffirmIf(status_id,(status and OFFERED_DEADLINE_MISSED_STATUS) /= OFFERED_DEADLINE_MISSED_STATUS, "Expected: 0", "Received 1");
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;
stim_prc : process(all)
begin
if rising_edge(clk) then
stim_done <= '0';
case (stim_stage) is
when IDLE =>
if (stim_start = '1') then
stim_stage <= START;
else
stim_done <= '1';
end if;
when START =>
if (ack_dds = '1') then
case (stimulus.opcode) is
when GET_OFFERED_DEADLINE_MISSED_STATUS =>
stim_stage <= DONE;
stim_cnt <= 0;
when others =>
stim_stage <= PUSH;
stim_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
-- DEFAULT
stim_stage <= DONE;
case (stimulus.opcode) is
when REGISTER_INSTANCE =>
stim_stage <= CHECK;
stim_cnt <= 0;
when LOOKUP_INSTANCE =>
stim_stage <= CHECK;
stim_cnt <= 0;
when others =>
null;
end case;
end if;
end if;
when DONE =>
if (done_dds = '1') then
AffirmIfEqual(ret_id, return_code_dds, stimulus.ret_code);
case (stimulus.opcode) is
when GET_OFFERED_DEADLINE_MISSED_STATUS =>
if (stimulus.ret_code = RETCODE_OK) then
stim_stage <= CHECK_DEADLINE;
stim_cnt <= 0;
else
stim_stage <= IDLE;
end if;
when others =>
stim_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
AlertIf(data_id, last_word_out_dds /= '1', "Last Word Signal not pulled High", ERROR);
stim_stage <= IDLE;
end if;
end if;
when CHECK_DEADLINE =>
if (valid_out_dds = '1') then
stim_cnt <= stim_cnt + 1;
case (stim_cnt) is
when 0 =>
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(to_unsigned(deadline_ref.count,CDR_LONG_WIDTH)));
when 1 =>
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(to_unsigned(deadline_ref.change,CDR_LONG_WIDTH)));
when 2 =>
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(deadline_ref.instance(0)));
when 3 =>
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(deadline_ref.instance(1)));
when 4 =>
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(deadline_ref.instance(2)));
when 5 =>
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(deadline_ref.instance(3)));
AlertIf(data_id, last_word_out_dds /= '1', "Last Word Signal not pulled High", ERROR);
stim_stage <= IDLE;
when others =>
null;
end case;
end if;
end case;
end if;
-- DEFAULT
start_dds <= '0';
valid_in_dds <= '0';
last_word_in_dds <= '0';
data_in_dds <= (others => '0');
instance_handle_dds <= HANDLE_NIL;
source_ts_dds <= TIME_INVALID;
ready_out_dds <= '0';
case (stim_stage) is
when START =>
start_dds <= '1';
opcode_dds <= stimulus.opcode;
instance_handle_dds <= stimulus.cc.instance;
source_ts_dds <= stimulus.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);
when CHECK =>
ready_out_dds <= '1';
when CHECK_DEADLINE =>
ready_out_dds <= '1';
when others =>
null;
end case;
end process;
ref_prc : process(all)
begin
if rising_edge(clk) then
ref_done <= '0';
case (ref_stage) is
when IDLE =>
if (ref_start = '1') then
ref_stage <= START;
else
ref_done <= '1';
end if;
when START =>
if (ack_rtps = '1') then
ref_stage <= DONE;
end if;
when DONE =>
if (done_rtps = '1') then
-- DEFAULT
ref_stage <= IDLE;
AffirmIfEqual(ret_id, HISTORY_CACHE_RESPONSE_TYPE'pos(ret_rtps), HISTORY_CACHE_RESPONSE_TYPE'pos(reference.ret_code));
case (reference.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;
end if;
when GET_MIN_SN =>
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(reference.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));
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;
end if;
end if;
end case;
end if;
-- DEFAULT
start_rtps <= '0';
get_data_rtps <= '0';
ready_out_rtps <= '0';
case (ref_stage) is
when START =>
start_rtps <= '1';
opcode_rtps <= reference.opcode;
seq_nr_rtps <= reference.cc.seq_nr;
when DONE =>
if (done_rtps = '1') then
case (reference.opcode) is
when GET_CACHE_CHANGE =>
get_data_rtps <= '1';
when others =>
null;
end case;
end if;
when CHECK =>
ready_out_rtps <= '1';
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;

View File

@ -0,0 +1,671 @@
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;
entity L0_dds_writer_test3_ain is
end entity;
architecture testbench of L0_dds_writer_test3_ain is
-- *CONSTANT DECLARATION*
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 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
);
type DEADLINE_TEST_TYPE is record
count : natural;
change : natural;
instance : INSTANCE_HANDLE_TYPE;
end record;
constant DEFAULT_DEADLINE_TEST : DEADLINE_TEST_TYPE := (
count => 0,
change => 0,
instance => HANDLE_NIL
);
-- *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_WRITER_OPCODE_TYPE := NOP;
signal opcode_kh : KEY_HOLDER_OPCODE_TYPE := NOP;
signal ret_rtps : HISTORY_CACHE_RESPONSE_TYPE := ERROR;
signal seq_nr_rtps, cc_seq_nr : SEQUENCENUMBER_TYPE := SEQUENCENUMBER_UNKNOWN;
signal ready_out_rtps, valid_out_rtps, last_word_out_rtps : std_logic := '0';
signal ready_in_dds, ready_out_dds, valid_in_dds, valid_out_dds, last_word_in_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_out_rtps, data_in_dds, data_out_dds, data_in_kh, data_out_kh : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0');
signal get_data_rtps, liveliness_assertion, data_available, abort_kh : std_logic := '0';
signal cc_source_timestamp, source_ts_dds : TIME_TYPE := TIME_INVALID;
signal cc_kind : CACHE_CHANGE_KIND_TYPE := ALIVE;
signal cc_instance_handle, instance_handle_dds : INSTANCE_HANDLE_TYPE := HANDLE_NIL;
signal max_wait_dds : DURATION_TYPE := DURATION_INFINITE;
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 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 deadline_ref : DEADLINE_TEST_TYPE := DEFAULT_DEADLINE_TEST;
signal inst_id, kind_id, sn_id, ts_id, data_id, ret_id, status_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_writer(arch)
generic map(
HISTORY_QOS => KEEP_ALL_HISTORY_QOS,
DEADLINE_QOS => gen_duration(1,0),
LIFESPAN_QOS => DURATION_INFINITE,
LEASE_DURATION => DURATION_INFINITE,
WITH_KEY => FALSE,
MAX_SAMPLES => std_logic_vector(to_unsigned(4,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)),
PAYLOAD_FRAME_SIZE => 11
)
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,
seq_nr_rtps => seq_nr_rtps,
get_data_rtps => get_data_rtps,
data_out_rtps => data_out_rtps,
valid_out_rtps => valid_out_rtps,
ready_out_rtps => ready_out_rtps,
last_word_out_rtps => last_word_out_rtps,
liveliness_assertion => liveliness_assertion,
data_available => data_available,
cc_instance_handle => cc_instance_handle,
cc_kind => cc_kind,
cc_source_timestamp => cc_source_timestamp,
cc_seq_nr => cc_seq_nr,
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_handle_dds => instance_handle_dds,
source_ts_dds => source_ts_dds,
max_wait_dds => max_wait_dds,
done_dds => done_dds,
return_code_dds => return_code_dds,
ready_in_dds => ready_in_dds,
valid_in_dds => valid_in_dds,
data_in_dds => data_in_dds,
last_word_in_dds => last_word_in_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,
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;
alias idle_sig is <<signal uut.idle_sig : std_logic>>;
impure function gen_payload(key_hash : INSTANCE_HANDLE_TYPE; len : natural) return TEST_PACKET_TYPE is
variable ret : TEST_PACKET_TYPE := EMPTY_TEST_PACKET;
begin
assert (len >= 4) report "Payload length has to be at least 16 Bytes long" severity FAILURE;
for i in 0 to len-1 loop
if (i < 4) then
-- NOTE: Beginning of payload is negated key to allow deterministic Key Hash generation from the kh_prc
ret.data(ret.length) := not key_hash(i);
else
ret.data(ret.length) := RV.RandSlv(WORD_WIDTH);
end if;
ret.length := ret.length + 1;
end loop;
ret.last(ret.length-1) := '1';
return ret;
end function;
impure function gen_key_hash return KEY_HASH_TYPE is
variable ret : KEY_HASH_TYPE := (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_stim is
begin
stim_start <= '1';
wait until rising_edge(clk);
stim_start <= '0';
wait until rising_edge(clk);
end procedure;
procedure start_ref is
begin
ref_start <= '1';
wait until rising_edge(clk);
ref_start <= '0';
wait until rising_edge(clk);
end procedure;
procedure wait_on_stim is
begin
if (stim_done /= '1') then
wait until stim_done = '1';
end if;
end procedure;
procedure wait_on_ref is
begin
if (ref_done /= '1') then
wait until ref_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';
end if;
end procedure;
-- NOTE: This procedure waits until the idle_sig is high for at least
-- two consecutive clock cycles.
procedure wait_on_idle is
begin
loop
if (idle_sig /= '1') then
wait until idle_sig = '1';
else
exit;
end if;
wait until rising_edge(clk);
wait until rising_edge(clk);
end loop;
end procedure;
begin
SetAlertLogName("dds_writer - (KEEP ALL, Infinite Lifespan, Keyed) - Level 0 - Deadline Handling");
SetAlertEnable(FAILURE, TRUE);
SetAlertEnable(ERROR, TRUE);
SetAlertEnable(WARNING, TRUE);
SetLogEnable(DEBUG, FALSE);
SetLogEnable(PASSED, FALSE);
SetLogEnable(INFO, TRUE);
RV.InitSeed(RV'instance_name);
inst_id <= GetAlertLogID("Instance", ALERTLOG_BASE_ID);
kind_id <= GetAlertLogID("Cache Change Kind", ALERTLOG_BASE_ID);
sn_id <= GetAlertLogID("SequenceNumber", ALERTLOG_BASE_ID);
ts_id <= GetAlertLogID("TimeStamp", ALERTLOG_BASE_ID);
data_id <= GetAlertLogID("Data Out", ALERTLOG_BASE_ID);
ret_id <= GetAlertLogID("Return Code", ALERTLOG_BASE_ID);
status_id <= GetAlertLogID("Communication Status", ALERTLOG_BASE_ID);
-- Key Hashes
kh1 := gen_key_hash;
kh2 := gen_key_hash;
kh3 := gen_key_hash;
kh4 := gen_key_hash;
Log("Initiating Test", INFO);
Log("Current Time: 0s", INFO);
check_time <= TIME_ZERO;
reset <= '1';
wait until rising_edge(clk);
wait until rising_edge(clk);
reset <= '0';
wait_on_idle;
-- Stored CC: 0, 0, 0, 0
AffirmIf(status_id,(status and OFFERED_DEADLINE_MISSED_STATUS) /= OFFERED_DEADLINE_MISSED_STATUS, "Expected: 0", "Received 1");
Log("Current Time: 1s", INFO);
check_time <= gen_duration(1,0);
wait until rising_edge(clk);
wait until rising_edge(clk);
wait_on_idle;
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;
deadline_ref := DEFAULT_DEADLINE_TEST;
deadline_ref.count := 1;
deadline_ref.change := 1;
start_stim;
wait_on_stim;
wait_on_idle;
AffirmIf(status_id,(status and OFFERED_DEADLINE_MISSED_STATUS) /= OFFERED_DEADLINE_MISSED_STATUS, "Expected: 0", "Received 1");
cc.serialized_key := FALSE;
cc.kind := ALIVE;
cc.instance := kh1;
cc.payload := gen_payload(kh1,10);
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;
cc1 := cc;
-- Stored CC: I1S1, 0, 0, 0
Log("Current Time: 2s", INFO);
check_time <= gen_duration(2,0);
wait until rising_edge(clk);
wait until rising_edge(clk);
wait_on_idle;
AffirmIf(status_id,(status and OFFERED_DEADLINE_MISSED_STATUS) /= OFFERED_DEADLINE_MISSED_STATUS, "Expected: 0", "Received 1");
Log("Current Time: 3s", INFO);
check_time <= gen_duration(3,0);
wait until rising_edge(clk);
wait until rising_edge(clk);
wait_on_idle;
AffirmIf(status_id,(status and OFFERED_DEADLINE_MISSED_STATUS) = OFFERED_DEADLINE_MISSED_STATUS, "Expected: 1", "Received 0");
Log("Current Time: 4s", INFO);
check_time <= gen_duration(4,0);
wait until rising_edge(clk);
wait until rising_edge(clk);
wait_on_idle;
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;
deadline_ref := DEFAULT_DEADLINE_TEST;
deadline_ref.count := 3;
deadline_ref.change := 2;
start_stim;
wait_on_stim;
wait_on_idle;
AffirmIf(status_id,(status and OFFERED_DEADLINE_MISSED_STATUS) /= OFFERED_DEADLINE_MISSED_STATUS, "Expected: 0", "Received 1");
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;
stim_prc : process(all)
begin
if rising_edge(clk) then
stim_done <= '0';
case (stim_stage) is
when IDLE =>
if (stim_start = '1') then
stim_stage <= START;
else
stim_done <= '1';
end if;
when START =>
if (ack_dds = '1') then
case (stimulus.opcode) is
when GET_OFFERED_DEADLINE_MISSED_STATUS =>
stim_stage <= DONE;
stim_cnt <= 0;
when others =>
stim_stage <= PUSH;
stim_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
-- DEFAULT
stim_stage <= DONE;
case (stimulus.opcode) is
when REGISTER_INSTANCE =>
stim_stage <= CHECK;
stim_cnt <= 0;
when LOOKUP_INSTANCE =>
stim_stage <= CHECK;
stim_cnt <= 0;
when others =>
null;
end case;
end if;
end if;
when DONE =>
if (done_dds = '1') then
AffirmIfEqual(ret_id, return_code_dds, stimulus.ret_code);
case (stimulus.opcode) is
when GET_OFFERED_DEADLINE_MISSED_STATUS =>
if (stimulus.ret_code = RETCODE_OK) then
stim_stage <= CHECK_DEADLINE;
stim_cnt <= 0;
else
stim_stage <= IDLE;
end if;
when others =>
stim_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
AlertIf(data_id, last_word_out_dds /= '1', "Last Word Signal not pulled High", ERROR);
stim_stage <= IDLE;
end if;
end if;
when CHECK_DEADLINE =>
if (valid_out_dds = '1') then
stim_cnt <= stim_cnt + 1;
case (stim_cnt) is
when 0 =>
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(to_unsigned(deadline_ref.count,CDR_LONG_WIDTH)));
when 1 =>
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(to_unsigned(deadline_ref.change,CDR_LONG_WIDTH)));
when 2 =>
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(deadline_ref.instance(0)));
when 3 =>
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(deadline_ref.instance(1)));
when 4 =>
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(deadline_ref.instance(2)));
when 5 =>
AffirmIfEqual(data_id, data_out_dds, std_logic_vector(deadline_ref.instance(3)));
AlertIf(data_id, last_word_out_dds /= '1', "Last Word Signal not pulled High", ERROR);
stim_stage <= IDLE;
when others =>
null;
end case;
end if;
end case;
end if;
-- DEFAULT
start_dds <= '0';
valid_in_dds <= '0';
last_word_in_dds <= '0';
data_in_dds <= (others => '0');
instance_handle_dds <= HANDLE_NIL;
source_ts_dds <= TIME_INVALID;
ready_out_dds <= '0';
case (stim_stage) is
when START =>
start_dds <= '1';
opcode_dds <= stimulus.opcode;
instance_handle_dds <= stimulus.cc.instance;
source_ts_dds <= stimulus.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);
when CHECK =>
ready_out_dds <= '1';
when CHECK_DEADLINE =>
ready_out_dds <= '1';
when others =>
null;
end case;
end process;
ref_prc : process(all)
begin
if rising_edge(clk) then
ref_done <= '0';
case (ref_stage) is
when IDLE =>
if (ref_start = '1') then
ref_stage <= START;
else
ref_done <= '1';
end if;
when START =>
if (ack_rtps = '1') then
ref_stage <= DONE;
end if;
when DONE =>
if (done_rtps = '1') then
-- DEFAULT
ref_stage <= IDLE;
AffirmIfEqual(ret_id, HISTORY_CACHE_RESPONSE_TYPE'pos(ret_rtps), HISTORY_CACHE_RESPONSE_TYPE'pos(reference.ret_code));
case (reference.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;
end if;
when GET_MIN_SN =>
AffirmIfEqual(sn_id, convert_from_double_word(cc_seq_nr), convert_from_double_word(reference.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));
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;
end if;
end if;
end case;
end if;
-- DEFAULT
start_rtps <= '0';
get_data_rtps <= '0';
ready_out_rtps <= '0';
case (ref_stage) is
when START =>
start_rtps <= '1';
opcode_rtps <= reference.opcode;
seq_nr_rtps <= reference.cc.seq_nr;
when DONE =>
if (done_rtps = '1') then
case (reference.opcode) is
when GET_CACHE_CHANGE =>
get_data_rtps <= '1';
when others =>
null;
end case;
end if;
when CHECK =>
ready_out_rtps <= '1';
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;

View File

@ -59,6 +59,8 @@ analyze Level_0/L0_dds_writer_test1_ain.vhd
analyze Level_0/L0_dds_writer_test1_lik.vhd
analyze Level_0/L0_dds_writer_test1_afk.vhd
analyze Level_0/L0_dds_writer_test2_aik.vhd
analyze Level_0/L0_dds_writer_test3_aik.vhd
analyze Level_0/L0_dds_writer_test3_ain.vhd
#simulate L0_rtps_handler_test1
#simulate L0_rtps_handler_test2
@ -99,4 +101,6 @@ analyze Level_0/L0_dds_writer_test2_aik.vhd
#simulate L0_dds_writer_test1_ain
#simulate L0_dds_writer_test1_lik
#simulate L0_dds_writer_test1_afk
simulate L0_dds_writer_test2_aik
#simulate L0_dds_writer_test2_aik
simulate L0_dds_writer_test3_aik
#simulate L0_dds_writer_test3_ain

View File

@ -366,6 +366,8 @@ architecture arch of dds_writer is
signal data_available_sig, data_available_sig_next : std_logic := '0';
-- Denotes if Orphan Samples (of an removed stale instance) need to be removed
signal orphan_samples, orphan_samples_next : std_logic := '0';
-- Test signal used for testbench synchronisation
signal idle_sig : std_logic := '0';
-- *COMMUNICATION STATUS*
@ -661,6 +663,7 @@ begin
valid_out_kh <= '0';
last_word_out_kh <= '0';
abort_kh <= '0';
idle_sig <= '0';
data_out_kh <= (others => '0');
inst_addr_update <= (others => '0');
sample_addr <= (others => '0');
@ -673,6 +676,7 @@ begin
case (stage) is
when IDLE =>
idle_sig <= '1';
-- Reset
remove_oldest_sample_next <= '0';
remove_oldest_inst_sample_next <= '0';
@ -702,7 +706,7 @@ begin
inst_data_next2.status_info(ISI_LIVELINESS_FLAG) <= '0';
else
-- Update Requested Deadline Missed Status
status_sig_next <= status_sig and REQUESTED_DEADLINE_MISSED_STATUS;
status_sig_next <= status_sig or OFFERED_DEADLINE_MISSED_STATUS;
deadline_miss_cnt_next <= deadline_miss_cnt + 1;
deadline_miss_cnt_change_next <= deadline_miss_cnt_change + 1;
end if;
@ -3281,8 +3285,13 @@ begin
end case;
when GET_LIVELINESS_LOST_STATUS =>
case (cnt) is
-- Return Code
when 0 =>
done_dds <= '1';
return_code_dds <= RETCODE_OK;
cnt_next <= cnt + 1;
-- Total Count
when 0 =>
when 1 =>
data_out_dds <= std_logic_vector(liveliness_lost_cnt);
valid_out_dds <= '1';
@ -3290,23 +3299,14 @@ begin
cnt_next <= cnt + 1;
end if;
-- Total Count Change
when 1 =>
data_out_dds <= std_logic_vector(liveliness_lost_cnt_change);
valid_out_dds <= '1';
when 2 =>
data_out_dds <= std_logic_vector(liveliness_lost_cnt_change);
valid_out_dds <= '1';
last_word_out_dds <= '1';
if (ready_out_dds = '1') then
-- Reset
liveliness_lost_cnt_change_next <= (others => '0');
cnt_next <= cnt + 1;
end if;
-- Return Code
when 2 =>
done_dds <= '1';
return_code_dds <= RETCODE_OK;
if (ready_out_dds = '1') then
-- Reset
status_sig_next <= status_sig and (not LIVELINESS_LOST_STATUS);
-- DONE
@ -3317,8 +3317,13 @@ begin
end case;
when GET_OFFERED_DEADLINE_MISSED_STATUS =>
case (cnt) is
-- Total Count
-- Return Code
when 0 =>
done_dds <= '1';
return_code_dds <= RETCODE_OK;
cnt_next <= cnt + 1;
-- Total Count
when 1 =>
data_out_dds <= std_logic_vector(deadline_miss_cnt);
valid_out_dds <= '1';
@ -3326,7 +3331,7 @@ begin
cnt_next <= cnt + 1;
end if;
-- Total Count Change
when 1 =>
when 2 =>
data_out_dds <= std_logic_vector(deadline_miss_cnt_change);
valid_out_dds <= '1';
@ -3337,38 +3342,31 @@ begin
cnt_next <= cnt + 1;
end if;
-- Last Instance Handle 1/4
when 2 =>
when 3 =>
data_out_dds <= deadline_miss_last_inst(0);
valid_out_dds <= '1';
if (ready_out_dds = '1') then
cnt_next <= cnt + 1;
end if;
-- Last Instance Handle 2/4
when 3 =>
when 4 =>
data_out_dds <= deadline_miss_last_inst(1);
valid_out_dds <= '1';
if (ready_out_dds = '1') then
cnt_next <= cnt + 1;
end if;
-- Last Instance Handle 3/4
when 4 =>
when 5 =>
data_out_dds <= deadline_miss_last_inst(2);
valid_out_dds <= '1';
if (ready_out_dds = '1') then
cnt_next <= cnt + 1;
end if;
-- Last Instance Handle 4/4
when 5 =>
when 6 =>
data_out_dds <= deadline_miss_last_inst(3);
valid_out_dds <= '1';
last_word_out_dds <= '1';
if (ready_out_dds = '1') then
cnt_next <= cnt + 1;
end if;
-- Return Code
when 6 =>
done_dds <= '1';
return_code_dds <= RETCODE_OK;
if (ready_out_dds = '1') then
-- Reset
status_sig_next <= status_sig and (not OFFERED_DEADLINE_MISSED_STATUS);
@ -3415,7 +3413,7 @@ begin
cnt_next <= 1;
else
-- Update Requested Deadline Missed Status
status_sig_next <= status_sig and OFFERED_DEADLINE_MISSED_STATUS;
status_sig_next <= status_sig or OFFERED_DEADLINE_MISSED_STATUS;
deadline_miss_cnt_next <= deadline_miss_cnt + 1;
deadline_miss_cnt_change_next <= deadline_miss_cnt_change + 1;
deadline_miss_last_inst_next <= inst_data.key_hash;
@ -4390,7 +4388,7 @@ begin
sample_rej_last_inst <= HANDLE_NIL;
deadline_miss_last_inst <= HANDLE_NIL;
key_hash <= HANDLE_NIL;
deadline_time <= TIME_INVALID;
deadline_time <= time + DEADLINE_QOS;
lifespan_time <= TIME_INVALID;
source_ts <= TIME_INVALID;
timeout_time <= TIME_INVALID;