Add KEY_HOLDER implementation for TYPE2

This commit is contained in:
Greek 2021-11-05 17:45:16 +01:00
parent eef62e17ce
commit 57128bcea3
7 changed files with 819 additions and 199 deletions

View File

@ -0,0 +1,783 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.rtps_package.all;
use work.rtps_config_package.all;
use work.Type2_package.all;
architecture TYPE2 of key_holder is
--*****COMPONENT DECLARATION*****
component md5_calculator is
port (
clk : in std_logic;
reset : in std_logic;
start : in std_logic;
ack : out std_logic;
data_in : in std_logic_vector(7 downto 0);
valid_in : in std_logic;
ready_in : out std_logic;
last_word_in : in std_logic;
hash_out : out std_logic_vector(127 downto 0);
done : out std_logic
);
end component;
--*****TYPE DECLARATION*****
-- FSM states. Explained below in detail
type STAGE_TYPE is (IDLE,START_MD5_CALCULATION,GET_PAYLOAD_HEADER,FETCH,ALIGN_IN_STREAM,SKIP_PAYLOAD,DECODE_PAYLOAD,PUSH,ALIGN_OUT_STREAM,SERIALIZE_KEY,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);
type TESTSEQUENCE_TESTARRAY_ADDR_TYPE is array (0 to TESTSEQUENCE_MAX_DEPTH-1) of std_logic_vector(TESTSEQUENCE_TESTARRAY_ADDR_WIDTH-1 downto 0);
type TESTSEQUENCE_TESTARRAY_DATA_TYPE is array (0 to TESTSEQUENCE_MAX_DEPTH-1) of std_logic_vector(CDR_OCTET_WIDTH-1 downto 0);
-- ###GENERATED END###
-- *MAIN PROCESS*
signal stage, stage_next : STAGE_TYPE := IDLE;
signal cnt, cnt_next : natural range 0 to 5 := 0;
signal endian_flag, endian_flag_next : std_logic := '0';
signal last_word_in_latch, last_word_in_latch_next : std_logic := '0';
signal decode_error_latch, decode_error_latch_next : std_logic := '0';
signal align_offset, align_offset_next : unsigned(MAX_ALIGN_OFFSET_WIDTH-1 downto 0) := (others => '0');
signal target_align, target_align_next : ALIGN_TYPE := ALIGN_1;
signal data_in_latch, data_in_latch_next : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0');
signal data_out_latch, data_out_latch_next : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0');
signal optional, optional_next : std_logic := '0';
signal abort_mem : std_logic := '0';
signal opcode_latch, opcode_latch_next : KEY_HOLDER_OPCODE_TYPE := NOP;
signal cnt_2, cnt_2_next : natural range 0 to (WORD_WIDTH/BYTE_WIDTH)-1 := 0;
signal align_op, align_op_next : std_logic := '0';
signal finalize_payload, finalize_payload_next : std_logic := '0';
signal ready_in_sig : std_logic := '0';
-- ###GENERATED START###
signal start_md5, ack_md5, done_md5 : std_logic := '0';
signal data_in_md5 : std_logic_vector(BYTE_WIDTH-1 downto 0) := (others => '0');
signal valid_in_md5, ready_in_md5, last_word_in_md5 : std_logic := '0';
signal hash_out_md5 : std_logic_vector(KEY_HASH_WIDTH-1 downto 0) := (others => '0');
signal key_hash, key_hash_next : KEY_HASH_TYPE := HANDLE_NIL;
signal decode_stage, decode_stage_next : DECODE_STAGE_TYPE := GET_ID;
signal encode_stage, encode_stage_next : ENCODE_STAGE_TYPE := WRITE_ID;
signal return_stage, return_stage_next : DECODE_STAGE_TYPE := GET_ID;
signal id_latch, id_latch_next : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0');
signal TestSequence_cnt, TestSequence_cnt_next : natural range 0 to TESTSEQUENCE_MAX_DEPTH-1 := 0;
signal TestSequence_len_latch, TestSequence_len_latch_next : unsigned(TESTSEQUENCE_ADDR_WIDTH-1 downto 0) := (others => '0');
signal TestSequence_addr_latch, TestSequence_addr_latch_next : std_logic_vector(TESTSEQUENCE_ADDR_WIDTH-1 downto 0) := (others => '0');
signal TestSequence_TestArray_cnt, TestSequence_TestArray_cnt_next : natural range 0 to TESTSEQUENCE_TESTARRAY_MAX_DEPTH-1 := 0;
-- TestSequence_TestArray_mem SIGNALS
signal TestSequence_TestArray_mem_addr : TESTSEQUENCE_TESTARRAY_ADDR_TYPE := (others => (others => '0'));
signal TestSequence_TestArray_mem_read, TestSequence_TestArray_mem_ready_in, TestSequence_TestArray_mem_ready_out, TestSequence_TestArray_mem_valid_in, TestSequence_TestArray_mem_valid_out : std_logic_vector(0 to TESTSEQUENCE_TESTARRAY_MAX_DEPTH-1) := (others => '0');
signal TestSequence_TestArray_mem_data_in, TestSequence_TestArray_mem_data_out : TESTSEQUENCE_TESTARRAY_DATA_TYPE := (others => (others => '0'));
-- ###GENERATED END###
--*****ALIAS DECLARATION*****
alias representation_id : std_logic_vector(PAYLOAD_REPRESENTATION_ID_WIDTH-1 downto 0) is data_in(WORD_WIDTH-1 downto WORD_WIDTH-PAYLOAD_REPRESENTATION_ID_WIDTH);
alias representation_options : std_logic_vector(PAYLOAD_REPRESENTATION_ID_WIDTH-1 downto 0) is data_in(PAYLOAD_REPRESENTATION_OPTIONS_WIDTH-1 downto 0);
alias parameter_id : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) is data_in_latch(WORD_WIDTH-1 downto WORD_WIDTH-PARAMETER_ID_WIDTH);
alias parameter_length : std_logic_vector(PARAMETER_LENGTH_WIDTH-1 downto 0) is data_in_latch(PARAMETER_LENGTH_WIDTH-1 downto 0);
begin
-- ###GENERATED START###
TestSequence_TestArray_gen : for i in 0 to TESTSEQUENCE_MAX_DEPTH-1 generate
begin
TestSequence_TestArray_mem : entity work.mem_ctrl(arch)
generic map (
ADDR_WIDTH => TESTSEQUENCE_TESTARRAY_ADDR_WIDTH,
DATA_WIDTH => CDR_OCTET_WIDTH,
MEMORY_DEPTH => TESTSEQUENCE_TESTARRAY_MAX_DEPTH,
MAX_BURST_LENGTH => 1
)
port map (
clk => clk,
reset => reset or abort_mem,
addr => TestSequence_TestArray_mem_addr(i),
read => TestSequence_TestArray_mem_read(i),
ready_in => TestSequence_TestArray_mem_ready_in(i),
valid_in => TestSequence_TestArray_mem_valid_in(i),
data_in => TestSequence_TestArray_mem_data_in(i),
ready_out => TestSequence_TestArray_mem_ready_out(i),
valid_out => TestSequence_TestArray_mem_valid_out(i),
data_out => TestSequence_TestArray_mem_data_out(i)
);
end generate;
md5_calculator_inst : md5_calculator
port map (
clk => clk,
reset => reset,
start => start_md5,
ack => ack_md5,
data_in => data_in_md5,
valid_in => valid_in_md5,
ready_in => ready_in_md5,
last_word_in => last_word_in_md5,
hash_out => hash_out_md5,
done => done_md5
);
-- ###GENERATED END###
decode_error <= decode_error_latch;
ready_in <= ready_in_sig;
main_prc : process (all)
variable tmp_length : unsigned(WORD_WIDTH-1 downto 0) := (others => '0');
begin
-- DEFAULT
stage_next <= stage;
decode_stage_next <= decode_stage;
encode_stage_next <= encode_stage;
return_stage_next <= return_stage;
cnt_next <= cnt;
cnt_2_next <= cnt_2;
endian_flag_next <= endian_flag;
last_word_in_latch_next <= last_word_in_latch;
decode_error_latch_next <= decode_error_latch;
align_offset_next <= align_offset;
target_align_next <= target_align;
optional_next <= optional;
data_in_latch_next <= data_in_latch;
opcode_latch_next <= opcode_latch;
key_hash_next <= key_hash;
align_op_next <= align_op;
finalize_payload_next <= finalize_payload;
abort_mem <= '0';
ack <= '0';
ready_in_sig <= '0';
last_word_out <= '0';
valid_out <= '0';
data_out <= (others => '0');
-- ###GENERATED START###
id_latch_next <= id_latch;
TestSequence_len_latch_next <= TestSequence_len_latch;
TestSequence_cnt_next <= TestSequence_cnt;
TestSequence_TestArray_cnt_next <= TestSequence_TestArray_cnt;
TestSequence_addr_latch_next <= TestSequence_addr_latch;
TestSequence_TestArray_mem_addr <= (others => (others => '0'));
TestSequence_TestArray_mem_read <= (others => '0');
TestSequence_TestArray_mem_valid_in <= (others => '0');
TestSequence_TestArray_mem_ready_out <= (others => '0');
TestSequence_TestArray_mem_data_in <= (others => (others => '0'));
-- ###GENERATED END###
-- Last Word Latch Setter
if (last_word_in = '1') then
last_word_in_latch_next <= '1';
end if;
case (stage) is
when IDLE =>
-- Latch Opcode
opcode_latch_next <= opcode;
if (start = '1') then
case (opcode) is
when PUSH_DATA =>
ack <= '1';
stage_next <= GET_PAYLOAD_HEADER;
-- Reset
key_hash_next <= HANDLE_NIL;
when PUSH_SERIALIZED_KEY =>
ack <= '1';
-- Serialized Key is in PLAIN_CDR2 Big Endian encoding
endian_flag_next <= '0';
stage_next <= FETCH;
decode_stage_next <= GET_ID;
when READ_KEY_HASH =>
ack <= '1';
-- Key Hash not calculated
if (key_hash = HANDLE_NIL) then
-- DES: If MAX_TYPE2_KEY_HOLDER_SIZE is <= 16 we don't have to calculate the md5 (or even instantiate the md5_calculator at all)
stage_next <= START_MD5_CALCULATION;
else
stage_next <= PUSH_KEY_HASH;
cnt_next <= 0;
end if;
when READ_SERIALIZED_KEY =>
ack <= '1';
stage_next <= SERIALIZE_KEY;
encode_stage_next <= WRITE_ID;
when others =>
null;
end case;
end if;
when START_MD5_CALCULATION =>
start_md5 <= '1';
if (ack_md5 = '1') then
stage_next <= SERIALIZE_KEY;
encode_stage_next <= WRITE_ID;
end if;
when GET_PAYLOAD_HEADER =>
-- TODO: Latch Offset from Options Field?
ready_in_sig <= '1';
-- Input Guard
if (valid_in = '1') then
case (representation_id) is
when CDR_BE =>
endian_flag_next <= '0';
stage_next <= FETCH;
decode_stage_next <= GET_ID;
-- Alignment Reset
align_offset_next <= (others => '0');
-- Initial Fetch
when CDR_LE =>
endian_flag_next <= '1';
stage_next <= FETCH;
decode_stage_next <= GET_ID;
-- Alignment Reset
align_offset_next <= (others => '0');
when others =>
-- Unknown Payload Encoding
stage_next <= SKIP_PAYLOAD;
decode_error_latch_next <= '1';
end case;
end if;
when FETCH =>
ready_in_sig <= '1';
-- Input Guard
if (valid_in = '1') then
data_in_latch_next <= data_in;
-- Alignment Operation in progress
if (align_op = '1') then
stage_next <= ALIGN_IN_STREAM;
-- Reset
align_op_next <= '0';
else
stage_next <= DECODE_PAYLOAD;
end if;
end if;
when ALIGN_IN_STREAM =>
-- Target Stream Alignment reached
if (check_align(align_offset, target_align)) then
-- DONE
stage_next <= DECODE_PAYLOAD;
else
align_offset_next <= align_offset + 1;
-- Need to fetch new Input Word
if (align_offset(1 downto 0) = "11") then
align_op_next <= '1';
stage_next <= FETCH;
end if;
end if;
when SKIP_PAYLOAD =>
if (last_word_in_latch = '0' and last_word_in = '0') then
-- Skip Read
ready_in_sig <= '1';
else
stage_next <= IDLE;
-- Reset
last_word_in_latch_next <= '0';
end if;
when DECODE_PAYLOAD =>
-- ###GENERATED START###
case (decode_stage) is
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)
if (not check_align(align_offset, ALIGN_4)) then
target_align_next <= ALIGN_4;
stage_next <= ALIGN_IN_STREAM;
else
id_latch_next <= endian_swap(endian_flag, data_in_latch);
align_offset_next <= align_offset + 4;
stage_next <= FETCH;
-- Next Member
decode_stage_next <= GET_TESTSEQUENCE_LENGTH;
end if;
when GET_TESTSEQUENCE_LENGTH =>
-- ALIGN GUARD
if (not check_align(align_offset, ALIGN_4)) then
target_align_next <= ALIGN_4;
stage_next <= ALIGN_IN_STREAM;
else
tmp_length := unsigned(endian_swap(endian_flag, data_in_latch));
align_offset_next <= align_offset + 4;
stage_next <= FETCH;
-- Empty Sequence
if (tmp_length = 0) then
-- Next Member
stage_next <= SKIP_PAYLOAD;
else
decode_stage_next <= GET_TESTSEQUENCE_TESTARRAY;
TestSequence_len_latch_next <= resize(tmp_length, TestSequence_len_latch_next'length);
TestSequence_cnt_next <= 0;
-- DES: For array types the _cnt has to be initialized in the previous member stage
TestSequence_TestArray_cnt_next <= 0;
end if;
end if;
when GET_TESTSEQUENCE_TESTARRAY =>
-- ALIGN GUARD
if (not check_align(align_offset, ALIGN_1)) then
target_align_next <= ALIGN_1;
stage_next <= ALIGN_IN_STREAM;
else
TestSequence_TestArray_mem_addr(TestSequence_cnt) <= std_logic_vector(to_unsigned(TestSequence_TestArray_cnt,TestSequence_TestArray_mem_addr'length));
TestSequence_TestArray_mem_data_in(TestSequence_cnt) <= endian_swap(endian_flag, get_sub_vector(data_in_latch, to_integer(align_offset(1 downto 0)), CDR_OCTET_WIDTH, TRUE));
TestSequence_TestArray_mem_valid_in(TestSequence_cnt) <= '1';
-- Memory Operation Guard
if (TestSequence_TestArray_mem_ready_in(TestSequence_cnt) = '1') then
align_offset_next <= align_offset + 1;
-- All Elements processed
if (TestSequence_TestArray_cnt = TESTSEQUENCE_TESTARRAY_MAX_DEPTH-1) then
-- DES: The decoding stages are used for both PUSH_DATA and PUSH_SERIALIZED_KEY.
-- We us the latched opcode to differentiate between them.
if (opcode_latch = READ_SERIALIZED_KEY) then
decode_stage_next <= TESTSEQUENCE_MEMBER_END;
else
decode_stage_next <= GET_TESTSEQUENCE_TESTCHAR;
end if;
else
TestSequence_TestArray_cnt_next <= TestSequence_TestArray_cnt + 1;
end if;
-- DES: Needed for ALIGN_1
-- Need to fetch next Word
if(align_offset(1 downto 0) = "11") then
stage_next <= FETCH;
end if;
end if;
end if;
when GET_TESTSEQUENCE_TESTCHAR =>
-- ALIGN GUARD
if (not check_align(align_offset, ALIGN_1)) then
target_align_next <= ALIGN_1;
stage_next <= ALIGN_IN_STREAM;
else
align_offset_next <= align_offset + 1;
decode_stage_next <= GET_TESTSEQUENCE_TESTWCHAR;
-- Need to fetch next Word
if(align_offset(1 downto 0) = "11") then
stage_next <= FETCH;
end if;
end if;
when GET_TESTSEQUENCE_TESTWCHAR =>
-- ALIGN GUARD
if (not check_align(align_offset, ALIGN_2)) then
target_align_next <= ALIGN_2;
stage_next <= ALIGN_IN_STREAM;
else
align_offset_next <= align_offset + 2;
decode_stage_next <= GET_TESTSEQUENCE_TESTLONGLONG;
cnt_next <= 0;
-- DES: Needed for ALIGN_2
-- Need to fetch next Word
if(align_offset(1) = '1') then
stage_next <= FETCH;
end if;
end if;
when GET_TESTSEQUENCE_TESTLONGLONG =>
-- ALIGN GUARD
if (not check_align(align_offset, ALIGN_8)) then
target_align_next <= ALIGN_8;
stage_next <= ALIGN_IN_STREAM;
else
case (cnt) is
-- Double Word 1/2
when 0 =>
stage_next <= FETCH;
cnt_next <= cnt + 1;
-- Double Word 2/2
when 1 =>
stage_next <= FETCH;
cnt_next <= cnt + 1;
-- Push Double Word
when 2 =>
align_offset_next <= align_offset + 8;
decode_stage_next <= GET_OPTIONAL_HEADER;
return_stage_next <= GET_TESTSEQUENCE_TESTLONGDOUBLE;
cnt_next <= 0;
when others =>
null;
end case;
end if;
when GET_TESTSEQUENCE_TESTLONGDOUBLE =>
-- Optional Omitted
if (optional = '0') then
decode_stage_next <= TESTSEQUENCE_MEMBER_END;
-- ALIGN GUARD
elsif (not check_align(align_offset, ALIGN_8)) then
target_align_next <= ALIGN_8;
stage_next <= ALIGN_IN_STREAM;
else
case (cnt) is
-- Quad Word 1/4
when 0 =>
stage_next <= FETCH;
cnt_next <= cnt + 1;
-- Quad Word 2/4
when 1 =>
stage_next <= FETCH;
cnt_next <= cnt + 1;
-- Quad Word 3/4
when 2 =>
stage_next <= FETCH;
cnt_next <= cnt + 1;
-- Quad Word 4/4
when 3 =>
stage_next <= FETCH;
cnt_next <= cnt + 1;
-- Push Quad Word
when 4 =>
align_offset_next <= align_offset + 16;
decode_stage_next <= TESTSEQUENCE_MEMBER_END;
when others =>
null;
end case;
end if;
-- DES: If the elements of an array/sequence are of a complex/nested type, the array/sequence iteration check is done in a seperate *_MEMBER_END stage.
when TESTSEQUENCE_MEMBER_END =>
-- All Elements processed
if (TestSequence_cnt = TestSequence_len_latch-1) then
-- Next Member
stage_next <= SKIP_PAYLOAD;
else
TestSequence_cnt_next <= TestSequence_cnt + 1;
decode_stage_next <= GET_TESTSEQUENCE_TESTARRAY;
TestSequence_TestArray_cnt_next <= 0;
end if;
when GET_OPTIONAL_HEADER =>
-- ALIGN GUARD
if (not check_align(align_offset, ALIGN_4)) then
target_align_next <= ALIGN_4;
stage_next <= ALIGN_IN_STREAM;
else
case (cnt) is
-- Optional Member Header
when 0 =>
-- Extended Parameter Header
if (endian_swap(endian_flag,parameter_id) = PID_EXTENDED) then
cnt_next <= cnt + 1;
stage_next <= FETCH;
else
stage_next <= FETCH;
decode_stage_next <= return_stage;
cnt_next <= 0;
-- Alignment Reset
align_offset_next <= (others => '0');
-- Optional omitted
if(endian_swap(endian_flag,parameter_length) = (parameter_length'reverse_range => '0')) then
optional_next <= '0';
else
optional_next <= '1';
end if;
end if;
-- eMemberHeader
when 1 =>
-- Ignore Parameter ID
cnt_next <= cnt + 1;
stage_next <= FETCH;
-- Llength
when 2 =>
stage_next <= FETCH;
decode_stage_next <= return_stage;
cnt_next <= 0;
-- Alignment Reset
align_offset_next <= (others => '0');
-- Optional omitted
if(endian_swap(endian_flag, data_in) = (data_in'reverse_range => '0')) then
optional_next <= '0';
else
optional_next <= '1';
end if;
when others =>
null;
end case;
end if;
when others =>
null;
end case;
-- ###GENERATED END###
when PUSH =>
-- Push to MD5 Calculator
if (opcode_latch = READ_KEY_HASH) then
-- Mark Last Word
if (finalize_payload = '1' and cnt_2 = to_integer(unsigned(align_offset(1 downto 0)))) then
last_word_out <= '1';
end if;
valid_in_md5 <= '1';
data_in_md5 <= get_sub_vector(data_out_latch, cnt_2, BYTE_WIDTH, TRUE);
-- Output Guard
if (ready_in_md5 = '1') then
-- Last Byte
if ((finalize_payload = '1' and cnt_2 = to_integer(unsigned(align_offset(1 downto 0)))) or cnt_2 = (WORD_WIDTH/BYTE_WIDTH)-1) then
-- Reset
cnt_2_next <= 0;
-- Alignment Operation in process
if (align_op = '1') then
stage_next <= ALIGN_OUT_STREAM;
-- Reset
align_op_next <= '0';
-- DONE
elsif (finalize_payload = '1') then
stage_next <= GET_KEY_HASH;
-- Reset
finalize_payload_next <= '0';
else
stage_next <= SERIALIZE_KEY;
end if;
else
cnt_2_next <= cnt_2 + 1;
end if;
end if;
else
-- Mark Last Word
if (finalize_payload = '1') then
last_word_out <= '1';
end if;
valid_out <= '1';
data_out <= data_out_latch;
-- Output Guard
if (ready_out = '1') then
-- NOTE: Ensures all padding is zero.
data_out_latch_next <= (others => '0');
-- Alignment Operation in process
if (align_op = '1') then
stage_next <= ALIGN_OUT_STREAM;
-- Reset
align_op_next <= '0';
-- DONE
elsif (finalize_payload = '1') then
finalize_payload_next <= '0';
stage_next <= IDLE;
else
stage_next <= SERIALIZE_KEY;
end if;
end if;
end if;
when ALIGN_OUT_STREAM =>
-- Target Stream Alignment reached
if (check_align(align_offset, target_align)) then
-- DONE
stage_next <= SERIALIZE_KEY;
else
align_offset_next <= align_offset + 1;
-- Need to push Word
if (align_offset(1 downto 0) = "11") then
align_op_next <= '1';
stage_next <= PUSH;
end if;
end if;
when SERIALIZE_KEY =>
-- ###GENERATED START###
case (encode_stage) is
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;
align_offset_next <= align_offset + 4;
stage_next <= PUSH;
-- Next Member
encode_stage_next <= WRITE_TESTSEQUENCE_LENGTH;
end if;
when WRITE_TESTSEQUENCE_LENGTH =>
-- 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 <= std_logic_vector(resize(TestSequence_len_latch,WORD_WIDTH));
align_offset_next <= align_offset + 4;
stage_next <= PUSH;
-- Empty Sequence
if (unsigned(TestSequence_len_latch) = 0) then
-- DONE
stage_next <= PUSH;
finalize_payload_next <= '1';
else
encode_stage_next <= WRITE_TESTSEQUENCE_TESTARRAY;
cnt_next <= 0;
TestSequence_cnt_next <= 0;
-- DES: For array types the _cnt has to be initialized in the previous member stage
TestSequence_TestArray_cnt_next <= 0;
end if;
end if;
when WRITE_TESTSEQUENCE_TESTARRAY =>
-- ALIGN GUARD
if (not check_align(align_offset, ALIGN_1)) then
target_align_next <= ALIGN_1;
stage_next <= ALIGN_OUT_STREAM;
else
case (cnt) is
-- GET
when 0 =>
TestSequence_TestArray_mem_addr(TestSequence_cnt) <= std_logic_vector(to_unsigned(TestSequence_TestArray_cnt,TestSequence_TestArray_mem_addr'length));
TestSequence_TestArray_mem_valid_in(TestSequence_cnt) <= '1';
TestSequence_TestArray_mem_read(TestSequence_cnt) <= '1';
-- Memory Operation Guard
if (TestSequence_TestArray_mem_ready_in(TestSequence_cnt) = '1') then
cnt_next <= cnt + 1;
end if;
-- WRITE
when 1 =>
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);
align_offset_next <= align_offset + 1;
cnt_next <= 0;
-- All Elements processed
if (TestSequence_TestArray_cnt = TESTSEQUENCE_TESTARRAY_MAX_DEPTH-1) then
-- DONE
stage_next <= PUSH;
finalize_payload_next <= '1';
else
TestSequence_TestArray_cnt_next <= TestSequence_TestArray_cnt + 1;
end if;
-- DES: Needed for ALIGN_1
-- Need to fetch next Word
if(align_offset(1 downto 0) = "11") then
stage_next <= PUSH;
end if;
end if;
when others =>
end case;
end if;
when TESTSEQUENCE_MEMBER_END =>
-- All Elements processed
if (TestSequence_cnt = unsigned(TestSequence_len_latch)-1) then
-- DONE
stage_next <= PUSH;
finalize_payload_next <= '1';
else
TestSequence_cnt_next <= TestSequence_cnt + 1;
encode_stage_next <= WRITE_TESTSEQUENCE_TESTARRAY;
TestSequence_TestArray_cnt_next <= 0;
cnt_next <= 0;
end if;
end case;
-- ###GENERATED END###
when GET_KEY_HASH =>
if (done_md5 = '1') then
key_hash_next <= to_key_hash(hash_out_md5);
stage_next <= PUSH_KEY_HASH;
cnt_next <= 0;
end if;
when PUSH_KEY_HASH =>
case (cnt) is
-- Key Hash 1/4
when 0 =>
data_out <= key_hash(0);
valid_out <= '1';
-- Output Guard
if (ready_out = '1') then
cnt_next <= cnt + 1;
end if;
-- Key Hash 2/4
when 1 =>
data_out <= key_hash(1);
valid_out <= '1';
-- Output Guard
if (ready_out = '1') then
cnt_next <= cnt + 1;
end if;
-- Key Hash 3/4
when 2 =>
data_out <= key_hash(2);
valid_out <= '1';
-- Output Guard
if (ready_out = '1') then
cnt_next <= cnt + 1;
end if;
-- Key Hash 4/4
when 3 =>
data_out <= key_hash(3);
valid_out <= '1';
last_word_out <= '1';
-- Output Guard
if (ready_out = '1') then
-- DONE
stage_next <= IDLE;
end if;
when others =>
null;
end case;
when others =>
null;
end case;
-- OVERREAD GUARD
-- Attempted read on empty input
if (last_word_in_latch = '1' and ready_in_sig = '1') then
stage_next <= SKIP_PAYLOAD;
decode_error_latch_next <= '1';
end if;
end process;
sync_prc : process(clk)
begin
if rising_edge(clk) then
if (reset = '1') then
stage <= IDLE;
decode_stage <= GET_ID;
encode_stage <= WRITE_ID;
return_stage <= GET_ID;
target_align <= ALIGN_1;
opcode_latch <= NOP;
cnt <= 0;
cnt_2 <= 0;
endian_flag <= '0';
last_word_in_latch <= '0';
decode_error <= '0';
optional <= '0';
align_op <= '0';
finalize_payload <= '0';
align_offset <= (others => '0');
data_in_latch <= (others => '0');
key_hash <= HANDLE_NIL;
-- ###GENERATED START###
id_latch <= (others => '0');
TestSequence_len_latch <= (others => '0');
TestSequence_cnt <= 0;
TestSequence_TestArray_cnt <= 0;
-- ###GENERATED END###
else
stage <= stage_next;
decode_stage <= decode_stage_next;
encode_stage <= encode_stage_next;
return_stage <= return_stage_next;
target_align <= target_align_next;
opcode_latch <= opcode_latch_next;
cnt <= cnt_next;
cnt_2 <= cnt_2_next;
endian_flag <= endian_flag_next;
last_word_in_latch <= last_word_in_latch_next;
decode_error <= decode_error_latch_next;
optional <= optional_next;
align_op <= align_op_next;
finalize_payload <= finalize_payload_next;
align_offset <= align_offset_next;
data_in_latch <= data_in_latch_next;
key_hash <= key_hash_next;
-- ###GENERATED START###
id_latch <= id_latch_next;
TestSequence_len_latch <= TestSequence_len_latch_next;
TestSequence_cnt <= TestSequence_cnt_next;
TestSequence_TestArray_cnt <= TestSequence_TestArray_cnt_next;
-- ###GENERATED END###
end if;
end if;
end process;
end architecture;

View File

@ -1,24 +0,0 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity key_generator is
port (
clk : in std_logic;
reset : in std_logic;
start : in std_logic;
opcode : in KEY_GENERATOR_OPCODE_TYPE;
busy : out std_logic;
data_in : in std_logic_vector(WORD_WIDTH-1 downto 0);
valid_in : in std_logic;
ready_in : out std_logic;
last_word_in : in std_logic;
data_out : out std_logic_vector(WORD_WIDTH-1 downto 0);
valid_out : out std_logic;
ready_out : in std_logic;
last_word_out : out std_logic
);
end entity;

View File

@ -1,148 +0,0 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity key_hash_generator is
port (
clk : in std_logic;
reset : in std_logic;
data_in : in std_logic_vector(WORD_WIDTH-1 downto 0);
valid_in : in std_logic;
ready_in : out std_logic;
last_word_in : in std_logic;
data_out : out std_logic_vector(WORD_WIDTH-1 downto 0);
valid_out : out std_logic;
ready_out : in std_logic;
last_word_out : out std_logic
);
end entity;
architecture arch of key_hash_generator is
--*****CONSTANT DECLARATION*****
constant KEY_SIZE : natural := TODO;
--*****TYPE DECLARATION*****
type STAGE_TYPE is (IDLE, TODO);
--*****SIGNAL DECLARATION*****
signal key_gen_start, key_gen_busy, key_gen_valid_in, key_gen_ready_in, key_gen_last_word_in, key_gen_valid_out, key_gen_ready_out, key_gen_last_word_out : std_logic := '0';
signal key_gen_opcode : KEY_GENERATOR_OPCODE_TYPE := NOP;
signal key_gen_data_in, key_gen_data_out : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0');
signal stage, stage_next : STAGE_TYPE := IDLE;
signal key_hash, key_hash_next : KEY_HASH_TYPE := (others => (others => '0'));
signal cnt, cnt_next : natural range 0 to KEY_HASH_TYPE'length-1 := 0;
begin
key_generator_inst : entity work.key_generator(arch)
port map(
clk => clk,
reset => reset,
start => key_gen_start,
opcode => key_gen_opcode,
busy => key_gen_busy,
data_in => key_gen_data_in,
valid_in => key_gen_valid_in,
ready_in => key_gen_ready_in,
last_word_in => key_gen_last_word_in,
data_out => key_gen_data_out,
valid_out => key_gen_valid_out,
ready_out => key_gen_ready_out,
last_word_out => key_gen_last_word_out
);
main_prc : process (all)
begin
-- DEFAULT
stage_next <= stage;
key_hash_next <= key_hash;
cnt_next <= cnt;
ready_in <= '0';
key_gen_start <= '0';
key_gen_valid_in <= '0';
key_gen_last_word_in <= '0';
key_gen_data_in <= (others => '0');
key_gen_ready_out <= '0';
valid_out <= '0';
last_word_out <= '0';
data_out <= (others => '0');
case (stage) is
when IDLE =>
if (valid_in = '1' and key_gen_busy = '0') then
key_gen_start <= '1';
key_gen_opcode <= WRITE_PAYLOAD;
stage_next <= PASSTHROUGH_PAYLOAD;
end if;
when PASSTHROUGH_PAYLOAD =>
-- TODO: Connect directly to key_generator?
ready_in <= key_gen_ready_in;
key_gen_valid_in <= valid_in;
key_gen_data_in <= data_in;
key_gen_last_word_in <= last_word_in;
-- Exit Condition
if (last_word_in = '1') then
stage_next <= GET_SIZE;
end if;
when GET_SIZE =>
if (key_gen_busy = '0') then
key_gen_start <= '1';
key_gen_opcode <= READ_SIZE;
stage_next <= READ_SIZE;
end if;
when READ_SIZE =>
key_gen_ready_out <= '1';
if (key_gen_valid_out = '1') then
if (unsigned(key_gen_data_out)) > (KEY_HASH_WIDTH/BYTE_WIDTH)) then
-- TODO: MD5 Calculation
assert FALSE report "MD5 Key hash generation not yet implemented." severity FAILURE;
else
stage_next <= GET_KEY_HASH;
end if;
end if;
when GET_KEY_HASH =>
if (key_gen_busy = '0') then
key_gen_start <= '1';
key_gen_opcode <= READ_KEY;
stage_next <= WRITE_KEY_HASH;
cnt_next <= 0;
key_hash_next <= (others => (others => '0'));
end if;
when WRITE_KEY_HASH =>
key_gen_ready_out <= '1';
if (key_gen_valid_out) then
cnt_next <= cnt + 1;
key_hash_next(cnt) <= key_gen_data_out;
if (key_gen_last_word_out = '1') then
stage_next <= FINISHED_KEY_HASH;
cnt_next <= 0;
end if;
end if;
when FINISHED_KEY_HASH =>
valid_out <= '1';
if (ready_out = '1') then
cnt_next <= cnt + 1;
data_out <= key_hash(cnt);
if (cnt = key_hash'length-1) then
last_word_out <= '1';
-- DONE
stage_next <= IDLE;
end if;
end if;
when others =>
null;
end case;
end process;
end architecture;

View File

@ -8,8 +8,9 @@ entity key_holder is
reset : in std_logic;
start : in std_logic;
opcode : in KEY_HOLDER_TYPE;
ack : in std_logic;
opcode : in KEY_HOLDER_OPCODE_TYPE;
ack : out std_logic;
decode_error : out std_logic;
data_in : in std_logic_vector(WORD_WIDTH-1 downto 0);
valid_in : in std_logic;

21
src/md5_calculator.vhd Normal file
View File

@ -0,0 +1,21 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity md5_calculator is
port (
clk : in std_logic;
reset : in std_logic;
start : in std_logic;
ack : out std_logic;
data_in : in std_logic_vector(7 downto 0);
valid_in : in std_logic;
ready_in : out std_logic;
last_word_in : in std_logic;
hash_out : out std_logic_vector(127 downto 0);
done : out std_logic;
);
end entity;

View File

@ -463,6 +463,7 @@ package rtps_package is
function to_guid(A : GUIDPREFIX_TYPE; B : std_logic_vector(ENTITYID_WIDTH-1 downto 0)) return GUID_TYPE;
function to_key_hash(A : GUID_TYPE) return KEY_HASH_TYPE;
function to_key_hash(A : std_logic_vector) return KEY_HASH_TYPE;
-- *OVERLOAD FUNCTIONS*
function to_unsigned (input: DOUBLE_WORD_ARRAY) return unsigned;
@ -709,6 +710,16 @@ package body rtps_package is
return ret;
end function;
function to_key_hash (A : std_logic_vector) return KEY_HASH_TYPE is
variable ret : KEY_HASH_TYPE := HANDLE_NIL;
begin
assert (A'length = KEY_HASH_WIDTH) severity FAILURE;
for i in 0 to KEY_HASH_TYPE'length-1 loop
ret(i) := A(((i+1)*WORD_WIDTH)-1 downto i*WORD_WIDTH);
end loop;
return ret;
end function;
function to_unsigned(input : KEY_HASH_TYPE) return unsigned is
variable ret : unsigned(KEY_HASH_WIDTH-1 downto 0) := (others => '0');
begin

View File

@ -1,24 +0,0 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity serialized_key_generator is
port (
clk : in std_logic;
reset : in std_logic;
start : in std_logic;
opcode : in KEY_GENERATOR_OPCODE_TYPE;
busy : out std_logic;
data_in : in std_logic_vector(WORD_WIDTH-1 downto 0);
valid_in : in std_logic;
ready_in : out std_logic;
last_word_in : in std_logic;
data_out : out std_logic_vector(WORD_WIDTH-1 downto 0);
valid_out : out std_logic;
ready_out : in std_logic;
last_word_out : out std_logic
);
end entity;