library IEEE; use IEEE.std_logic_1164.all; use IEEE.NUMERIC_STD.all; library ganimede; use ganimede.io_types.all; library gan_socbridge; use gan_socbridge.socbridge_driver_tb_pkg.all; library controller; entity ganimede_tb is end entity ganimede_tb; architecture tb of ganimede_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_ganimede : ext_to_ganimede_t := (socbridge => ( payload => (others => '0'), control => (others => '0') )); signal ganimede_to_ext : ganimede_to_ext_t; signal ganimede_to_ip : ganimede_to_ip_t; signal ganimede_to_cpu : controller_to_cpu_t; signal cpu_to_ganimede : cpu_to_controller_t := ( driver_id => (others => '0'), address => (others => '0'), seq_mem_access_count => 0, cmd => (others => '0') ); signal ip_to_ganimede : ip_to_ganimede_t := (socbridge => ( 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 drivers_to_controller: drivers_to_controller_t := (socbridge => (is_active => '0')); signal controller_to_cpu: controller_to_cpu_t; signal controller_to_drivers: controller_to_drivers_t; signal curr_word : std_logic_vector(ext_to_ganimede.socbridge.payload'length - 1 downto 0); signal expected_out : std_logic_vector(ganimede_to_ext.socbridge.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(ganimede_to_ext.socbridge.payload'length - 1 downto 0)) is begin if(not (correct_data = ganimede_to_ext.socbridge.payload)) then report "Data out is not what was expected, found " & to_string(ganimede_to_ext.socbridge.payload) & " but expected " & to_string(correct_data) severity error; fail("Data out"); end if; end procedure; procedure check_parity(correct_data: std_logic_vector(ganimede_to_ext.socbridge.payload'length - 1 downto 0)) is begin if(not (calc_parity(correct_data) = calc_parity(ganimede_to_ext.socbridge.payload))) then report "Parity out is not what was expected, found " & std_logic'image(calc_parity(ganimede_to_ext.socbridge.payload)) & " but expected " & std_logic'image(calc_parity(correct_data)) severity error; fail("Parity out"); end if; end procedure; begin ganimede_inst: entity ganimede.ganimede_toplevel port map( clk => clk, rst => rst, cpu_to_ganimede => cpu_to_ganimede, ganimede_to_cpu => ganimede_to_cpu, ext_to_ganimede => ext_to_ganimede, ganimede_to_ext => ganimede_to_ext, ip_to_ganimede => ip_to_ganimede, ganimede_to_ip => ganimede_to_ip ); ext_to_ganimede.socbridge.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 drivers_to_controller.socbridge.is_active = '1'; report "Task received in driver, awaiting completion..."; cpu_to_controller.address <= (others => '0'); cpu_to_controller.cmd <= "00"; wait until drivers_to_controller.socbridge.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 drivers_to_controller.socbridge.is_active = '1'; report "Task received in driver, awaiting completion..."; cpu_to_controller.address <= (others => '0'); cpu_to_controller.cmd <= "00"; wait until drivers_to_controller.socbridge.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_ganimede.socbridge.payload <= curr_word; ext_to_ganimede.socbridge.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 ip_to_ganimede.socbridge.is_full_in <= '0'; ip_to_ganimede.socbridge.write_enable_out <= '0'; wait for 3 * CLK_PERIOD; -- stimulus goes here ip_to_ganimede.socbridge.write_enable_out <= '1'; ip_to_ganimede.socbridge.payload <= std_logic_vector(to_unsigned(input, ip_to_ganimede.socbridge.payload'length)); input := input + 1 mod 256; wait until rising_edge(clk) and ganimede_to_ip.socbridge.is_full_out = '0'; wait until falling_edge(clk); for x in 0 to 1000 loop ip_to_ganimede.socbridge.payload <= std_logic_vector(to_unsigned(input, ip_to_ganimede.socbridge.payload'length)); input := input + 1 mod 256; wait until rising_edge(clk) and ganimede_to_ip.socbridge.is_full_out = '0'; wait until falling_edge(clk); end loop; wait; end process internal_stimulus; end architecture tb;