140 lines
3.5 KiB
VHDL
140 lines
3.5 KiB
VHDL
library IEEE;
|
|
use IEEE.std_logic_1164.all;
|
|
use IEEE.MATH_REAL.all;
|
|
library work;
|
|
use work.io_types.all;
|
|
|
|
|
|
entity socbridge_driver_tb is
|
|
end entity socbridge_driver_tb;
|
|
|
|
architecture tb of socbridge_driver_tb is
|
|
pure function calc_parity(
|
|
d : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0)
|
|
) return std_logic is
|
|
variable parity : std_logic;
|
|
begin
|
|
parity := d(0);
|
|
for x in 1 to d'length - 1 loop
|
|
parity := parity xor d(x);
|
|
end loop;
|
|
return not parity;
|
|
end function;
|
|
|
|
|
|
component socbridge_driver is
|
|
port(
|
|
clk : in std_logic;
|
|
rst : in std_logic;
|
|
ext_in : in ext_socbridge_in_t;
|
|
ext_out : out ext_socbridge_out_t;
|
|
int_in : out int_socbridge_in_t;
|
|
int_out : in int_socbridge_out_t
|
|
);
|
|
end component socbridge_driver;
|
|
signal clk : std_logic := '0';
|
|
signal rst : std_logic;
|
|
signal ext_in : ext_socbridge_in_t;
|
|
signal ext_out : ext_socbridge_out_t;
|
|
signal int_in : int_socbridge_in_t;
|
|
signal int_out : int_socbridge_out_t;
|
|
|
|
signal curr_word : std_logic_vector(ext_in.payload'length - 1 downto 0);
|
|
|
|
constant CLK_PERIOD : TIME := 10 ns;
|
|
constant SIMULATION_CYCLE_COUNT : INTEGER := 100;
|
|
|
|
begin
|
|
|
|
|
|
socbridge_driver_inst: entity work.socbridge_driver
|
|
port map(
|
|
clk => clk,
|
|
rst => rst,
|
|
ext_in => ext_in,
|
|
ext_out => ext_out,
|
|
int_in => int_in,
|
|
int_out => int_out
|
|
);
|
|
|
|
ext_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;
|
|
|
|
|
|
verify_clk: process
|
|
variable last_clk : std_logic;
|
|
begin
|
|
wait for CLK_PERIOD / 2;
|
|
for x in 0 to SIMULATION_CYCLE_COUNT loop
|
|
if last_clk = ext_out.control(1) then
|
|
report "Secondary side clk not correct." severity warning;
|
|
end if;
|
|
last_clk := ext_out.control(1);
|
|
wait for CLK_PERIOD;
|
|
end loop;
|
|
wait;
|
|
end process verify_clk;
|
|
|
|
verify_parity: process
|
|
variable curr_parity : std_logic;
|
|
begin
|
|
for x in 0 to SIMULATION_CYCLE_COUNT * 2 loop
|
|
curr_parity := calc_parity(ext_out.payload);
|
|
if not (curr_parity = ext_out.control(0)) then
|
|
report "Secondary side parity not correct" severity warning;
|
|
end if;
|
|
wait for CLK_PERIOD / 2;
|
|
end loop;
|
|
wait;
|
|
end process verify_parity;
|
|
|
|
external_stimulus_signal: process(curr_word)
|
|
begin
|
|
ext_in.payload <= curr_word;
|
|
ext_in.control(0) <= calc_parity(curr_word);
|
|
end process external_stimulus_signal;
|
|
|
|
external_stimulus: process
|
|
begin
|
|
rst <= '1';
|
|
curr_word <= "00000000";
|
|
wait for 3 * CLK_PERIOD;
|
|
rst <= '0';
|
|
wait for CLK_PERIOD / 2;
|
|
-- stimulus goes here
|
|
wait for CLK_PERIOD*10;
|
|
wait;
|
|
end process external_stimulus;
|
|
|
|
|
|
internal_stimulus: process
|
|
begin
|
|
int_out.is_full_in <= '0';
|
|
int_out.write_enable_out <= '0';
|
|
wait for 3 * CLK_PERIOD;
|
|
-- stimulus goes here
|
|
int_out.write_enable_out <= '1';
|
|
int_out.payload <= "00000000";
|
|
wait until int_in.is_full_out = '0';
|
|
int_out.payload <= "00000010";
|
|
wait until int_in.is_full_out = '0';
|
|
int_out.payload <= "00000100";
|
|
wait until int_in.is_full_out = '0';
|
|
int_out.payload <= "00001000";
|
|
wait until int_in.is_full_out = '0';
|
|
int_out.payload <= "00010000";
|
|
wait until int_in.is_full_out = '0';
|
|
int_out.payload <= "00100000";
|
|
wait until int_in.is_full_out = '0';
|
|
wait;
|
|
end process internal_stimulus;
|
|
|
|
end architecture tb ;
|