Verification Testbench: Nagesh Loke ARM CPU Verification Lead/Manager
Verification Testbench: Nagesh Loke ARM CPU Verification Lead/Manager
Nagesh Loke
ARM CPU Verification Lead/Manager
1
What to expect?
2
What is a testbench?
▪ A testbench helps build an environment to test and verify a design
▪ The key components of a testbench are:
▪ Stimulus
▪ is used to drive inputs of the design to generate a high-level of confidence
▪ should be able to exercise all normal input scenarios and a good portion of critical combinations
with ease
▪ Checker
▪ is a parallel & independent implementation of the specification
▪ is used verify the design output against the modeled output
▪ Coverage
▪ Helps measure quality of stimulus
▪ Provides a measure of confidence to help determine closure of verification effort
3
What are we verifying? opcode[2:0]
▪ An ALU has
▪ an input clock
A[7:0]
▪ two 8-bit inputs as operands
▪ a 3-bit opcode as an operator
▪ a 16-bit output
OUT [15:0]
B[7:0]
clk
4
How was it done in the past?
5
What should the approach be?
▪ Start with a Verification plan
▪ A Verification plan talks about:
▪ various design features and scenarios that need to be tested
▪ architecture of the testbench
▪ reuse in higher level testbenches
6
SystemVerilog
▪ SystemVerilog as a hardware verification language provides a rich set of features
▪ Data Types & Aggregate data types
▪ Class, Event, Enum, Cast, Parameterization, Arrays, Associative arrays, Queues and manipulating methods
▪ OOP functionality
▪ Classes, Inheritance, Encapsulation, Polymorphism, memory management
▪ Processes
▪ fork-join control, wait statements
▪ Clocking blocks
▪ Interprocess synchronization & communication
▪ Semaphores, Mailboxes, named events
▪ Assertions
▪ Functional Coverage
▪ Virtual Interfaces
▪ Constraints
7
Components of a testbench
▪ The ALU testbench module now looks
different
▪ It includes headers for various components
▪ ALU Interface
▪ ALU Transaction
▪ ALU Monitor
▪ ALU BFM (driver)
▪ ALU Scoreboard
▪ It creates the interfaces
▪ It instantiates the DUT
8
Main Test
▪ A program block is the main entry point
▪ A bfm object and a scoreboard object are
created
▪ All the components are started
▪ A fork/join process ensures that they all
start in parallel
▪ We exit the fork statement at 0 time
▪ Simulation is stopped when $finish is called
▪ Multiple initial blocks execute in parallel
9
Transaction class
10
BFM/driver
▪ The BFM/driver class:
▪ Has a handle to a virtual interface
▪ Declares a alu_trxn data type
▪ Has a constructor
▪ drive() task:
◦ Does not end
◦ Creates a new transaction
◦ Randomizes the transaction
◦ Passes the handle to drive_trxn() task
▪ drive_trxn () task
◦ consumes time
◦ drives the input signals based on the values in the
trxn class
◦ Uses clocking block and non-blocking assignments
◦ Adheres to pin level timing of signals
11
Scoreboard
▪ The Scoreboard:
▪ Functionality is to continuously check the output
independent of the input stimulus
▪ check() task:
◦ Collects information from the interface and
populates the trxn class
◦ Calls a compute_expected_out function
▪ compute_expected_out() task
◦ Implements the model of the deisign
◦ Takes in the inputs and gets an expected output
◦ Compares the actual output against the expected
output
◦ Issues an error message if the comparison fails
12
How does the testbench look like?
alu_tb
clock Process control
generation logic logic
clk
A OUT
alu_bfm ALU
ALU
B
alu_sb
13
How do we know we are done?
▪ With a random testbench it is difficult to know what scenarios have been exercised
▪ Two techniques are typically used to get a measure of what’s done
▪ Code Coverage
▪ No additional instrumentation is needed
▪ Toggle, Statement, Expression, Branch coverage
▪ Functional Coverage
▪ Requires planning
▪ Requires instrumenting code
▪ SystemVerilog provide constructs to support functional coverage
▪ Provides detailed reports on how frequently coverage was hit with the test sample
▪ Coverage closure is an important aspect of verification quality
14
What did we go over …
15
ARM Cortex A72 CPU
16
ARM CCN-512 SoC Framework
17
What are the challenges of verifying complex systems?
▪ Typical processor development from scratch could be about 100s of staff years effort
▪ Multiple parallel developments, multiple sites and it takes a crowd to verify a processor
▪ The challenges are numerous – especially when units are put together as a larger unit
or a whole processor and verified
▪ Reuse of code becomes an absolute key to avoid duplication of work
▪ Multiple times it is essential to integrate an external IP into your system
▪ The IP can come with it’s own verification implementation
▪ This requires rigorous planning, code structure, & lockstep development
▪ Standardization becomes a key consideration
18
Useful pointers
▪ https://verificationacademy.com/
▪ SV Unit YouTube Video
▪ EDA Playground
▪ http://testbench.in/
▪ Search for SystemVerilog on YouTube
19
Let’s solve this …
class base; program a;
int a; initial begin
static bit b; base b1, b2;
function new(int val); sub s1, s2;
a = val; othersub os1;
endfunction
virtual function void say_hi(); b1 = new(1);
$display($psprintf("hello from base (a == %0d)", a)); s1 = new(2);
endfunction os1 = new(3);
class sub extends base;
int c; s1.say_hi();
function new(int val); os1.say_hi();
super.new(val);
c = val; b2 = os1;
endfunction b2.say_hi();
virtual function void say_hi();
super.say_hi(); $display($psprintf("b == %0d", base::b));
$display($psprintf("hello from sub (c == %0d)", c)); $display($psprintf("b == %0d", othersub::b));
endfunction end
endclass endprogram
20