Below is my testbench code for a simple (unclocked) 4 bit Adder. My simulation currently will display any errors that occur along with a "Test Completed" at the end. If there are no errors, the simulation will simply return "Test Completed".
My question is:
Is there a way to somehow include an "if" statement so as to display a "Test Completed, no errors" when no errors are detected in the simulation, and a "Test Completed, [x] errors found" when errors are detected in the simulation (where x is the variable amount of errors returned when the simulation is finished.)?
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY adder_4bit_TB IS
END adder_4bit_TB;
ARCHITECTURE behavior OF adder_4bit_TB IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT adder_4bit
PORT(
a : IN std_logic_vector(3 downto 0);
b : IN std_logic_vector(3 downto 0);
carry : OUT std_logic;
sum : OUT std_logic_vector(3 downto 0)
);
END COMPONENT;
--Inputs
signal a : std_logic_vector(3 downto 0) := (others => '0');
signal b : std_logic_vector(3 downto 0) := (others => '0');
--Outputs
signal carry : std_logic;
signal sum : std_logic_vector(3 downto 0);
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: adder_4bit PORT MAP (
a => a,
b => b,
carry => carry,
sum => sum
);
-- Stimulus process
stim_proc: process -- No CLK
begin
-- Initialize Input values
a <= "0000";
b <= "0000";
--Loop over all values of "a" and check sum
for I in 0 to 15 loop
--Loop over all values of "b" and check sum
for J in 0 to 15 loop
-- Wait for output to update (10 ns)
wait for 10ns;
-- Below is the self-verification routune being implemented for the 4 bit Adder.
-- The routine checks the sum of "a" and "b" at the end of every loop, and
-- reports any Errors that may have occured. If no errors occur, simulation
-- will return "Test Completed" (line109) in Command Window.
assert (sum = a + b) report "Expected sum of " &
integer'image(to_integer(unsigned((a + b)))) & ". For a = " &
integer'image(to_integer(unsigned((a)))) & " and b = " &
integer'image(to_integer(unsigned((b)))) & ", but returned sum was " &
integer'image(to_integer(unsigned((sum)))) severity ERROR; -- severity level can be NOTE, WARNING, ERROR, or FAILURE
-- Increment to next value of four bit vector "b"
b <= b + "0001";
end loop;
-- Increment to next value of four bit vector "a"
a <= a + "0001";
end loop;
--Echo to user that report has finished
report "Test completed";
wait; --will wait forever
end process;
END;
Using the answer below, here is the resulting working code:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY adder_4bit_TB IS
END adder_4bit_TB;
ARCHITECTURE behavior OF adder_4bit_TB IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT adder_4bit
PORT(
a : IN std_logic_vector(3 downto 0);
b : IN std_logic_vector(3 downto 0);
carry : OUT std_logic;
sum : OUT std_logic_vector(3 downto 0)
);
END COMPONENT;
--Inputs
signal a : std_logic_vector(3 downto 0) := (others => '0');
signal b : std_logic_vector(3 downto 0) := (others => '0');
--Outputs
signal carry : std_logic;
signal sum : std_logic_vector(3 downto 0);
--Outputs (Testbench only)
signal Errors : boolean; -- Boolean value. True if error detected. False if no error detected.
signal ErrorCount : integer := 0; -- Integer value to store the qty of errors. Intitialized to zero
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: adder_4bit PORT MAP (
a => a,
b => b,
carry => carry,
sum => sum
);
-- Stimulus process
stim_proc: process -- No CLK
begin
-- Initialize Input values
a <= "0000";
b <= "0000";
--Loop over all values of "a" and check sum
for I in 0 to 15 loop
--Loop over all values of "b" and check sum
for J in 0 to 15 loop
-- Wait for output to update (10 ns)
wait for 10ns;
-- Below is the self-verification routune being implemented for the 4 bit Adder.
-- The routine checks the sum of "a" and "b" at the end of every loop, and
-- reports any Errors that may have occured.
if (sum /= a + b) then ---- "/=" syntax: test for inequality, result is boolean
Errors <= true;
ErrorCount <= ErrorCount + 1;
else
Errors <= false;
end if;
assert (Errors = false) report "Expected sum of " &
integer'image(to_integer(unsigned((a + b)))) & ". For a = " &
integer'image(to_integer(unsigned((a)))) & " and b = " &
integer'image(to_integer(unsigned((b)))) & ", but returned sum was " &
integer'image(to_integer(unsigned((sum)))) severity ERROR; -- severity level can be NOTE, WARNING, ERROR, or FAILURE
-- Increment to next value of four bit vector "b"
b <= b + "0001";
end loop;
-- Increment to next value of four bit vector "a"
a <= a + "0001";
end loop;
--Echo to user that report has finished
report "Test completed with " & integer'image(ErrorCount) & " errors";
wait; --will wait forever
end process;
END;
This would be pretty straight forward to add to what you have. Instead of using an assertion to directly test the result of the sum, use an if
statement to set a boolean
if the sum is not correct, then assert/count errors based on this. Something like:
variable Error : boolean;
variable ErrorCount : integer := 0;
...
if (sum /= a + b) then
Error := true;
ErrorCount := ErrorCount + 1;
else
Error := false;
end if;
assert (Error = false) report "Expected sum of " &
integer'image(to_integer(unsigned((a + b)))) & ". For a = " &
integer'image(to_integer(unsigned((a)))) & " and b = " &
integer'image(to_integer(unsigned((b)))) & ", but returned sum was " &
integer'image(to_integer(unsigned((sum)))) severity ERROR;
...
report "Test completed with " & integer'image(ErrorCount) & " errors";