Hierarchy and Datapaths
Clean Hardware Structure
How lint warnings expose unused signals, undriven outputs, width mismatches, and other structural risks before integration.
2 min read · Updated
Lint is an automated style-and-structure check for HDL. Simulation asks whether a chosen set of inputs produced expected outputs; lint asks whether the description contains suspicious structures even when a test happens to pass.
An unused signal is declared or computed but never consumed. It may be harmless cleanup, or it may reveal that a result was supposed to reach another block but was never connected.
An undriven output has no source. A port can exist in a module interface while no continuous assignment, procedural assignment, or submodule output supplies its value.
A width mismatch connects values with different bit counts. Sometimes extension or truncation is deliberate, but it should be visible in the code.
Arithmetic is the case worth memorising, because the rule is not the intuitive one: when an
addition is assigned directly to a signal, Verilog evaluates it at the width of the widest value
involved, either operand or the signal that receives the result. With eight-bit x and y,
wire [8:0] big;
assign big = x + y; // evaluated at 9 bits: the carry lands in big[8]is already correct. The carry is lost only when the sum passes through something narrower on the way:
wire [7:0] mid = x + y; // evaluated at 8 bits here: the carry is discarded
assign big = mid; // zero-extending afterwards cannot recover itWidening the final destination alone never helps; the fix belongs wherever the addition's result
first lands. Give that destination room for the carry, zero-extend the operands before adding
({1'b0, x} + {1'b0, y}), or drop the narrow intermediate entirely. Padding the finished sum,
{1'b0, x + y}, does not work: inside a concatenation the addition is sized by its own operands.
A combinational loop feeds a combinational result back into itself without clocked storage to separate one update from the next. That structure has no simple “previous cycle” value and usually signals a design error.
Treat warnings as questions to answer, not messages to silence. Identify the class, trace the affected route, and make the intended width or driver explicit.