Transcript Document

SoC Verification
HW #2
TA: Wei-Ting Tu
Assignment: 04/12/06
Due: 04/26/06

Lab introductions
 Lab 1-3: examples
 Lab 4-6: exercises

Lab requirements
 Implement each task in lab 4~6.

References
 svtb.pdf: SystemVerilog TestBench Guide
 svtb_tutorial.pdf: SystemVerilog TestBench Tutorial
 SVTB_2005.06_SG.pdf: SystemVerilog Workshop Student
Guide
 SVTB_2005.06_LG_01~3.pdf: SystemVerilog Workshop
examples
 SVTB_2005.06_LG_04~6.pdf: SystemVerilog Workshop
exercises
i- 2
Workshop Goal
Acquire the skills to write a SystemVerilog
testbench to verify Verilog/SystemVerilog RTL
code with coverage-driven random stimulus.
i- 3
Target Audience
Design or Verification engineers
writing SystemVerilog testbenches
to verify Verilog or SystemVerilog code.
i- 4
Workshop Prerequisites

You must have experience in the following areas:

Familiarity with a UNIX text editor

Basic programming skills in Verilog, VHDL or C

Debugging experience with Verilog, VHDL or C
i- 5
What Is the Device Under Test?
A router:
16 x 16 crosspoint switch
din [15:0]
dout [15:0]
frame_n[15:0]
valid_n [15:0]
frameo_n [15:0]
router
valido_n [15:0]
reset_n
clock
i- 6
A Functional Perspective
frame_n[0]
valid_n[0]
din[0]
inputs
outputs
port
port
0
0
frameo_n[0]
valido_n[0]
dout[0]
1
1
2
2
3
3
4
4
partial view
i- 7
The Router Description

Single positive-edge clock

Input and output data are serial (1 bit / clock)

Packets are sent through in variable length:

Each packet is composed of two parts
Header
 Payload


Packets can be routed from any input port to any
output port on a packet-by-packet basis

No internal buffering or broadcasting (1-to-N)
i- 8
Input Packet Structure

frame_n:



din:


Falling edge indicates first bit of packet
Rising edge indicates last bit of packet
Header (destination address & padding bits) and payload
valid_n:

valid_n is low if payload bit is valid, high otherwise
clock
din[i]
x
A0
A1
A2
A3
valid_n[i]
x
x
x
x
x
d0
....
x
dn-1
dn
x
frame_n[i]
dest. address
pad
payload
i- 9
Output Packet Structure

Output activity is indicated by:
frameo_n, valido_n, and dout

Data is valid only when:



frameo_n output is low (except for last bit)
valido_n output is low
Header field is stripped
clock
dout[i]
x
valido_n[i]
x
x
d0
d1
x
x
d2
d3
dn-3
x
dn-2 dn-1
x
x
frameo_n[i]
i- 10
Reset Signal

While asserting reset_n, frame_n and valid_n
must be de-asserted

reset_n is asserted for at least one clock cycle

After de-asserting reset_n, wait for 15 clocks
before sending a packet through the router
clock
reset_n
frame_n[i]
15 clock cycles
i- 11
The DUT: router.v

The Design Under Test, router.v, is a Verilog file:

Located under the rtl directory

From the lab workspace: ../../rtl/router.v
~
solutions/
labs/
lab1/
lab2/
lab6/
lab1/
rtl/
lab6/
router.v
lab work files
i- 12
The SystemVerilog Test Environment
Configure
Generator
Top level
harness file
Transactor
Driver
Checks
completeness
Coverage
Self Check
Observes data
from DUT
DUT
Checks
correctness
Identifies
transactions
Transactor
Test
program
Monitor
interface
i- 13
SystemVerilog Testbench Building Process
router.v
ntb_template -t router router.v
Discard
router.test_top.v
router.vr.tmp
router.test_top.sv
router.if.sv
Top level harness
Interface
router.if.vrh
router.tb.sv
Test program
vcs –sverilog router.test_top.sv router.tb.sv router.if.sv router.v
simv
i- 14
Create Verilog Test Harness File

Use VCS template generator
ntb_template -t router router.v

Generates three files:

router.test_top.v Verilog test harness file

router.if.vrh
Discard (for OpenVera only)

router.vr.tmp
Discard (for OpenVera only)

-t router Specifies DUT module name

router.v DUT source code file

router.test_top.v will be used to help build
SystemVerilog testbench files
i- 15
Creating SystemVerilog Interface File

Create interface file from router.test_top.v
cp router.test_top.v router.if.sv

Encapsulate signals in interface block
module router_test_top;
parameter simulation_cycle = 100;
reg SystemClock ;
wire reset_n ;
wire [15:0] din ;
wire clock ;
wire [15:0] frame_n ;
wire [15:0] valid_n ;
wire [15:0] dout ;
wire [15:0] busy_n ;
wire [15:0] valido_n ;
wire [15:0] frameo_n ;
`ifdef SYNOPSYS_NTB
...
`endif
router dut( … );
initial begin
SystemClock = 0 ;
forever begin
#(simulation_cycle/2)
SystemClock = ~SystemClock ;
end
end
router.test_top.v
endmodule
Create from default harness file
Change module to interface
Delete all except wires
interface router_io(input logic clock);
logic reset_n ;
Move clock to
logic [15:0] din ;
//wire
clock;
input argument
logic [15:0] frame_n ;
logic [15:0] valid_n ;
router.if.sv
logic [15:0] dout ;
logic [15:0] busy_n ;
logic [15:0] valido_n ;
logic [15:0] frameo_n ;
endinterface
Change wire to logic
i- 16
Define Test Program Interface Port

By default all interface signals are asynchronous

Synchronous signals can be created via clocking
block and connected to test program via modport
Create synchronous
by placing signals
into clocking block
Define connection
for test program
with modport
router.if.sv
interface router_io(input logic clock);
logic reset_n ;
logic [15:0] din ;
Configure
logic [15:0] frame_n ;
logic [15:0] valid_n ;
Generator
Coverage
logic [15:0] dout ;
logic [15:0] busy_n ;
Transactor
Self Check
Transactor
logic [15:0] valido_n ;
logic [15:0] frameo_n ;
clocking cb @(posedge clock);
Driver
Monitor
default input #1 output #1;
output reset_n;
output din;
DUT
output frame_n;
output valid_n;
input dout;
Sample/drive skew
input busy_n;
input valido_n;
Direction w/respect to test
input frameo_n;
endclocking
modport TB(clocking cb, output reset_n);
endinterface
Synchronous
Asynchronous
i- 17
Build Testbench

Testbench is encapsulated in program block

List interface signals in argument
Both synchronous and
asynchronous signals are
encapsulated in modport
router.tb.sv
program automatic router_test(router_io.TB router);
// develop test code in initial block:
initial begin
$vcdpluson; // Dumping file control
$display(“Hello World”);
end
endprogram
Configure
Generator
Coverage
Transactor
Self Check
Driver
Transactor
Monitor
DUT
i- 18
Sample Testbench

Develop test program code in initial block
program automatic router_test(router_io.TB router);
//testbench code in initial block:
interface router_io(input logic clock);
logic reset_n ;
initial begin
logic [15:0] din ;
$vcdpluson; // Dumping file control
logic [15:0] frame_n ;
logic [15:0] valid_n ;
//
$display(“Hello World”);
...
end
clocking cb @(posedge clock);
initial begin Asynchronous signals are
default input #1 output #1;
driven
without
reference
to
output reset_n;
reset();
output din;
clocking block
end
output frame_n;
output valid_n;
task reset();
...
router.reset_n <= 1’b0;
endclocking
modport TB(clocking cb, output reset_n);
router.cb.frame_n <= 16’hffff;
endinterface
router.cb.valid_n <= ~(’b0);
##2 router.cb.reset_n <= 1’b1; // reset_n can be both synchronous and asynchronous
repeat(15) @(router.cb);
Synchronous signals are
endtask
driven via clocking block
endprogram
Advance clock cycles via
clocking block
i- 19
Driving Synchronous Device Signals
[##num] interface.cb.signal <= <value> or <variable expression>;

Must be driven with <= (non-blocking assignment)

Can be specified with ##num of clocks delay
##1 router.cb.din[3] <= var_a;
Equivalent to:
repeat(num) @(router.cb);
router.din[3] <= #input_skew_value var_a;
clock
var_a
din[3]
Statement executes here
Variable expression evaluates
Apply drive here
Next statement executes
router.cb.din[3] = 1’b1; // error (must be non-blocking)
i- 20
Sampling Synchronous Device Signals
variable = interface.cb.signal;

No delay attribute (## num)

Variable is assigned the sampled value

Sampling of output signal is not allowed
Examples:
data[i]
= router.cb.dout[7];
all_data = router.cb.dout;
@(posedge router.cb.frameo_n[7]);
$display(“router.cb.din = %b\n”, router.din); //error
if(router.cb.din[3] == 1’b0) //error
i- 21
Advancing Simulation Time

Asynchronous (Verilog coding style):
#delay;
@(negedge interface.signal);

Synchronous (advancing clock cycles):

Verilog coding style:
@(posedge interface.clock_signal);
repeat (10) @(posedge interface.clock_signal);

SystemVerilog coding style (clocking block):
@(interface.clocking_block);
repeat (10) @(interface.clocking_block);

Each clocking block specifies a clock signal and edge:
interface router_io(input logic clock);
clocking cb @(posedge clock);
...
endclocking
endinterface
i- 22
Create SystemVerilog Harness File

Create harness file from router.test_top.v
mv router.test_top.v router.test_top.sv
Configure
module router_test_top;
parameter simulation_cycle = 100;
reg SystemClock ;
wire reset_n ;
wire clock ;
wire [15:0] frame_n ;
wire [15:0] valid_n ;
wire [15:0]
dinall; wire declarations
Delete
wire [15:0] dout ;
andbusy_n
all OpenVera
stuff
wire [15:0]
;
wire [15:0] valido_n ;
wire [15:0] frameo_n ;
`ifdef SYNOPSYS_NTB
...
`endif
router dut( … );
initial begin
SystemClock = 0 ;
forever begin
#(simulation_cycle/2)
SystemClock = ~SystemClock ;
end
end
router.test_top.sv
endmodule
Generator
Coverage
Transactor
Self Check
Transactor
Driver
Monitor
DUT
module router_test_top;
parameter simulation_cycle = 100;
reg SystemClock ;
router dut( … );
initial begin
SystemClock = 0 ;
forever begin
#(simulation_cycle/2)
SystemClock = ~SystemClock ;
end
end
router.test_top.sv
endmodule
i- 23
Complete Top Level Harness File

Instantiate test program and interface in harness file
router.test_top.sv
Instantiate
interface
Connect SystemClock
to interface block
module router_test_top;
module router_test_top;
parameter simulation_cycle = 100;
parameter simulation_cycle = 100;
reg SystemClock ;
reg SystemClock;
router dut(
router_io top_io(SystemClock);
.reset_n(reset_n),
router_test test(top_io);
.clock(clock),
router dut(.reset_n(top_io.reset_n),
Instantiate
.frame_n(frame_n),
.clock(top_io.clock),
.valid_n(valid_n),
test program
.frame_n(top_io.frame_n),
.din(din),
.valid_n(top_io.valid_n),
.dout(dout),
.din(top_io.din),
Update DUT
.busy_n(busy_n),
.dout(top_io.dout),
instantiation using
.valido_n(valido_n),
.busy_n(top_io.busy_n),
.frameo_n(frameo_n)); interface connection
.valido_n(top_io.valido_n),
initial begin
.frameo_n(top_io.frameo_n));
SystemClock = 0 ;
initial begin
forever begin
SystemClock = 0 ;
#(simulation_cycle/2)
forever begin
SystemClock = ~SystemClock ;
#(simulation_cycle/2)
end
SystemClock = ~SystemClock ;
end
end
endmodule
end
endmodule
i- 24
Compile RTL & Simulate w/ VCS NTB
Configure
router.tb.sv
Generator
Coverage
Transactor
Self Check
Driver
Transactor
router.test_top.sv
Monitor
router.if.sv
DUT

router.v
Compile HDL code: (generate simv simulation binary)
> vcs –sverilog [-debug]
router.test_top.sv \
router.tb.sv router.if.sv router.v
Get vcs compiler switch summary:
> vcs -help


Simulate DUT with SystemVerilog testbench: (running simv)
> ./simv
i- 25