Advance Verilog
Concepts
Race Around Condition
• When two expressions are scheduled to
execute at same time, and if the order of the
execution is not determined, then race
condition occurs.
module race; module race;
reg out; reg out;
reg in; reg in;
initial initial
begin begin
in = 1; in = 1;
#1 out <= in; out <= in;
$display(out); $display(out);
end end
endmodule endmodule
Types Of Race Condition
1. Write-write Race
It occurs when same register is written in
both the blocks.
EXAMPLE:
always @(posedge clk)
a = 1;
always @(posedge clk)
a = 5;
2. Read-Write Race:
It occurs when same register is read in
one block and writes in another.
EXAMPLE:
always @(posedge clk)
a = 1;
always @(posedge clk)
b = a;
EXAMPLE : To remove race
always @(posedge clk)
a <= 1;
always @(posedge clk)
b <= a;
Testbench DUT race condition.
• In test bench , if driving is done at posedge
and sampling in DUT is done at the same
time , then there is race.
• To avoid this, write from the Testbench at
negedge or before the posedge of clock.
• This makes sure that the DUT samples the
signal without any race.
module testbench();
EXAMPLE:
module DUT(); DUT dut_i(d,clk,q);
input d;
input clock; initial
output q; begin
//@(posedge clk)
always @(posedge cloc @(negedge clk)
k) d = 1;
q = d; //@(posedge clock)
endmodule @(negedge clk)
d = 0;
end
endmodule
Guidelines to avoid race
condition
1. When modelling sequential logic,use
nonblocking assignments
2. When modelling latches, use nonblocking
assignments
3. When modelling combinational logic with
in an always block, use blocking
assignments
4. When modelling both sequentinal and
combinational logic within the same
always block, use non blocking
assignmnets
5. Donot mix blocking and nonblocking
assignments in the same always block
6. Do not make assignments to the same
variable from more than one always block
7. Use $strobe to display values that have
been assigned using nonblocking
assignments
8. Donot make assignments using #0 delays.
The Stratified Event Queue or Event
Timing Regions
Active
Region
Inactive Region
What is the final value of
a?
module test ;
reg a; Active Region
a=x
T1 a=0
initial a=0; //T1
initial #0 a=1; //T2 InActive Region
T2 a=1
Final value of a=1
endmodule
What is the output ?
module test;
reg a; Active region.
a=0;
initial a=0; InActive Region
$display executes ,a=0
initial begin
#0 $display(“ a=%b ”,a);
end
endmodule
NBA and postponed
regions
What is the output ?
module test; Active region
reg a,b; a=1;b=0;
Samples value of b in the active region.
Executes $display in the active region.
initial begin NBA Region
a=1;b=0; a=0; //final value of a
Schedules update of a in the NBA region.
a<=b;
$display("a=%0d b=%0d ",a,b);
end
endmodule Output of $display is:
a=1 b=0;
What is the output ?
module test;
reg [2:0] a; Active Region
a=1
NBA Region
a<=2
Postponed Region
initial begin $strobe(a)
$strobe ("Strobe a=%0d
",a);
a=1;
a<=2;
end
endmodule
What is the
output ?
module test;
reg [2:0] a;
initial $monitor (" a=%0d ",a);
Active Region
initial begin a=1
a=1;
a<=2; NBA Region
a<=2
end
endmodule Postponed Region
$monitor(a)
What is the output ?
module test;
reg a;
NBA Region
initial begin
a <= 0;
a <= 0; a <= 1;
a <= 1; Final value of a is 1
end
endmodule
module test1;
reg [1:0]a,b,c;
initial
begin
a = 1; //blocking //R1
$display($time,"D",a);//2 //R1
a <= 2; // nonblocking //R3
$monitor($time,"M",a);//R4
$strobe($time,"M",a);//R4
end
endmodule
module test2;
reg [1:0]a;
Initial begin:B1 //1. if it executes same time
//2. if it executes in same region
a=1;//R1 //3. if it happens to same variable
//4. different execution gives
end different outputs
initial begin:B2
a=2;//R1
end
initial $monitor(a);
endmodule
File Handling
The system tasks and functions for file based
operations are divided into four categories:
Tasks that open and close files.
Tasks that write output values into files.
Tasks that write output values into variables.
Tasks and functions that read values from
files and load into variables or memories.
Opening a file
Before writing to a file we need to open a file.
In order to open a file we have a task called $fopen.
Syntax:
<file_handle>=$fopen(“<name_of_file>”);
Ex: t1=$fopen(“abc.txt”);
Note:
Here ‘t1’ is a file handle(which should be declared as
integer in test bench) to access the file called
“abc.txt”.
Opening a file
$fopen generally used inside the initial block in
testbench.
Example:
module tb_add(); //testbench code start
reg [15:0] a;
reg [15:0] b;
wire [16:0] c;
adder DUT(a,b,c); //DUT Instantiation for adder design
integer t1;
initial
t1=$fopen(“abc.txt");
endmodule
Writing to a file
To write data into a file we have a task called $fdisplay.
Syntax:
$fdisplay(<file_handle>,”<data_name>”,<data>);
Ex:
repeat(100) begin //writing into file abc.txt
a = $random;
$fdisplay(t1,"a ",a);
end
Note:
Here ‘t1’ is a file handle to the file abc.txt data (i.e., a)will be shown in abc.txt file after
simulation.
Random number generated using system task are given to a for 100 times.
These 100 times “abc.txt” file will be written with random values of ‘a’.
Closing a file
After writing is over we have to close the file
properly otherwise data won’t be saved inside the
file.
To close a file we have a task called $fclose.
For every $fopen task there should be a $fclose task.
Syntax:
$fclose(<file_handle>);
Ex: $fclose(t1);
Example
module tb_add(); //TestBench code start
reg [15:0] a;
reg [15:0] b;
wire [16:0] c;
adder DUT(a,b,c); //DUT Instantiation of adder(c=a+b)
integer t1,t2,t3; // declaring file handlers for
//xyz.txt,abc.txt,iam.txt resp
initial
begin
t1=$fopen("xyz.txt");
t2=$fopen("abc.txt");
t3=$fopen("iam.txt");
//…contd in next slide
repeat(100)
begin
a = $random;
$fdisplay(t1,"a",a);
b = $random;
$fdisplay(t2,"b",b);
$fdisplay(t3,"c",c);
#10 $display(" a=%0d,b=%0d,c=%0d",a,b,c);
end
$fclose(t1);
$fclose(t2);
$fclose(t3);
End
end module
Initializing Memories
In verilog we can read some data from a file and
load to a specific memory.
Two tasks are there for this purpose :
$readmemb, $readmemh are used to initialize
the memories.
Syntax:
$readmemb(“file_name”,<memory_name>);
$readmemb(“file_name”,<memory_name>,<start
_addr>);
$readmemb(“file_name”,<memory_name>,<start
_addr>,<end_addr>);
Initializing Memories Example
module mem(); //main module starts
reg [7:0] memory[0:7]; //memory declaration
initial
begin
$readmemb(“init.txt”,memory); // read file which contains
binary values and store into memory
end
endmodule
Note:
Here init.txt contains the intialization data.
Addresses are specified in the file with @<address>.
Data is separated by white spaces from each other.
Initializing Memories Example
Example for writing initialization data file
----------------------------------
@0002//hexadecimal address
11111111 00000000//two data
01010101 10101010//next two data
-----------------------------------
It means from address location 0002, data are
available for initialization.
Different Types of Test Benches
1. Direct Test Bench
2. Randomization based Test Bench
3. Task Based Test Bench
4. File Based Test Bench
5. Self-Checking Test Bench
Direct Testbench or Linear
Testbench
initial
begin
# 10 wr = 0; address = 100 ; data = 10;
# 10 address = 101 ; data = 11;
# 10 address = 102 ; data = 12;
# 10 address = 103 ; data = 13;
# 10 address = 104 ; data = 14;
end
Randomization based Test Bench
initial
Begin
#10; wr = 0;
#10; addr = $random; data =
$random;
end
Task Based Testbench
task write (input reg[2:0] address,input reg[7:0]
data_in);
begin
@(posedge clk);
wr =0;
address = $random;
data_in = $random;
end
endtask
task read (input reg[2:0]
address,output reg[7:0]
data_in);
begin
@(posedge clk);
wr =1;
address = $random;
data_in = $random;
end
endtask
• Task calling
initial begin
repeat(10) begin
write($random,$random);
read($random,data_in);
end
end
File Based Testbench
initial begin
#10; rst = 0;
file1 = $fopen("mem_ram.txt"); // file opening
repeat(3) begin
wr = 0;
#10; address = $random;
#10; data_in = $random;
#100; wr = 1;
$fdisplay(file1,"address=%0h,data_in=%0h,wr =%0b",address,data_in,wr);
end
$readmemb("file1",ram);
$fclose(file1);
end
endmodule
Self- Checking TestBench
module dec_tb;
reg [2:0]a;
wire [7:0] y;
dec_dut uut (.a(a),.y(y));
reg [7:0] memory [0:7];
initial
begin
memory [0] = 00000001;
memory [1] = 00000010;
memory [2] = 00000100;
memory [3] = 00001000;
memory [4] = 00010000;
memory [5] = 00100000;
memory [6] = 01000000;
memory [7] = 10000000;
end
initial
begin
repeat(16)
begin
#10; a= $random;
end
end
always @(y)
begin
if (memory[a] == y )
$display("test case passed for a=%b,y=%b",a,y);
else
$display("test case passed for a=%b,y=%b",a,y);
end
endmodule
THANK YOU