In this video, you will learn the concept of using a Verilog program called a Testbench to test another Verilog program which will be your code. You'll learn how to write simple testbenches, and how to use loops to generate stimulus for those testbenches, and how to use assertions to determine and report test results. What is a testbench? A testbench is a program written in any language for the purposes of exercising and verifying the functional correctness of the hardware model as coded. In our case, Verilog is going to be used for both the model and the test code. The use of the testbench to auto-generate a stimulus for the unit under test is much more efficient than entering test vectors manually in the simulator, Modelsim in this case. The testbench is also sometimes called a test fixture or a test harness. Its a very powerful tool for auto generating test stimulus and test results, particularly when combined with a simulator like Modelsim in which the Verilog test code will run. Once you've written your code for a module in Verilog or VHDL, you're not even half done at that point. Most designers spend at least as much time creating testbench code as they do the code for the unit under test. A testbench can have several functional sections, including the top-level testbench declaration, stimulus and response signal declarations, component declarations, component instantiations, which will put the device under test into the circuit, external stimulation device models, a test process which applies stimulus to the device under test, and a test monitor which reports results. Here's a picture of the structure of a testbench. Stimulus comes from either a test vector file which contains a set of test vectors to test all possible functions of the device, or models in the testbench of external devices that generate signals that are applied to the unit under test. The instantiated component on our test generates outputs as i would in actual use. The outputs are compared to the expected outputs, and if they don't match, an error message is generated, which can be stored in a file or displayed on the message window of the simulator. When an error is detected, the simulation can be stopped or it can continue until all tests vectors are applied. Note that just because the output doesn't match the expected output doesn't mean the device under test is an error. The error could be in the test code itself. Usually, the waveforms generated are used to determine which it is. Let's construct a simple testbench for an adder. We tend to use an underscore under tb suffix to indicate that this is a testbench in the module name. So here we have Adder_tb. Note there's no sensitivity list. This is because there are no external interfaces to the testbench, everything is present within it. We have the usual input signals for an adder, two numbers and the carry in, with the sum, and carry out outputs. We've added an additional signal expected to provide the reference result, which we will compare the output to once the simulation is complete. Then there's the instantiation of the adder circuit. This instances labeled DUT or device under test. You may also see UUT or unit under test, or other labels for the instance of the unit under test. Continuing with the adder testbench code, we generate the stimulus with a series of assignment statements that set the input signals to particular values at particular times. Obviously, this isn't a very efficient way to write the test case. We'd rather use a loop to generate the stimulus. Finally then, the test results are displayed in the simulator message window using a built-in monitor or function in verilog, which is like an event-driven print f. The dollar sign time is a built-in variable which represents the simulator system time, and the dollar sign stop tells the simulator to stop simulating at this particular time. Here's the output of such a testbench which will look like this for a functional simulation. The time is in the base unit of nanoseconds, and from this, we can see that the adder works for the three test cases we created. The simulator waveform is generated by the testbench simulation automatically. The port signals or the device under test are shown. The output and the expected output match in each case in response to the changing inputs. A more efficient way to generate the testbench signals is to use a loop to iterate through many tests vector possibilities. In this example, all possible combinations of values for the a and b input vectors are applied in addition to the carry in by use of three different for loops to iterate through all possible combinations of each one of those inputs. The expected value is also calculated for all possible input combinations. Here's what the waveform output of such a testbench will look like after simulation. Notice many more test cases have been auto-generated, and if we scroll through them all, we can see that they all match. But this manual check would be very time consuming and error-prone. Instead, we'd like to testbench to be self-checking. We can further enhance the testbench by adding a self checking feature so that we don't have to scan the output for errors. In this example, any mismatch detected will display an error message, but only when there is an error. This reduces the effort greatly to only the cases that need attention. A helpful feature available in VHDL and also system Verilog is the assertion statement. Here we use the assertion to assert a true condition, the tests, and if it passes, then we can print a message, or for most of the time, just omit the past message and continue, or if the test fails, we display an error message and record the result. The dollar sign finish as a system function, which causes the simulation to end. We like to use assertions because they can be enabled or disabled globally in simulations unlike our previous tests. They can also have different severity levels, including fatal, in which case the simulation will stop, error, or warning, and info, which allows us to respond to the test results in different ways. The assertions are ignored by synthesis. In this video, you have learned the concept of using a Verilog program called a testbench to test another Verilog program, how to write simple testbenches, how to use loops to generate stimulus, and how to use assertions to determine a report test results. Cool.