Verilog basics: the use of task and function (1)

  related articles

Verilog Basics: Determination of Expression Bit Width (Bit Width Expansion)        

Verilog Basics: Determination of Expression Symbols

Verilog Basics: Data Types

Verilog basics: the connection between bit width expansion and signed arithmetic

Verilog basics: case, casex, casez statements

Verilog basics: use of casex and full_case, parallel_case

Verilog basics: integer constants (integer) in expressions

Verilog basics: the use of task and function (2)

Verilog Basics: Hierarchical Name References for Identifiers

Verilog Basics: Upward and Downward Hierarchical Name References for Identifiers


Table of contents

1 Introduction

2. The difference between task and function

3. Declaration and enablement of task

3.1 Declaration of task

3.2 Task enabling and parameter passing

3.3 memory usage and concurrent processes of task 


1 Introduction

        Tasks and functions provide the ability to execute common procedures from different locations (because this enables code sharing), and also provide the ability to decompose large procedures into smaller procedures (because smaller procedures are easier to read and debug. ). The difference between task and function will be introduced below, and how to define and call task and function will be introduced.

        Note: Both functions and tasks can be synthesized, but there are many requirements and restrictions, so use them with caution.

2. The difference between task and function

        The differences between task and function are listed below.

  • function cannot contain timing control statements (such as #delay, @event, wait level), and can only be performed within one simulation time unit; while task can contain timing control statements.
  • Function cannot call task (this is well understood, because task may contain timing control statements), and task can call function.
  • A function must have at least one parameter of input type, and cannot have parameters of output and inout types (the function passes the output through the return value, not the output port), and the task can have no parameters (just like testbench), and can also have various parameters. types of parameters.
  • function returns a value, while task does not return a value.
  • A function can only return one result value for an input value, while a task can support various uses, and can calculate and return multiple result values. For task, only output and inout can be used to pass back the result value. A function can be used as an operand in an expression, and the value of the operand is the return value of the function.

        Example: For byte exchange of 16bits word, we can implement it with either task or function.

        //Use the task, old_word is input, new_word is output         

        switch_bytes (old_word, new_word);

        //Use the function, old_word is input, new_word is returned value

        new_word = switch_bytes (old_word);

3. Declaration and enablement of task

        The enabling of a task (that is, calling, but in the standard, enable is used for task, and call is used for function), is to transfer control from the calling process to task from a call statement that can include input and output. When the task is complete, control returns to the calling procedure, so if the task contains timing control statements, the time when the task is called and the time when the task is exited may be different. A task can then enable (call) other tasks, there is no limit to the number.

3.1 Declaration of task

        The syntax for a task declaration is as follows:

Verilog-1995

       Verilog-2001

        Explanation of the task statement:

        1. The first one is the Verilog-1995 syntax, and the passed parameters are declared in sequence after task_identifier;.

        2. The second is the grammar of Verilog-2001. The passed parameters can also be defined inside the brackets of task_identifier(); which is the style of ANSI-C.

        3. Various types of variables (reg, integer, real, realtime) can be declared in the task, and parameter, local parameter and event are also supported.

        4. Verilog-2001 has added the automatic feature of the task. A task without automatic is static. All parameters and variables declared by the task are statically allocated storage space. The emulator shares these parameters and variables for all concurrent executions of the same task. .

        5. The task using automatic is reentrant (Reentrant). The emulator dynamically allocates storage space for each concurrently executed task, that is, each task has its own unique set of variables, but at the end of the automatic task, These variables are destroyed.

3.2 Task enabling and parameter passing

        The enabling of a task is to pass the comma-separated expression list in parentheses as actual parameters to the task.

        The syntax of task enable is as follows:   

         The rules for task delivery are as follows:

        1. If the task has no parameters, you can use task_identifier(); or task_identifier;

        2. If the task has parameters, the number of expressions (actual parameters) must correspond to the parameters defined by the task, and unconnected ports cannot appear (modules can have unconnected ports).

        3. The calculation order of the expressions in the expression list is indeterminate.

        4. If the formal parameter of the task is an input type, then the corresponding expression (actual parameter) can be any expression.

        5. If the formal parameter of the task is an output type, then the corresponding expression (actual parameter) must conform to the rules of the process assignment LHS (this is different from the module, the output port of the module can only be connected to an external wire network signal).

         6. When the task is an enable statement, the value (actual parameter) of the corresponding expression is passed into the input and inout parameters (only once during execution, which is different from the connection of the module input port).

        7. When returning from the task, the values ​​of the output and inout formal parameters will be returned to the corresponding expression (actual parameter) (only returned once when returning, which is different from the connection of the module output port).       

        8. All parameters are passed by value, not by reference. That is, the operation of the input parameters in the task will not affect the input actual parameters. 

Example: task enable

                                     

        The above figure defines the task in two ways, and the following expression enables the task.

        The actual parameters v, w, x, y, z of the task enabling statement correspond to the task formal parameters a, b, c, d, e. When the task is enabled, the input and inout type parameters a, b and c Accept the values ​​passed by the actual parameters v, w, and x respectively, as if the following assignment statements are executed.

        In fact, the input and output ports of a task are both reg type by default, which is different from the module, the input port of the module can only be the wire type by default, and the output port of the module can be defined as the reg type or the wire type.

        During the execution of the task, the task calculates and changes the values ​​of the formal parameters c, d, and e. At the end of the task, assigning the values ​​of c, d, and e to the actual parameters x, y, and z is like executing the following assignment statement.

 Example: use task to describe a semaphore.

3.3 memory usage and concurrent processes of task 

        Reentrance tasks are very important to verification engineers, because these engineers need to call the same task multiple times concurrently. But many people don't know that Verilog-1995 tasks use static variables, which means that when the first task call is still running, make a second call to this task, then the two task calls use is the same set of static variables, which can cause serious problems for testbench.

        Verilog-2001 has expanded task and function, and added an optional attribute automatic. Every time the task or function is called, the storage space used by the local variable is allocated, so that the task and function can be reentrant . Reentrancy means that during the execution of a task or function, the task or function can be called again.

        The following is a comparison between static task and automatic task.

        1. For a static task, all its parameters and variables are static, no matter how many times the task is enabled concurrently. The so-called static means that for each instance of the module, the emulator only allocates storage space once for the parameters and variables declared by the static task at the beginning, and then uses it all the time, and no longer allocates it during execution. Note: For different instances of the module, each static task still uses its own independent storage space.

        2. The variables declared in the static task, including input, output, and inout parameters, will maintain the value of the last use (because it is a reg type).

        3. For the automatic task, when it is enabled concurrently each time, the emulator will allocate new storage space for all its parameters and variables. Because the parameters and variables declared by the automatic task are released when the task is completed, they cannot be used after the task is completed.       

        4. The variables and parameters declared in the automatic task, including input, output and inout parameters, are initialized to the default value (x) at the start of the simulation, while input and inout are initialized as an expression list and passed in when they are enabled value.

        For static task and static function, their parameters and variables have static life time, that is, these variables are only allocated once at the beginning, and then they are used all the time. This causes these parameters and variables to always retain their last used value. But the synthesis tool doesn't think so. The synthesis tool thinks that task and function will not depend on the previous values ​​of these parameters and variables, and thinks that these parameters and variables must be reinitialized every time they are called. This can lead to inconsistencies between simulation and synthesis. So for consistent results, to reassign these parameters and variables each time, we should use automatic.

The above content comes from "Verilog Programming Art", the source of the picture is IEEE Verilog-2001 Standard  

Guess you like

Origin blog.csdn.net/weixin_45791458/article/details/130339058