|HOME |ABOUT |ARTICLES |ACK |FEEDBACK |TOC |LINKS |BLOG |JOBS |


Tutorials



ONES COUNTER EXAMPLE


Following example is TestBench for ones counter. It has some verification components which are required, but not all the verification components discussed earlier. All the components implementation can be seen in further chapters with another protocol. Description of the language construct is discussed in further chapters, so don't pay attention to them. The intention of showing this example is to make you familiar with some steps required while building verification environment and to help you to understand the flow discussed above.  


Specification:


Ones Counter is a Counter which counts the number of one's coming in serial stream. The Minimum value of the count is "0" and count starts by incriminating one till "15".  After "15" the counter rolls back to "0".  Reset is also provided to reset the counter value to "0". Reset signal is active negedge. Input is 1 bit port for which the serial stream enters. Out bit is 4 bit port from where the count values can be taken. Reset and clock pins also provided.




The following is the RTL code of onescounter with bugs.


     module dff(clk,reset,din,dout);
          input clk,reset,din;
          output dout;
          logic dout;
          
          always@(posedge clk,negedge reset)
               if(!reset)
                   dout <= 0;
               else
                   dout <= din;
     endmodule
    
     module ones_counter(clk,reset,data,count);
           input clk,reset,data;
           output [0:3] count;
        
           dff d1(clk,reset,data,count[0]);
           dff d2(count[0],reset,~count[1],count[1]);
           dff d3(count[1],reset,~count[2],count[2]);
           dff d4(count[2],reset,~count[3],count[3]);
        
     endmodule
    
Test Plan:

This is a simple testplan. Features to be verified are
1)      Count should increment from "0" to "15".( Coverage item)
2)      Count should roolover to "0" after "15".(Coverage transition)
3)      Reset should make the output count to "0", when the count values is non "0". ( Assertion coverage)


Block Diagram:





Verification Environment Hierarchy


TOP
|-- Clock generator
|-- Dut Instance
|-- Interface
|-- Assertion block instance ( assertion coverage)
|-- Testcase instance
           |-- Environment
                   |-- Driver
                   |     |-- Stimulus
                   |     |-- Covergroup
                   |-- Monitor
                   |-- Scoreboard




Testbench Components:

Stimulus

Stimulus is a single bit value.  

class stimulus;
  rand  bit value;
  constraint distribution {value dist { 0  := 1 , 1 := 1 }; } 
endclass

Driver

This driver consists of reset and drive method.  Reset method resets the DUT and drive method generates the stimulus and sends it to DUT. Driver also calculates the expected DUT output and stores in scoreboard. Coverage is also sampled in this component. Feature 1 and 2 which are mentioned in Testplan are covered in this cover group.

 
   class driver;
        stimulus sti;
        Scoreboard sb;
  
        covergroup cov;
             Feature_1: coverpoint sb.store ;
             Feature_2 :  coverpoint  sb.store  {  bins trans = ( 15 => 0) ;} 
        endgroup
        
        virtual intf_cnt intf;
        
        function new(virtual intf_cnt intf,scoreboard sb);
             this.intf = intf;
             this.sb = sb;
             cov = new();
        endfunction
        
        task reset();  // Reset method
             intf.data = 0;
             @ (negedge intf.clk);
             intf.reset = 1;
             @ (negedge intf.clk);
             intf.reset = 0;
             @ (negedge intf.clk);
             intf.reset = 1;
        endtask
        
        task drive(input integer iteration);
             repeat(iteration)
             begin
                  sti = new();
                  @ (negedge intf.clk);
                  if(sti.randomize()) // Generate stimulus
                      intf.data = sti.value; // Drive to DUT
                  sb.store = sb.store + sti.value;// Cal exp value and store in Scoreboard
                  if(sti.value)
                      cov.sample();
             end
        endtask
   endclass

Monitor

The monitor collects the DUT output and then gets the expected value from the score board and compares them.


    class monitor;
          scoreboard sb;
          virtual intf_cnt intf;
          
          function new(virtual intf_cnt intf,scoreboard sb);
               this.intf = intf;
               this.sb = sb;
          endfunction
          
          task check();
              forever
              @ (negedge intf.clk)
              if(sb.store != intf.count) // Get expected value from scoreboard and compare with DUT output
                  $display(" * ERROR * DUT count is %b :: SB count is %b ", intf.count,sb.store );
              else
                  $display("           DUT count is %b :: SB count is %b ", intf.count,sb.store );
          endtask
    endclass

Assertion Coverage

This block contains the assertion coverage related to 3 rd feature mentioned in testplan.

    module assertion_cov(intf_cnt intf);
       Feature_3 : cover property (@(posedge intf.clk)  (intf.count !=0)  |-> intf.reset == 0 );
    endmodule

Scoreboard

This scoreboard is a simple one which stores one expected value.

   class scoreboard;
       bit [0:3] store;
   endclass

Environment:

Environment contains instances of driver, monitor and scoreboard.  

     class environment;
           driver drvr;
           scoreboard sb;
           monitor mntr;
           virtual intf_cnt intf;
          
           function new(virtual intf_cnt intf);
                 this.intf = intf;
                 sb = new();
                 drvr = new(intf,sb);
                 mntr = new(intf,sb);
                 fork 
                     mntr.check();
                 join_none
           endfunction
          
     endclass
    

Top:

The interface is declared and the test bench and DUT instances are taken. Testbench and DUT are connected using interfaces.  Clock is also generated and connects it to DUT and testbench.


   interface intf_cnt(input clk);

      wire clk;
      wire reset;
      wire data;
      wire [0:3] count;

   endinterface
            
  
   module top();
      reg clk = 0;
      initial  // clock generator
      forever #5 clk = ~clk;
      
      // DUT/assertion monitor/testcase instances
      intf_cnt intf(clk);
      ones_counter DUT(clk,intf.reset,intf.data,intf.count);
      testcase test(intf);
      assertion_cov acov(intf);
   endmodule

Tests:

This is a simple test case.  It does reset and then send 10 input values.

    program testcase(intf_cnt intf);
         environment env = new(intf);
        
         initial
         begin
              env.drvr.reset();
              env.drvr.drive(10);
         end
    endprogram

After simulating with this testcase, the coverage report I got

Total Coverage Summary

SCORE   ASSERT    GROUP
9.38    0.00       18.75

Cover group report
VARIABLE   EXPECTED UNCOVERED COVERED PERCENT GOAL WEIGHT  
Feature_1   16      10          6      37.50    100 1
Feature_2    1      1           0       0.00    100 1

Assertion coverage report:
COVER      PROPERTIES CATEGORY SEVERITY ATTEMPTS MATCHES INCOMPLETE
Feature_3  0          0           13    0          0



This coverage report will be different if you simulate in your tool.
To improve the coverage, than the 1st testcase , I wrote 2nd testcase with more input values and also logic related to 3 feature in the testplan.


program testcase(intf_cnt intf);
  environment env = new(intf);
  
  initial
  begin
    env.drvr.reset();
    env.drvr.drive(100);
    env.drvr.reset();
    env.drvr.drive(100);
  end
endprogram

Download the phase 1 files:

ones_counter.tar
Browse the code in ones_counter.tar

Run the simulation:
your_tool_command -f filelist test_1.sv
your_tool_command -f filelist test_2.sv

Simulation Log Report:
           DUT count is 0xxx :: SB count is 0000 
           DUT count is 0xxx :: SB count is 0000 
           DUT count is 0000 :: SB count is 0000 
           DUT count is 0000 :: SB count is 0000 
 * ERROR * DUT count is 1111 :: SB count is 0001 
 * ERROR * DUT count is 0111 :: SB count is 0001 
 * ERROR * DUT count is 0111 :: SB count is 0001 
 * ERROR * DUT count is 0111 :: SB count is 0001 
 * ERROR * DUT count is 1011 :: SB count is 0010 
 * ERROR * DUT count is 1011 :: SB count is 0011 
           DUT count is 0011 :: SB count is 0011 
           DUT count is 0011 :: SB count is 0011 
 * ERROR * DUT count is 1101 :: SB count is 0100



Index
Asic Design
Bottle Neck In Asic Flow
Functional Verification Need
Testbench
Linear Testbench
Linear Random Testbench
How To Check The Results
Self Checking Testbenchs
How To Get Scenarios Which We Never Thought
How To Check Whether The Testbench Has Satisfactorily Exercised The Design
Types Of Code Coverage
Statement Coverage
Block Coverage
Conditional Coverage
Branch Coverage
Path Coverage
Toggle Coverage
Fsm Coverage
Make Your Goal 100 Percent Code Coverage Nothing Less
Functional Coverage
Coverage Driven Constraint Random Verification Architecture
Phases Of Verification
Ones Counter Example
Verification Plan

Report a Bug or Comment on This section - Your input is what keeps Testbench.in improving with time!





<< PREVIOUS PAGE

TOP

NEXT PAGE >>

copyright © 2007-2017 :: all rights reserved www.testbench.in::Disclaimer