Initial import
git-svn-id: http://moon:8086/svn/vhdl/trunk@2 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
@@ -0,0 +1,308 @@
|
||||
-------------------------------------------------------------------------
|
||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||
-- This file: Testbench for JCPU
|
||||
-- also writes 'opc.lst' for JASM-assembler
|
||||
--
|
||||
-- Copyright (C) 2007 J. Ahrensfeld
|
||||
--
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation, either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
LIBRARY ieee;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
USE ieee.numeric_std.ALL;
|
||||
|
||||
library work;
|
||||
use work.mips_types.all;
|
||||
use work.mips_instr.all;
|
||||
|
||||
ENTITY tb_mips_muldiv IS
|
||||
END tb_mips_muldiv;
|
||||
|
||||
ARCHITECTURE behavior OF tb_mips_muldiv IS
|
||||
|
||||
COMPONENT muldiv is
|
||||
Port
|
||||
(
|
||||
rst : in std_logic;
|
||||
clk : in std_logic;
|
||||
hilo_we : in std_logic;
|
||||
din_hi : in word_t;
|
||||
din_lo : in word_t;
|
||||
mul_divn : in std_logic;
|
||||
s_un : in std_logic;
|
||||
start : in std_logic;
|
||||
hilo_sel : in std_logic;
|
||||
busy : out std_logic;
|
||||
dout : out word_t
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
constant CLK_PERIOD : time := 10 ns;
|
||||
signal ENABLE_FAIL_REPORT : boolean := true;
|
||||
signal rst : std_logic := '1';
|
||||
signal clk : std_logic := '1';
|
||||
signal busy : std_logic;
|
||||
signal mul_divn : std_logic := '0';
|
||||
signal s_un : std_logic := '1';
|
||||
signal hilo_we : std_logic := '0';
|
||||
signal start : std_logic := '0';
|
||||
signal din_hi : word_t := (others => '-');
|
||||
signal din_lo : word_t := (others => '-');
|
||||
signal ref_hi : word_t := (others => '-');
|
||||
signal ref_lo : word_t := (others => '-');
|
||||
signal dout : word_t;
|
||||
signal hilo_sel : std_logic := '0';
|
||||
signal result : unsigned (2*word_t'length-1 downto 0);
|
||||
signal ref_result : unsigned (2*word_t'length-1 downto 0);
|
||||
|
||||
type word_array_t is array (natural range <>) of word_t;
|
||||
|
||||
constant operands : word_array_t(0 to 63) :=
|
||||
(
|
||||
X"00000000",
|
||||
X"00000001",
|
||||
X"00000010",
|
||||
X"00000100",
|
||||
X"00001000",
|
||||
X"00010000",
|
||||
X"00100000",
|
||||
X"01000000",
|
||||
X"10000000",
|
||||
X"0000000F",
|
||||
X"000000FF",
|
||||
X"00000FFF",
|
||||
X"0000FFFF",
|
||||
X"000FFFFF",
|
||||
X"00FFFFFF",
|
||||
X"0FFFFFFF",
|
||||
X"12345678",
|
||||
X"23456789",
|
||||
X"7FFFFFFF",
|
||||
X"80000000",
|
||||
X"A541B3B9",
|
||||
X"80000001",
|
||||
X"80000010",
|
||||
X"80000100",
|
||||
X"80001000",
|
||||
X"80010000",
|
||||
X"80100000",
|
||||
X"81000000",
|
||||
X"87654321",
|
||||
X"98765432",
|
||||
X"FFFFFFFF",
|
||||
X"FFFFFFFE",
|
||||
X"FFFFFFFD",
|
||||
X"FFFFFFFB",
|
||||
X"FFFFFFF7",
|
||||
X"FFFFFFEF",
|
||||
X"FFFFFFDF",
|
||||
X"FFFFFFBF",
|
||||
X"FFFFFF7F",
|
||||
X"FFFFFEFF",
|
||||
X"FFFFFDFF",
|
||||
X"FFFFFBFF",
|
||||
X"FFFFF7FF",
|
||||
X"FFFFEFFF",
|
||||
X"FFFFDFFF",
|
||||
X"FFFFBFFF",
|
||||
X"FFFF7FFF",
|
||||
X"FFFEFFFF",
|
||||
X"FFFDFFFF",
|
||||
X"FFFBFFFF",
|
||||
X"FFF7FFFF",
|
||||
X"FFEFFFFF",
|
||||
X"FFDFFFFF",
|
||||
X"FFBFFFFF",
|
||||
X"FF7FFFFF",
|
||||
X"FEFFFFFF",
|
||||
X"FDFFFFFF",
|
||||
X"FBFFFFFF",
|
||||
X"F7FFFFFF",
|
||||
X"EFFFFFFF",
|
||||
X"DFFFFFFF",
|
||||
X"BFFFFFFF",
|
||||
X"CFFFFFFF",
|
||||
X"7FFFFFFF"
|
||||
);
|
||||
|
||||
BEGIN
|
||||
|
||||
uut: muldiv
|
||||
PORT MAP(
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
hilo_we => hilo_we,
|
||||
din_hi => din_hi,
|
||||
din_lo => din_lo,
|
||||
mul_divn => mul_divn,
|
||||
s_un => s_un,
|
||||
start => start,
|
||||
hilo_sel => hilo_sel,
|
||||
busy => busy,
|
||||
dout => dout
|
||||
);
|
||||
|
||||
CLK_GEN: process
|
||||
begin
|
||||
wait for CLK_PERIOD/2;
|
||||
clk <= not clk;
|
||||
end process;
|
||||
|
||||
REF_GEN: process
|
||||
variable tmp : unsigned (2*word_t'length-1 downto 0);
|
||||
variable tmp2 : unsigned (word_t'length-1 downto 0);
|
||||
begin
|
||||
if mul_divn = '0' then
|
||||
wait until rising_edge(clk) and start = '1';
|
||||
ref_lo <= din_lo;
|
||||
ref_hi <= din_hi;
|
||||
wait until rising_edge(clk) and busy = '0';
|
||||
wait until rising_edge(clk);
|
||||
wait until rising_edge(clk);
|
||||
if s_un = '1' then
|
||||
tmp := unsigned(signed(result(31 downto 0)) * signed(ref_lo));
|
||||
tmp2 := unsigned(signed(tmp(31 downto 0)) + signed(result(63 downto 32)));
|
||||
ref_result <= X"00000000" & tmp2(31 downto 0);
|
||||
else
|
||||
tmp := result(31 downto 0) * ref_lo;
|
||||
tmp2 := tmp(31 downto 0) + result(63 downto 32);
|
||||
ref_result <= X"00000000" & tmp2(31 downto 0);
|
||||
end if;
|
||||
wait until rising_edge(clk);
|
||||
|
||||
if ref_lo /= X"00000000" then
|
||||
if ENABLE_FAIL_REPORT then
|
||||
assert ref_hi = ref_result(31 downto 0) report "Error on divison" severity failure;
|
||||
end if;
|
||||
end if;
|
||||
else
|
||||
wait until rising_edge(clk) and start = '1';
|
||||
wait until rising_edge(clk) and busy = '0';
|
||||
if s_un = '1' then
|
||||
ref_result <= unsigned(signed(din_hi) * signed(din_lo));
|
||||
else
|
||||
ref_result <= unsigned(din_hi) * unsigned(din_lo);
|
||||
end if;
|
||||
wait until rising_edge(clk);
|
||||
wait until rising_edge(clk);
|
||||
wait until rising_edge(clk);
|
||||
if ENABLE_FAIL_REPORT then
|
||||
assert ref_result = result report "Error on multiplication" severity failure;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
end process;
|
||||
|
||||
STIMULUS: process
|
||||
|
||||
begin
|
||||
|
||||
wait for 3*CLK_PERIOD;
|
||||
wait until rising_edge(clk);
|
||||
rst <= '0';
|
||||
wait for 2*CLK_PERIOD;
|
||||
|
||||
mul_divn <= '0';
|
||||
s_un <= '0';
|
||||
for i in 0 to operands'length-1 loop
|
||||
for j in 0 to operands'length-1 loop
|
||||
wait until rising_edge(clk) and busy = '0';
|
||||
din_hi <= operands(i);
|
||||
din_lo <= operands(j);
|
||||
start <= '1';
|
||||
wait until rising_edge(clk);
|
||||
start <= '0';
|
||||
hilo_sel <= '0';
|
||||
|
||||
-- Read result
|
||||
wait until rising_edge(clk) and busy = '0';
|
||||
result(31 downto 0) <= dout;
|
||||
hilo_sel <= '1';
|
||||
wait until rising_edge(clk);
|
||||
result(63 downto 32) <= dout;
|
||||
wait for 2*CLK_PERIOD;
|
||||
end loop;
|
||||
end loop;
|
||||
|
||||
s_un <= '1';
|
||||
for i in 0 to operands'length-1 loop
|
||||
for j in 0 to operands'length-1 loop
|
||||
wait until rising_edge(clk) and busy = '0';
|
||||
din_hi <= operands(i);
|
||||
din_lo <= operands(j);
|
||||
start <= '1';
|
||||
wait until rising_edge(clk);
|
||||
start <= '0';
|
||||
hilo_sel <= '0';
|
||||
|
||||
-- Read result
|
||||
wait until rising_edge(clk) and busy = '0';
|
||||
result(31 downto 0) <= dout;
|
||||
hilo_sel <= '1';
|
||||
wait until rising_edge(clk);
|
||||
result(63 downto 32) <= dout;
|
||||
wait for 2*CLK_PERIOD;
|
||||
end loop;
|
||||
end loop;
|
||||
|
||||
mul_divn <= '1';
|
||||
s_un <= '0';
|
||||
for i in 0 to operands'length-1 loop
|
||||
for j in 0 to operands'length-1 loop
|
||||
wait until rising_edge(clk) and busy = '0';
|
||||
din_hi <= operands(i);
|
||||
din_lo <= operands(j);
|
||||
start <= '1';
|
||||
wait until rising_edge(clk);
|
||||
start <= '0';
|
||||
hilo_sel <= '0';
|
||||
|
||||
-- Read result
|
||||
wait until rising_edge(clk) and busy = '0';
|
||||
result(31 downto 0) <= dout;
|
||||
hilo_sel <= '1';
|
||||
wait until rising_edge(clk);
|
||||
result(63 downto 32) <= dout;
|
||||
end loop;
|
||||
end loop;
|
||||
|
||||
s_un <= '1';
|
||||
for i in 0 to operands'length-1 loop
|
||||
for j in 0 to operands'length-1 loop
|
||||
wait until rising_edge(clk) and busy = '0';
|
||||
din_hi <= operands(i);
|
||||
din_lo <= operands(j);
|
||||
start <= '1';
|
||||
wait until rising_edge(clk);
|
||||
start <= '0';
|
||||
hilo_sel <= '0';
|
||||
|
||||
-- Read result
|
||||
wait until rising_edge(clk) and busy = '0';
|
||||
result(31 downto 0) <= dout;
|
||||
hilo_sel <= '1';
|
||||
wait until rising_edge(clk);
|
||||
result(63 downto 32) <= dout;
|
||||
end loop;
|
||||
end loop;
|
||||
|
||||
wait;
|
||||
|
||||
end process;
|
||||
|
||||
END;
|
||||
Reference in New Issue
Block a user