diff --git a/sim/modelsim.ini b/sim/modelsim.ini index d35ad92..ea112b1 100644 --- a/sim/modelsim.ini +++ b/sim/modelsim.ini @@ -19,7 +19,7 @@ others = $MODEL_TECH/../modelsim.ini default = W:/HDL-SIM/OSVVM-Scripts/../sim/VHDL_LIBS/ModelSim-2020.02/default.lib osvvm = W:/HDL-SIM/OSVVM-Scripts/../sim/VHDL_LIBS/ModelSim-2020.02/osvvm.lib -Testbench-Lib = W:/HDL-SIM/OSVVM-Scripts/../sim/VHDL_LIBS/ModelSim-2020.02/Testbench-Lib.lib +Testbench-Lib1 = W:/HDL-SIM/OSVVM-Scripts/../sim/VHDL_LIBS/ModelSim-2020.02/Testbench-Lib1.lib [vcom] ; VHDL93 variable selects language version as the default. ; Default is VHDL-2002. diff --git a/src/Tests/Level_1/L1_Type1_key_holder_test1.vhd b/src/Tests/Level_1/L1_Type1_key_holder_test1.vhd new file mode 100644 index 0000000..efbd542 --- /dev/null +++ b/src/Tests/Level_1/L1_Type1_key_holder_test1.vhd @@ -0,0 +1,311 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library osvvm; -- Utility Library +context osvvm.OsvvmContext; + +use work.rtps_package.all; +use work.user_config.all; +use work.rtps_config_package.all; +use work.rtps_test_package.all; +use work.Type2_package.all; + +-- This testbench tests the KEY_HOLDER commands of TYPE1. +-- It uses the writer_wrapper to send a valid TYPE2 payload, then reads the serialized key and the key hash. The returned serialized key is compared to a "handcrafted" reference, and the key hash is latched for later comparison. +-- Then the reference serialized key is pushed (resetting the internaly generated key hash), and the serialized key and key hash are re-read and compared (The key hash is compared to the previosuly compared). +-- The TYPE2 payload is sent in Big Endian. + +entity L1_Type1_key_holder_test1 is +end entity; + +architecture testbench of L1_Type1_key_holder_test1 is + + signal clk, reset : std_logic := '0'; + signal ready_sk, ready_w, ready_kh_in, ready_kh_out, valid_sk, valid_w, valid_kh_in, valid_kh_out, last_word_sk, last_word_w, last_word_kh_in, last_word_kh_out : std_logic := '0'; + signal data_sk, data_w, data_kh_in, data_kh_out : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0'); + signal start_w, ack_w, start_kh, ack_kh, decode_error, encode_done : std_logic := '0'; + signal opcode_kh : KEY_HOLDER_OPCODE_TYPE := NOP; + shared variable SB_out : osvvm.ScoreBoardPkg_slv.ScoreBoardPType; + shared variable serialized_key : TEST_PACKET_TYPE := EMPTY_TEST_PACKET; + signal key_hash, key_hash_latch : KEY_HASH_TYPE := HANDLE_NIL; + + signal id_in : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); + signal a_in : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); +begin + + Type1_writer_wrapper_inst : entity work.Type1_writer_wrapper(arch) + port map ( + clk => clk, + reset => reset, + start_dds => open, + ack_dds => '1', + opcode_dds => open, + instance_handle_dds => open, + source_ts_dds => open, + max_wait_dds => open, + done_dds => '1', + return_code_dds => RETCODE_OK, + ready_out_dds => ready_w, + valid_out_dds => valid_w, + data_out_dds => data_w, + last_word_out_dds => last_word_w, + ready_in_dds => open, + valid_in_dds => '0', + data_in_dds => (others => '0'), + last_word_in_dds => '0', + status_dds => (others => '0'), + start_user => start_w, + ack_user => ack_w, + opcode_user => WRITE, + instance_handle_user => HANDLE_NIL, + source_ts_user => TIME_ZERO, + max_wait_user => TIME_INFINITE, + done_user => open, + return_code_user => open, + ready_out_user => '1', + valid_out_user => open, + data_out_user => open, + last_word_out_user => open, + status_user => open, + encode_done => encode_done, + id => id_in, + a => a_in + ); + + uut : entity work.key_holder(TYPE1) + port map ( + clk => clk, + reset => reset, + start => start_kh, + opcode => opcode_kh, + ack => ack_kh, + decode_error => decode_error, + data_in => data_kh_in, + valid_in => valid_kh_in, + ready_in => ready_kh_in, + last_word_in => last_word_kh_in, + data_out => data_kh_out, + valid_out => valid_kh_out, + ready_out => ready_kh_out, + last_word_out => last_word_kh_out + ); + + + stimulus_prc : process + variable RV : RandomPType; + variable align_offset : unsigned(MAX_ALIGN_OFFSET_WIDTH-1 downto 0) := (others => '0'); + variable SK, KH : AlertLogIDType; + + procedure wait_on_sig(signal sig : std_logic) is + begin + if (sig /= '1') then + wait on sig until sig = '1'; + end if; + end procedure; + + procedure push_sk is + begin + for i in 0 to serialized_key.length-1 loop + SB_out.Push(serialized_key.data(i)); + end loop; + end procedure; + + begin + + SetAlertLogName("Type1_key_holder - Level 1 - (Big Endian) - Generic"); + SetAlertEnable(FAILURE, TRUE); + SetAlertEnable(ERROR, TRUE); + SetAlertEnable(WARNING, TRUE); + SetLogEnable(DEBUG, FALSE); + SetLogEnable(PASSED, FALSE); + SetLogEnable(INFO, TRUE); + RV.InitSeed(RV'instance_name); + SK := GetAlertLogID("SerializedKey", ALERTLOG_BASE_ID); + KH := GetAlertLogID("KeyHash", ALERTLOG_BASE_ID); + + Log("Setting Data in Writer Side", INFO); + + start_w <= '0'; + wait until rising_edge(clk); + + -- Static + id_in <= RV.RandSlv(id_in'length); + a_in <= RV.RandSlv(a_in'length); + wait for 0 ns; + gen_CDR(id_in, ALIGN_4, align_offset, serialized_key); + + -- Finalize Serialized Key + if (align_offset(1 downto 0) /= "00") then + serialized_key.length := serialized_key.length + 1; + end if; + + push_sk; + + Log("Push DATA", INFO); + opcode_kh <= PUSH_DATA; + start_w <= '1'; + wait_on_sig(ack_w); + wait until rising_edge(clk); + start_w <= '0'; + start_kh <= '1'; + wait_on_sig(ack_kh); + wait until rising_edge(clk); + start_kh <= '0'; + wait_on_sig(last_word_kh_in); + wait_on_sig(ready_kh_in); + wait until rising_edge(clk); + + Log("Read and Compare Serialized Key", INFO); + opcode_kh <= READ_SERIALIZED_KEY; + start_kh <= '1'; + wait_on_sig(ack_kh); + wait until rising_edge(clk); + start_kh <= '0'; + wait_on_sig(last_word_kh_out); + wait_on_sig(ready_kh_out); + wait until rising_edge(clk); + + Log("Read Key Hash", INFO); + opcode_kh <= READ_KEY_HASH; + start_kh <= '1'; + wait_on_sig(ack_kh); + wait until rising_edge(clk); + start_kh <= '0'; + wait_on_sig(last_word_kh_out); + wait_on_sig(ready_kh_out); + wait until rising_edge(clk); + + Log("Push Serialized Key", INFO); + opcode_kh <= PUSH_SERIALIZED_KEY; + start_kh <= '1'; + wait_on_sig(ack_kh); + wait until rising_edge(clk); + start_kh <= '0'; + wait_on_sig(last_word_sk); + wait_on_sig(ready_sk); + wait until rising_edge(clk); + + push_sk; + Log("Read and Compare Serialized Key", INFO); + opcode_kh <= READ_SERIALIZED_KEY; + start_kh <= '1'; + wait_on_sig(ack_kh); + wait until rising_edge(clk); + start_kh <= '0'; + wait_on_sig(last_word_kh_out); + wait_on_sig(ready_kh_out); + wait until rising_edge(clk); + + -- Latch previous read Key Hash + key_hash_latch <= key_hash; + Log("Read and Compare Key Hash", INFO); + opcode_kh <= READ_KEY_HASH; + start_kh <= '1'; + wait_on_sig(ack_kh); + wait until rising_edge(clk); + start_kh <= '0'; + wait_on_sig(last_word_kh_out); + wait_on_sig(ready_kh_out); + wait until rising_edge(clk); + AffirmIfEqual(KH, to_unsigned(key_hash), to_unsigned(key_hash_latch)); + + TranscriptOpen(RESULTS_FILE, APPEND_MODE); + SetTranscriptMirror; + ReportAlerts; + TranscriptClose; + std.env.stop; + wait; + end process; + + clock_prc : process + begin + clk <= '0'; + wait for TEST_CLOCK_PERIOD/2; + clk <= '1'; + wait for TEST_CLOCK_PERIOD/2; + end process; + + alert_prc : process(all) + begin + if rising_edge(clk) then + Alertif(decode_error = '1', "The Reader signals a DECODE Error", ERROR); + end if; + end process; + + switch_prc : process(all) + begin + case (opcode_kh) is + when PUSH_SERIALIZED_KEY => + ready_sk <= ready_kh_in; + valid_kh_in <= valid_sk; + data_kh_in <= data_sk; + last_word_kh_in <= last_word_sk; + ready_w <= '0'; + when others => + ready_w <= ready_kh_in; + valid_kh_in <= valid_w; + data_kh_in <= data_w; + last_word_kh_in <= last_word_w; + ready_sk <= '0'; + end case; + end process; + + sk_prc : process(all) + variable cnt : natural := 0; + begin + if rising_edge(clk) then + valid_sk <= '1'; + data_sk <= serialized_key.data(cnt); + if (cnt = serialized_key.length-1) then + last_word_sk <= '1'; + end if; + + if (ready_sk = '1') then + if (cnt = serialized_key.length-1) then + cnt := 0; + else + cnt := cnt + 1; + end if; + end if; + end if; + end process; + + output_check_prc : process(all) + variable cnt : natural range 0 to 3 := 0; + begin + if rising_edge(clk) then + case (opcode_kh) is + when READ_KEY_HASH => + ready_kh_out <= '1'; + if (valid_kh_out = '1') then + key_hash(cnt) <= data_kh_out; + if (cnt = 3) then + cnt := 0; + Alertif(last_word_kh_out = '0', "last_word_in is 0"); + else + cnt := cnt + 1; + end if; + end if; + when READ_SERIALIZED_KEY => + ready_kh_out <= '1'; + if (valid_kh_out = '1') then + SB_out.Check(data_kh_out); + if (SB_out.empty) then + Alertif(last_word_kh_out = '0', "last_word_in is 0"); + end if; + end if; + when others => + ready_kh_out <= '0'; + end case; + end if; + end process; + + watchdog : process + begin + wait for 1 ms; + Alert("Test timeout", FAILURE); + std.env.stop; + end process; + +end architecture; \ No newline at end of file diff --git a/src/Tests/Level_1/L1_Type1_key_holder_test2.vhd b/src/Tests/Level_1/L1_Type1_key_holder_test2.vhd new file mode 100644 index 0000000..4611911 --- /dev/null +++ b/src/Tests/Level_1/L1_Type1_key_holder_test2.vhd @@ -0,0 +1,314 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library osvvm; -- Utility Library +context osvvm.OsvvmContext; + +use work.rtps_package.all; +use work.user_config.all; +use work.rtps_config_package.all; +use work.rtps_test_package.all; +use work.Type2_package.all; + +-- This testbench tests the KEY_HOLDER commands of TYPE1. +-- It uses the writer_wrapper to send a valid TYPE2 payload, then reads the serialized key and the key hash. The returned serialized key is compared to a "handcrafted" reference, and the key hash is latched for later comparison. +-- Then the reference serialized key is pushed (resetting the internaly generated key hash), and the serialized key and key hash are re-read and compared (The key hash is compared to the previosuly compared). +-- The TYPE2 payload is sent in Little Endian. + +entity L1_Type1_key_holder_test2 is +end entity; + +architecture testbench of L1_Type1_key_holder_test2 is + + signal clk, reset : std_logic := '0'; + signal ready_sk, ready_w, ready_kh_in, ready_kh_out, valid_sk, valid_w, valid_kh_in, valid_kh_out, last_word_sk, last_word_w, last_word_kh_in, last_word_kh_out : std_logic := '0'; + signal data_sk, data_w, data_kh_in, data_kh_out : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0'); + signal start_w, ack_w, start_kh, ack_kh, decode_error, encode_done : std_logic := '0'; + signal opcode_kh : KEY_HOLDER_OPCODE_TYPE := NOP; + shared variable SB_out : osvvm.ScoreBoardPkg_slv.ScoreBoardPType; + shared variable serialized_key : TEST_PACKET_TYPE := EMPTY_TEST_PACKET; + signal key_hash, key_hash_latch : KEY_HASH_TYPE := HANDLE_NIL; + + signal id_in : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); + signal a_in : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); +begin + + Type1_writer_wrapper_inst : entity work.Type1_writer_wrapper(arch) + generic map ( + LITTLE_ENDIAN => '1' + ) + port map ( + clk => clk, + reset => reset, + start_dds => open, + ack_dds => '1', + opcode_dds => open, + instance_handle_dds => open, + source_ts_dds => open, + max_wait_dds => open, + done_dds => '1', + return_code_dds => RETCODE_OK, + ready_out_dds => ready_w, + valid_out_dds => valid_w, + data_out_dds => data_w, + last_word_out_dds => last_word_w, + ready_in_dds => open, + valid_in_dds => '0', + data_in_dds => (others => '0'), + last_word_in_dds => '0', + status_dds => (others => '0'), + start_user => start_w, + ack_user => ack_w, + opcode_user => WRITE, + instance_handle_user => HANDLE_NIL, + source_ts_user => TIME_ZERO, + max_wait_user => TIME_INFINITE, + done_user => open, + return_code_user => open, + ready_out_user => '1', + valid_out_user => open, + data_out_user => open, + last_word_out_user => open, + status_user => open, + encode_done => encode_done, + id => id_in, + a => a_in + ); + + uut : entity work.key_holder(TYPE1) + port map ( + clk => clk, + reset => reset, + start => start_kh, + opcode => opcode_kh, + ack => ack_kh, + decode_error => decode_error, + data_in => data_kh_in, + valid_in => valid_kh_in, + ready_in => ready_kh_in, + last_word_in => last_word_kh_in, + data_out => data_kh_out, + valid_out => valid_kh_out, + ready_out => ready_kh_out, + last_word_out => last_word_kh_out + ); + + + stimulus_prc : process + variable RV : RandomPType; + variable align_offset : unsigned(MAX_ALIGN_OFFSET_WIDTH-1 downto 0) := (others => '0'); + variable SK, KH : AlertLogIDType; + + procedure wait_on_sig(signal sig : std_logic) is + begin + if (sig /= '1') then + wait on sig until sig = '1'; + end if; + end procedure; + + procedure push_sk is + begin + for i in 0 to serialized_key.length-1 loop + SB_out.Push(serialized_key.data(i)); + end loop; + end procedure; + + begin + + SetAlertLogName("Type1_key_holder - Level 1 - (Little Endian) - Generic"); + SetAlertEnable(FAILURE, TRUE); + SetAlertEnable(ERROR, TRUE); + SetAlertEnable(WARNING, TRUE); + SetLogEnable(DEBUG, FALSE); + SetLogEnable(PASSED, FALSE); + SetLogEnable(INFO, TRUE); + RV.InitSeed(RV'instance_name); + SK := GetAlertLogID("SerializedKey", ALERTLOG_BASE_ID); + KH := GetAlertLogID("KeyHash", ALERTLOG_BASE_ID); + + Log("Setting Data in Writer Side", INFO); + + start_w <= '0'; + wait until rising_edge(clk); + + -- Static + id_in <= RV.RandSlv(id_in'length); + a_in <= RV.RandSlv(a_in'length); + wait for 0 ns; + gen_CDR(id_in, ALIGN_4, align_offset, serialized_key); + + -- Finalize Serialized Key + if (align_offset(1 downto 0) /= "00") then + serialized_key.length := serialized_key.length + 1; + end if; + + push_sk; + + Log("Push DATA", INFO); + opcode_kh <= PUSH_DATA; + start_w <= '1'; + wait_on_sig(ack_w); + wait until rising_edge(clk); + start_w <= '0'; + start_kh <= '1'; + wait_on_sig(ack_kh); + wait until rising_edge(clk); + start_kh <= '0'; + wait_on_sig(last_word_kh_in); + wait_on_sig(ready_kh_in); + wait until rising_edge(clk); + + Log("Read and Compare Serialized Key", INFO); + opcode_kh <= READ_SERIALIZED_KEY; + start_kh <= '1'; + wait_on_sig(ack_kh); + wait until rising_edge(clk); + start_kh <= '0'; + wait_on_sig(last_word_kh_out); + wait_on_sig(ready_kh_out); + wait until rising_edge(clk); + + Log("Read Key Hash", INFO); + opcode_kh <= READ_KEY_HASH; + start_kh <= '1'; + wait_on_sig(ack_kh); + wait until rising_edge(clk); + start_kh <= '0'; + wait_on_sig(last_word_kh_out); + wait_on_sig(ready_kh_out); + wait until rising_edge(clk); + + Log("Push Serialized Key", INFO); + opcode_kh <= PUSH_SERIALIZED_KEY; + start_kh <= '1'; + wait_on_sig(ack_kh); + wait until rising_edge(clk); + start_kh <= '0'; + wait_on_sig(last_word_sk); + wait_on_sig(ready_sk); + wait until rising_edge(clk); + + push_sk; + Log("Read and Compare Serialized Key", INFO); + opcode_kh <= READ_SERIALIZED_KEY; + start_kh <= '1'; + wait_on_sig(ack_kh); + wait until rising_edge(clk); + start_kh <= '0'; + wait_on_sig(last_word_kh_out); + wait_on_sig(ready_kh_out); + wait until rising_edge(clk); + + -- Latch previous read Key Hash + key_hash_latch <= key_hash; + Log("Read and Compare Key Hash", INFO); + opcode_kh <= READ_KEY_HASH; + start_kh <= '1'; + wait_on_sig(ack_kh); + wait until rising_edge(clk); + start_kh <= '0'; + wait_on_sig(last_word_kh_out); + wait_on_sig(ready_kh_out); + wait until rising_edge(clk); + AffirmIfEqual(KH, to_unsigned(key_hash), to_unsigned(key_hash_latch)); + + TranscriptOpen(RESULTS_FILE, APPEND_MODE); + SetTranscriptMirror; + ReportAlerts; + TranscriptClose; + std.env.stop; + wait; + end process; + + clock_prc : process + begin + clk <= '0'; + wait for TEST_CLOCK_PERIOD/2; + clk <= '1'; + wait for TEST_CLOCK_PERIOD/2; + end process; + + alert_prc : process(all) + begin + if rising_edge(clk) then + Alertif(decode_error = '1', "The Reader signals a DECODE Error", ERROR); + end if; + end process; + + switch_prc : process(all) + begin + case (opcode_kh) is + when PUSH_SERIALIZED_KEY => + ready_sk <= ready_kh_in; + valid_kh_in <= valid_sk; + data_kh_in <= data_sk; + last_word_kh_in <= last_word_sk; + ready_w <= '0'; + when others => + ready_w <= ready_kh_in; + valid_kh_in <= valid_w; + data_kh_in <= data_w; + last_word_kh_in <= last_word_w; + ready_sk <= '0'; + end case; + end process; + + sk_prc : process(all) + variable cnt : natural := 0; + begin + if rising_edge(clk) then + valid_sk <= '1'; + data_sk <= serialized_key.data(cnt); + if (cnt = serialized_key.length-1) then + last_word_sk <= '1'; + end if; + + if (ready_sk = '1') then + if (cnt = serialized_key.length-1) then + cnt := 0; + else + cnt := cnt + 1; + end if; + end if; + end if; + end process; + + output_check_prc : process(all) + variable cnt : natural range 0 to 3 := 0; + begin + if rising_edge(clk) then + case (opcode_kh) is + when READ_KEY_HASH => + ready_kh_out <= '1'; + if (valid_kh_out = '1') then + key_hash(cnt) <= data_kh_out; + if (cnt = 3) then + cnt := 0; + Alertif(last_word_kh_out = '0', "last_word_in is 0"); + else + cnt := cnt + 1; + end if; + end if; + when READ_SERIALIZED_KEY => + ready_kh_out <= '1'; + if (valid_kh_out = '1') then + SB_out.Check(data_kh_out); + if (SB_out.empty) then + Alertif(last_word_kh_out = '0', "last_word_in is 0"); + end if; + end if; + when others => + ready_kh_out <= '0'; + end case; + end if; + end process; + + watchdog : process + begin + wait for 1 ms; + Alert("Test timeout", FAILURE); + std.env.stop; + end process; + +end architecture; \ No newline at end of file diff --git a/src/Tests/Level_1/L1_Type1_wrapper_test1.vhd b/src/Tests/Level_1/L1_Type1_wrapper_test1.vhd new file mode 100644 index 0000000..0384de7 --- /dev/null +++ b/src/Tests/Level_1/L1_Type1_wrapper_test1.vhd @@ -0,0 +1,220 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library osvvm; -- Utility Library +context osvvm.OsvvmContext; + +use work.rtps_package.all; +use work.user_config.all; +use work.rtps_config_package.all; +use work.rtps_test_package.all; +use work.Type2_package.all; + +-- This testbench tests the Payload encoding/decoding of the TYPE1_wrapper entities. +-- It does so by interconnecting the writer and reader wrapper, setting some inputs to the writer and checking if the reader returns the same data. +-- This testbench tests only the Big Endian encoding/decoding. + +entity L1_Type1_wrapper_test1 is +end entity; + +architecture testbench of L1_Type1_wrapper_test1 is + + signal clk, reset : std_logic := '0'; + signal ready, valid, last_word : std_logic := '0'; + signal data : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0'); + signal start_w, get_data_r, decode_error, valid_r, encode_done : std_logic := '0'; + + signal id_in, id_out : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); + signal a_in, a_out : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); +begin + + uut_w : entity work.Type1_writer_wrapper(arch) + port map ( + clk => clk, + reset => reset, + start_dds => open, + ack_dds => '1', + opcode_dds => open, + instance_handle_dds => open, + source_ts_dds => open, + max_wait_dds => open, + done_dds => '1', + return_code_dds => RETCODE_OK, + ready_out_dds => ready, + valid_out_dds => valid, + data_out_dds => data, + last_word_out_dds => last_word, + ready_in_dds => open, + valid_in_dds => '0', + data_in_dds => (others => '0'), + last_word_in_dds => '0', + status_dds => (others => '0'), + start_user => start_w, + ack_user => open, + opcode_user => WRITE, + instance_handle_user => HANDLE_NIL, + source_ts_user => TIME_ZERO, + max_wait_user => TIME_INFINITE, + done_user => open, + return_code_user => open, + ready_out_user => '1', + valid_out_user => open, + data_out_user => open, + last_word_out_user => open, + status_user => open, + encode_done => encode_done, + id => id_in, + a => a_in + ); + + uut_r : entity work.Type1_reader_wrapper(arch) + port map ( + clk => clk, + reset => reset, + start_dds => open, + ack_dds => '1', + opcode_dds => open, + instance_state_dds => open, + view_state_dds => open, + sample_state_dds => open, + instance_handle_dds => open, + max_samples_dds => open, + get_data_dds => open, + done_dds => '1', + return_code_dds => RETCODE_OK, + ready_in_dds => ready, + valid_in_dds => valid, + data_in_dds => data, + last_word_in_dds => last_word, + si_sample_state_dds => (others => '0'), + si_view_state_dds => (others => '0'), + si_instance_state_dds => (others => '0'), + si_source_timestamp_dds => TIME_ZERO, + si_instance_handle_dds => HANDLE_NIL, + si_publication_handle_dds => GUID_UNKNOWN, + si_disposed_generation_count_dds => (others => '0'), + si_no_writers_generation_count_dds => (others => '0'), + si_sample_rank_dds => (others => '0'), + si_generation_rank_dds => (others => '0'), + si_absolute_generation_rank_dds => (others => '0'), + si_valid_data_dds => '1', + si_valid_dds => '1', + si_ack_dds => open, + eoc_dds => '1', + status_dds => (others => '0'), + start_user => '0', + ack_user => open, + opcode_user => NOP, + instance_state_user => (others => '0'), + view_state_user => (others => '0'), + sample_state_user => (others => '0'), + instance_handle_user => HANDLE_NIL, + max_samples_user => (others => '0'), + get_data_user => get_data_r, + done_user => open, + return_code_user => open, + si_sample_state_user => open, + si_view_state_user => open, + si_instance_state_user => open, + si_source_timestamp_user => open, + si_instance_handle_user => open, + si_publication_handle_user => open, + si_disposed_generation_count_user => open, + si_no_writers_generation_count_user => open, + si_sample_rank_user => open, + si_generation_rank_user => open, + si_absolute_generation_rank_user => open, + si_valid_data_user => open, + si_valid_user => open, + si_ack_user => '1', + eoc_user => open, + status_user => open, + decode_error => decode_error, + id => id_out, + a => a_out, + valid => valid_r + ); + + stimulus_prc : process + variable RV : RandomPType; + variable ID, A : AlertLogIDType; + + procedure wait_on_sig(signal sig : std_logic) is + begin + if (sig /= '1') then + wait on sig until sig = '1'; + end if; + end procedure; + begin + + SetAlertLogName("Type1_wrapper - Level 1 - (Big Endian) - Encoding/Decoding"); + SetAlertEnable(FAILURE, TRUE); + SetAlertEnable(ERROR, TRUE); + SetAlertEnable(WARNING, TRUE); + SetLogEnable(DEBUG, FALSE); + SetLogEnable(PASSED, FALSE); + SetLogEnable(INFO, TRUE); + RV.InitSeed(RV'instance_name); + ID := GetAlertLogID("ID", ALERTLOG_BASE_ID); + A := GetAlertLogID("A", ALERTLOG_BASE_ID); + + Log("Setting Data in Writer Side", INFO); + + start_w <= '0'; + get_data_r <= '0'; + + -- Static + id_in <= RV.RandSlv(id_in'length); + a_in <= RV.RandSlv(a_in'length); + wait for 0 ns; + + + Log("Initiate Writer->Reader Transfer", INFO); + + start_w <= '1'; + get_data_r <= '1'; + wait until rising_edge(clk); + start_w <= '0'; + get_data_r <= '0'; + + Log("Wait until Transfer done", INFO); + wait_on_sig(encode_done); + wait_on_sig(valid_r); + + Log("Compare Writer and Reader Side", INFO); + AffirmIfEqual(ID, id_out, id_in); + AffirmIfEqual(A, a_out,a_in); + + + TranscriptOpen(RESULTS_FILE, APPEND_MODE); + SetTranscriptMirror; + ReportAlerts; + TranscriptClose; + std.env.stop; + wait; + end process; + + clock_prc : process + begin + clk <= '0'; + wait for TEST_CLOCK_PERIOD/2; + clk <= '1'; + wait for TEST_CLOCK_PERIOD/2; + end process; + + alert_prc : process(all) + begin + if rising_edge(clk) then + alertif(decode_error = '1', "The Reader signals a DECODE Error", ERROR); + end if; + end process; + + watchdog : process + begin + wait for 1 ms; + Alert("Test timeout", FAILURE); + std.env.stop; + end process; + +end architecture; \ No newline at end of file diff --git a/src/Tests/Level_1/L1_Type1_wrapper_test2.vhd b/src/Tests/Level_1/L1_Type1_wrapper_test2.vhd new file mode 100644 index 0000000..7a87572 --- /dev/null +++ b/src/Tests/Level_1/L1_Type1_wrapper_test2.vhd @@ -0,0 +1,223 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library osvvm; -- Utility Library +context osvvm.OsvvmContext; + +use work.rtps_package.all; +use work.user_config.all; +use work.rtps_config_package.all; +use work.rtps_test_package.all; +use work.Type2_package.all; + +-- This testbench tests the Payload encoding/decoding of the TYPE1_wrapper entities. +-- It does so by interconnecting the writer and reader wrapper, setting some inputs to the writer and checking if the reader returns the same data. +-- This testbench tests only the Little Endian encoding/decoding. + +entity L1_Type1_wrapper_test2 is +end entity; + +architecture testbench of L1_Type1_wrapper_test2 is + + signal clk, reset : std_logic := '0'; + signal ready, valid, last_word : std_logic := '0'; + signal data : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0'); + signal start_w, get_data_r, decode_error, valid_r, encode_done : std_logic := '0'; + + signal id_in, id_out : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); + signal a_in, a_out : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); +begin + + uut_w : entity work.Type1_writer_wrapper(arch) + generic map ( + LITTLE_ENDIAN => '1' + ) + port map ( + clk => clk, + reset => reset, + start_dds => open, + ack_dds => '1', + opcode_dds => open, + instance_handle_dds => open, + source_ts_dds => open, + max_wait_dds => open, + done_dds => '1', + return_code_dds => RETCODE_OK, + ready_out_dds => ready, + valid_out_dds => valid, + data_out_dds => data, + last_word_out_dds => last_word, + ready_in_dds => open, + valid_in_dds => '0', + data_in_dds => (others => '0'), + last_word_in_dds => '0', + status_dds => (others => '0'), + start_user => start_w, + ack_user => open, + opcode_user => WRITE, + instance_handle_user => HANDLE_NIL, + source_ts_user => TIME_ZERO, + max_wait_user => TIME_INFINITE, + done_user => open, + return_code_user => open, + ready_out_user => '1', + valid_out_user => open, + data_out_user => open, + last_word_out_user => open, + status_user => open, + encode_done => encode_done, + id => id_in, + a => a_in + ); + + uut_r : entity work.Type1_reader_wrapper(arch) + port map ( + clk => clk, + reset => reset, + start_dds => open, + ack_dds => '1', + opcode_dds => open, + instance_state_dds => open, + view_state_dds => open, + sample_state_dds => open, + instance_handle_dds => open, + max_samples_dds => open, + get_data_dds => open, + done_dds => '1', + return_code_dds => RETCODE_OK, + ready_in_dds => ready, + valid_in_dds => valid, + data_in_dds => data, + last_word_in_dds => last_word, + si_sample_state_dds => (others => '0'), + si_view_state_dds => (others => '0'), + si_instance_state_dds => (others => '0'), + si_source_timestamp_dds => TIME_ZERO, + si_instance_handle_dds => HANDLE_NIL, + si_publication_handle_dds => GUID_UNKNOWN, + si_disposed_generation_count_dds => (others => '0'), + si_no_writers_generation_count_dds => (others => '0'), + si_sample_rank_dds => (others => '0'), + si_generation_rank_dds => (others => '0'), + si_absolute_generation_rank_dds => (others => '0'), + si_valid_data_dds => '1', + si_valid_dds => '1', + si_ack_dds => open, + eoc_dds => '1', + status_dds => (others => '0'), + start_user => '0', + ack_user => open, + opcode_user => NOP, + instance_state_user => (others => '0'), + view_state_user => (others => '0'), + sample_state_user => (others => '0'), + instance_handle_user => HANDLE_NIL, + max_samples_user => (others => '0'), + get_data_user => get_data_r, + done_user => open, + return_code_user => open, + si_sample_state_user => open, + si_view_state_user => open, + si_instance_state_user => open, + si_source_timestamp_user => open, + si_instance_handle_user => open, + si_publication_handle_user => open, + si_disposed_generation_count_user => open, + si_no_writers_generation_count_user => open, + si_sample_rank_user => open, + si_generation_rank_user => open, + si_absolute_generation_rank_user => open, + si_valid_data_user => open, + si_valid_user => open, + si_ack_user => '1', + eoc_user => open, + status_user => open, + decode_error => decode_error, + id => id_out, + a => a_out, + valid => valid_r + ); + + stimulus_prc : process + variable RV : RandomPType; + variable ID, A : AlertLogIDType; + + procedure wait_on_sig(signal sig : std_logic) is + begin + if (sig /= '1') then + wait on sig until sig = '1'; + end if; + end procedure; + begin + + SetAlertLogName("Type1_wrapper - Level 1 - (Little Endian) - Encoding/Decoding"); + SetAlertEnable(FAILURE, TRUE); + SetAlertEnable(ERROR, TRUE); + SetAlertEnable(WARNING, TRUE); + SetLogEnable(DEBUG, FALSE); + SetLogEnable(PASSED, FALSE); + SetLogEnable(INFO, TRUE); + RV.InitSeed(RV'instance_name); + ID := GetAlertLogID("ID", ALERTLOG_BASE_ID); + A := GetAlertLogID("A", ALERTLOG_BASE_ID); + + Log("Setting Data in Writer Side", INFO); + + start_w <= '0'; + get_data_r <= '0'; + + -- Static + id_in <= RV.RandSlv(id_in'length); + a_in <= RV.RandSlv(a_in'length); + wait for 0 ns; + + + Log("Initiate Writer->Reader Transfer", INFO); + + start_w <= '1'; + get_data_r <= '1'; + wait until rising_edge(clk); + start_w <= '0'; + get_data_r <= '0'; + + Log("Wait until Transfer done", INFO); + wait_on_sig(encode_done); + wait_on_sig(valid_r); + + Log("Compare Writer and Reader Side", INFO); + AffirmIfEqual(ID, id_out, id_in); + AffirmIfEqual(A, a_out,a_in); + + + TranscriptOpen(RESULTS_FILE, APPEND_MODE); + SetTranscriptMirror; + ReportAlerts; + TranscriptClose; + std.env.stop; + wait; + end process; + + clock_prc : process + begin + clk <= '0'; + wait for TEST_CLOCK_PERIOD/2; + clk <= '1'; + wait for TEST_CLOCK_PERIOD/2; + end process; + + alert_prc : process(all) + begin + if rising_edge(clk) then + alertif(decode_error = '1', "The Reader signals a DECODE Error", ERROR); + end if; + end process; + + watchdog : process + begin + wait for 1 ms; + Alert("Test timeout", FAILURE); + std.env.stop; + end process; + +end architecture; \ No newline at end of file diff --git a/src/Tests/Type1.idl b/src/Tests/Type1.idl new file mode 100644 index 0000000..a7f868f --- /dev/null +++ b/src/Tests/Type1.idl @@ -0,0 +1,5 @@ +@extensibility(FINAL) +struct Type1 { + @key long id; + long a; +}; \ No newline at end of file diff --git a/src/Tests/Type1_key_holder.vhd b/src/Tests/Type1_key_holder.vhd new file mode 100644 index 0000000..74afab7 --- /dev/null +++ b/src/Tests/Type1_key_holder.vhd @@ -0,0 +1,518 @@ +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.Type1_package.all; + +architecture TYPE1 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,PUSH,ALIGN_OUT_STREAM,SERIALIZE_KEY,GET_KEY_HASH,PUSH_KEY_HASH); + -- ###GENERATED START### + type DECODE_STAGE_TYPE is (GET_OPTIONAL_HEADER, GET_ID); + type ENCODE_STAGE_TYPE is (WRITE_ID); + -- ###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'; + signal start_kh, ack_kh, done_kh : std_logic := '0'; + signal data_in_kh : std_logic_vector(BYTE_WIDTH-1 downto 0) := (others => '0'); + signal valid_in_kh, ready_in_kh, last_word_in_kh : std_logic := '0'; + signal key_hash_kh : 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; + -- ###GENERATED START### + signal id_latch, id_latch_next : std_logic_vector(CDR_LONG_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(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 + ); + + 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; + 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'; + data_in_kh <= (others => '0'); + data_out <= (others => '0'); + -- ###GENERATED START### + id_latch_next <= id_latch; + -- ###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; + + -- Alignment Reset + align_offset_next <= (others => '0'); + -- ###GENERATED START### + decode_stage_next <= GET_ID; + -- ###GENERATED END### + when READ_KEY_HASH => + ack <= '1'; + -- Key Hash not calculated + if (key_hash = HANDLE_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'; + stage_next <= SERIALIZE_KEY; + -- Alignment Reset + align_offset_next <= (others => '0'); + data_out_latch_next <= (others => '0'); + -- ###GENERATED START### + encode_stage_next <= WRITE_ID; + -- ###GENERATED END### + when others => + null; + end case; + end if; + when START_KEY_HASH_GENERATION => + start_kh <= '1'; + + if (ack_kh = '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; + -- Alignment Reset + align_offset_next <= (others => '0'); + -- ###GENERATED START### + decode_stage_next <= GET_ID; + -- ###GENERATED END### + when CDR_LE => + endian_flag_next <= '1'; + stage_next <= FETCH; + -- Alignment Reset + align_offset_next <= (others => '0'); + -- ###GENERATED START### + decode_stage_next <= GET_ID; + -- ###GENERATED END### + 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 GET_ID => + -- ALIGN GUARD + 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 + stage_next <= SKIP_PAYLOAD; + end if; + -- ###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 PUSH => + -- Push to Key Hash Generator + 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_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 ((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 => + case (encode_stage) is + -- ###GENERATED START### + when WRITE_ID => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_4)) then + target_align_next <= ALIGN_4; + stage_next <= ALIGN_OUT_STREAM; + else + data_out_latch_next <= id_latch; + align_offset_next <= align_offset + 4; + -- DONE + stage_next <= PUSH; + finalize_payload_next <= '1'; + end if; + -- ###GENERATED END### + when others => + 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; + + -- OVERREAD GUARD + -- Attempted read on empty input + if (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 <= 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_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 <= HANDLE_NIL; + -- ###GENERATED START### + id_latch <= (others => '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_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### + id_latch <= id_latch_next; + -- ###GENERATED END### + end if; + end if; + end process; + +end architecture; \ No newline at end of file diff --git a/src/Tests/Type1_package.vhd b/src/Tests/Type1_package.vhd new file mode 100644 index 0000000..14cb054 --- /dev/null +++ b/src/Tests/Type1_package.vhd @@ -0,0 +1,18 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.rtps_package.all; +use work.math_pkg.all; + +package Type1_package is + + + + constant MAX_ID_SIZE : natural := 4; + constant MAX_A_SIZE : natural := 4; -- 8 + constant MAX_TYPE1_SIZE : natural := 8; + + constant MAX_TYPE1_KEY_HOLDER_SIZE : natural := 4; + +end package; \ No newline at end of file diff --git a/src/Tests/Type1_reader_wrapper.vhd b/src/Tests/Type1_reader_wrapper.vhd new file mode 100644 index 0000000..07e487f --- /dev/null +++ b/src/Tests/Type1_reader_wrapper.vhd @@ -0,0 +1,416 @@ +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.Type1_package.all; + +entity Type1_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; + + -- ###GENERATED START### + id : out std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + a : out std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + -- ###GENERATED END### + valid : out std_logic + ); +end entity; + +architecture arch of Type1_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_A, GET_OPTIONAL_HEADER); + -- ###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'; + signal valid_latch, valid_latch_next : std_logic := '0'; + signal decode_stage, decode_stage_next : DECODE_STAGE_TYPE := GET_ID; + signal return_stage, return_stage_next : DECODE_STAGE_TYPE := GET_ID; + -- ###GENERATED START### + signal id_latch, id_latch_next : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); + signal a_latch, a_latch_next : std_logic_vector(CDR_LONG_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_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 + + -- 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; + a <= a_latch; + -- ###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; + align_op_next <= align_op; + abort_mem <= '0'; + ready_in_dds_sig <= '0'; + -- ###GENERATED START### + id_latch_next <= id_latch; + a_latch_next <= a_latch; + -- ###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 + null; + 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; + -- Alignment Reset + align_offset_next <= (others => '0'); + -- ###GENERATED START### + decode_stage_next <= GET_ID; + -- ###GENERATED END### + -- Initial Fetch + when CDR_LE => + endian_flag_next <= '1'; + stage_next <= FETCH; + -- Alignment Reset + align_offset_next <= (others => '0'); + -- ###GENERATED START### + decode_stage_next <= GET_ID; + -- ###GENERATED END### + 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 => + case (decode_stage) is + -- ###GENERATED START### + 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_A; + end if; + when GET_A => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_4)) then + target_align_next <= ALIGN_4; + stage_next <= ALIGN_STREAM; + else + a_latch_next <= endian_swap(endian_flag, data_in_latch); + align_offset_next <= align_offset + 4; + stage_next <= FETCH; + -- Next Member + stage_next <= SKIP_PAYLOAD; + end if; + -- ###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_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_dds) = (data_in_dds'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 others => + null; + end case; + + -- OVERREAD GUARD + -- Attempted read on empty input + if (last_word_in_latch = '1' and last_word_in_dds = '0' 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'); + -- ###GENERATED START### + id_latch <= (others => '0'); + a_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; + -- ###GENERATED START### + id_latch <= id_latch_next; + a_latch <= a_latch_next; + -- ###GENERATED END### + end if; + end if; + end process; + +end architecture; \ No newline at end of file diff --git a/src/Tests/Type1_writer_wrapper.vhd b/src/Tests/Type1_writer_wrapper.vhd new file mode 100644 index 0000000..96a3656 --- /dev/null +++ b/src/Tests/Type1_writer_wrapper.vhd @@ -0,0 +1,260 @@ +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.Type1_package.all; + +entity Type1_writer_wrapper is + generic ( + LITTLE_ENDIAN : std_logic := '0' + ); + port ( + -- SYSTEM + clk : in std_logic; + reset : in std_logic; + -- FROM DDS WRITER + start_dds : out std_logic; + ack_dds : in std_logic; + opcode_dds : out DDS_WRITER_OPCODE_TYPE; + instance_handle_dds : out INSTANCE_HANDLE_TYPE; + source_ts_dds : out TIME_TYPE; + max_wait_dds : out DURATION_TYPE; + done_dds : in std_logic; + return_code_dds : in std_logic_vector(RETURN_CODE_WIDTH-1 downto 0); + ready_out_dds : in std_logic; + valid_out_dds : out std_logic; + data_out_dds : out std_logic_vector(WORD_WIDTH-1 downto 0); + last_word_out_dds : out std_logic; + 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; + -- 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_WRITER_OPCODE_TYPE; + instance_handle_user : in INSTANCE_HANDLE_TYPE; + source_ts_user : in TIME_TYPE; + max_wait_user : in DURATION_TYPE; + done_user : out std_logic; + return_code_user : out std_logic_vector(RETURN_CODE_WIDTH-1 downto 0); + ready_out_user : in std_logic; + valid_out_user : out std_logic; + data_out_user : out std_logic_vector(WORD_WIDTH-1 downto 0); + last_word_out_user : out std_logic; + -- Communication Status + status_user : out std_logic_vector(STATUS_KIND_WIDTH-1 downto 0); + + -- ###GENERATED START### + id : in std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + a : in std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + -- ###GENERATED END### + + encode_done : out std_logic + ); +end entity; + +architecture arch of Type1_writer_wrapper is + + --*****TYPE DECLARATION***** + -- FSM states. Explained below in detail + type STAGE_TYPE is (IDLE,WRITE_PAYLOAD_HEADER,PUSH,ALIGN_STREAM,ENCODE_PAYLOAD); + -- ###GENERATED START### + type ENCODE_STAGE_TYPE is (WRITE_ID, WRITE_A); + -- TYPES DECLARATIONS + -- ###GENERATED END### + + -- *MAIN PROCESS* + signal stage, stage_next : STAGE_TYPE := IDLE; + signal cnt, cnt_next : natural range 0 to 5 := 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_out_latch, data_out_latch_next : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0'); + signal abort_mem : std_logic := '0'; + signal finalize_payload, finalize_payload_next : std_logic := '0'; + signal encode_stage, encode_stage_next : ENCODE_STAGE_TYPE := WRITE_ID; + + +begin + + -- PASSTHROUGH + start_dds <= start_user; + ack_user <= ack_dds; + opcode_dds <= opcode_user; + instance_handle_dds <= instance_handle_user; + source_ts_dds <= source_ts_user; + max_wait_dds <= max_wait_user; + done_user <= done_dds; + return_code_user <= return_code_dds; + ready_in_dds <= ready_out_user; + valid_out_user <= valid_in_dds; + data_out_user <= data_in_dds; + last_word_out_user <= last_word_in_dds; + status_user <= status_dds; + + main_prc : process (all) + variable tmp_length : unsigned(WORD_WIDTH-1 downto 0) := (others => '0'); + begin + -- DEFAULT + stage_next <= stage; + encode_stage_next <= encode_stage; + cnt_next <= cnt; + align_offset_next <= align_offset; + align_op_next <= align_op; + target_align_next <= target_align; + data_out_latch_next <= data_out_latch; + finalize_payload_next <= finalize_payload; + abort_mem <= '0'; + encode_done <= '0'; + valid_out_dds <= '0'; + last_word_out_dds <= '0'; + data_out_dds <= (others => '0'); + + case (stage) is + when IDLE => + -- User Requests Payload + if (start_user = '1' and ack_dds = '1') then + case (opcode_user) is + when REGISTER_INSTANCE => + stage_next <= WRITE_PAYLOAD_HEADER; + -- RESET + abort_mem <= '1'; + when UNREGISTER_INSTANCE => + stage_next <= WRITE_PAYLOAD_HEADER; + -- RESET + abort_mem <= '1'; + when LOOKUP_INSTANCE => + stage_next <= WRITE_PAYLOAD_HEADER; + -- RESET + abort_mem <= '1'; + when WRITE => + stage_next <= WRITE_PAYLOAD_HEADER; + -- RESET + abort_mem <= '1'; + when DISPOSE => + stage_next <= WRITE_PAYLOAD_HEADER; + -- RESET + abort_mem <= '1'; + when others => + null; + end case; + else + null; + end if; + when WRITE_PAYLOAD_HEADER => + if (LITTLE_ENDIAN = '0') then + data_out_latch_next <= CDR_BE & x"0000"; + else + data_out_latch_next <= CDR_LE & x"0000"; + end if; + stage_next <= PUSH; + -- ###GENERATED START### + encode_stage_next <= WRITE_ID; + -- ###GENERATED END### + when PUSH => + -- Mark Last Word + if (finalize_payload = '1') then + last_word_out_dds <= '1'; + end if; + + valid_out_dds <= '1'; + data_out_dds <= data_out_latch; + -- Output Guard + if (ready_out_dds = '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_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; + when ALIGN_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 WRITE_ID => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_4)) then + target_align_next <= ALIGN_4; + stage_next <= ALIGN_STREAM; + else + data_out_latch_next <= endian_swap(LITTLE_ENDIAN,id); + align_offset_next <= align_offset + 4; + stage_next <= PUSH; + -- Next Member + encode_stage_next <= WRITE_A; + end if; + when WRITE_A => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_4)) then + target_align_next <= ALIGN_4; + stage_next <= ALIGN_STREAM; + else + data_out_latch_next <= endian_swap(LITTLE_ENDIAN,a); + align_offset_next <= align_offset + 4; + -- DONE + stage_next <= PUSH; + finalize_payload_next <= '1'; + encode_done <= '1'; + end if; + -- ###GENERATED END### + when others => + null; + end case; + when others => + null; + end case; + end process; + + sync_prc : process(clk) + begin + if rising_edge(clk) then + if (reset = '1') then + stage <= IDLE; + encode_stage <= WRITE_ID; + target_align <= ALIGN_1; + cnt <= 0; + finalize_payload <= '0'; + align_op <= '0'; + align_offset <= (others => '0'); + data_out_latch <= (others => '0'); + else + stage <= stage_next; + encode_stage <= encode_stage_next; + target_align <= target_align_next; + cnt <= cnt_next; + finalize_payload <= finalize_payload_next; + align_op <= align_op_next; + align_offset <= align_offset_next; + data_out_latch <= data_out_latch_next; + end if; + end if; + end process; + +end architecture; \ No newline at end of file diff --git a/src/Tests/test_config.vhd b/src/Tests/test_config1.vhd similarity index 100% rename from src/Tests/test_config.vhd rename to src/Tests/test_config1.vhd diff --git a/src/Tests/testbench.pro b/src/Tests/testbench.pro index 8a0bb6b..8522a57 100644 --- a/src/Tests/testbench.pro +++ b/src/Tests/testbench.pro @@ -2,10 +2,10 @@ include ../OSVVM/osvvm.pro # Compile -library Testbench-Lib +library Testbench-Lib1 analyze ../math_pkg.vhd analyze ../rtps_package.vhd -analyze test_config.vhd +analyze test_config1.vhd analyze ../rtps_config_package.vhd analyze ../rtps_test_package.vhd analyze test_ram.vhd @@ -83,11 +83,19 @@ analyze Level_0/L0_dds_reader_test6_arzkriu.vhd analyze Level_0/L0_dds_reader_test7_arzkriu.vhd analyze ../key_holder.vhd analyze ../key_hash_generator.vhd +analyze test_key_hash_generator.vhd +analyze Type1_package.vhd +analyze Type1_reader_wrapper.vhd +analyze Type1_writer_wrapper.vhd +analyze Type1_key_holder.vhd analyze Type2_package.vhd analyze Type2_reader_wrapper.vhd analyze Type2_writer_wrapper.vhd analyze Type2_key_holder.vhd -analyze test_key_hash_generator.vhd +analyze Level_1/L1_Type1_wrapper_test1.vhd +analyze Level_1/L1_Type1_wrapper_test2.vhd +analyze Level_1/L1_Type1_key_holder_test1.vhd +analyze Level_1/L1_Type1_key_holder_test2.vhd analyze Level_1/L1_Type2_wrapper_test1.vhd analyze Level_1/L1_Type2_wrapper_test2.vhd analyze Level_1/L1_Type2_key_holder_test1.vhd @@ -154,6 +162,10 @@ simulate L0_dds_reader_test4_arznriu simulate L0_dds_reader_test5_arzkriu simulate L0_dds_reader_test6_arzkriu simulate L0_dds_reader_test7_arzkriu +simulate L1_Type1_wrapper_test1 +simulate L1_Type1_wrapper_test2 +simulate L1_Type1_key_holder_test1 +simulate L1_Type1_key_holder_test2 simulate L1_Type2_wrapper_test1 simulate L1_Type2_wrapper_test2 simulate L1_Type2_key_holder_test1