Merge pull request #295 from LarsAsplund/master

Run VHDL tests with VUnit
pull/303/head
Michael Neuling 3 years ago committed by GitHub
commit ff7421c54e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -33,7 +33,6 @@ jobs:
max-parallel: 3
matrix:
task: [
"tests_unit",
"tests_console",
"{1..99}",
"{100..199}",
@ -52,6 +51,14 @@ jobs:
- uses: actions/checkout@v2
- run: bash -c "make -j$(nproc) ${{ matrix.task }}"

VUnit:
needs: [build]
runs-on: ubuntu-latest
container: ghdl/vunit:llvm
steps:
- uses: actions/checkout@v2
- run: python3 ./run.py -p10

symbiflow:
strategy:
fail-fast: false

@ -39,8 +39,8 @@ ECPPACK = $(DOCKERBIN) $(DOCKERARGS) hdlc/prjtrellis ecppack
OPENOCD = $(DOCKERBIN) $(DOCKERARGS) --device /dev/bus/usb hdlc/prog openocd
endif

all = core_tb icache_tb dcache_tb multiply_tb dmi_dtm_tb divider_tb \
rotator_tb countzero_tb wishbone_bram_tb soc_reset_tb
all = core_tb icache_tb dcache_tb dmi_dtm_tb \
wishbone_bram_tb soc_reset_tb

all: $(all)

@ -62,7 +62,7 @@ uart_files = $(wildcard uart16550/*.v)
soc_sim_files = $(core_files) $(soc_files) sim_console.vhdl sim_pp_uart.vhdl sim_bram_helpers.vhdl \
sim_bram.vhdl sim_jtag_socket.vhdl sim_jtag.vhdl dmi_dtm_xilinx.vhdl \
sim_16550_uart.vhdl \
random.vhdl glibc_random.vhdl glibc_random_helpers.vhdl
foreign_random.vhdl glibc_random.vhdl glibc_random_helpers.vhdl

soc_sim_c_files = sim_vhpi_c.c sim_bram_helpers_c.c sim_console_c.c \
sim_jtag_socket_c.c
@ -79,7 +79,6 @@ $(unisim_lib): $(unisim_lib_files)
$(GHDL) -i --std=08 --work=unisim --workdir=$(unisim_dir) $^
GHDLFLAGS += -P$(unisim_dir)

core_tbs = multiply_tb divider_tb rotator_tb countzero_tb
soc_tbs = core_tb icache_tb dcache_tb dmi_dtm_tb wishbone_bram_tb
soc_flash_tbs = core_flash_tb
soc_dram_tbs = dram_tb core_dram_tb
@ -105,9 +104,6 @@ $(soc_flash_tbs): %: $(soc_sim_files) $(soc_sim_obj_files) $(unisim_lib) $(fmf_l
$(soc_tbs): %: $(soc_sim_files) $(soc_sim_obj_files) $(unisim_lib) %.vhdl
$(GHDL) -c $(GHDLFLAGS) $(soc_sim_link) $(soc_sim_files) $@.vhdl -e $@

$(core_tbs): %: $(core_files) glibc_random.vhdl glibc_random_helpers.vhdl %.vhdl
$(GHDL) -c $(GHDLFLAGS) $(core_files) glibc_random.vhdl glibc_random_helpers.vhdl $@.vhdl -e $@

soc_reset_tb: fpga/soc_reset_tb.vhdl fpga/soc_reset.vhdl
$(GHDL) -c $(GHDLFLAGS) fpga/soc_reset_tb.vhdl fpga/soc_reset.vhdl -e $@

@ -236,19 +232,15 @@ test_micropython: core_tb
test_micropython_long: core_tb
@./scripts/test_micropython_long.py

tests_core_tb = $(patsubst %_tb,%_tb_test,$(core_tbs))
tests_soc_tb = $(patsubst %_tb,%_tb_test,$(soc_tbs))

%_test: %
./$< --assert-level=error > /dev/null

tests_core: $(tests_core_tb)

tests_soc: $(tests_soc_tb)

# FIXME SOC tests have bit rotted, so disable for now
#tests_unit: tests_core tests_soc
tests_unit: tests_core
#tests_unit: tests_soc

TAGS:
find . -name '*.vhdl' | xargs ./scripts/vhdltags

@ -1,12 +1,18 @@
library vunit_lib;
context vunit_lib.vunit_context;

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library work;
use work.common.all;
use work.glibc_random.all;

library osvvm;
use osvvm.RandomPkg.all;

entity countzero_tb is
generic (runner_cfg : string := runner_cfg_default);
end countzero_tb;

architecture behave of countzero_tb is
@ -37,9 +43,14 @@ begin

stim_process: process
variable r: std_ulogic_vector(63 downto 0);
variable rnd : RandomPType;
begin
-- test with input = 0
report "test zero input";
rnd.InitSeed(stim_process'path_name);

test_runner_setup(runner, runner_cfg);

while test_suite loop
if run("Test with input = 0") then
rs <= (others => '0');
is_32bit <= '0';
count_right <= '0';
@ -60,10 +71,10 @@ begin
assert result = x"0000000000000020"
report "bad cnttzw 0 = " & to_hstring(result);

report "test cntlzd/w";
elsif run("Test cntlzd/w") then
count_right <= '0';
for j in 0 to 100 loop
r := pseudorand(64);
r := rnd.RandSlv(64);
r(63) := '1';
for i in 0 to 63 loop
rs <= r;
@ -85,10 +96,10 @@ begin
end loop;
end loop;

report "test cnttzd/w";
elsif run("Test cnttzd/w") then
count_right <= '1';
for j in 0 to 100 loop
r := pseudorand(64);
r := rnd.RandSlv(64);
r(0) := '1';
for i in 0 to 63 loop
rs <= r;
@ -108,7 +119,9 @@ begin
r := r(62 downto 0) & '0';
end loop;
end loop;
end if;
end loop;

std.env.finish;
test_runner_cleanup(runner);
end process;
end behave;

@ -1,3 +1,6 @@
library vunit_lib;
context vunit_lib.vunit_context;

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
@ -5,10 +8,13 @@ use ieee.numeric_std.all;
library work;
use work.decode_types.all;
use work.common.all;
use work.glibc_random.all;
use work.ppc_fx_insns.all;

library osvvm;
use osvvm.RandomPkg.all;

entity divider_tb is
generic (runner_cfg : string := runner_cfg_default);
end divider_tb;

architecture behave of divider_tb is
@ -37,19 +43,28 @@ begin
variable q128: std_ulogic_vector(127 downto 0);
variable q64: std_ulogic_vector(63 downto 0);
variable rem32: std_ulogic_vector(31 downto 0);
variable rnd : RandomPType;
begin
rnd.InitSeed(stim_process'path_name);

test_runner_setup(runner, runner_cfg);

while test_suite loop
rst <= '1';
wait for clk_period;
rst <= '0';

d1.valid <= '1';
d1.dividend <= x"0000000010001000";
d1.divisor <= x"0000000000001111";
d1.is_signed <= '0';
d1.is_32bit <= '0';
d1.neg_result <= '0';
d1.is_extended <= '0';
d1.is_32bit <= '0';
d1.is_modulus <= '0';
d1.neg_result <= '0';
d1.valid <= '0';

if run("Test interface") then
d1.valid <= '1';
d1.dividend <= x"0000000010001000";
d1.divisor <= x"0000000000001111";

wait for clk_period;
assert d2.valid = '0';
@ -89,13 +104,12 @@ begin
wait for clk_period;
assert d2.valid = '0';

-- test divd
report "test divd";
elsif run("Test divd") then
divd_loop : for dlength in 1 to 8 loop
for vlength in 1 to dlength loop
for i in 0 to 100 loop
ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 64));
rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
ra := std_ulogic_vector(resize(signed(rnd.RandSlv(dlength * 8)), 64));
rb := std_ulogic_vector(resize(signed(rnd.RandSlv(vlength * 8)), 64));

d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra));
d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb));
@ -124,18 +138,15 @@ begin
end loop;
end loop;

-- test divdu
report "test divdu";
elsif run("Test divdu") then
divdu_loop : for dlength in 1 to 8 loop
for vlength in 1 to dlength loop
for i in 0 to 100 loop
ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 64));
rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
ra := std_ulogic_vector(resize(unsigned(rnd.RandSlv(dlength * 8)), 64));
rb := std_ulogic_vector(resize(unsigned(rnd.RandSlv(vlength * 8)), 64));

d1.dividend <= ra;
d1.divisor <= rb;
d1.is_signed <= '0';
d1.neg_result <= '0';
d1.valid <= '1';

wait for clk_period;
@ -159,13 +170,12 @@ begin
end loop;
end loop;

-- test divde
report "test divde";
elsif run("Test divde") then
divde_loop : for vlength in 1 to 8 loop
for dlength in 1 to vlength loop
for i in 0 to 100 loop
ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 64));
rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
ra := std_ulogic_vector(resize(signed(rnd.RandSlv(dlength * 8)), 64));
rb := std_ulogic_vector(resize(signed(rnd.RandSlv(vlength * 8)), 64));

d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra));
d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb));
@ -200,18 +210,15 @@ begin
end loop;
end loop;

-- test divdeu
report "test divdeu";
elsif run("Test divdeu") then
divdeu_loop : for vlength in 1 to 8 loop
for dlength in 1 to vlength loop
for i in 0 to 100 loop
ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 64));
rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
ra := std_ulogic_vector(resize(unsigned(rnd.RandSlv(dlength * 8)), 64));
rb := std_ulogic_vector(resize(unsigned(rnd.RandSlv(vlength * 8)), 64));

d1.dividend <= ra;
d1.divisor <= rb;
d1.is_signed <= '0';
d1.neg_result <= '0';
d1.is_extended <= '1';
d1.valid <= '1';

@ -238,19 +245,17 @@ begin
end loop;
end loop;

-- test divw
report "test divw";
elsif run("Test divw") then
divw_loop : for dlength in 1 to 4 loop
for vlength in 1 to dlength loop
for i in 0 to 100 loop
ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 64));
rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
ra := std_ulogic_vector(resize(signed(rnd.RandSlv(dlength * 8)), 64));
rb := std_ulogic_vector(resize(signed(rnd.RandSlv(vlength * 8)), 64));

d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra));
d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb));
d1.is_signed <= '1';
d1.neg_result <= ra(63) xor rb(63);
d1.is_extended <= '0';
d1.is_32bit <= '1';
d1.valid <= '1';

@ -275,19 +280,15 @@ begin
end loop;
end loop;

-- test divwu
report "test divwu";
elsif run("Test divwu") then
divwu_loop : for dlength in 1 to 4 loop
for vlength in 1 to dlength loop
for i in 0 to 100 loop
ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 64));
rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
ra := std_ulogic_vector(resize(unsigned(rnd.RandSlv(dlength * 8)), 64));
rb := std_ulogic_vector(resize(unsigned(rnd.RandSlv(vlength * 8)), 64));

d1.dividend <= ra;
d1.divisor <= rb;
d1.is_signed <= '0';
d1.neg_result <= '0';
d1.is_extended <= '0';
d1.is_32bit <= '1';
d1.valid <= '1';

@ -312,19 +313,17 @@ begin
end loop;
end loop;

-- test divwe
report "test divwe";
elsif run("Test divwe") then
divwe_loop : for vlength in 1 to 4 loop
for dlength in 1 to vlength loop
for i in 0 to 100 loop
ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 32)) & x"00000000";
rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
ra := std_ulogic_vector(resize(signed(rnd.RandSlv(dlength * 8)), 32)) & x"00000000";
rb := std_ulogic_vector(resize(signed(rnd.RandSlv(vlength * 8)), 64));

d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra));
d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb));
d1.is_signed <= '1';
d1.neg_result <= ra(63) xor rb(63);
d1.is_extended <= '0';
d1.is_32bit <= '1';
d1.valid <= '1';

@ -353,19 +352,15 @@ begin
end loop;
end loop;

-- test divweu
report "test divweu";
elsif run("Test divweu") then
divweu_loop : for vlength in 1 to 4 loop
for dlength in 1 to vlength loop
for i in 0 to 100 loop
ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 32)) & x"00000000";
rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
ra := std_ulogic_vector(resize(unsigned(rnd.RandSlv(dlength * 8)), 32)) & x"00000000";
rb := std_ulogic_vector(resize(unsigned(rnd.RandSlv(vlength * 8)), 64));

d1.dividend <= ra;
d1.divisor <= rb;
d1.is_signed <= '0';
d1.neg_result <= '0';
d1.is_extended <= '0';
d1.is_32bit <= '1';
d1.valid <= '1';

@ -390,20 +385,17 @@ begin
end loop;
end loop;

-- test modsd
report "test modsd";
elsif run("Test modsd") then
modsd_loop : for dlength in 1 to 8 loop
for vlength in 1 to dlength loop
for i in 0 to 100 loop
ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 64));
rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
ra := std_ulogic_vector(resize(signed(rnd.RandSlv(dlength * 8)), 64));
rb := std_ulogic_vector(resize(signed(rnd.RandSlv(vlength * 8)), 64));

d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra));
d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb));
d1.is_signed <= '1';
d1.neg_result <= ra(63);
d1.is_extended <= '0';
d1.is_32bit <= '0';
d1.is_modulus <= '1';
d1.valid <= '1';

@ -428,20 +420,15 @@ begin
end loop;
end loop;

-- test modud
report "test modud";
elsif run("Test modud") then
modud_loop : for dlength in 1 to 8 loop
for vlength in 1 to dlength loop
for i in 0 to 100 loop
ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 64));
rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
ra := std_ulogic_vector(resize(unsigned(rnd.RandSlv(dlength * 8)), 64));
rb := std_ulogic_vector(resize(unsigned(rnd.RandSlv(vlength * 8)), 64));

d1.dividend <= ra;
d1.divisor <= rb;
d1.is_signed <= '0';
d1.neg_result <= '0';
d1.is_extended <= '0';
d1.is_32bit <= '0';
d1.is_modulus <= '1';
d1.valid <= '1';

@ -466,19 +453,17 @@ begin
end loop;
end loop;

-- test modsw
report "test modsw";
elsif run("Test modsw") then
modsw_loop : for dlength in 1 to 4 loop
for vlength in 1 to dlength loop
for i in 0 to 100 loop
ra := std_ulogic_vector(resize(signed(pseudorand(dlength * 8)), 64));
rb := std_ulogic_vector(resize(signed(pseudorand(vlength * 8)), 64));
ra := std_ulogic_vector(resize(signed(rnd.RandSlv(dlength * 8)), 64));
rb := std_ulogic_vector(resize(signed(rnd.RandSlv(vlength * 8)), 64));

d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra));
d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb));
d1.is_signed <= '1';
d1.neg_result <= ra(63);
d1.is_extended <= '0';
d1.is_32bit <= '1';
d1.is_modulus <= '1';
d1.valid <= '1';
@ -509,19 +494,15 @@ begin
end loop;
end loop;

-- test moduw
report "test moduw";
elsif run("Test moduw") then
moduw_loop : for dlength in 1 to 4 loop
for vlength in 1 to dlength loop
for i in 0 to 100 loop
ra := std_ulogic_vector(resize(unsigned(pseudorand(dlength * 8)), 64));
rb := std_ulogic_vector(resize(unsigned(pseudorand(vlength * 8)), 64));
ra := std_ulogic_vector(resize(unsigned(rnd.RandSlv(dlength * 8)), 64));
rb := std_ulogic_vector(resize(unsigned(rnd.RandSlv(vlength * 8)), 64));

d1.dividend <= ra;
d1.divisor <= rb;
d1.is_signed <= '0';
d1.neg_result <= '0';
d1.is_extended <= '0';
d1.is_32bit <= '1';
d1.is_modulus <= '1';
d1.valid <= '1';
@ -546,7 +527,9 @@ begin
end loop;
end loop;
end loop;
end if;
end loop;

std.env.finish;
test_runner_cleanup(runner);
end process;
end behave;

@ -0,0 +1,30 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library work;
use work.glibc_random.all;

entity random is
port (
clk : in std_ulogic;
data : out std_ulogic_vector(63 downto 0);
raw : out std_ulogic_vector(63 downto 0);
err : out std_ulogic
);
end entity random;

architecture behaviour of random is
begin
err <= '0';

process(clk)
variable rand : std_ulogic_vector(63 downto 0);
begin
if rising_edge(clk) then
rand := pseudorand(64);
data <= rand;
raw <= rand;
end if;
end process;
end behaviour;

@ -1,3 +1,6 @@
library vunit_lib;
context vunit_lib.vunit_context;

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
@ -5,10 +8,13 @@ use ieee.numeric_std.all;
library work;
use work.decode_types.all;
use work.common.all;
use work.glibc_random.all;
use work.ppc_fx_insns.all;

library osvvm;
use osvvm.RandomPkg.all;

entity multiply_tb is
generic (runner_cfg : string := runner_cfg_default);
end multiply_tb;

architecture behave of multiply_tb is
@ -46,7 +52,14 @@ begin
variable ra, rb, rt, behave_rt: std_ulogic_vector(63 downto 0);
variable si: std_ulogic_vector(15 downto 0);
variable sign: std_ulogic;
variable rnd : RandomPType;
begin
rnd.InitSeed(stim_process'path_name);

test_runner_setup(runner, runner_cfg);

while test_suite loop
if run("Test interface") then
wait for clk_period;

m1.valid <= '1';
@ -82,10 +95,10 @@ begin
assert m2.valid = '1';
assert m2.result = x"00000000000000000000000001111000";

-- test mulld
elsif run("Test mulld") then
mulld_loop : for i in 0 to 1000 loop
ra := pseudorand(ra'length);
rb := pseudorand(rb'length);
ra := rnd.RandSlv(ra'length);
rb := rnd.RandSlv(rb'length);

behave_rt := ppc_mulld(ra, rb);

@ -108,10 +121,10 @@ begin
report "bad mulld expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.result(63 downto 0));
end loop;

-- test mulhdu
elsif run("Test mulhdu") then
mulhdu_loop : for i in 0 to 1000 loop
ra := pseudorand(ra'length);
rb := pseudorand(rb'length);
ra := rnd.RandSlv(ra'length);
rb := rnd.RandSlv(rb'length);

behave_rt := ppc_mulhdu(ra, rb);

@ -133,10 +146,10 @@ begin
report "bad mulhdu expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.result(127 downto 64));
end loop;

-- test mulhd
elsif run("Test mulhd") then
mulhd_loop : for i in 0 to 1000 loop
ra := pseudorand(ra'length);
rb := pseudorand(rb'length);
ra := rnd.RandSlv(ra'length);
rb := rnd.RandSlv(rb'length);

behave_rt := ppc_mulhd(ra, rb);

@ -159,10 +172,10 @@ begin
report "bad mulhd expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.result(127 downto 64));
end loop;

-- test mullw
elsif run("Test mullw") then
mullw_loop : for i in 0 to 1000 loop
ra := pseudorand(ra'length);
rb := pseudorand(rb'length);
ra := rnd.RandSlv(ra'length);
rb := rnd.RandSlv(rb'length);

behave_rt := ppc_mullw(ra, rb);

@ -187,10 +200,10 @@ begin
report "bad mullw expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.result(63 downto 0));
end loop;

-- test mulhw
elsif run("Test mulhw") then
mulhw_loop : for i in 0 to 1000 loop
ra := pseudorand(ra'length);
rb := pseudorand(rb'length);
ra := rnd.RandSlv(ra'length);
rb := rnd.RandSlv(rb'length);

behave_rt := ppc_mulhw(ra, rb);

@ -216,10 +229,10 @@ begin
to_hstring(m2.result(63 downto 32) & m2.result(63 downto 32));
end loop;

-- test mulhwu
elsif run("Test mulhwu") then
mulhwu_loop : for i in 0 to 1000 loop
ra := pseudorand(ra'length);
rb := pseudorand(rb'length);
ra := rnd.RandSlv(ra'length);
rb := rnd.RandSlv(rb'length);

behave_rt := ppc_mulhwu(ra, rb);

@ -244,10 +257,10 @@ begin
to_hstring(m2.result(63 downto 32) & m2.result(63 downto 32));
end loop;

-- test mulli
elsif run("Test mulli") then
mulli_loop : for i in 0 to 1000 loop
ra := pseudorand(ra'length);
si := pseudorand(si'length);
ra := rnd.RandSlv(ra'length);
si := rnd.RandSlv(si'length);

behave_rt := ppc_mulli(ra, si);

@ -270,8 +283,10 @@ begin
assert to_hstring(behave_rt) = to_hstring(m2.result(63 downto 0))
report "bad mulli expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.result(63 downto 0));
end loop;
end if;
end loop;

std.env.finish;
test_runner_cleanup(runner);
wait;
end process;
end behave;

@ -1,3 +1,6 @@
library vunit_lib;
context vunit_lib.vunit_context;

library ieee;
use ieee.std_logic_1164.all;

@ -6,6 +9,7 @@ use work.common.all;
use work.wishbone_types.all;

entity plru_tb is
generic (runner_cfg : string := runner_cfg_default);
end plru_tb;

architecture behave of plru_tb is
@ -50,6 +54,8 @@ begin

stim: process
begin
test_runner_setup(runner, runner_cfg);

wait for 4*clk_period;

report "accessing 1:";
@ -103,6 +109,6 @@ begin
wait for clk_period;
report "lru:" & to_hstring(lru);

std.env.finish;
test_runner_cleanup(runner);
end process;
end;

@ -2,8 +2,8 @@ library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library work;
use work.glibc_random.all;
library osvvm;
use osvvm.RandomPkg.all;

entity random is
port (
@ -20,9 +20,10 @@ begin

process(clk)
variable rand : std_ulogic_vector(63 downto 0);
variable rnd : RandomPType;
begin
if rising_edge(clk) then
rand := pseudorand(64);
rand := rnd.RandSlv(64);
data <= rand;
raw <= rand;
end if;

@ -1,14 +1,20 @@
library vunit_lib;
context vunit_lib.vunit_context;

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library work;
use work.common.all;
use work.glibc_random.all;
use work.ppc_fx_insns.all;
use work.insn_helpers.all;

library osvvm;
use osvvm.RandomPkg.all;

entity rotator_tb is
generic (runner_cfg : string := runner_cfg_default);
end rotator_tb;

architecture behave of rotator_tb is
@ -41,9 +47,14 @@ begin
stim_process: process
variable behave_ra: std_ulogic_vector(63 downto 0);
variable behave_ca_ra: std_ulogic_vector(64 downto 0);
variable rnd : RandomPType;
begin
-- rlwinm, rlwnm
report "test rlw[i]nm";
rnd.InitSeed(stim_process'path_name);

test_runner_setup(runner, runner_cfg);

while test_suite loop
if run("Test rlw[i]nm") then
ra <= (others => '0');
is_32bit <= '1';
right_shift <= '0';
@ -52,35 +63,33 @@ begin
clear_right <= '1';
extsw <= '0';
rlwnm_loop : for i in 0 to 1000 loop
rs <= pseudorand(64);
shift <= pseudorand(7);
insn <= x"00000" & '0' & pseudorand(10) & '0';
rs <= rnd.RandSlv(64);
shift <= rnd.RandSlv(7);
insn <= x"00000" & '0' & rnd.RandSlv(10) & '0';
wait for clk_period;
behave_ra := ppc_rlwinm(rs, shift(4 downto 0), insn_mb32(insn), insn_me32(insn));
assert behave_ra = result
report "bad rlwnm expected " & to_hstring(behave_ra) & " got " & to_hstring(result);
end loop;

-- rlwimi
report "test rlwimi";
elsif run("Test rlwimi") then
is_32bit <= '1';
right_shift <= '0';
arith <= '0';
clear_left <= '1';
clear_right <= '1';
rlwimi_loop : for i in 0 to 1000 loop
rs <= pseudorand(64);
ra <= pseudorand(64);
shift <= "00" & pseudorand(5);
insn <= x"00000" & '0' & pseudorand(10) & '0';
rs <= rnd.RandSlv(64);
ra <= rnd.RandSlv(64);
shift <= "00" & rnd.RandSlv(5);
insn <= x"00000" & '0' & rnd.RandSlv(10) & '0';
wait for clk_period;
behave_ra := ppc_rlwimi(ra, rs, shift(4 downto 0), insn_mb32(insn), insn_me32(insn));
assert behave_ra = result
report "bad rlwimi expected " & to_hstring(behave_ra) & " got " & to_hstring(result);
end loop;

-- rldicl, rldcl
report "test rld[i]cl";
elsif run("Test rld[i]cl") then
ra <= (others => '0');
is_32bit <= '0';
right_shift <= '0';
@ -88,17 +97,16 @@ begin
clear_left <= '1';
clear_right <= '0';
rldicl_loop : for i in 0 to 1000 loop
rs <= pseudorand(64);
shift <= pseudorand(7);
insn <= x"00000" & '0' & pseudorand(10) & '0';
rs <= rnd.RandSlv(64);
shift <= rnd.RandSlv(7);
insn <= x"00000" & '0' & rnd.RandSlv(10) & '0';
wait for clk_period;
behave_ra := ppc_rldicl(rs, shift(5 downto 0), insn_mb(insn));
assert behave_ra = result
report "bad rldicl expected " & to_hstring(behave_ra) & " got " & to_hstring(result);
end loop;

-- rldicr, rldcr
report "test rld[i]cr";
elsif run("Test rld[i]cr") then
ra <= (others => '0');
is_32bit <= '0';
right_shift <= '0';
@ -106,9 +114,9 @@ begin
clear_left <= '0';
clear_right <= '1';
rldicr_loop : for i in 0 to 1000 loop
rs <= pseudorand(64);
shift <= pseudorand(7);
insn <= x"00000" & '0' & pseudorand(10) & '0';
rs <= rnd.RandSlv(64);
shift <= rnd.RandSlv(7);
insn <= x"00000" & '0' & rnd.RandSlv(10) & '0';
wait for clk_period;
behave_ra := ppc_rldicr(rs, shift(5 downto 0), insn_me(insn));
--report "rs = " & to_hstring(rs);
@ -120,8 +128,7 @@ begin
report "bad rldicr expected " & to_hstring(behave_ra) & " got " & to_hstring(result);
end loop;

-- rldic
report "test rldic";
elsif run("Test rldic") then
ra <= (others => '0');
is_32bit <= '0';
right_shift <= '0';
@ -129,35 +136,33 @@ begin
clear_left <= '1';
clear_right <= '1';
rldic_loop : for i in 0 to 1000 loop
rs <= pseudorand(64);
shift <= '0' & pseudorand(6);
insn <= x"00000" & '0' & pseudorand(10) & '0';
rs <= rnd.RandSlv(64);
shift <= '0' & rnd.RandSlv(6);
insn <= x"00000" & '0' & rnd.RandSlv(10) & '0';
wait for clk_period;
behave_ra := ppc_rldic(rs, shift(5 downto 0), insn_mb(insn));
assert behave_ra = result
report "bad rldic expected " & to_hstring(behave_ra) & " got " & to_hstring(result);
end loop;

-- rldimi
report "test rldimi";
elsif run("Test rldimi") then
is_32bit <= '0';
right_shift <= '0';
arith <= '0';
clear_left <= '1';
clear_right <= '1';
rldimi_loop : for i in 0 to 1000 loop
rs <= pseudorand(64);
ra <= pseudorand(64);
shift <= '0' & pseudorand(6);
insn <= x"00000" & '0' & pseudorand(10) & '0';
rs <= rnd.RandSlv(64);
ra <= rnd.RandSlv(64);
shift <= '0' & rnd.RandSlv(6);
insn <= x"00000" & '0' & rnd.RandSlv(10) & '0';
wait for clk_period;
behave_ra := ppc_rldimi(ra, rs, shift(5 downto 0), insn_mb(insn));
assert behave_ra = result
report "bad rldimi expected " & to_hstring(behave_ra) & " got " & to_hstring(result);
end loop;

-- slw
report "test slw";
elsif run("Test slw") then
ra <= (others => '0');
is_32bit <= '1';
right_shift <= '0';
@ -165,16 +170,15 @@ begin
clear_left <= '0';
clear_right <= '0';
slw_loop : for i in 0 to 1000 loop
rs <= pseudorand(64);
shift <= pseudorand(7);
rs <= rnd.RandSlv(64);
shift <= rnd.RandSlv(7);
wait for clk_period;
behave_ra := ppc_slw(rs, std_ulogic_vector(resize(unsigned(shift), 64)));
assert behave_ra = result
report "bad slw expected " & to_hstring(behave_ra) & " got " & to_hstring(result);
end loop;

-- sld
report "test sld";
elsif run("Test sld") then
ra <= (others => '0');
is_32bit <= '0';
right_shift <= '0';
@ -182,16 +186,15 @@ begin
clear_left <= '0';
clear_right <= '0';
sld_loop : for i in 0 to 1000 loop
rs <= pseudorand(64);
shift <= pseudorand(7);
rs <= rnd.RandSlv(64);
shift <= rnd.RandSlv(7);
wait for clk_period;
behave_ra := ppc_sld(rs, std_ulogic_vector(resize(unsigned(shift), 64)));
assert behave_ra = result
report "bad sld expected " & to_hstring(behave_ra) & " got " & to_hstring(result);
end loop;

-- srw
report "test srw";
elsif run("Test srw") then
ra <= (others => '0');
is_32bit <= '1';
right_shift <= '1';
@ -199,16 +202,15 @@ begin
clear_left <= '0';
clear_right <= '0';
srw_loop : for i in 0 to 1000 loop
rs <= pseudorand(64);
shift <= pseudorand(7);
rs <= rnd.RandSlv(64);
shift <= rnd.RandSlv(7);
wait for clk_period;
behave_ra := ppc_srw(rs, std_ulogic_vector(resize(unsigned(shift), 64)));
assert behave_ra = result
report "bad srw expected " & to_hstring(behave_ra) & " got " & to_hstring(result);
end loop;

-- srd
report "test srd";
elsif run("Test srd") then
ra <= (others => '0');
is_32bit <= '0';
right_shift <= '1';
@ -216,16 +218,15 @@ begin
clear_left <= '0';
clear_right <= '0';
srd_loop : for i in 0 to 1000 loop
rs <= pseudorand(64);
shift <= pseudorand(7);
rs <= rnd.RandSlv(64);
shift <= rnd.RandSlv(7);
wait for clk_period;
behave_ra := ppc_srd(rs, std_ulogic_vector(resize(unsigned(shift), 64)));
assert behave_ra = result
report "bad srd expected " & to_hstring(behave_ra) & " got " & to_hstring(result);
end loop;

-- sraw[i]
report "test sraw[i]";
elsif run("Test sraw[i]") then
ra <= (others => '0');
is_32bit <= '1';
right_shift <= '1';
@ -233,8 +234,8 @@ begin
clear_left <= '0';
clear_right <= '0';
sraw_loop : for i in 0 to 1000 loop
rs <= pseudorand(64);
shift <= '0' & pseudorand(6);
rs <= rnd.RandSlv(64);
shift <= '0' & rnd.RandSlv(6);
wait for clk_period;
behave_ca_ra := ppc_sraw(rs, std_ulogic_vector(resize(unsigned(shift), 64)));
--report "rs = " & to_hstring(rs);
@ -245,8 +246,7 @@ begin
report "bad sraw expected " & to_hstring(behave_ca_ra) & " got " & to_hstring(carry_out & result);
end loop;

-- srad[i]
report "test srad[i]";
elsif run("Test srad[i]") then
ra <= (others => '0');
is_32bit <= '0';
right_shift <= '1';
@ -254,8 +254,8 @@ begin
clear_left <= '0';
clear_right <= '0';
srad_loop : for i in 0 to 1000 loop
rs <= pseudorand(64);
shift <= pseudorand(7);
rs <= rnd.RandSlv(64);
shift <= rnd.RandSlv(7);
wait for clk_period;
behave_ca_ra := ppc_srad(rs, std_ulogic_vector(resize(unsigned(shift), 64)));
--report "rs = " & to_hstring(rs);
@ -266,8 +266,7 @@ begin
report "bad srad expected " & to_hstring(behave_ca_ra) & " got " & to_hstring(carry_out & result);
end loop;

-- extswsli
report "test extswsli";
elsif run("Test extswsli") then
ra <= (others => '0');
is_32bit <= '0';
right_shift <= '0';
@ -276,8 +275,8 @@ begin
clear_right <= '0';
extsw <= '1';
extswsli_loop : for i in 0 to 1000 loop
rs <= pseudorand(64);
shift <= '0' & pseudorand(6);
rs <= rnd.RandSlv(64);
shift <= '0' & rnd.RandSlv(6);
wait for clk_period;
behave_ra := rs;
behave_ra(63 downto 32) := (others => rs(31));
@ -290,7 +289,8 @@ begin
assert behave_ra = result
report "bad extswsli expected " & to_hstring(behave_ra) & " got " & to_hstring(result);
end loop;

std.env.finish;
end if;
end loop;
test_runner_cleanup(runner);
end process;
end behave;

@ -0,0 +1,27 @@
from pathlib import Path
from vunit import VUnit
from glob import glob

prj = VUnit.from_argv()
prj.add_osvvm()
root = Path(__file__).parent

lib = prj.add_library("lib")
lib.add_source_files(root / "litedram/extras/*.vhdl")
lib.add_source_files(root / "litedram/generated/sim/*.vhdl")

# Use multiply.vhd and not xilinx-mult.vhd. Use VHDL-based random.
vhdl_files = glob(str(root / "*.vhdl"))
vhdl_files = [
src_file
for src_file in vhdl_files
if ("xilinx-mult" not in src_file)
and ("foreign_random" not in src_file)
and ("nonrandom" not in src_file)
]
lib.add_source_files(vhdl_files)

unisim = prj.add_library("unisim")
unisim.add_source_files(root / "sim-unisim/*.vhdl")

prj.main()
Loading…
Cancel
Save