Previous Section Next Section

2.4 Verification Example

The simple XOR verification example discussed in this section does not cover all the components discussed in "Components of a Verification Environment" on page 18. However, it does give the reader an idea of building a verification environment in e.

The purpose of this example is to introduce the reader to e. Syntax details are not explained in this section but will be covered in later chapters. It is important to pay attention to only the high-level verification structure at this point. We will learn e syntax in great detail in later chapters. There are plenty of comments throughout the examples in this section. However, the actual e code is very simple.

A Verilog example is described in this section. However, e code will work with either a Verilog or VHDL design.

2.4.1 XOR Device Under Test (DUT) Description

The design to be tested is a simple XOR flipflop. Figure 2-6 shows the circuit diagram for this flipflop.

Figure 2-6. XOR DUT Description

graphics/02fig06.gif

The Verilog code for the XOR DUT is shown in Example 2-2 below.

Example 2-2 Verilog Code for XOR DUT
//Definition of XOR Module
'define width 2
module xor_mod (out, a, b, clk);
parameter width = 'width;
input clk; // 1 bit input
input  [width-1:0] a, b; // 2 bit inputs

output [width-1:0] out; // 2 bit output
reg    [width-1:0] out;
always @(posedge clk) out = #1 (a ^ b);
endmodule
// xor module

2.4.2 Simulator Hierarchy

The XOR DUT is instantiated inside the module xor_top. Module xor_top instantiates the DUT, creates a clock whereby e code synchronizes with DUT and declares variables a, b, and out. The Verilog code for the xor_top module is shown in Example 2-3.

Example 2-3 Top Level Verilog Module
// Top level module to test an n-bit XOR Verilog design
// that is to be tested using e
'define width 2 //Define a 2 bit width

//Define the top level module
module xor_top;
  //Define the parameters
  parameter width = 'width;
  parameter clock_period = 100;

  //Define variables for a, b and out
  reg [width-1:0] a, b;
  wire [width-1:0] out;

  // Setup clock. This clock will be used by
  // e code to synchronize with DUT.
  reg clk;

 initial clk =0;
  always #(clock_period/2) clk = ~clk;

  //Verilog monitor task
  task mon ;
    begin
       $monitor($time,"clk=%b a=%b b=%bout=%b",clk,a,b,out);
    end
  endtask

  // Instantiate the n-bit XOR DUT
  xor_mod x1(out,a,b,clk);

endmodule

Thus, in the simulator, the hierarchy of the Verilog design is as shown in Figure 2-7 below.

Figure 2-7. Verilog Hierarchy for XOR Example

graphics/02fig07.gif

2.4.3 Test Plan

The test plan for the above DUT is very simple.

  1. Test all legal combinations of a and b (any 0,1 combination is legal).

  2. Check values of out against expected values.

The clk variable will be used by e code to synchronize with the DUT. The test plan will be executed from e code, i.e., the values of inputs a and b will be chosen and toggled from within e code. Figure 2-8 shows the interaction between Specman Elite and the Simulator.

Figure 2-8. Interface between Specman Elite and the Simulator for XOR DUT Verification

graphics/02fig08.gif

2.4.4 e Verification Hierarchy

Various verification components will be needed to verify the XOR DUT. The test hierarchy to verify the XOR DUT will be represented in e. Figure 2-9 shows a possible hierarchy for the verification environment. We have omitted the protocol checker from this example for the sake of brevity.

Figure 2-9. Verification Environment Hierarchy

graphics/02fig09.gif

2.4.5 e Code for the Verification Environment

The e code for the verification environment is shown in Example 2-4 below. Each component in the verification is highlighted with comments. There is no need to understand the syntax for the e code shown in this example. The purpose of displaying the e code is to give the reader a feel for the syntax. Details of e syntax will be described in later chapters.

Example 2-4 e Code for Verification Environment
This is a test environment for the XOR DUT written in e
      out[1:0] == (a[1:0] ^ b[1:0])
Beginning of e code to verify XOR DUT
<'
//---------------------------------------------------
// Data object. This is the basic stimulus item that will
// be applied to the DUT.
struct operation {
  a: int (bits: 2 ); //input to DUT
  b: int (bits: 2 ); //input to DUT
  !result_from_dut: int (bits:2); //output from DUT
};
//---------------------------------------------------
// sys instantiates a list of basic stimulus items. These
// form the test vectors to apply to DUT. The number
// of test vectors is constrained to be less than 20.
extend sys {
  ops: list of operation; // List of stimulus items
  keep ops.size() < 20; //Keep number of stimulus items < 20
};

//---------------------------------------------------
// Can call a Verilog task directly from within e code
verilog task 'xor_top.mon'(); //Need full path name

//---------------------------------------------------
// struct verify. Input Driver, Output Receiver and
// Data Checker functions are all combined into this
// struct. Typically, these functions would be in separate
// structs or units.
struct verify {
//Create an event fall_clk that will be triggered
//at each falling edge of clk. Specman Elite will be
//invoked by the Verilog simulator at each occurrence.
event fall_clk is fall('~/xor_top/clk')@sim;

//Define a time consuming method to run input driver,
//output receiver and data checker functions
//This procedure is synchronized to falling edge of clk.
verify_xor() @fall_clk is {
'xor_top.mon'(); //Call the Verilog task
for each operation (op) in sys.ops { //For each data item
                                     //in list execute block

//Write values to Verilog variable
//This part does task of Input Driver
'~/xor_top/a' = op.a; //Apply value of a to Verilog variable
'~/xor_top/b' = op.b; //Apply value of b to Verilog variable

wait [1]; // wait one cycle, i.e till next falling edge

//Read values from Verilog variable
//This part does task of Output Receiver
op.result_from_dut = '~/xor_top/out1';
print op; // Print the current data object

//Check output against expected values
//This part does task of Data Checker
check that op.result_from_dut == (op.a ^ op.b);

//Emit an event for the coverage group to sample data
emit op.done;
}; //End of for each loop

//Stop the run, finish simulation
stop_run();
}; //End of method verify_xor


//Invoke the verify_xor method at simulation time 0
run() is also {
    start verify_xor();
};

}; //End of struct verify

//---------------------------------------------------
//Extend sys to instantiate the verify struct defined above
extend sys {
verify1: verify; //Instance named verify1
};

//---------------------------------------------------
//Define coverage analyzer group
//Coverage group is defined inside the struct operation
//instead of defining it as a separate struct or unit
extend operation {
    event done; //Whenever this event is emitted, take
                //a snapshot of the items below
    cover done is {
        item a; //Snapshot of value of a
        item b; //Snapshot of value of b
        cross a, b; //Cross coverage of a and b values
    };
};

//Setup needed to enable coverage
extend sys { //Extend sys
                 //to set up tool configuration.
  setup_test() is also {
     set_config(cover, mode, count_only); //Enable count_only coverage
  };
//---------------------------------------------------

'>
End of e code to verify XOR DUT

2.4.6 Specman.v File

The specman.v file contains the interface between the Simulator and Specman Elite.[6] This file is compiled into the Verilog simulator and run with the other DUT files. This file is created automatically by Specman Elite. All e code is loaded into Specman Elite and then a command is invoked to create this file. Figure 2-10 shows the interaction between Specman Elite and the HDL Simulator.

[6] The file specman.vhd is created in a VHDL environment.

Figure 2-10. Interaction between Specman Elite and the Simulator for XOR DUT Verification

graphics/02fig10.gif

The specman.v file should never be modified manually. It should always be created with a Specman Elite command. Specman.v file contains a Verilog module called specman. Example 2-5 shows the code generated for the specman.v file generated for the XOR DUT verification example. There is no need to understand the code inside the specman.v file.

Example 2-5 Specman.v File Code for XOR DUT Verification
/* specman.v - A Specman Elite stubs file (top module is xor) */
/* Generated automatically on Thu Oct 31 12:15:25 2002*/

module specman;

    parameter sn_version_id = 944493104;  /* Version */
    parameter sn_version_date = 100998;  /* Version date*/

 event sn_never_happens;
    always @sn_never_happens begin
        $sn();
    end

    reg sn_register_memory;
    event sn_register_memory_event;
    initial begin
        sn_register_memory=0;
    end
    always @(sn_register_memory_event) begin
        sn_register_memory=1;
    end
 initial begin
        ->sn_register_memory_event;
    end

    event require_specman_tick;
    event emit_specman_tick;

    always @(require_specman_tick) begin
        #0 ->emit_specman_tick ;
    end


 /* Verilog task xor_top.mon */
reg mon_0_trig;

always @(posedge mon_0_trig) begin
xor_top.mon;
mon_0_trig = 0;
->require_specman_tick;
end

reg finish_test;
always @(posedge finish_test) begin
$finish;
end

endmodule /* specman */

module specman_trace;
endmodule /* specman_trace */

2.4.7 Running the Simulation

The following steps summarize the flow of running the simulation to verify the XOR DUT example.

  1. To run the simulation, both Specman Elite and the Simulator processes are invoked simultaneously. Specman Elite gains control and the Simulator stops at simulation time t=0. The control is then explicitly passed to the Simulator and the simulation is started.

  2. The Simulator continues to run until it reaches a falling edge of the clock (set by event fall_clk which has its sampling event @sim). At this point, the Simulator halts further execution and transfers control to Specman Elite.

  3. Specman Elite executes the first action in the verif_xor() method at the first falling edge of the clock. The verif_xor() method applies the a and b inputs to the DUT. Then, it encounters a wait keyword, so it transfers control back to Simulator.

  4. The Simulator continues simulation until it reaches the next falling edge of the clock. Control is passed back to Specman Elite. The verif_xor() method gathers the output and checks the output against the expected value. An event done is emitted for the coverage analyzer to take a sample. Then it goes to the top of the for each loop and applies the a and b inputs of the next stimulus item to the DUT.

  5. Simulation continues with control passing back and forth between Specman Elite and the Simulator until a and b inputs for all stimulus items in the ops list are applied to the DUT and the outputs are checked. When all stimulus items are applied, Specman Elite quits the for each loop and encounters a stop_run() invocation. This indicates completion of simulation.

  6. The coverage results can be displayed. The coverage report tells which values of a and b inputs have not been covered. The next test can cover these values until all possible values of a and b inputs are covered.

Previous Section Next Section