Functional Coverage and Clocking Blocks PDF
Functional Coverage and Clocking Blocks PDF
Coverage Basics
1
4
46747**sldi e
61182**sldi e
61121**sldi e
Functional Coverage
Because it is fully specified by the user, functional
coverage requires more up-front effort (someone has
to write the coverage model). Functional coverage
also requires a more structured approach to
verification.
Although functional coverage can shorten the overall
verification effort and yield higher quality designs, its
shortcomings can impede its adoption.
covergroup
1
9
46748**sldi e
Coverage Points
1
1
1
46750**sldi e
Each coverage point includes a set of bins associated with its sampled
values or its value transitions
The bins can be explicitly defined by the user or automatically created by the
tool
Sample()
User-defined sample() method is typically used
to collect coverage from different variables to the
same coverpoint/ covergroup
Bins construct
The bins construct allows creating a separate
bin for each value in the given range list or a
single bin for the entire range of values.
To create a separate bin for each value (an
array of bins), the square brackets, [], shall
follow the bin name.
To create a fixed number of bins for a set of
values, a number can be specified inside the
square brackets.
Features of Coverage
1
4
3
61282**sldi e
Coverage Class
//coverage class
class coverage;
virtual intf i;
covergroup cg @(i.a,i.b);
A: coverpoint i.a{bins a_bin = {[5:7]};}
B: coverpoint i.b;
S: coverpoint i.s{bins s1 = {0,1};bins s2 = {2,3};}
D: coverpoint i.c;
endgroup
function new (virtual intf i);
this.i = i ;
cg = new;
endfunction
task sample();
cg.sample();
endtask
endclass
Mailboxes
A mailbox is a communication mechanism that
allows messages to be exchanged between
processes. Data can be sent to a mailbox by
one process and retrieved by another.
Conceptually, mailboxes behave like real
mailboxes. When a letter is delivered and put
into the mailbox, one can retrieve the letter
(and any data stored within).
However, if the letter has not been delivered
when one checks the mailbox, one must
choose whether to wait for the letter or
retrieve the letter on subsequent trips to the
mailbox.
Mailboxes
Similarly, SystemVerilog's mailboxes provide
processes to transfer and retrieve data in a
controlled manner.
Mailboxes are created as having either a
bounded or unbounded queue size.
A bounded mailbox becomes full when it
contains the bounded number of messages.
A process that attempts to place a message
into a full mailbox shall be suspended until
enough room becomes available in the mailbox
queue.
Methods in Mailboxes
Mailbox is a built-in class that provides the
following methods:
Create a mailbox: new()
Place a message in a mailbox: put()
Retrieve a message from a mailbox: get()
Retrieve the number of messages in the
mailbox: num()
Mailbox Examples
module mailbox_ex;
//PKT CLASS
class pkt;
rand bit a;
rand bit b;
endclass
Generator Class
//generator class
class generator;
bit success;
mailbox #(pkt) mb_gen = new();
pkt inst ;
task run();
repeat(5)
begin
inst=new();
success = inst.randomize();
mb_gen.put(inst);
$display($time, "Putting packet: a = %d && b = %d", inst.a, inst.b);
#10;
end
endtask
endclass
Driver Class
// driver class
class driver;
mailbox #(pkt) mb_drv = new();
pkt inst;
task run();
#100;
inst=new();
mb_drv.get(inst);
$display($time,"getting packet from mailbox: a = %d &&
b = %d",inst.a,inst.b);
endtask
endclass
Module Execution
generator gen = new();
driver drv = new();
//Module execution starts
initial
begin
fork
gen.run();
#50 drv.run();
join
$finish();
end
endmodule
Mailbox Example 2
module mailbox_ex2();
//PKT CLASS
class random_pkt;
rand bit [2:0] a;
rand bit [4:0] b;
endclass
Generator Class
class generator;
random_pkt inst=new() ;
bit success;
mailbox #(random_pkt) mb_gen = new();
task run();
repeat(5)
begin
inst = new();
success = inst.randomize();
mb_gen.put(inst);
$display ($time,"Putting packet: a = %d && b = %d", inst.a, inst.b);
#5;
end
endtask
endclass
Driver Class
class driver;
random_pkt inst=new();
mailbox #(random_pkt)mb_drv ;
task run();
#25;
$display("mailbox size in driver is =%d",mb_drv.num());
repeat(5)
begin
#5;
mb_drv.get(inst);
$display($time,"getting packet from mailbox: a = %d && b =
%d",inst.a,inst.b);
#5;
end
endtask
endclass
Module Execution
generator gen = new();
driver drv = new();
//Module execution starts
initial
begin
drv.mb_drv = gen.mb_gen;
fork
gen.run();
drv.run();
join
$finish();
end
endmodule
Program Block
The program block serves three basic purposes:
1) It provides an entry point to the execution of testbenches.
2) It creates a scope that encapsulates program-wide data.
3) It provides a syntactic context that specifies scheduling in the
Reactive region.
31
Program Block
The program construct serves as a clear separator between
design and testbench, and, more importantly, it specifies
specialized execution semantics in the Reactive region for all
elements declared within the program.
Together with clocking blocks, the program construct provides
for race-free interaction between the design and the
testbench, and enables cycle and transaction level
abstractions.
32
Program Blocks
1
2
3
46385**sldi e
terminated
When all the programs are done (either by calling the $exit() method or by
finishing all the threads), the $finish() system task is called automatically
Program Syntax
1
2
4
60941**sldi e
Data declarations, class definitions, subroutines, and one or more initial and
final procedures
Program Block
The program block serves the following purposes:
Provides an entry point to the execution of testbenches.
Creates a scope that encapsulates program-wide data, tasks, and functions.
Provides a syntactic context that specifies scheduling in the reactive region.
Together with clocking blocks, the program construct provides for race-free
interaction between the design and the testbench and enables cycle and
transaction-level abstractions.
The abstraction and modeling constructs of SystemVerilog simplify the
creation and maintenance of testbenches.
Clocking Block
1
2
9
77291**sldi e
Timing information
Synchronization requirements
Input sampling
Clocking Block
1
3
0
46388**sldi e
Sample the inputs and drive the outputs to synchronize with a specific clock
Input skew specifies how long before a "real" clock-edge signal is sampled
Output skew specifies how long after a "real" clock-edge signal is driven
Clocking Blocks
A clocking block assembles signals that are
synchronous to a particular clock and makes their
timing explicit.
The clocking block is a key element in a cycle-based
methodology, which enables users to write
testbenches at a higher level of abstraction.
Rather than focusing on signals and transitions in time,
the test can be defined in terms of cycles and
transactions.
Depending on the environment, a testbench can
contain one or more clocking blocks, each containing
its own clock plus an arbitrary number of signals.
46391**sldi e
One clocking block can be specified as the default for all cycle operations
A default is valid only within the scope of the default clocking specification
Only one default clocking can be specified in a module, interface, program,
or checker
Cycle operator ##
Example
Interface Declaration
interface intf(input rst, clk);
logic [1:2] select; // operation
logic [1:4] dtoe; // dut to env data
logic [1:4] etod; // env to dut data
wire [1:4] bus; // bidirectional data
modport env (inout bus,
output etod, select,
input dtoe, rst, clk);
modport design (inout bus,
output dtoe,
input etod, select, rst, clk);
endinterface
Clocking block
program env (intf.env if1);
clocking cb @(posedge if1.clk);
output select = if1.select;
input dtoe = if1.dtoe;
output etod = if1.etod;
inout bus = if1.bus;
endclocking
task doit(input logic [1:2] sel, input logic [1:4] toe, bd);
cb.select <= sel;
cb.etod <= toe;
cb.bus <= bd;
endtask
Clocking block
initial begin
cb.etod <= 4'b0000;
cb.bus <= 4'bz;
@cb doit(2'b00, 4'b1001, 4'bzzzz);
@cb doit(2'b01, 4'b0110, 4'bzzzz);
@cb doit(2'b10, 4'b0101, 4'b01x1);
@cb doit(2'b11, 4'b0001, 4'bzzzz);
@cb $finish(0);
end
initial forever @cb begin
$display("at %0d, in %m: select=%b etod=%b dtoe=%b
bus=%b",
$time, if1.select, if1.etod, if1.dtoe, if1.bus);
end
endprogram
Design module
module design (intf.design if1);
wire clk = if1.clk;
wire [1:2] select = if1.select;
reg [1:4] dtoe, busdrv;
assign if1.dtoe = dtoe;
assign if1.bus = busdrv;
always @(posedge clk) begin
dtoe <= 0;
busdrv <= 'bz;
case (select)
2'b00: ;
2'b01: dtoe <= if1.etod;
2'b10: busdrv <= if1.etod;
2'b11: dtoe <= if1.bus;
endcase
end
endmodule
Debug the error if any from the solution for the given
problem
60979**sldi e
fork-join
1
4
0
fork-join any
1
4
1
fork-join_none
1
4
2
FAQ
1
4
8