Starting with a backtick,`certain identifiers are Verilog system compiler directives.
Compiler directives provide great convenience for writing, compiling, and debugging Verilog code.
The following introduces all 8 compiler directives, among which the first 4 are more frequently used.
`define, `undef
During the compilation stage,`defineit is used for text replacement, similar to #define in C language.#define。
Once`definethe directive is compiled, it will be valid throughout the entire compilation process. For example, if defined in one file:
`define DATA_DW 32
then DATA_DW can also be used directly in another file.
`define S $stop; //用`S来代替系统函数$stop; (包括分号) `define WORD_DEF reg [31:0] //可以用`WORD_DEF来声明32bit寄存器变量
`undefIt is used to cancel a previous macro definition, for example:
`define DATA_DW 32 …… reg [DATA_DW-1:0] data_in ; …… `undef DATA_DW `ifdef, `ifndef, `elsif, `else, `endif
These are conditional compilation directives. For example, in the example below, if MCU51 is defined, the first type of parameter description is used; if MCU is not defined but WINDOW is defined, the second type of parameter description is used; if neither of the two is defined, the third type of parameter description is used.
`ifdef MCU51
parameter DATA_DW = 8 ;
`elsif WINDOW
parameter DATA_DW = 64 ;
`else
parameter DATA_DW = 32 ;
`endif
`elsif, `elseThe compiler directive, with respect to the`ifdefdirective, is optional; that is, it can consist of only`ifdefand`endifto form a conditional compilation directive block.
Of course, you can also use`ifndefto set up conditional compilation, meaning that if the relevant macro is not defined, the relevant statements will be executed.
In the following example, if WINDOW is defined, the second type of parameter description is used. If WINDOW is not defined, the first type of parameter description is used.
Example
parameter DATA_DW = 32 ;
`else
parameter DATA_DW = 64 ;
`endif
`include
Using`includeone Verilog file can be embedded into another Verilog file at compile time, which functions similarly to the #include structure in C language. This directive is usually used to include global or common header files in the design file.
The file path can be either a relative path or an absolute path.
`include "../../param.v" `include "header.v"
`timescale
In Verilog models, delays have specific unit-time expressions and use the`timescalecompiler directive to associate the time unit with the actual time.
This directive is used to define the units and precision of delays and simulation. The format is as follows:
`timescale time_unit / time_precision
time_unit represents the time unit, and time_precision represents the time precision. Both are composed of a number and a unit: s (seconds), ms (milliseconds), us (microseconds), ns (nanoseconds), ps (picoseconds), and fs (femtoseconds). The time precision can be the same as the time unit, but the time precision value cannot exceed the time unit value. For example, in the following example, output Z will delay 5.21ns before outputting the result of A&B.
Example
//`timescale 100ps/1ns //invalid
module AndFunc(Z, A, B);
output Z;
input A, B ;
assign #5.207 Z = A & B
endmodule
During compilation, the`timescaledirective affects the delay values in all subsequent modules, until another`timescaledirective or the`resetalldirective is encountered.
Since there is no default`timescale, if not specified`timescale, Verilog modules will inherit the previously compiled module's`timescaleparameter. This may lead to design errors.
If multiple modules in a design all have`timescale, the simulator always positions itself at the smallest delay precision among all modules, and all delays are correspondingly converted to the smallest delay precision. The delay unit is not affected. For example:
Example
module test;
reg A, B ;
wire OUTZ ;
initial begin
A = 1;
B = 0;
# 1.28 B = 1;
# 3.1 A = 0;
end
AndFunc u_and(OUTZ, A, B) ;
endmodule
In module AndFunc, 5.207 corresponds to 5.21ns.
In module test, 1.28 corresponds to 13ns, and 3.1 corresponds to 31ns.
However, when simulating test, since the minimum precision in AndFunc is 100ps, the delay precision in test will be readjusted. 13ns will correspond to 130*100ps, and 31ns will correspond to 310*100ps. During simulation, the delay precision will also use 100ps. The size of the simulation time unit has no effect.
If there are parallel submodules, the `timescale directives among submodules do not affect each other.
For example, instantiate another submodule OrFunc in module test. When simulating test, the #5.207 delay in OrFunc still corresponds to 52ns.
Example
`timescale 10ns/1ns //Time unit is 1ns, precision is 100ps, legal
module OrFunc(Z, A, B);
output Z;
input A, B ;
assign #5.207 Z = A | B
endmodule
//Top-level module:
`timescale 10ns/1ns
module test;
reg A, B ;
wire OUTZ ;
wire OUTX ;
initial begin
A = 1;
B = 0;
# 1.28 B = 1;
# 3.1 A = 0;
end
AndFunc u_and(OUTZ, A, B) ;
OrFunc u_and(OUTX, A, B) ;
endmodule
In this example, when simulating test, the #5.207 delay in OrFunc still corresponds to 52ns.
`timescaleThe time precision setting will affect the simulation time. The smaller the time precision, the more memory is occupied during simulation, and the longer the actual simulation time used. Therefore, if not necessary, try to set the time precision as large as possible.
`default_nettype
This directive is used to specify implicit net variables as net types, that is, to define undeclared wires as net types.
`default_nettype wand
The default net defined in this example is the wire-AND type. Therefore, if any wire in any module after this directive is not declared, the net is assumed to be of the wire-AND type.
`default_nettype none
After this example is defined, wire-type variables will no longer be automatically generated.
For example, the first writing style below will not report an Error during compilation, while the second writing style will fail to compile.
Example
module test_and(
input A,
input B,
output Z);
assign Z1 = A & B ;
endmodule
Example
`default_nettype none
module test_and(
input A,
input B,
output Z);
assign Z1 = A & B ;
endmodule
`resetall
This compiler directive resets all compiler directives to their default values.
`resetallIt can make the default connection type a net type.
When`resetallWhen added at the end of a module, the current`timescaleis cancelled to prevent further propagation, ensuring only that the current`timescaleis locally valid, avoiding erroneous inheritance of `timescale.
`celldefine, `endcelldefine
These two program directives are used to mark modules as cell modules; they contain the module definitions. For example, some AND, OR, NOT gates, some PLL cells, PAD models, and some Analog IP, etc.
Example
module (
input clk,
input rst,
output clk_pll,
output flag);
……
endmodule
`endcelldefine
`unconnected_drive, `nounconnected_drive
In module instantiation, any unconnected input ports appearing between these two compiler directives are in a forward-biased circuit state or in a reverse-biased circuit state.
`unconnected_drive pull1 . . . / *在这两个程序指令间的所有未连接的输入端口为正偏电路状态(连接到高电平) * / `nounconnected_drive
`unconnected_drive pull0 . . . / *在这两个程序指令间的所有未连接的输入端口为反偏电路状态(连接到低电平) * / `nounconnected_drive