ASIC Verification: Coverage in Specman

Sunday, March 9, 2008

Coverage in Specman

Every verification engineers faces this question. How much verification is enough? The answer to this question would most probably provided by coverage. Coverage also provide the information about where the verification engineer's energy should be focussed in the design. In this section we are going to see the description of functional coverage, what are the coverage groups and coverage items.

Functional coverage checks whether all stimulus scenarios, corner cases and protocols are covered in the verification environment. It also measures if all the important and interesting combination of stimulus have been exercised. So the functional coverage is important, because

  • It allows the engineer to focus on key areas of the design
  • It tells the engineer how much verification is enough
  • It improves the efficiency of stimulus generation
Following example shows the definition of coverage groups.

type usb_transaction : [CONTROL, BULK, ISO, INTERRUPT];
type hpie_state : [IDLE, TOKEN, DATA, HANDSHAKE, CRC];
struct usb
transaction_done : bool; // Set by some struct in sys
transaction : usb_transaction; // Define enumerated type
event packet_is_xmitted; // Declare an event
// Define coverage group
cover packet_is_xmitted using
// This option reduces the memory consumption
// Because the data collected for this group is reduced
// A text description for the coverage group.
// This can be quoted string, The text is shown at the
// beginning of the info. for the group in the coverage report.
text = " Checking ISO transaction",
//The radix value for the buckets names to be displayed.
radix = HEX,
// Specifies the grading weight of the current group relative
// to the other group
weight = 10,
// Coverage groups are sampled only when
// this boolean expression is true
when = (transaction_done == TRUE) is
item transaction; // Item transaction is to be covered
// If there is any state machine in the DUT, coverage of
// Statemachine is done using
item state : hpie_state = '~/top/hub/hpie/current_state';

run() is also
emit packet_is_xmitted;
};// End of run()
}; // End of Struct
Basic Coverage Item

A basic coverage item can be any one of the following elements

  • A field in the local struct
  • A field in the another struct in the hierarchy path
  • An HDL signal
type up_opcode : [ADD, SUB];
type up_reg : [reg0, reg1];

struct basic_coverage
opcode : up_opcode;
op1: up_reg;
op2: byte;
event rdy;

cover rdy is
// op1 is in local struct
item op1 using radix=DEC;
// item op2 is in another struct
item op3 : bool = sys.header.op3;
// An HDL signal
item packet_rdy : int = '~/top/hub/ready';
}; // End of cover
}; // End of struct

Anybody knows more about the "Basic coverage item ranges" can contribute to this section.

Transition Coverage Item

Transition coverage items record the change in the item's value between two consecutive samplings of the item. Transition items are very useful for covering DUT state machines. The coverage options for the transition coverage items are similar to the Basic coverage items. However, the ranges option is not available for with transition coverage items.
type hpie_state : [IDLE, TOKEN, DATA, HANDSHAKE];

struct hpie_sm
event r_clk is rise ('~/top/clock');

cover r_clk is
item state : hpie_state = '~/top/hub/hpie/present_state';

// Illegal option prints an error message
// when the boolean expression is true.

transition state using illegal =
not (( prev_st == IDLE and current_state == DATA) or
(prev_st == IDLE and current_state == HANDSHAKE) or
(prev_st == TOKEN and current_state == HANDSHAKE) );

}; // End of cover
}; // End of struct
Cross Coverage Item

Cross coverage items provide a cross product of two or more previously declared basic items. It is possible to create a cross of any number of basic or transition items declared in the same coverage group.

Latency Coverage

Latency coverage requires comparison of the time an activity ends with the time that activity started. There are no built-in constructs provided by e for latency coverage. However, it is easily possible to perform latency coverage using e.
struct latency
!first_occurance : time;
!latency : time;

event start;
event end;

// Take a snapshot of system time on start
on start { first_occurance = sys.time};

// Take a snapshot of system time on end and compute the latency
on end { latency = sys.time - first_occurance};

cover end is { // Set up the coverage when the packet finishes
item latency;
}; // End of cover
}; // End of struct
Turn ON the Coverage

Use the cover configuration option to turn on coverage. If cover groups are defined then coverage is automatically turned on. The set_config() method is called to turn on the coverage. The set_config() method has a different option. Based on the user's requirement, they can include the different modes.
struct coverage
field1 : int;
legal : bool;
keep field1 == 5;
}; // End of struct

extend sys
setup() is also // Extend the setup() of sys
set_config(cover, mode, on); // Turn On the coverage
}; // End of sys()
}; // End of extend
Viewing Coverage Results

After the e-based simulation is completed, coverage output is produced. Coverage output from Specman Elite can be viewed graphically or in a text file. Coverage output can also be accumulated over multiple test runs to view cumulative coverage.

1 comment:

Anonymous said...

Hi Suresh,

Was looking through your blog and found your examples very interesting and well described.
One thing that got my attention was your latency coverage example. I see that you are using the type time for your item and according to specman documentation cover items can only be scalars (of size <= 32 bits) or strings. How did you get this to work?