Functions in system verilog:
What is a Function?
A function is like a mini calculator inside your code.
It takes some input, does a quick calculation, and gives back one result —
instantly (no time delay).
Functions are two types:
1. Static function
2. Automatic function
Key points
Function does not contain a simulation time, Returns a single value or an
expression.
A function with out a range or return type declarations it returns a one bit
value.
Can declare Static variables in Automatic variables and vice versa. By
using automatic keyword in Static and Static keyword in automatic.
Used to compute and return a single value without consuming simulation
time.
Must return exactly one value (cannot be void like in tasks).
Only input arguments are allowed. No output or inout.
Functions execute in zero simulation time, meaning they cannot include:
# (delay), @ (event control) and wait statements
Can be used within expressions (e.g., in assignments, if conditions).
Default argument type is LOGIC if no type has been specified.
Default direction of argument is input if no direction has been specified
By default functions declared as STATIC.
Function can call function but it cannot call TASK. (because task is a time
consuming)
Syntax of Function:
function [return_type] function_name (input [type] arg1, ...);
// body
return value;
endfunction
Or we can write
function [return_type] function_name ();
input [type] arg1;
// body
return value;
Endfunction
Ex:
function int add(input int a, b);
add = a + b;
endfunction
initial begin
int result = add(5, 3); // Function call
$display("Sum = %0d", result);
end
endmodule
So hear return type is Integer and function is add
Note:
With STATIC function we can use only one memory location, hence it can
override the previous values during multiple calling.
With AUTOMATIC function we can allocate multiple memory locations during
multiple calls.
What is Premature Function Return in System Verilog?
A premature function return means that the function stops and returns a value
before reaching the end of the function body, usually using the return keyword
directly.
Normally, SystemVerilog functions return a value by assigning to the
function name, like this:
function int square(input int a);
square = a * a;
endfunction
But sometimes, you might want to exit the function early — like if a certain
condition is met. You can do that using the return statement directly, like this:
function int safe_divide(input int a, b);
if (b == 0) begin
return 0; // Premature return if division by zero
end
safe_divide = a / b; // Normal return
endfunction
If b == 0, the function returns 0 immediately and skips the rest.
If b != 0, it returns a / b as usual.
Hence Premature return is useful for handling errors, invalid inputs, or
shortcut logic.
TASK:
Key points:
A task is used to group a sequence of statements that may include delays or
events.
Unlike functions, tasks can include: # delays,@ event controls, wait statements
Tasks do not return a value like functions.Instead, they can use output or
inout arguments to give results back.
Called like a normal statement (not an expression).
Tasks can call both other tasks and functions.
Used heavily for stimulus generation, driving signals, waiting for conditions, and
checking responses.
Syntax
task display_delay(input int a);
#5; // delay of 5 time units
$display("Value after 5 units = %0d", a);
endtask
"task automatic is used to create a new copy of local variables every time the task is
called. This avoids variable conflicts, especially in concurrent or class-based
environments."
“Without automatic, tasks use static storage for local variables. When a task is called
in parallel, all instances share the same variables, which can lead to data conflicts.
Declaring the task as automatic ensures each call has its own safe, separate
memory.”
Ex
With out automatic
// Task Definition
task show;
int count;
count++;
$display("Count = %0d", count);
endtask
// Initial Block
initial begin
fork
show();
show();
join
end
Since show is not declared as automatic, it behaves statically.
That means both calls share the same count variable.
So the result is unpredictable — the two tasks are fighting over one shared
count.
With automatic
task automatic show;
int count;
count++;
$display("Count = %0d", count);
endtask
initial begin
fork
show();
show();
join
End
Feature Function Task
Zero simulation time
Execution time Can consume simulation time
(idealized)
Can return multiple values via
Return value Returns a single value
output arguments
Call usage Used like an expression Used like a statement
Allowed No delays (#), no @, no
Can contain #delay, @events, wait
operations wait
Only input arguments
Inputs/outputs Can have input, output, inout
allowed
Blocking vs Non-blocking Assignments
Feature Blocking (=) Non-blocking (<=)
Keyword = (equal sign) <= (less than or equal sign)
Execution
Step-by-step (sequential) Concurrent (parallel update)
Style
Simulation Update happens at end of
Immediate update
Timing current time step
Mainly in sequential logic,
Mainly in combinational
Used in always_ff or clocked always
logic, initial blocks
blocks
Can cause race conditions
Risk Safer for registers and flip-flops
in sequential code
"Blocking (=) executes line-by-line, while non-blocking (<=) schedules updates
that all happen in parallel at the end of the simulation cycle. That’s why we
use non-blocking in flip-flop-based designs — to avoid race conditions."
Use = in combinational logic (always @(*))
Use <= in sequential logic (always @(posedge clk))
Example: Blocking (=)
always @(*) begin
a = b;
c = a;
end
c gets the value of a, which is already updated by b.
This is step-by-step assignment.
Example: Non-blocking (<=)
always @(posedge clk) begin
a <= b;
c <= a;
end
Here, a and c are both updated together at the end of the clock edge.
So c gets the old value of a, not the newly assigned one.
3. OOPS (Objective Oriented Program ) Concept
What is a Class?
In System Verilog, a class is like a blueprint for creating objects.
It groups together:
Data (called properties or variables)
Functions and tasks (called methods)
What is Encapsulation?
Encapsulation means keeping data and functions together inside a class, and
protecting that data from outside interference.
You bundle data + operations in one unit.
You hide internal details from the outside world.
You control access using local, protected, and public.
Example:
class Counter;
// Data (encapsulated)
int count;
// Constructor (special function to initialize object)
function new();
count = 0;
endfunction
// Method to increase count
function void increment();
count++;
endfunction
// Method to get count
function int get_count();
return count;
endfunction
Endclass
Test
module test;
initial begin
Counter c1 = new(); // create object
c1.increment(); // call method
c1.increment();
$display("Count = %0d", c1.get_count()); // Output: Count = 2
end
endmodule
Example with real-time scenario
class BankAccount;
// public: can be accessed by anyone
string account_holder;
// protected: accessible to this class and any subclass
protected int account_number;
// local: strictly private, only this class can access
local int balance;
// Constructor
function new(string name, int acc_no, int initial_balance);
account_holder = name;
account_number = acc_no;
balance = initial_balance;
endfunction
// public method to deposit money
function void deposit(int amount);
balance += amount;
endfunction
// public method to view balance
function int get_balance();
return balance;
endfunction
endclass
Test
module test;
initial begin
BankAccount b1 = new("Santhosh", 1234, 1000);
b1.deposit(500); // OK: public method
$display("Balance = %0d", b1.get_balance()); // OK: 1500
$display("Name = %s", b1.account_holder); // OK: public
//$display("Acc = %0d", b1.account_number); // ❌ Error: protected
//$display("Bal = %0d", b1.balance); // ❌ Error: local
end
endmodule
Modifier Access from outside? Used for...
public ✅ Yes General access
protected ❌ No (except subclasses) Safe inheritance
local ❌ No Strict privacy (encapsulation)
"Encapsulation in System Verilog is enforced using access modifiers like local
and protected. They control access to variables and prevent accidental or
unauthorized usage from outside, keeping data safe and cleanly managed."
Why Encapsulation is Good?
Keeps code organized and modular.
Makes it easy to reuse and test.
Prevents bugs by hiding internal data.
Objects: Dynamic allocation using new.
In SystemVerilog, objects are created from classes using dynamic allocation with
the new keyword. This means memory is allocated during simulation (runtime), not
statically during compilation like in modules or structs.
What is an Object?
An object is an instance of a class. If the class is like a blueprint, the object is the
actual building.
Syntax of Object Creation:
ClassName object_handle = new(arguments);
“object_handle” is a handle (pointer) to the object.
new(arguments) dynamically allocates memory and calls the constructor.
Example using the PACKET class
module test;
initial begin
// Create an object of class Packet
Packet pkt1 = new("Data_Packet");
// Access public members
$display("Packet name: %s", pkt1.name);
// Access addr using method (addr is private)
$display("Address: %h", pkt1.get_addr());
// Set new address
pkt1.set_addr(8'hCD);
$display("New Address: %h", pkt1.get_addr());
end
Endmodule
Explanation:
Packet pkt1 = new("Data_Packet");
Allocates memory and calls the constructor with "Data_Packet" as the name.
pkt1.name is directly accessed because it's public.
pkt1.get_addr() reads the private addr field.
pkt1.set_addr(8'hCD); updates the private addr.
Note:
If you only declare the handle without new, the object is not created yet:
Packet pkt2; // Only a handle, no memory allocated yet
Accessing members of such an uninitialized handle will cause a null handle
error.
Inheritance
What is Inheritance in System Verilog?
Inheritance is an object-oriented programming concept that allows one class
(called the child or subclass) to reuse, extend, or override the properties and
methods of another class (called the parent or superclass).
Why Inheritance?
To avoid code duplication.
To promote code re-usability.
To allow specialization of existing functionality.
Syntax of Inheritance:
class ChildClass extends ParentClass;
// Additional properties and methods
endclass
Genral example
A child inherits characteristics from a parent:
If Vehicle is a class with common features like speed, then Car and Bike
can inherit those features and also add their own.
Example in SystemVerilog:
class Animal;
function void speak();
$display("Animal speaks");
endfunction
endclass
class Dog extends Animal;
function void bark();
$display("Dog barks");
endfunction
endclass