Tasks and functions are introduced in the verilog, to provide the ability to execute common procedures from different places in a description. This helps the designer to break up large behavioral designs into smaller pieces. The designer has to abstract the similar pieces in the description and replace them either functions or tasks. This also improves the readability of the code, and hence easier to debug. Tasks and functions must be defined in a module and are local to the module. Tasks are used when:
- There are delay, timing, or event control constructs in the code.
- There is no input.
- There is zero output or more than one output argument.
- The code executes in zero simulation time.
- The code provides only one output(return value) and has at least one input.
- There are no delay, timing, or event control constructs.
| Functions || Tasks |
| Can enable another function but not another task. || Can enable other tasks and functions. |
| Executes in 0 simulation time. || May execute in non-zero simulation time. |
| Must not contain any delay, event, or timing control statements. || May contain delay, event, or timing control statements. |
| Must have at least one input argument. They can have more than one input. || May have zero or more arguments of type input, output, or inout. |
| Functions always return a single value. They cannot have output or inout arguments. || Tasks do not return with a value, but can pass multiple values through output and inout arguments. |
There are two ways of defining a task. The first way shall begin with the keyword task, followed by the optional keyword automatic, followed by a name for the task, and ending with the keyword endtask. The keyword automatic declares an automatic task that is reentrant with all the task declarations allocated dynamically for each concurrent task entry. Task item declarations can specify the following:
- Input arguments.
- Output arguments.
- Inout arguments.
- All data types that can be declared in a procedural block
In both ways, the port declarations are same. Tasks without the optional keyword automatic are static tasks, with all declared items being statically allocated. These items shall be shared across all uses of the task executing concurrently. Task with the optional keyword automatic are automatic tasks. All items declared inside automatic tasks are allocated dynamically for each invocation. Automatic task items can not be accessed by hierarchical references. Automatic tasks
can be invoked through use of their hierarchical name.
Functions are mainly used to return a value, which shall be used in an expression. The functions are declared using the keyword function, and definition ends with the keyword endfunction.
If a function is called concurrently from two locations, the results are non-deterministic because both calls operate on the same variable space. The keyword automatic declares a recursive function with all the function declarations allocated dynamically for each recursive call. Automatic function items can not be accessed by hierarchical references. Automatic functions can be invoked through the use of their hierarchical name.
When a function is declared, a register with function name is declared implicitly inside Verilog HDL. The output of a function is passed back by setting the value of that register appropriately.
1. Simple task example, where task is used to get the address tag and offset of a given address.
wire [31:0] addr;
wire [23:0] addr_tag;
wire [7:0] offset;
task get_tag_and_offset ( addr, tag, offset);
output tag, offset;
tag = addr[31:8];
offset = addr[7:0];
get_tag_and_offset (addr, addr_tag, addr_offset);
// other internals of module
2. Task example, which uses the global variables of a module. Here task is used to do temperature conversion.
// task uses the global variables of the module
t2 = (9/5)*(t1+32);
|<< Previous||Home||Next >>|