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 := 2000; signal clk, rst : std_logic := '0'; signal controller_to_socbridge_driver_cmd : command_t; signal controller_to_socbridge_driver_address : std_logic_vector(31 downto 0); signal cmd_size : positive; signal ext_to_socbridge_driver : ext_to_socbridge_driver_t := ( payload => (others => '0'), control => (others => '0') ); signal socbridge_driver_to_ext : socbridge_driver_to_ext_t; signal socbridge_driver_to_buffer : socbridge_driver_to_buffer_t; signal buffer_to_socbridge_driver : buffer_to_socbridge_driver_t := ( payload => (others => '0'), write_enable_out => '0', is_full_in => '0' ); signal cpu_to_controller: cpu_to_controller_t := ( driver_id => (others => '0'), address => (others => '0'), seq_mem_access_count => 0, cmd => "00" ); signal socbridge_driver_to_controller: socbridge_driver_to_controller_t := (is_active => '0'); signal controller_to_cpu: controller_to_cpu_t; signal controller_to_socbridge_driver: controller_to_socbridge_driver_t; signal curr_word : std_logic_vector(ext_to_socbridge_driver.payload'length - 1 downto 0); signal expected_out : std_logic_vector(socbridge_driver_to_ext.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(socbridge_driver_to_ext.payload'length - 1 downto 0)) is begin if(not (correct_data = socbridge_driver_to_ext.payload)) then report "Data out is not what was expected, found " & to_string(socbridge_driver_to_ext.payload) & " but expected " & to_string(correct_data) severity error; fail("Data out"); end if; end procedure; procedure check_parity(correct_data: std_logic_vector(socbridge_driver_to_ext.payload'length - 1 downto 0)) is begin if(not (calc_parity(correct_data) = calc_parity(socbridge_driver_to_ext.payload))) then report "Parity out is not what was expected, found " & std_logic'image(calc_parity(socbridge_driver_to_ext.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, controller_to_socbridge_driver => controller_to_socbridge_driver, socbridge_driver_to_controller => socbridge_driver_to_controller, ext_to_socbridge_driver => ext_to_socbridge_driver, socbridge_driver_to_ext => socbridge_driver_to_ext, buffer_to_socbridge_driver => buffer_to_socbridge_driver, socbridge_driver_to_buffer => socbridge_driver_to_buffer ); controller_unit_inst: entity controller.control_unit port map( clk => clk, rst => rst, cpu_to_controller => cpu_to_controller, controller_to_cpu => controller_to_cpu, socbridge_driver_to_controller => socbridge_driver_to_controller, controller_to_socbridge_driver => controller_to_socbridge_driver ); ext_to_socbridge_driver.control(1) <= clk; controller_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 controller_clock_proc; stimulus_proc: process begin report "Starting Simulation Stimulus!"; rst <= '1'; cpu_to_controller.address <= (others => '0'); cpu_to_controller.cmd <= "00"; cpu_to_controller.driver_id <= "1"; cpu_to_controller.seq_mem_access_count <= 256; wait for 3 * CLK_PERIOD; report "Reset grace period ended, starting stimulus..."; rst <= '0'; cpu_to_controller.address <= x"FA0FA0FA"; cpu_to_controller.cmd <= "01"; wait until socbridge_driver_to_controller.is_active = '1'; report "Task received in driver, awaiting completion..."; cpu_to_controller.address <= (others => '0'); cpu_to_controller.cmd <= "00"; wait until socbridge_driver_to_controller.is_active = '0'; wait for CLK_PERIOD; report "Task completed in driver, sending next task..."; cpu_to_controller.address <= x"FA0FA0FA"; cpu_to_controller.cmd <= "10"; wait for CLK_PERIOD; wait until socbridge_driver_to_controller.is_active = '1'; report "Task received in driver, awaiting completion..."; cpu_to_controller.address <= (others => '0'); cpu_to_controller.cmd <= "00"; wait until socbridge_driver_to_controller.is_active = '0'; wait for CLK_PERIOD; report "Task completed in driver, ending simulation stimulus"; cpu_to_controller.address <= (others => '0'); cpu_to_controller.cmd <= "00"; cpu_to_controller.driver_id <= "0"; cpu_to_controller.seq_mem_access_count <= 0; wait; end process stimulus_proc; external_stimulus_signal: process(curr_word) begin ext_to_socbridge_driver.payload <= curr_word; ext_to_socbridge_driver.control(0) <= calc_parity(curr_word); end process external_stimulus_signal; external_stimulus: process variable input : positive := 1; 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 * 140; curr_word <= "00101001"; wait for CLK_PERIOD; curr_word <= "00000000"; wait for CLK_PERIOD * 140; curr_word <= "00101001"; wait for CLK_PERIOD; curr_word <= "00000000"; wait for CLK_PERIOD * 20; curr_word <= "01100111"; wait for CLK_PERIOD; for x in 0 to 127 loop curr_word <= std_logic_vector(to_unsigned(input, 8)); input := input + 1 mod 256; wait for CLK_PERIOD; end loop; curr_word <= "00000000"; wait for CLK_PERIOD * 140; wait for CLK_PERIOD * 20; curr_word <= "01100111"; wait for CLK_PERIOD; for x in 0 to 127 loop curr_word <= std_logic_vector(to_unsigned(input, 8)); input := input + 1 mod 256; wait for CLK_PERIOD; end loop; wait; end process external_stimulus; internal_stimulus: process variable input : positive := 1; begin buffer_to_socbridge_driver.is_full_in <= '0'; buffer_to_socbridge_driver.write_enable_out <= '0'; wait for 3 * CLK_PERIOD; -- stimulus goes here buffer_to_socbridge_driver.write_enable_out <= '1'; buffer_to_socbridge_driver.payload <= std_logic_vector(to_unsigned(input, buffer_to_socbridge_driver.payload'length)); input := input + 1 mod 256; wait until rising_edge(clk) and socbridge_driver_to_buffer.is_full_out = '0'; wait until falling_edge(clk); for x in 0 to 1000 loop buffer_to_socbridge_driver.payload <= std_logic_vector(to_unsigned(input, buffer_to_socbridge_driver.payload'length)); input := input + 1 mod 256; wait until rising_edge(clk) and socbridge_driver_to_buffer.is_full_out = '0'; wait until falling_edge(clk); end loop; wait; end process internal_stimulus; end architecture tb;