cpet-233-lab/lab5/calculator_tb.vhd

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;