0
0
VerilogHow-ToBeginner · 3 min read

Verilog Non-Synthesizable Constructs: What to Avoid

In Verilog, constructs like initial blocks, wait statements, fork-join parallel blocks, and file I/O operations are not synthesizable because they describe simulation-only behavior. Also, delays using # and system tasks like $display cannot be converted into hardware.
📐

Syntax

Here are some common non-synthesizable Verilog constructs and their syntax:

  • initial block: runs once at simulation start
  • wait statement: pauses until a condition is true
  • fork-join: runs parallel threads
  • Delay control: #10 delays execution by 10 time units
  • System tasks: $display, $finish, etc.
verilog
initial begin
  $display("This runs once at simulation start");
end

always @(posedge clk) begin
  wait (reset == 0);
  // wait until reset is deasserted
end

fork
  // parallel threads
  thread1();
  thread2();
join

always @(posedge clk) begin
  #5 data <= data + 1; // delay not synthesizable
end
💻

Example

This example shows an initial block and a delay, both not synthesizable. The always block with posedge clk is synthesizable.

verilog
module example(input clk, input reset, output reg [3:0] count);

  initial begin
    $display("Simulation start");
  end

  always @(posedge clk) begin
    if (!reset) begin
      #2 count <= count + 1; // delay not synthesizable
    end
  end

endmodule
Output
Simulation start
⚠️

Common Pitfalls

Using non-synthesizable constructs in your design can cause synthesis tools to fail or ignore parts of your code. For example, initial blocks are often used for testbench setup but should not be used for hardware logic. Delays (#) are for simulation timing and have no hardware equivalent.

Wrong way (non-synthesizable):

initial begin
  led = 1;
  #10 led = 0;
end

Right way (synthesizable):

always @(posedge clk or posedge reset) begin
  if (reset) led <= 1;
  else led <= 0;
end
📊

Quick Reference

ConstructSynthesizable?Reason
initial blockNoRuns once at simulation start, no hardware equivalent
wait statementNoPauses simulation, no hardware equivalent
fork-joinNoParallel threads for simulation only
Delay (#)NoSimulation timing control, no hardware delay
System tasks ($display, $finish)NoSimulation output and control
always blockYesDescribes hardware behavior
assign statementYesContinuous hardware assignment

Key Takeaways

Avoid using initial blocks and delays in synthesizable Verilog code.
Simulation-only constructs like wait and fork-join cannot be converted to hardware.
Use always blocks and assign statements for hardware logic.
System tasks such as $display are for simulation and not synthesizable.
Check synthesis tool warnings to catch non-synthesizable code early.