Compiler Directives in Verilog
Complier directives are common in any programming language which is based on compilers. These directives, as the name suggests, direct how the compiler will compile the code. In Verilog, there are various compiler directives to set the timescale of simulation, control the compiler flow. Compiler directives start with the `
(backquote) symbol.
Compiler Directives, once declared, stays effective until another directive overrides the directive. Thus, if a directive is declared in one file, it is effective in other files also.
Different directives available in Verilog are:
- `define
- `include
- `ifdef
- `ifndef
- `elseif
- `else
- `timescale
- `undef
- `resetall
- `defaultnettype
Let us see different directives in detail.
Include directive
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”
`define
This 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
Example
This example shows how a define directive can be used to define a custom data type. A nibble is a 4-bit data which is defined using `define directive.
`define nibble reg[3:0]
module define_demo;
`nibble a;
initial begin
a = 4'b1010;
$display("a = %b", a);
end
endmodule
Output
# a = 1010
`undef
This directive is used to remove any defined macros.
Example
This code will show an error as nibble is undefined using `undef directive. Thus, nibble cannot be used after the highlighted line.
module undefine_demo;
`undef nibble
`nibble a;
initial begin
a = 4'b1010;
$display("a = %b", a);
end
endmodule
`ifdef
This 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. Thus, any code written inside `ifdef and `endif directive will be compiled only when a particular macro is defined.
Syntax: `ifdef macro_name <code> `endif
The macros can either be defined using `define directive or be passed as a parameter with the compile command using the +define
option.
`ifndef
This 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
This directive is used with the `ifdef or `ifndef directive to give added options, just as in the case of if-else-if statements.
`else
This 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
This 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. For example, if time precision is selected to be 100ns, then #1.2 would mean a time delay of 1.2µs. If precision is also set to 1µs, then #1.2 will mean a time delay of 1µs. As there is the precision is also in µs.
Example
In the below example, it must be noted that the $realtime
function's output is related to the time precision we provide. Precision in the example is 100ns, and as 1µs = 10 * 100ns, thus the output of the $realtime
function is 10.
`timescale 1us/100ns
module timescale_demo;
reg a = 1'b0;
initial begin
#1.4
a = 1'b1;
$display("Simulation at %0t x 100ns", $realtime);
#1.42
a = 1'b0;
$display("Simulation at %0t x 100ns", $realtime);
#1.46
a = 1'b1;
$display("Simulation at %0t x 100ns", $realtime);
end
endmodule
Output
# Simulation at 14 x 100ns
# Simulation at 28 x 100ns
# Simulation at 43 x 100ns