🧭 Verilog Compiler Directives & Macros#
Compiler directives in Verilog start with a backtick `
and instruct the compiler/simulator, not the synthesized hardware. They’re essential for conditional compilation, macro definitions, file inclusion, and simulation control.
📌 Common Compiler Directives#
Directive | Description | Example |
---|---|---|
`define | Defines a macro or constant | `define WIDTH 8 |
`ifdef / `ifndef | Conditional compilation | `ifdef DEBUG ... `endif |
`include | Includes another file | `include "defs.v" |
`timescale | Sets time unit & precision | `timescale 1ns / 1ps |
`undef | Removes a macro definition | `undef WIDTH |
`else / `elsif | Used with ifdef for alternate code paths | — |
`default_nettype | Controls implicit wire declarations | `default_nettype none |
`resetall | Resets all directives to default | — |
🧠 Macro Example#
You can define constants or reusable code snippets with `define
:
`define WIDTH 8
module adder (
input [`WIDTH-1:0] a, b,
output [`WIDTH-1:0] y
);
assign y = a + b;
endmodule
Macros are replaced by the preprocessor before compilation — think of them like
#define
in C.
🔀 Conditional Compilation#
Useful for enabling debug logic or platform-specific features:
`define DEBUG
module test;
initial begin
`ifdef DEBUG
$display("Debug mode enabled");
`endif
end
endmodule
🔄 File Inclusion#
To split code across files:
`include "parameters.vh"
Best practice: Use
.vh
or.svh
extensions for include files.
🚫 Disabling Implicit Nets#
By default, undeclared signals are treated as wire
. This can lead to silent bugs. Prevent it using:
`default_nettype none
✅ Inline Code Block (Macro-like):#
`define PRINT_SIGNAL(signal) \
$display("Signal %s = %b", `"signal`", signal)
initial begin
`PRINT_SIGNAL(my_reg); // expands to: $display("Signal my_reg = %b", my_reg);
end
Note: Macro parameters should be enclosed in parentheses, and each line should end with a backslash (
\
).
🔐 Include Guard Example#
📁 safe_defs.vh
`ifndef __SAFE_DEFS_VH__
`define __SAFE_DEFS_VH__
`define WIDTH 32
`define RESET_VAL 0
`endif
✅ Best Practices#
- Use
`default_nettype none
at the top of all files. - Always wrap macro code with
ifdef
/endif
to avoid naming collisions. - Avoid overly complex macros — they’re hard to debug.
- Use
include
only for constants, parameters, or small utility code.
`timescale 1ns / 1ps
`default_nettype none
`define WIDTH 8
`define RESET_VAL 0
`define PRINT_SIGNAL(sig) \
$display("Signal %s = %b", `"sig`", sig)
module tb_directives;
reg [`WIDTH-1:0] my_reg = 8'hA5;
initial begin
`ifdef DEBUG
$display("Debugging Enabled");
`endif
`PRINT_SIGNAL(my_reg);
#10 $finish;
end
endmodule
`undef WIDTH
`resetall