imageNamaste FPGA
image
SystemVerilog Verification2 min read

Scope in SystemVerilog & UVM and role of ref

Scope defines the region where functions, tasks, and variables are declared, determining where they can be accessed and modified in the code.

Scope also dictates the visibility of variables, tasks, and functions. There are three possible scopes: Local, Global, and Caller.

1) Global Scope: Variables, tasks, and functions declared inside the top module, interface, or program can be accessed anywhere within that module, interface, or program. These are said to have a global scope. Global scope is usually used to declare variables or methods that are shared across submodules.

2) Local Scope: Variables declared inside a function, task, or class belong to a local scope and are accessible only within the block in which they are declared. They are invisible outside that block. These variables are created when the function/task is called and destroyed when it ends. Local scope is often used for storing temporary variables required for computation within that block or methods specific to that block. For example, it is used for printing local variables of a class or updating values of class-local variables.

3) Caller Scope: When a function or task is called, execution happens within the caller scope. Usually, procedural blocks such as always or initial execute tasks or functions. Variables from these blocks or global scope can be passed as arguments to a task or function.

Functions in SystemVerilog follow Verilog behavior, meaning they should only read arguments, perform computation, and return a result. Using ref in a function would allow it to modify the variable passed as an argument, violating the default function behavior hence ref is not allowed with static function by default.

Tasks, unlike functions, can have multiple output ports and can modify variables passed as arguments. If we want changes made to an argument inside a task to be reflected in the calling scope, we must use ref, which allows pass-by-reference behavior. This ensures that modifications made inside the task affect the original variable.

If we do not want the original variable to be modified, we use pass-by-value, where a local copy of the argument is created inside the function or task for computation. A task without the ref keyword also creates a local copy of the argument without modifying the original source variable.

Summary : Scope in SystemVerilog defines where functions, tasks, and variables can be accessed and modified. It includes global scope (accessible across a module or interface), local scope (limited to the function, task, or class where declared), and caller scope (where functions/tasks execute). Functions use pass-by-value, while tasks can modify arguments using ref for pass-by-reference behavior.

Blog illustration
625 views