-- altera vhdl_input_version vhdl_2008 -- XXX: QSYS Fix (https://www.intel.com/content/www/us/en/support/programmable/articles/000079458.html) library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.rtps_package.all; use work.rtps_config_package.all; architecture TYPENAME of key_holder is --*****COMPONENT DECLARATION***** component key_hash_generator 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; key_hash : 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_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); -- TYPES DECLARATIONS -- ###GENERATED END### -- *MAIN PROCESS* signal stage, stage_next : STAGE_TYPE; signal cnt, cnt_next : natural range 0 to 5; signal endian_flag, endian_flag_next : std_logic; signal last_word_in_latch, last_word_in_latch_next : std_logic; signal decode_error_latch, decode_error_latch_next : std_logic; signal align_offset, align_offset_next : unsigned(MAX_ALIGN_OFFSET_WIDTH-1 downto 0); signal target_align, target_align_next : ALIGN_TYPE; signal data_in_latch, data_in_latch_next : std_logic_vector(WORD_WIDTH-1 downto 0); signal data_out_latch, data_out_latch_next : std_logic_vector(WORD_WIDTH-1 downto 0); signal optional, optional_next : std_logic; signal abort_mem : std_logic; 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 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); signal valid_in_kh, ready_in_kh, last_word_in_kh : std_logic; signal key_hash_kh : std_logic_vector(KEY_HASH_WIDTH-1 downto 0); signal key_hash, key_hash_next : KEY_HASH_TYPE; signal decode_stage, decode_stage_next : DECODE_STAGE_TYPE; signal encode_stage, encode_stage_next : ENCODE_STAGE_TYPE; signal return_stage, return_stage_next : DECODE_STAGE_TYPE; -- ###GENERATED START### -- SIGNAL DECLARATION -- ###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 key_hash_generator_inst : key_hash_generator port map ( clk => clk, reset => reset, start => start_kh, ack => ack_kh, data_in => data_in_kh, valid_in => valid_in_kh, ready_in => ready_in_kh, last_word_in => last_word_in_kh, key_hash => key_hash_kh, done => done_kh ); -- ###GENERATED START### -- MEMORY INSTANTIATIONS -- ###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); variable cnt2_ref : std_logic_vector(1 downto 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; data_out_latch_next <= data_out_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'; start_kh <= '0'; valid_in_kh <= '0'; last_word_in_kh <= '0'; data_in_kh <= (others => '0'); data_out <= (others => '0'); -- ###GENERATED START### -- DEFAULT SIGNAL ASSIGNMENTS -- ###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 <= KEY_HASH_NIL; when PUSH_SERIALIZED_KEY => ack <= '1'; stage_next <= GET_PAYLOAD_HEADER; -- Reset key_hash_next <= KEY_HASH_NIL; when READ_KEY_HASH => ack <= '1'; -- Key Hash not calculated if (key_hash = KEY_HASH_NIL) then stage_next <= START_KEY_HASH_GENERATION; else stage_next <= PUSH_KEY_HASH; cnt_next <= 0; end if; when READ_SERIALIZED_KEY => ack <= '1'; endian_flag_next <= LITTLE_ENDIAN; stage_next <= WRITE_PAYLOAD_HEADER; when others => null; end case; end if; when START_KEY_HASH_GENERATION => start_kh <= '1'; -- 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 <= ENCODE_PAYLOAD; -- ###GENERATED START### encode_stage_next <= TODO; -- ###GENERATED START### 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; -- Alignment Reset align_offset_next <= (others => '0'); 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'); 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; 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') then -- Skip Read ready_in_sig <= '1'; else stage_next <= IDLE; -- Reset last_word_in_latch_next <= '0'; end if; when DECODE_PAYLOAD => case (decode_stage) is -- ###GENERATED START### when TODO => -- ###GENERATED END### 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; 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 -- XXX: Assumes data_out_latch is 32 bits (TODO) cnt2_ref := std_logic_vector(unsigned(align_offset(1 downto 0)) - to_unsigned(1,2)); -- Mark Last Word if (finalize_payload = '1' and cnt_2 = to_integer(unsigned(cnt2_ref))) then last_word_in_kh <= '1'; end if; valid_in_kh <= '1'; data_in_kh <= get_sub_vector(data_out_latch, cnt_2, BYTE_WIDTH, TRUE); -- Output Guard if (ready_in_kh = '1') then -- Last Byte if (cnt_2 = to_integer(unsigned(cnt2_ref))) 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 <= ENCODE_PAYLOAD; end if; else cnt_2_next <= cnt_2 + 1; end if; end if; 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'; 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 <= ENCODE_PAYLOAD; 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 <= ENCODE_PAYLOAD; 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 ENCODE_PAYLOAD => case (encode_stage) is -- ###GENERATED START### when TODO => -- ###GENERATED END### end case; when GET_KEY_HASH => if (done_kh = '1') then key_hash_next <= to_key_hash(key_hash_kh); 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; -- ABORT if (abort = '1' and stage /= IDLE) then stage_next <= IDLE; -- Reset last_word_in_latch_next <= '0'; align_op_next <= '0'; finalize_payload_next <= '0'; -- OVERREAD GUARD -- Attempted read on empty input elsif (last_word_in_latch = '1' and last_word_in = '0' 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 <= TODO; encode_stage <= TODO; return_stage <= TODO; target_align <= ALIGN_1; opcode_latch <= NOP; cnt <= 0; cnt_2 <= 0; endian_flag <= '0'; last_word_in_latch <= '0'; decode_error_latch <= '0'; optional <= '0'; align_op <= '0'; finalize_payload <= '0'; align_offset <= (others => '0'); data_in_latch <= (others => '0'); data_out_latch <= (others => '0'); key_hash <= KEY_HASH_NIL; -- ###GENERATED START### -- RESET SYNC SIGNAL VALUE -- ###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_latch <= 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; data_out_latch <= data_out_latch_next; key_hash <= key_hash_next; -- ###GENERATED START### -- SYNC SIGNALS -- ###GENERATED END### end if; end if; end process; end architecture;