Bug Fix and Redesign of TEMPLATE_key_holder
Until now it was assumed that a serialized key is the PLAIN_CDR2 Big Endian encoding of a <TYPENAME>KeyHolder Object [DDS_XTYPES v1.3, 7.6.8] (I.e. the same blob that computes the MD5 key hash). Taking other DDS implementations as reference (e.g. Cyclone DDS), it seems they are using a normal Payload containing a KeyHolder(<TYPENAME>) Object [DDS_XTYPES v1.3, 7.2.2.4.7] as the serialized key. The Key Holder Template (together with the Type1 and Type2 implementations) were updated to reflect this change. A bug fix were the Key Hash was not reset on a 'PUSH_SERIALIZED_KEY' opcode was also fixed (together with the testbench).
This commit is contained in:
parent
5d9acb6f41
commit
830d6c1409
47
sim/L1_Type1_key_holder_test1.do
Normal file
47
sim/L1_Type1_key_holder_test1.do
Normal file
@ -0,0 +1,47 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate -divider SYSTEM
|
||||
add wave -noupdate /l1_type1_key_holder_test1/uut/clk
|
||||
add wave -noupdate /l1_type1_key_holder_test1/uut/reset
|
||||
add wave -noupdate /l1_type1_key_holder_test1/uut/start
|
||||
add wave -noupdate /l1_type1_key_holder_test1/uut/opcode
|
||||
add wave -noupdate /l1_type1_key_holder_test1/uut/ack
|
||||
add wave -noupdate /l1_type1_key_holder_test1/uut/decode_error
|
||||
add wave -noupdate -divider INPUT
|
||||
add wave -noupdate -radix hexadecimal /l1_type1_key_holder_test1/uut/data_in
|
||||
add wave -noupdate /l1_type1_key_holder_test1/uut/valid_in
|
||||
add wave -noupdate /l1_type1_key_holder_test1/uut/ready_in
|
||||
add wave -noupdate /l1_type1_key_holder_test1/uut/last_word_in
|
||||
add wave -noupdate -divider OUTPUT
|
||||
add wave -noupdate -radix hexadecimal /l1_type1_key_holder_test1/uut/data_out
|
||||
add wave -noupdate /l1_type1_key_holder_test1/uut/valid_out
|
||||
add wave -noupdate /l1_type1_key_holder_test1/uut/ready_out
|
||||
add wave -noupdate /l1_type1_key_holder_test1/uut/last_word_out
|
||||
add wave -noupdate -divider INTERNAL
|
||||
add wave -noupdate /l1_type1_key_holder_test1/uut/stage
|
||||
add wave -noupdate /l1_type1_key_holder_test1/uut/stage_next
|
||||
add wave -noupdate /l1_type1_key_holder_test1/uut/decode_stage
|
||||
add wave -noupdate /l1_type1_key_holder_test1/uut/decode_stage_next
|
||||
add wave -noupdate /l1_type1_key_holder_test1/uut/encode_stage
|
||||
add wave -noupdate /l1_type1_key_holder_test1/uut/encode_stage_next
|
||||
add wave -noupdate /l1_type1_key_holder_test1/uut/cnt
|
||||
add wave -noupdate -divider MISC
|
||||
add wave -noupdate /l1_type1_key_holder_test1/uut/align_offset
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 1} {13838438 ps} 0}
|
||||
quietly wave cursor active 1
|
||||
configure wave -namecolwidth 150
|
||||
configure wave -valuecolwidth 100
|
||||
configure wave -justifyvalue left
|
||||
configure wave -signalnamewidth 1
|
||||
configure wave -snapdistance 10
|
||||
configure wave -datasetprefix 0
|
||||
configure wave -rowmargin 4
|
||||
configure wave -childrowmargin 2
|
||||
configure wave -gridoffset 0
|
||||
configure wave -gridperiod 1
|
||||
configure wave -griddelta 40
|
||||
configure wave -timeline 0
|
||||
configure wave -timelineunits ns
|
||||
update
|
||||
WaveRestoreZoom {13547400 ps} {14571400 ps}
|
||||
47
sim/L1_Type2_key_holder_test2.do
Normal file
47
sim/L1_Type2_key_holder_test2.do
Normal file
@ -0,0 +1,47 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate -divider SYSTEM
|
||||
add wave -noupdate /l1_type2_key_holder_test2/uut/clk
|
||||
add wave -noupdate /l1_type2_key_holder_test2/uut/reset
|
||||
add wave -noupdate /l1_type2_key_holder_test2/uut/start
|
||||
add wave -noupdate /l1_type2_key_holder_test2/uut/opcode
|
||||
add wave -noupdate /l1_type2_key_holder_test2/uut/ack
|
||||
add wave -noupdate /l1_type2_key_holder_test2/uut/decode_error
|
||||
add wave -noupdate -divider INPUT
|
||||
add wave -noupdate -radix hexadecimal /l1_type2_key_holder_test2/uut/data_in
|
||||
add wave -noupdate /l1_type2_key_holder_test2/uut/valid_in
|
||||
add wave -noupdate /l1_type2_key_holder_test2/uut/ready_in
|
||||
add wave -noupdate /l1_type2_key_holder_test2/uut/last_word_in
|
||||
add wave -noupdate -divider OUTPUT
|
||||
add wave -noupdate -radix hexadecimal /l1_type2_key_holder_test2/uut/data_out
|
||||
add wave -noupdate /l1_type2_key_holder_test2/uut/valid_out
|
||||
add wave -noupdate /l1_type2_key_holder_test2/uut/ready_out
|
||||
add wave -noupdate /l1_type2_key_holder_test2/uut/last_word_out
|
||||
add wave -noupdate -divider INTERNAL
|
||||
add wave -noupdate /l1_type2_key_holder_test2/uut/stage
|
||||
add wave -noupdate /l1_type2_key_holder_test2/uut/stage_next
|
||||
add wave -noupdate /l1_type2_key_holder_test2/uut/decode_stage
|
||||
add wave -noupdate /l1_type2_key_holder_test2/uut/decode_stage_next
|
||||
add wave -noupdate /l1_type2_key_holder_test2/uut/encode_stage
|
||||
add wave -noupdate /l1_type2_key_holder_test2/uut/encode_stage_next
|
||||
add wave -noupdate /l1_type2_key_holder_test2/uut/cnt
|
||||
add wave -noupdate -divider MISC
|
||||
add wave -noupdate /l1_type2_key_holder_test2/uut/align_offset
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 1} {13838438 ps} 0}
|
||||
quietly wave cursor active 1
|
||||
configure wave -namecolwidth 150
|
||||
configure wave -valuecolwidth 100
|
||||
configure wave -justifyvalue left
|
||||
configure wave -signalnamewidth 1
|
||||
configure wave -snapdistance 10
|
||||
configure wave -datasetprefix 0
|
||||
configure wave -rowmargin 4
|
||||
configure wave -childrowmargin 2
|
||||
configure wave -gridoffset 0
|
||||
configure wave -gridperiod 1
|
||||
configure wave -griddelta 40
|
||||
configure wave -timeline 0
|
||||
configure wave -timelineunits ns
|
||||
update
|
||||
WaveRestoreZoom {13547400 ps} {14571400 ps}
|
||||
@ -259,28 +259,39 @@ Both encode_stage and decode_stage signals exist.
|
||||
The 'ALIGN_STREAM' stage is split into 'ALIGN_IN_STREAM' (for decode_stage) and 'ALIGN_OUT_STREAM'
|
||||
(for encode_stage).
|
||||
|
||||
The encoding/decoding follows the definition of the <TOPIC>KeyHolder sub-type definition.[6]
|
||||
The decode procedure (decode_stage stages) follow the reader_wrapper procedure of the <TOPIC> type until
|
||||
the last declared member that is also member of the <TOPIC>KeyHolder type, after which the 'SKIP_PAYLOAD'
|
||||
stage is taken. (Since the serialized key only uses the KeyHolder members, the rest is ignored)
|
||||
The encode procedure (encode_stage stages) follow the writer_wrapper procedure of the <TOPIC>KeyHolder type.
|
||||
The decode procedure (decode_stage stages) follows 2 different decoding procedures.
|
||||
The first - taken on a 'PUSH_DATA' opcode - follows the reader_wrapper procedure of the <TOPIC> type until
|
||||
the last declared member that is also member of the KeyHolder(<TYPENAME>)[6] Type (i.e. the last decalred
|
||||
key of the type), after which the 'SKIP_PAYLOAD' stage is taken.
|
||||
(Since the serialized key only uses the KeyHolder(<TYPENAME>) members, the rest is ignored)
|
||||
The second - taken on a 'PUSH_SERIALIZED_KEY' opcode - follows the reader_wrapper procedure of the
|
||||
KeyHolder(<TYPENAME>) directly.
|
||||
Since the decode_stages for the second decoding procedure are a subset of the first decoding procedure,
|
||||
the same decode stages are used, and only the 'decode_stage_next' signal is set depending on the
|
||||
'opcode_latch' signal. The 'GET_PAYLAOD_HEADER' stage selects the correct first decode stage.
|
||||
|
||||
Similarly the encode procedure also follows 2 different encoding procedures.
|
||||
The first - taken on a 'READ_SERIALIZED_KEY' opcode - follows the write_wrapper procedure of the
|
||||
KeyHolder(<TYPENAME>) Type.
|
||||
The second - taken on a 'READ_KEY_HASH' opcode (if the key is not already calculated) - follows the
|
||||
write_wrapper procedure of the <TYPENAME>KeyHolder[7] Type. Note that this encoding is in PLAIN_CDR2
|
||||
Big Endian, meaning that types wich have an ALIGN_8 in PLAIN_CDR have a ALIGN_4 in PLAIN_CDR2.
|
||||
Both encoding procedures share the same encode_stages, and the 'encode_stage_next' signal is
|
||||
set depending on the 'opcode_latch' signal. On a 'READ_SERIALIZED_KEY' opcode the
|
||||
'WRITE_PAYLOAD_HEADER' stage selects the first encode_stage, while on a 'READ_KEY_HASH' opcode the
|
||||
'START_KEY_HASH_GENERATION' stage selects the first encode_stage.
|
||||
|
||||
Since the decode_stages are used to parse both <TOPIC> type data (normal Payloads) and <TOPIC>KeyHolder
|
||||
type data (Serialized Key), some additional modification have to be done to the decode_stages.
|
||||
The 'GET_PAYLAOD_HEADER' stage select decode_stage of the first declared member of the <TOPIC> type, while
|
||||
the 'IDLE' stage (with opcode 'PUSH_SERIALIZED_KEY') selects the decode_stage of the first declared member
|
||||
of the <TOPIC>KeyHolder type.
|
||||
All decode_stages use the 'opcode_latch' signal to determine the next decode_stage. When 'opcode_latch'
|
||||
is 'PUSH_SERIALIZED_KEY', the <TOPIC>KeyHolder type declaration order is followed, else the <TOPIC> type
|
||||
declaration order.
|
||||
|
||||
PITFALLS
|
||||
########
|
||||
* Make sure to initialize the 'cnt' signal to zero before calling a decode_stage/encode_stage with sub-stages
|
||||
* Keep in mind the ALIGN difference between PLAIN_CDR and PLAIN_CDR2
|
||||
* Note that the order of the <TYPENAME>KeyHolder[7] members is in ascending member ID and may not be the same as KeyHolder(<TYPENAME>)[6]
|
||||
|
||||
[1] DDS_XTYPES v1.3, 7.4.3.1
|
||||
[2] DDS_XTYPES v1.3, 7.4.1.1.1
|
||||
[3] DDS_XTYPES v1.3, 7.4.1.1.3
|
||||
[4] DDS_XTYPES v1.3, 7.4.1.1.4
|
||||
[5] DDS_XTYPES v1.3, 7.4.1.1.5.2
|
||||
[6] DDS_XTYPES v1.3, 7.6.8
|
||||
[6] DDS_XTYPES v1.3, 7.2.2.4.7
|
||||
[7] DDS_XTYPES v1.3, 7.6.8
|
||||
@ -7,7 +7,6 @@ use ieee.numeric_std.all;
|
||||
|
||||
use work.rtps_package.all;
|
||||
use work.rtps_config_package.all;
|
||||
use work.Type2_package.all;
|
||||
|
||||
architecture TYPENAME of key_holder is
|
||||
|
||||
@ -32,7 +31,7 @@ architecture TYPENAME of key_holder is
|
||||
|
||||
--*****TYPE DECLARATION*****
|
||||
-- FSM states. Explained below in detail
|
||||
type STAGE_TYPE is (IDLE,START_KEY_HASH_GENERATION,GET_PAYLOAD_HEADER,FETCH,ALIGN_IN_STREAM,SKIP_PAYLOAD,DECODE_PAYLOAD,PUSH,ALIGN_OUT_STREAM,SERIALIZE_KEY,GET_KEY_HASH,PUSH_KEY_HASH);
|
||||
type STAGE_TYPE is (IDLE,START_KEY_HASH_GENERATION,GET_PAYLOAD_HEADER,FETCH,ALIGN_IN_STREAM,SKIP_PAYLOAD,DECODE_PAYLOAD, WRITE_PAYLOAD_HEADER, PUSH,ALIGN_OUT_STREAM,ENCODE_PAYLOAD,GET_KEY_HASH,PUSH_KEY_HASH);
|
||||
-- ###GENERATED START###
|
||||
type DECODE_STAGE_TYPE is (GET_OPTIONAL_HEADER, TODO);
|
||||
type ENCODE_STAGE_TYPE is (TODO);
|
||||
@ -54,7 +53,7 @@ architecture TYPENAME of key_holder is
|
||||
signal opcode_latch, opcode_latch_next : KEY_HOLDER_OPCODE_TYPE;
|
||||
signal cnt_2, cnt_2_next : natural range 0 to (WORD_WIDTH/BYTE_WIDTH)-1;
|
||||
signal align_op, align_op_next : std_logic;
|
||||
signal finalize_payload, finalize_payload_next : std_logic
|
||||
signal finalize_payload, finalize_payload_next : std_logic;
|
||||
signal ready_in_sig : std_logic;
|
||||
signal start_kh, ack_kh, done_kh : std_logic;
|
||||
signal data_in_kh : std_logic_vector(BYTE_WIDTH-1 downto 0);
|
||||
@ -153,15 +152,9 @@ begin
|
||||
key_hash_next <= KEY_HASH_NIL;
|
||||
when PUSH_SERIALIZED_KEY =>
|
||||
ack <= '1';
|
||||
-- Serialized Key is in PLAIN_CDR2 Big Endian encoding
|
||||
endian_flag_next <= '0';
|
||||
stage_next <= FETCH;
|
||||
|
||||
-- Alignment Reset
|
||||
align_offset_next <= (others => '0');
|
||||
-- ###GENERATED START###
|
||||
decode_stage_next <= TODO;
|
||||
-- ###GENERATED END###
|
||||
stage_next <= GET_PAYLOAD_HEADER;
|
||||
-- Reset
|
||||
key_hash_next <= KEY_HASH_NIL;
|
||||
when READ_KEY_HASH =>
|
||||
ack <= '1';
|
||||
-- Key Hash not calculated
|
||||
@ -173,13 +166,8 @@ begin
|
||||
end if;
|
||||
when READ_SERIALIZED_KEY =>
|
||||
ack <= '1';
|
||||
stage_next <= SERIALIZE_KEY;
|
||||
-- Alignment Reset
|
||||
align_offset_next <= (others => '0');
|
||||
data_out_latch_next <= (others => '0');
|
||||
-- ###GENERATED START###
|
||||
encode_stage_next <= TODO;
|
||||
-- ###GENERATED END###
|
||||
endian_flag_next <= LITTLE_ENDIAN;
|
||||
stage_next <= WRITE_PAYLOAD_HEADER;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
@ -187,11 +175,17 @@ begin
|
||||
when START_KEY_HASH_GENERATION =>
|
||||
start_kh <= '1';
|
||||
|
||||
-- <TYPENAME>KeyHolder is in PLAIN_CDR2 Big Endian encoding (see 7.6.8 DDS_XTYPES v1.3)
|
||||
endian_flag_next <= '0';
|
||||
-- Alignment Reset
|
||||
align_offset_next <= (others => '0');
|
||||
data_out_latch_next <= (others => '0');
|
||||
|
||||
if (ack_kh = '1') then
|
||||
stage_next <= SERIALIZE_KEY;
|
||||
stage_next <= ENCODE_PAYLOAD;
|
||||
-- ###GENERATED START###
|
||||
encode_stage_next <= TODO;
|
||||
-- ###GENERATED END###
|
||||
-- ###GENERATED START###
|
||||
end if;
|
||||
when GET_PAYLOAD_HEADER =>
|
||||
-- TODO: Latch Offset from Options Field?
|
||||
@ -205,17 +199,31 @@ begin
|
||||
stage_next <= FETCH;
|
||||
-- Alignment Reset
|
||||
align_offset_next <= (others => '0');
|
||||
-- ###GENERATED START###
|
||||
decode_stage_next <= TODO;
|
||||
-- ###GENERATED END###
|
||||
if (opcode_latch = PUSH_DATA) then
|
||||
-- ###GENERATED START###
|
||||
decode_stage_next <= TODO;
|
||||
-- ###GENERATED END###
|
||||
else --(opcode_latch = PUSH_SERIALIZED_KEY)
|
||||
assert(opcode_latch = PUSH_SERIALIZED_KEY) severity FAILURE;
|
||||
-- ###GENERATED START###
|
||||
decode_stage_next <= TODO;
|
||||
-- ###GENERATED END###
|
||||
end if;
|
||||
when CDR_LE =>
|
||||
endian_flag_next <= '1';
|
||||
stage_next <= FETCH;
|
||||
-- Alignment Reset
|
||||
align_offset_next <= (others => '0');
|
||||
-- ###GENERATED START###
|
||||
decode_stage_next <= TODO;
|
||||
-- ###GENERATED END###
|
||||
if (opcode_latch = PUSH_DATA) then
|
||||
-- ###GENERATED START###
|
||||
decode_stage_next <= TODO;
|
||||
-- ###GENERATED END###
|
||||
else --(opcode_latch = PUSH_SERIALIZED_KEY)
|
||||
assert(opcode_latch = PUSH_SERIALIZED_KEY) severity FAILURE;
|
||||
-- ###GENERATED START###
|
||||
decode_stage_next <= TODO;
|
||||
-- ###GENERATED END###
|
||||
end if;
|
||||
when others =>
|
||||
-- Unknown Payload Encoding
|
||||
stage_next <= SKIP_PAYLOAD;
|
||||
@ -316,6 +324,23 @@ begin
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
when WRITE_PAYLOAD_HEADER =>
|
||||
valid_out <= '1';
|
||||
if (LITTLE_ENDIAN = '0') then
|
||||
data_out <= CDR_BE & x"0000";
|
||||
else
|
||||
data_out <= CDR_LE & x"0000";
|
||||
end if;
|
||||
-- Output Guard
|
||||
if (ready_out = '1') then
|
||||
stage_next <= ENCODE_PAYLOAD;
|
||||
-- Reset
|
||||
align_offset_next <= (others => '0');
|
||||
data_out_latch_next <= (others => '0');
|
||||
-- ###GENERATED START###
|
||||
encode_stage_next <= TODO;
|
||||
-- ###GENERATED END###
|
||||
end if;
|
||||
when PUSH =>
|
||||
-- Push to Key Hash Generator
|
||||
if (opcode_latch = READ_KEY_HASH) then
|
||||
@ -343,13 +368,14 @@ begin
|
||||
-- Reset
|
||||
finalize_payload_next <= '0';
|
||||
else
|
||||
stage_next <= SERIALIZE_KEY;
|
||||
stage_next <= ENCODE_PAYLOAD;
|
||||
end if;
|
||||
else
|
||||
cnt_2_next <= cnt_2 + 1;
|
||||
end if;
|
||||
end if;
|
||||
else
|
||||
else -- (opcode_latch = READ_SERIALIZED_KEY)
|
||||
assert(opcode_latch = READ_SERIALIZED_KEY) severity FAILURE;
|
||||
-- Mark Last Word
|
||||
if (finalize_payload = '1') then
|
||||
last_word_out <= '1';
|
||||
@ -371,7 +397,7 @@ begin
|
||||
finalize_payload_next <= '0';
|
||||
stage_next <= IDLE;
|
||||
else
|
||||
stage_next <= SERIALIZE_KEY;
|
||||
stage_next <= ENCODE_PAYLOAD;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
@ -379,7 +405,7 @@ begin
|
||||
-- Target Stream Alignment reached
|
||||
if (check_align(align_offset, target_align)) then
|
||||
-- DONE
|
||||
stage_next <= SERIALIZE_KEY;
|
||||
stage_next <= ENCODE_PAYLOAD;
|
||||
else
|
||||
align_offset_next <= align_offset + 1;
|
||||
-- Need to push Word
|
||||
@ -388,12 +414,11 @@ begin
|
||||
stage_next <= PUSH;
|
||||
end if;
|
||||
end if;
|
||||
when SERIALIZE_KEY =>
|
||||
when ENCODE_PAYLOAD =>
|
||||
case (encode_stage) is
|
||||
-- ###GENERATED START###
|
||||
when TODO =>
|
||||
-- ###GENERATED END###
|
||||
when others =>
|
||||
end case;
|
||||
when GET_KEY_HASH =>
|
||||
if (done_kh = '1') then
|
||||
|
||||
@ -165,15 +165,22 @@ begin
|
||||
-- ###GENERATED END###
|
||||
end if;
|
||||
when WRITE_PAYLOAD_HEADER =>
|
||||
valid_out_dds <= '1';
|
||||
if (LITTLE_ENDIAN = '0') then
|
||||
data_out_latch_next <= CDR_BE & x"0000";
|
||||
data_out_dds <= CDR_BE & x"0000";
|
||||
else
|
||||
data_out_latch_next <= CDR_LE & x"0000";
|
||||
data_out_dds <= CDR_LE & x"0000";
|
||||
end if;
|
||||
-- Output Guard
|
||||
if (ready_out_dds = '1') then
|
||||
stage_next <= ENCODE_PAYLOAD;
|
||||
-- Reset
|
||||
align_offset_next <= (others => '0');
|
||||
data_out_latch_next <= (others => '0');
|
||||
-- ###GENERATED START###
|
||||
encode_stage_next <= TODO;
|
||||
-- ###GENERATED END###
|
||||
end if;
|
||||
stage_next <= PUSH;
|
||||
-- ###GENERATED START###
|
||||
encode_stage_next <= TODO;
|
||||
-- ###GENERATED END###
|
||||
when PUSH =>
|
||||
-- Mark Last Word
|
||||
if (finalize_payload = '1') then
|
||||
|
||||
@ -65,8 +65,9 @@
|
||||
* What happens if we get a sample with a source timestamp earlier than the last sample that was accessed by the DataReader when using DESTINATION ORDER BY_SOURCE_TIMESTAMP? Is the sample dropped?
|
||||
* The spec does not define the serialized Key (KEY=1 DATA MESSAGE)
|
||||
- fast-rtps assumes it is the Key Hash
|
||||
- opendds sends Payload Encapsulation with a Key Holder Object (As defined in XType 7.6.8)
|
||||
- opensplice seems to do the same as opendds
|
||||
- opendds sends a full Payload (including Payload Header) containing a KeyHolder(Type) (Option a in https://issues.omg.org/issues/DDSXTY14-38)
|
||||
- opensplice does same as opendds
|
||||
- CycloneDDS does same as opendds
|
||||
* Assert Heartbeat period > Heartbeat Suppression Period
|
||||
* Can I request (NACK) SNs that were NOT announced by the writer (> last_sn in Heartbeat)?
|
||||
* Does AUTOMATIC Liveliness QoS also update the lease on write/assert_liveliness operations?
|
||||
|
||||
@ -12,9 +12,9 @@ use work.rtps_test_package.all;
|
||||
use work.Type2_package.all;
|
||||
|
||||
-- This testbench tests the KEY_HOLDER commands of TYPE1.
|
||||
-- It uses the writer_wrapper to send a valid TYPE2 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.
|
||||
-- It uses the writer_wrapper 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.
|
||||
-- Then the reference serialized key is pushed (resetting the internaly generated key hash), and the serialized key and key hash are re-read and compared (The key hash is compared to the previosuly compared).
|
||||
-- The TYPE2 payload is sent in Big Endian.
|
||||
-- The payload is sent in Big Endian.
|
||||
|
||||
entity L1_Type1_key_holder_test1 is
|
||||
end entity;
|
||||
@ -97,6 +97,7 @@ begin
|
||||
variable RV : RandomPType;
|
||||
variable align_offset : unsigned(MAX_ALIGN_OFFSET_WIDTH-1 downto 0) := (others => '0');
|
||||
variable SK, KH : AlertLogIDType;
|
||||
constant SERIALIZED_KEY_HEADER : std_logic_vector(WORD_WIDTH-1 downto 0) := CDR_BE & x"0000";
|
||||
|
||||
procedure wait_on_sig(signal sig : std_logic) is
|
||||
begin
|
||||
@ -132,6 +133,11 @@ begin
|
||||
wait until rising_edge(clk);
|
||||
reset <= '0';
|
||||
|
||||
-- Serialized Key Payload Header
|
||||
gen_CDR(SERIALIZED_KEY_HEADER, ALIGN_4, align_offset, serialized_key);
|
||||
-- Reset Alignement
|
||||
align_offset := (others => '0');
|
||||
|
||||
Log("Setting Data in Writer Side", INFO);
|
||||
-- Static
|
||||
id_in <= RV.RandSlv(id_in'length);
|
||||
@ -258,13 +264,13 @@ begin
|
||||
sk_prc : process(all)
|
||||
variable cnt : natural := 0;
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
valid_sk <= '1';
|
||||
data_sk <= serialized_key.data(cnt);
|
||||
if (cnt = serialized_key.length-1) then
|
||||
last_word_sk <= '1';
|
||||
end if;
|
||||
valid_sk <= '1';
|
||||
data_sk <= serialized_key.data(cnt);
|
||||
if (cnt = serialized_key.length-1) then
|
||||
last_word_sk <= '1';
|
||||
end if;
|
||||
|
||||
if rising_edge(clk) then
|
||||
if (ready_sk = '1') then
|
||||
if (cnt = serialized_key.length-1) then
|
||||
cnt := 0;
|
||||
|
||||
@ -12,9 +12,9 @@ use work.rtps_test_package.all;
|
||||
use work.Type2_package.all;
|
||||
|
||||
-- This testbench tests the KEY_HOLDER commands of TYPE1.
|
||||
-- It uses the writer_wrapper to send a valid TYPE2 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.
|
||||
-- It uses the writer_wrapper 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.
|
||||
-- Then the reference serialized key is pushed (resetting the internaly generated key hash), and the serialized key and key hash are re-read and compared (The key hash is compared to the previosuly compared).
|
||||
-- The TYPE2 payload is sent in Little Endian.
|
||||
-- The payload is sent in Little Endian.
|
||||
|
||||
entity L1_Type1_key_holder_test2 is
|
||||
end entity;
|
||||
@ -77,6 +77,9 @@ begin
|
||||
);
|
||||
|
||||
uut : entity work.key_holder(TYPE1)
|
||||
generic map (
|
||||
LITTLE_ENDIAN => '1'
|
||||
)
|
||||
port map (
|
||||
clk => clk,
|
||||
reset => reset,
|
||||
@ -100,6 +103,7 @@ begin
|
||||
variable RV : RandomPType;
|
||||
variable align_offset : unsigned(MAX_ALIGN_OFFSET_WIDTH-1 downto 0) := (others => '0');
|
||||
variable SK, KH : AlertLogIDType;
|
||||
constant SERIALIZED_KEY_HEADER : std_logic_vector(WORD_WIDTH-1 downto 0) := CDR_LE & x"0000";
|
||||
|
||||
procedure wait_on_sig(signal sig : std_logic) is
|
||||
begin
|
||||
@ -135,12 +139,17 @@ begin
|
||||
wait until rising_edge(clk);
|
||||
reset <= '0';
|
||||
|
||||
-- Serialized Key Payload Header
|
||||
gen_CDR(SERIALIZED_KEY_HEADER, ALIGN_4, align_offset, serialized_key);
|
||||
-- Reset Alignement
|
||||
align_offset := (others => '0');
|
||||
|
||||
Log("Setting Data in Writer Side", INFO);
|
||||
-- Static
|
||||
id_in <= RV.RandSlv(id_in'length);
|
||||
a_in <= RV.RandSlv(a_in'length);
|
||||
wait for 0 ns;
|
||||
gen_CDR(id_in, ALIGN_4, align_offset, serialized_key);
|
||||
gen_CDR(endian_swap('1',id_in), ALIGN_4, align_offset, serialized_key);
|
||||
|
||||
-- Finalize Serialized Key
|
||||
if (align_offset(1 downto 0) /= "00") then
|
||||
@ -261,13 +270,13 @@ begin
|
||||
sk_prc : process(all)
|
||||
variable cnt : natural := 0;
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
valid_sk <= '1';
|
||||
data_sk <= serialized_key.data(cnt);
|
||||
if (cnt = serialized_key.length-1) then
|
||||
last_word_sk <= '1';
|
||||
end if;
|
||||
valid_sk <= '1';
|
||||
data_sk <= serialized_key.data(cnt);
|
||||
if (cnt = serialized_key.length-1) then
|
||||
last_word_sk <= '1';
|
||||
end if;
|
||||
|
||||
if rising_edge(clk) then
|
||||
if (ready_sk = '1') then
|
||||
if (cnt = serialized_key.length-1) then
|
||||
cnt := 0;
|
||||
|
||||
@ -12,9 +12,9 @@ use work.rtps_test_package.all;
|
||||
use work.Type2_package.all;
|
||||
|
||||
-- This testbench tests the KEY_HOLDER commands of TYPE2.
|
||||
-- It uses the writer_wrapper to send a valid TYPE2 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.
|
||||
-- It uses the writer_wrapper 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.
|
||||
-- Then the reference serialized key is pushed (resetting the internaly generated key hash), and the serialized key and key hash are re-read and compared (The key hash is compared to the previosuly compared).
|
||||
-- The TYPE2 payload is sent in Big Endian.
|
||||
-- The payload is sent in Big Endian.
|
||||
|
||||
entity L1_Type2_key_holder_test1 is
|
||||
end entity;
|
||||
@ -169,6 +169,7 @@ begin
|
||||
variable RV : RandomPType;
|
||||
variable align_offset : unsigned(MAX_ALIGN_OFFSET_WIDTH-1 downto 0) := (others => '0');
|
||||
variable SK, KH : AlertLogIDType;
|
||||
constant SERIALIZED_KEY_HEADER : std_logic_vector(WORD_WIDTH-1 downto 0) := CDR_BE & x"0000";
|
||||
|
||||
procedure wait_on_sig(signal sig : std_logic) is
|
||||
begin
|
||||
@ -204,6 +205,11 @@ begin
|
||||
wait until rising_edge(clk);
|
||||
reset <= '0';
|
||||
|
||||
-- Serialized Key Payload Header
|
||||
gen_CDR(SERIALIZED_KEY_HEADER, ALIGN_4, align_offset, serialized_key);
|
||||
-- Reset Alignement
|
||||
align_offset := (others => '0');
|
||||
|
||||
Log("Setting Data in Writer Side", INFO);
|
||||
-- Static
|
||||
id_in <= RV.RandSlv(id_in'length);
|
||||
@ -381,13 +387,13 @@ begin
|
||||
sk_prc : process(all)
|
||||
variable cnt : natural := 0;
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
valid_sk <= '1';
|
||||
data_sk <= serialized_key.data(cnt);
|
||||
if (cnt = serialized_key.length-1) then
|
||||
last_word_sk <= '1';
|
||||
end if;
|
||||
valid_sk <= '1';
|
||||
data_sk <= serialized_key.data(cnt);
|
||||
if (cnt = serialized_key.length-1) then
|
||||
last_word_sk <= '1';
|
||||
end if;
|
||||
|
||||
if rising_edge(clk) then
|
||||
if (ready_sk = '1') then
|
||||
if (cnt = serialized_key.length-1) then
|
||||
cnt := 0;
|
||||
|
||||
@ -12,9 +12,9 @@ use work.rtps_test_package.all;
|
||||
use work.Type2_package.all;
|
||||
|
||||
-- This testbench tests the KEY_HOLDER commands of TYPE2.
|
||||
-- It uses the writer_wrapper to send a valid TYPE2 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.
|
||||
-- It uses the writer_wrapper 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.
|
||||
-- Then the reference serialized key is pushed (resetting the internaly generated key hash), and the serialized key and key hash are re-read and compared (The key hash is compared to the previosuly compared).
|
||||
-- The TYPE2 payload is sent in Little Endian.
|
||||
-- The payload is sent in Little Endian.
|
||||
|
||||
entity L1_Type2_key_holder_test2 is
|
||||
end entity;
|
||||
@ -149,6 +149,9 @@ begin
|
||||
);
|
||||
|
||||
uut : entity work.key_holder(TYPE2)
|
||||
generic map (
|
||||
LITTLE_ENDIAN => '1'
|
||||
)
|
||||
port map (
|
||||
clk => clk,
|
||||
reset => reset,
|
||||
@ -172,6 +175,7 @@ begin
|
||||
variable RV : RandomPType;
|
||||
variable align_offset : unsigned(MAX_ALIGN_OFFSET_WIDTH-1 downto 0) := (others => '0');
|
||||
variable SK, KH : AlertLogIDType;
|
||||
constant SERIALIZED_KEY_HEADER : std_logic_vector(WORD_WIDTH-1 downto 0) := CDR_LE & x"0000";
|
||||
|
||||
procedure wait_on_sig(signal sig : std_logic) is
|
||||
begin
|
||||
@ -207,6 +211,11 @@ begin
|
||||
wait until rising_edge(clk);
|
||||
reset <= '0';
|
||||
|
||||
-- Serialized Key Payload Header
|
||||
gen_CDR(SERIALIZED_KEY_HEADER, ALIGN_4, align_offset, serialized_key);
|
||||
-- Reset Alignement
|
||||
align_offset := (others => '0');
|
||||
|
||||
Log("Setting Data in Writer Side", INFO);
|
||||
-- Static
|
||||
id_in <= RV.RandSlv(id_in'length);
|
||||
@ -217,10 +226,10 @@ begin
|
||||
TestUnion_OctetU_in <= RV.RandSlv(TestUnion_OctetU_in'length);
|
||||
TestBitmask_in <= RV.RandSlv(TestBitmask_in'length);
|
||||
wait for 0 ns;
|
||||
gen_CDR(id_in, ALIGN_4, align_offset, serialized_key);
|
||||
gen_CDR(endian_swap('1',id_in), ALIGN_4, align_offset, serialized_key);
|
||||
|
||||
TestSequence_len_in <= int(2,TestSequence_len_in'length);
|
||||
gen_CDR(int(2,CDR_LONG_WIDTH), ALIGN_4, align_offset, serialized_key);
|
||||
gen_CDR(endian_swap('1',int(2,CDR_LONG_WIDTH)), ALIGN_4, align_offset, serialized_key);
|
||||
-- Memory
|
||||
for i in 0 to 1 loop
|
||||
TestSequence_addr_in <= int(i,TestSequence_addr_in'length);
|
||||
@ -236,7 +245,7 @@ begin
|
||||
TestSequence_TestArray_wen_in <= '1';
|
||||
wait until rising_edge(clk);
|
||||
TestSequence_TestArray_wen_in <= '0';
|
||||
gen_CDR(TestSequence_TestArray_w_in, ALIGN_1, align_offset, serialized_key);
|
||||
gen_CDR(endian_swap('1',TestSequence_TestArray_w_in), ALIGN_1, align_offset, serialized_key);
|
||||
end loop;
|
||||
wait_on_sig(TestSequence_ready_in);
|
||||
TestSequence_wen_in <= '1';
|
||||
@ -384,13 +393,13 @@ begin
|
||||
sk_prc : process(all)
|
||||
variable cnt : natural := 0;
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
valid_sk <= '1';
|
||||
data_sk <= serialized_key.data(cnt);
|
||||
if (cnt = serialized_key.length-1) then
|
||||
last_word_sk <= '1';
|
||||
end if;
|
||||
valid_sk <= '1';
|
||||
data_sk <= serialized_key.data(cnt);
|
||||
if (cnt = serialized_key.length-1) then
|
||||
last_word_sk <= '1';
|
||||
end if;
|
||||
|
||||
if rising_edge(clk) then
|
||||
if (ready_sk = '1') then
|
||||
if (cnt = serialized_key.length-1) then
|
||||
cnt := 0;
|
||||
|
||||
@ -29,7 +29,7 @@ architecture TYPE1 of key_holder is
|
||||
|
||||
--*****TYPE DECLARATION*****
|
||||
-- FSM states. Explained below in detail
|
||||
type STAGE_TYPE is (IDLE,START_KEY_HASH_GENERATION,GET_PAYLOAD_HEADER,FETCH,ALIGN_IN_STREAM,SKIP_PAYLOAD,DECODE_PAYLOAD,PUSH,ALIGN_OUT_STREAM,SERIALIZE_KEY,GET_KEY_HASH,PUSH_KEY_HASH);
|
||||
type STAGE_TYPE is (IDLE,START_KEY_HASH_GENERATION,GET_PAYLOAD_HEADER,FETCH,ALIGN_IN_STREAM,SKIP_PAYLOAD,DECODE_PAYLOAD, WRITE_PAYLOAD_HEADER, PUSH,ALIGN_OUT_STREAM,ENCODE_PAYLOAD,GET_KEY_HASH,PUSH_KEY_HASH);
|
||||
-- ###GENERATED START###
|
||||
type DECODE_STAGE_TYPE is (GET_OPTIONAL_HEADER, GET_ID);
|
||||
type ENCODE_STAGE_TYPE is (WRITE_ID);
|
||||
@ -145,15 +145,9 @@ begin
|
||||
key_hash_next <= KEY_HASH_NIL;
|
||||
when PUSH_SERIALIZED_KEY =>
|
||||
ack <= '1';
|
||||
-- Serialized Key is in PLAIN_CDR2 Big Endian encoding
|
||||
endian_flag_next <= '0';
|
||||
stage_next <= FETCH;
|
||||
|
||||
-- Alignment Reset
|
||||
align_offset_next <= (others => '0');
|
||||
-- ###GENERATED START###
|
||||
decode_stage_next <= GET_ID;
|
||||
-- ###GENERATED END###
|
||||
stage_next <= GET_PAYLOAD_HEADER;
|
||||
-- Reset
|
||||
key_hash_next <= KEY_HASH_NIL;
|
||||
when READ_KEY_HASH =>
|
||||
ack <= '1';
|
||||
-- Key Hash not calculated
|
||||
@ -165,13 +159,8 @@ begin
|
||||
end if;
|
||||
when READ_SERIALIZED_KEY =>
|
||||
ack <= '1';
|
||||
stage_next <= SERIALIZE_KEY;
|
||||
-- Alignment Reset
|
||||
align_offset_next <= (others => '0');
|
||||
data_out_latch_next <= (others => '0');
|
||||
-- ###GENERATED START###
|
||||
encode_stage_next <= WRITE_ID;
|
||||
-- ###GENERATED END###
|
||||
endian_flag_next <= LITTLE_ENDIAN;
|
||||
stage_next <= WRITE_PAYLOAD_HEADER;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
@ -179,9 +168,17 @@ begin
|
||||
when START_KEY_HASH_GENERATION =>
|
||||
start_kh <= '1';
|
||||
|
||||
-- <TYPENAME>KeyHolder is in PLAIN_CDR2 Big Endian encoding (see 7.6.8 DDS_XTYPES v1.3)
|
||||
endian_flag_next <= '0';
|
||||
-- Alignment Reset
|
||||
align_offset_next <= (others => '0');
|
||||
data_out_latch_next <= (others => '0');
|
||||
|
||||
if (ack_kh = '1') then
|
||||
stage_next <= SERIALIZE_KEY;
|
||||
stage_next <= ENCODE_PAYLOAD;
|
||||
-- ###GENERATED START###
|
||||
encode_stage_next <= WRITE_ID;
|
||||
-- ###GENERATED START###
|
||||
end if;
|
||||
when GET_PAYLOAD_HEADER =>
|
||||
-- TODO: Latch Offset from Options Field?
|
||||
@ -195,17 +192,31 @@ begin
|
||||
stage_next <= FETCH;
|
||||
-- Alignment Reset
|
||||
align_offset_next <= (others => '0');
|
||||
-- ###GENERATED START###
|
||||
decode_stage_next <= GET_ID;
|
||||
-- ###GENERATED END###
|
||||
if (opcode_latch = PUSH_DATA) then
|
||||
-- ###GENERATED START###
|
||||
decode_stage_next <= GET_ID;
|
||||
-- ###GENERATED END###
|
||||
else --(opcode_latch = PUSH_SERIALIZED_KEY)
|
||||
assert(opcode_latch = PUSH_SERIALIZED_KEY) severity FAILURE;
|
||||
-- ###GENERATED START###
|
||||
decode_stage_next <= GET_ID;
|
||||
-- ###GENERATED END###
|
||||
end if;
|
||||
when CDR_LE =>
|
||||
endian_flag_next <= '1';
|
||||
stage_next <= FETCH;
|
||||
-- Alignment Reset
|
||||
align_offset_next <= (others => '0');
|
||||
-- ###GENERATED START###
|
||||
decode_stage_next <= GET_ID;
|
||||
-- ###GENERATED END###
|
||||
if (opcode_latch = PUSH_DATA) then
|
||||
-- ###GENERATED START###
|
||||
decode_stage_next <= GET_ID;
|
||||
-- ###GENERATED END###
|
||||
else --(opcode_latch = PUSH_SERIALIZED_KEY)
|
||||
assert(opcode_latch = PUSH_SERIALIZED_KEY) severity FAILURE;
|
||||
-- ###GENERATED START###
|
||||
decode_stage_next <= GET_ID;
|
||||
-- ###GENERATED END###
|
||||
end if;
|
||||
when others =>
|
||||
-- Unknown Payload Encoding
|
||||
stage_next <= SKIP_PAYLOAD;
|
||||
@ -317,6 +328,23 @@ begin
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
when WRITE_PAYLOAD_HEADER =>
|
||||
valid_out <= '1';
|
||||
if (LITTLE_ENDIAN = '0') then
|
||||
data_out <= CDR_BE & x"0000";
|
||||
else
|
||||
data_out <= CDR_LE & x"0000";
|
||||
end if;
|
||||
-- Output Guard
|
||||
if (ready_out = '1') then
|
||||
stage_next <= ENCODE_PAYLOAD;
|
||||
-- Reset
|
||||
align_offset_next <= (others => '0');
|
||||
data_out_latch_next <= (others => '0');
|
||||
-- ###GENERATED START###
|
||||
encode_stage_next <= WRITE_ID;
|
||||
-- ###GENERATED END###
|
||||
end if;
|
||||
when PUSH =>
|
||||
-- Push to Key Hash Generator
|
||||
if (opcode_latch = READ_KEY_HASH) then
|
||||
@ -344,13 +372,14 @@ begin
|
||||
-- Reset
|
||||
finalize_payload_next <= '0';
|
||||
else
|
||||
stage_next <= SERIALIZE_KEY;
|
||||
stage_next <= ENCODE_PAYLOAD;
|
||||
end if;
|
||||
else
|
||||
cnt_2_next <= cnt_2 + 1;
|
||||
end if;
|
||||
end if;
|
||||
else
|
||||
else -- (opcode_latch = READ_SERIALIZED_KEY)
|
||||
assert(opcode_latch = READ_SERIALIZED_KEY) severity FAILURE;
|
||||
-- Mark Last Word
|
||||
if (finalize_payload = '1') then
|
||||
last_word_out <= '1';
|
||||
@ -372,7 +401,7 @@ begin
|
||||
finalize_payload_next <= '0';
|
||||
stage_next <= IDLE;
|
||||
else
|
||||
stage_next <= SERIALIZE_KEY;
|
||||
stage_next <= ENCODE_PAYLOAD;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
@ -380,7 +409,7 @@ begin
|
||||
-- Target Stream Alignment reached
|
||||
if (check_align(align_offset, target_align)) then
|
||||
-- DONE
|
||||
stage_next <= SERIALIZE_KEY;
|
||||
stage_next <= ENCODE_PAYLOAD;
|
||||
else
|
||||
align_offset_next <= align_offset + 1;
|
||||
-- Need to push Word
|
||||
@ -389,7 +418,7 @@ begin
|
||||
stage_next <= PUSH;
|
||||
end if;
|
||||
end if;
|
||||
when SERIALIZE_KEY =>
|
||||
when ENCODE_PAYLOAD =>
|
||||
case (encode_stage) is
|
||||
-- ###GENERATED START###
|
||||
when WRITE_ID =>
|
||||
@ -398,7 +427,7 @@ begin
|
||||
target_align_next <= ALIGN_4;
|
||||
stage_next <= ALIGN_OUT_STREAM;
|
||||
else
|
||||
data_out_latch_next <= id_latch;
|
||||
data_out_latch_next <= endian_swap(endian_flag, id_latch);
|
||||
align_offset_next <= align_offset + 4;
|
||||
-- DONE
|
||||
stage_next <= PUSH;
|
||||
|
||||
@ -147,15 +147,22 @@ begin
|
||||
null;
|
||||
end if;
|
||||
when WRITE_PAYLOAD_HEADER =>
|
||||
valid_out_dds <= '1';
|
||||
if (LITTLE_ENDIAN = '0') then
|
||||
data_out_latch_next <= CDR_BE & x"0000";
|
||||
data_out_dds <= CDR_BE & x"0000";
|
||||
else
|
||||
data_out_latch_next <= CDR_LE & x"0000";
|
||||
data_out_dds <= CDR_LE & x"0000";
|
||||
end if;
|
||||
-- Output Guard
|
||||
if (ready_out_dds = '1') then
|
||||
stage_next <= ENCODE_PAYLOAD;
|
||||
-- Reset
|
||||
align_offset_next <= (others => '0');
|
||||
data_out_latch_next <= (others => '0');
|
||||
-- ###GENERATED START###
|
||||
encode_stage_next <= WRITE_ID;
|
||||
-- ###GENERATED END###
|
||||
end if;
|
||||
stage_next <= PUSH;
|
||||
-- ###GENERATED START###
|
||||
encode_stage_next <= WRITE_ID;
|
||||
-- ###GENERATED END###
|
||||
when PUSH =>
|
||||
-- Mark Last Word
|
||||
if (finalize_payload = '1') then
|
||||
|
||||
@ -29,7 +29,7 @@ architecture TYPE2 of key_holder is
|
||||
|
||||
--*****TYPE DECLARATION*****
|
||||
-- FSM states. Explained below in detail
|
||||
type STAGE_TYPE is (IDLE,START_KEY_HASH_GENERATION,GET_PAYLOAD_HEADER,FETCH,ALIGN_IN_STREAM,SKIP_PAYLOAD,DECODE_PAYLOAD,PUSH,ALIGN_OUT_STREAM,SERIALIZE_KEY,GET_KEY_HASH,PUSH_KEY_HASH);
|
||||
type STAGE_TYPE is (IDLE,START_KEY_HASH_GENERATION,GET_PAYLOAD_HEADER,FETCH,ALIGN_IN_STREAM,SKIP_PAYLOAD,DECODE_PAYLOAD, WRITE_PAYLOAD_HEADER, PUSH,ALIGN_OUT_STREAM,ENCODE_PAYLOAD,GET_KEY_HASH,PUSH_KEY_HASH);
|
||||
-- ###GENERATED START###
|
||||
type DECODE_STAGE_TYPE is (GET_ID,GET_TESTSEQUENCE_LENGTH,GET_TESTSEQUENCE_TESTARRAY,GET_TESTSEQUENCE_TESTCHAR,GET_TESTSEQUENCE_TESTWCHAR,GET_TESTSEQUENCE_TESTLONGLONG,GET_TESTSEQUENCE_TESTLONGDOUBLE,TESTSEQUENCE_MEMBER_END,GET_OPTIONAL_HEADER);
|
||||
type ENCODE_STAGE_TYPE is (WRITE_ID,WRITE_TESTSEQUENCE_LENGTH,WRITE_TESTSEQUENCE_TESTARRAY,TESTSEQUENCE_MEMBER_END);
|
||||
@ -189,15 +189,9 @@ begin
|
||||
key_hash_next <= KEY_HASH_NIL;
|
||||
when PUSH_SERIALIZED_KEY =>
|
||||
ack <= '1';
|
||||
-- Serialized Key is in PLAIN_CDR2 Big Endian encoding
|
||||
endian_flag_next <= '0';
|
||||
stage_next <= FETCH;
|
||||
|
||||
-- Alignment Reset
|
||||
align_offset_next <= (others => '0');
|
||||
-- ###GENERATED START###
|
||||
decode_stage_next <= GET_ID;
|
||||
-- ###GENERATED END###
|
||||
stage_next <= GET_PAYLOAD_HEADER;
|
||||
-- Reset
|
||||
key_hash_next <= KEY_HASH_NIL;
|
||||
when READ_KEY_HASH =>
|
||||
ack <= '1';
|
||||
-- Key Hash not calculated
|
||||
@ -209,13 +203,8 @@ begin
|
||||
end if;
|
||||
when READ_SERIALIZED_KEY =>
|
||||
ack <= '1';
|
||||
stage_next <= SERIALIZE_KEY;
|
||||
-- Alignment Reset
|
||||
align_offset_next <= (others => '0');
|
||||
data_out_latch_next <= (others => '0');
|
||||
-- ###GENERATED START###
|
||||
encode_stage_next <= WRITE_ID;
|
||||
-- ###GENERATED END###
|
||||
endian_flag_next <= LITTLE_ENDIAN;
|
||||
stage_next <= WRITE_PAYLOAD_HEADER;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
@ -223,9 +212,17 @@ begin
|
||||
when START_KEY_HASH_GENERATION =>
|
||||
start_kh <= '1';
|
||||
|
||||
-- <TYPENAME>KeyHolder is in PLAIN_CDR2 Big Endian encoding (see 7.6.8 DDS_XTYPES v1.3)
|
||||
endian_flag_next <= '0';
|
||||
-- Alignment Reset
|
||||
align_offset_next <= (others => '0');
|
||||
data_out_latch_next <= (others => '0');
|
||||
|
||||
if (ack_kh = '1') then
|
||||
stage_next <= SERIALIZE_KEY;
|
||||
stage_next <= ENCODE_PAYLOAD;
|
||||
-- ###GENERATED START###
|
||||
encode_stage_next <= WRITE_ID;
|
||||
-- ###GENERATED START###
|
||||
end if;
|
||||
when GET_PAYLOAD_HEADER =>
|
||||
-- TODO: Latch Offset from Options Field?
|
||||
@ -239,17 +236,31 @@ begin
|
||||
stage_next <= FETCH;
|
||||
-- Alignment Reset
|
||||
align_offset_next <= (others => '0');
|
||||
-- ###GENERATED START###
|
||||
decode_stage_next <= GET_ID;
|
||||
-- ###GENERATED END###
|
||||
if (opcode_latch = PUSH_DATA) then
|
||||
-- ###GENERATED START###
|
||||
decode_stage_next <= GET_ID;
|
||||
-- ###GENERATED END###
|
||||
else --(opcode_latch = PUSH_SERIALIZED_KEY)
|
||||
assert(opcode_latch = PUSH_SERIALIZED_KEY) severity FAILURE;
|
||||
-- ###GENERATED START###
|
||||
decode_stage_next <= GET_ID;
|
||||
-- ###GENERATED END###
|
||||
end if;
|
||||
when CDR_LE =>
|
||||
endian_flag_next <= '1';
|
||||
stage_next <= FETCH;
|
||||
-- Alignment Reset
|
||||
align_offset_next <= (others => '0');
|
||||
-- ###GENERATED START###
|
||||
decode_stage_next <= GET_ID;
|
||||
-- ###GENERATED END###
|
||||
if (opcode_latch = PUSH_DATA) then
|
||||
-- ###GENERATED START###
|
||||
decode_stage_next <= GET_ID;
|
||||
-- ###GENERATED END###
|
||||
else --(opcode_latch = PUSH_SERIALIZED_KEY)
|
||||
assert(opcode_latch = PUSH_SERIALIZED_KEY) severity FAILURE;
|
||||
-- ###GENERATED START###
|
||||
decode_stage_next <= GET_ID;
|
||||
-- ###GENERATED END###
|
||||
end if;
|
||||
when others =>
|
||||
-- Unknown Payload Encoding
|
||||
stage_next <= SKIP_PAYLOAD;
|
||||
@ -293,8 +304,8 @@ begin
|
||||
last_word_in_latch_next <= '0';
|
||||
end if;
|
||||
when DECODE_PAYLOAD =>
|
||||
-- ###GENERATED START###
|
||||
case (decode_stage) is
|
||||
-- ###GENERATED START###
|
||||
when GET_ID =>
|
||||
-- ALIGN GUARD
|
||||
-- DES: If ALIGN_8 is used, we have to to check the latched opcode and use ALIGN_4 if PUSH_SERIALIZED_KEY (since it uses PLAIN_CDR2 encoding)
|
||||
@ -463,6 +474,7 @@ begin
|
||||
decode_stage_next <= GET_TESTSEQUENCE_TESTARRAY;
|
||||
TestSequence_TestArray_cnt_next <= 0;
|
||||
end if;
|
||||
-- ###GENERATED END###
|
||||
when GET_OPTIONAL_HEADER =>
|
||||
-- ALIGN GUARD
|
||||
if (not check_align(align_offset, ALIGN_4)) then
|
||||
@ -516,7 +528,23 @@ begin
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
-- ###GENERATED END###
|
||||
when WRITE_PAYLOAD_HEADER =>
|
||||
valid_out <= '1';
|
||||
if (LITTLE_ENDIAN = '0') then
|
||||
data_out <= CDR_BE & x"0000";
|
||||
else
|
||||
data_out <= CDR_LE & x"0000";
|
||||
end if;
|
||||
-- Output Guard
|
||||
if (ready_out = '1') then
|
||||
stage_next <= ENCODE_PAYLOAD;
|
||||
-- Reset
|
||||
align_offset_next <= (others => '0');
|
||||
data_out_latch_next <= (others => '0');
|
||||
-- ###GENERATED START###
|
||||
encode_stage_next <= WRITE_ID;
|
||||
-- ###GENERATED END###
|
||||
end if;
|
||||
when PUSH =>
|
||||
-- Push to Key Hash Generator
|
||||
if (opcode_latch = READ_KEY_HASH) then
|
||||
@ -544,13 +572,14 @@ begin
|
||||
-- Reset
|
||||
finalize_payload_next <= '0';
|
||||
else
|
||||
stage_next <= SERIALIZE_KEY;
|
||||
stage_next <= ENCODE_PAYLOAD;
|
||||
end if;
|
||||
else
|
||||
cnt_2_next <= cnt_2 + 1;
|
||||
end if;
|
||||
end if;
|
||||
else
|
||||
else -- (opcode_latch = READ_SERIALIZED_KEY)
|
||||
assert(opcode_latch = READ_SERIALIZED_KEY) severity FAILURE;
|
||||
-- Mark Last Word
|
||||
if (finalize_payload = '1') then
|
||||
last_word_out <= '1';
|
||||
@ -572,7 +601,7 @@ begin
|
||||
finalize_payload_next <= '0';
|
||||
stage_next <= IDLE;
|
||||
else
|
||||
stage_next <= SERIALIZE_KEY;
|
||||
stage_next <= ENCODE_PAYLOAD;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
@ -580,7 +609,7 @@ begin
|
||||
-- Target Stream Alignment reached
|
||||
if (check_align(align_offset, target_align)) then
|
||||
-- DONE
|
||||
stage_next <= SERIALIZE_KEY;
|
||||
stage_next <= ENCODE_PAYLOAD;
|
||||
else
|
||||
align_offset_next <= align_offset + 1;
|
||||
-- Need to push Word
|
||||
@ -589,16 +618,16 @@ begin
|
||||
stage_next <= PUSH;
|
||||
end if;
|
||||
end if;
|
||||
when SERIALIZE_KEY =>
|
||||
-- ###GENERATED START###
|
||||
when ENCODE_PAYLOAD =>
|
||||
case (encode_stage) is
|
||||
-- ###GENERATED START###
|
||||
when WRITE_ID =>
|
||||
-- ALIGN GUARD
|
||||
if (not check_align(align_offset, ALIGN_4)) then
|
||||
target_align_next <= ALIGN_4;
|
||||
stage_next <= ALIGN_OUT_STREAM;
|
||||
else
|
||||
data_out_latch_next <= id_latch;
|
||||
data_out_latch_next <= endian_swap(endian_flag, id_latch);
|
||||
align_offset_next <= align_offset + 4;
|
||||
stage_next <= PUSH;
|
||||
-- Next Member
|
||||
@ -610,7 +639,7 @@ begin
|
||||
target_align_next <= ALIGN_4;
|
||||
stage_next <= ALIGN_OUT_STREAM;
|
||||
else
|
||||
data_out_latch_next <= std_logic_vector(resize(TestSequence_len_latch,WORD_WIDTH));
|
||||
data_out_latch_next <= endian_swap(endian_flag, std_logic_vector(resize(TestSequence_len_latch,WORD_WIDTH)));
|
||||
align_offset_next <= align_offset + 4;
|
||||
stage_next <= PUSH;
|
||||
|
||||
@ -648,7 +677,7 @@ begin
|
||||
TestSequence_TestArray_mem_ready_out(TestSequence_cnt) <= '1';
|
||||
-- Memory Operation Guard
|
||||
if (TestSequence_TestArray_mem_valid_out(TestSequence_cnt) = '1') then
|
||||
data_out_latch_next <= write_sub_vector(data_out_latch, TestSequence_TestArray_mem_data_out(TestSequence_cnt), to_integer(align_offset(1 downto 0)), TRUE);
|
||||
data_out_latch_next <= write_sub_vector(data_out_latch, endian_swap(endian_flag,TestSequence_TestArray_mem_data_out(TestSequence_cnt)), to_integer(align_offset(1 downto 0)), TRUE);
|
||||
align_offset_next <= align_offset + 1;
|
||||
cnt_next <= 0;
|
||||
|
||||
@ -681,8 +710,8 @@ begin
|
||||
TestSequence_TestArray_cnt_next <= 0;
|
||||
cnt_next <= 0;
|
||||
end if;
|
||||
-- ###GENERATED END###
|
||||
end case;
|
||||
-- ###GENERATED END###
|
||||
when GET_KEY_HASH =>
|
||||
if (done_kh = '1') then
|
||||
key_hash_next <= to_key_hash(key_hash_kh);
|
||||
|
||||
@ -510,15 +510,22 @@ begin
|
||||
-- ###GENERATED END###
|
||||
end if;
|
||||
when WRITE_PAYLOAD_HEADER =>
|
||||
valid_out_dds <= '1';
|
||||
if (LITTLE_ENDIAN = '0') then
|
||||
data_out_latch_next <= CDR_BE & x"0000";
|
||||
data_out_dds <= CDR_BE & x"0000";
|
||||
else
|
||||
data_out_latch_next <= CDR_LE & x"0000";
|
||||
data_out_dds <= CDR_LE & x"0000";
|
||||
end if;
|
||||
-- Output Guard
|
||||
if (ready_out_dds = '1') then
|
||||
stage_next <= ENCODE_PAYLOAD;
|
||||
-- Reset
|
||||
align_offset_next <= (others => '0');
|
||||
data_out_latch_next <= (others => '0');
|
||||
-- ###GENERATED START###
|
||||
encode_stage_next <= WRITE_ID;
|
||||
-- ###GENERATED END###
|
||||
end if;
|
||||
stage_next <= PUSH;
|
||||
-- ###GENERATED START###
|
||||
encode_stage_next <= WRITE_ID;
|
||||
-- ###GENERATED END###
|
||||
when PUSH =>
|
||||
-- Mark Last Word
|
||||
if (finalize_payload = '1') then
|
||||
|
||||
@ -9,6 +9,9 @@ use work.rtps_package.all;
|
||||
use work.rtps_config_package.all;
|
||||
|
||||
entity key_holder is
|
||||
generic (
|
||||
LITTLE_ENDIAN : std_logic := '0'
|
||||
);
|
||||
port (
|
||||
-- SYSTEM
|
||||
clk : in std_logic;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user