Day_14
Functions and Tasks In Verilog
Complier Directives In Verilog
• The moment we write a code, then we may need to use the same line of code
repeatedly in different places.
• The same line of code repeating at different places triggers errors in the code
and reduces the readability of the code.
• Thus, for executing the same code several times, there exist subroutines in a
programming language (also termed as subroutine).
• In Verilog, there exist two types of subroutines: functions and tasks.
• A function is pretty much the same thing as functions of any programming
language; however, tasks are somewhat different.
Subroutine ?
• Before learning more about
functions and tasks, let us see what
a subroutine is.
• A routine defines the execution
flow of a code.
• A subroutine is some code that is
executed only when called by the
main programme.
• Once the execution of the
subroutine is complete, the pointer
moves back to the main
programme.
Function in Verilog
A function, as discussed earlier, is the same as that found in other programming languages. To write a
function, first, we need to declare it. This step is known as a functional declaration. After declaration, we
write the function's body, which is nothing but the function's functionality and is known as a function
definition. Please remember, we cannot define a function before declaring it.
Function declaration consists of 3 parts:
• Function name – This is the name of the function that will be used to invoke the function. It can be
any legal identifier.
• Automatic - This keyword is used to make the function automatic. Detailed explanation about
automatic function is discussed later in this lesson.
• Return type – This is the data type of the value that the function returns. If nothing needs to be
returned by the function, then void is used.
• Arguments – This is the input into the functions. There can be no or even more than one argument
into a function. Arguments are similar to the port list in modules.
Function Syntax
A function is declared using a function keyword, and the function definition ends with
the endfunction keyword. The function definition goes inside begin end block.
Output
Rules to Remember
In Verilog, while declaring a function, some rules need to be remembered.
These rules are:
1. A function should have at least one argument.
2. A function argument can take input only as direction. output or inout
cannot be used in function arguments.
3. Any delay statement or @ statements should be in function definition
since functions cannot consume time.
4. A function definition should not have a non-blocking assignment or
procedural-continuous assignment.
Tasks in Verilog
• In Verilog, a task is a special subroutine type,
which can consume time. We know that Verilog is a
time-dependent simulator. So sometimes we need
to provide a delay in subroutines. However, delays Syntax
cannot be used in functions as they should not
consume time; otherwise, a compile-time error is
shown. A task helps to tackle this problem.
• Like functions, a task is also declared first and then
defined. However, the declaration of a task does
not contain a return type. We use a port with an
output direction in the arguments.
Note:- In Verilog, global functions or tasks are not
allowed. It is only allowed in System Verilog.
Declaration of a global function or task will throw a
compile-time error.
Output
Tasks vs Functions
Task Function
Can have zero or more than one argument. It needs to have at least one argument.
A function cannot have a delay statement. It should
A task can have delay statements inside it.
return a value at the same time step.
A Task Does not have a return type. However,
A function does have a return type.
output arguments help return value.
A task can return more than one values as there can A function can return only one value as output
be any number of output arguments. arguments cannot be used in functions.
A function can only call another function from its
A task can call another function or a task from its
body. A task cannot be called as it can consume
body.
time, and function is not allowed to consume time.
Static vs Automatic
Both functions and tasks are of 2 types, static and automatic.
By default, all functions and tasks are static in Verilog. Static tasks mean that
the variable or nets declared inside a task will retain their previous value
whenever the task is called. Therefore, it can be said that the memory
allocated for the function or task remains the same during each call, making it
static.
Whereas in Automatic function or task, a new memory location is allocated
each time they are called. Thus any internal variable present inside the task
would not retain its previous value.
Complier Directives in Verilog
In Verilog, there are many compiler directives for setting timescale in simulation and
controlling compiler flow. Compiler directives start with the ` symbol. Compiler Directives,
declared, stays in effect until overridden by another directive. Thus, if a directive is declared
in one file, it will be available in other files as well.
Different directives available in Verilog:
•`define •`else
•`include •`timescale
•`ifdef •`undef
•`ifndef •`resetall
•`elseif •`defaultnettype
Define and include Directives
Define directive is used to declare a Macro or to define a custom data type.
Macros are code that can be used to perform some tasks. It is different from
function or task as it can be defined outside the modules and thus be used globally.
Also, macros do not have any construct like that of function and task.
Syntax: `define name code
Include directive is used when a module defined in a file needs to be included in
another file. This compiler directive will copy all the codes written in the
mentioned file and include them in the present file during compile time, making
all the code from another file accessible in the file.
Syntax: `include “file_name”
Undef, ifdef and ifndef
Undef directive is used to remove any defined macros.
Ifdef directive is like an if-else statement but is evaluated during the compile time. If a macro has been
defined, it will compile the statements present after the directive. `ifdef directive is always followed by an
`endif directive which marks the end of condition code.
Syntax: `ifdef macro_name <code> `endif
Ifndef directive is just the opposite of the `ifdef directive. This directive will compile the underlying code
only when the macro is not defined. Generally, this is used when we want to compile some code only once.
So, if a macro is not defined, it can compile some code and then define the exact macros. Now the same
code will not be recompiled.
Syntax: `ifndef macro_name <code> `endif
Elseif, else and Timescale
Elseif directive is used with the `ifdef or `ifndef directive to give added options, just as
in the case of if-else-if statements.
Else directive is used to define a default case, i.e., if none of the directives evaluates to
true, then the statement present in this directive is compiled. It is not necessary to
include an `else directive with `ifdef or `ifndef directives.
Timescale directive is used to define the time scale of the simulation. Choosing a correct
timescale is very crucial for a simulation.
The time scale is divided into two parts: time unit and time precision.
Time unit maps one simulation unit to a real time unit. For example, if the time unit
is selected as 1µs, then #1 will mean a delay of 1µs.
Time precision shows the precision of the time scale. It can be equal to or less than
the time unit specified.