Ostensibly incorrect synthesis by SynplifyPro, result differs from Icarus Verilog & Verilator

2026-05-21

Stack Overflow: View Question

Tags: verilog, signed, hdl, register-transfer-level, saturation-arithmetic

Score: 0 | Views: 103

The asker wrote a parameterized signed saturating truncator: take a WIN-bit signed input, produce a WOUT-bit signed output that clamps to MAX/MIN if the input falls outside the representable range, and sign-extends when WOUT >= WIN. Icarus and Verilator simulate the module correctly, but SynplifyPro synthesizes hardware whose behavior diverges from both simulators — a classic "passes sim, fails on the board" trap.

Why this is interesting: Saturation logic is one of the most error-prone idioms in RTL because it mixes three sharp edges of the Verilog language at once:

Direction toward an answer:

Gotchas: when WOUT >= WIN the saturation branch must be unreachable, but generate-time conditionals often still synthesize the dead arm and can introduce unsigned literals into the always block. Wrap the saturation in a generate if so the dead logic vanishes from the netlist. Also: if any intermediate is declared reg rather than reg signed, sign info is lost across the assignment regardless of the RHS.

The challenge: Saturation arithmetic exposes the gap between Verilog's loose signedness/width rules and how individual synthesis tools resolve them, making "works in sim" a misleading proof of correctness.

All newsletters