178 lines
4.8 KiB
VHDL
178 lines
4.8 KiB
VHDL
|
-- -------------------------------------------------------------------------- --
|
||
|
-- TRASHERNET SoC - A Trashy Ethernet SoC for FPGAs --
|
||
|
-- -------------------------------------------------------------------------- --
|
||
|
-- VUnit test bench for the aps6404l Wishbone IF
|
||
|
-- -------------------------------------------------------------------------- --
|
||
|
-- Author : Markus Koch <markus@notsyncing.net>
|
||
|
-- Contributors : None
|
||
|
-- License : Mozilla Public License (MPL) Version 2
|
||
|
-- -------------------------------------------------------------------------- --
|
||
|
|
||
|
library ieee;
|
||
|
use ieee.std_logic_1164.all;
|
||
|
use ieee.numeric_std.all;
|
||
|
|
||
|
library design;
|
||
|
use design.all;
|
||
|
|
||
|
library generics;
|
||
|
use generics.wishbone_pkg.all;
|
||
|
|
||
|
library device_models;
|
||
|
use device_models.all;
|
||
|
|
||
|
library vunit_lib;
|
||
|
context vunit_lib.vunit_context;
|
||
|
|
||
|
entity bench_aps6404l_wb is
|
||
|
generic(
|
||
|
runner_cfg : string := runner_cfg_default
|
||
|
);
|
||
|
end entity bench_aps6404l_wb;
|
||
|
|
||
|
architecture RTL of bench_aps6404l_wb is
|
||
|
signal wbi_o : wishbone_slave_out;
|
||
|
signal wbi_i : wishbone_slave_in;
|
||
|
signal wb_o : wishbone_slave_out;
|
||
|
signal wb_i : wishbone_slave_in;
|
||
|
|
||
|
signal clk : std_logic;
|
||
|
signal rst : std_logic;
|
||
|
|
||
|
signal psram_ce_n : std_logic;
|
||
|
signal psram_sclk : std_logic;
|
||
|
signal psram_sio : std_logic_vector(3 downto 0);
|
||
|
begin
|
||
|
aps6404l_wb_inst : entity design.aps6404l_wb
|
||
|
port map(
|
||
|
clk => clk,
|
||
|
rst => rst,
|
||
|
wbi_o => wbi_o,
|
||
|
wbi_i => wbi_i,
|
||
|
wb_o => wb_o,
|
||
|
wb_i => wb_i,
|
||
|
psram_ce_n => psram_ce_n,
|
||
|
psram_sclk => psram_sclk,
|
||
|
psram_sio => psram_sio
|
||
|
);
|
||
|
|
||
|
aps6404l_inst : entity device_models.aps6404l
|
||
|
port map(
|
||
|
ce_n => psram_ce_n,
|
||
|
sclk => psram_sclk,
|
||
|
sio => psram_sio
|
||
|
);
|
||
|
|
||
|
test : process is
|
||
|
procedure bus_write(
|
||
|
signal master_o : out wishbone_master_out;
|
||
|
signal master_i : in wishbone_master_in;
|
||
|
constant address : in wishbone_address;
|
||
|
constant data : in wishbone_data
|
||
|
) is
|
||
|
begin
|
||
|
info("Writing to address 0x" & to_hstring(address));
|
||
|
master_o.we <= '1';
|
||
|
master_o.adr <= address;
|
||
|
master_o.dat <= data;
|
||
|
master_o.sel <= (others => '1');
|
||
|
master_o.cyc <= '1';
|
||
|
master_o.stb <= '1';
|
||
|
loop
|
||
|
wait until rising_edge(clk);
|
||
|
exit when master_i.ack = '1';
|
||
|
end loop;
|
||
|
master_o.cyc <= '0';
|
||
|
master_o.stb <= '0';
|
||
|
end procedure bus_write;
|
||
|
|
||
|
procedure bus_read(
|
||
|
signal master_o : out wishbone_master_out;
|
||
|
signal master_i : in wishbone_master_in;
|
||
|
constant address : in wishbone_address;
|
||
|
variable data : out wishbone_data
|
||
|
) is
|
||
|
begin
|
||
|
info("Reading from address 0x" & to_hstring(address));
|
||
|
master_o.we <= '0';
|
||
|
master_o.adr <= address;
|
||
|
master_o.sel <= (others => '1');
|
||
|
master_o.cyc <= '1';
|
||
|
master_o.stb <= '1';
|
||
|
loop
|
||
|
wait until rising_edge(clk);
|
||
|
exit when master_i.ack = '1';
|
||
|
end loop;
|
||
|
data := master_i.dat;
|
||
|
master_o.cyc <= '0';
|
||
|
master_o.stb <= '0';
|
||
|
end procedure bus_read;
|
||
|
|
||
|
procedure readcheck(signal master_o : out wishbone_master_out;
|
||
|
signal master_i : in wishbone_master_in;
|
||
|
constant address : in wishbone_address;
|
||
|
constant expected : in wishbone_data) is
|
||
|
variable data : wishbone_data;
|
||
|
variable time_start : time;
|
||
|
begin
|
||
|
time_start := now;
|
||
|
bus_read(wbi_i, wbi_o, address, data);
|
||
|
info("Read data: 0x" & to_hstring(data) & " after " & time'image(now - time_start));
|
||
|
check(data = expected, "Data readback incorrect.");
|
||
|
end procedure readcheck;
|
||
|
|
||
|
variable data : wishbone_data;
|
||
|
begin
|
||
|
test_runner_setup(runner, runner_cfg);
|
||
|
|
||
|
wbi_i.sel <= (others => '1');
|
||
|
wbi_i.cyc <= '0';
|
||
|
wbi_i.stb <= '0';
|
||
|
wb_i.cyc <= '0';
|
||
|
wb_i.stb <= '0';
|
||
|
|
||
|
while test_suite loop
|
||
|
info("Resetting DUT");
|
||
|
rst <= '1';
|
||
|
wait for 30 ns;
|
||
|
rst <= '0';
|
||
|
|
||
|
if run("data") then
|
||
|
bus_write(wb_i, wb_o, x"00000000", x"12345678");
|
||
|
bus_read(wb_i, wb_o, x"00000000", data);
|
||
|
info("Read data: 0x" & to_hstring(data));
|
||
|
check(data = x"12345678", "Data readback incorrect.");
|
||
|
wait for 500 ns;
|
||
|
|
||
|
elsif run("instruction") then
|
||
|
bus_write(wb_i, wb_o, x"00000000", x"11223344");
|
||
|
bus_write(wb_i, wb_o, x"00000004", x"55667788");
|
||
|
bus_write(wb_i, wb_o, x"00000008", x"99aabbcc");
|
||
|
bus_write(wb_i, wb_o, x"0000000c", x"ddeeff00");
|
||
|
wait for 1 us;
|
||
|
readcheck(wbi_i, wbi_o, x"00000000", x"11223344");
|
||
|
wait for 1 us;
|
||
|
readcheck(wbi_i, wbi_o, x"00000004", x"55667788");
|
||
|
wait for 1 us;
|
||
|
readcheck(wbi_i, wbi_o, x"00000008", x"99aabbcc");
|
||
|
wait for 1 us;
|
||
|
readcheck(wbi_i, wbi_o, x"0000000c", x"ddeeff00");
|
||
|
wait for 1 us;
|
||
|
|
||
|
end if;
|
||
|
end loop;
|
||
|
test_runner_cleanup(runner);
|
||
|
end process test;
|
||
|
|
||
|
test_runner_watchdog(runner, 1 ms);
|
||
|
|
||
|
clock_driver : process
|
||
|
constant period : time := 20 ns;
|
||
|
begin
|
||
|
clk <= '0';
|
||
|
wait for period / 2;
|
||
|
clk <= '1';
|
||
|
wait for period / 2;
|
||
|
end process clock_driver;
|
||
|
end architecture RTL;
|