Spyglass Lint is a dedicated tool for RTL code quality checks, covering syntax verification, bit-width mismatch detection, and synthesis readiness analysis. While tools like Design Compiler include basic Lint capabilities, Spyglass offers superior performance for pre-synthesis code validation.
Tpyically, Spyglass Lint is integrated early in the RTL development phase, before synthesis, to catch issues early. This article introduces the core Lint workflow using automated scripts rather than manual GUI interaction.
Script-Based Operation
Like many Synopsys tools, Spyglass can be driven via Tcl scripts. A typical Lint run follows these steps: file reading, design setup, goal selection, and execution. Below is an example Tcl script:
set top_module "my_design"
# Read source files from a list
read_file -type sourcelist ../../prj/filelist.f
# Optional: read SGDC constraints
read_file -type sgdc ../../src/sdc/${top_module}.sgdc
# Configure top-level module and enable SDC-to-SGDC conversion
set_option top ${top_module}
set_option sdc2sgdc yes
current_goal Design_Read -top ${top_module}
link_design -force
# Run RTL Lint
current_goal lint/lint_rtl -top ${top_module}
run_goal
# Save the Spyglass project
save_project -force
File Reading Strategies
The read_file command supports multiple formats:
- Individual files:
read_file -type verilog {a.v b.v} - File list:
read_file -type sourcelist filelist.f(more efficient for large designs) - Constraints: SDC files can be read as SGDC after enabling
set_option sdc2sgdc yes. A separate SGDC file is also supported usingread_file -type sgdc. - Black-box modules: Liberty library files (
.lib) can be loaded usingread_file -type gateslibwithout corresponding Verilog sources.
When reusing SDC constraints, include them in a separate script and feed into Spyglass with read_file -type sgdc. The SDC script might look like:
current_design my_design
sdc_data -file ../../src/sdc/my_design.sdc
Design Read and Lint Goals
The Design_Read goal performs basic syntax checks. If it passes, you can proceed to Lint goals. Spyglass offers various Lint variants; the two most common are:
- lint_rtl: Checks RTL code only (no SGDC required).
- lint_turbo_rtl: Checks RTL together with timing constraints (SGDC needed).
After running lint_rtl, the log should show zero Fatals and zero Errors. Warnings should be reviewed case by case.
# Summary example:
# Fatals: 0 Errors: 0 Warnings: 5
GUI Interaction (Optional)
You can launch the Spyglass GUI with gui_start. The Message Tree panel displays detailed issues. The schematic view (MS button) is similar to Design Compiler’s schematic viewer.
To run lint_turbo_rtl (requires SGDC), use the Goal Setup dialog, check lint_turbo_rtl, and click Run Goal(s). Without SGDC, a Fatal error will occur.
SDC Constraint Checks
Spyglass provides dedicated goals for SDC verification: sdc_audit and sdc_check. sdc_audit reports coverage gaps (unconstrained ports/registers). sdc_check validates SDC semantics and consistency. Results appear in Message Tree.
Below is an example SDC file that initially triggered warnings and errors:
# Original SDC with issues
set Tclk 20 ;#50MHz
set clk_name "clk"
set unc_perc 0.05
create_clock -name $clk_name -period $Tclk [get_ports clk]
set_clock_uncertainty -setup [expr $Tclk * $unc_perc] [get_clocks $clk_name]
set_clock_transition 0.4 [all_clocks]
set_dont_touch_network [get_ports clk]
set_ideal_network [get_port clk]
set_dont_touch_network [get_ports rst_n]
set_ideal_network [get_port rst_n]
set_input_delay [expr $Tclk*1/5.0] -clock $clk_name [all_inputs]
set_output_delay [expr $Tclk*1/5.0] -clock $clk_name [all_outputs]
set_max_transition 0.6 [current_design]
set_max_fanout 64 [current_design]
set_max_capacitance 3 [current_design]
set_input_transition -max 0.5 [all_inputs]
set_load 3 [all_outputs]
set_max_leakage_power 0
set_max_area 0
The warning arose because set_input_delay was applied to the clock port, which is not recommended. The error came from set_load 3 exceeding Spyglass’s default default_max_capacitance of 2. Note that Spyglass does not honor set_max_capacitance from SDC for this check.
Three solutions exist:
- Load a synthesis library that defines maximum capacitance values, overriding Spyglass defaults.
- Modify the Spyglass parameter:
set_parameter default_max_capacitance 5.6in the Tcl script. - Adjust the SDC: lower
set_loador useremove_input_delayon the clock port.
After applying the third option, the SDC becomes clean:
# Clean SDC
set Tclk 20
set clk_name "clk"
set unc_perc 0.05
create_clock -name $clk_name -period $Tclk [get_ports clk]
set_clock_uncertainty -setup [expr $Tclk * $unc_perc] [get_clocks $clk_name]
set_clock_transition 0.4 [all_clocks]
set_dont_touch_network [get_ports clk]
set_ideal_network [get_port clk]
set_dont_touch_network [get_ports rst_n]
set_ideal_network [get_port rst_n]
set_input_delay [expr $Tclk*1/5.0] -clock $clk_name [all_inputs]
remove_input_delay [get_ports clk]
set_output_delay [expr $Tclk*1/5.0] -clock $clk_name [all_outputs]
set_max_transition 0.6 [current_design]
set_max_fanout 64 [current_design]
set_max_capacitance 2 [current_design]
set_input_transition -max 0.5 [all_inputs]
set_load 2 [all_outputs]
set_max_leakage_power 0
set_max_area 0