When writing synthesizable Verilog / System Verilog code, it is important to follow certain guidelines to ensure the code can be correctly synthesized into hardware using a synthesis tool. Here are some basic guidelines for writing synthesizable Verilog / System Verilog code:
-
Clearly define modules and interfaces: To ensure clarity and consistency in your code, define modules and interfaces with proper ports and data types. Clearly state the purpose and functionality of each module and use descriptive names for signals and variables.
-
Use non-blocking assignments for sequential logic: For accurate modeling of flip-flops, use non-blocking assignments (<=) inside
always_ff
oralways_comb
blocks for sequential logic. Non-blocking assignments ensure simultaneous updates in the next clock cycle. -
Use blocking assignments for combinational logic: In combinational logic, use blocking assignments (=) inside
always_comb
blocks for immediate updates. Blocking assignments ensure that updates occur immediately and in the order they are written. -
Avoid inferring latches: Unless explicitly required, avoid inferring latches. To prevent latch inference, cover all possible input combinations in your design and provide a default assignment for all variables in the
always
block. -
Specify edge-sensitive constructs for flip-flops: Specify the triggering conditions for flip-flop updates using
posedge
(positive edge) ornegedge
(negative edge). This ensures that flip-flops are updated only when the specified edge occurs on the clock signal. -
Limit the usage of
always @(posedge clk)
: Enhance readability and synthesis efficiency by minimizing the use of clock-sensitive constructs outside the main sequential logic, such asalways @(posedge clk)
. Use them only where necessary to avoid unnecessary updates and potential timing issues. -
Explicitly define sensitivity lists in procedural blocks: Ensure proper signal sensitivity by explicitly specifying sensitivity lists in
always_comb
,always_ff
, oralways_latch
blocks. This helps avoid unintended synthesis issues and makes the code more robust. -
Use
always_ff
for synchronous logic: For synchronous logic, usealways_ff
blocks to maintain explicit control over clock and reset signals, ensuring proper synchronization. -
Avoid race conditions: Prevent race conditions where multiple signals drive the same output by using proper coding techniques, such as prioritization. Race conditions can lead to unpredictable results and should be avoided.
-
Write portable code: To make your Verilog/SV code portable across different synthesis tools and FPGA vendors, avoid using vendor-specific or tool-specific constructs or pragmas unless explicitly required for your target platform. This ensures compatibility and facilitates ease of migration.
-
Prefer the
logic
data type: For better compatibility and readability, use thelogic
data type instead ofreg
. Reserve the use ofreg
for variables with scheduling semantics. -
Utilize enumerated types (
enum
): Enhance clarity and maintainability by usingenum
to define state machines or control signals. Enumerated types provide a concise and organized way to represent a set of values. -
Follow coding style guidelines: Maintain consistent indentation, naming conventions, and comments throughout your code. Following coding style guidelines improves code readability and facilitates understanding and maintenance.
-
Validate synthesis results: After synthesizing your code, validate the synthesized output using reports and physical design tools. This ensures that the hardware matches the intended design and meets performance requirements.
Popular Synthesis Tools: Here are some popular synthesis tools widely used in the industry:
- Cadence Design Systems – Genus Synthesis Solution
- Synopsys Inc – Design Compiler, DC NXT, Fusion Compiler
- Mentor Graphics – Precision RTL Synthesis
- Xilinx – Vivado Synthesis
- Intel Corporation – Intel Quartus Prime
- Open Source – Yosys Open Synthesis Suite
Following these guidelines will help you write synthesizable Verilog / SV code that can be correctly synthesized into hardware. This will save you time and effort in the long run and will help you to create reliable and efficient electronic systems.
I hope this blog post was helpful. If you have any questions, please feel free to leave a comment below.