Basic stimulus generation and verification

First basic stimulus generation is demonstrated. A simple XOR build from AND and OR gates is used as an example. An extra term is added to deliberately introduce an error.
        y <= (x1 and not x2) or (x2 and not x1) or (x1 and x2);
It's possible to generate stimulus using a process with signal assignments and wait statements as shown below:
       test_seq: process

       begin

       x1 <= '0';
       x2 <= '0';
       wait for 10 ns;

       x1 <= '1';
       x2 <= '0';
       wait for 10 ns;

       x1 <= '0';
       x2 <= '1';
       wait for 10 ns;

       x1 <= '1';
       x2 <= '1';
       wait for 10 ns;

       x1 <= 'X';
       x2 <= 'X';

       ...

       end process test_seq;

This code can now be simulated and it's possible to identify the design error by observing the waveforms:

However it's more efficient to build in checks which automatically verify the result of a simulation. This can be accomplished with the use of assert statements. An assert statement verifies that a certain condition holds true. If the condition is violated it will generate the associated message and will attach the specified severity level to it. The example VHDL code could be extended like this:

       ....

       wait for 10 ns;

       x1 <= '1';
       x2 <= '1';
       assert y = (x1 xor x2)
         report "E@TB: circuit failed"
         severity Error;

       wait for 10 ns;

       ...       

A simulator executing the code will produce output similar to this:

       # ** Error: E@TB: circuit failed
       #    Time: 40 ns  Iteration: 0  Instance: /tb1

Ideally the assert statement should provide information about the condition in which the error occurred. This will aid debugging substantially. Below are two alternatives to the previous assert statements. One uses the 'image attribute from the VHDL 93 standard. The other uses the conversion function str() from package txt_util.vhd which is used extensively throughout this course. The package provides a somewhat less cumbersome way to handle string processing and similar tasks.

       assert y = (x1 xor x2)
         report "E@TB: failure at: x1="& std_logic'image(x1)&
                " x2="& std_logic'image(x2)
         severity Error;

       assert y = (x1 xor x2)
         report "E@TB: failure at: x1="& str(x1)& " x2="& str(x2)
         severity Error;
Shown below is the output of the two assert statements. It's now much easier to identify the cause of the problem.
       # ** Error: E@TB: failure at: x1='1' x2='1'
       #    Time: 40 ns  Iteration: 0  Instance: /tb1
       
       # ** Error: E@TB: failure at: x1=1 x2=1
       #    Time: 40 ns  Iteration: 0  Instance: /tb1
A standard format for error messages will also help to identify the location of a bug. The standard adopted here uses the first letter to indicate the severity (I=Information, W=Warning, E=Error, F=Failure) followed by "@" and the entity name of the unit which generated the message. The "E@" notation makes it very easy to grep long logfiles and identify problems. Knowing the entity which detected a bug will aid fixing it, too.

Below are the files which have been simulated in this section:

txt_util.vhd tb1.vhd
txt_util.vhd tb1.vhd

Note: The txt_util package requires a VHDL 93 compatible simulator.


previous Index next