🧭 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
✅ 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.