196 lines
8.9 KiB
VHDL
196 lines
8.9 KiB
VHDL
--*****************************************************************************
|
|
--*************************** VHDL Source Code ******************************
|
|
--********* Copyright 2011, Rochester Institute of Technology ***************
|
|
--*****************************************************************************
|
|
--
|
|
-- DESIGNER NAME: Jeanne Christman
|
|
--
|
|
-- LAB NAME: Calculator
|
|
--
|
|
-- FILE NAME: calculator_tb.vhd
|
|
--
|
|
-------------------------------------------------------------------------------
|
|
--
|
|
-- DESCRIPTION
|
|
--
|
|
-- This test bench will provide input to test a four function calculator.
|
|
-- The calculator function will accept two 4-bit numbers and a 2-bit selection
|
|
-- signal that will enable the operations in the table below. The outputs R
|
|
-- is the 8 bit result.
|
|
--
|
|
-- _______________________________________________________________________
|
|
-- | OP signal | Operation |
|
|
-- ================================
|
|
-- | 00 | Addition |
|
|
-- | 01 | Subtraction |
|
|
-- | 10 | Multiplication |
|
|
-- | 11 | Division |
|
|
-------------------------------------------------------------------------------
|
|
--
|
|
-- REVISION HISTORY
|
|
--
|
|
-- _______________________________________________________________________
|
|
-- | DATE | USER | Ver | Description |
|
|
-- |==========+======+=====+================================================
|
|
-- | | | |
|
|
-- | 9/19/17 | JWC | 1.0 | Created
|
|
|
|
--
|
|
--*****************************************************************************
|
|
--*****************************************************************************
|
|
|
|
LIBRARY IEEE;
|
|
USE ieee.std_logic_1164.ALL;
|
|
USE ieee.numeric_std.ALL;
|
|
|
|
|
|
ENTITY calculator_tb IS
|
|
END ENTITY calculator_tb;
|
|
|
|
ARCHITECTURE test OF calculator_tb IS
|
|
|
|
--the component name MUST match the entity name of the VHDL module being tested
|
|
COMPONENT calculator is
|
|
Port ( in_A : in STD_LOGIC_VECTOR(3 downto 0); --A input
|
|
in_B : in STD_LOGIC_VECTOR(3 downto 0); --B input
|
|
Op : in STD_LOGIC_VECTOR(1 downto 0);
|
|
Result : out STD_LOGIC_VECTOR(7 downto 0));
|
|
end COMPONENT;
|
|
|
|
|
|
-- testbench signals. These do not need to be modified
|
|
SIGNAL a_tb : std_logic_vector(3 DOWNTO 0);
|
|
SIGNAL b_tb : std_logic_vector(3 DOWNTO 0);
|
|
SIGNAL op_tb : std_logic_vector(1 downto 0);
|
|
--
|
|
SIGNAL R_tb : std_logic_vector(7 DOWNTO 0);
|
|
SIGNAL test_signed_8b : SIGNED(7 DOWNTO 0);
|
|
--========================================================================================
|
|
-- this is a function used in the self check feature
|
|
-- converts a std_logic_vector into a hex string. Taken from txt_util package. Package obtained from http://www.stefanvhdl.com/
|
|
function hstr(slv: std_logic_vector) return string is
|
|
variable hexlen: integer;
|
|
variable longslv : std_logic_vector(67 downto 0) := (others => '0');
|
|
variable hex : string(1 to 16);
|
|
variable fourbit : std_logic_vector(3 downto 0);
|
|
begin
|
|
hexlen := (slv'left+1)/4;
|
|
if (slv'left+1) mod 4 /= 0 then
|
|
hexlen := hexlen + 1;
|
|
end if;
|
|
longslv(slv'left downto 0) := slv;
|
|
for i in (hexlen -1) downto 0 loop
|
|
fourbit := longslv(((i*4)+3) downto (i*4));
|
|
case fourbit is
|
|
when "0000" => hex(hexlen -I) := '0';
|
|
when "0001" => hex(hexlen -I) := '1';
|
|
when "0010" => hex(hexlen -I) := '2';
|
|
when "0011" => hex(hexlen -I) := '3';
|
|
when "0100" => hex(hexlen -I) := '4';
|
|
when "0101" => hex(hexlen -I) := '5';
|
|
when "0110" => hex(hexlen -I) := '6';
|
|
when "0111" => hex(hexlen -I) := '7';
|
|
when "1000" => hex(hexlen -I) := '8';
|
|
when "1001" => hex(hexlen -I) := '9';
|
|
when "1010" => hex(hexlen -I) := 'A';
|
|
when "1011" => hex(hexlen -I) := 'B';
|
|
when "1100" => hex(hexlen -I) := 'C';
|
|
when "1101" => hex(hexlen -I) := 'D';
|
|
when "1110" => hex(hexlen -I) := 'E';
|
|
when "1111" => hex(hexlen -I) := 'F';
|
|
when "ZZZZ" => hex(hexlen -I) := 'z';
|
|
when "UUUU" => hex(hexlen -I) := 'u';
|
|
when "XXXX" => hex(hexlen -I) := 'x';
|
|
when others => hex(hexlen -I) := '?';
|
|
end case;
|
|
end loop;
|
|
return hex(1 to hexlen);
|
|
end hstr;
|
|
--========================================================================================
|
|
|
|
BEGIN
|
|
--this must match component above
|
|
UUT : calculator PORT MAP (
|
|
in_a => a_tb,
|
|
in_b => b_tb,
|
|
op => op_tb,
|
|
Result => R_tb
|
|
);
|
|
|
|
---------------------------------------------------------------------------
|
|
-- NAME: Stimulus
|
|
--
|
|
-- DESCRIPTION:
|
|
-- This process will apply the stimulus to the UUT
|
|
---------------------------------------------------------------------------
|
|
stimulus : PROCESS
|
|
VARIABLE temp_slv_8b : STD_LOGIC_VECTOR(7 DOWNTO 0);
|
|
VARIABLE temp_signed_8b : SIGNED(7 DOWNTO 0);
|
|
VARIABLE temp_unsigned_8b : UNSIGNED(7 DOWNTO 0);
|
|
BEGIN
|
|
FOR k in 0 to 3 Loop
|
|
op_tb <= std_logic_vector(to_unsigned(k,2));
|
|
FOR i IN 0 TO 15 LOOP
|
|
a_tb <= std_logic_vector(to_unsigned(i,4));
|
|
FOR j IN 0 TO 15 LOOP
|
|
if (k = 3) and (j = 0) then --skip over divide by zero
|
|
next;
|
|
else
|
|
b_tb <= std_logic_vector(to_unsigned(j,4));
|
|
end if;
|
|
|
|
WAIT FOR 10 ns;
|
|
|
|
--========================================================================================
|
|
-- THIS IS THE SELF TEST SECTION
|
|
--========================================================================================
|
|
Case k is
|
|
|
|
WHEN 0 =>
|
|
temp_signed_8b := resize(SIGNED(a_tb),r_tb'LENGTH) + resize(SIGNED(b_tb),r_tb'LENGTH);
|
|
ASSERT r_tb = std_logic_vector(temp_signed_8b)
|
|
REPORT "Sum operation failed. "&LF&
|
|
"A="&integer'image(to_integer(signed(a_tb)))&", B="&integer'image(to_integer(signed(b_tb)))&", R="&integer'image(to_integer(signed(r_tb)))&LF&
|
|
"Result should be "& integer'image(to_integer(temp_signed_8b))
|
|
SEVERITY error;
|
|
WHEN 1 =>
|
|
temp_signed_8b := resize(SIGNED(a_tb),r_tb'LENGTH) - resize(SIGNED(b_tb),r_tb'LENGTH);
|
|
ASSERT r_tb = std_logic_vector(temp_signed_8b)
|
|
REPORT "Subtraction operation failed. "&LF&
|
|
"A="&integer'image(to_integer(signed(a_tb)))&", B="&integer'image(to_integer(signed(b_tb)))&", R="&integer'image(to_integer(signed(r_tb)))&LF&
|
|
"Result should be "& integer'image(to_integer(temp_signed_8b))
|
|
SEVERITY error;
|
|
WHEN 2 =>
|
|
temp_signed_8b := resize(SIGNED(a_tb) * SIGNED(b_tb),r_tb'LENGTH);
|
|
ASSERT r_tb = std_logic_vector(temp_signed_8b)
|
|
REPORT "Multiply operation failed. "&LF&
|
|
"A="&integer'image(to_integer(signed(a_tb)))&", B="&integer'image(to_integer(signed(b_tb)))&", R="&integer'image(to_integer(signed(r_tb)))&LF&
|
|
"Result should be "& integer'image(to_integer(temp_signed_8b))
|
|
SEVERITY error;
|
|
WHEN 3 =>
|
|
temp_signed_8b := resize(SIGNED(a_tb),r_tb'LENGTH) / resize(SIGNED(b_tb),r_tb'LENGTH);
|
|
ASSERT r_tb = std_logic_vector(temp_signed_8b)
|
|
REPORT "Division operation failed. "&LF&
|
|
"A="&integer'image(to_integer(signed(a_tb)))&", B="&integer'image(to_integer(signed(b_tb)))&", R="&integer'image(to_integer(signed(r_tb)))&LF&
|
|
"Result should be "& integer'image(to_integer(temp_signed_8b))
|
|
SEVERITY error;
|
|
|
|
WHEN OTHERS => NULL;
|
|
END CASE;
|
|
test_signed_8b <= temp_signed_8b;
|
|
--==========================================================================================
|
|
END LOOP;
|
|
END LOOP;
|
|
END LOOP;
|
|
|
|
|
|
REPORT LF&"Simulation Completed" Severity Note;
|
|
-- -----------------------------------------------------------------------
|
|
-- -- This last WAIT statement needs to be here to prevent the PROCESS
|
|
-- -- sequence from restarting.
|
|
-- -----------------------------------------------------------------------
|
|
WAIT;
|
|
END PROCESS stimulus;
|
|
|
|
|
|
END test;
|