Skip to main content

SystemVerilog Tasks and Functions

· loading · loading · ·
Hardware Design Verification SystemVerilog Tasks Functions RTL Design Testbench Reusability
Hardware Design Verification
Axolot Logic
Author
Axolot Logic
Digital Design Engineer
Table of Contents
SystemVerilog Design Series - This article is part of a series.
Part 14: This Article

🔧 SystemVerilog Tasks and Functions
#

SystemVerilog provides tasks and functions to help you write reusable blocks of code. These are used extensively in both RTL modeling and testbench development for calculations, procedural modeling, stimulus generation, and communication between components.


📌 Overview
#

FeatureFunctionTask
ReturnsSingle valueNone (void) or multiple via outputs
TimeZero simulation timeMay consume simulation time
UsagePure computationInteraction with other modules, delays, file I/O
InputsInputs onlyInputs, outputs, inouts
Call StyleCalled like a functionCalled like a procedure

🧠 When to Use
#

Use CaseUse Function?Use Task?
Pure computation (math)
Delays (e.g., #5, @posedge)
File operations, $display, $fopen
Return multiple values
Assertions or comparisons
Clocking block usage

🔁 Function Syntax
#

A function returns a single value and completes in zero simulation time.

function int add(int a, int b);
  return a + b;
endfunction

int result = add(3, 5);
  • Can’t contain #delay, @, wait, or time-consuming operations
  • Must return exactly one value
  • All inputs are passed by value

🔄 Task Syntax
#

A task can do everything a function can’t — including delays and returning multiple outputs.

task automatic delay_and_add(input int a, b, output int sum);
  #5;
  sum = a + b;
endtask

int x;
delay_and_add(2, 3, x);
  • Can use #, @, wait, $display, etc.
  • Inputs/outputs can be passed by value, reference, or inout
  • Supports zero or more return values

📥 Input, Output, Inout
#

TypeDescription
inputRead-only inside task/function
outputAssigned inside task and returned
inoutBi-directional; use with care
task operate(input int a, inout int b, output int result);
  b += a;
  result = a * b;
endtask

🧠 automatic vs static
#

By default, tasks and functions in Verilog are static — shared among calls. In SystemVerilog, you can use automatic to allocate separate stack frames per call.

task automatic do_something();
  int counter = 0;
  counter++;
  $display("Counter = %0d", counter);
endtask

✅ Always use automatic for recursive calls, reentrant tasks, or concurrent testbenches.


🧪 Example: Function in RTL Design
#

module alu(input logic [3:0] a, b, output logic [4:0] result);

  function logic [4:0] add;
    input logic [3:0] x, y;
    add = x + y;
  endfunction

  assign result = add(a, b);

endmodule

🧪 Example: Task in Testbench
#

task automatic print_banner(string msg);
  $display("\n=====================");
  $display("  %s", msg);
  $display("=====================\n");
endtask

initial begin
  print_banner("Simulation Started");
end

🚦 Synthesis vs Simulation
#

FeatureSynthesizableNotes
Functions with only combinational logicUseful for ALUs, comparators
Tasks with delays or $displayUse only in testbenches
Tasks with only logic assignments✅ (with care)Must be static and bounded

✅ Best Practices
#

  • Use functions for combinational, stateless logic
  • Use tasks in testbenches for procedural control and time-based actions
  • Use automatic to avoid side effects and shared state
  • Avoid tasks with delay in synthesizable modules
  • Prefer named arguments for clarity:
my_task(.a(10), .b(20), .result(my_var));

🔚 Summary
#

KeywordReturns ValueAllows DelayMultiple OutputsPreferred In
functionRTL, utility math
task❌ (uses output)Testbenches, control

SystemVerilog tasks and functions allow you to write modular, reusable, and intent-expressive code — which is critical in both design and verification.


module tb_task_function_demo;

    // Function: Pure computation
    function automatic int multiply_by_two(int val);
        return val * 2;
    endfunction

    // Task: With delay and multiple outputs
    task automatic compute_delay_add(
        input int a, b,
        output int sum
    );
        #5;
        sum = a + b;
        $display("Delayed Sum = %0d", sum);
    endtask

    // Task: With input, inout, output
    task automatic operate(
        input int a,
        inout int b,
        output int res
    );
        b += a;
        res = a * b;
    endtask

    initial begin
        int result, sum, val = 5, io = 3;

        result = multiply_by_two(val);
        $display("multiply_by_two(%0d) = %0d", val, result);

        compute_delay_add(7, 8, sum);

        operate(2, io, result);
        $display("After operate: io = %0d, result = %0d", io, result);

        $finish;
    end

endmodule

SystemVerilog Design Series - This article is part of a series.
Part 14: This Article

Related

SystemVerilog Enum Data Type
· loading · loading
Hardware Design Verification SystemVerilog Enum FSM RTL Design Testbench Debugging
Hardware Design Verification
SystemVerilog Loops and Control Flow – for, while, foreach, repeat, break
· loading · loading
Hardware Design Verification SystemVerilog Loops Control Flow Testbench RTL Design Break/Continue
Hardware Design Verification
SystemVerilog Arrays
· loading · loading
Hardware Design Verification SystemVerilog Arrays Packed Dynamic Arrays Queues Testbench
Hardware Design Verification
SystemVerilog Clocking Block – Timing Control for Testbenches
· loading · loading
Verification Hardware Design SystemVerilog Clocking Block RTL Design Testbench UVM Timing
Verification Hardware Design
SystemVerilog Logic Data Type
· loading · loading
Hardware Design Verification SystemVerilog Logic RTL Design Verilog Synthesis Net vs Variable
Hardware Design Verification
SystemVerilog Data Types
· loading · loading
Hardware Design Verification SystemVerilog Verilog RTL Design Data Types Synthesis Simulation
Hardware Design Verification