A semantic linter for Verilog, built on pyverilog's AST. It looks for where the RTL you wrote diverges from what you meant — latch inference, blocking/non-blocking misuse, multi-driver conflicts — the bugs that pass simulation clean and only show up after synthesis.
Windows executable, no Python required. Still needs Icarus Verilog installed separately.
Or install from source (macOS / Linux / WSL)
Live example
Run against a Verilog file with seven deliberately planted bugs — one of every rule the checker knows.
Rules
Not a syntax linter — a semantic one. Every rule here targets a class of bug that iverilog or a testbench will happily let through.
| rule | what it catches |
|---|---|
| if-without-else | Combinational if with no else — classic latch inference risk. |
| missing-default-case | Combinational case/casex/casez with no default branch. |
| blocking-in-seq | Blocking (=) assignment inside a posedge/negedge block — race condition risk. |
| nonblocking-in-comb | Non-blocking (<=) assignment inside combinational logic. |
| unused-signal | Declared but never read anywhere in the module. |
| undriven-signal | Read somewhere, but never assigned within the module. |
| multi-driver | Same signal driven by more than one always block. |
Validation
Getting a trustworthy pass took real debugging against real designs — including a taped-out RISC-V core and open-source Verilog the author didn't write. That process is documented in full in the repo.