diff --git a/src/control_socbridge_merge/control_socbridge_tb.vhd b/src/control_socbridge_merge/control_socbridge_tb.vhd new file mode 100644 index 0000000..53ce62f --- /dev/null +++ b/src/control_socbridge_merge/control_socbridge_tb.vhd @@ -0,0 +1,273 @@ +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.NUMERIC_STD.all; +library ganimede; +use ganimede.io_types.all; +library socbridge; +use socbridge.socbridge_driver_tb_pkg.all; +library controller; + +entity control_socbridge_tb is +end entity control_socbridge_tb; + +architecture tb of control_socbridge_tb is + + constant CLK_PERIOD : Time := 10 ns; + constant SIMULATION_CYCLE_COUNT : integer := 200; + signal clk, rst : std_logic := '0'; + signal cu_to_sb_cmd: command_t; + signal cu_to_sb_address: std_logic_vector(31 downto 0); + signal cmd_size : positive; + signal ext_socbridge_in : ext_socbridge_in_t := ( + payload => (others => '0'), + control => (others => '0') + ); + signal ext_socbridge_out : ext_socbridge_out_t; + signal int_socbridge_out : int_socbridge_out_t; + signal int_socbridge_in : int_socbridge_in_t := ( + payload => (others => '0'), + write_enable_out => '0', + is_full_in => '0' + ); + signal ext_control_input: ext_control_unit_in_t := ( + driver_id => (others => '0'), + address => (others => '0'), + seq_mem_access_count => 0, + cmd => "00" + ); + signal int_control_input: int_control_unit_in_t := (active_driver => (others => '0')); + signal ext_control_output: ext_control_unit_out_t; + signal int_control_output: int_control_unit_out_t; + + signal driver_to_control: driver_to_control_t; + signal control_to_driver: control_to_driver_t; + + signal curr_word : std_logic_vector(ext_socbridge_in.payload'length - 1 downto 0); + signal expected_out : std_logic_vector(ext_socbridge_out.payload'length - 1 downto 0); + + procedure fail(error_msg : string) is + begin + wait for CLK_PERIOD; + report "Simulation ending due to: " & error_msg & ". Shutting down..." severity FAILURE; + end procedure; + + procedure check_next_state(correct_state: state_t) is + begin + if(not (correct_state = G_next_state)) then + report "Next State is not what was expected, found " & state_t'image(G_next_state) + & " but expected " & state_t'image(correct_state) severity error; + fail("Next State"); + end if; + end procedure; + + procedure check_data_out(correct_data: std_logic_vector(ext_socbridge_out.payload'length - 1 downto 0)) is + begin + if(not (correct_data = ext_socbridge_out.payload)) then + report "Data out is not what was expected, found " & to_string(ext_socbridge_out.payload) + & " but expected " & to_string(correct_data) severity error; + fail("Data out"); + end if; + end procedure; + + procedure check_parity(correct_data: std_logic_vector(ext_socbridge_out.payload'length - 1 downto 0)) is + begin + if(not (calc_parity(correct_data) = calc_parity(ext_socbridge_out.payload))) then + report "Parity out is not what was expected, found " & std_logic'image(calc_parity(ext_socbridge_out.payload)) + & " but expected " & std_logic'image(calc_parity(correct_data)) severity error; + fail("Parity out"); + end if; + end procedure; + +begin + socbridge_inst: entity socbridge.socbridge_driver + port map( + clk => clk, + rst => rst, + ctrl_in => control_to_driver, + ctrl_out => driver_to_control, + ext_in => ext_socbridge_in, + ext_out => ext_socbridge_out, + int_in => int_socbridge_in, + int_out => int_socbridge_out + ); + + control_unit_inst: entity controller.control_unit + port map( + clk => clk, + rst => rst, + ext_control_in => ext_control_input, + ext_control_out => ext_control_output, + int_control_in => int_control_input, + int_control_out => int_control_output + ); + + control_to_driver.address <= int_control_output.address; + control_to_driver.request <= int_control_output.driver_id(0); + control_to_driver.instruction <= int_control_output.instruction; + control_to_driver.seq_mem_access_count <= int_control_output.seq_mem_access_count; + + int_control_input.active_driver(0) <= driver_to_control.is_active; + + ext_socbridge_in.control(1) <= clk; + control_clock_proc: process + begin + for i in 0 to SIMULATION_CYCLE_COUNT - 1 loop + wait for CLK_PERIOD / 2; + clk <= not clk; + end loop; + wait; + end process control_clock_proc; + + stimulus_proc: process + begin + report "Starting Simulation Stimulus!"; + rst <= '1'; + ext_control_input.address <= (others => '0'); + ext_control_input.cmd <= "00"; + ext_control_input.driver_id <= "1"; + ext_control_input.seq_mem_access_count <= 2; + wait for 3 * CLK_PERIOD; + report "Reset grace period ended, starting stimulus..."; + rst <= '0'; + ext_control_input.address <= x"FA0FA0FA"; + ext_control_input.cmd <= "01"; + wait until int_control_input.active_driver(0) = '1'; + report "Task received in driver, awaiting completion..."; + ext_control_input.address <= (others => '0'); + ext_control_input.cmd <= "00"; + wait until int_control_input.active_driver(0) = '0'; + wait for CLK_PERIOD; + report "Task completed in driver, sending next task..."; + ext_control_input.address <= x"FA0FA0FA"; + ext_control_input.cmd <= "10"; + wait for CLK_PERIOD; + wait until int_control_input.active_driver(0) = '1'; + report "Task received in driver, awaiting completion..."; + ext_control_input.address <= (others => '0'); + ext_control_input.cmd <= "00"; + wait until int_control_input.active_driver(0) = '0'; + wait for CLK_PERIOD; + report "Task completed in driver, ending simulation stimulus"; + + wait; + end process stimulus_proc; + + external_stimulus_signal: process(curr_word) + begin + ext_socbridge_in.payload <= curr_word; + ext_socbridge_in.control(0) <= calc_parity(curr_word); + end process external_stimulus_signal; + + external_stimulus: process + begin + wait for CLK_PERIOD / 1000; + curr_word <= "00000000"; + wait for 999 * CLK_PERIOD / 1000; + wait for 2 * CLK_PERIOD; + wait for CLK_PERIOD / 2; + wait for 10* CLK_PERIOD; + curr_word <= "00001001"; + wait for CLK_PERIOD; + curr_word <= "00000000"; + wait for CLK_PERIOD * 20; + curr_word <= "00101001"; + wait for CLK_PERIOD; + curr_word <= "00000000"; + wait for CLK_PERIOD*10; + curr_word <= "01100001"; + wait for CLK_PERIOD; + curr_word <= "00100000"; + wait for CLK_PERIOD; + curr_word <= "00010000"; + wait for CLK_PERIOD; + curr_word <= "00000000"; + + + wait; + end process external_stimulus; + + internal_stimulus: process + variable input : positive := 1; + begin + int_socbridge_in.is_full_in <= '0'; + int_socbridge_in.write_enable_out <= '0'; + wait for 3 * CLK_PERIOD; + -- stimulus goes here + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + wait; + end process internal_stimulus; + +end architecture tb; diff --git a/src/controller/control_unit.vhd b/src/controller/control_unit.vhd index 00a4f5d..0371216 100644 --- a/src/controller/control_unit.vhd +++ b/src/controller/control_unit.vhd @@ -63,6 +63,12 @@ begin state.instruction <= WRITE when "01", READ when "10", NO_OP when others; + else + state <= ((others => '0'), + 0, + (others => '0'), + '1', + NO_OP); end if; end if; end if; diff --git a/src/ganimede/control_socbridge_tb.vhd b/src/ganimede/control_socbridge_tb.vhd deleted file mode 100644 index 0c46ec0..0000000 --- a/src/ganimede/control_socbridge_tb.vhd +++ /dev/null @@ -1,491 +0,0 @@ -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.NUMERIC_STD.all; -library ganimede; -use ganimede.io_types.all; -library socbridge; -use socbridge.socbridge_driver_tb_pkg.all; -library controller; - -entity control_socbridge_tb is -end entity control_socbridge_tb; - -architecture tb of control_socbridge_tb is - - constant CLK_PERIOD : Time := 10 ns; - constant SIMULATION_CYCLE_COUNT : integer := 100; - signal clk, rst : std_logic; - signal cu_to_sb_cmd: command_t; - signal cu_to_sb_address: std_logic_vector(31 downto 0); - signal cmd_size : positive; - signal ext_socbridge_in : ext_socbridge_in_t := ( - payload => (others => '0'), - control => (others => '0') - ); - signal ext_socbridge_out : ext_socbridge_out_t; - signal int_socbridge_out : int_socbridge_out_t; - signal int_socbridge_in : int_socbridge_in_t := ( - payload => (others => '0'), - write_enable_out => '0', - is_full_in => '0' - ); - signal ext_control_input: ext_control_unit_in_t := ( - driver_id => (others => '0'), - address => (others => '0'), - seq_mem_access_count => 0, - cmd => "00" - ); - signal int_control_input: int_control_unit_in_t := (active_driver => (others => '0')); - signal ext_control_output: ext_control_unit_out_t; - signal int_control_output: int_control_unit_out_t; - - signal driver_to_control: driver_to_control_t; - signal control_to_driver: control_to_driver_t; - - signal curr_word : std_logic_vector(ext_socbridge_in.payload'length - 1 downto 0); - signal expected_out : std_logic_vector(ext_socbridge_out.payload'length - 1 downto 0); - - procedure fail(error_msg : string) is - begin - wait for CLK_PERIOD; - report "Simulation ending due to: " & error_msg & ". Shutting down..." severity FAILURE; - end procedure; - - procedure check_next_state(correct_state: state_t) is - begin - if(not (correct_state = G_next_state)) then - report "Next State is not what was expected, found " & state_t'image(G_next_state) - & " but expected " & state_t'image(correct_state) severity error; - fail("Next State"); - end if; - end procedure; - - procedure check_data_out(correct_data: std_logic_vector(ext_socbridge_out.payload'length - 1 downto 0)) is - begin - if(not (correct_data = ext_socbridge_out.payload)) then - report "Data out is not what was expected, found " & to_string(ext_socbridge_out.payload) - & " but expected " & to_string(correct_data) severity error; - fail("Data out"); - end if; - end procedure; - - procedure check_parity(correct_data: std_logic_vector(ext_socbridge_out.payload'length - 1 downto 0)) is - begin - if(not (calc_parity(correct_data) = calc_parity(ext_socbridge_out.payload))) then - report "Parity out is not what was expected, found " & std_logic'image(calc_parity(ext_socbridge_out.payload)) - & " but expected " & std_logic'image(calc_parity(correct_data)) severity error; - fail("Parity out"); - end if; - end procedure; - -begin - - socbridge_inst: entity socbridge.socbridge_driver - port map( - clk => clk, - rst => rst, - ctrl_in => control_to_driver, - ctrl_out => driver_to_control, - ext_in => ext_socbridge_in, - ext_out => ext_socbridge_out, - int_in => int_socbridge_in, - int_out => int_socbridge_out - ); - - control_unit_inst: entity controller.control_unit - port map( - clk => clk, - rst => rst, - ext_control_in => ext_control_input, - ext_control_out => ext_control_output, - int_control_in => int_control_input, - int_control_out => int_control_output - ); - - control_to_driver.address <= int_control_output.address; - control_to_driver.request <= int_control_output.driver_id(0); - control_to_driver.instruction <= int_control_output.instruction; - control_to_driver.seq_mem_access_count <= int_control_output.seq_mem_access_count; - - int_control_input.active_driver(0) <= driver_to_control.is_active; - - control_clock_proc: process - begin - for i in 0 to 50 loop - wait for CLK_PERIOD / 2; - clk <= not clk; - end loop; - wait; - end process control_clock_proc; - - stimulus_proc: process - begin - ext_control_input.address <= (others => '0'); - ext_control_input.cmd <= "00"; - ext_control_input.driver_id <= "1"; - ext_control_input.seq_mem_access_count <= 2; - wait for 3 * CLK_PERIOD; - ext_control_input.address <= x"FA0FA0FA"; - ext_control_input.cmd <= "01"; - wait until int_control_input.active_driver(0) = '1'; - ext_control_input.address <= (others => '0'); - ext_control_input.cmd <= "00"; - wait until int_control_input.active_driver(0) = '0'; - wait for CLK_PERIOD; - ext_control_input.address <= x"FA0FA0FA"; - ext_control_input.cmd <= "10"; - wait until int_control_input.active_driver(0) = '1'; - ext_control_input.address <= (others => '0'); - ext_control_input.cmd <= "00"; - wait until int_control_input.active_driver(0) = '0'; - wait for CLK_PERIOD; - - - wait; - end process stimulus_proc; - - monitor_proc: process - begin - wait; - end process monitor_proc; - - ext_socbridge_in.control(1) <= clk; - real_clk_proc: process - begin - for x in 0 to SIMULATION_CYCLE_COUNT*2 loop - clk <= not clk; - wait for CLK_PERIOD / 2; - end loop; - wait; - end process real_clk_proc; - - external_stimulus_signal: process(curr_word) - begin - ext_socbridge_in.payload <= curr_word; - ext_socbridge_in.control(0) <= calc_parity(curr_word); - end process external_stimulus_signal; - - external_stimulus: process - begin - wait for CLK_PERIOD / 1000; - curr_word <= "00000000"; - wait for 999 * CLK_PERIOD / 1000; - wait for 2 * CLK_PERIOD; - wait for CLK_PERIOD / 2; - wait for 4* CLK_PERIOD; - curr_word <= "00001001"; - wait for CLK_PERIOD; - curr_word <= "00000000"; - wait for CLK_PERIOD * 14; - curr_word <= "00101001"; - wait for CLK_PERIOD; - curr_word <= "00000000"; - wait for CLK_PERIOD*5; - curr_word <= "01100001"; - wait for CLK_PERIOD; - curr_word <= "00100000"; - wait for CLK_PERIOD; - curr_word <= "00010000"; - wait for CLK_PERIOD; - curr_word <= "00000000"; - - - wait; - end process external_stimulus; - - internal_stimulus: process - variable input : integer := 0; - begin - int_socbridge_in.is_full_in <= '0'; - int_socbridge_in.write_enable_out <= '0'; - wait for 3 * CLK_PERIOD; - -- stimulus goes here - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - wait until falling_edge(clk); - wait; - end process internal_stimulus; - -end architecture tb; diff --git a/src/socbridge/socbridge_driver.vhd b/src/socbridge/socbridge_driver.vhd index fb5bf3c..7b51634 100644 --- a/src/socbridge/socbridge_driver.vhd +++ b/src/socbridge/socbridge_driver.vhd @@ -13,9 +13,6 @@ entity socbridge_driver is rst : in std_logic; ctrl_in : in control_to_driver_t; ctrl_out: out driver_to_control_t; - -- cmd : in command_t; - -- address : in std_logic_vector(31 downto 0); - -- cmd_size: in positive; ext_in : in ext_socbridge_in_t; ext_out : out ext_socbridge_out_t; int_out : out int_socbridge_out_t; @@ -50,6 +47,7 @@ begin G_curr_response <= curr_response; G_curr_response_bits <= curr_response_bits; G_st <= st; + G_trans_st <= trans_st; -- synthesis translate_on ext_in_rec.data <= ext_in.payload; ext_in_rec.clk <= ext_in.control(1); @@ -263,13 +261,16 @@ begin -- Wait for driver to go idle and send next instruction. Then enter AWAIT when SEND => if st.curr_state /= IDLE then - trans_next_state <= AWAIT; + trans_next_state <= SEND_ACCEPTED; else trans_next_state <= SEND; end if; + -- Transisitonal state to decrement counter in transition between SEND and AWAIT. + when SEND_ACCEPTED => + trans_next_state <= AWAIT; -- Wait for driver to finish current instruction, then reenter SEND when AWAIT => - if trans_st.curr_inst.seq_mem_access_count <= 0 then + if trans_st.curr_inst.seq_mem_access_count <= 0 and st.curr_state = IDLE then trans_next_state <= IDLE; elsif st.curr_state = IDLE then trans_next_state <= SEND; @@ -300,10 +301,12 @@ begin if trans_st.curr_inst.seq_mem_access_count > 256 then next_cmd_size <= 256; - else + elsif trans_st.curr_inst.seq_mem_access_count > 0 then next_cmd_size <= trans_st.curr_inst.seq_mem_access_count; + else + next_cmd_size <= 0; end if; - when AWAIT => + when others => end case; end process comb_proc; @@ -335,18 +338,27 @@ begin st.curr_cmd <= next_cmd; st.curr_cmd_size <= next_cmd_size; st.curr_addr <= trans_st.curr_inst.address; + if next_cmd_size > 0 then + st.write_stage <= next_cmd_size - 1; + st.read_stage <= next_cmd_size - 1; + end if; when TX_HEADER => - st.write_stage <= 2**(st.curr_cmd_size - 1) - 1; when TX_BODY => if st.write_stage > 0 then st.write_stage <= st.write_stage - 1; end if; + when TX_ACK => + st.curr_cmd <= NO_OP; + st.curr_cmd_size <= 0; when RX_HEADER => - st.read_stage <= 2**(st.curr_cmd_size - 1) - 1; when RX_BODY => if st.read_stage > 0 then st.read_stage <= st.read_stage - 1; + else + st.curr_cmd <= NO_OP; + st.curr_cmd_size <= 0; end if; + when others => end case; end if; @@ -366,10 +378,19 @@ begin when IDLE => if ctrl_in.request = '1' then trans_st.curr_inst <= ctrl_in; + else end if; + trans_st.is_first_word <= '1'; when SEND => + when SEND_ACCEPTED => trans_st.curr_inst.seq_mem_access_count <= trans_st.curr_inst.seq_mem_access_count - 256; when AWAIT => + if trans_st.curr_inst.seq_mem_access_count <= 0 and st.curr_state = IDLE then + trans_st.curr_inst.request <= '0'; + trans_st.curr_inst.address <= (others => '0'); + trans_st.curr_inst.seq_mem_access_count <= 0; + trans_st.curr_inst.instruction <= NO_OP; + end if; trans_st.is_first_word <= '0'; when others => end case; diff --git a/src/socbridge/socbridge_driver_tb.vhd b/src/socbridge/socbridge_driver_tb.vhd index 25a67fc..75bd29c 100644 --- a/src/socbridge/socbridge_driver_tb.vhd +++ b/src/socbridge/socbridge_driver_tb.vhd @@ -21,6 +21,8 @@ architecture tb of socbridge_driver_tb is signal ext_out : ext_socbridge_out_t; signal int_in : int_socbridge_in_t; signal int_out : int_socbridge_out_t; + signal ctrl_in : control_to_driver_t; + signal ctrl_out : driver_to_control_t; signal curr_word : std_logic_vector(ext_in.payload'length - 1 downto 0); signal expected_out : std_logic_vector(ext_out.payload'length - 1 downto 0); @@ -79,9 +81,8 @@ begin port map( clk => clk, rst => rst, - cmd => cmd, - address => address, - cmd_size => cmd_size, + ctrl_in => ctrl_in, + ctrl_out => ctrl_out, ext_in => ext_in, ext_out => ext_out, int_in => int_in, @@ -113,7 +114,6 @@ begin end process verify_clk; verify_out_signals: process - variable curr_parity : std_logic; begin wait for CLK_PERIOD / 2; for x in 0 to SIMULATION_CYCLE_COUNT loop @@ -125,7 +125,6 @@ begin end process verify_out_signals; verify_signals : process - variable nsv: boolean; begin expected_out <= "00000000"; wait for 3 * CLK_PERIOD; @@ -306,30 +305,30 @@ begin internal_stimulus: process begin - int_out.is_full_in <= '0'; - int_out.write_enable_out <= '0'; + int_in.is_full_in <= '0'; + int_in.write_enable_out <= '0'; wait for 3 * CLK_PERIOD; -- stimulus goes here - int_out.write_enable_out <= '1'; - int_out.payload <= "00000001"; - wait until rising_edge(clk) and int_in.is_full_out = '0'; + int_in.write_enable_out <= '1'; + int_in.payload <= "00000001"; + wait until rising_edge(clk) and int_out.is_full_out = '0'; wait until falling_edge(clk); - int_out.payload <= "00000010"; - wait until rising_edge(clk) and int_in.is_full_out = '0'; + int_in.payload <= "00000010"; + wait until rising_edge(clk) and int_out.is_full_out = '0'; wait until falling_edge(clk); - int_out.payload <= "00000100"; - wait until rising_edge(clk) and int_in.is_full_out = '0'; + int_in.payload <= "00000100"; + wait until rising_edge(clk) and int_out.is_full_out = '0'; wait until falling_edge(clk); - int_out.payload <= "00001000"; - wait until rising_edge(clk) and int_in.is_full_out = '0'; + int_in.payload <= "00001000"; + wait until rising_edge(clk) and int_out.is_full_out = '0'; wait until falling_edge(clk); - int_out.payload <= "00010000"; - wait until int_in.is_full_out = '0'; + int_in.payload <= "00010000"; + wait until int_out.is_full_out = '0'; wait for CLK_PERIOD/2; wait until rising_edge(clk); wait until rising_edge(clk); - int_out.payload <= "00100000"; - wait until int_in.is_full_out = '0'; + int_in.payload <= "00100000"; + wait until int_out.is_full_out = '0'; wait for CLK_PERIOD/2; wait until rising_edge(clk); wait until rising_edge(clk); --- ??? Why all these rising_edge checks? diff --git a/src/socbridge/socbridge_driver_tb_pkg.vhd b/src/socbridge/socbridge_driver_tb_pkg.vhd index 060d8e8..f5febce 100644 --- a/src/socbridge/socbridge_driver_tb_pkg.vhd +++ b/src/socbridge/socbridge_driver_tb_pkg.vhd @@ -7,7 +7,7 @@ use ganimede.io_types.all; package socbridge_driver_tb_pkg is - subtype command_size_t is integer range 1 to 128; + subtype command_size_t is integer range 0 to 128; type command_t is (NO_OP, WRITE_ADD, WRITE, READ_ADD, READ, P_ERR); @@ -21,7 +21,7 @@ package socbridge_driver_tb_pkg is RX_HEADER, RX_RESPONSE, RX_BODY_NO_OUT, RX_BODY); --- TRANSLATOR --- - type translator_state_t is (IDLE, SEND, AWAIT); + type translator_state_t is (IDLE, SEND, SEND_ACCEPTED, AWAIT); type translator_state_rec_t is record curr_inst : control_to_driver_t; @@ -64,6 +64,7 @@ package socbridge_driver_tb_pkg is signal G_curr_response : response_t; signal G_curr_response_bits : std_logic_vector(4 downto 0); signal G_st : state_rec_t; + signal G_trans_st : translator_state_rec_t; -- synthesis translate_on end package socbridge_driver_tb_pkg; @@ -91,6 +92,8 @@ package body socbridge_driver_tb_pkg is end loop; return not parity; end function; + + pure function create_io_type_out_from_ext_protocol( input : ext_protocol_t @@ -122,7 +125,23 @@ package body socbridge_driver_tb_pkg is return std_logic_vector is variable val : std_logic_vector(2 downto 0); begin - val := std_logic_vector(TO_UNSIGNED(size - 1, 3)); + if size > 2**6 then + val := "111"; + elsif size > 2**5 then + val := "110"; + elsif size > 2**4 then + val := "101"; + elsif size > 2**3 then + val := "100"; + elsif size > 2**2 then + val := "011"; + elsif size > 2**1 then + val := "010"; + elsif size > 2**0 then + val := "001"; + elsif size >= 0 then + val := "000"; + end if; return val; end function; pure function get_size_bits_sim(size: command_size_t)