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;