// 04 Nov
Always remember that
- data flow
- continuos assignment
Continuous assignment in Verilog is a way to continuously drive a value
onto a wire. Unlike procedural assignments (which are executed in a sequence),
continuous assignments are always active and continuously update the values of
signals based on the expressions specified.
- assign
- wires driven continuously
Wires driven continuously" implies that the values on these wires are
constantly updated based on continuous assignments, reflecting the dynamic nature
of digital circuits.
- so we don't use reg at the output
- behavioural
- procedural block
- always block
- initial block
- for output reg variable is declared
- Structural / gate
- we actually deal with primitive gates ( in built )
- Ex : and , or , not , nand , xor , nor , exnor
- we also can instantiate
- possible
- Syntax for using primitive gates
and a1 (Destination,Source);
and -> name of the gate
a1 -> instance name
Destination-o/p
Source-i/p
- Switch level
- Transistors
We are not going to deal ?
- Millions of transistors we can't handle?
// Data flow level
// By default all the variables are wires
//wires are continuously driven
module ha(a,b,sum,carry);// input , output ? No
input a,b;// a and b are wires -> signal
output sum,carry; // when wire ? when reg ?
assign {carry,sum}=a+b;
endmodule
// Behavioural level
module ha (a,b,sum,carry);
input a,b;
output reg sum,carry;
always @ ( )//always @(*)// Vaibhav will answer
begin
sum=a^b;
carry=a&b; // try {carry,sum}=a+b; Assignment
end
endmodule
Compile error :- no arguments , syntax error
// Structural
module hs(a,b,sum,carry);
input a,b;
output sum,carry;
xor x1 (sum,a,b);
and a1 (carry,a,b);
endmodule
a=1'b1;// 1
b=1'b1;// 1
{a,b} = 2'b11; // 11
$random = generate 32 bit random values
{a,b} = $random;
// 05 Nov
Verilog Basics
Necessity
- To model hardware ?
- Why can't we code or design using any other languages like c,c++ ?
- clk , that's where we are failing to model using any other languages (c++ ,
c ,python ,ruby , j ava)
What do we model in Verilog?
- Digital circuits
- Combinational
- Sequential
// 2 ways of using comment
What is comment ?
- Not read by compiler
- A single line comment starts with // and tells Verilog compiler to treat
everything after this po in t to the end of the line as a comment.
- A multiple-line comment starts with /* and ends with */ and cannot be nested
assign {a,b}=c+d; // {a,b}=c+d , here we are getting to know the functionality
/* This is verilog language , everyone please focus , Learn everything completely
and try to design circuits and come up with the code */
/ -> forward slash
\ -> backward slash
- Verilog value set
0 , 1 , x ,z ?
0 -> -logic low
-false condition
-ground
-swicth off
1 -> -logic high
-true condition
-Vcc
-swicth on
x -> -Unknown ( either 0 or 1)
-Metastable condition
- based on what?
-setup and hold time
-everyone should go through the pdf , which I've sent and
should let me know by tomorrow.
z -> -High impedance level (High resistance with min current flow)
-float condition (we have port , if port is neither driven by 1 nor 0)
-open wire (nothing is connected)
- Data types
-Net
- wire
- default value z
- Why z
- open wire , high impedance
- wand
- U should understand either by going through youtube or anywhere else
wand -> wire and
why do we use?
- whenever we have circuits with anded behaviour
- whenever we have 2 signals that has to be given to to an i/p
- we and it and we give
wand Y ; // Y-> output
assign Y = A;
assign Y = B;
- wor
- U should understand either by going through youtube or anywhere else
wor -> wired or
wor Y;
assign Y=A;
assign Y=B;
- tri
- tri Y;
- assign Y = (ctrl) ? A : z;
-Reg
- reg
- default value is x
-> reg will not be knowing the value (0 or 1)
- integer
- signed ( acn take up +ve and -ve )
- 32 bit value
- default value x
- real
- holds decimal point
- default value 0
- time
- 64 bit value
- unsigned
- default value is x
- $time - > indicates what? -> Current simulation time
- string
- what is string
- stores characters in " " (double quotes)
- reg [8*5:1] name ;
initial
begin
name = "vlsi";
- Formula is for vector length
| [MSB - LSB] | + 1
- System Tasks
$display
$monitor
$value$plusargs
$finish
$stop
$strobe
$write
$random
$urandom_range
$time
Nested condition
- if ()
-if ()
- else if ()
- else
- else
-if()
-else()
// 7/11/22
- Literals
- Rules to assign values to a variable
integer a = 32'h0;//correct
integer a=h;//wrong
reg [8*1] name;
name = "V";//yes
name = "v";//yes
name = v;//No
- Identifier
name_a;//yes
123_name;//no
$_name;//no
- Keywords
reg , wire
- Vectors
- WHAT IS THE NEED OF VECTOR?
FOR MULTI BIT REPRESENTATION
- wire a0;
- wire a1;
- wire a2;
- wire a3;
- wire a4;
- wire a5;
// instead
wire [6:1]a; // or wire [5:0]a;
LHS <variable_name> -> vector
- MSB - 6
- LSB - 1
wire [1:6]a;
- MSB - 1
- LSB - 6
-reg [13:1]a;
- bits ? -> |MSB-LSB|+1 = |13-1|+1=13 bits
- reg [-3:-1]a;
- bits? -> 3 bits
WHich is MSB
-> -3
Which is LSB
-> -1
- reg [3:1]a;
- bits -> 3 bits
MSB -> 3
LSB -> 1
- reg [0:3];
Bits -> 4 bits
MSB - 0
LSB - 3
- reg [3:0];
Bits -> 4 bits
MSB - 3
LSB - 0
- wire [3:0]a;
- 4 wires - 4 bits
- Copy one vector value to another vector
-> reg [3:0]a;
-> reg [14:1]b;//14 bits
a=4'b1111;//4'b1111
- replicate -> repeat
b=a;//copy value of a to b whole vector copy
output :- b= 00_0000_0000_1111
b[14:11]=a;//4 bits ill be copied , other bits will be having x
output :- b= 11_11xx_xxxx_xxxx
- Vector slicing
-> b[10:7]=a[3:1];//possible? -> yes
output -> b = xx_xx01_11xx_xxxx
- Parameters
parameter WIDTH = 12;
generalisation of a constant
- assigned b/w module and endmodule
reg [WIDTH-1:0]a;
WIDTH = 50
reg [50-1:0]a;
// WIDTH--> 30,56,17...ect
- Arrays
- Syntax
<data_type><name_array><[]>
- array can be declared using following data types:-
- reg
-> Ex : reg a[1:0];
-> Ex : reg a[1:0][1:0];
-> Ex : reg [1:0] a [1:0];
-> Ex : reg [1:0] a [1:0][1:0];
- integer
-> Ex : integer a[1:0];
-> Ex : integer a[1:0][1:0];
- wire
-> Ex : wire a[1:0];
-> Ex : wire a[1:0][1:0];
-> Ex : wire [1:0] a [1:0];
-> Ex : wire [1:0] a [1:0][1:0];
- real
-> Ex : real a[1:0];
-> Ex : real a[1:0][1:0];
-> Which is the best data type to declare array?
-> reg
-> Why?
-> register -> hold the value
-> memory -> hold the value
-> calculation -> size = width X depth
parameterisable memory -> WIDTH , DEPTH => generic code , where
in any people should be able to understand the code and perform according to their
reqirements
-> integer a[1:0] ;// array -> memory -> 32 bits of 2 locations
-> is this a parameterisable
-> real ? // parameterisable -> memory // non synthesizable and also
not possible
Ex :
parameter DEPTH = 10;
real a[DEPTH-1:0];// 64 bits , 10 locations
I'm a new user , I refering to ur code , checking the
possible conditions
50 locations
parameter DEPTH = 50;
real a[DEPTH-1:0];// 10 bits -> width , 50 locations // error
- reg arr[10:0];
- arr[0] will hold a single bit?
<variable_name>RHS
- arr[0] -> this is the way of accessing
- reg arr[DEPTH-1:0];//single dimension
- Why?
-> one index at RHS
- reg [1:0]arr[1:0];
- arr[0] -> how many bits-> 2 bits
- arr[1] -> 2 bits
- Multi - Dimensional array
-Ex : reg [1:0]a[5:0];// single dimension
-Ex : reg [1:0]a[5:0][1:0];// two dimension
- Memory
parameter WIDTH = 4;
or
parameter width = 4;
parameter DEPTH = 5;
- reg [WIDTH-1:0]arr[DEPTH-1:0];
// reg [4-1:0]arr[5-1:0];
reg [3:0]arr[4:0]
DEPTH -> Array
WIDTH -> Vector
-> parameter is constant within the module (b/w module and endmodule)
-> Parameter overriding
-> 3 types
-> # -> represents the overriding of parameter
-> override by name
Ex:-
module eg1();
parameter size = 10;//size=10
initial
begin
$display("size=%0d",size);
end
endmodule
module design();
eg1 #(.size(30)) i1();//now the eg1 size=30
eg1 #(.size(15)) i2();//size =15
eg1 i3() ;//size =10
endmodule
-> override by position / order
Ex :-
module eg1();
parameter size = 10;//size=10
initial
begin
$display("size=%0d",size);
end
endmodule
module design();
eg1 #(30) i1();//now the eg1 size=30
eg1 #(15) i2();//size =15
eg1 i3() ;//size =10
endmodule
-> override by defparam -> follow the hierarchy to access the
parameters
Ex :-
module eg1();
parameter size = 10;//size=10
initial
begin
$display("size=%0d",size);
end
endmodule
module design();
deparam eg1.size = 100;
endmodule
- declare a memory of 1Kb depth , width is of 1 bit
- reg arr[1:1024];
- declare a memory of Depth 2KB , width is of 1 byte
- 1 byte -> 8 bits
- reg [7:0]mem[0:2047];
size = WxD
size = 8*2048
size = 16384
- declare a memory size 2kB, with width is 1 byte
B-> byte
b -> bit
2kB => 2048 * 8 = 2**11 x 2**3 => 2**14
size = WxD
size = 2**14
width = 2*3
depth = ?
depth = size/width
depth = 2**11 x 2**3 / 2**3
depth = 2**11
- reg [7:0]mem[0:2047];
- declare a memory of size 5kB with depth 5 bytes , width?
- declare a memory of size 5kB with width 5 bytes , depth ?
- declare a memory of depth 5 bytes , width 8 bytes , size ?
-> $display () -> display the current value irrespective of changes in i/p's
-> $monitor () -> display the current value respective of changes in i/p's
// functionality c= a+b;
initial
begin
-> based on changing the sensitivity , it will display
repeat(10)
begin
{a,b}=$random; // 32 bits
#1;
$display();
end
// $monitor("a=%0d , b=%0d , c=%0d",a,b,c);
end
-
// 08/11/2022
- Scalar and Vector
- Single bit varibales : Scalar
- wire a; // a will hold either 0 , 1 , x , z , single bit
- reg a;// will hold 0 , 1 x, z in just a , single bit
- Multi bit variables : Vectors
- wire [1:0]a;//2 bits
- Why
a0 , a1 // two bits
-00,01,10,11
- reg [1:0]a;// 2bits
- 0,1,z,x
Almost all Verilog data types are 4-state, which means they can take on 4 values:
0 , 1 , x ,z
- Bit Select
- selcting a single bit position in a vector and assigning value
Ex : reg [31:0]addr;
bit select -> addr[1]=0;
- Part Select
- Selecting a multiple bit positions and assigning a value
- Ex -> reg [31:0]addr;
part select -> addr[15:7]=9'hAB;
- Working with Vector
make all the bits of vector to x
- assume 8 bits and make all bits hold x value
Ex : reg [7:0]data;
data=8'hx;
- make all 0
addr = 'b0;
- make all z
addr = 'bz;
- make all 1
reg [31:0]addr;
addr = 32'b1;//this way??? -> Try this
32'b111111111111111111..... ????? ->
$display("%/1d");
what is to be done?
addr = {32{1'b1}};32 times 1'b1
32'b1111111111111111111111111111
- Vector to Vector value Assignment
reg a,b;
- {a,b} =$random;//$random -> 32 bits
-> remember me to code and show
-> (LHS > 0r <) =>( RHS > or <)
-> vect_a = vect_b;
* -> Generate 64 bit random value ??
{a,b}={$random,$random};
* reg[-3:3]a,reg[7:1]b;//same vector size
a -> how many bits? -> 7 bits
b -> 7 bits
* assume a=b;//copy b (contents) to a
* What's the mapping of individual positions??
-> a[3]=b[1] ; // the value of b[1] position will get
copied to a[3] position
-> a[2]=b[2];
-> a[1]=b[3];
-> a[0]=b[4];
-> a[-1]=b[5];
-> a[-2]=b[6];
-> a[-3]=b[7];
reg [1:6]a , reg [1:3]b;// different vector size
-> a-> 6 , b-> 3
a[6]=b[3];
a[5]=b[2];
a[4]=b[1];
a[3]= 0;
a[2]= 0;
a[1]= 0;
a[0]= 0;
*- Vector Slice Management
- reg [1:0]busA;
- reg [5:1]busB;
assume -> copy -> busA[1:0]=busB[5:1];//copy happens by position not by
index
busA[0]=busB[1];
busA[1]=busB[2];
*- Vector Operations
- Arithmetic operations
reg [4:0]busA;
reg [2:0]busB;
reg [9:0]busC;
busC= busA * busB;
-> a=32'hFFFF_FFFF;
-> b=32'hABCD_FFFF;
-> a && b;//logical
-> b = ~& a;//
- Operators
-> operators - & , ^ , !
-> operands -> inputs (Ex: a, b)
- Arithmetic
-> +, -, *, /, %, **
- Logical
-> &&, ||, !
-> logically true(1) or false(0) or unknown (x)
- Bitwise
-> & , | , ~ , ^ , ~^
-> bit by bit operations
- Unary reduction
-> & , | , ^ , ~^ , ~& , ~|
-> single operator , operand
- Shift operators
-> << , >> , >>> , <<<
-> arithmetic right shift -> / 2 (divide by 2)
-> arithmetic left shift -> x 2 (multiply by 2)
- Concatenation operator
-> {}
- Replication operator
->{n{}}
- Relational
-> return 0,1,x
- Equality
-> Logical (== , !=) -> return 0,1,x
-> case (===,!==) -> 0,1
- Conditional(Ternary)
-> Y=sel?A:B;
-> Operator Precedence
-> unary operator
Ex : y = a && c &d;
-> which will be evaluated first -> &d
- Difference b/w Vector and Array
- Vector -> No of bits to be stored {WIDTH}
- Vector is written in the LHS of variable
- Stores everything in single location
reg [31:0]a;
Ex:- a = 32'hABCD_FFFF;//everybit written in a single location
- bit and part selcect in vector
reg [2:0]a;
a[1]=1;//bit select
reg [2:1]=2'b01;//part select
- Array -> Location {DEPTH}
- Array is written in the RHS of variable
- Stores each array in multiple locations
reg a[3:0];
a = 20;// not work in array
Ex; a[0] = 1 bit;// 1 location
a[1] = 1 bit;//1 location
a[2] = 1 bit;// 1 location
a[3] = 1 bit;//1 location
reg [31:0] a[3:0];
a[0]=32 bits
a[1]= 32 bits
Ex:
reg [31:0] temp;
temp1= 20;
temp= 20;
temp =30;
Can I Store the values
temp[1]=20;
temp[2]=30;
temp[31]=40;
avg =
- we don't have any slicing like bit / part select
a[0]
a[1]
a[2]
a[3:2]=a[1:0];// not possible
- We have dimensions in array
- Real time example -> memory
- Vector , all bits are stored in same address location
- vector we'll store all the bits in single location
- reg [1:0]vec_a =2'b0; //??00
- reg [2:3]vec_b;
vec_b=vec_a;
-> we have 1 addr
reg [31:0]addr1;
addr1 = 32'hABCD;
reg [31:0]addr2;
addr2 = 32'hEEEG;
- array , we'll store in different location
reg [1:0] arr[1:0];//memory
-> arr[0]= 2 bits
-> arr = 100;//this will not work
- Limitations of array
- Can't access multiple array indices at the same time,array slices or
entire array at once
reg [1:0]mem[10:0]
array -> 11 location
vector -> 2 bits
Ex :- mem[10:8]--> not possible since we are accessing 3 indices
at a time.
Tool commands
-> quit -sim // quit simulation
-> cd -> change directory
-> pwd -> present working directory
-> cd ..-> go back to one location backwards
-> do run.do ->
run.do
-> The file contains all these
-> vlog ts.v -> compilation , i'll have to give name of testbench
file
vsim ts // elaboration , i'll have to give module name
add wave * // add the waveform
run -all // simulation ,run till the end of simulation
vlog tst.v
vsim -novopt -suppress 12110 tst
add wave -position insertpoint sim:/tst/*
run -all
- Compiler Directives
- `define
- define text macros in verilog
Ex: -
`define WIDTH 50 ->global scope -> check this and let me know
-> define -> this in the module
-> outside the module
`define WIDTH 50
module ha(a,b,s,c);
parameter WIDTH = 50;->within the module
input [WIDTH-1:0]a,b; // a is of size WIDTH-1 : 0 and b is also
WIDTH-1:0
output reg [WIDTH-1:0]sum;
reg c;
always@(*)
begin
{c,s}=a+b;
end
endmodule
- `include
- Ex :- I have to include ha.v file in my test bench file
`include "ha.v"
Arrays
-> reg , wire , integer , real
Ex : reg a[1:0];//each location will hold how many bits -> 1
Ex : wire a[1:0];
Ex : integer a[1:0];// since integer is of 32 bits , each location will
hold 32 bits
Ex : real a[1:0];//floating values can be stored , how many bits? -> 64
or 1 bit
-> single dimension array
Ex : reg a[3:0];//4 locations with 1 bit storing capability
Ex : reg a[0];// 1 location with 1 bit storing capability
-> two dimensional array
Ex : reg a[3:0][1:0];
-> memory -> array of vectors
-> reg [WIDTH-1:0]mem[DEPTH-1:0];
Ex : reg [3:0]a[1:0];//single dimension memory
Ex : reg [3:0]a[1:0][1:0];//two dimensional memory
-> Statement , Expression , Process
-> Statement -> any sentence ending with semicolon(;)
Ex : #5;//single statement
Ex : a=10;
Ex : $display("");
-> Expression -> Including some operations , some functionality
Ex : y = a&b;//whole will be statement
a&b -> expression
-> Process -> sentences b/w begin and end
Ex : begin : Process one -> P1
#10;
a = b + c;
$display("");//empty line
$display("a=%0d",a);
end
begin : Process two -> P2
b = 10;
#5;
$display("b=%0d",b);
end
begin : Process 3 -> P3
begin : P3.1
end
begin : P3.2
end
end
-> Seed in random
-> To generate same random number pattern in all runs , then use the same
seed
Ex : $random();
1st time -> generate some 32 bits = 2560 => o/p checked
2nd time -> generate some 32 bits = 2560 => o/p checked
seed=1234
seed=1256798
Ex : $random(seed)
seed=234567457
1st time -> generate some 32 bits = 2789 => o/p checked
seed=12345678
2nd time -> generate some 32 bist = 12378 => o/p checked
-> seed will always be of integer data type
-> integer seed ; //seed identifier
-> integer randing;//can this become a seed -> yes
$random(randing);//possible
-> check for other data types //not done
-> it works with integer , reg , real , time
-> Hierarchical structure
-> Top module
-> submodules
-> lowest modules
-> If you code from Top to bottom -> Top-down approach
-> If you code from bottom to Top -> Bottom-up approach
-> casex and casez statements
->casex
-Treats x,?,z as don't cares (x) -> Pg-134
->casez
-Treats ?,z as don't cares(x)
-> Multiplication using shift logic
Ex: 65*37 => 2405
-> 65 => 64 + 1 => 2**6 + 1
-> 37 => reamins same
=> (2**6 + 1)*37
=> 2**6 X 37 + 2**0 X 37
=> check the powers , according to power ,left shift the value
-> 2**6 X 37
-> since 6 is power , left shift 37 value by 6 positions
-> if 37 = 100101
-> shift by 6 positions (left)
-> 100101_000000
-> 2**0 X 37
-> since 0 is power , no shift
-> if 37 = 100101
-> since no shift
-> 100101
-> add all the bits
100101_000000
+ 100101
-> 100101_100101 => 2405
-> Verilog Assign Statement
-> 2 types of assign statement
-> Implicit Continuous Assignment
-> wire out = a+b;//produce the same o/p
-> Explicit Continuous Assignment
-> assign out = a+b;//produce the same o/p
-> Replication
-> Syntax -> {n{value}} //-> n-> number of time that u wanna replicate
-> Can I replace n by a varibale
-> Not possible
-> Can I replace value by a variable
-> yes
-> Ex : {6{1'b1}} => 6'b111111
-> Nested Replication
{2{a}} => simple replication
{{2{a}},{10{b}},{11{c}}}=> nested replication
-> Verilog always block
-> always block executes sequentially (block the current statement until it
completes)
-> Syntax
-> always @(sensitivity)
begin
statement1;
statement2;
end
-> What is sensitivity list?
-> sensitivity list is list of events that should be given insiside
the paranthesis of always block
-> Ex : always @ (a or b)
statement;
-> What is the always block used for?
if we have multiple always block
-> if u have multiple always block they'll start the execution
concurrently but the statments inside always block will be executing sequentially.
-> they'll start the execution at the simulation time 0
-> always block will execute multiple times (continuously
checking for sensitivity)
Ex ;
always @(*)
begin
statement1;//sequentially
$display();//
$monitor();//no
$strobe();//check
$write();//check
end
always @(*)
statement2;
always @(*)
statement3;
-> Verilog initial block
-> Syntax
initial
begin
a=10;
b=20;
$display();
$monitor();
$strobe();
$write();
end
-> multiple initial blocks start running concurrently , but inside each of
the initial block it executes sequentially
-> Initial will also execute at simulation time 0
-> Initial block will execute once
-> What is the initial block used for?
-> When does an initial block start and end?
-> What happens if there's a delay
-> How many initial blocks are allowed in a module?
-> Verilog generate block
-> Generate :- Allows us to do multiple instantiations , conditional
execution
-> Cannot contain -> ports , parameters
-> Is generate similar to module ?
-> No -> because module has ports but generate doesn't have ports
-> Is generate synthesizable ?
-> Yes
Syntax :-
generate
for_loop ();
if_else();
case();
endgenerate
-> Generate if
-> When to use this ?
-> It will be used while dealing with any abstraction of
same/different combinational circuits
syntax: generate
if(condition)
statement1;
else
statement2;
endgenerate
-> Generate case
-> When to use
-> It will be used while dealing with any abstraction of
same/different combinational circuits
syntax: generate
case(condition)
0:statement1;
1:statement2;
endgenerate
-> Generate for loop
syntax: genvar i;
generate
for(i=0;i<N;i=i+1)
statements;
endgenerate
-> Genvar is a construct in verilog used for code
replication(repeatation)
-> It's the only way to use for loop outside always and
initial block
-> By writing genvar , we are informing the compiler to
replicate the cod e before compilation
-> Task and function
-> Task
-> Important points to consider in task
- Task may not be defined inside procedural blocks
- A task invocation is a statement itself.It can't be used as an
operand in an expressio n
- Ex a = fd_write();// not possible -> since no return type
- Task doesn't return any value
- Time consuming construct
- If code has delay causing statements , it should be implemented
as task only
- Task may have zero or more arguments
- Arguments can be input,output,inout
- Task is usually non-synthesizable
- But we can make it sythesizable , if all the lines inside
the task are synthesizable
- Task can call another task , function
-> Ex where task is defined inside initial block -> Not possible
initial
begin
task display();//zero arguments
begin
$display("James_Bond");
end
endtask
display();//no arguments
end
-> Syntax :-
task name_task(ports can be i/p,inout,o/p);
begin
statement1;
statement2;
end
endtask
-> Static task
-> Static =>Fixed allocation of memory
-> By default -> task is static (fixed allocation) and also
function is static
task name_task ();
statement1;
endtask
-> Automatic task
-> Automatic => Variable allocation
task automatic name_task ();
statement1;
endtask
-> Global task
-> Task declared globally outside module
Ex :
task print();
$display("Displaying");
endtask
module tst;
initial
begin
print();//invocation of global task
end
endmodule
-> Not a global task then how to access? ->
If it's a Local task => can be accessed within the module
and also inside the other module as well
Ex : module tst;
initial
begin
print();
end
task print();
$display("Displaying");
entask
endmodule
module tst1;
tst u0 ();//instance of tst module
initial
begin
u0.print();
end
endmodule
-> Disable task
module tst;
initial
begin
display();
end
task display();
begin:L1
$display("Process#1");
end
begin:L2
$display("Process#2");
end
endtask
endmodule
module tst_i;
tst t0 ();
initial
begin
#10;
disable t0.display.L1;//disable L1 -> don't display
Process#1
end
endmodule
-> Simple task
A task can have the variables which are declared inside the
task , which are local to th e task , It can't be accesse outside the
task
-> Task using global varibales
A task can access the variables which are declared inside the
module , which are global to the task.
-> Calling a task
- Invocation of task
module
initial
begin
task_1();//calling a task or invocation of task
task_2();
end
endmodule
-> Function
-> Function declaration
Syntax :
function data_type name_of_function (input []
variable_name);
begin
name_of_function = variable_name +1;
end
endfunction
-> Important points to consider in function
- function may not be defined inside procedural blocks
- A function invocation is a statement itself.It can be used as
an operand in an express ion
- Ex a= fd_write();// possible -> since it'll have return type
- function returns any value
- Not Time consuming construct
- Executes at 0 simulation time
- delay causing statements ,can't be implemented as function only
- function will have atleat one input argument
- Arguments can be only input and the name of the function is the
output
- function is usually synthesizable
- Function can call another function but not task
-> Returning a value from function
->
module tst;
reg a;
initial
begin
a = name_of_function(10);//calling the
function and storing the return v alue
end
endmodule
-> Static function
-> Static =>Fixed allocation of memory
-> By default -> task is static (fixed allocation) and also
function is static
function name_of_function ();
statement1;
endfunction
-> Automatic function
-> Automatic => Variable allocation => whenevr the function is
called , memory get alloc ated
function automatic name_of_function ();
statement1;
endfunction
-> Recursive function -> a function calling itself
-> need to use automatic function
Ex : Factorial of a number
-> Function and Task
-> Can we use function and task inside a testbench ?
-> Yes , we can use.
-> Can we use function and task inside an RTL code ?
-> Yes , we can
-> Task should not have delays
-> Fullcase and Parallel case
-> Fullcase => define all the possible combination of inputs
-> Ex : Half adder
case({ab})
2'b00:begin sum=0; carry=0; end
2'b01:begin sum=1; carry=0; end
2'b10:begin sum=1; carry=0; end
2'b11:begin sum=0; carry=1; end
default : begin sum=x; carry=x; end
-> Parallel case => We can define two or more conditions in one
condition
-> Ex : Half adder
casex ({ab})
2'b0?:begin sum=b; carry=0; end
2'b1x:begin sum=~b; carry=b; end
default : begin sum=x; carry=x; end
-> Verilog code execution styles
-> Sequential execution
-> the statements are executed sequentially in the given
order
Ex :- initial
begin
#5;//#5ns
$display("Hi");//at 5ns Hi get's
displayed
$display("How r u");//at 5ns How r u
get's displayed
end
always @(posedge clk)
begin
q=d;//1st statement
a=b;//2nd statement
c=d;// 3rd statement
end
-> Parallel(concurrent) execution -> Fork - Join
-> All the statements will execute at same time or
simultaneously
initial
begin
fork
#5 $display("A");
#5 $display("B");
#9 $display("C");
join
end
-> In detail all modeling styles of verilog
-> Structural
-> Gate types -> from text book -> Pg 61
-> Buf/Not gate
-> Bufif/Notif
-> Gate delays
-> Rise time
- The change of input voltage from 10% to 90%
-> Fall time
- The change of input voltage from 90% to 10%
-> Turn off
- Transition to z from any values like 0,1,x
syntax : and #(rise,fall,turn_off) a1 (out,i2,i1);
-> Data flow
-> Continuous assignment -> Pg 86
-> Implicit assignment
Ex : wire y=a&b;
-> Explicit assignment
Ex : assign y=a&b;
-> Regular delay / Inter delay
-> The delay b/w the statements
Ex : a=10;
#5 c=5;
a=10;
#5;
c=5;
-> Implicit Continuous assignment delay / Intra delay
-> Delay which is present inside the statement
Ex : a = #5 10;
-> Net delay
-> wire with some delay
Ex : wire #5 y=a&b;
Ex : wire #5 b;
-> Behavioral -> 115
-> Two structured procedures
-> initial block
-> Starts execution at 0 simulation time
-> Executes only once
-> Non-synthesizable
-> If there are multiple initial blocks , all the blocks starts
execution at same time (concurrently) , but the process inside will run
sequentially
-> Only used in TB coding , can't be used inside RTL code
-> always block
-> Starts execution at 0 simulation time
-> Executes multiple times (looping fashion)
-> Synthesizable
-> If there are multiple initial blocks , all the blocks starts
execution at same time (concurrently) , but the process inside will run
sequentially
-> Used in RTL (which is synthesizable) , we can also use in TB
(but non-synthesizable)
-> You can't drive single signal inside single always and
multiple always block
Ex -> Generating a clock
Formulas:
- Timeperiod = 1/ frequency
- frequency = 1/ Timeperiod
- Duty cycle = Ton / Tp => Ton/Ton+Toff
Scenario -> If I have Timeperiod as 50ns , what will be the
frequency , duty cycle = 60%
-> frequency=20MHz
-> Ton = 30ns , Toff = 20ns
Scenario -> If I have a frequency of 500GHz , what will be
the timeperiod
-> Timeperiod=2ps
Ex :
// initially clk=0 , then clk=1
module tst;
reg clk;
initial
begin
clk=0;
#50 $finish;
end
always #5
clk=~clk;//Timeperiod = 10ns -> High time=5ns , Low time=5ns
// Frequency => 1/time period
=> 100Mhz
endmodule
// initially clk=1 , then
clk=0
module tst;
reg clk;
initial
begin
clk=1;
#50 $finish;
end
always #5
clk=~clk;//Timeperiod = 10ns -> High time=5ns , Low time=5ns
// Frequency => 1/time period
=> 100Mhz
endmodule
-> Blocking
-> Important points
- Statements which block the execution of next statement
until current statement is completed
- Blocking statement execution in one go
- Calculate the RHS expression
- Assign the expression value to LHS variable
immediately
Ex Q = a+b;
- Blocking assignment are suggested to use in combinational
circuit
Q1=d;//Q1 will get updated value of d
Q2=Q1;//Q2 will get updated value of Q1
Q3=Q2;//Q3 will get updated value of Q3
=> Q3=Q2=Q1=d ; //1 FF
Q1=d;
Q3=Q2;
Q2=Q1;//2ff's
Q3=Q2;
Q2=Q1;
Q1=d;//3ff's
-> Non-Blocking statements
-> Important points
- Statements which doesn't block the execution of next
statement.
Ex Q <= a+b;
- <= is called as non-blocking assignment
- Execution happens in 2 stages
-> Capture the RHS expression value into
temporary variable
-> Assign this temporary variable to LHS
variable at the end of the clock cycle
a=5
b=5
c=5
- It will assign a+b to a temporary variable
(ex :- Q_t) , Q_t will be assig ned to Q at the
end of the timestep
- Non-Blocking statements are suggested to use in
sequential circuits
Q1<=d;//Q1 will get old value of d
Q2<=Q1;//Q2 will get old value of Q1
Q3<=Q2;//Q3 will get old value of Q2
=> 3 FF's
Q1<=d;
Q3<=Q2;
Q2<=Q1;//3 Ff's
Q3<=Q2;
Q2<=Q1;
Q1<=d;//3 FF's
-> Verilog Assignments
-> Procedural
-> Variables (vector/scalar)
-> bit select/part select
-> concatenation
-> Continuous
-> nets (vector/scalar)
-> bit select/part select
-> concatenation
-> Procedural continuous
-> nets / varaibles (vector/scalar)
-> concatenation
- Two types
-> assign - deassign
Ex : always @(posedge Clk)
Cnt = Cnt + 1;
always @(Reset)
if (Reset)
assign Cnt = 0; // prevents
counting until Reset is 0
else
deassign Cnt; // resume
counting on next posedge Clk
initial
begin
#100 force Rst = 1'b0;
#200 release Rst;
end
-> force - release
Ex : Refer above example
Refer->
https://www.hdlworks.com/hdl_corner/verilog_ref/items/ProceduralContinuousAssignmen
t.htm
-> Verilog control blocks
-> for loop
-> while loop
-> If else
-> Nested if esle
-> case
-> repeat
-> forever
-> Verilog `ifdef and `elsif , `ifndef and `elsif
-> Compiler directives
-> Verilog delay control
-> Delay based
- Regular /Inter delay
- Intra delay
- Zero delay
-> Event control
- Regular event control
-> posedge
-> negedge
- Named event
-> event e;
-> Can be used in both TB and RTL
-> Edge sensitive
-> posedge clk
-> negedge clk
-> Level sensitive
-> wait
-> Verilog Hierarchical Reference
-> Accessing the variables that are in different module with help
of .(dot) operator
-> What is transparent latch
-> Whatever the i/ps , the same will be reflected to the o/p's
-> Ex : D Latch
-> What is gated latch
-> A latch with an enable signal
-> Synthesis example
-> Synthesis -> Converting RTL code to Gate level net list
-> Refer the pictures available in the folder called design examples
-> Regions in verilog
-> Active
-> Inactive
-> NBA
-> Monitored
-> Timescale -> 177
-> Timescale syntax:
`timescale <time_unit>/<time_precision>
or
`timescale <time_step>/<time_precision>
-> Timescale - Timescale specifies the time unit and time precision of a
module that follow it.
-> Timestep - This controls the step of time that the simulator uses to
determine what actions take place next (and/or simultaneously) and at what
resolution of incremental time passage.
-> Timeprecision -> Specifies the precision to which the delays are
rounded - off during simulation
-> Conclusion
At one Ex :- `timescale 100ns/100ns , or 10ns/10ns (this won't work
according to calculation), except 1ns/1ns (this works)
timestep should be greater than precision
-> System tasks and functions
- $display -> task
- $monitor -> task
- $strobe -> task
- $write -> task
- $time -> function
- $realtime -> function
- $stop -> task
- $finish -> task
- $random; -> function
- $urandom; -> function
- $urandom_range(); -> function
- $value$plusargs -> task
- $clog2 -> function
-> Backdoor access -> task
-> Simulation time 0 execution
-> Non-synthesizable
- $readmemh -> read from a file(file should have hex values) and write into
the locations
- $readmemb -> read from a file(files should have binary values) and write
into the locations
- $writememh -> write to file (in hexa) and read from locations
- $writememb -> write to file (in binary) and read from locations
-> Conversions -> function
- $itor -> integer to real
- $rtoi -> real to integer
- $realtobits
- $bitstoreal
-> File handling
- Handling the file with respect to open,close,display and work more
- $fopen,$fclose,$fmonitor,$fdisplay,$fstrobe,$fwrite
$fdisplay() Prints in decimal by default
$fdisplayb() Prints in binary
$fdisplayo() Prints in octal
$fdisplayh() Prints in hexadecimal
-> File handling -> Pg 179
-> File write -> open a file , initialise values , monitor to txt file
- $fopen -> open file
- $fclose -> close a file
- $fmonitor -> to monitor the values and write into a file
- $fdisplay -> to display the values , which are written into a file
-> Conversion system function
-> rtoi
-> itor
-> $realtobits
-> $bitstoreal
-> Compiler Directives
- `define
- `include
- `timescale
- `ifdef , elsif , endif
- `ifdef , else , endif
-> XMR(Cross module reference) -> Verilog Hierarchical Reference
-> Signal Strength
-> 3 types
- Driving -> 4 strngths
- supply,strong,pull,weak
- Capacitive
- large,medium,small
- High Impedance
- high
-> highz0
-> highz1
- Precedence
- supply,strong,pull,large,weak,medium,small,high
-> Strengths can be used to reslove which value should appear on net / gate o/p
Refer ->
https://peterfab.com/ref/verilog/verilog_renerta/mobile/source/vrg00047.htm
-> UDP -> Pg 229
-> Combinational UDP : UDP's are defined where the o/p is solely determined
by a logical combination of the inputs.
Ex : 4 to 1 MUX
-> Sequential UDP : UDP's take the value of the current ip/s and current op/s
to determine the value of the next output.The value of the o/p is also the internal
state of UDP.
Ex : Flipflops and Latches
-> Syntax : primitive name(out,in1,in2);
output out;
input in1,in2
table
0 0 : 0;
0 1 : 0;
1 0 : 0;
1 1 : 1;
endtable
endprimitive
-> Can have many inputs but one output
-> All the ports must be a single bit (1 bit) Scalar
-> Udp's are meant for modelling and not at all synthesizable.
-> Verilog good programming practices
- There should be default condition in condtional statements
- There should be separation b/w always block with blocking and non-blocking
- Multi driver error should be avoided
- All the ip/s and op/s must be declared in separate lines / new lines
- Comment for better understanding
- Make code parameterisable (Generic)
- We'll not have any logic for clk or rst or clear
- Importance of delay (drive same varibales without delay there comes a
confliction)
- It's better to write $monitor inside separate initial block
- Always check the waveform must for sequential
- Use run.do (a must)
- Labelling is important when there are multiple blocks
- Instantiating the propering name of the module
- Overriding (Parameter) with order is acceptable (more preferrable)
- Connection by name is more preferrable
- Before developing code, try to read the complete specification
- You can mix different abstractions
- Design a block diagram
- Use Gvim commands to code fast (very important).
- Develop skills of GVim(commands)
- Avoid incomplete specifications
- Proper Indentation
initial
begin
end
- Before running the code , check the code (check the syntaxes,data
type,input,output,functionality)
- Mention the proper data type for array , according to convinience
- Use proper verilog constructs
- Make the code sythesizable , If you are developing RTL code
- Usually don't prefer to use non-synthesizable constructs when you are
developing RTL code
-> Difference between `define and parameter (very important)
`define WIDTH 6
-> Can you override a `define (Compiler directive) ?
-> No
-> Globally declared
-> Yes
parameter WIDTH = 8
-> Can you override parameters?
-> Yes
-> Overriding methods
- override by name
- override by position/order
- override by defparam
-> Local to the module , can't declare a parameter outside module
-> Synthesizable and Non-Synthesizable code
-> Refer : https://asic-soc.blogspot.com/2013/06/synthesizable-and-non-
synthesizable.html#:~:text=Synthesizable%20and%20Non-Synthesizable%20Verilog
%20constructs%20%20%20,%20%20%20%2012%20more%20rows%20
- Synthesizable -> Any construct which has equivalent gate representation
- Non - Synthesizable -> Any construct which has no equivalent gate
representation