-
Notifications
You must be signed in to change notification settings - Fork 30
Linter notes
This is a list of common Verilog coding errors, and best practices. TODO: make a similar page/section for VHDL.
The goal is to acquire a F/OSS linter which detects all of these errors and enforces these best practices. This may be done by using an existing tool (if one can be found), writing patches to improve an existing tool, or creating a new tool from scratch. The choice of which path to take will be made after this list is closer to final.
So far, this list is largely based on azonenberg's personal recollections of bugs he's found in his own code. Contributions are welcome!
These are legal, but discouraged (generate a warning?)
-
`default_nettype none
is required at the start of each HDL file, before any declarations - Mixing
<=
and=
assignments in the samealways
block is prohibited - (questionable, discuss:)
=
assignments are prohibited in clockedalways
blocks; possibly allow in combinatorialalways
blocks - All conditional paths in a combinatorial
always
block must assign all variables - Combinatorial
always
blocks must use*
rather than an explicit sensitivity list - If a
reg
starts at zero and is set to 1 by a clockedalways
block, but never set to 0, this is probably a flag somebody forgot to clear. Provide a Verilog attribute which can be attached to that wire if "sticking" is the intended behavior.
These are blatantly illegal for synthesis, generate an error for sure
- Multiple
always
blocks driving one net - Multiple
assign
statements driving one net -
assign
to a variable ofreg
type - Use of
#
delays (outside sim code) - Use of Z/X in a case statement (not casex/casez)
Just some musings here, nothing is definite...
This might be best done as a separate step (analysis on post-synthesis netlist)
- Require all signals originating at a top-level module port to be tagged
(* REFCLK = "clock_name" *)
- If no REFCLK constraint, the signal is assumed asynchronous to all clocks in the design
- All signals driving the input of a flipflop must be either ** Clocked by the same clock as the FF ** Tagged REFCLK = (same clock as the FF)
- The only exception is if the load FF is tagged (* CROSS_CLOCK *), indicating this is a deliberate clock domain crossing
- TODO: how to handle PLLs etc
- Otherwise, flag all clock domain crossings as potential timing errors
Things that we know need discussion, but don't have a set of rules yet
- Rules re sign extension, truncation, etc
This list includes both pure linters and tools which include some level of linting as one of their functions. F/OSS tools only, please.
- Icarus Verilog
- Verilator
- Yosys read_verilog