Bug Fix: Key_Holder was not resetting the decode_error signal

Fixed Updated Template-, Type1-, and Type2-key_holder to reset the
decode_error signal when a new PUSH_* operation is initiated.
Testbenches are extended to test foe decode_error and its reset.
This commit is contained in:
John Ring 2023-06-17 00:25:35 +02:00
parent 3f2e4e82d1
commit d2d40c1326
7 changed files with 316 additions and 94 deletions

View File

@ -150,12 +150,14 @@ begin
ack <= '1'; ack <= '1';
stage_next <= GET_PAYLOAD_HEADER; stage_next <= GET_PAYLOAD_HEADER;
-- Reset -- Reset
key_hash_next <= KEY_HASH_NIL; key_hash_next <= KEY_HASH_NIL;
decode_error_latch_next <= '0';
when PUSH_SERIALIZED_KEY => when PUSH_SERIALIZED_KEY =>
ack <= '1'; ack <= '1';
stage_next <= GET_PAYLOAD_HEADER; stage_next <= GET_PAYLOAD_HEADER;
-- Reset -- Reset
key_hash_next <= KEY_HASH_NIL; key_hash_next <= KEY_HASH_NIL;
decode_error_latch_next <= '0';
when READ_KEY_HASH => when READ_KEY_HASH =>
ack <= '1'; ack <= '1';
-- Key Hash not calculated -- Key Hash not calculated

View File

@ -9,11 +9,12 @@ use work.rtps_package.all;
use work.user_config.all; use work.user_config.all;
use work.rtps_config_package.all; use work.rtps_config_package.all;
use work.rtps_test_package.all; use work.rtps_test_package.all;
use work.Type2_package.all; use work.Type1_package.all;
-- This testbench tests the KEY_HOLDER commands of TYPE1. -- This testbench tests the KEY_HOLDER commands of TYPE1.
-- It uses the writer_interface to send a valid payload, then reads the serialized key and the key hash. The returned serialized key is compared to a "handcrafted" reference, and the key hash is latched for later comparison. -- Firstly an invalid serialized payload is sent to test the decode error.
-- Then the reference serialized key is pushed (resetting the internally generated key hash), and the serialized key and key hash are re-read and compared (The key hash is compared to the previously compared). -- Secondly the writer_interface is used to send a valid payload, then reads the serialized key and the key hash. The returned serialized key is compared to a "handcrafted" reference, and the key hash is latched for later comparison.
-- Thirty the reference serialized key is pushed (resetting the internally generated key hash), and the serialized key and key hash are re-read and compared (The key hash is compared to the previously compared).
-- The payload is sent in Big Endian. -- The payload is sent in Big Endian.
entity L1_Type1_key_holder_test1 is entity L1_Type1_key_holder_test1 is
@ -22,13 +23,14 @@ end entity;
architecture testbench of L1_Type1_key_holder_test1 is architecture testbench of L1_Type1_key_holder_test1 is
signal clk, reset : std_logic := '0'; signal clk, reset : std_logic := '0';
signal ready_sk, ready_w, ready_kh_in, ready_kh_out, valid_sk, valid_w, valid_kh_in, valid_kh_out, last_word_sk, last_word_w, last_word_kh_in, last_word_kh_out : std_logic := '0'; signal ready_de, ready_sk, ready_w, ready_kh_in, ready_kh_out, valid_de, valid_sk, valid_w, valid_kh_in, valid_kh_out, last_word_de, last_word_sk, last_word_w, last_word_kh_in, last_word_kh_out : std_logic := '0';
signal data_sk, data_w, data_kh_in, data_kh_out : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0'); signal data_de, data_sk, data_w, data_kh_in, data_kh_out : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0');
signal start_w, ack_w, start_kh, ack_kh, decode_error, encode_done : std_logic := '0'; signal start_w, ack_w, start_kh, ack_kh, decode_error, encode_done : std_logic := '0';
signal opcode_kh : KEY_HOLDER_OPCODE_TYPE := NOP; signal opcode_kh : KEY_HOLDER_OPCODE_TYPE := NOP;
shared variable SB_out : osvvm.ScoreBoardPkg_slv.ScoreBoardPType; shared variable SB_out : osvvm.ScoreBoardPkg_slv.ScoreBoardPType;
shared variable serialized_key : TEST_PACKET_TYPE := EMPTY_TEST_PACKET; shared variable serialized_key, invalid_data : TEST_PACKET_TYPE := EMPTY_TEST_PACKET;
signal key_hash, key_hash_latch : KEY_HASH_TYPE := KEY_HASH_NIL; signal key_hash, key_hash_latch : KEY_HASH_TYPE := KEY_HASH_NIL;
signal send_invalid_data : std_logic := '0';
signal id_in : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); signal id_in : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0');
signal a_in : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); signal a_in : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0');
@ -125,14 +127,23 @@ begin
KH := GetAlertLogID("KeyHash", ALERTLOG_BASE_ID); KH := GetAlertLogID("KeyHash", ALERTLOG_BASE_ID);
Log("Initial Reset", INFO); Log("Initial Reset", INFO);
start_w <= '0'; send_invalid_data <= '0';
reset <= '1'; start_w <= '0';
reset <= '1';
wait until rising_edge(clk); wait until rising_edge(clk);
wait until rising_edge(clk); wait until rising_edge(clk);
reset <= '0'; reset <= '0';
-- Create Invalid Serialized Payload
for i in 0 to MAX_TYPE1_SIZE loop
invalid_data.data(i) := RV.RandSlv(invalid_data.data(i)'length);
invalid_data.length := invalid_data.length + 1;
end loop;
invalid_data.last(invalid_data.length-1) := '1';
-- Serialized Key Payload Header -- Serialized Key Payload Header
gen_CDR(SERIALIZED_KEY_HEADER, ALIGN_4, align_offset, serialized_key); write_serialized_payload(SERIALIZED_KEY_HEADER, ALIGN_4, align_offset, serialized_key);
-- Reset Alignment -- Reset Alignment
align_offset := (others => '0'); align_offset := (others => '0');
@ -141,7 +152,7 @@ begin
id_in <= RV.RandSlv(id_in'length); id_in <= RV.RandSlv(id_in'length);
a_in <= RV.RandSlv(a_in'length); a_in <= RV.RandSlv(a_in'length);
wait for 0 ns; wait for 0 ns;
gen_CDR(id_in, ALIGN_4, align_offset, serialized_key); write_serialized_payload(id_in, ALIGN_4, align_offset, serialized_key);
-- Finalize Serialized Key -- Finalize Serialized Key
if (align_offset(1 downto 0) /= "00") then if (align_offset(1 downto 0) /= "00") then
@ -150,6 +161,24 @@ begin
push_sk; push_sk;
Log("Push Invalid DATA", INFO);
send_invalid_data <= '1';
opcode_kh <= PUSH_DATA;
start_w <= '1';
wait_on_sig(ack_w);
wait until rising_edge(clk);
start_w <= '0';
start_kh <= '1';
wait_on_sig(ack_kh);
wait until rising_edge(clk);
start_kh <= '0';
wait_on_sig(last_word_kh_in);
wait_on_sig(ready_kh_in);
wait until rising_edge(clk);
Alertif(decode_error /= '1', "Decode error not asserted", ERROR);
send_invalid_data <= '0';
Log("Push DATA", INFO); Log("Push DATA", INFO);
opcode_kh <= PUSH_DATA; opcode_kh <= PUSH_DATA;
start_w <= '1'; start_w <= '1';
@ -160,9 +189,12 @@ begin
wait_on_sig(ack_kh); wait_on_sig(ack_kh);
wait until rising_edge(clk); wait until rising_edge(clk);
start_kh <= '0'; start_kh <= '0';
wait for 1 ps; -- Wait until signals are stable
Alertif(decode_error /= '0', "Decode error still asserted", ERROR);
wait_on_sig(last_word_kh_in); wait_on_sig(last_word_kh_in);
wait_on_sig(ready_kh_in); wait_on_sig(ready_kh_in);
wait until rising_edge(clk); wait until rising_edge(clk);
Alertif(decode_error = '1', "Decode error asserted", ERROR);
Log("Read and Compare Serialized Key", INFO); Log("Read and Compare Serialized Key", INFO);
opcode_kh <= READ_SERIALIZED_KEY; opcode_kh <= READ_SERIALIZED_KEY;
@ -193,6 +225,7 @@ begin
wait_on_sig(last_word_sk); wait_on_sig(last_word_sk);
wait_on_sig(ready_sk); wait_on_sig(ready_sk);
wait until rising_edge(clk); wait until rising_edge(clk);
Alertif(decode_error = '1', "Decode error asserted", ERROR);
push_sk; push_sk;
Log("Read and Compare Serialized Key", INFO); Log("Read and Compare Serialized Key", INFO);
@ -234,28 +267,29 @@ begin
wait for TEST_CLOCK_PERIOD/2; wait for TEST_CLOCK_PERIOD/2;
end process; end process;
alert_prc : process(all)
begin
if rising_edge(clk) then
Alertif(decode_error = '1', "The Reader signals a DECODE Error", ERROR);
end if;
end process;
switch_prc : process(all) switch_prc : process(all)
begin begin
ready_w <= '0';
ready_de <= '0';
ready_sk <= '0';
case (opcode_kh) is case (opcode_kh) is
when PUSH_SERIALIZED_KEY => when PUSH_SERIALIZED_KEY =>
ready_sk <= ready_kh_in; ready_sk <= ready_kh_in;
valid_kh_in <= valid_sk; valid_kh_in <= valid_sk;
data_kh_in <= data_sk; data_kh_in <= data_sk;
last_word_kh_in <= last_word_sk; last_word_kh_in <= last_word_sk;
ready_w <= '0';
when others => when others =>
ready_w <= ready_kh_in; if (send_invalid_data = '1') then
valid_kh_in <= valid_w; ready_de <= ready_kh_in;
data_kh_in <= data_w; valid_kh_in <= valid_de;
last_word_kh_in <= last_word_w; data_kh_in <= data_de;
ready_sk <= '0'; last_word_kh_in <= last_word_de;
else
ready_w <= ready_kh_in;
valid_kh_in <= valid_w;
data_kh_in <= data_w;
last_word_kh_in <= last_word_w;
end if;
end case; end case;
end process; end process;
@ -279,6 +313,26 @@ begin
end if; end if;
end process; end process;
de_prc : process(all)
variable cnt : natural := 0;
begin
valid_de <= '1';
data_de <= invalid_data.data(cnt);
if (cnt = invalid_data.length-1) then
last_word_de <= '1';
end if;
if rising_edge(clk) then
if (ready_de = '1') then
if (cnt = invalid_data.length-1) then
cnt := 0;
else
cnt := cnt + 1;
end if;
end if;
end if;
end process;
output_check_prc : process(all) output_check_prc : process(all)
variable cnt : natural range 0 to 3 := 0; variable cnt : natural range 0 to 3 := 0;
begin begin

View File

@ -9,11 +9,12 @@ use work.rtps_package.all;
use work.user_config.all; use work.user_config.all;
use work.rtps_config_package.all; use work.rtps_config_package.all;
use work.rtps_test_package.all; use work.rtps_test_package.all;
use work.Type2_package.all; use work.Type1_package.all;
-- This testbench tests the KEY_HOLDER commands of TYPE1. -- This testbench tests the KEY_HOLDER commands of TYPE1.
-- It uses the writer_interface to send a valid payload, then reads the serialized key and the key hash. The returned serialized key is compared to a "handcrafted" reference, and the key hash is latched for later comparison. -- Firstly an invalid serialized payload is sent to test the decode error.
-- Then the reference serialized key is pushed (resetting the internally generated key hash), and the serialized key and key hash are re-read and compared (The key hash is compared to the previously compared). -- Secondly the writer_interface is used to send a valid payload, then reads the serialized key and the key hash. The returned serialized key is compared to a "handcrafted" reference, and the key hash is latched for later comparison.
-- Thirty the reference serialized key is pushed (resetting the internally generated key hash), and the serialized key and key hash are re-read and compared (The key hash is compared to the previously compared).
-- The payload is sent in Little Endian. -- The payload is sent in Little Endian.
entity L1_Type1_key_holder_test2 is entity L1_Type1_key_holder_test2 is
@ -22,13 +23,14 @@ end entity;
architecture testbench of L1_Type1_key_holder_test2 is architecture testbench of L1_Type1_key_holder_test2 is
signal clk, reset : std_logic := '0'; signal clk, reset : std_logic := '0';
signal ready_sk, ready_w, ready_kh_in, ready_kh_out, valid_sk, valid_w, valid_kh_in, valid_kh_out, last_word_sk, last_word_w, last_word_kh_in, last_word_kh_out : std_logic := '0'; signal ready_de, ready_sk, ready_w, ready_kh_in, ready_kh_out, valid_de, valid_sk, valid_w, valid_kh_in, valid_kh_out, last_word_de, last_word_sk, last_word_w, last_word_kh_in, last_word_kh_out : std_logic := '0';
signal data_sk, data_w, data_kh_in, data_kh_out : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0'); signal data_de, data_sk, data_w, data_kh_in, data_kh_out : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0');
signal start_w, ack_w, start_kh, ack_kh, decode_error, encode_done : std_logic := '0'; signal start_w, ack_w, start_kh, ack_kh, decode_error, encode_done : std_logic := '0';
signal opcode_kh : KEY_HOLDER_OPCODE_TYPE := NOP; signal opcode_kh : KEY_HOLDER_OPCODE_TYPE := NOP;
shared variable SB_out : osvvm.ScoreBoardPkg_slv.ScoreBoardPType; shared variable SB_out : osvvm.ScoreBoardPkg_slv.ScoreBoardPType;
shared variable serialized_key : TEST_PACKET_TYPE := EMPTY_TEST_PACKET; shared variable serialized_key, invalid_data : TEST_PACKET_TYPE := EMPTY_TEST_PACKET;
signal key_hash, key_hash_latch : KEY_HASH_TYPE := KEY_HASH_NIL; signal key_hash, key_hash_latch : KEY_HASH_TYPE := KEY_HASH_NIL;
signal send_invalid_data : std_logic := '0';
signal id_in : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); signal id_in : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0');
signal a_in : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); signal a_in : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0');
@ -131,14 +133,23 @@ begin
KH := GetAlertLogID("KeyHash", ALERTLOG_BASE_ID); KH := GetAlertLogID("KeyHash", ALERTLOG_BASE_ID);
Log("Initial Reset", INFO); Log("Initial Reset", INFO);
start_w <= '0'; send_invalid_data <= '0';
reset <= '1'; start_w <= '0';
reset <= '1';
wait until rising_edge(clk); wait until rising_edge(clk);
wait until rising_edge(clk); wait until rising_edge(clk);
reset <= '0'; reset <= '0';
-- Create Invalid Serialized Payload
for i in 0 to MAX_TYPE1_SIZE loop
invalid_data.data(i) := RV.RandSlv(invalid_data.data(i)'length);
invalid_data.length := invalid_data.length + 1;
end loop;
invalid_data.last(invalid_data.length-1) := '1';
-- Serialized Key Payload Header -- Serialized Key Payload Header
gen_CDR(SERIALIZED_KEY_HEADER, ALIGN_4, align_offset, serialized_key); write_serialized_payload(SERIALIZED_KEY_HEADER, ALIGN_4, align_offset, serialized_key);
-- Reset Alignment -- Reset Alignment
align_offset := (others => '0'); align_offset := (others => '0');
@ -147,7 +158,7 @@ begin
id_in <= RV.RandSlv(id_in'length); id_in <= RV.RandSlv(id_in'length);
a_in <= RV.RandSlv(a_in'length); a_in <= RV.RandSlv(a_in'length);
wait for 0 ns; wait for 0 ns;
gen_CDR(endian_swap('1',id_in), ALIGN_4, align_offset, serialized_key); write_serialized_payload(endian_swap('1',id_in), ALIGN_4, align_offset, serialized_key);
-- Finalize Serialized Key -- Finalize Serialized Key
if (align_offset(1 downto 0) /= "00") then if (align_offset(1 downto 0) /= "00") then
@ -156,6 +167,24 @@ begin
push_sk; push_sk;
Log("Push Invalid DATA", INFO);
send_invalid_data <= '1';
opcode_kh <= PUSH_DATA;
start_w <= '1';
wait_on_sig(ack_w);
wait until rising_edge(clk);
start_w <= '0';
start_kh <= '1';
wait_on_sig(ack_kh);
wait until rising_edge(clk);
start_kh <= '0';
wait_on_sig(last_word_kh_in);
wait_on_sig(ready_kh_in);
wait until rising_edge(clk);
Alertif(decode_error /= '1', "Decode error not asserted", ERROR);
send_invalid_data <= '0';
Log("Push DATA", INFO); Log("Push DATA", INFO);
opcode_kh <= PUSH_DATA; opcode_kh <= PUSH_DATA;
start_w <= '1'; start_w <= '1';
@ -166,9 +195,12 @@ begin
wait_on_sig(ack_kh); wait_on_sig(ack_kh);
wait until rising_edge(clk); wait until rising_edge(clk);
start_kh <= '0'; start_kh <= '0';
wait for 1 ps; -- Wait until signals are stable
Alertif(decode_error /= '0', "Decode error still asserted", ERROR);
wait_on_sig(last_word_kh_in); wait_on_sig(last_word_kh_in);
wait_on_sig(ready_kh_in); wait_on_sig(ready_kh_in);
wait until rising_edge(clk); wait until rising_edge(clk);
Alertif(decode_error = '1', "Decode error asserted", ERROR);
Log("Read and Compare Serialized Key", INFO); Log("Read and Compare Serialized Key", INFO);
opcode_kh <= READ_SERIALIZED_KEY; opcode_kh <= READ_SERIALIZED_KEY;
@ -199,6 +231,7 @@ begin
wait_on_sig(last_word_sk); wait_on_sig(last_word_sk);
wait_on_sig(ready_sk); wait_on_sig(ready_sk);
wait until rising_edge(clk); wait until rising_edge(clk);
Alertif(decode_error = '1', "Decode error asserted", ERROR);
push_sk; push_sk;
Log("Read and Compare Serialized Key", INFO); Log("Read and Compare Serialized Key", INFO);
@ -240,28 +273,29 @@ begin
wait for TEST_CLOCK_PERIOD/2; wait for TEST_CLOCK_PERIOD/2;
end process; end process;
alert_prc : process(all)
begin
if rising_edge(clk) then
Alertif(decode_error = '1', "The Reader signals a DECODE Error", ERROR);
end if;
end process;
switch_prc : process(all) switch_prc : process(all)
begin begin
ready_w <= '0';
ready_de <= '0';
ready_sk <= '0';
case (opcode_kh) is case (opcode_kh) is
when PUSH_SERIALIZED_KEY => when PUSH_SERIALIZED_KEY =>
ready_sk <= ready_kh_in; ready_sk <= ready_kh_in;
valid_kh_in <= valid_sk; valid_kh_in <= valid_sk;
data_kh_in <= data_sk; data_kh_in <= data_sk;
last_word_kh_in <= last_word_sk; last_word_kh_in <= last_word_sk;
ready_w <= '0';
when others => when others =>
if (send_invalid_data = '1') then
ready_de <= ready_kh_in;
valid_kh_in <= valid_de;
data_kh_in <= data_de;
last_word_kh_in <= last_word_de;
else
ready_w <= ready_kh_in; ready_w <= ready_kh_in;
valid_kh_in <= valid_w; valid_kh_in <= valid_w;
data_kh_in <= data_w; data_kh_in <= data_w;
last_word_kh_in <= last_word_w; last_word_kh_in <= last_word_w;
ready_sk <= '0'; end if;
end case; end case;
end process; end process;
@ -285,6 +319,26 @@ begin
end if; end if;
end process; end process;
de_prc : process(all)
variable cnt : natural := 0;
begin
valid_de <= '1';
data_de <= invalid_data.data(cnt);
if (cnt = invalid_data.length-1) then
last_word_de <= '1';
end if;
if rising_edge(clk) then
if (ready_de = '1') then
if (cnt = invalid_data.length-1) then
cnt := 0;
else
cnt := cnt + 1;
end if;
end if;
end if;
end process;
output_check_prc : process(all) output_check_prc : process(all)
variable cnt : natural range 0 to 3 := 0; variable cnt : natural range 0 to 3 := 0;
begin begin

View File

@ -12,8 +12,9 @@ use work.rtps_test_package.all;
use work.Type2_package.all; use work.Type2_package.all;
-- This testbench tests the KEY_HOLDER commands of TYPE2. -- This testbench tests the KEY_HOLDER commands of TYPE2.
-- It uses the writer_interface to send a valid payload, then reads the serialized key and the key hash. The returned serialized key is compared to a "handcrafted" reference, and the key hash is latched for later comparison. -- Firstly an invalid serialized payload is sent to test the decode error.
-- Then the reference serialized key is pushed (resetting the internally generated key hash), and the serialized key and key hash are re-read and compared (The key hash is compared to the previously compared). -- Secondly the writer_interface is used to send a valid payload, then reads the serialized key and the key hash. The returned serialized key is compared to a "handcrafted" reference, and the key hash is latched for later comparison.
-- Thirty the reference serialized key is pushed (resetting the internally generated key hash), and the serialized key and key hash are re-read and compared (The key hash is compared to the previously compared).
-- The payload is sent in Big Endian. -- The payload is sent in Big Endian.
entity L1_Type2_key_holder_test1 is entity L1_Type2_key_holder_test1 is
@ -22,13 +23,14 @@ end entity;
architecture testbench of L1_Type2_key_holder_test1 is architecture testbench of L1_Type2_key_holder_test1 is
signal clk, reset : std_logic := '0'; signal clk, reset : std_logic := '0';
signal ready_sk, ready_w, ready_kh_in, ready_kh_out, valid_sk, valid_w, valid_kh_in, valid_kh_out, last_word_sk, last_word_w, last_word_kh_in, last_word_kh_out : std_logic := '0'; signal ready_de, ready_sk, ready_w, ready_kh_in, ready_kh_out, valid_de, valid_sk, valid_w, valid_kh_in, valid_kh_out, last_word_de, last_word_sk, last_word_w, last_word_kh_in, last_word_kh_out : std_logic := '0';
signal data_sk, data_w, data_kh_in, data_kh_out : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0'); signal data_de, data_sk, data_w, data_kh_in, data_kh_out : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0');
signal start_w, ack_w, start_kh, ack_kh, decode_error, encode_done : std_logic := '0'; signal start_w, ack_w, start_kh, ack_kh, decode_error, encode_done : std_logic := '0';
signal opcode_kh : KEY_HOLDER_OPCODE_TYPE := NOP; signal opcode_kh : KEY_HOLDER_OPCODE_TYPE := NOP;
shared variable SB_out : osvvm.ScoreBoardPkg_slv.ScoreBoardPType; shared variable SB_out : osvvm.ScoreBoardPkg_slv.ScoreBoardPType;
shared variable serialized_key : TEST_PACKET_TYPE := EMPTY_TEST_PACKET; shared variable serialized_key, invalid_data : TEST_PACKET_TYPE := EMPTY_TEST_PACKET;
signal key_hash, key_hash_latch : KEY_HASH_TYPE := KEY_HASH_NIL; signal key_hash, key_hash_latch : KEY_HASH_TYPE := KEY_HASH_NIL;
signal send_invalid_data : std_logic := '0';
signal id_in : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); signal id_in : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0');
signal TestSequence_len_in, TestSequence_addr_in: std_logic_vector(TESTSEQUENCE_ADDR_WIDTH-1 downto 0) := (others => '0'); signal TestSequence_len_in, TestSequence_addr_in: std_logic_vector(TESTSEQUENCE_ADDR_WIDTH-1 downto 0) := (others => '0');
@ -197,14 +199,23 @@ begin
KH := GetAlertLogID("KeyHash", ALERTLOG_BASE_ID); KH := GetAlertLogID("KeyHash", ALERTLOG_BASE_ID);
Log("Initial Reset", INFO); Log("Initial Reset", INFO);
start_w <= '0'; send_invalid_data <= '0';
reset <= '1'; start_w <= '0';
reset <= '1';
wait until rising_edge(clk); wait until rising_edge(clk);
wait until rising_edge(clk); wait until rising_edge(clk);
reset <= '0'; reset <= '0';
-- Create Invalid Serialized Payload
for i in 0 to MAX_TYPE2_SIZE loop
invalid_data.data(i) := RV.RandSlv(invalid_data.data(i)'length);
invalid_data.length := invalid_data.length + 1;
end loop;
invalid_data.last(invalid_data.length-1) := '1';
-- Serialized Key Payload Header -- Serialized Key Payload Header
gen_CDR(SERIALIZED_KEY_HEADER, ALIGN_4, align_offset, serialized_key); write_serialized_payload(SERIALIZED_KEY_HEADER, ALIGN_4, align_offset, serialized_key);
-- Reset Alignment -- Reset Alignment
align_offset := (others => '0'); align_offset := (others => '0');
@ -218,10 +229,10 @@ begin
TestUnion_OctetU_in <= RV.RandSlv(TestUnion_OctetU_in'length); TestUnion_OctetU_in <= RV.RandSlv(TestUnion_OctetU_in'length);
TestBitmask_in <= RV.RandSlv(TestBitmask_in'length); TestBitmask_in <= RV.RandSlv(TestBitmask_in'length);
wait for 0 ns; wait for 0 ns;
gen_CDR(id_in, ALIGN_4, align_offset, serialized_key); write_serialized_payload(id_in, ALIGN_4, align_offset, serialized_key);
TestSequence_len_in <= int(2,TestSequence_len_in'length); TestSequence_len_in <= int(2,TestSequence_len_in'length);
gen_CDR(int(2,CDR_LONG_WIDTH), ALIGN_4, align_offset, serialized_key); write_serialized_payload(int(2,CDR_LONG_WIDTH), ALIGN_4, align_offset, serialized_key);
-- Memory -- Memory
for i in 0 to 1 loop for i in 0 to 1 loop
TestSequence_addr_in <= int(i,TestSequence_addr_in'length); TestSequence_addr_in <= int(i,TestSequence_addr_in'length);
@ -237,7 +248,7 @@ begin
TestSequence_TestArray_wen_in <= '1'; TestSequence_TestArray_wen_in <= '1';
wait until rising_edge(clk); wait until rising_edge(clk);
TestSequence_TestArray_wen_in <= '0'; TestSequence_TestArray_wen_in <= '0';
gen_CDR(TestSequence_TestArray_w_in, ALIGN_1, align_offset, serialized_key); write_serialized_payload(TestSequence_TestArray_w_in, ALIGN_1, align_offset, serialized_key);
end loop; end loop;
wait_on_sig(TestSequence_ready_in); wait_on_sig(TestSequence_ready_in);
TestSequence_wen_in <= '1'; TestSequence_wen_in <= '1';
@ -273,9 +284,10 @@ begin
push_sk; push_sk;
Log("Push DATA", INFO); Log("Push Invalid DATA", INFO);
opcode_kh <= PUSH_DATA; send_invalid_data <= '1';
start_w <= '1'; opcode_kh <= PUSH_DATA;
start_w <= '1';
wait_on_sig(ack_w); wait_on_sig(ack_w);
wait until rising_edge(clk); wait until rising_edge(clk);
start_w <= '0'; start_w <= '0';
@ -287,6 +299,26 @@ begin
wait_on_sig(ready_kh_in); wait_on_sig(ready_kh_in);
wait until rising_edge(clk); wait until rising_edge(clk);
Alertif(decode_error /= '1', "Decode error not asserted", ERROR);
send_invalid_data <= '0';
Log("Push DATA", INFO);
opcode_kh <= PUSH_DATA;
start_w <= '1';
wait_on_sig(ack_w);
wait until rising_edge(clk);
start_w <= '0';
start_kh <= '1';
wait_on_sig(ack_kh);
wait until rising_edge(clk);
start_kh <= '0';
wait for 1 ps; -- Wait until signals are stable
Alertif(decode_error /= '0', "Decode error still asserted", ERROR);
wait_on_sig(last_word_kh_in);
wait_on_sig(ready_kh_in);
wait until rising_edge(clk);
Alertif(decode_error = '1', "Decode error asserted", ERROR);
Log("Read and Compare Serialized Key", INFO); Log("Read and Compare Serialized Key", INFO);
opcode_kh <= READ_SERIALIZED_KEY; opcode_kh <= READ_SERIALIZED_KEY;
start_kh <= '1'; start_kh <= '1';
@ -316,6 +348,7 @@ begin
wait_on_sig(last_word_sk); wait_on_sig(last_word_sk);
wait_on_sig(ready_sk); wait_on_sig(ready_sk);
wait until rising_edge(clk); wait until rising_edge(clk);
Alertif(decode_error = '1', "Decode error asserted", ERROR);
push_sk; push_sk;
Log("Read and Compare Serialized Key", INFO); Log("Read and Compare Serialized Key", INFO);
@ -357,28 +390,29 @@ begin
wait for TEST_CLOCK_PERIOD/2; wait for TEST_CLOCK_PERIOD/2;
end process; end process;
alert_prc : process(all)
begin
if rising_edge(clk) then
Alertif(decode_error = '1', "The Reader signals a DECODE Error", ERROR);
end if;
end process;
switch_prc : process(all) switch_prc : process(all)
begin begin
ready_w <= '0';
ready_de <= '0';
ready_sk <= '0';
case (opcode_kh) is case (opcode_kh) is
when PUSH_SERIALIZED_KEY => when PUSH_SERIALIZED_KEY =>
ready_sk <= ready_kh_in; ready_sk <= ready_kh_in;
valid_kh_in <= valid_sk; valid_kh_in <= valid_sk;
data_kh_in <= data_sk; data_kh_in <= data_sk;
last_word_kh_in <= last_word_sk; last_word_kh_in <= last_word_sk;
ready_w <= '0';
when others => when others =>
if (send_invalid_data = '1') then
ready_de <= ready_kh_in;
valid_kh_in <= valid_de;
data_kh_in <= data_de;
last_word_kh_in <= last_word_de;
else
ready_w <= ready_kh_in; ready_w <= ready_kh_in;
valid_kh_in <= valid_w; valid_kh_in <= valid_w;
data_kh_in <= data_w; data_kh_in <= data_w;
last_word_kh_in <= last_word_w; last_word_kh_in <= last_word_w;
ready_sk <= '0'; end if;
end case; end case;
end process; end process;
@ -402,6 +436,26 @@ begin
end if; end if;
end process; end process;
de_prc : process(all)
variable cnt : natural := 0;
begin
valid_de <= '1';
data_de <= invalid_data.data(cnt);
if (cnt = invalid_data.length-1) then
last_word_de <= '1';
end if;
if rising_edge(clk) then
if (ready_de = '1') then
if (cnt = invalid_data.length-1) then
cnt := 0;
else
cnt := cnt + 1;
end if;
end if;
end if;
end process;
output_check_prc : process(all) output_check_prc : process(all)
variable cnt : natural range 0 to 3 := 0; variable cnt : natural range 0 to 3 := 0;
begin begin

View File

@ -12,8 +12,9 @@ use work.rtps_test_package.all;
use work.Type2_package.all; use work.Type2_package.all;
-- This testbench tests the KEY_HOLDER commands of TYPE2. -- This testbench tests the KEY_HOLDER commands of TYPE2.
-- It uses the writer_interface to send a valid payload, then reads the serialized key and the key hash. The returned serialized key is compared to a "handcrafted" reference, and the key hash is latched for later comparison. -- Firstly an invalid serialized payload is sent to test the decode error.
-- Then the reference serialized key is pushed (resetting the internally generated key hash), and the serialized key and key hash are re-read and compared (The key hash is compared to the previously compared). -- Secondly the writer_interface is used to send a valid payload, then reads the serialized key and the key hash. The returned serialized key is compared to a "handcrafted" reference, and the key hash is latched for later comparison.
-- Thirty the reference serialized key is pushed (resetting the internally generated key hash), and the serialized key and key hash are re-read and compared (The key hash is compared to the previously compared).
-- The payload is sent in Little Endian. -- The payload is sent in Little Endian.
entity L1_Type2_key_holder_test2 is entity L1_Type2_key_holder_test2 is
@ -22,13 +23,14 @@ end entity;
architecture testbench of L1_Type2_key_holder_test2 is architecture testbench of L1_Type2_key_holder_test2 is
signal clk, reset : std_logic := '0'; signal clk, reset : std_logic := '0';
signal ready_sk, ready_w, ready_kh_in, ready_kh_out, valid_sk, valid_w, valid_kh_in, valid_kh_out, last_word_sk, last_word_w, last_word_kh_in, last_word_kh_out : std_logic := '0'; signal ready_de, ready_sk, ready_w, ready_kh_in, ready_kh_out, valid_de, valid_sk, valid_w, valid_kh_in, valid_kh_out, last_word_de, last_word_sk, last_word_w, last_word_kh_in, last_word_kh_out : std_logic := '0';
signal data_sk, data_w, data_kh_in, data_kh_out : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0'); signal data_de, data_sk, data_w, data_kh_in, data_kh_out : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0');
signal start_w, ack_w, start_kh, ack_kh, decode_error, encode_done : std_logic := '0'; signal start_w, ack_w, start_kh, ack_kh, decode_error, encode_done : std_logic := '0';
signal opcode_kh : KEY_HOLDER_OPCODE_TYPE := NOP; signal opcode_kh : KEY_HOLDER_OPCODE_TYPE := NOP;
shared variable SB_out : osvvm.ScoreBoardPkg_slv.ScoreBoardPType; shared variable SB_out : osvvm.ScoreBoardPkg_slv.ScoreBoardPType;
shared variable serialized_key : TEST_PACKET_TYPE := EMPTY_TEST_PACKET; shared variable serialized_key, invalid_data : TEST_PACKET_TYPE := EMPTY_TEST_PACKET;
signal key_hash, key_hash_latch : KEY_HASH_TYPE := KEY_HASH_NIL; signal key_hash, key_hash_latch : KEY_HASH_TYPE := KEY_HASH_NIL;
signal send_invalid_data : std_logic := '0';
signal id_in : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); signal id_in : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0');
signal TestSequence_len_in, TestSequence_addr_in: std_logic_vector(TESTSEQUENCE_ADDR_WIDTH-1 downto 0) := (others => '0'); signal TestSequence_len_in, TestSequence_addr_in: std_logic_vector(TESTSEQUENCE_ADDR_WIDTH-1 downto 0) := (others => '0');
@ -203,14 +205,23 @@ begin
KH := GetAlertLogID("KeyHash", ALERTLOG_BASE_ID); KH := GetAlertLogID("KeyHash", ALERTLOG_BASE_ID);
Log("Initial Reset", INFO); Log("Initial Reset", INFO);
start_w <= '0'; send_invalid_data <= '0';
reset <= '1'; start_w <= '0';
reset <= '1';
wait until rising_edge(clk); wait until rising_edge(clk);
wait until rising_edge(clk); wait until rising_edge(clk);
reset <= '0'; reset <= '0';
-- Create Invalid Serialized Payload
for i in 0 to MAX_TYPE2_SIZE loop
invalid_data.data(i) := RV.RandSlv(invalid_data.data(i)'length);
invalid_data.length := invalid_data.length + 1;
end loop;
invalid_data.last(invalid_data.length-1) := '1';
-- Serialized Key Payload Header -- Serialized Key Payload Header
gen_CDR(SERIALIZED_KEY_HEADER, ALIGN_4, align_offset, serialized_key); write_serialized_payload(SERIALIZED_KEY_HEADER, ALIGN_4, align_offset, serialized_key);
-- Reset Alignment -- Reset Alignment
align_offset := (others => '0'); align_offset := (others => '0');
@ -224,10 +235,10 @@ begin
TestUnion_OctetU_in <= RV.RandSlv(TestUnion_OctetU_in'length); TestUnion_OctetU_in <= RV.RandSlv(TestUnion_OctetU_in'length);
TestBitmask_in <= RV.RandSlv(TestBitmask_in'length); TestBitmask_in <= RV.RandSlv(TestBitmask_in'length);
wait for 0 ns; wait for 0 ns;
gen_CDR(endian_swap('1',id_in), ALIGN_4, align_offset, serialized_key); write_serialized_payload(endian_swap('1',id_in), ALIGN_4, align_offset, serialized_key);
TestSequence_len_in <= int(2,TestSequence_len_in'length); TestSequence_len_in <= int(2,TestSequence_len_in'length);
gen_CDR(endian_swap('1',int(2,CDR_LONG_WIDTH)), ALIGN_4, align_offset, serialized_key); write_serialized_payload(endian_swap('1',int(2,CDR_LONG_WIDTH)), ALIGN_4, align_offset, serialized_key);
-- Memory -- Memory
for i in 0 to 1 loop for i in 0 to 1 loop
TestSequence_addr_in <= int(i,TestSequence_addr_in'length); TestSequence_addr_in <= int(i,TestSequence_addr_in'length);
@ -243,7 +254,7 @@ begin
TestSequence_TestArray_wen_in <= '1'; TestSequence_TestArray_wen_in <= '1';
wait until rising_edge(clk); wait until rising_edge(clk);
TestSequence_TestArray_wen_in <= '0'; TestSequence_TestArray_wen_in <= '0';
gen_CDR(endian_swap('1',TestSequence_TestArray_w_in), ALIGN_1, align_offset, serialized_key); write_serialized_payload(endian_swap('1',TestSequence_TestArray_w_in), ALIGN_1, align_offset, serialized_key);
end loop; end loop;
wait_on_sig(TestSequence_ready_in); wait_on_sig(TestSequence_ready_in);
TestSequence_wen_in <= '1'; TestSequence_wen_in <= '1';
@ -279,9 +290,10 @@ begin
push_sk; push_sk;
Log("Push DATA", INFO); Log("Push Invalid DATA", INFO);
opcode_kh <= PUSH_DATA; send_invalid_data <= '1';
start_w <= '1'; opcode_kh <= PUSH_DATA;
start_w <= '1';
wait_on_sig(ack_w); wait_on_sig(ack_w);
wait until rising_edge(clk); wait until rising_edge(clk);
start_w <= '0'; start_w <= '0';
@ -293,6 +305,26 @@ begin
wait_on_sig(ready_kh_in); wait_on_sig(ready_kh_in);
wait until rising_edge(clk); wait until rising_edge(clk);
Alertif(decode_error /= '1', "Decode error not asserted", ERROR);
send_invalid_data <= '0';
Log("Push DATA", INFO);
opcode_kh <= PUSH_DATA;
start_w <= '1';
wait_on_sig(ack_w);
wait until rising_edge(clk);
start_w <= '0';
start_kh <= '1';
wait_on_sig(ack_kh);
wait until rising_edge(clk);
start_kh <= '0';
wait for 1 ps; -- Wait until signals are stable
Alertif(decode_error /= '0', "Decode error still asserted", ERROR);
wait_on_sig(last_word_kh_in);
wait_on_sig(ready_kh_in);
wait until rising_edge(clk);
Alertif(decode_error = '1', "Decode error asserted", ERROR);
Log("Read and Compare Serialized Key", INFO); Log("Read and Compare Serialized Key", INFO);
opcode_kh <= READ_SERIALIZED_KEY; opcode_kh <= READ_SERIALIZED_KEY;
start_kh <= '1'; start_kh <= '1';
@ -322,6 +354,7 @@ begin
wait_on_sig(last_word_sk); wait_on_sig(last_word_sk);
wait_on_sig(ready_sk); wait_on_sig(ready_sk);
wait until rising_edge(clk); wait until rising_edge(clk);
Alertif(decode_error = '1', "Decode error asserted", ERROR);
push_sk; push_sk;
Log("Read and Compare Serialized Key", INFO); Log("Read and Compare Serialized Key", INFO);
@ -363,28 +396,29 @@ begin
wait for TEST_CLOCK_PERIOD/2; wait for TEST_CLOCK_PERIOD/2;
end process; end process;
alert_prc : process(all)
begin
if rising_edge(clk) then
Alertif(decode_error = '1', "The Reader signals a DECODE Error", ERROR);
end if;
end process;
switch_prc : process(all) switch_prc : process(all)
begin begin
ready_w <= '0';
ready_de <= '0';
ready_sk <= '0';
case (opcode_kh) is case (opcode_kh) is
when PUSH_SERIALIZED_KEY => when PUSH_SERIALIZED_KEY =>
ready_sk <= ready_kh_in; ready_sk <= ready_kh_in;
valid_kh_in <= valid_sk; valid_kh_in <= valid_sk;
data_kh_in <= data_sk; data_kh_in <= data_sk;
last_word_kh_in <= last_word_sk; last_word_kh_in <= last_word_sk;
ready_w <= '0';
when others => when others =>
if (send_invalid_data = '1') then
ready_de <= ready_kh_in;
valid_kh_in <= valid_de;
data_kh_in <= data_de;
last_word_kh_in <= last_word_de;
else
ready_w <= ready_kh_in; ready_w <= ready_kh_in;
valid_kh_in <= valid_w; valid_kh_in <= valid_w;
data_kh_in <= data_w; data_kh_in <= data_w;
last_word_kh_in <= last_word_w; last_word_kh_in <= last_word_w;
ready_sk <= '0'; end if;
end case; end case;
end process; end process;
@ -408,6 +442,26 @@ begin
end if; end if;
end process; end process;
de_prc : process(all)
variable cnt : natural := 0;
begin
valid_de <= '1';
data_de <= invalid_data.data(cnt);
if (cnt = invalid_data.length-1) then
last_word_de <= '1';
end if;
if rising_edge(clk) then
if (ready_de = '1') then
if (cnt = invalid_data.length-1) then
cnt := 0;
else
cnt := cnt + 1;
end if;
end if;
end if;
end process;
output_check_prc : process(all) output_check_prc : process(all)
variable cnt : natural range 0 to 3 := 0; variable cnt : natural range 0 to 3 := 0;
begin begin

View File

@ -146,12 +146,14 @@ begin
ack <= '1'; ack <= '1';
stage_next <= GET_PAYLOAD_HEADER; stage_next <= GET_PAYLOAD_HEADER;
-- Reset -- Reset
key_hash_next <= KEY_HASH_NIL; key_hash_next <= KEY_HASH_NIL;
decode_error_latch_next <= '0';
when PUSH_SERIALIZED_KEY => when PUSH_SERIALIZED_KEY =>
ack <= '1'; ack <= '1';
stage_next <= GET_PAYLOAD_HEADER; stage_next <= GET_PAYLOAD_HEADER;
-- Reset -- Reset
key_hash_next <= KEY_HASH_NIL; key_hash_next <= KEY_HASH_NIL;
decode_error_latch_next <= '0';
when READ_KEY_HASH => when READ_KEY_HASH =>
ack <= '1'; ack <= '1';
-- Key Hash not calculated -- Key Hash not calculated

View File

@ -188,12 +188,14 @@ begin
ack <= '1'; ack <= '1';
stage_next <= GET_PAYLOAD_HEADER; stage_next <= GET_PAYLOAD_HEADER;
-- Reset -- Reset
key_hash_next <= KEY_HASH_NIL; key_hash_next <= KEY_HASH_NIL;
decode_error_latch_next <= '0';
when PUSH_SERIALIZED_KEY => when PUSH_SERIALIZED_KEY =>
ack <= '1'; ack <= '1';
stage_next <= GET_PAYLOAD_HEADER; stage_next <= GET_PAYLOAD_HEADER;
-- Reset -- Reset
key_hash_next <= KEY_HASH_NIL; key_hash_next <= KEY_HASH_NIL;
decode_error_latch_next <= '0';
when READ_KEY_HASH => when READ_KEY_HASH =>
ack <= '1'; ack <= '1';
-- Key Hash not calculated -- Key Hash not calculated