System Verilog: Program Block & Interface

Download as pdf or txt
Download as pdf or txt
You are on page 1of 38

System Verilog

PROGRAM BLOCK & INTERFACE

ROHIT KHANNA
Program Block

 Verilog module works well for design but when used for Test
benches may lead to race-around condition between design and
Test bench.

 System Verilog adds program block which is used meant for


writing Test Bench.

 program and endprogram keywords are used to define a


program block.

System Verilog Program Block and Interface


Program Block

 program block has following features:


o They separate test benches from design unit.
o Statements are executed in Reactive Region.
o always blocks are not allowed in program block.
o They can be instantiated inside other modules.
o Instance of module or program block is not allowed inside
program block.
o They have access to variables present inside a module where they
are instantiated but vice versa is not true.
o Implicit system task $exit is called when program block terminates.

System Verilog Program Block and Interface


Program Block Region

Preponed Active

Test Bench runs once


Inactive
From Current Time Slot all design related
NBA activities are over.
Observed

Re-Active
Program Block
To Next Time Slot
Re-Inactive Runs Here

Postponed Re-NBA

System Verilog Program Block and Interface


Example1

module tb;
reg clk=0, t=1;
module tff (q, clk, t);
wire q=0;
input clk, t;
output reg q=0; always #5 clk=~clk;

tff u0 (q, clk, t);


always @ (posedge clk)
if(t) q<= ~ q; always @ (posedge clk)
endmodule $display($time, “q=%d”, q);

endmodule

System Verilog Program Block and Interface


Example1

Result:
5 q= 0
15 q= 1
25 q= 0
35 q= 1
45 q= 0
55 q= 1

System Verilog Program Block and Interface


Example2

program tb (input clk);


module
input clk, t; initial //always not allowed
output reg q=0; begin
forever @ (posedge clk)
always @ (posedge clk) $display($time, “q=%d”, q);
if(t) q<= ~ q; end
endmodule initial t=1;

endprogram

System Verilog Program Block and Interface


Example2

module top;
reg clk=0, t;
wire q;

always #5 clk=~clk;

tff u0 (q, clk, t);


tb u1 (clk); //program has access to t and q

endmodule

System Verilog Program Block and Interface


Example2

Result:
5 q= 1
15 q= 0
25 q= 1
35 q= 0
45 q= 1
55 q= 0

System Verilog Program Block and Interface


Example3

program tb;
int a;
initial $monitor(“result is %d”, a);
Result : result is 2
initial begin a=5
#3 a= a + 2;
#4 a= a + 3; $monitor does not execute for
end a=5 because of implicit $exit

endprogram

System Verilog Program Block and Interface


Example4

program tb;
int a;
initial $monitor(“result is %d”, a);

initial begin
#3 a= a + 2; Result :
#4 a= a + 3; result is 2
#1 ; result is 5
end

endprogram

System Verilog Program Block and Interface


Interface

 Interface is used to encapsulate communication between design


blocks, and between design and verification blocks.

 Encapsulating communication between blocks facilitates design


reuse. Interfaces can be accessed through ports as a single item.

 Signals can be added to and remove easily from an interface


without modifying any port list.

 Interface can contain the connectivity, synchronization, and


optionally, the functionality of the communication between two or
more blocks.

System Verilog Program Block and Interface


Design

module adder (input bit clk,


input logic [3:0] a, b,
output logic [4:0] sum);

always @ (posedge clk)


sum= a + b;

endmodule

System Verilog Program Block and Interface


Test Bench

program tb (input bit clk,


input logic [4:0] sum,
output logic [3:0] a, b);

initial
begin
$monitor (“a=%0d b=%0d sum=%0d”, a, b, sum);
forever begin a=$random; b=$random; #10; end
end

endprogram

System Verilog Program Block and Interface


Top Level

module top ();


bit clk=0;
Now in case you have to add one
logic [3:0] a, b; more input c, you have to define c
logic [4:0] sum; at three place adder, tb and top.

always #5 clk=~clk;

adder a0 (.*); //connect variables to ports that have


tb t0 (.*); // same name and same data type
endmodule

System Verilog Program Block and Interface


Defining Interface

interface intf (input bit clk);

logic [3:0] a, b;
logic [4:0] sum;

endinterface : inf

System Verilog Program Block and Interface


Design

module adder (intf inf);

always @ (posedge inf.clk)


inf.sum= inf.a + inf.b;

endmodule : adder

System Verilog Program Block and Interface


Test Bench

program tb (inft inf);

initial begin
$monitor (“a=%0d b=%0d sum=%0d”, inf.a, inf.b, inf.sum);
forever begin
inf.a=$random;
inf.b=$random;
#10; end
end

endprogram : tb

System Verilog Program Block and Interface


Top Level

module top ();


bit clk=0;

always #5 clk=~clk;

intf inf(clk); //inf is interface instance


adder a0 (inf);
tb t0 (inf);

endmodule

System Verilog Program Block and Interface


Modport

 modport construct is to used to provide direction information for


module ports.
interface intf (input bit clk);

logic [3:0] a, b;
logic [4:0] sum;
//incase of inout port use wire
modport DUT (input clk, a, b, output sum);
modport TB (input clk, sum, output a, b);

endinterface : intf
System Verilog Program Block and Interface
Design

module adder (intf.DUT inf);

always @ (posedge inf.clk)


inf.sum= inf.a + inf.b;

endmodule : adder

System Verilog Program Block and Interface


Test Bench

program tb (intf.TB inf);

initial begin
$monitor (“a=%0d b=%0d sum=%0d”, inf.a, inf.b, inf.sum);
forever begin
inf.a=$random;
inf.b=$random;
#10; end
end

endprogram : tb

System Verilog Program Block and Interface


Top Level

module top ();


bit clk=0;

always #5 clk=~clk;

intf i0 (.*);
adder a0 (.*);
tb t0 (.*);

endmodule

System Verilog Program Block and Interface


Clocking Block

 Clocking block construct identifies clock signals and captures the


timing and synchronization requirements of the blocks being
modeled.

 Clocking block assembles signals that are synchronous to a


particular clock and makes their timing explicit.

 Clocking block separates the timing and synchronization details


from the structural, functional, and procedural elements of a test
bench.

System Verilog Program Block and Interface


Clocking Block

 In case of synchronous circuits, input should be sampled just before


the clock and output should be driven just after the clock.

 So from test bench point of view, design outputs should be


sampled just before the clock and design inputs should be driven
just after the clock.

 By default design outputs are sampled at #1step (Prepone


Region) and design inputs are driven at #0 (Inactive /Re-Inactive
Region).

System Verilog Program Block and Interface


Clocking Block

interface intf(input bit clk);


…………
modport TB (input clk, clocking cb);
clocking cb @ (posedge clk); //specifying active clock edge
input sum; //sampled in prepone region
output a, b; //driven in inactive region
endclocking : cb //Directions w.r.t Test Bench
…………
endinterface

System Verilog Program Block and Interface


Clocking Block

Clk

en
Output of Test Bench

en

Output of Clocking Block / Input to DUT

System Verilog Program Block and Interface


Clocking Block

Clk

count 1 2 3 4 5 6 7

Output of DUT/ Input to Clocking Block

0 1 2 3 4 5 6
count
Input to Test Bench

System Verilog Program Block and Interface


Clocking Block

………………………
clocking cb @ (posedge clk); //specifying active clock edge
default input #3ns output #2ns;
//Specifying user default for sampling and driving

input sum, reset; //sampled 3ns before active clock edge


output a, b; //driven 2ns after active clock edge
endclocking : cb
…………………………

System Verilog Program Block and Interface


Clocking Block

………………………
clocking cb @ (posedge clk); //specifying active clock edge
default input #3ns output #2ns;
//Specifying user default for sampling and driving

input sum; //sampled 3ns before active clock edge


output a, b; //driven 2ns after active clock edge
input negedge reset; //Overriding default sampling for reset
endclocking : cb
…………………………

System Verilog Program Block and Interface


Interface

interface intf(input bit clk);


logic [3:0] count; logic en;

modport DUT (input clk, en, output count); //DUT


modport TB (input clk, clocking cb); //Test Bench

clocking cb @ (posedge clk); //Clocking Block


input count;
output en;
endclocking
endinterface

System Verilog Program Block and Interface


Design

module counter (intf.DUT inf);

always @ (posedge inf.clk)


if(inf.en)
inf.count+=1;

endmodule : counter

System Verilog Program Block and Interface


Test Bench

program tb (intf.TB inf);

initial begin
@inf.cb; //continue on active edge in cb
#3 inf.cb.en<=1; // use NBA for signals in cb
##8 inf.cb.en<=0; //wait for 8 active edges in cb
repeat(2) @inf.cb; //wait for 2 active edges in cb
inf.cb.en<=1;
wait (inf.cb.count==3) inf.cb.en<=0; //wait for count to become 3
end
endprogram : tb
System Verilog Program Block and Interface
Parameterized Interface

interface intf #(size=3, type typ=logic) (input bit clk);


typ [size-1:0] count;
typ en;

modport DUT (input clk, en, output count); //DUT


modport TB (input clk, count, output en); //Test Bench

endinterface

System Verilog Program Block and Interface


Virtual Interface

 A virtual interface is a variable that represents an interface


instance. This interface is not use to represent physical connections.

 Virtual interface variables can be passed as arguments to tasks,


and functions.

 Tasks and functions can modify variables present in a virtual


interface which has the same effect as accessing physical
interface.

 A virtual interface can be declared as class property, should be


initialize before usage.

System Verilog Program Block and Interface


Virtual Interface

interface intf (input bit clk);


logic req, gnt;

always @(posedge clk); //functionality inside interface


if(req) begin
repeat(2) @(posedge clk);
gnt<=1; end
else gnt<=0;
endinterface

System Verilog Program Block and Interface


Virtual Interface

task gen_req(virtual intf a);


module test;
@(posedge a.clk) a.req<=1;
bit clk=0;
@(posedge a.clk) a.req<=0;
always #5 clk=~clk;
repeat (5) @(posedge a.clk); a.req<=1;
intf inf(clk);
@(posedge a.clk) a.req<=0; endtask
initial
fork task rec_gnt(virtual intf b);
gen_req(inf); forever begin
rec_gnt(inf); @(posedge b.gnt)
join $display($time, “ grant asserted ”); end
endmodule endtask

System Verilog Program Block and Interface


Virtual Interface

class test; module top;


virtual intf t1 ; bit clk=0;
always #5 clk=~clk;
function new(virtual intf t2); intf inf(clk);
t1=t2; //initializing virtual test c1= new(inf);
//interface
initial fork
endfunction
c1.gen_req(inf);
//task gen_req(virtual intf a); c1.rec_gnt(inf);
//task rec_gnt(virtual intf b); join
endmodule
endclass
System Verilog Program Block and Interface

You might also like