URL
https://opencores.org/ocsvn/lxp32/lxp32/trunk
Subversion Repositories lxp32
Compare Revisions
- This comparison shows the changes necessary to convert path
/lxp32/trunk/verify/lxp32/src/tb
- from Rev 6 to Rev 9
- ↔ Reverse comparison
Rev 6 → Rev 9
/monitor.vhd
1,80 → 1,80
--------------------------------------------------------------------- |
-- Test monitor |
-- |
-- Part of the LXP32 testbench |
-- |
-- Copyright (c) 2016 by Alex I. Kuznetsov |
-- |
-- Provide means for a test platform to interact with the testbench. |
--------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
use work.common_pkg.all; |
use work.tb_pkg.all; |
|
entity monitor is |
generic( |
VERBOSE: boolean |
); |
port( |
clk_i: in std_logic; |
rst_i: in std_logic; |
|
wbs_cyc_i: in std_logic; |
wbs_stb_i: in std_logic; |
wbs_we_i: in std_logic; |
wbs_sel_i: in std_logic_vector(3 downto 0); |
wbs_ack_o: out std_logic; |
wbs_adr_i: in std_logic_vector(27 downto 2); |
wbs_dat_i: in std_logic_vector(31 downto 0); |
wbs_dat_o: out std_logic_vector(31 downto 0); |
|
finished_o: out std_logic; |
result_o: out std_logic_vector(31 downto 0) |
); |
end entity; |
|
architecture sim of monitor is |
|
signal result: std_logic_vector(31 downto 0):=(others=>'0'); |
signal finished: std_logic:='0'; |
|
begin |
|
wbs_ack_o<=wbs_cyc_i and wbs_stb_i; |
wbs_dat_o<=(others=>'0'); |
|
finished_o<=finished; |
result_o<=result; |
|
process (clk_i) is |
begin |
if rising_edge(clk_i) then |
if rst_i='1' then |
finished<='0'; |
result<=(others=>'0'); |
elsif wbs_cyc_i='1' and wbs_stb_i='1' and wbs_we_i='1' then |
assert wbs_sel_i="1111" |
report "Monitor doesn't support byte-granular access "& |
"(SEL_I() is 0x"&hex_string(wbs_sel_i)&")" |
severity failure; |
|
if VERBOSE then |
report "Monitor: value "& |
"0x"&hex_string(wbs_dat_i)& |
" written to address "& |
"0x"&hex_string(wbs_adr_i); |
end if; |
|
if unsigned(wbs_adr_i)=to_unsigned(0,wbs_adr_i'length) then |
result<=wbs_dat_i; |
finished<='1'; |
end if; |
end if; |
end if; |
end process; |
|
end architecture; |
--------------------------------------------------------------------- |
-- Test monitor |
-- |
-- Part of the LXP32 testbench |
-- |
-- Copyright (c) 2016 by Alex I. Kuznetsov |
-- |
-- Provide means for a test platform to interact with the testbench. |
--------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
use work.common_pkg.all; |
use work.tb_pkg.all; |
|
entity monitor is |
generic( |
VERBOSE: boolean |
); |
port( |
clk_i: in std_logic; |
rst_i: in std_logic; |
|
wbs_cyc_i: in std_logic; |
wbs_stb_i: in std_logic; |
wbs_we_i: in std_logic; |
wbs_sel_i: in std_logic_vector(3 downto 0); |
wbs_ack_o: out std_logic; |
wbs_adr_i: in std_logic_vector(27 downto 2); |
wbs_dat_i: in std_logic_vector(31 downto 0); |
wbs_dat_o: out std_logic_vector(31 downto 0); |
|
finished_o: out std_logic; |
result_o: out std_logic_vector(31 downto 0) |
); |
end entity; |
|
architecture sim of monitor is |
|
signal result: std_logic_vector(31 downto 0):=(others=>'0'); |
signal finished: std_logic:='0'; |
|
begin |
|
wbs_ack_o<=wbs_cyc_i and wbs_stb_i; |
wbs_dat_o<=(others=>'0'); |
|
finished_o<=finished; |
result_o<=result; |
|
process (clk_i) is |
begin |
if rising_edge(clk_i) then |
if rst_i='1' then |
finished<='0'; |
result<=(others=>'0'); |
elsif wbs_cyc_i='1' and wbs_stb_i='1' and wbs_we_i='1' then |
assert wbs_sel_i="1111" |
report "Monitor doesn't support byte-granular access "& |
"(SEL_I() is 0x"&hex_string(wbs_sel_i)&")" |
severity failure; |
|
if VERBOSE then |
report "Monitor: value "& |
"0x"&hex_string(wbs_dat_i)& |
" written to address "& |
"0x"&hex_string(wbs_adr_i); |
end if; |
|
if unsigned(wbs_adr_i)=to_unsigned(0,wbs_adr_i'length) then |
result<=wbs_dat_i; |
finished<='1'; |
end if; |
end if; |
end if; |
end process; |
|
end architecture; |
/tb.vhd
1,147 → 1,147
--------------------------------------------------------------------- |
-- LXP32 verification environment (self-checking testbench) |
-- |
-- Part of the LXP32 testbench |
-- |
-- Copyright (c) 2016 by Alex I. Kuznetsov |
-- |
-- Simulates LXP32 test platform, verifies results. |
-- |
-- Parameters: |
-- CPU_DBUS_RMW: DBUS_RMW CPU generic |
-- CPU_MUL_ARCH: MUL_ARCH CPU generic |
-- MODEL_LXP32C: when true, simulates LXP32C variant (with |
-- instruction cache), otherwise LXP32U |
-- TEST_CASE: If non-empty, selects a test case to run. |
-- If empty, all tests are executed. |
-- THROTTLE_IBUS: perform pseudo-random instruction bus |
-- throttling |
-- THROTTLE_DBUS: perform pseudo-random data bus throttling |
-- VERBOSE: report everything that is written to the |
-- test monitor address space |
--------------------------------------------------------------------- |
|
use std.textio.all; |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
use work.tb_pkg.all; |
|
entity tb is |
generic( |
CPU_DBUS_RMW: boolean:=false; |
CPU_MUL_ARCH: string:="dsp"; |
MODEL_LXP32C: boolean:=true; |
TEST_CASE: string:=""; |
THROTTLE_DBUS: boolean:=true; |
THROTTLE_IBUS: boolean:=true; |
VERBOSE: boolean:=false |
); |
end entity; |
|
architecture testbench of tb is |
|
signal clk: std_logic:='0'; |
|
signal globals: soc_globals_type:=(others=>'1'); |
signal soc_wbs_in: soc_wbs_in_type; |
signal soc_wbs_out: soc_wbs_out_type; |
signal soc_wbm_in: soc_wbm_in_type; |
signal soc_wbm_out: soc_wbm_out_type; |
|
signal monitor_out: monitor_out_type; |
|
signal finish: std_logic:='0'; |
|
begin |
|
dut: entity work.platform(rtl) |
generic map( |
CPU_DBUS_RMW=>CPU_DBUS_RMW, |
CPU_MUL_ARCH=>CPU_MUL_ARCH, |
MODEL_LXP32C=>MODEL_LXP32C, |
THROTTLE_DBUS=>THROTTLE_DBUS, |
THROTTLE_IBUS=>THROTTLE_IBUS |
) |
port map( |
clk_i=>clk, |
rst_i=>globals.rst_i, |
cpu_rst_i=>globals.cpu_rst_i, |
|
wbm_cyc_o=>soc_wbm_out.cyc, |
wbm_stb_o=>soc_wbm_out.stb, |
wbm_we_o=>soc_wbm_out.we, |
wbm_sel_o=>soc_wbm_out.sel, |
wbm_ack_i=>soc_wbm_in.ack, |
wbm_adr_o=>soc_wbm_out.adr, |
wbm_dat_o=>soc_wbm_out.dat, |
wbm_dat_i=>soc_wbm_in.dat, |
|
wbs_cyc_i=>soc_wbs_in.cyc, |
wbs_stb_i=>soc_wbs_in.stb, |
wbs_we_i=>soc_wbs_in.we, |
wbs_sel_i=>soc_wbs_in.sel, |
wbs_ack_o=>soc_wbs_out.ack, |
wbs_adr_i=>soc_wbs_in.adr, |
wbs_dat_i=>soc_wbs_in.dat, |
wbs_dat_o=>soc_wbs_out.dat |
); |
|
monitor_inst: entity work.monitor(sim) |
generic map( |
VERBOSE=>VERBOSE |
) |
port map( |
clk_i=>clk, |
rst_i=>globals.rst_i, |
|
wbs_cyc_i=>soc_wbm_out.cyc, |
wbs_stb_i=>soc_wbm_out.stb, |
wbs_we_i=>soc_wbm_out.we, |
wbs_sel_i=>soc_wbm_out.sel, |
wbs_ack_o=>soc_wbm_in.ack, |
wbs_adr_i=>soc_wbm_out.adr, |
wbs_dat_i=>soc_wbm_out.dat, |
wbs_dat_o=>soc_wbm_in.dat, |
|
finished_o=>monitor_out.valid, |
result_o=>monitor_out.data |
); |
|
clk<=not clk and not finish after 5 ns; |
|
process is |
begin |
if TEST_CASE'length=0 then |
run_test("test001.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test002.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test003.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test004.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test005.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test006.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test007.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test008.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test009.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test010.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test011.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test012.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test013.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test014.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test015.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test016.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test017.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test018.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test019.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test020.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
else |
run_test(TEST_CASE,clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
end if; |
|
report "ALL TESTS WERE COMPLETED SUCCESSFULLY"; |
finish<='1'; |
wait; |
end process; |
|
end architecture; |
--------------------------------------------------------------------- |
-- LXP32 verification environment (self-checking testbench) |
-- |
-- Part of the LXP32 testbench |
-- |
-- Copyright (c) 2016 by Alex I. Kuznetsov |
-- |
-- Simulates LXP32 test platform, verifies results. |
-- |
-- Parameters: |
-- CPU_DBUS_RMW: DBUS_RMW CPU generic |
-- CPU_MUL_ARCH: MUL_ARCH CPU generic |
-- MODEL_LXP32C: when true, simulates LXP32C variant (with |
-- instruction cache), otherwise LXP32U |
-- TEST_CASE: If non-empty, selects a test case to run. |
-- If empty, all tests are executed. |
-- THROTTLE_IBUS: perform pseudo-random instruction bus |
-- throttling |
-- THROTTLE_DBUS: perform pseudo-random data bus throttling |
-- VERBOSE: report everything that is written to the |
-- test monitor address space |
--------------------------------------------------------------------- |
|
use std.textio.all; |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
use work.tb_pkg.all; |
|
entity tb is |
generic( |
CPU_DBUS_RMW: boolean:=false; |
CPU_MUL_ARCH: string:="dsp"; |
MODEL_LXP32C: boolean:=true; |
TEST_CASE: string:=""; |
THROTTLE_DBUS: boolean:=true; |
THROTTLE_IBUS: boolean:=true; |
VERBOSE: boolean:=false |
); |
end entity; |
|
architecture testbench of tb is |
|
signal clk: std_logic:='0'; |
|
signal globals: soc_globals_type:=(others=>'1'); |
signal soc_wbs_in: soc_wbs_in_type; |
signal soc_wbs_out: soc_wbs_out_type; |
signal soc_wbm_in: soc_wbm_in_type; |
signal soc_wbm_out: soc_wbm_out_type; |
|
signal monitor_out: monitor_out_type; |
|
signal finish: std_logic:='0'; |
|
begin |
|
dut: entity work.platform(rtl) |
generic map( |
CPU_DBUS_RMW=>CPU_DBUS_RMW, |
CPU_MUL_ARCH=>CPU_MUL_ARCH, |
MODEL_LXP32C=>MODEL_LXP32C, |
THROTTLE_DBUS=>THROTTLE_DBUS, |
THROTTLE_IBUS=>THROTTLE_IBUS |
) |
port map( |
clk_i=>clk, |
rst_i=>globals.rst_i, |
cpu_rst_i=>globals.cpu_rst_i, |
|
wbm_cyc_o=>soc_wbm_out.cyc, |
wbm_stb_o=>soc_wbm_out.stb, |
wbm_we_o=>soc_wbm_out.we, |
wbm_sel_o=>soc_wbm_out.sel, |
wbm_ack_i=>soc_wbm_in.ack, |
wbm_adr_o=>soc_wbm_out.adr, |
wbm_dat_o=>soc_wbm_out.dat, |
wbm_dat_i=>soc_wbm_in.dat, |
|
wbs_cyc_i=>soc_wbs_in.cyc, |
wbs_stb_i=>soc_wbs_in.stb, |
wbs_we_i=>soc_wbs_in.we, |
wbs_sel_i=>soc_wbs_in.sel, |
wbs_ack_o=>soc_wbs_out.ack, |
wbs_adr_i=>soc_wbs_in.adr, |
wbs_dat_i=>soc_wbs_in.dat, |
wbs_dat_o=>soc_wbs_out.dat |
); |
|
monitor_inst: entity work.monitor(sim) |
generic map( |
VERBOSE=>VERBOSE |
) |
port map( |
clk_i=>clk, |
rst_i=>globals.rst_i, |
|
wbs_cyc_i=>soc_wbm_out.cyc, |
wbs_stb_i=>soc_wbm_out.stb, |
wbs_we_i=>soc_wbm_out.we, |
wbs_sel_i=>soc_wbm_out.sel, |
wbs_ack_o=>soc_wbm_in.ack, |
wbs_adr_i=>soc_wbm_out.adr, |
wbs_dat_i=>soc_wbm_out.dat, |
wbs_dat_o=>soc_wbm_in.dat, |
|
finished_o=>monitor_out.valid, |
result_o=>monitor_out.data |
); |
|
clk<=not clk and not finish after 5 ns; |
|
process is |
begin |
if TEST_CASE'length=0 then |
run_test("test001.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test002.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test003.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test004.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test005.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test006.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test007.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test008.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test009.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test010.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test011.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test012.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test013.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test014.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test015.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test016.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test017.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test018.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test019.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
run_test("test020.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
else |
run_test(TEST_CASE,clk,globals,soc_wbs_in,soc_wbs_out,monitor_out); |
end if; |
|
report "ALL TESTS WERE COMPLETED SUCCESSFULLY"; |
finish<='1'; |
wait; |
end process; |
|
end architecture; |
/tb_pkg.vhd
1,70 → 1,70
--------------------------------------------------------------------- |
-- LXP32 testbench package |
-- |
-- Part of the LXP32 testbench |
-- |
-- Copyright (c) 2016 by Alex I. Kuznetsov |
-- |
-- Auxiliary package declaration for the LXP32 testbench |
--------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
package tb_pkg is |
constant c_max_program_size: integer:=8192; |
|
type soc_globals_type is record |
rst_i: std_logic; |
cpu_rst_i: std_logic; |
end record; |
|
type soc_wbs_in_type is record |
cyc: std_logic; |
stb: std_logic; |
we: std_logic; |
sel: std_logic_vector(3 downto 0); |
adr: std_logic_vector(31 downto 2); |
dat: std_logic_vector(31 downto 0); |
end record; |
|
type soc_wbs_out_type is record |
ack: std_logic; |
dat: std_logic_vector(31 downto 0); |
end record; |
|
type soc_wbm_in_type is record |
ack: std_logic; |
dat: std_logic_vector(31 downto 0); |
end record; |
|
type soc_wbm_out_type is record |
cyc: std_logic; |
stb: std_logic; |
we: std_logic; |
sel: std_logic_vector(3 downto 0); |
adr: std_logic_vector(27 downto 2); |
dat: std_logic_vector(31 downto 0); |
end record; |
|
type monitor_out_type is record |
data: std_logic_vector(31 downto 0); |
valid: std_logic; |
end record; |
|
procedure load_ram( |
filename: string; |
signal clk: in std_logic; |
signal soc_in: out soc_wbs_in_type; |
signal soc_out: in soc_wbs_out_type |
); |
|
procedure run_test( |
filename: string; |
signal clk: in std_logic; |
signal globals: out soc_globals_type; |
signal soc_in: out soc_wbs_in_type; |
signal soc_out: in soc_wbs_out_type; |
signal result: in monitor_out_type |
); |
end package; |
--------------------------------------------------------------------- |
-- LXP32 testbench package |
-- |
-- Part of the LXP32 testbench |
-- |
-- Copyright (c) 2016 by Alex I. Kuznetsov |
-- |
-- Auxiliary package declaration for the LXP32 testbench |
--------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
package tb_pkg is |
constant c_max_program_size: integer:=8192; |
|
type soc_globals_type is record |
rst_i: std_logic; |
cpu_rst_i: std_logic; |
end record; |
|
type soc_wbs_in_type is record |
cyc: std_logic; |
stb: std_logic; |
we: std_logic; |
sel: std_logic_vector(3 downto 0); |
adr: std_logic_vector(31 downto 2); |
dat: std_logic_vector(31 downto 0); |
end record; |
|
type soc_wbs_out_type is record |
ack: std_logic; |
dat: std_logic_vector(31 downto 0); |
end record; |
|
type soc_wbm_in_type is record |
ack: std_logic; |
dat: std_logic_vector(31 downto 0); |
end record; |
|
type soc_wbm_out_type is record |
cyc: std_logic; |
stb: std_logic; |
we: std_logic; |
sel: std_logic_vector(3 downto 0); |
adr: std_logic_vector(27 downto 2); |
dat: std_logic_vector(31 downto 0); |
end record; |
|
type monitor_out_type is record |
data: std_logic_vector(31 downto 0); |
valid: std_logic; |
end record; |
|
procedure load_ram( |
filename: string; |
signal clk: in std_logic; |
signal soc_in: out soc_wbs_in_type; |
signal soc_out: in soc_wbs_out_type |
); |
|
procedure run_test( |
filename: string; |
signal clk: in std_logic; |
signal globals: out soc_globals_type; |
signal soc_in: out soc_wbs_in_type; |
signal soc_out: in soc_wbs_out_type; |
signal result: in monitor_out_type |
); |
end package; |
/tb_pkg_body.vhd
1,100 → 1,100
--------------------------------------------------------------------- |
-- LXP32 testbench package body |
-- |
-- Part of the LXP32 testbench |
-- |
-- Copyright (c) 2016 by Alex I. Kuznetsov |
-- |
-- Auxiliary package body for the LXP32 testbench |
--------------------------------------------------------------------- |
|
use std.textio.all; |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
use work.common_pkg.all; |
|
package body tb_pkg is |
procedure load_ram( |
filename: string; |
signal clk: in std_logic; |
signal soc_in: out soc_wbs_in_type; |
signal soc_out: in soc_wbs_out_type |
) is |
file f: text open read_mode is filename; |
variable i: integer:=0; |
variable l: line; |
variable v: bit_vector(31 downto 0); |
begin |
wait until rising_edge(clk); |
|
report "Loading program RAM from """&filename&""""; |
|
while not endfile(f) loop |
readline(f,l); |
read(l,v); |
|
assert i<c_max_program_size report "Error: program size is too large" severity failure; |
|
soc_in.cyc<='1'; |
soc_in.stb<='1'; |
soc_in.we<='1'; |
soc_in.sel<=(others=>'1'); |
soc_in.adr<=std_logic_vector(to_unsigned(i,30)); |
soc_in.dat<=to_stdlogicvector(v); |
|
wait until rising_edge(clk) and soc_out.ack='1'; |
|
i:=i+1; |
end loop; |
|
report integer'image(i)&" words loaded from """&filename&""""; |
|
soc_in.cyc<='0'; |
soc_in.stb<='0'; |
|
wait until rising_edge(clk); |
end procedure; |
|
procedure run_test( |
filename: string; |
signal clk: in std_logic; |
signal globals: out soc_globals_type; |
signal soc_in: out soc_wbs_in_type; |
signal soc_out: in soc_wbs_out_type; |
signal result: in monitor_out_type |
) is |
begin |
-- Assert SoC and CPU resets |
wait until rising_edge(clk); |
globals.rst_i<='1'; |
globals.cpu_rst_i<='1'; |
wait until rising_edge(clk); |
|
-- Deassert SoC reset, leave CPU in reset state for now |
globals.rst_i<='0'; |
wait until rising_edge(clk); |
|
-- Load RAM |
load_ram(filename,clk,soc_in,soc_out); |
|
-- Deassert CPU reset |
globals.cpu_rst_i<='0'; |
|
while result.valid/='1' loop |
wait until rising_edge(clk); |
end loop; |
|
-- Analyze result |
|
if result.data=X"00000001" then |
report "TEST """&filename&""" RESULT: SUCCESS (return code 0x"& |
hex_string(result.data)&")"; |
else |
report "TEST """&filename&""" RESULT: FAILURE (return code 0x"& |
hex_string(result.data)&")" severity failure; |
end if; |
end procedure; |
end package body; |
--------------------------------------------------------------------- |
-- LXP32 testbench package body |
-- |
-- Part of the LXP32 testbench |
-- |
-- Copyright (c) 2016 by Alex I. Kuznetsov |
-- |
-- Auxiliary package body for the LXP32 testbench |
--------------------------------------------------------------------- |
|
use std.textio.all; |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
use work.common_pkg.all; |
|
package body tb_pkg is |
procedure load_ram( |
filename: string; |
signal clk: in std_logic; |
signal soc_in: out soc_wbs_in_type; |
signal soc_out: in soc_wbs_out_type |
) is |
file f: text open read_mode is filename; |
variable i: integer:=0; |
variable l: line; |
variable v: bit_vector(31 downto 0); |
begin |
wait until rising_edge(clk); |
|
report "Loading program RAM from """&filename&""""; |
|
while not endfile(f) loop |
readline(f,l); |
read(l,v); |
|
assert i<c_max_program_size report "Error: program size is too large" severity failure; |
|
soc_in.cyc<='1'; |
soc_in.stb<='1'; |
soc_in.we<='1'; |
soc_in.sel<=(others=>'1'); |
soc_in.adr<=std_logic_vector(to_unsigned(i,30)); |
soc_in.dat<=to_stdlogicvector(v); |
|
wait until rising_edge(clk) and soc_out.ack='1'; |
|
i:=i+1; |
end loop; |
|
report integer'image(i)&" words loaded from """&filename&""""; |
|
soc_in.cyc<='0'; |
soc_in.stb<='0'; |
|
wait until rising_edge(clk); |
end procedure; |
|
procedure run_test( |
filename: string; |
signal clk: in std_logic; |
signal globals: out soc_globals_type; |
signal soc_in: out soc_wbs_in_type; |
signal soc_out: in soc_wbs_out_type; |
signal result: in monitor_out_type |
) is |
begin |
-- Assert SoC and CPU resets |
wait until rising_edge(clk); |
globals.rst_i<='1'; |
globals.cpu_rst_i<='1'; |
wait until rising_edge(clk); |
|
-- Deassert SoC reset, leave CPU in reset state for now |
globals.rst_i<='0'; |
wait until rising_edge(clk); |
|
-- Load RAM |
load_ram(filename,clk,soc_in,soc_out); |
|
-- Deassert CPU reset |
globals.cpu_rst_i<='0'; |
|
while result.valid/='1' loop |
wait until rising_edge(clk); |
end loop; |
|
-- Analyze result |
|
if result.data=X"00000001" then |
report "TEST """&filename&""" RESULT: SUCCESS (return code 0x"& |
hex_string(result.data)&")"; |
else |
report "TEST """&filename&""" RESULT: FAILURE (return code 0x"& |
hex_string(result.data)&")" severity failure; |
end if; |
end procedure; |
end package body; |