源自於http://www.doulos.com/knowhow/verilog_designers_guide/test_benches/
Test Benches
Test benches help you to verify that a design is correct. How do you create a simple testbench in Verilog?
Let's take the exisiting MUX_2 example module and create a testbench for it. We can create a template for the testbench code simply by refering to the diagram above.
module MUX2TEST; // No ports! ... initial // Stimulus ... MUX2 M (SEL, A, B, F); initial // Analysis ... endmodule
Initial Statement
In this code fragment, the stimulus and response capture are going to be coded using a pair of initial blocks. An initial block can contain sequential statements that can be used to describe the behaviour of signals in a test bench.
In the Stimulus initial block, we need to generate waveform on the A, B and SEL inputs. Thus:
initial // Stimulus begin SEL = 0; A = 0; B = 0; #10 A = 1; #10 SEL = 1; #10 B = 1; end
Once again, let's look at each line in turn.
SEL = 0; A = 0; B = 0;
This line contains three sequential statements. First of all, SEL is set to 0, then A, then B. All three are set to 0 at simulation time 0.
#10 A = 1;
In terms of simulation, the simulator now advances by 10 time units and then assigns 1 to A. Note that we are at simulation time = 10 time units, not 10 ns or 10 ps! Unless we direct the Verilog simulator otherwise, a Verilog simulation works in dimensionless time units.
#10 SEL = 1; #10 B = 1;
These two lines are similar to the one above. 10 time units after A is set to 1, SEL is set to 1. Another 10 time units later (so we are now at simulation time = 30 time units), B is set to 1. The diagram below shows how the initial block has created a waveform sequence for the three signals.
We shall look at the use of the initial block to capture the MUX_2's response in the next section of the tutorial.
Response Capture
In the previous section of the tutorial, we looked at describing stimuli in Verilog to test our 2-input multiplexer. So next, we’ll look at how to capture the response of our device under test.
Remember from the module template that we are using initial blocks to code up the Stimulus and Response blocks.
module MUX2TEST; // No ports!
...
initial
// Stimulus
...
MUX2 M (SEL, A, B, F);
initial
// Analysis
...
endmodule
The Response initial block can be described very easily in Verilog as we can benefit from a built-in Verilog system task. Thus:
initial // Response $monitor($time, , SEL, A, B, F);
Once again, let's look at each item in turn.
$monitor();
$monitor is a system task that is part of the Verilog language. Its mission in life is to print values to the screen. The values it prints are those corresponding to the arguments that you pass to the task when it is executed. The $monitor task is executed whenever any one of its arguments changes, with one or two notable exceptions.
$time
$time is a system function (as opposed to a system task). It returns the current simulation time. In the above example, $time is an argument to $monitor. However, $time changing does not cause $monitor to execute - $monitor is clever enough to know that you wouldn't really want to print to the screen the values of all of the arguments every time the simulation time changed.
, , ,
The space at position 2 in the argument list ensures that a space is printed to the screen after the value of $time each time$monitor is executed. This is a simple method of formatting the screen output.
SEL, A, B, F
Finally we come to the signal arguments themselves. Each time one of these signals changes value, $monitor will execute. When $monitor executes it will print all of the argument values to the screen, including $time. This is the output created by$monitor in our MUX2 testbench:
0 0000 10 0101 20 1100 30 1111
This is simply a tabular listing of the waveforms that would be generated during simulation (if we had a waveform viewer, that is!).
It's amazing what you can learn from two lines of code, isn't it? We'll look at more elaborate output formatting soon.
沒有留言:
張貼留言