数字asic流程实验(EX2)Spyglss Lint
Spyglass Lint工具可以用于RTL代码检查,包括了语法检查,位宽不匹配检查,综合性检查等。尽管我们知道Design Compiler也具备Lint功能,但Spyglass作为专用Lint工具有着更好的性能。
一般Spyglass Lint操作可以插入到RTL编写阶段,在综合前对代码质量进行检查。
这里简单介绍一下Spyglass的Lint操作。
Spyglass可以通过GUI界面或者脚本进行调用。使用GUI界面操作的效率比较多,这里直接介绍自动化脚本。
类似于其他Synopsys软件,Spyglass可以通过tcl脚本进行操作:
set design_name "example"
# read in files
read_file -type sourcelist ../../prj/filelist.f
# read_file -type gateslib ../../lib/
read_file -type sgdc ../../src/sdc/${design_name}.sgdc
# setup
set_option top ${design_name}
set_option sdc2sgdc yes
current_goal Design_Read -top ${design_name}
link_design -force
# run lint
current_goal lint/lint_rtl -top ${design_name}
run_goal
# save project
save_project -force
上面的tcl脚本起到的作用包括了:读入文件,读入设计,运行RTL Lint以及保存工程四个步骤。
read_file命令用于文件的读入,可以用read_file -type verilog {xxx.v xxx.v}
的方式来挨个输入要读入的文件,更高效的做法是直接复用filelist.f文件,使用read_file -type sourcelist xxx.f
即可,此外如果编写了设计约束的话,可以通过read_file -type sgdc xxx.sgdc
的方式来进行读入。这里的sgdc可以写成复用sdc的方式,因为我们run DC的时候还是吃的sdc文件。
current_design xxx
sdc_data -file ../../src/sdc/xxx.sdc
注意后面要通过set_option sdc2sgdc yes
来对这个功能进行配合。
一些设计中的没有.v,需要被设为黑盒子的IP模块可以通过read_file -type gateslib xxxx.lib
的方式来实现读入。
读入设计阶段Design Read阶段会检查一下是否存在语法错误,如果顺利通过,那么就会进入RTL_Lint。Spyglass提供了许多不同的Lint功能,这里只简单介绍lint_rtl和lint_turbo_rtl这两种Lint。
通过current_goal
设置目前目标为lint_rtl,run_goal
命令开始运行lint,lint_rtl只对RTL代码进行Lint,此时可以不读入sgdc。如果Lint顺利通过,可以看到log中打印:
其中Fatals,Errors应该均为零,Warnings的内容可以具体内容具体分析。
通过gui_start
命令可以启动Spyglass的图形界面:
在下方的窗口里可以看到Message Tree,可以点开查看条目的具体内容。
通过点击上面的MS小按钮可以查看设计的原理图,和DC里面差不多。
如果读入了sgdc,那么可以进一步运行lint_turbo_rtl,将设计和约束文件在一起进行Lint。方法是点击上面的Goal Setup,勾选lint_turbo_rtl,然后点击Run Goal(s):
这里如果没有读入sgdc那么会报Fatal,如果有的话,那么可以和lint_rtl一样先看summary,然后看Message Tree做具体分析:
此外设计约束的编写检查也是一个重要的问题,如果需要单独对sdc进行检查,那么可以去Goal Setup中勾选sdc_audit和sdc_check。sdc_audit会检查sdc文件对设计的覆盖情况,是否存在没有被约束到的端口或寄存器等。sdc_check会对sdc的内容进行检查,适中定义是否清晰,是否出现了不一致的约束等。
结果同样可以和之前一样去看,举个例子,这里我写的sdc报了一个warning和一个error:
# Definition of Clock
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 Ideal Network
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]
# Definition of IO
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]
# Other Constraint
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
简单分析一下就可以知道,Warning来源于我在clock端口上也加了input delay的约束,在一般的操作中clock是不会加这个约束的。因此最好去sdc里面修改这个问题。另一个Error的来源在于我在这里将负载电容通过set_load设置成了3,这和spyglass rule中default_max_capacitance只有2产生了冲突。且spyglass声明了其不受到sdc中的set_max_capacitance命令的影响。因此这个问题的解决方式要么是:1.再读入综合库,一般库中会规定max_capacitance,以此覆盖spyglass rule中的default_max_capacitance; 2. 去脚本中通过set_parameter default_max_capacitance 5.6
来重新指定这个值; 3,干脆去修改sdc中的set_load。
用户可以根据自己的情况来处理这个问题。
所以我这里修改sdc之后就clean了。
# Definition of Clock
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 Ideal Network
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]
# Definition of IO
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]
# Other Constraint
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