What is synthesis ?
Verilog synthesis is the process of transforming high-level Verilog code, which describes digital circuits, into a lower-level representation that can be implemented in hardware. This transformation typically results in a netlist, which consists of logical components like gates and flip-flops that can be physically realized in an FPGA or ASIC.

Synthesis converts abstract descriptions of designs (written in Verilog) into a format that can be mapped to physical hardware components. The synthesis process optimizes the design for various constraints such as area, timing, and power consumption.
How is synthesis done ?
The process begins with a synthesizable subset of Verilog code, typically written at the Register Transfer Level (RTL). The synthesis tool applies algorithms to optimize the logic, reducing the number of gates and improving performance. Specify timing constraints to guide the synthesis tool in optimizing for speed and performance.The final output is a netlist that describes the circuit in terms of basic logic gates and flip-flops.
Various tools are available for Verilog synthesis, including Synopsys Design Compiler, Cadence Genus, Xilinx Vivado, etc. Different synthesis tools may interpret Verilog code differently, leading to variations in synthesized output.
What is a synthesis constraint file ?
A Synthesis Constraint File is typically written in the Synopsys Design Constraints (SDC) format, which is used to specify timing, area, and power constraints for digital designs. During synthesis, the SDC file guides tools like Synopsys Design Compiler to optimize the logic based on specified constraints.
# Set the version of the SDC file
set_version 2.1
# Define the clock
create_clock -period 10 [get_ports clk] ; # 100 MHz clock
# Set input delay constraints
set_input_delay -max 2 [get_ports data_in[*]] -clock [get_clocks clk]
set_input_delay -min 1 [get_ports data_in[*]] -clock [get_clocks clk]
# Set output delay constraints
set_output_delay -max 3 [get_ports data_out[*]] -clock [get_clocks clk]
set_output_delay -min 1 [get_ports data_out[*]] -clock [get_clocks clk]
# Set load capacitance on output ports
set_load 0.01 [get_ports data_out[*]]
# Define false paths (if any)
set_false_path -from [get_ports reset] -to [get_ports data_out[*]]
# Set maximum fanout for specific ports
set_max_fanout 10 [get_ports data_in[*]]
Verilog Constructs to Avoid
Ensure that the Verilog code adheres to synthesizable constructs; not all Verilog features are suitable for synthesis.
Initial Blocks | The initial block is used for testbenches but is not synthesizable. It is ignored during synthesis. |
Delay Constructs | Any use of delays (e.g., #10) is not supported in synthesis. Such constructs are only relevant for simulation. |
Real Data Types | The real and time data types are not synthesizable. |
Fork/Join Constructs | Keywords like fork , join , join_any and join_none are not supported in synthesis. |
Random Functions | Keywords such as $random are used for random number generation but are not synthesizable. |
X and Z States | The use of unknown (x) and high impedance (z) states is typically not allowed in synthesizable designs. |
Primitives | Only gate level primitives are supported. |
Force and Release | Force and release of data types not supported. |
When writing Verilog code intended for synthesis, it's crucial to avoid these unsupported keywords and constructs to ensure that your design can be correctly synthesized into hardware. Always refer to the documentation of the specific synthesis tool you are using, as there may be slight variations in support across different tools.
Comparison of X and Z
In Verilog synthesis, comparisons to x (unknown) and z (high impedance) states are generally ignored. This behavior can lead to unintended consequences if not understood properly. Here’s an example illustrating how synthesis tools handle these comparisons:
module compare_xz (
input wire b,
output reg a
);
always @(*) begin
if ((b == 1'bz) || (b == 1'bx)) begin
a = 1; // Set a to 1 if b is high impedance or unknown
end else begin
a = 0; // Set a to 0 otherwise
end
end
endmodule
In simulation, the conditions b == 1'bz and b == 1'bx can be evaluated. If b is high impedance or unknown, the output a will be set accordingly. But during synthesis, the synthesis tool ignores the comparisons to 1'bz and 1'bx. This means that the logic intended to handle these cases will not be realized in the synthesized hardware.
So, it is advisable to limit designs to binary states (0 and 1) and avoid using x and z for comparisons in synthesizable code. Instead, ensure that all signals are driven with defined values.
Multiple Driver
When multiple drivers attempt to drive the same signal in Verilog, it can lead to synthesis errors. This situation arises when two or more sources try to assign different values to a single net or wire, creating conflicts that the synthesis tool cannot resolve.
module multiple_drivers_example (
input wire clk,
input wire reset,
input wire enable,
output reg out
);
// First driver
always @(posedge clk or posedge reset) begin
if (reset) begin
out <= 0; // Reset condition
end
end
// Second driver
always @(posedge clk) begin
if (enable) begin
out <= 1; // Another assignment to out
end
end
endmodule
When synthesizing this code, the synthesis tool will encounter a "multiple drivers" error because both always blocks can potentially drive the same signal (out) at the same time. This creates ambiguity about which value (0 or 1) should be assigned to out, leading to a conflict.