Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
21 views

Aimp Verilog - Notes

- Continuous assignments in Verilog are always active and continuously update signal values based on expressions, unlike procedural assignments which execute sequentially. Wires are continuously driven to reflect the dynamic nature of digital circuits. - Behavioral models use procedural blocks like always and initial blocks and declare outputs as reg variables. Structural models instantiate gates and connect them to model digital circuits. Switch level models represent circuits using transistors.

Uploaded by

Ullas Farm
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
21 views

Aimp Verilog - Notes

- Continuous assignments in Verilog are always active and continuously update signal values based on expressions, unlike procedural assignments which execute sequentially. Wires are continuously driven to reflect the dynamic nature of digital circuits. - Behavioral models use procedural blocks like always and initial blocks and declare outputs as reg variables. Structural models instantiate gates and connect them to model digital circuits. Switch level models represent circuits using transistors.

Uploaded by

Ullas Farm
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 31

// 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

You might also like