diff --git a/src/Tests/Type2.idl b/src/Tests/Type2.idl new file mode 100644 index 0000000..231755f --- /dev/null +++ b/src/Tests/Type2.idl @@ -0,0 +1,61 @@ +@extensibility(FINAL) @nested +union TestUnion_t switch (char) { + case 'a': + long LongU; + default: + octet OctetU; +}; + +@bit_bound(9) +bitmask TestBitmask_t { + @position(0) POS1, + @position(3) POS3, + @position(4) POS4 +}; + +@bit_bound(7) +enum TestEnum_t { + A, + B, + C, + D +}; + +typedef octet TestArray_t[5]; + +@extensibility(FINAL) @nested +struct NestedStruct_t { + @key TestArray_t TestArray; + char TestChar; + wchar TestWChar; + long long TestLongLong; + @optional long double TestLongDouble; +}; + +typedef sequence TestSequence_t; +typedef string<12> TestString_t; +typedef TestMap_t map; + +@extensibility(FINAL) @topic +struct Type2 { + @key long id; + @key TestSequence_t TestSequence; + TestMap_t TestMap; + TestEnum_t TestEnum; + @optional TestUnion_t TestUnion; + TestBitmask_t TestBitmask + TestString_t TestString; +}; + +@final +struct NestedStruct_tKeyHolder { + TestArray_t TestArray; +}; + +typedef sequence TestSequence_tKeyHolder; + +@final +struct Type2KeyHolder { + long id; + TestSequence_tKeyHolder TestSequence; +}; \ No newline at end of file diff --git a/src/Tests/Type2_package.vhd b/src/Tests/Type2_package.vhd new file mode 100644 index 0000000..a469d39 --- /dev/null +++ b/src/Tests/Type2_package.vhd @@ -0,0 +1,87 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.rtps_package.all; +use work.math_pkg.all; + +package Type2_package is + + + + constant TESTSEQUENCE_MAX_DEPTH : natural := 4; + constant TESTSEQUENCE_ADDR_WIDTH : natural := log2c(TESTSEQUENCE_MAX_DEPTH); + constant TESTSEQUENCE_TESTARRAY_MAX_DEPTH : natural := 5; + constant TESTSEQUENCE_TESTARRAY_ADDR_WIDTH : natural := log2c(TESTSEQUENCE_TESTARRAY_MAX_DEPTH); + constant TESTSTRING_MAX_DEPTH : natural := 12; + constant TESTSTRING_ADDR_WIDTH : natural := log2c(TESTSTRING_MAX_DEPTH); + constant TESTMAP_MAX_DEPTH : natural := 4; + constant TESTMAP_ADDR_WIDTH : natural := log2c(TESTMAP_MAX_DEPTH); + + constant TESTUNION_LONGU_D : std_logic_vector(CDR_CHAR_WIDTH-1 downto 0) := x"61"; + + constant TESTBITMASK_WIDTH : natural := 9; + constant TESTBITMASK_CDR_WIDTH : natural := CDR_SHORT_WIDTH; + constant TESTBITMASK_POS1 : natural := 0; + constant TESTBITMASK_POS3 : natural := 3; + constant TESTBITMASK_POS4 : natural := 4; + + constant TESTENUM_WIDTH : natural := 7; + constant TESTENUM_CDR_WIDTH : natural := CDR_INT8_WIDTH; + constant TESTENUM_A : std_logic_vector(TESTENUM_WIDTH-1 downto 0) := "0000001"; + constant TESTENUM_B : std_logic_vector(TESTENUM_WIDTH-1 downto 0) := "0000010"; + constant TESTENUM_C : std_logic_vector(TESTENUM_WIDTH-1 downto 0) := "0000011"; + constant TESTENUM_D : std_logic_vector(TESTENUM_WIDTH-1 downto 0) := "0000100"; + + constant MAX_ID_SIZE : natural := 4; + constant MAX_TESTSEQUENCE_TESTARRAY_SIZE : natural := 5; + constant MAX_TESTSEQUENCE_TESTCHAR_SIZE : natural := 1; + constant MAX_TESTSEQUENCE_TESTWCHAR_SIZE : natural := 2; + constant MAX_TESTSEQUENCE_TESTLONGLONG_SIZE : natural := 8; + constant MAX_TESTSEQUENCE_TESTLONGDOUBLE_SIZE : natural := 20; + constant MAX_TESTSEQUENCE_SIZE : natural := 148; -- 152 + constant MAX_TESTMAP_SIZE : natural := 20; -- 172 + constant MAX_TESTENUM_SIZE : natural := 1; -- 173 + constant MAX_TESTUNION_SIZE : natural := 7; -- 180 + constant MAX_TESTBITMASK_SIZE : natural := 4; -- 184 + constant MAX_TESTSTRING_SIZE : natural := 17; -- 201 + constant MAX_TYPE2_SIZE : natural := 201; + + constant MAX_TYPE2_KEY_HOLDER_SIZE : natural := 28; + + -- TODO: + constant MAX_ALIGN_OFFSET_WIDTH : natural := 3; + type ALIGN_TYPE is (ALIGN_1, ALIGN_2, ALIGN_4, ALIGN_8); + + function check_align(offset : unsigned; align : ALIGN_TYPE) return boolean; + +end package; + +package body Type2_package is + + function check_align(offset : unsigned; align : ALIGN_TYPE) return boolean is + variable ret : boolean := FALSE; + begin + assert (offset'length = MAX_ALIGN_OFFSET_WIDTH) severity FAILURE; + + case (align) is + when ALIGN_1 => + ret := TRUE; + when ALIGN_2 => + if (offset(0 downto 0) = "0") then + ret := TRUE; + end if; + when ALIGN_4 => + if (offset(1 downto 0) = "00") then + ret := TRUE; + end if; + when ALIGN_8 => + if (offset(2 downto 0) = "000") then + ret := TRUE; + end if; + end case; + + return ret; + end function; + +end package body; \ No newline at end of file diff --git a/src/Tests/Type2_reader_wrapper.vhd b/src/Tests/Type2_reader_wrapper.vhd new file mode 100644 index 0000000..d4749d5 --- /dev/null +++ b/src/Tests/Type2_reader_wrapper.vhd @@ -0,0 +1,1151 @@ +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; + +entity Type2_reader_wrapper is + port ( + -- SYSTEM + clk : in std_logic; + reset : in std_logic; + -- FROM DDS READER + start_dds : out std_logic; + ack_dds : in std_logic; + opcode_dds : out DDS_READER_OPCODE_TYPE; + instance_state_dds : out std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); + view_state_dds : out std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0); + sample_state_dds : out std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0); + instance_handle_dds : out INSTANCE_HANDLE_TYPE; + max_samples_dds : out std_logic_vector(MAX_SAMPLES_WIDTH-1 downto 0); + get_data_dds : out std_logic; + done_dds : in std_logic; + return_code_dds : in std_logic_vector(RETURN_CODE_WIDTH-1 downto 0); + ready_in_dds : out std_logic; + valid_in_dds : in std_logic; + data_in_dds : in std_logic_vector(WORD_WIDTH-1 downto 0); + last_word_in_dds : in std_logic; + -- Sample Info + si_sample_state_dds : in std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0); + si_view_state_dds : in std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0); + si_instance_state_dds : in std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); + si_source_timestamp_dds : in TIME_TYPE; + si_instance_handle_dds : in INSTANCE_HANDLE_TYPE; + si_publication_handle_dds : in PUBLICATION_HANDLE_TYPE; + si_disposed_generation_count_dds : in std_logic_vector(DISPOSED_GENERATION_COUNT_WIDTH-1 downto 0); + si_no_writers_generation_count_dds : in std_logic_vector(NO_WRITERS_GENERATION_COUNT_WIDTH-1 downto 0); + si_sample_rank_dds : in std_logic_vector(SAMPLE_RANK_WIDTH-1 downto 0); + si_generation_rank_dds : in std_logic_vector(GENERATION_RANK_WIDTH-1 downto 0); + si_absolute_generation_rank_dds : in std_logic_vector(ABSOLUTE_GENERATION_COUNT_WIDTH-1 downto 0); + si_valid_data_dds : in std_logic; + si_valid_dds : in std_logic; + si_ack_dds : out std_logic; + eoc_dds : in std_logic; + -- Communication Status + status_dds : in std_logic_vector(STATUS_KIND_WIDTH-1 downto 0); + + -- TO USER ENTITY + start_user : in std_logic; + ack_user : out std_logic; + opcode_user : in DDS_READER_OPCODE_TYPE; + instance_state_user : in std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); + view_state_user : in std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0); + sample_state_user : in std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0); + instance_handle_user : in INSTANCE_HANDLE_TYPE; + max_samples_user : in std_logic_vector(MAX_SAMPLES_WIDTH-1 downto 0); + get_data_user : in std_logic; + done_user : out std_logic; + return_code_user : out std_logic_vector(RETURN_CODE_WIDTH-1 downto 0); + -- Sample Info + si_sample_state_user : out std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0); + si_view_state_user : out std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0); + si_instance_state_user : out std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); + si_source_timestamp_user : out TIME_TYPE; + si_instance_handle_user : out INSTANCE_HANDLE_TYPE; + si_publication_handle_user : out PUBLICATION_HANDLE_TYPE; + si_disposed_generation_count_user : out std_logic_vector(DISPOSED_GENERATION_COUNT_WIDTH-1 downto 0); + si_no_writers_generation_count_user : out std_logic_vector(NO_WRITERS_GENERATION_COUNT_WIDTH-1 downto 0); + si_sample_rank_user : out std_logic_vector(SAMPLE_RANK_WIDTH-1 downto 0); + si_generation_rank_user : out std_logic_vector(GENERATION_RANK_WIDTH-1 downto 0); + si_absolute_generation_rank_user : out std_logic_vector(ABSOLUTE_GENERATION_COUNT_WIDTH-1 downto 0); + si_valid_data_user : out std_logic; + si_valid_user : out std_logic; + si_ack_user : in std_logic; + eoc_user : out std_logic; + -- Communication Status + status_user : out std_logic_vector(STATUS_KIND_WIDTH-1 downto 0); + decode_error : out std_logic; + + -- TYPE SPECIFIC PORTS + id : out std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + TestSequence_len : out std_logic_vector(TESTSEQUENCE_ADDR_WIDTH-1 downto 0); + TestSequence_addr : in std_logic_vector(TESTSEQUENCE_ADDR_WIDTH-1 downto 0); + TestSequence_ready : out std_logic; + TestSequence_ren : in std_logic; + TestSequence_valid : out std_logic; + TestSequence_TestArray_addr : in std_logic_vector(TESTSEQUENCE_TESTARRAY_ADDR_WIDTH-1 downto 0); + TestSequence_TestArray_ready : out std_logic; + TestSequence_TestArray_ren : in std_logic; + TestSequence_TestArray_valid : out std_logic; + TestSequence_TestArray : out std_logic_vector(CDR_OCTET_WIDTH-1 downto 0); + TestSequence_TestChar : out std_logic_vector(CDR_CHAR_WIDTH-1 downto 0); + TestSequence_TestWChar : out std_logic_vector(CDR_WCHAR_WIDTH-1 downto 0); + TestSequence_TestLongLong : out std_logic_vector(CDR_LONG_LONG_WIDTH-1 downto 0); + TestSequence_TestLongDouble : out std_logic_vector(CDR_LONG_DOUBLE_WIDTH-1 downto 0); + TestSequence_TestLongDouble_valid : out std_logic; + TestMap_len : out std_logic_vector(TESTMAP_ADDR_WIDTH-1 downto 0); + TestMap_addr : in std_logic_vector(TESTMAP_ADDR_WIDTH-1 downto 0); + TestMap_ready : out std_logic; + TestMap_ren : in std_logic; + TestMap_valid : out std_logic; + TestMap_key : out std_logic_vector(CDR_OCTET_WIDTH-1 downto 0); + TestMap_value : out std_logic_vector(CDR_SHORT_WIDTH-1 downto 0); + TestEnum : out std_logic_vector(TESTENUM_WIDTH-1 downto 0); + TestUnion_valid : out std_logic; + TestUnion_d : out std_logic_vector(CDR_CHAR_WIDTH-1 downto 0); + TestUnion_LongU : out std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + TestUnion_OctetU : out std_logic_vector(CDR_OCTET_WIDTH-1 downto 0); + TestBitmask : out std_logic_vector(TESTBITMASK_WIDTH-1 downto 0); + TestString_len : out std_logic_vector(TESTSTRING_ADDR_WIDTH-1 downto 0); + TestString_addr : in std_logic_vector(TESTSTRING_ADDR_WIDTH-1 downto 0); + TestString_ready : out std_logic; + TestString_ren : in std_logic; + TestString_valid : out std_logic; + TestString : out std_logic_vector(CDR_CHAR_WIDTH-1 downto 0); + valid : out std_logic + ); +end entity; + +architecture arch of Type2_reader_wrapper is + + --*****TYPE DECLARATION***** + -- FSM states. Explained below in detail + type STAGE_TYPE is (IDLE,GET_PAYLOAD_HEADER,FETCH,ALIGN_STREAM,SKIP_PAYLOAD,DECODE_PAYLOAD); + -- ###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_TESTMAP_LENGTH,GET_TESTMAP_KEY,GET_TESTMAP_VALUE,TESTMAP_MEMBER_END,GET_TESTENUM,GET_TESTUNION_D,GET_TESTUNION_LONGU,GET_TESTUNION_OCTETU,GET_TESTBITMASK,GET_TESTSTRING_LENGTH,GET_TESTSTRING,GET_OPTIONAL_HEADER); + 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 align_op, align_op_next : std_logic := '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 optional, optional_next : std_logic := '0'; + signal abort_mem : std_logic := '0'; + signal ready_in_dds_sig : std_logic := '0'; + -- ###GENERATED START### + signal decode_stage, decode_stage_next : DECODE_STAGE_TYPE := GET_ID; + signal valid_latch, valid_latch_next : std_logic := '0'; + signal return_stage, return_stage_next : DECODE_STAGE_TYPE := GET_ID; + signal dw_latch, dw_latch_next : std_logic_vector(CDR_LONG_LONG_WIDTH-1 downto 0) := (others => '0'); + signal qw_latch, qw_latch_next : std_logic_vector(CDR_LONG_DOUBLE_WIDTH-1 downto 0) := (others => '0'); + 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; + signal TestMap_cnt, TestMap_cnt_next : natural range 0 to TESTMAP_MAX_DEPTH-1 := 0; + signal TestMap_len_latch, TestMap_len_latch_next : unsigned(TESTMAP_ADDR_WIDTH-1 downto 0) := (others => '0'); + signal TestMap_key_latch, TestMap_key_latch_next : std_logic_vector(CDR_OCTET_WIDTH-1 downto 0) := (others => '0'); + signal TestString_cnt, TestString_cnt_next : natural range 0 to TESTSTRING_MAX_DEPTH-1 := 0; + signal TestString_len_latch, TestString_len_latch_next : unsigned(TESTSTRING_ADDR_WIDTH-1 downto 0) := (others => '0'); + signal TestEnum_latch, TestEnum_latch_next : std_logic_vector(TESTENUM_WIDTH-1 downto 0) := (others => '0'); + signal TestUnion_valid_latch, TestUnion_valid_latch_next : std_logic := '0'; + signal TestUnion_d_latch, TestUnion_d_latch_next : std_logic_vector(CDR_CHAR_WIDTH-1 downto 0) := (others => '0'); + signal TestUnion_LongU_latch, TestUnion_LongU_latch_next : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); + signal TestUnion_OctetU_latch, TestUnion_OctetU_latch_next : std_logic_vector(CDR_OCTET_WIDTH-1 downto 0) := (others => '0'); + signal TestBitmask_latch, TestBitmask_latch_next : std_logic_vector(TESTBITMASK_WIDTH-1 downto 0) := (others => '0'); + -- TestSequence_TestChar_mem SIGNALS + signal TestSequence_TestChar_mem_addr : std_logic_vector(TESTSEQUENCE_ADDR_WIDTH-1 downto 0) := (others => '0'); + signal TestSequence_TestChar_mem_read, TestSequence_TestChar_mem_ready_in, TestSequence_TestChar_mem_ready_out, TestSequence_TestChar_mem_valid_in, TestSequence_TestChar_mem_valid_out : std_logic := '0'; + signal TestSequence_TestChar_mem_data_in, TestSequence_TestChar_mem_data_out : std_logic_vector(CDR_CHAR_WIDTH-1 downto 0) := (others => '0'); + -- TestSequence_TestWChar_mem SIGNALS + signal TestSequence_TestWChar_mem_addr : std_logic_vector(TESTSEQUENCE_ADDR_WIDTH-1 downto 0) := (others => '0'); + signal TestSequence_TestWChar_mem_read, TestSequence_TestWChar_mem_ready_in, TestSequence_TestWChar_mem_ready_out, TestSequence_TestWChar_mem_valid_in, TestSequence_TestWChar_mem_valid_out : std_logic := '0'; + signal TestSequence_TestWChar_mem_data_in, TestSequence_TestWChar_mem_data_out : std_logic_vector(CDR_WCHAR_WIDTH-1 downto 0) := (others => '0'); + -- TestSequence_TestLongLong_mem SIGNALS + signal TestSequence_TestLongLong_mem_addr : std_logic_vector(TESTSEQUENCE_ADDR_WIDTH-1 downto 0) := (others => '0'); + signal TestSequence_TestLongLong_mem_read, TestSequence_TestLongLong_mem_ready_in, TestSequence_TestLongLong_mem_ready_out, TestSequence_TestLongLong_mem_valid_in, TestSequence_TestLongLong_mem_valid_out : std_logic := '0'; + signal TestSequence_TestLongLong_mem_data_in, TestSequence_TestLongLong_mem_data_out : std_logic_vector(CDR_LONG_LONG_WIDTH-1 downto 0) := (others => '0'); + -- TestSequence_TestLongDouble_mem SIGNALS + signal TestSequence_TestLongDouble_mem_addr : std_logic_vector(TESTSEQUENCE_ADDR_WIDTH-1 downto 0) := (others => '0'); + signal TestSequence_TestLongDouble_mem_read, TestSequence_TestLongDouble_mem_ready_in, TestSequence_TestLongDouble_mem_ready_out, TestSequence_TestLongDouble_mem_valid_in, TestSequence_TestLongDouble_mem_valid_out : std_logic := '0'; + signal TestSequence_TestLongDouble_mem_data_in, TestSequence_TestLongDouble_mem_data_out : std_logic_vector(CDR_LONG_DOUBLE_WIDTH+1-1 downto 0) := (others => '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')); + -- TestMap_mem SIGNALS + signal TestMap_mem_addr : std_logic_vector(TESTMAP_ADDR_WIDTH-1 downto 0) := (others => '0'); + signal TestMap_mem_read, TestMap_mem_ready_in, TestMap_mem_ready_out, TestMap_mem_valid_in, TestMap_mem_valid_out : std_logic := '0'; + signal TestMap_mem_data_in, TestMap_mem_data_out : std_logic_vector(CDR_OCTET_WIDTH+CDR_SHORT_WIDTH-1 downto 0) := (others => '0'); + -- TestString_mem SIGNALS + signal TestString_mem_addr : std_logic_vector(TESTMAP_ADDR_WIDTH-1 downto 0) := (others => '0'); + signal TestString_mem_read, TestString_mem_ready_in, TestString_mem_ready_out, TestString_mem_valid_in, TestString_mem_valid_out : std_logic := '0'; + signal TestString_mem_data_in, TestString_mem_data_out : std_logic_vector(CDR_CHAR_WIDTH-1 downto 0) := (others => '0'); + -- ###GENERATED END### + + --*****ALIAS DECLARATION***** + alias representation_id : std_logic_vector(PAYLOAD_REPRESENTATION_ID_WIDTH-1 downto 0) is data_in_dds(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_dds(PAYLOAD_REPRESENTATION_OPTIONS_WIDTH-1 downto 0); + alias parameter_id : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) is data_in_dds(WORD_WIDTH-1 downto WORD_WIDTH-PARAMETER_ID_WIDTH); + alias parameter_length : std_logic_vector(PARAMETER_LENGTH_WIDTH-1 downto 0) is data_in_dds(PARAMETER_LENGTH_WIDTH-1 downto 0); + + +begin + + -- ###GENERATED START### + TestSequence_TestChar_mem : entity work.mem_ctrl(arch) + generic map ( + ADDR_WIDTH => TESTSEQUENCE_ADDR_WIDTH, + DATA_WIDTH => CDR_CHAR_WIDTH, + MEMORY_DEPTH => TESTSEQUENCE_MAX_DEPTH, + MAX_BURST_LENGTH => 1 + ) + port map ( + clk => clk, + reset => reset or abort_mem, + addr => TestSequence_TestChar_mem_addr, + read => TestSequence_TestChar_mem_read, + ready_in => TestSequence_TestChar_mem_ready_in, + valid_in => TestSequence_TestChar_mem_valid_in, + data_in => TestSequence_TestChar_mem_data_in, + ready_out => TestSequence_TestChar_mem_ready_out, + valid_out => TestSequence_TestChar_mem_valid_out, + data_out => TestSequence_TestChar_mem_data_out + ); + + TestSequence_TestWChar_mem : entity work.mem_ctrl(arch) + generic map ( + ADDR_WIDTH => TESTSEQUENCE_ADDR_WIDTH, + DATA_WIDTH => CDR_WCHAR_WIDTH, + MEMORY_DEPTH => TESTSEQUENCE_MAX_DEPTH, + MAX_BURST_LENGTH => 1 + ) + port map ( + clk => clk, + reset => reset or abort_mem, + addr => TestSequence_TestWChar_mem_addr, + read => TestSequence_TestWChar_mem_read, + ready_in => TestSequence_TestWChar_mem_ready_in, + valid_in => TestSequence_TestWChar_mem_valid_in, + data_in => TestSequence_TestWChar_mem_data_in, + ready_out => TestSequence_TestWChar_mem_ready_out, + valid_out => TestSequence_TestWChar_mem_valid_out, + data_out => TestSequence_TestWChar_mem_data_out + ); + + TestSequence_TestLongLong_mem : entity work.mem_ctrl(arch) + generic map ( + ADDR_WIDTH => TESTSEQUENCE_ADDR_WIDTH, + DATA_WIDTH => CDR_LONG_LONG_WIDTH, + MEMORY_DEPTH => TESTSEQUENCE_MAX_DEPTH, + MAX_BURST_LENGTH => 1 + ) + port map ( + clk => clk, + reset => reset or abort_mem, + addr => TestSequence_TestLongLong_mem_addr, + read => TestSequence_TestLongLong_mem_read, + ready_in => TestSequence_TestLongLong_mem_ready_in, + valid_in => TestSequence_TestLongLong_mem_valid_in, + data_in => TestSequence_TestLongLong_mem_data_in, + ready_out => TestSequence_TestLongLong_mem_ready_out, + valid_out => TestSequence_TestLongLong_mem_valid_out, + data_out => TestSequence_TestLongLong_mem_data_out + ); + + TestSequence_TestLongDouble_mem : entity work.mem_ctrl(arch) + generic map ( + ADDR_WIDTH => TESTSEQUENCE_ADDR_WIDTH, + DATA_WIDTH => CDR_LONG_DOUBLE_WIDTH+1, + MEMORY_DEPTH => TESTSEQUENCE_MAX_DEPTH, + MAX_BURST_LENGTH => 1 + ) + port map ( + clk => clk, + reset => reset or abort_mem, + addr => TestSequence_TestLongDouble_mem_addr, + read => TestSequence_TestLongDouble_mem_read, + ready_in => TestSequence_TestLongDouble_mem_ready_in, + valid_in => TestSequence_TestLongDouble_mem_valid_in, + data_in => TestSequence_TestLongDouble_mem_data_in, + ready_out => TestSequence_TestLongDouble_mem_ready_out, + valid_out => TestSequence_TestLongDouble_mem_valid_out, + data_out => TestSequence_TestLongDouble_mem_data_out + ); + + 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; + + TestMap_mem : entity work.mem_ctrl(arch) + generic map ( + ADDR_WIDTH => TESTMAP_ADDR_WIDTH, + DATA_WIDTH => CDR_OCTET_WIDTH+CDR_SHORT_WIDTH, + MEMORY_DEPTH => TESTMAP_MAX_DEPTH, + MAX_BURST_LENGTH => 1 + ) + port map ( + clk => clk, + reset => reset or abort_mem, + addr => TestMap_mem_addr, + read => TestMap_mem_read, + ready_in => TestMap_mem_ready_in, + valid_in => TestMap_mem_valid_in, + data_in => TestMap_mem_data_in, + ready_out => TestMap_mem_ready_out, + valid_out => TestMap_mem_valid_out, + data_out => TestMap_mem_data_out + ); + + TestString_mem : entity work.mem_ctrl(arch) + generic map ( + ADDR_WIDTH => TESTSTRING_ADDR_WIDTH, + DATA_WIDTH => CDR_CHAR_WIDTH, + MEMORY_DEPTH => TESTSTRING_MAX_DEPTH, + MAX_BURST_LENGTH => 1 + ) + port map ( + clk => clk, + reset => reset or abort_mem, + addr => TestString_mem_addr, + read => TestString_mem_read, + ready_in => TestString_mem_ready_in, + valid_in => TestString_mem_valid_in, + data_in => TestString_mem_data_in, + ready_out => TestString_mem_ready_out, + valid_out => TestString_mem_valid_out, + data_out => TestString_mem_data_out + ); + -- ###GENERATED END### + + -- PASSTHROUGH + start_dds <= start_user; + ack_user <= ack_dds; + opcode_dds <= opcode_user; + instance_state_dds <= instance_state_user; + view_state_dds <= view_state_user; + sample_state_dds <= sample_state_user; + instance_handle_dds <= instance_handle_user; + max_samples_dds <= max_samples_user; + get_data_dds <= get_data_user; + done_user <= done_dds; + return_code_user <= return_code_dds; + si_sample_state_user <= si_sample_state_dds; + si_view_state_user <= si_view_state_dds; + si_instance_state_user <= si_instance_state_dds; + si_source_timestamp_user <= si_source_timestamp_dds; + si_instance_handle_user <= si_instance_handle_dds; + si_publication_handle_user <= si_publication_handle_dds; + si_disposed_generation_count_user <= si_disposed_generation_count_dds; + si_no_writers_generation_count_user <= si_no_writers_generation_count_dds; + si_sample_rank_user <= si_sample_rank_dds; + si_generation_rank_user <= si_generation_rank_dds; + si_absolute_generation_rank_user <= si_absolute_generation_rank_dds; + si_valid_data_user <= si_valid_data_dds; + si_valid_user <= si_valid_dds; + si_ack_dds <= si_ack_user; + eoc_user <= eoc_dds; + status_user <= status_dds; + + valid <= valid_latch; + decode_error <= decode_error_latch; + ready_in_dds <= ready_in_dds_sig; + + -- ###GENERATED START### + id <= id_latch; + TestSequence_len <= std_logic_vector(TestSequence_len_latch); + TestSequence_valid <= TestSequence_TestChar_mem_valid_out and TestSequence_TestWChar_mem_valid_out and TestSequence_TestLongLong_mem_valid_out and TestSequence_TestLongDouble_mem_valid_out; + -- NOTE: We could also solve this with a one-hot mux, but syntesis of a one-hot mux is more complex than a simple index mux. + -- Alternatively you could just OR all outputs, but that places the restriction that the data_out signal has to be (others => '0') when valid = '0'. + TestSequence_TestArray <= TestSequence_TestArray_mem_data_out(to_integer(unsigned(TestSequence_addr_latch))); + TestSequence_TestArray_valid <= TestSequence_TestArray_mem_valid_out(to_integer(unsigned(TestSequence_addr_latch))); + TestSequence_TestChar <= TestSequence_TestChar_mem_data_out; + TestSequence_TestWChar <= TestSequence_TestWChar_mem_data_out; + TestSequence_TestLongLong <= TestSequence_TestLongLong_mem_data_out; + TestSequence_TestLongDouble <= TestSequence_TestLongDouble_mem_data_out(CDR_LONG_DOUBLE_WIDTH-1 downto 0); + TestSequence_TestLongDouble_valid <= TestSequence_TestLongDouble_mem_data_out(CDR_LONG_DOUBLE_WIDTH); + TestMap_len <= std_logic_vector(TestMap_len_latch); + TestMap_valid <= TestMap_mem_valid_out; + TestMap_key <= TestMap_mem_data_out(CDR_OCTET_WIDTH+CDR_SHORT_WIDTH-1 downto CDR_SHORT_WIDTH); + TestMap_value <= TestMap_mem_data_out(CDR_SHORT_WIDTH-1 downto 0); + TestEnum <= TestEnum_latch; + TestUnion_valid <= TestUnion_valid_latch; + TestUnion_d <= TestUnion_d_latch; + TestUnion_LongU <= TestUnion_LongU_latch; + TestUnion_OctetU <= TestUnion_OctetU_latch; + TestBitmask <= TestBitmask_latch; + TestString_len <= std_logic_vector(TestString_len_latch); + TestString_valid <= TestString_mem_valid_out; + TestString <= TestString_mem_data_out; + -- ###GENERATED END### + + 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; + return_stage_next <= return_stage; + cnt_next <= cnt; + 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; + valid_latch_next <= valid_latch; + data_in_latch_next <= data_in_latch; + dw_latch_next <= dw_latch; + qw_latch_next <= qw_latch; + align_op_next <= align_op; + abort_mem <= '0'; + ready_in_dds_sig <= '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; + TestMap_cnt_next <= TestMap_cnt; + TestMap_len_latch_next <= TestMap_len_latch; + TestMap_key_latch_next <= TestMap_key_latch; + TestEnum_latch_next <= TestEnum_latch; + TestUnion_valid_latch_next <= TestUnion_valid_latch; + TestUnion_d_latch_next <= TestUnion_d_latch; + TestUnion_LongU_latch_next <= TestUnion_LongU_latch; + TestUnion_OctetU_latch_next <= TestUnion_OctetU_latch; + TestBitmask_latch_next <= TestBitmask_latch; + TestString_cnt_next <= TestString_cnt; + TestString_len_latch_next <= TestString_len_latch; + TestSequence_TestChar_mem_addr <= (others => '0'); + TestSequence_TestChar_mem_read <= '0'; + TestSequence_TestChar_mem_valid_in <= '0'; + TestSequence_TestChar_mem_ready_out <= '0'; + TestSequence_TestChar_mem_data_in <= (others => '0'); + TestSequence_TestWChar_mem_addr <= (others => '0'); + TestSequence_TestWChar_mem_read <= '0'; + TestSequence_TestWChar_mem_valid_in <= '0'; + TestSequence_TestWChar_mem_ready_out <= '0'; + TestSequence_TestWChar_mem_data_in <= (others => '0'); + TestSequence_TestLongLong_mem_addr <= (others => '0'); + TestSequence_TestLongLong_mem_read <= '0'; + TestSequence_TestLongLong_mem_valid_in <= '0'; + TestSequence_TestLongLong_mem_ready_out <= '0'; + TestSequence_TestLongLong_mem_data_in <= (others => '0'); + TestSequence_TestLongDouble_mem_addr <= (others => '0'); + TestSequence_TestLongDouble_mem_read <= '0'; + TestSequence_TestLongDouble_mem_valid_in <= '0'; + TestSequence_TestLongDouble_mem_ready_out <= '0'; + TestSequence_TestLongDouble_mem_data_in <= (others => '0'); + 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')); + TestMap_mem_addr <= (others => '0'); + TestMap_mem_read <= '0'; + TestMap_mem_valid_in <= '0'; + TestMap_mem_ready_out <= '0'; + TestMap_mem_data_in <= (others => '0'); + TestString_mem_addr <= (others => '0'); + TestString_mem_read <= '0'; + TestString_mem_valid_in <= '0'; + TestString_mem_ready_out <= '0'; + TestString_mem_data_in <= (others => '0'); + TestSequence_ready <= '0'; + TestSequence_TestArray_ready <= '0'; + TestMap_ready <= '0'; + TestString_ready <= '0'; + -- ###GENERATED END### + + -- Last Word Latch Setter + if (last_word_in_dds = '1') then + last_word_in_latch_next <= '1'; + end if; + + case (stage) is + when IDLE => + -- User Requests Payload + if (si_valid_dds = '1' and si_valid_data_dds = '1' and si_ack_user = '1' and get_data_user = '1') then + stage_next <= GET_PAYLOAD_HEADER; + -- RESET + decode_error_latch_next <= '0'; + valid_latch_next <= '0'; + abort_mem <= '1'; + else + TestSequence_ready <= TestSequence_TestChar_mem_ready_in and TestSequence_TestWChar_mem_ready_in and TestSequence_TestLongLong_mem_ready_in and TestSequence_TestLongDouble_mem_ready_in; + TestSequence_TestChar_mem_addr <= TestSequence_addr; + TestSequence_TestChar_mem_read <= TestSequence_ren; + TestSequence_TestChar_mem_valid_in <= TestSequence_ren; + TestSequence_TestChar_mem_ready_out <= TestSequence_ren; + TestSequence_TestWChar_mem_addr <= TestSequence_addr; + TestSequence_TestWChar_mem_read <= TestSequence_ren; + TestSequence_TestWChar_mem_valid_in <= TestSequence_ren; + TestSequence_TestWChar_mem_ready_out <= TestSequence_ren; + TestSequence_TestLongLong_mem_addr <= TestSequence_addr; + TestSequence_TestLongLong_mem_read <= TestSequence_ren; + TestSequence_TestLongLong_mem_valid_in <= TestSequence_ren; + TestSequence_TestLongLong_mem_ready_out <= TestSequence_ren; + TestSequence_TestLongDouble_mem_addr <= TestSequence_addr; + TestSequence_TestLongDouble_mem_read <= TestSequence_ren; + TestSequence_TestLongDouble_mem_valid_in <= TestSequence_ren; + TestSequence_TestLongDouble_mem_ready_out <= TestSequence_ren; + TestSequence_TestArray_ready <= TestSequence_TestArray_mem_ready_in(to_integer(unsigned(TestSequence_addr))); + TestSequence_TestArray_mem_addr(to_integer(unsigned(TestSequence_addr))) <= TestSequence_TestArray_addr; + TestSequence_TestArray_mem_read(to_integer(unsigned(TestSequence_addr))) <= TestSequence_TestArray_ren; + TestSequence_TestArray_mem_valid_in(to_integer(unsigned(TestSequence_addr))) <= TestSequence_TestArray_ren; + TestSequence_TestArray_mem_ready_out <= (others => TestSequence_TestArray_ren); + -- Latch Address for output + if (TestSequence_TestArray_ren = '1') then + TestSequence_addr_latch_next <= TestSequence_addr; + end if; + TestMap_ready <= TestMap_mem_ready_in; + TestMap_mem_addr <= TestMap_addr; + TestMap_mem_read <= TestMap_ren; + TestMap_mem_valid_in <= TestMap_ren; + TestMap_mem_ready_out <= TestMap_ren; + TestString_ready <= TestString_mem_ready_in; + TestString_mem_addr <= TestString_addr; + TestString_mem_read <= TestString_ren; + TestString_mem_valid_in <= TestString_ren; + TestString_mem_ready_out <= TestString_ren; + end if; + when GET_PAYLOAD_HEADER => + -- TODO: Latch Offset from Options Field? + + ready_in_dds_sig <= '1'; + -- Input Guard + if (valid_in_dds = '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_dds_sig <= '1'; + -- Input Guard + if (valid_in_dds = '1') then + data_in_latch_next <= data_in_dds; + -- Alignment Operation in progress + if (align_op = '1') then + stage_next <= ALIGN_STREAM; + -- Reset + align_op_next <= '0'; + else + stage_next <= DECODE_PAYLOAD; + end if; + end if; + when ALIGN_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_dds = '0') then + -- Skip Read + ready_in_dds_sig <= '1'; + else + stage_next <= IDLE; + + -- If no Decode Error, mark output as valid + if (decode_error_latch /= '0') then + valid_latch_next <= '1'; + end if; + + -- Reset + last_word_in_latch_next <= '0'; + end if; + when DECODE_PAYLOAD => + -- ###GENERATED START### + case (decode_stage) is + when GET_ID => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_4)) then + target_align_next <= ALIGN_4; + stage_next <= ALIGN_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_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 + decode_stage_next <= GET_TESTMAP_LENGTH; + 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_STREAM; + else + TestSequence_TestArray_mem_addr(TestSequence_cnt) <= std_logic_vector(to_unsigned(TestSequence_TestArray_cnt,TESTSEQUENCE_TESTARRAY_ADDR_WIDTH)); + 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; + TestSequence_TestArray_cnt_next <= TestSequence_TestArray_cnt + 1; + + -- All Elements processed + if (TestSequence_TestArray_cnt = TESTSEQUENCE_TESTARRAY_MAX_DEPTH-1) then + decode_stage_next <= GET_TESTSEQUENCE_TESTCHAR; + 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_STREAM; + else + TestSequence_TestChar_mem_addr <= std_logic_vector(to_unsigned(TestSequence_cnt,TESTSEQUENCE_ADDR_WIDTH)); + TestSequence_TestChar_mem_data_in <= endian_swap(endian_flag, get_sub_vector(data_in_latch, to_integer(align_offset(1 downto 0)), CDR_CHAR_WIDTH, TRUE)); + TestSequence_TestChar_mem_valid_in <= '1'; + + -- Memory Operation Guard + if (TestSequence_TestChar_mem_ready_in = '1') then + 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; + 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_STREAM; + else + TestSequence_TestWChar_mem_addr <= std_logic_vector(to_unsigned(TestSequence_cnt,TESTSEQUENCE_ADDR_WIDTH)); + TestSequence_TestWChar_mem_data_in <= endian_swap(endian_flag, get_sub_vector(data_in_latch, to_integer(align_offset(1 downto 1)), CDR_WCHAR_WIDTH, TRUE)); + TestSequence_TestWChar_mem_valid_in <= '1'; + + -- Memory Operation Guard + if (TestSequence_TestWChar_mem_ready_in = '1') then + 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 downto 1) = "1") then + stage_next <= FETCH; + end if; + 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_STREAM; + else + case (cnt) is + -- Double Word 1/2 + when 0 => + dw_latch_next(CDR_LONG_LONG_WIDTH-1 downto CDR_LONG_LONG_WIDTH/2) <= data_in_latch; + stage_next <= FETCH; + cnt_next <= cnt + 1; + -- Double Word 2/2 + when 1 => + dw_latch_next((CDR_LONG_LONG_WIDTH/2)-1 downto 0) <= data_in_latch; + stage_next <= FETCH; + cnt_next <= cnt + 1; + -- Push Double Word + when 2 => + TestSequence_TestLongLong_mem_addr <= std_logic_vector(to_unsigned(TestSequence_cnt,TESTSEQUENCE_ADDR_WIDTH)); + TestSequence_TestLongLong_mem_data_in <= endian_swap(endian_flag, dw_latch); + TestSequence_TestLongLong_mem_valid_in <= '1'; + + -- Memory Operation Guard + if (TestSequence_TestLongLong_mem_ready_in = '1') then + align_offset_next <= align_offset + 8; + decode_stage_next <= GET_OPTIONAL_HEADER; + return_stage_next <= GET_TESTSEQUENCE_TESTLONGDOUBLE; + cnt_next <= 0; + end if; + when others => + null; + end case; + end if; + when GET_TESTSEQUENCE_TESTLONGDOUBLE => + -- Optional Omitted + if (optional = '0') then + -- Mark Optional as Invalid + TestSequence_TestLongDouble_mem_addr <= std_logic_vector(to_unsigned(TestSequence_cnt,TESTSEQUENCE_ADDR_WIDTH)); + TestSequence_TestLongDouble_mem_data_in(CDR_LONG_DOUBLE_WIDTH) <= '0'; + TestSequence_TestLongDouble_mem_valid_in <= '1'; + -- Memory Operation Guard + if (TestSequence_TestLongLong_mem_ready_in = '1') then + decode_stage_next <= TESTSEQUENCE_MEMBER_END; + end if; + -- ALIGN GUARD + elsif (not check_align(align_offset, ALIGN_8)) then + target_align_next <= ALIGN_8; + stage_next <= ALIGN_STREAM; + else + case (cnt) is + -- Quad Word 1/4 + when 0 => + qw_latch_next(CDR_LONG_DOUBLE_WIDTH-1 downto CDR_LONG_DOUBLE_WIDTH-WORD_WIDTH) <= data_in_latch; + stage_next <= FETCH; + cnt_next <= cnt + 1; + -- Quad Word 2/4 + when 1 => + qw_latch_next(CDR_LONG_DOUBLE_WIDTH-WORD_WIDTH-1 downto CDR_LONG_DOUBLE_WIDTH-(2*WORD_WIDTH)) <= data_in_latch; + stage_next <= FETCH; + cnt_next <= cnt + 1; + -- Quad Word 3/4 + when 2 => + qw_latch_next(CDR_LONG_DOUBLE_WIDTH-(2*WORD_WIDTH)-1 downto CDR_LONG_DOUBLE_WIDTH-(3*WORD_WIDTH)) <= data_in_latch; + stage_next <= FETCH; + cnt_next <= cnt + 1; + -- Quad Word 4/4 + when 3 => + qw_latch_next(WORD_WIDTH-1 downto 0) <= data_in_latch; + stage_next <= FETCH; + cnt_next <= cnt + 1; + -- Push Quad Word + when 4 => + TestSequence_TestLongDouble_mem_addr <= std_logic_vector(to_unsigned(TestSequence_cnt,TESTSEQUENCE_ADDR_WIDTH)); + TestSequence_TestLongDouble_mem_data_in <= "1" & endian_swap(endian_flag, qw_latch); + TestSequence_TestLongDouble_mem_valid_in <= '1'; + + -- Memory Operation Guard + if (TestSequence_TestLongLong_mem_ready_in = '1') then + align_offset_next <= align_offset + 16; + decode_stage_next <= TESTSEQUENCE_MEMBER_END; + end if; + 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 + decode_stage_next <= GET_TESTMAP_LENGTH; + else + TestSequence_cnt_next <= TestSequence_cnt + 1; + decode_stage_next <= GET_TESTSEQUENCE_TESTARRAY; + TestSequence_TestArray_cnt_next <= 0; + end if; + when GET_TESTMAP_LENGTH => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_4)) then + target_align_next <= ALIGN_4; + stage_next <= ALIGN_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 + decode_stage_next <= GET_TESTENUM; + else + TestMap_len_latch_next <= resize(tmp_length, TestMap_len_latch_next'length); + TestMap_cnt_next <= 0; + decode_stage_next <= GET_TESTMAP_KEY; + end if; + end if; + when GET_TESTMAP_KEY => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_1)) then + target_align_next <= ALIGN_1; + stage_next <= ALIGN_STREAM; + else + TestMap_key_latch_next <= endian_swap(endian_flag, get_sub_vector(data_in_latch, to_integer(align_offset(1 downto 0)), CDR_OCTET_WIDTH, TRUE)); + align_offset_next <= align_offset + 1; + decode_stage_next <= GET_TESTMAP_VALUE; + + -- Need to fetch next Word + if(align_offset(1 downto 0) = "11") then + stage_next <= FETCH; + end if; + end if; + when GET_TESTMAP_VALUE => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_2)) then + target_align_next <= ALIGN_2; + stage_next <= ALIGN_STREAM; + else + TestMap_mem_addr <= std_logic_vector(to_unsigned(TestMap_cnt,TESTMAP_ADDR_WIDTH)); + TestMap_mem_data_in <= TestMap_key_latch & endian_swap(endian_flag, get_sub_vector(data_in_latch, to_integer(align_offset(1 downto 1)), CDR_SHORT_WIDTH, TRUE)); + TestMap_mem_valid_in <= '1'; + + -- Memory Operation Guard + if (TestMap_mem_ready_in = '1') then + align_offset_next <= align_offset + 2; + decode_stage_next <= TESTMAP_MEMBER_END; + + -- Need to fetch next Word + if(align_offset(1 downto 1) = "1") then + stage_next <= FETCH; + end if; + end if; + end if; + when TESTMAP_MEMBER_END => + -- All Elements processed + if (TestMap_cnt = TestMap_len_latch-1) then + -- Next Member + decode_stage_next <= GET_TESTENUM; + else + TestMap_cnt_next <= TestMap_cnt + 1; + decode_stage_next <= GET_TESTMAP_KEY; + end if; + when GET_TESTENUM => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_1)) then + target_align_next <= ALIGN_1; + stage_next <= ALIGN_STREAM; + else + TestEnum_latch_next <= endian_swap(endian_flag, get_sub_vector(data_in_latch, to_integer(align_offset(1 downto 0)), CDR_OCTET_WIDTH, TRUE))(TESTENUM_WIDTH-1 downto 0); + align_offset_next <= align_offset + 1; + -- Next Member + decode_stage_next <= GET_OPTIONAL_HEADER; + return_stage_next <= GET_TESTUNION_D; + cnt_next <= 0; + + -- Need to fetch next Word + if(align_offset(1 downto 0) = "11") then + stage_next <= FETCH; + end if; + end if; + when GET_TESTUNION_D => + -- Optional Omitted + if (optional = '0') then + decode_stage_next <= GET_TESTBITMASK; + TestUnion_valid_latch_next <= '0'; + -- ALIGN GUARD + elsif (not check_align(align_offset, ALIGN_1)) then + target_align_next <= ALIGN_1; + stage_next <= ALIGN_STREAM; + else + align_offset_next <= align_offset + 1; + + TestUnion_valid_latch_next <= '1'; + TestUnion_d_latch_next <= endian_swap(endian_flag, get_sub_vector(data_in_latch, to_integer(align_offset(1 downto 0)), CDR_CHAR_WIDTH, TRUE)); + + case (endian_swap(endian_flag, get_sub_vector(data_in_latch, to_integer(align_offset(1 downto 0)), CDR_CHAR_WIDTH, TRUE))) is + when TESTUNION_LONGU_D => + decode_stage_next <= GET_TESTUNION_LONGU; + when others => + decode_stage_next <= GET_TESTUNION_OCTETU; + end case; + + -- Need to fetch next Word + if(align_offset(1 downto 0) = "11") then + stage_next <= FETCH; + end if; + end if; + when GET_TESTUNION_LONGU => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_4)) then + target_align_next <= ALIGN_4; + stage_next <= ALIGN_STREAM; + else + TestUnion_LongU_latch_next <= endian_swap(endian_flag, data_in_latch); + align_offset_next <= align_offset + 4; + stage_next <= FETCH; + -- Next Member + decode_stage_next <= GET_TESTBITMASK; + end if; + when GET_TESTUNION_OCTETU => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_1)) then + target_align_next <= ALIGN_1; + stage_next <= ALIGN_STREAM; + else + TestUnion_OctetU_latch_next <= endian_swap(endian_flag, get_sub_vector(data_in_latch, to_integer(align_offset(1 downto 0)), CDR_OCTET_WIDTH, TRUE)); + align_offset_next <= align_offset + 1; + -- Next Member + decode_stage_next <= GET_TESTBITMASK; + + -- Need to fetch next Word + if(align_offset(1 downto 0) = "11") then + stage_next <= FETCH; + end if; + end if; + when GET_TESTBITMASK => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_2)) then + target_align_next <= ALIGN_2; + stage_next <= ALIGN_STREAM; + else + TestBitmask_latch_next <= endian_swap(endian_flag, get_sub_vector(data_in_latch, to_integer(align_offset(1 downto 1)), CDR_SHORT_WIDTH, TRUE))(TESTBITMASK_WIDTH-1 downto 0); + align_offset_next <= align_offset + 2; + -- Next Member + decode_stage_next <= GET_TESTSTRING_LENGTH; + + -- Need to fetch next Word + if(align_offset(1 downto 1) = "1") then + stage_next <= FETCH; + end if; + end if; + when GET_TESTSTRING_LENGTH => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_4)) then + target_align_next <= ALIGN_4; + stage_next <= ALIGN_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 + -- DONE + stage_next <= SKIP_PAYLOAD; + else + TestString_len_latch_next <= resize(tmp_length, TestString_len_latch_next'length); + TestString_cnt_next <= 0; + decode_stage_next <= GET_TESTSTRING; + end if; + end if; + when GET_TESTSTRING => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_1)) then + target_align_next <= ALIGN_1; + stage_next <= ALIGN_STREAM; + else + TestString_mem_addr <= std_logic_vector(to_unsigned(TestString_cnt,TESTSTRING_ADDR_WIDTH)); + TestString_mem_data_in <= endian_swap(endian_flag, get_sub_vector(data_in_latch, to_integer(align_offset(1 downto 0)), CDR_CHAR_WIDTH, TRUE)); + TestString_mem_valid_in <= '1'; + -- Memory Operation Guard + if (TestString_mem_ready_in = '1') then + align_offset_next <= align_offset + 1; + TestString_cnt_next <= TestString_cnt + 1; + + -- Need to fetch next Word + if(align_offset(1 downto 0) = "11") then + stage_next <= FETCH; + end if; + + -- All Elements processed + if (TestString_cnt = TestString_len_latch-1) then + -- DONE + stage_next <= SKIP_PAYLOAD; + end if; + end if; + end if; + when GET_OPTIONAL_HEADER => + 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_dds) = (data_in_dds'reverse_range => '0')) then + optional_next <= '0'; + else + optional_next <= '1'; + end if; + when others => + null; + end case; + when others => + null; + end case; + -- ###GENERATED END### + when others => + null; + end case; + + -- OVERREAD GUARD + -- Attempted read on empty input + if (last_word_in_latch = '1' and ready_in_dds_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; + return_stage <= GET_ID; + target_align <= ALIGN_1; + cnt <= 0; + endian_flag <= '0'; + last_word_in_latch <= '0'; + decode_error_latch <= '0'; + optional <= '0'; + valid_latch <= '0'; + align_op <= '0'; + align_offset <= (others => '0'); + data_in_latch <= (others => '0'); + dw_latch <= (others => '0'); + qw_latch <= (others => '0'); + -- ###GENERATED START### + id_latch <= (others => '0'); + TestSequence_len_latch <= (others => '0'); + TestSequence_cnt <= 0; + TestSequence_TestArray_cnt <= 0; + TestSequence_addr_latch <= (others => '0'); + TestMap_cnt <= 0; + TestMap_len_latch <= (others => '0'); + TestMap_key_latch <= (others => '0'); + TestEnum_latch <= (others => '0'); + TestUnion_valid_latch <= '0'; + TestUnion_d_latch <= (others => '0'); + TestUnion_LongU_latch <= (others => '0'); + TestUnion_OctetU_latch <= (others => '0'); + TestBitmask_latch <= (others => '0'); + TestString_cnt <= 0; + TestString_len_latch <= (others => '0'); + -- ###GENERATED END### + else + stage <= stage_next; + decode_stage <= decode_stage_next; + return_stage <= return_stage_next; + target_align <= target_align_next; + cnt <= cnt_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; + valid_latch <= valid_latch_next; + align_op <= align_op_next; + align_offset <= align_offset_next; + data_in_latch <= data_in_latch_next; + dw_latch <= dw_latch_next; + qw_latch <= qw_latch_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; + TestSequence_addr_latch <= TestSequence_addr_latch_next; + TestMap_cnt <= TestMap_cnt_next; + TestMap_len_latch <= TestMap_len_latch_next; + TestMap_key_latch <= TestMap_key_latch_next; + TestEnum_latch <= TestEnum_latch_next; + TestUnion_valid_latch <= TestUnion_valid_latch_next; + TestUnion_d_latch <= TestUnion_d_latch_next; + TestUnion_LongU_latch <= TestUnion_LongU_latch_next; + TestUnion_OctetU_latch <= TestUnion_OctetU_latch_next; + TestBitmask_latch <= TestBitmask_latch_next; + TestString_cnt <= TestString_cnt_next; + TestString_len_latch <= TestString_len_latch_next; + -- ###GENERATED END### + end if; + end if; + end process; + +end architecture; \ No newline at end of file diff --git a/src/Type_CDR_ref.txt b/src/Type_CDR_ref.txt new file mode 100644 index 0000000..dd1d5a7 --- /dev/null +++ b/src/Type_CDR_ref.txt @@ -0,0 +1,108 @@ +# IDL DEFINITION + +module Messenger { + + @extensibility(FINAL) @nested + union TestUnion_t switch (char) { + case 'A': + long LongU; + default: + octet OctetU; + }; + + @bit_bound(7) + enum TestEnum_t { + A, + B, + C, + D + }; + + typedef octet TestArray_t[5]; + + @extensibility(FINAL) @nested + struct NestedStruct_t { + @key TestArray_t TestArray; + octet TestOctet; + short TestShort; + long long TestLongLong; + }; + + typedef sequence TestSequence_t; + typedef string<12> TestString_t; + + @topic + @extensibility(FINAL) + struct Message { + @key long id; + TestSequence_t TestSequence; + TestEnum_t TestEnum; + @optional TestUnion_t TestUnion; + TestString_t TestString; + }; +}; + +# CONTENT INITIALIZATION + +Messenger::Message message; +message.id = 10; +message.TestSequence.length(2); +message.TestSequence[0] = Messenger::NestedStruct_t(); +message.TestSequence[0].TestArray[0] = 1; +message.TestSequence[0].TestArray[1] = 2; +message.TestSequence[0].TestArray[2] = 3; +message.TestSequence[0].TestArray[3] = 4; +message.TestSequence[0].TestArray[4] = 5; +message.TestSequence[0].TestOctet = 'a'; +message.TestSequence[0].TestShort = L'b'; +message.TestSequence[0].TestLongLong = 1024; +message.TestSequence[1] = Messenger::NestedStruct_t(); +message.TestSequence[1].TestArray[0] = 6; +message.TestSequence[1].TestArray[1] = 7; +message.TestSequence[1].TestArray[2] = 8; +message.TestSequence[1].TestArray[3] = 9; +message.TestSequence[1].TestArray[4] = 10; +message.TestSequence[1].TestOctet = 'A'; +message.TestSequence[1].TestShort = L'B'; +message.TestSequence[1].TestLongLong = 4096; +message.TestEnum = Messenger::TestEnum_t::C; +message.TestUnion._d(0); +message.TestUnion.LongU(512); +message.TestUnion.OctetU(128); +message.TestString = "HelloWorld"; + + 31............24..............16..............8...............0 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Representation_id | Representation_options | + 00 01 (=CDR_LE) 00 00 + | id | + 0a 00 00 00 + | TestSequence.length | + 02 00 00 00 + | TS[0].TA[0] | TS[0].TA[1] | TS[0].TA[2] | TS[0].TA[3] | (TS...TestSequence, TA..TestArray) + 01 02 03 04 + | TS[0].TA[4] |TS[0].TestOctet| TS[0].TestShort | + 05 61 62 00 + | TS[0].TestLongLong | + | | + 00 04 00 00 00 00 00 00 + | TS[1].TA[0] | TS[2].TA[1] | TS[3].TA[2] | TS[4].TA[3] | + 06 07 08 09 + | TS[1].TA[4] |TS[1].TestOctet| TS[1].TestShort | + 0a 41 42 00 + | TS[0].TestLongLong | + | | + 00 10 00 00 00 00 00 00 + | TestEnum | + 02 00 00 00 + | TestUnion._d | TU.OctetU | PADDING | + 00 80 00 00 + | TestString.length | + 0b 00 00 00 + | TestString[0] | TestString[1] | TestString[2] | TestString[3] | + 48 65 6c 6c + | TestString[4] | TestString[5] | TestString[6] | TestString[7] | + 6f 57 6f 72 + | TestString[8] | TestString[9] | TestString[10]|###############| + 6c 64 00 + diff --git a/src/rtps_config_package.vhd b/src/rtps_config_package.vhd index 85ba376..3fb143e 100644 --- a/src/rtps_config_package.vhd +++ b/src/rtps_config_package.vhd @@ -43,7 +43,6 @@ package rtps_config_package is type HISTORY_CACHE_OPCODE_TYPE is (NOP, ADD_CACHE_CHANGE, GET_CACHE_CHANGE, ACK_CACHE_CHANGE, NACK_CACHE_CHANGE, REMOVE_CACHE_CHANGE, REMOVE_WRITER, GET_MIN_SN, GET_MAX_SN); type KEY_HOLDER_OPCODE_TYPE is (NOP, PUSH_DATA, PUSH_SERIALIZED_KEY, READ_KEY_HASH, READ_SERIALIZED_KEY); - type KEY_GENERATOR_OPCODE_TYPE is (NOP, WRITE_PAYLOAD, READ_KEY, READ_SIZE); type HISTORY_CACHE_RESPONSE_TYPE is (OK, REJECTED, INVALID, ERROR); type DDS_WRITER_OPCODE_TYPE is (NOP, REGISTER_INSTANCE, WRITE, DISPOSE, UNREGISTER_INSTANCE, LOOKUP_INSTANCE, WAIT_FOR_ACKNOWLEDGEMENTS, GET_OFFERED_DEADLINE_MISSED_STATUS, ASSERT_LIVELINESS, GET_LIVELINESS_LOST_STATUS); type DDS_READER_OPCODE_TYPE is (NOP, READ, TAKE, READ_NEXT_SAMPLE, TAKE_NEXT_SAMPLE, READ_INSTANCE, TAKE_INSTANCE, READ_NEXT_INSTANCE, TAKE_NEXT_INSTANCE, GET_SAMPLE_REJECTED_STATUS, GET_REQUESTED_DEADLINE_MISSED_STATUS); @@ -140,6 +139,19 @@ package rtps_config_package is function gen_inline_qos (id : natural) return OUTPUT_DATA_TYPE; + -- Indexing Function to extract sub-vectors from std_logic_vector signals + -- input SLV from which to extract a sub-vector + -- index The SLV is divided in width-sized sub-vectors. index states which sub-vector to extract (depending on invert) + -- width width of sub-vector (NOTE: SLV must have a length multiple to width) + -- invert If invert=TRUE, index 0 is the leftmost sub-vector, else the rightmost + function get_sub_vector (input : std_logic_vector; index : natural; width : natural; invert : boolean) return std_logic_vector; + -- Indexing Function to write sub-vectors to std_logic_vector signals + -- input SLV from to which to write a sub-vector + -- sub Sub-vector to write into the SLV + -- index The SLV is divided in sub-sized 'sub'-vectors. index states which sub-vector to write (depending on invert) + -- invert If invert=TRUE, index 0 is the leftmost sub-vector, else the rightmost + function write_sub_vector(input : std_logic_vector; sub : std_logic_vector; index : natural; invert : boolean) return std_logic_vector; + end package; package body rtps_config_package is @@ -1200,4 +1212,36 @@ package body rtps_config_package is end if; end function; + function get_sub_vector (input : std_logic_vector; index : natural; width : natural; invert : boolean) return std_logic_vector is + variable ret : std_logic_vector(width-1 downto 0) := (others => '0'); + begin + assert(input'length mod width = 0) report "Input Length has to be multiple of width" severity FAILURE; + assert(input'length / width > index) report "Index out of bounds" severity FAILURE; + + if (invert = TRUE) then + ret := input(input'length-(index*width)-1 downto input'length-((index+1)*width)); + else + ret := input(((index+1)*width)-1 downto index*width); + end if; + + return ret; + end function; + + function write_sub_vector(input : std_logic_vector; sub : std_logic_vector; index : natural; invert : boolean) return std_logic_vector is + variable ret : std_logic_vector(input'length-1 downto 0) := (others => '0'); + begin + assert(input'length mod sub'length = 0) report "Input Length has to be multiple of sub width" severity FAILURE; + assert(input'length / sub'length > index) report "Index out of bounds" severity FAILURE; + + ret := input; + + if (invert = TRUE) then + ret(input'length-(index*sub'length)-1 downto input'length-((index+1)*sub'length)) := sub; + else + ret(((index+1)*sub'length)-1 downto index*sub'length) := sub; + end if; + + return ret; + end function; + end package body;