The Stimulus Module

Once a module has been designed it can be tested by applying test inputs. This is idea of the stimulus module. It calls the design module and uses its functionality, then results can be monitored to verify its design. A well written stimulus will be able to put the whole design through its paces.

Below is the stimulus for the multiplexor examples given in the previous sections, the same stimulus can be applied to each of the designs above since they look the same externally and are performing the same function, only in different ways.

        module muxstimulus;
          reg IN1, IN2, IN3, IN4, CNTRL1, CNTRL2;
          wire OUT;

        multiplexor4_1 mux1_4(OUT, IN1, IN2, IN3, IN4, CNTRL1, CNTRL2);

        initial begin
          IN1 = 1; IN2 = 0; IN3 = 1; IN4 = 0;
          $display("Initial arbitrary values");
          #0 $display("input1 = %b, input2 = %b, input3 = %b, input4 = %b\n",
                                IN1, IN2, IN3, IN4);

         {CNTRL1, CNTRL2} = 2'b00;
         #1 $display("cntrl1=%b, cntrl2=%b, output is %b", CNTRL1, CNTRL2, OUT);

           {CNTRL1, CNTRL2} = 2'b01;
         #1 $display("cntrl1=%b, cntrl2=%b output is %b", CNTRL1, CNTRL2, OUT);

         {CNTRL1, CNTRL2} = 2'b10;
         #1 $display("cntrl1=%b, cntrl2=%b output is %b", CNTRL1, CNTRL2, OUT);

         {CNTRL1, CNTRL2} = 2'b11;
         #1 $display("cntrl1=%b, cntrl2=%b output is %b", CNTRL1, CNTRL2, OUT);

        end

        endmodule

Now we look at this part by part.
        module muxstimulus;

This is a top level module it, ie. nothing else calls it to use its functionality, so it doesn't need a port list. The keyword module remains and the module name should be chosen to to indicate that it is a stimulus module.
          reg IN1, IN2, IN3, IN4, CNTRL1, CNTRL2;
          wire OUT;

Remember the inputs to the multiplexor are in1, in2, in3, in4, cntrl1 and cntrl2; and the output from the multiplexor is out. The idea of the stimulus is to apply artificial stimulus to the inputs and see what values are assigned to out by the multiplexor4_1 module.
So we want to be able to assign values to the inputs and values to be driven into the output. It follows that the inputs must be reg data types and the output must be a wire.
        multiplexor4_1 mux1_4(OUT, IN1, IN2, IN3, IN4, CNTRL1, CNTRL2);

This calls the multiplexor4_1 module, the syntax is
<module_name> <instance_name> (port list);
The instance name is necessary when calling user defined modules, this is to aid the traversal down the hierarchy of design (but we will not cover this aspect of the language). The port list sets up the correspondence of the stimulus module variable with the variables of the design module. The post list must be in the same order when the module is called as when it is defined to ensure the variables correspond as expected.

Now multiplexor4_1 is active, if the inputs change, ie. are assigned test values, it will compute a value for the output and drive it into out.

        initial begin
          IN1 = 1; IN2 = 0; IN3 = 1; IN4 = 0;
          $display("Initial arbitrary values");
          #0 $display("input1 = %b, input2 = %b, input3 = %b, input4 = %b\n",
                                IN1, IN2, IN3, IN4);

The main part of the simulation is enclosed in the construct initial begin ... end. This is a way of grouping statements which may run concurrently, since there is only one initial block in this example, its use is not fully illustrated.
First the inputs are assigned arbitrary values and these are displayed using $display. Note the #0 before the display statement. This is to ensure that the display is made after the assignment of values to the input. The assignments are made at simulation time 0, putting a #0 ensures that the $display is executed at the end of the 0 time slice. The execution of an assignment using = is always in the order given so these don't have to be time controlled.
The syntax of the $display is similar to that of printf in C,
$display( expr1, expr2, ...., exprN);
exprN can be variables, expressions or quotes strings.
        {CNTRL1, CNTRL2} = 2'b00;
         #1 $display("cntrl1=%b, cntrl2=%b, output is %b", CNTRL1, CNTRL2, OUT);

The first line is an assignment to the control signals and is the same as saying
CNTRL1 = 0;
CNTRL2 = 0;
The concatenation operator { } can be used to make group assignments. The number of bits in the assignment must be the same as the number of bits in the variables.
Now that the inputs and control signals have values multiplexor4_1 module will drive a value into out. We want to test whether this value is the one we expect so we can check it using $display.
        {CNTRL1, CNTRL2} = 2'b01;
        #1 $display("cntrl1=%b, cntrl2=%b output is %b", CNTRL1, CNTRL2, OUT);

        {CNTRL1, CNTRL2} = 2'b10;
        #1 $display("cntrl1=%b, cntrl2=%b output is %b", CNTRL1, CNTRL2, OUT);

        {CNTRL1, CNTRL2} = 2'b11;
        #1 $display("cntrl1=%b, cntrl2=%b output is %b", CNTRL1, CNTRL2, OUT);

        end
        endmodule

In the same way the values of the control signals are changed and the value of the output is checked via the display.
Note the $display statements have a delay associated with them, the first is delayed by 1 time unit, the second by 1 after that (ie. 2 units from the start of the simulation). This is to ensure the displays are delayed until the correct values have been assigned to the control signals.

This test file does not fully exercise the multiplexor, but it is a good initial check.


previous contents