Skip to article

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 it

Widening 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.