Draft preview. Lessons are being written and reviewed.

Digital Design / Module 11: Designing for silicon

61. Lint and code quality

Catch bugs before simulation.

Lecture coming soon

See it move

The idea

Lint tools check RTL against a set of rules, with no simulation and no test vectors. They can find a whole class of bugs in seconds, and they often catch issues that simulation can't.

What lint catches

IssueWhy it matters
Width mismatchValues get silently cut or extended
Multiple driversConflicts cause x in simulation, and contention in hardware
Inferred Usually unintended
Incomplete sensitivity listSimulation and gates disagree
Blocking in clocked blockRaces and lost stages
Unused signalsOften a real wiring mistake
Unintended clock or reset logicGlitches, hard timing

Width rules

Verilog silently resizes values, and this causes real failures.

wire [7:0] a, b;
wire [7:0] sum = a + b;      // the carry is lost
wire [8:0] ok  = a + b;      // keeps the carry

Be explicit, and use sized constants like 8'd1 instead of plain 1.

Stating your assumptions

SystemVerilog lets you turn assumptions into checks. unique case says that exactly one branch matches, and priority case says that at least one must, in order. Tools warn when reality differs. Use them only when you mean them, though, since they also permit optimisations that assume the claim is true.

A team habit

Run lint before every commit, and keep the design warning-free. Once a block has 200 known warnings, nobody will notice the new, important one. If a warning is truly fine, waive that specific one with a written reason, and don't turn off the rule.

Common mistake

Treating lint as a last step before tapeout. Issues are far cheaper to fix on the day they're written. Lint also isn't a replacement for CDC and RDC tools, which check clock and reset crossings specifically. Work through the examples in the animation above, and see whether you can spot each issue first.

Key ideas

  • Width mismatches and multiple drivers are common.
  • Unique and priority keywords make assumptions explicit.
  • Treat warnings as work to resolve.

Your exercise

Clean up a supplied file with ten lint issues.

Interview questions

coreWhy does width mismatch matter?

basica and b are 8-bit, and sum8 is declared as wire [7:0] sum8 = a + b;. What is sum8 for a = 200, b = 100, and why is there no error?

basicWhat can a lint tool find that simulation might not, and what is it not a replacement for?

coreA testbench checks sum8 from the previous question with this line, over 1000 random pairs, and reports no failures. Why does the test miss the lost carry?

if (sum8 !== a + b)
  errors = errors + 1;

coreWhat does a simulator show for m when p = 1 and q = 0, and what is the hardware risk?

wire m;
assign m = p;
assign m = q;

coreWhat happens to r in this block when s is 2 or 3?

always @(*)
  case (s)
    2'd0: r = 8'h11;
    2'd1: r = 8'h22;
  endcase

coreWhat do unique case and priority case in SystemVerilog tell the tools, and when are they dangerous?

advanceda and b are 8-bit. What is avg for a = 200, b = 100, and how would you fix it?

wire [7:0] avg = (a + b) >> 1;

advancedx is declared reg signed [7:0] and holds -3. What does y become?

reg  signed [7:0] x;
wire signed [9:0] y = x + 4'd2;

Practise these 9 questions with animations