A basic coverage item can be one of the following three elements.
A field in the local e struct
A field in another e struct in the hierarchy
An HDL signal or register
A basic coverage item can be specified with options that control how coverage data are collected and reported for the item. The item can be an existing field name or a new name. If you use a new name for a coverage item, you must specify the item's type and the expression that defines it. The syntax for a basic coverage group item is as follows:
item item-name[:type=exp] [using coverage-item-option, ...];
Table 10-3 describes the important coverage item options. These options can be specified with the definition of each basic coverage item.
Example 10-3 illustrates basic coverage items.
Example shows three types of basic coverage items: - Fields in a local struct - Fields in another struct - HDL signals An item must have a name if it is assigned to a field in another struct or an HDL signal. For fields in a local struct, the field name can be the item name. See the item options with each item. <' type cpu_opcode: [ADD, SUB, OR, AND, JMP, LABEL]; type cpu_reg: [reg0, reg1, reg2, reg3]; struct inst { opcode: cpu_opcode; op1: cpu_reg; op2: byte; event inst_driven; cover inst_driven is { //Three types of items //Field op1 in local struct, see item options item op1 using weight = 5, radix = DEC; //Field op2 in local struct, see item options item op2 using ignore = 0, radix = HEX, at_least = 10; //Name op2_big equal to boolean expression, see item options item op2_big: bool = (op2 >= 64) using weight = 10; //Name op3 equal to field in another struct item op3: bool = sys.header.op3; //Name hdl_sig equal a HDL variable value item hdl_sig: int = '~/top/sig_1'; }; }; '>
When one is covering int/uint types, it is not practical or necessary to cover the entire range of values for a 32-bit integer. Therefore, it is necessary to create a bucket for each boundary value or a range of values. Buckets can be created by means of the ranges option. Each bucket counts the number of samples within its range. The syntax for the ranges option is as follows:
ranges = {range(parameters); range(parameters); ...} range(range: range, name: string, every-count: int, at_least-num: int);
The arguments to range() are shown in Table 10-4 below.
Example 10-4 illustrates the ranges option.
Example of basic coverage group item using the ranges option <' struct pcc { pc_on_page_boundary: uint (bits: 15); //Local field pc: uint (bits: 15); //Local field stack_change: byte; //Local field event pclock; //Coverage group event cover pclock is { //Define coverage group item pc_on_page_boundary using //Cover the local field ranges = { //Ranges option range([0], "0"); //Only one value (0) in bucket range([4k], "4k"); //Only one value (4k) in bucket range([8k], "8k"); //Only one value (8k) in bucket range([12k], "12k"); //Only one value (12k) in bucket range([16k], "16k"); //Only one value (16k) in bucket range([20k], "20k"); //Only one value (20k) in bucket range([24k], "24k"); //Only one value (24k) in bucket range([28k], "28k"); //Only one value (28k) in bucket range([0..32k-1], "non-boundary"); //Default buckets }; item pc using radix = HEX, //Cover the local field ranges = { //Ranges option //range is 0..4k-1, name = page_0 //Cannot use every_count(UNDEF) due to name for range //at_least = 4 samples needed in this bucket range([0..4k-1], "page_0", UNDEF, 4); //range is 4k..32k-1, no name //every_count = 8k, creates buckets of 8k size //at_least = 2 samples needed in this bucket range([4k..32k-1], "", 8k, 2); }; item stack_change using //Cover the local field //Range is 0..32 divided into buckets of size 1 //i.e. 33 buckets ranges = { range( [0..32], "", 1); }; }; run() is also { emit pclock; //Collect coverage }; }; '>