exjobb-public/src/control_socbridge_merge/control_socbridge_tb.vhd
2025-03-13 16:28:39 +01:00

219 lines
8.0 KiB
VHDL

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;