rtl coding guidelines
**RTL Coding Guidelines for Synthesis** are the **engineering best practices and coding conventions for writing Verilog/SystemVerilog (or VHDL) register-transfer-level descriptions that are correctly and efficiently synthesized into gate-level hardware — where violations of synthesis-friendly coding patterns produce unexpected logic (latches instead of flip-flops, priority encoders instead of parallel muxes), timing-critical designs, excessive area, or simulation-synthesis mismatches that cause silicon failures**.
**Why Coding Style Matters for Hardware**
Unlike software, where the compiler optimizes any equivalent code to similar machine instructions, RTL coding style directly determines the hardware structure. An if-else chain infers a priority multiplexer (long critical path); a case statement infers a parallel multiplexer (short critical path). A missing else branch infers a latch. The RTL code IS the hardware specification.
**Critical Coding Rules**
- **Complete Sensitivity Lists**: Use `always @(*)` (Verilog) or `always_comb` (SystemVerilog) for combinational logic. Missing signals in the sensitivity list cause simulation-synthesis mismatch — simulation reacts to listed signals only, synthesis generates logic for all inputs.
- **No Latches**: Every `if` and `case` in combinational blocks must have a complete `else`/`default` branch. Incomplete branches infer transparent latches, which are difficult to time, test, and are often design errors. Lint tools (SpyGlass, Ascent) flag inferred latches.
- **Synchronous Reset**: Use synchronous reset (`if (reset) ...` inside `always @(posedge clk)`) for most registers. Asynchronous reset (`always @(posedge clk or negedge rst_n)`) only where required by the power-on sequence. Mixing styles carelessly creates timing paths from reset to all registers.
- **Non-Blocking Assignments for Sequential Logic**: Use `<=` in clocked always blocks. Blocking `=` in sequential blocks can cause race conditions between simulation and synthesis.
- **Blocking Assignments for Combinational Logic**: Use `=` in always_comb blocks. Non-blocking `<=` in combinational blocks creates unexpected simulation behavior.
- **Single Clock Per Always Block**: Each always block should be driven by one clock edge. Multi-clock blocks are not synthesizable in most tools and indicate a CDC design issue.
**Synthesis Optimization Guidelines**
- **Resource Sharing**: Synthesis tools can share arithmetic units across mutually exclusive paths: `if (sel) y = a+b; else y = c+b;` uses one adder with muxed inputs. But `if (sel) y = a+b; else y = c+d;` requires two adders unless the tool recognizes the sharing opportunity.
- **Pipeline Registers**: Insert flip-flop stages to break long combinational paths. F_max is determined by the longest combinational path between any two registers.
- **Avoid Tri-State Internal**: Tri-state buses inside the chip are converted to multiplexers by synthesis. Use explicit multiplexers in RTL for clarity and predictable synthesis results.
**RTL Coding Guidelines are the bridge between the designer's intent and the synthesis tool's interpretation** — the coding discipline that ensures the hardware generated matches the hardware intended, preventing the class of bugs that appear as correct simulation but incorrect silicon.