` ifdef` includes a region only if a macro is defined. The macro value is irrelevant: define MODE 0` still makes ifdef MODE`` true.
Code in the false branch is never compiled. It can reference signals that do not exist, which is fundamentally different from a run-time if that compiles both branches.
// snippet
`define FPGA_TARGET // value-less define: existence is the flag
`ifdef FPGA_TARGET
// FPGA clock buffer primitive (tool cell, shown as a fragment)
// bufg clk_buf (.I(clk_in), .O(clk));
`elsif ASIC_TARGET
// ASIC standard-cell buffer (tool cell, shown as a fragment)
// CLKBUF_X4 clk_buf (.A(clk_in), .Z(clk));
`else
assign clk = clk_in; // plain sim model
`endif
`ifndef SYNTHESIS // include when NOT defined
initial $display("Simulation-only banner");
`endif
// `undef removes a definition from this point onward
`undef FPGA_TARGETAn unguarded use of a build macro is a compile error when the flag is absent. Guard it or give it a default.
// snippet
`ifndef BUILD_TAG
`define BUILD_TAG "dev"
`endif
// initial $display("Simulation-only banner: build %s", `BUILD_TAG);Most defines come from the build script, not the source. One tree compiles into RTL sim, gate-level sim and synthesis without editing a file.
iverilog -g2012 -DUSE_FAST_TICK -o simv tick_gen.sv tb_tick.sv && vvp simv
iverilog -g2012 -DRTL_SIM -DASSERT_ON -o simv design.sv tb_top.sv && vvp simv
verilator --binary --timing +define+USE_FAST_TICK --top-module tb_tick tb_tick.svThe sim-versus-synthesis guard below is standard. Synthesis tools predefine SYNTHESIS, so sim-only checks vanish from the netlist build.
// snippet
`ifndef SYNTHESIS
always @(posedge clk)
if (fifo_full && wr_en)
$error("Write to full FIFO"); // sim-only check, stripped by synthesis
`endif
`ifdef GATE_SIM
// SDF annotation hardcodes the testbench hierarchy: a fragment, not reusable.
// initial $sdf_annotate("netlist.sdf", tb_top.dut);
`define CLK_PERIOD 12 // slower clock for annotated timing
`else
`define CLK_PERIOD 10
`endif
`ifdef ASSERT_ON
// assert_no_overflow: assert property (@(posedge clk) !(full && wr_en));
// Concurrent assertion: needs a tool with SVA support, shown as a fragment.
`endifConditional compilation does not compose. Two flags make four configurations and five make thirty-two, most never compiled and quietly broken, which is the ifdef-explosion smell.
Keep one central defines file listing every legal flag. Never scatter ` define`` statements across random files.
Prefer run-time plusargs for verbosity, test selection and iteration counts. They need no recompilation.
Prefer parameters and generate blocks for structural variants. They are type-checked in every branch.
Reserve ` ifdef`` for true compile-time concerns: tool and target differences, synthesis guards, restricted code.
Document the legal flag combinations when two flags interact.
A tick generator whose period is selected at compile time. The testbench derives its expectation from the same flag, so it passes with and without -D.
timeunit 1ns; timeprecision 1ps;
`ifdef USE_FAST_TICK
`define TICK_MAX 4
`else
`define TICK_MAX 8
`endif
module tick_gen (
input logic clk,
output logic tick
);
int count = 0;
always @(posedge clk) begin
if (count == `TICK_MAX - 1) begin count = 0; tick = 1; end
else begin count = count + 1; tick = 0; end
end
endmodule
module tb_tick;
logic clk = 0;
logic tick;
tick_gen dut (.clk(clk), .tick(tick));
int ticks = 0;
always #5 clk = ~clk;
initial begin
repeat (80) begin @(posedge clk); #1; if (tick) ticks++; end
`ifdef USE_FAST_TICK
if (ticks == 20) $display("PASS: fast config ticks every 4 cycles: 20 ticks in 80 cycles");
else $fatal(1, "FAIL: fast config tick count is wrong");
`else
if (ticks == 10) $display("PASS: default config ticks every 8 cycles: 10 ticks in 80 cycles");
else $fatal(1, "FAIL: default config tick count is wrong");
`endif
$finish;
end
endmodule define MODE 0` is in force. Is ifdef MODE`` true or false, and why?True. ` ifdef` tests existence, never value. Use ifndef`` for default-on behavior and a real comparison for values.
10 ticks. The ` else` branch defines TICK_MAX 8, so exactly every eighth edge raises tick`.