Lint Your RTL#
Linting checks your RTL for syntax and style problems without compiling
it, and it is the quickest way to get a real result out of SiliconCompiler. No
PDK, no cloud account, and – unusually – no EDA tools to install.
The default linter, slang, ships as a Python package
that comes with SiliconCompiler itself, so this works immediately after
pip install.
A run takes about ten milliseconds.
The script#
Save this next to a Verilog file called blinky.v:
from siliconcompiler import Design, Lint
from siliconcompiler.flows.lintflow import LintFlow
design = Design("blinky")
design.set_dataroot("root", __file__)
with design.active_dataroot("root"), design.active_fileset("rtl"):
design.set_topmodule("blinky")
design.add_file("blinky.v")
project = Lint(design)
project.add_fileset("rtl")
project.set_flow(LintFlow())
project.run()
project.summary()
The shape is the same as every other SiliconCompiler script – describe the
design, pick a flow, run – with two differences: the project type is
Lint rather than ASIC, and no target
is loaded, because there is no technology to target.
What it tells you#
On clean sources the run says so and stops:
| INFO | job0 | lint | 0 | Number of errors: 0
| INFO | job0 | lint | 0 | Number of warnings: 0
| INFO | job0 | lint | 0 | Finished task in 0.01s
Give it something broken – a mistyped signal name and an out-of-range bit select – and you get the diagnosis with the source line:
| ERROR | blinky.v:13:24: error: use of undeclared identifier 'count'
| ERROR | counter <= count + 1'b1;
| ERROR | ^~~~~
| ERROR | blinky.v:14:32: warning: cannot refer to element 8 of 'reg[7:0]' [-Windex-oob]
| ERROR | led <= counter[N];
| ERROR | ^
| INFO | Number of errors: 2
Both counts are recorded as metrics – [metric,errors]
and [metric,warnings] – so they appear in
Project.summary() and can be read back afterwards. Read them from the
history object Project.run() returns: job-scoped metrics are reset on
the live project when the job finishes, so the completed values live there.
history = project.run()
history.get("metric", "errors", step="lint", index="0")
That is what makes linting worth scripting rather than running by hand: the result is a number you can gate on.
Choosing the linter#
LintFlow takes a tool argument:
project.set_flow(LintFlow()) # slang (default)
project.set_flow(LintFlow(tool="verilator")) # verilator
project.set_flow(LintFlow(tool="all")) # both, as separate nodes
slang needs nothing installed. verilator is an
external tool and has to be available on your machine,
but it catches a different class of problem, which is what tool="all" is
for – it builds one node per linter and runs them side by side.
The lint script above passes -Weverything to slang, so you are seeing
everything it has to say.
In a real build script#
examples/heartbeat exposes linting as one target among many, so the same
design can be linted, synthesized, simulated or hardened without editing
anything:
def lint(N: Optional[str] = None):
"""Runs the linting flow on the Heartbeat design.
Linting checks the Verilog source code for syntax errors and style
issues without performing a full synthesis.
Args:
N (str, optional): The value for the Verilog parameter 'N'.
Defaults to None, which uses the value set in the design schema.
"""
# Create a project instance tailored for linting.
project = Lint()
# Instantiate the design configuration.
hb = HeartbeatDesign()
# Associate the design with the project.
project.set_design(hb)
# Add the necessary fileset for this flow.
project.add_fileset("rtl")
# Optionally override the 'N' parameter from the command line.
if N is not None:
hb.set_param("N", N, fileset="rtl")
# Configure the project to use the linting flow.
project.set_flow(LintFlow())
# Execute the flow.
project.run()
# Display a summary of the results.
project.summary()
cd examples/heartbeat
smake lint # or: smake lint --N 16
See Run a build script’s targets without editing it for how that works, and Example designs for the rest of what this one can do.
Next#
Simulate your design – the next cheapest check, and still no PDK.
Quickstart – the same design taken all the way to a layout.
How do I…? – recipes for the things you will want next.