0% found this document useful (0 votes)
3 views37 pages

System Verilog Notes: Basics To Advance

Download as pdf or txt
Download as pdf or txt
Download as pdf or txt
You are on page 1/ 37

SYSTEM VERILOG NOTES

BASICS TO ADVANCE
TYPES OF SIGNALS

Global Signal Control Signal

(CLK,RST) (raddr,waddr)

Data Signal

(rdata,wdata)

Fundamentals of procedural constructs:

Format of initial block in testbench:

Note : Always start the name of testbench with character.

There are two ways of implementing initial block

Single line Multiple Lines


Initial a=1; Initial begin
a=1;
#10;
a=0;
end

Initial start execution at 0nsec(Start of the simulation).

Initial block is executed once only.

For example here,

Even if the span of this initial block is over i.e we change


a from 1 to 0, but still it will hold the value till end of
simulation because of reg.

Where we work with reg(it holds the value)when


execution is over the reg variable still stores the value till
the end of simulation.
Usage of Initial block:

1) Adding control statement to block that helps us to enable waveform viewer( System task
at the start of simulation).

Sends value to console


whenever there is a change of
value.

2) Most important usage → Initialize a variable

3) Random signal for data control

Random waveform for a multibit signal this we will predominantly using with a verification env.
10 x 1ns

4) Stop simulation forcefully by calling $finish.

ALWAYS BLOCK
- Combinational ckts → always@(a,b)

Our system in sensitive to all inputs

- Sequential ckts → always@(posedge clk)

Our system is sensitive to clock signal.

Usage of Always block → Executing / evaluating expression till the end of simulation.

1. Generate clock
10ns
=5
2

Half clock period


Handling Phase differences between clocks

We have phase differences in this clock how we will handle these


Understanding timescale directive :
16 Mhz → period = 62.5 → Half period = 31.25ns

8 Mhz → period = 125nsec → Half period =62.25ns

`timescale 1ns / 1ns Time precision(TP)

Time Unit(TU)

#5 → 5 * time unit → 5 * 1ns =5ns

𝑇𝑈 Number of precision
= 1 = 100 digits, We can’t use
𝑇𝑃
floating point

#10.1 → 10

#10.6 → 11 This will happen when we specify floating point


number and no precision bit available.

Understanding `timescale 1ns/1ps

We can have 3
𝑇𝑈 10−9 digits after decimal
= −12 = 103
𝑇𝑃 10
Understanding parameters for generating clock :

Ton
𝐷𝑢𝑡𝑦 𝑐𝑦𝑐𝑙𝑒 =
Ton + Toff

Factors contributing to clock generation


1. Frequency
2. Duty cycle
3. Phase difference

Period = 1/freq
real period → nsec

𝑟𝑒𝑎𝑙 𝑇𝑜𝑛 = 𝑝𝑒𝑟𝑖𝑜𝑑 ∗ (𝐷𝑢𝑡𝑦 𝑐𝑦𝑐𝑙𝑒)/100

𝑟𝑒𝑎𝑙 𝑇𝑜𝑓𝑓 = 𝑝𝑒𝑟𝑖𝑜𝑑 − 𝑇𝑜𝑛


Data types

reg
Hardware

wire

Fixed

Variable
DATA TYPES Floating

Real time

Simulation

Fixed point time

2 state

Fixed

4 state
Variable

Floating
Declaring various data types

Variables

signed Unsigned

8-bit → byte
16-bit→ short int
32-bit→int
64-bit→long int
$time

$realtime

REG AND WIRE

Here in procedural construct reg is working fine with no error

But if we change to wire….


It gives error

If we use logic here…

Cin

Sout

a
S

Half
Half Adder
Adder C

b Cout
OR
Following will be declared within the Full adder module.

➔ Cin
➔ a
➔ b
➔ Sout
➔ Cout

Marked with green will not be declared within module.

Whenever with a module we have to connect the blocks, we have undefined nets.

We use wire/net type to define them.

Incorrect Implementation
module ha (

input wire a, b,

output wire sout, cout

);

assign sout = a ^ b;

assign cout= a & b;

endmodule

module fa

input a , b, cin,

output s, c

);

reg t1,t2,t3; //not correct


ha h1 (a ,b, t1, t2);

ha h2 (t1, cin, s, t3);

assign c = t2 | t3;

endmodule

Correct Implementation
module ha (

input wire a, b,

output wire sout, cout

);

assign sout = a ^ b;

assign cout= a & b;

endmodule

module fa

input a , b, cin,

output s, c

);

wire t1,t2,t3; //correct

ha h1 (a ,b, t1, t2);

ha h2 (t1, cin, s, t3);

assign c = t2 | t3;

endmodule
UNDERSTANDING ARRAYS:

Declaring fixed size array

Output

Accessing specific element of array:

Adding a new element to array

Printing all elements of a array


Default value
Array Initialization Strategies
arr [ ] = `{default :0}

Repetitive Value
Unique Values arr[] = `{ 6{1} }
arr[ ] = {1,2,3,4}
Array Operations
1. Copy

2. Compare
Dynamic Array:

Specifying the size of array, here we create capability of


storing 5 elements in a array

It will delete the array

Now let us assume in runtime we want to increase the size of


array.
Output of above code :

When we modify the above code as shown below


Output of above code :
With this approach first 5 elements will be as it is , new 25 elements will be added

FIXED ARRAY Vs DYNAMIC ARRAY


We are getting same output for fixed array and dynamic array

Queue :
Gives fast access to elements of array.

Declaring Queue

Output
Adding New element to Queue:

Adding element to 0th index

Adding element to last index

Output

Inserting a new element to Queue

Output

Before inserting

Taking out element from a Queue


Removing first element

Removing Last element


With above program we are getting following output :

How do we correct it ?
OUTPUT :
OUTPUT

VERIFICATION FUNDAMENTALS:
Learning how to create verification plan :
Let us take example we are planning to verify a single port RAM

CLK

RST
dout
wr Single Port RAM

din

addr

Let us create a verification plan for this design:


For creating verification plan we create 3 columns
1. Testcase: This column defines the name or condition under which each test
case will run. Naming conventions are meaningful, like rst_high or wr_low,
which make it clear which conditions are active during that particular test.
2. Description: This column explains what each test case does or the
conditions it applies to the system. It provides clarity on what is being tested
in each scenario.
3. Feature Covered: This column describes the specific feature or behavior
that is verified by each test case. It ensures that the verification plan is
aligned with the design specifications and that all functional requirements
are covered.
rst_high

Above is a verification plan for some design


Fundamentals of Class
1. First create class and give name to it.
2. Declare data members with there sizes
3. Create a module block
If we want to access the data members in module block
We use
f.data
Very much similar to what we did in Verilog to access variable from one module to other
f.data2

Adding data members to class

Handler for the class first

Creating a object of class, so new is referred as a constructor

So what is the difference between SV and Verilog, as we create a handler in SV but just
doing this will not help us access the class because class is a dynamic object whereas
module is static object i.e when we perform simulations right from start to end the
object will be present when we refer to static whereas for a class we don’t keep object
live for entire simulation.

➔ new constructor
when we create constructor new, it allocates space in memory for the data
members of class along with that it will also initialize default value the data member
can have.
The approach as shown here, we
follow similar approach in
creating testbenches also when
working with class.

Creating a handle of this


module here to
instantiate
Ways to add class to method:

Functions
Tasks
➔ Do not support timing
➔ Support timing control control.
➔ Do not support output
@(posedge clk);
port.
➔ Multiple output ports

FUNCTIONS :

You might also like