mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-01-11 23:43:15 +00:00
The VUnit log package is a SW style logging framework in VHDL and the check package is an assertion library doing its error reporting with VUnit logging. These testbenches don't use, and do not need, very advanced logging/checking features but the following was possible to improve - Checking equality in VHDL can be quite tedious with a lot of type conversions and long message strings to explain the data received and what was expected. VUnit's check_equal procedure allow comparison between same or similar types and automatically create the error message for you. - The code has report statements used for testbench progress reporting and debugging. These were replaced with the info and debug procedures. info logs are visible by default while debug is not. This means that debug logs don't have to be commented, which they are now, when not used. Instead there is a show procedure making debug messages visible. The show procedure has been commented to hide the debug messages but a more elegant solution is to control visibility from a generic and then set that generic from the command line. I've left this as a TODO but the run script allow you to extend the standard CLI of VUnit to add new options and you can also set generics from the run script. - VUnit log messages are color coded if color codes are supported by the terminal. It makes it quicker to spot messages of different types when there are many log messages. Error messages will always be made visible on the terminal but you must use the -v (verbose) to see other logs. - Some tests have a lot of "metvalue detected" warning messages from the numeric_std package and these clutter the logs when using the -v option. VUnit has a simulator independent option allowing you to suppress those messages. That option has been enabled. Signed-off-by: Lars Asplund <lars.anders.asplund@gmail.com>
290 lines
12 KiB
VHDL
290 lines
12 KiB
VHDL
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.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
|
|
constant clk_period: time := 10 ns;
|
|
signal ra, rs: std_ulogic_vector(63 downto 0);
|
|
signal shift: std_ulogic_vector(6 downto 0) := (others => '0');
|
|
signal insn: std_ulogic_vector(31 downto 0) := (others => '0');
|
|
signal is_32bit, right_shift, arith, clear_left, clear_right: std_ulogic := '0';
|
|
signal res: std_ulogic_vector(63 downto 0);
|
|
signal carry_out: std_ulogic;
|
|
signal extsw: std_ulogic;
|
|
|
|
begin
|
|
rotator_0: entity work.rotator
|
|
port map (
|
|
rs => rs,
|
|
ra => ra,
|
|
shift => shift,
|
|
insn => insn,
|
|
is_32bit => is_32bit,
|
|
right_shift => right_shift,
|
|
arith => arith,
|
|
clear_left => clear_left,
|
|
clear_right => clear_right,
|
|
sign_ext_rs => extsw,
|
|
result => res,
|
|
carry_out => carry_out
|
|
);
|
|
|
|
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
|
|
rnd.InitSeed(stim_process'path_name);
|
|
|
|
-- TODO: Consider making debug messages visible with a command line option
|
|
-- rather than uncommenting this line:
|
|
-- show(display_handler, debug);
|
|
|
|
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';
|
|
arith <= '0';
|
|
clear_left <= '1';
|
|
clear_right <= '1';
|
|
extsw <= '0';
|
|
rlwnm_loop : for i in 0 to 1000 loop
|
|
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));
|
|
check_equal(res, behave_ra, result("for rlwnm"));
|
|
end loop;
|
|
|
|
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 <= 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));
|
|
check_equal(res, behave_ra, result("for rlwnimi"));
|
|
end loop;
|
|
|
|
elsif run("Test rld[i]cl") then
|
|
ra <= (others => '0');
|
|
is_32bit <= '0';
|
|
right_shift <= '0';
|
|
arith <= '0';
|
|
clear_left <= '1';
|
|
clear_right <= '0';
|
|
rldicl_loop : for i in 0 to 1000 loop
|
|
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));
|
|
check_equal(res, behave_ra, result("for rldicl"));
|
|
end loop;
|
|
|
|
elsif run("Test rld[i]cr") then
|
|
ra <= (others => '0');
|
|
is_32bit <= '0';
|
|
right_shift <= '0';
|
|
arith <= '0';
|
|
clear_left <= '0';
|
|
clear_right <= '1';
|
|
rldicr_loop : for i in 0 to 1000 loop
|
|
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));
|
|
debug("rs = " & to_hstring(rs));
|
|
debug("ra = " & to_hstring(ra));
|
|
debug("shift = " & to_hstring(shift));
|
|
debug("insn me = " & to_hstring(insn_me(insn)));
|
|
debug("result = " & to_hstring(res));
|
|
check_equal(res, behave_ra, result("for rldicr"));
|
|
end loop;
|
|
|
|
elsif run("Test rldic") then
|
|
ra <= (others => '0');
|
|
is_32bit <= '0';
|
|
right_shift <= '0';
|
|
arith <= '0';
|
|
clear_left <= '1';
|
|
clear_right <= '1';
|
|
rldic_loop : for i in 0 to 1000 loop
|
|
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));
|
|
check_equal(res, behave_ra, result("for rldic"));
|
|
end loop;
|
|
|
|
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 <= 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));
|
|
check_equal(res, behave_ra, result("for rldimi"));
|
|
end loop;
|
|
|
|
elsif run("Test slw") then
|
|
ra <= (others => '0');
|
|
is_32bit <= '1';
|
|
right_shift <= '0';
|
|
arith <= '0';
|
|
clear_left <= '0';
|
|
clear_right <= '0';
|
|
slw_loop : for i in 0 to 1000 loop
|
|
rs <= rnd.RandSlv(64);
|
|
shift <= rnd.RandSlv(7);
|
|
wait for clk_period;
|
|
behave_ra := ppc_slw(rs, std_ulogic_vector(resize(unsigned(shift), 64)));
|
|
check_equal(res, behave_ra, result("for slv"));
|
|
end loop;
|
|
|
|
elsif run("Test sld") then
|
|
ra <= (others => '0');
|
|
is_32bit <= '0';
|
|
right_shift <= '0';
|
|
arith <= '0';
|
|
clear_left <= '0';
|
|
clear_right <= '0';
|
|
sld_loop : for i in 0 to 1000 loop
|
|
rs <= rnd.RandSlv(64);
|
|
shift <= rnd.RandSlv(7);
|
|
wait for clk_period;
|
|
behave_ra := ppc_sld(rs, std_ulogic_vector(resize(unsigned(shift), 64)));
|
|
check_equal(res, behave_ra, result("for sld"));
|
|
end loop;
|
|
|
|
elsif run("Test srw") then
|
|
ra <= (others => '0');
|
|
is_32bit <= '1';
|
|
right_shift <= '1';
|
|
arith <= '0';
|
|
clear_left <= '0';
|
|
clear_right <= '0';
|
|
srw_loop : for i in 0 to 1000 loop
|
|
rs <= rnd.RandSlv(64);
|
|
shift <= rnd.RandSlv(7);
|
|
wait for clk_period;
|
|
behave_ra := ppc_srw(rs, std_ulogic_vector(resize(unsigned(shift), 64)));
|
|
check_equal(res, behave_ra, result("for srw"));
|
|
end loop;
|
|
|
|
elsif run("Test srd") then
|
|
ra <= (others => '0');
|
|
is_32bit <= '0';
|
|
right_shift <= '1';
|
|
arith <= '0';
|
|
clear_left <= '0';
|
|
clear_right <= '0';
|
|
srd_loop : for i in 0 to 1000 loop
|
|
rs <= rnd.RandSlv(64);
|
|
shift <= rnd.RandSlv(7);
|
|
wait for clk_period;
|
|
behave_ra := ppc_srd(rs, std_ulogic_vector(resize(unsigned(shift), 64)));
|
|
check_equal(res, behave_ra, result("for srd"));
|
|
end loop;
|
|
|
|
elsif run("Test sraw[i]") then
|
|
ra <= (others => '0');
|
|
is_32bit <= '1';
|
|
right_shift <= '1';
|
|
arith <= '1';
|
|
clear_left <= '0';
|
|
clear_right <= '0';
|
|
sraw_loop : for i in 0 to 1000 loop
|
|
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)));
|
|
debug("rs = " & to_hstring(rs));
|
|
debug("ra = " & to_hstring(ra));
|
|
debug("shift = " & to_hstring(shift));
|
|
debug("result = " & to_hstring(carry_out & res));
|
|
check_equal(res, behave_ca_ra(63 downto 0), result("for sraw"));
|
|
check_equal(carry_out, behave_ca_ra(64), result("for sraw carry_out"));
|
|
end loop;
|
|
|
|
elsif run("Test srad[i]") then
|
|
ra <= (others => '0');
|
|
is_32bit <= '0';
|
|
right_shift <= '1';
|
|
arith <= '1';
|
|
clear_left <= '0';
|
|
clear_right <= '0';
|
|
srad_loop : for i in 0 to 1000 loop
|
|
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)));
|
|
debug("rs = " & to_hstring(rs));
|
|
debug("ra = " & to_hstring(ra));
|
|
debug("shift = " & to_hstring(shift));
|
|
debug("result = " & to_hstring(carry_out & res));
|
|
check_equal(res, behave_ca_ra(63 downto 0), result("for srad"));
|
|
check_equal(carry_out, behave_ca_ra(64), result("for srad carry_out"));
|
|
end loop;
|
|
|
|
elsif run("Test extswsli") then
|
|
ra <= (others => '0');
|
|
is_32bit <= '0';
|
|
right_shift <= '0';
|
|
arith <= '0';
|
|
clear_left <= '0';
|
|
clear_right <= '0';
|
|
extsw <= '1';
|
|
extswsli_loop : for i in 0 to 1000 loop
|
|
rs <= rnd.RandSlv(64);
|
|
shift <= '0' & rnd.RandSlv(6);
|
|
wait for clk_period;
|
|
behave_ra := rs;
|
|
behave_ra(63 downto 32) := (others => rs(31));
|
|
behave_ra := std_ulogic_vector(shift_left(unsigned(behave_ra),
|
|
to_integer(unsigned(shift))));
|
|
debug("rs = " & to_hstring(rs));
|
|
debug("ra = " & to_hstring(ra));
|
|
debug("shift = " & to_hstring(shift));
|
|
debug("result = " & to_hstring(carry_out & res));
|
|
check_equal(res, behave_ra, result("for extswsli"));
|
|
end loop;
|
|
end if;
|
|
end loop;
|
|
test_runner_cleanup(runner);
|
|
end process;
|
|
end behave;
|