Microsoft PowerPoint – HW_Verification_Lecture_3
Hardware Verification –
Copyright By PowCoder代写 加微信 powcoder
Autumn term 2022
• Introduction to SystemVerilog
• Data types
• Procedural statements and routines
• Connecting the testbench to the design : interfaces, clocking blocks
• Testbench timing issues
• Introduction to Object-Oriented Programming features
• Randomisation and principles of constrained random simulation
• More details on writing SVAs
• Introduction to main coursework on hardware verification
Simulation time slot
From previous
To next time slot
} Design events run
} Assertions are evaluated
} Testbench code in a program runs here
} Where signals are sampled at end of time slot
Sampling in a synchronous interface
Value of sig
sampled just
before rising
clock edge
cb.sig updated
on rising edge of
clk, to reflect
sampled value of
Introduction to OOP in SystemVerilog
• In Verilog and C, there is a strong division between data structures
and code that uses them.
• Data and code might even be in separate files
• It can make it hard to understand the functionality.
• OOP lets you create complex data types and tie them together with
the routines that work on them
• Create testbench at a more abstract level by calling routines rather than
toggling bits
• Code is more easily written and understood
• The testbench is decoupled from the design details – this makes it more
robust, and easier to maintain and re-use
Constructing a testbench
Assertions
Scoreboard Checker
Functional
Environment
From Spear & Tumbush, SystemVerilog for Verification
Testbench transactors and transactions
• Each testbench block is a transactor
• OOP enables you to create an object that includes data and routines
for a transactor
• Transactor generates transactions
• OOP also enables you to build an object that contains the data and
routines that make up the transactions
• These transactions can then be sent between blocks using mailboxes
• Represent these objects in SystemVerilog using a class
• Examples of a class: bus transaction, network packet, CPU instruction
The class construct
class Transaction;
bit [31:0] addr, checksum, data[8];
function void display();
$display(“Transaction: %h”, addr);
endfunction : display
function void calc_checksum();
checksum = addr ^ data.xor;
endfunction : calc_checksum;
endclass : Transaction
• A class encapsulates data together with the routines that manipulate it.
• The details of how a class implements actions are hidden from the outside
• This makes the class more reusable
OOP Terminology
OOP terms in System equivalent
Class – a basic building block containing routines and variables module
Object – an instance of a class Need to instantiate a module to
Handle – a pointer to an object Use name of instance
Property – a variable that holds data A signal such as a reg or wire
Method – the procedural code that manipulates variables, contained in
tasks and functions
Tasks and functions plus
initial and always blocks
Prototype – the header of a routine that shows the name, type and
argument list, plus a return type
More on classes
• A SystemVerilog class is constructed at runtime during a simulation,
when needed by the testbench
• Contrast this with Verilog, where you create modules and instantiate
them hierarchically at compilation time
Design for car
Class Object ObjectObject
Creating new objects
• SystemVerilog stimulus objects are dynamic and created when needed
• Objects may later be freed to make memory available for new ones
• To create an object, declare a handle and then call new() to construct it
Transaction tr; // Declare a handle
tr = new(); // Allocate a Transaction object
class Transaction;
bit [31:0] addr, checksum, data[8];
• new() allocates space for transaction – 40 bytes for this example
• initialises variables to default values and returns address where object is stored
• Don’t confuse new() with new[] !
Custom constructors
• You can define your own new() function to initialise values
class Transaction;
bit [31:0] addr, checksum, data[8];
function new();
data = ‘{default:5};
endfunction
Custom constructor with arguments
• You can use arguments with default values – then you can specify the
values when calling the constructor, or use the default values
class Transaction;
bit [31:0] addr, checksum, data[8];
function new(input bit [31:0] a=3, d=5);
data = ‘{default:d};
endfunction
initial begin
Transaction tr;
tr = new(.a(10)); / a=10, d uses default of 5
Dynamic allocation of objects
• Remember that you declare a handle and construct an object
• A handle can point to many objects over the course of a simulation
Transaction t1, t2;
t1 = new();
t1 = new();
Deallocating objects
• SystemVerilog lets you create objects dynamically, when needed
• Thousands of objects might need to be created during a simulation –
so SystemVerilog needs a way of reclaiming memory once an object is
no longer needed
• Garbage collection is automatic way of freeing objects that are no
longer referenced
Transaction tr;
tr = new();
tr = new(); // First object can be deallocated
tr = null; // Explicitly clear handle so second
// object can be deallocated
Using objects
• Refer to variables and routines with “.” notation
Transaction tr; // Declare tr as a handle
tr = new(); // Construct an object
tr.addr = 32’h44; // Set value of addr
tr.display(); // Call display routine
Class methods
• A method is a task or function defined inside the scope of the class
• A method in a class uses automatic storage by default
class Transaction;
bit [31:0] addr, checksum, data[8];
function void display();
$display(“Transaction: %h”, addr);
endfunction : display
endclass : Transaction
Transaction tr;
initial begin
tr = new();
tr.display();
Method definition outside of a class
• To keep the class to a reasonable length, methods can be defined
outside of a class
• Break the method into a prototype inside the class and the body after
class Transaction;
bit [31:0] addr, checksum, data[8];
extern function void display();
endclass : Transaction
function void Transaction::display();
$display(“Transaction: %h”, addr);
endfunction : display
Static rather than global variables
• If you need a variable that is shared by objects, create a static variable
inside the class
• This limits variable to only being visible to instances of that class
• In the example, each object has its own copy of id but there is only
one copy of count (it is stored with the class and not the object)
class Transaction;
static int count = 0;
function new();
id = count++;
endfunction
endclass : Transaction
Testbench constructed from classes
Assertions
Scoreboard Checker
Functional
Environment
From Spear & Tumbush, SystemVerilog for Verification
Code for transactor
• Transactor is a loop: receives transaction, does some processing, and
sends it to next block
class Transactor;
Transaction tr;
task run();
forever begin
// Get transaction from upstream block
… // Do some processing
… // Send transaction to downstream block
Randomisation
• With directed testing, you need to write a test and check the result.
• You need to think of all the scenarios that need testing
• You need to decide how many tests are needed
• A better approach is Constrained Random Testing (CRT)
• Random stimulus can uncover bugs due to scenarios that you never thought
• Use constraints to restrict the test scenarios and put more emphasis on
“interesting” cases
• CRT needs a reference model to check against – and functional coverage to
measure effectiveness of the random stimulus
• CRT uses test code to create a random stream of stimulus to the DUT,
together with a seed to the pseudo-random number generator
Constrained random testing
==? OK/Error
Functional
What to randomise?
• All decision points in your DUT need to be randomised, not just the
• Consider all design inputs, such as:
• Configurations – device and environment
• Primary inputs
• Encapsulated input data
• Transaction status
• Exceptions
• Errors and violations
Random variables in a class
• Random stimulus generation is best done in a class
class Packet;
rand bit [31:0] src, dst, data[8];
randc bit [7:0] kind; // random cyclic
constraint c {src > 10;
src < 15;}
initial begin
p = new();
assert (p.randomize) else $fatal;
transmit(p);
Weighted distributions
class atb_ready;
rand int delay;
rand bit response;
constraint atb_response_dist {
response dist {
0 :/ 20,
1 :/ 80 };
constraint atb_ready_delay {
delay dist {
1 :/ 10,
[2:4] :/ 90 };
Creating sets of values
• Create set of values using the inside operator
• Constraint solver chooses between values with equal probability
class Ranges;
rand bit [31:0] c;
bit [31:0] lo, hi;
constraint c_range {
c inside {[lo:hi]}; // lo <= c && c <= hi
Bidirectional constraints
• All constraints are solved in parallel
class parallel_solve;
rand bit [7:0] a, b, c;
constraint c_parallel {
Implication constraints
• There are two implication operators: -> and if
• These allow you to control when an expression is active
• if .. else constructs can also be used
class Busop;
rand bit [31:0] addr;
rand bit io_space
constraint c_io {
io_space_mode ->
addr[31] == 1’b1;
// Or equivalently: if (io_space_mode) addr[31] == 1’b1;
Other ways of controlling constraints
• “solve .. before” constraint e.g. solve x before y;
• Perform action before or after every call to randomize
• pre_randomize();
• post_randomize();
SystemVerilog Assertions (SVA)
• An assertion is a statement that a property must be true
“If the result of the compare is true, the ‘Z’ flag must be set”
• Assertions can be used to:
• Check designer intent
• Specify interface behaviour (the contract between block designers)
• As a tool for effective verification of a design
• Check completeness of verification, by measuring whether assertions have
been covered
• Assertions can be written by both design and verification engineers
Assertion-based Verification
• Assertion-based verification can lead to earlier closure of the
verification cycle – makes it easier to find bugs early
• Assertions can be used:
• During simulation (dynamic)
• For formal verification of a property (static)
• Two main types of assertion:
• Immediate Assertions
• Concurrent Assertions
Immediate Assertions
• Immediate – checks that statement is true when it is executed
assert (ack == 1’b0); // Immediate – Checks ack is low at this point in simulation
assert (ack == 1’b0) // With error message if assertion fails
else $error (“Error: ack not negated”);
Concurrent Assertions
• Concurrent – checks behaviour continuously throughout simulation
• Can check sequence of events over multiple clock cycles
property check_result; // Concurrent – requires a sampling clock
@(posedge clk) disable iff (!rst_n)
result == a + b;
endproperty
assert_check_result: assert property (check_result);
Assertion pass/fail behaviour
• Pass and fail messages can be user-specified
• Four severity levels for assertion fails:
• $fatal (simulation stops)
• $warning
assert (ack == 1’b0) // With error message if assertion fails
else $error (“Error: ack not negated”);
Specifying sequences in SVA
• Behaviour over a number of clock cycles can be checked by specifying a
• Specify number of clock cycles to wait before evaluating expression with ##
• Can specify range with [1:n] or infinite number with [1:$]
property check_req_ack;
@(posedge clk) disable iff (!rst_n)
req ##1 ack;
endproperty
assert_check_req_ack: assert property (check_req_ack);
else $fatal(“ack not asserted one cycle after req asserted”);
Repeat count
• Specify a repeat count with the ‘*’ operator
• Specify range of counts with [* min_count : max_count]
siga ##1 (sigb[*2]) – equivalent to: siga ##1 sigb ##1 sigb
(siga[*0:2] ##1 sigb) – sigb
or (siga ##1 sigb)
or (siga ##1 siga ##1 sigb)
Implication operator
• Use an implication operator to control whether an expression is
• |-> Evaluate on same clock edge
• |=> Evaluate on next clock edge
expressionA |-> expressionB; // Only evaluate expression B if expression A is true
expressionA |=> expressionB; // If expressionA is true, then evaluate
// expression B on the next clock edge
System functions to detect changes on signals
System functions to determine change since last clock tick
• $rose (expression); // true if changed to ‘1’
• $fell (expression); // true if changed to ‘0’
• $stable (expression); // true if no change
• $isunknown (expression); // true if any bit is X or Z
• $onehot (expression); // true if only one bit is set
$past (expression [, number of cycles]);
// returns value the number of cycles ago (default is 1 cycle if number not
specified)
SVA tutorial – for more details
https://www.doulos.com/knowhow/sysverilog/tutorial/assertions/
Next lecture:
Formal Verification
程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com