今日感想:学习只能慢慢搭积木,想一步登天可不行啊
在vcs仿真时调用$dump函数dump出fsdb文件,随后verdi load filelist和fsdb文件来进行debug
1、vcs两步仿真:先编译文件,生成simv可执行文件;后进行仿真
(compilation and simulation)
VCS:Verilog Compiler Simulator
问题一:当设计比较大的时候,每次都要全部重新编译一遍,比较浪费时间;
问题二:当设计中存在VHDL文件时,两步法就无法使用,因为VHDL文件需要单独处理。
2、vcs三步仿真:编译(compilation)、elaboration、和执行仿真(simulation)三步执行
elaboration:把各种资源进行整合链接,有些文章或书上说是建立层次关系,意思差不多,类似于c语言的link
适合于文件中存在多种语言,例如sv和vhdl同时存在
英文解释:Elaboration is the process of binding together the components of the design. Elaboration includes among other things creating instantiations, computing parameter values, resolving hierarchical names and connecting nets
. Often when referring to the compilation and elaboration phases they are not distinguished but are generally referred to as compilation.
3、CLI and GUI界面
(1)VCS有命令行模式和图形模式。
图形模式使用的是DVE,命令交互模式使用的是Unified Command-line Interface (UCLI) 。
(2)vcs中要调用ucli接口,执行脚本,必须在compile的时候,加入debug的权限:-debug,-debug_pp,-debug_all,-debug_access,-debug_region
。在run的时候,指定vcs -ucli [run_option],需要在编译时加入参数以开启ucli,否则ucli交互时只能使用简单的 ’run’、 ‘dump’、 'quit’命令。
4、带-
号的,一般是编译时用的,编译工具自带的。(编译选项)
带+
号的,一般是插件,环境,验证语言等加的,可扩展、自定义的。
5、VCS和VCS_MX区别
VCS_MX为mixed hdl仿真器,支持vhdl+verilog+sv
的混合仿真。VCS只支持verilog, sv。在feature上唯一的区别在于对vhdl的支持。如果没有vhdl的设计的话或许VCS好些,速度快些。
区分编译步骤和仿真步骤中加上的选项,添加错了位置选项就不起作用了
which vcs //查看vcs的安装路径
vcs -help //查看vcs的编译选项
vlogan
:vcs的编译指令,支持sv、v文件
vhdlan
:vcs的编译指令,支持vhdl文件
-sverilog
:支持SystemVerilog的语法
-f
:指定源文件的路径名列表,文件中可包括源代码文件的路径名称,和编译选项参数
-l
:指定vcs编译信息的存储文件
-ntb_opts uvm-1.2
:表示要引入UVM1.2的包,当然也可以选择使用1.0或1.1版本的,但是要注意这个选项不可缺少
-full64
:在64bit模式下编译、仿真,用于64位操作系统
-Mupdate
:源文件有修改时,只重新编译有改动的.v文件,节约编译时间。
-top
:设置顶层模块
+v2k
:支持Verilog-2001标准
+vcs+lic+wait
:一直等待licese
+licwait 100
:设置等待license的仿真超时时间
+memcbk
:查看多维数组
-error
:编译器遇到n个错误之后就停止
-o
:指定编译后产生的可执行文件名,默认编译后的文件名为simv
+incdir
:指定包含包含include文件的文件夹,以方便后续编译文件时不用逐个写出所有文件的路径,只需将其在pkg中include一下即可。可以指定多个目录,用+字符分隔每个路径名称
vcs top.v //编译verilog文件
vcs -sverilog top.sv //编译system verilog文件,要加选项
vcs -f file.list //按照顺序把源文件放到file.list里面,然后全部编译
vcs -sverilog +incdir+filespath pkg.sv //把相关的类定义放到一个package里面,pkg里面include源文件
vcs -l compile.log -sverilog top.sv //指定编译信息存储到log文件
vcs –sverilog design.sv –top work.tb1 //设置顶层模块
-R
:编译后立即进行仿真,如果不加这个会生成可执行文件后就退出了
-s
:在simulation仿真刚开始时立即停止,并进入交互模式。一般与-R和+cli配合使用
vcs cpu.v +cli+3 -R -s
-debug_all
:支持所有调试
-debug_pp
:同上,更加节约资源
-debug
:使能dve、verdi波形调试和UCLI命令行调试
-debug_access
:vcs -debug_access时,不需要再手动配置PLI的tab file verdi.tab 和静态库 pli.a,只需设置VERDI_HOME环境变量,vcs会自动查找所需文件,$fsdbDumpfile可以直接使用。
-debug_access+all 并不包含library(-v -y指定)和cell(celldefine编译原语标记的module,是cell module),无法PLI访问(如uvm_hdl_write)和波形dump。加上-debug_region=cell+lib
才可以正常访问。而-debug_all则是默认包含library和cell。(一般library和cell为标准单元,特别是在后仿,RTL综合成stdcell,被celldefine标记,而且PR也加入很多buf和inv, 降低仿真速度,增加波形文件size,如果不需要可以加上+nocelldefinepli+2,只dump module instance上的port波形)
-debug_access是新推出来的选项,更好地控制仿真过程中的调试性能
也就是说,debug_all和配置PLI,或者-debug_access+all和-debug_region选项
现在前仿过程中不涉及工艺库那些信息,所以就可以直接使用-debug_acc+all
!!!就可以了!
这个链接讲的很详细
配置PLI的方法
VERDI_PATH = /home/xxx/synopsys/verdi-2016.06-1/share/PLI/VCS/linux64
VERDI_ARGS = ${VERDI_PATH}/novas.tab \
${VERDI_PATH}/pli.a
编译选项加上-P ${VERDI_ARGS}
library cell:
design cell:
-y
:指定目录路径,定义verilog的库
-v
:设置搜索设计的文件,这两个参数和工艺库相关
+libext+
:让VCS在verilog库路径下搜索指定的扩展名文件,与-y配合
-lca
:(Limited Customer Availability)表示使用vcs“用户限制使用”功能,即vcs提供的一些功能,但该功能还未经过充分验证。
-kdb
:是lca下的一个feature,其作用是在vcs two-step flow和three-step flow中生成kdb databas,是vcs支持verdi很重要的选项
这两个命令加在一起:
vcs编译完后生成simv.daidir库文件,其中包含kdb.elab++文件
可以让verdi直接打开VCS编译之后的sim.daidir, 这样verdi可以直接trace代码
simv.daidir
:仿真生成的verdi的库文件,包含代码信息;verdi可以打开rtl代码而不需要重新编译
-debug_access -lca -kdb //vcs编译时加上这个选项,为了后面使用verdi
//使用kdb的几种方法
verdi -elab ./simv.daidir/kdb
verdi -dbdir simv.daidir
verdi -simBin simv
verdi -ssf top.fsdb //加载kdb的同时加载波形,一般用这种方式
+nospecify
:不进行时序检查
+notimingcheck
:不进行时序检查,前仿为了加快仿真速度暂时不需要,两个选项一般一起用
+delay_mode_unit
:延时模型,都是在前仿用不到的一些参数
+vcs+flush+all
:dump vpd的波形需要的选项
+define+< macro_name>=< value>
:定义一个文本宏,与源文件中的 ifdef配合
//top文件有如下定义
initial begin
`ifdef dumpon
$dumpfile("results.vcd");
$dumpvars;
`endif
end
vcs -sverilog +define+dumpon -l compile.log top.sv //改变参数的定义
//需要修改的时候,又要重新编译,比较麻烦
+fsdb+dumpon+500ns
:vcs编译选项,仿真从500ns开始时dump波形
+ntb_random_seed=3
:添加随机种子
-simprofile
:可以记录vcs各模块仿真时间
-override_timescale=< unit>/< preciision>
:让源文件统一使用指定的timescale
-timescale=
:为在前面编译且没有`timescale的源文件指定timescale。time_unit采用就近原则,例如顶层文件定义timescale后,中间文件再次定义timescale后,则其后的文件按照中间文件定义的timescale执行
vcs -sverilog -timescale = 1ns/1ps -l compile.log top.sv
vcs -sverilog -timescale_override = 1ns/1ps -l compile.log top.sv //覆盖源代码中的仿真时间单位和精度,不推荐使用,会把模型的时间单位覆盖,可能导致模型功能错误
(这部分请查看另一篇博客,单独来讲解)
-l
:仿真日志
-gui
:开启GUI界面,否则就在linux终端显示transcript的内容
-ucli
:在linux终端使用TCL控制仿真进程(统一命令行界面模式)
-i
: 启动DVE后,在UCLI要启动的TCL命令。或者其他的文件,这样就可以不重新编译,直接进行输出波形等的调整,节约仿真资源
在这里可以执行一些tcl命令
scope: 显示当前的顶层模块
scope u1: 就表示进入到当前顶层模块中的u1模块,同时将u1模块设置为顶层模块
scope -up: 回到目前顶层模块的上一层。
show: 显示当前顶层模块的信号以及子模块
show -value 信号 -radix hex/bin/dec:显示信号的值 以特定的进制显示。
run:运行仿真run 一直运行,直到遇到$stop或者设置的断点
run time: 运行多少时间停止(不推荐)
run -posedge: 信号 运行到信号的上升沿停止
run -negedge: 信号 运行到信号的下降沿停止
run -change: 信号 信号有变化时停止
stop: 设置断点stop 显示断点
stop -posedge: 信号 在信号的上升沿设置断点
stop -negedge: 信号 在信号的下降沿设置断点
stop -condition {信号表达式}: 信号表达式为真的地方设置断点
stop -delete 断点值: 删除断点值的断点
restart: 重新开启ucli调试模式
call {系统任务}:调用verilog系统任务,
finish:结束仿真
force:信号强制赋值
release:解除信号强制赋值
get:获取信号数值
step:单步执行
do *.do:可将很多这些UCLI命令整合到一个*.do文件内,然后以打包运行
命令 –h:显示命令的帮助
-vcd
:将输出VCD文件名设置为指定文件。默认文件名为verilog.dump。Verilog源代码中的$dumpfile系统任务将覆盖此选项;
-verdi
:使用verdi图形界面
+vcdfile+
:指定想要用于后期处理的VCD文件;
-vpd_file
:在运行时,定义VCS写入的VPD文件的替代名称,而不是缺省名称vcdplus.vpd;
+define+VCS
:定义全局的VCS,编译器在编译时如果源文件有类似ifdef VCS等字样,那么会执行定义之后的代码。
+vcs+vcdpluson
:编译选项,加入后会使能产生vpd文件,默认文件名vcdplus.vpd
-vpd
:打开仿真波形,一般在末尾加&,表示在后台运行
输出波形
verdi需要在testbench中添加如下代码
initial
begin
$fsdbDumpfile("./top.fsdb"); //指定输出波形名称
$fsdbDumpvars(0,tb);
//输出信号层级,0表示所有,1表示第一层,依次类推;
//tb表示例化的顶层模块名称
$fsdbDumpvars("+all"); //+all参数,dump SV中的struct结构体
$fsdbDumpSVA(); //将assertion的结果存存储到fsdb中
$fsdbDumpMDA(0, top); //dump memory arrays
end
if($test$plusargs("FSDB_ON"))
:表示从命令行读取参数并判断是否开启波形dump处理。如果去掉这个if判断,就表示无条件的波形dump。当然,正式项目开发中通常会加上条件判断,将开关控制权留到实际做仿真时去。因为回归验证由于要做大量的仿真,通常是不会dump波形,只有单个testcase的调试时才会进行仿真验证。
vcs在仿真时指定这个参数
vcs ... +FSDB_ON ...
verdi:分析过程,跟踪信号,比vcs自带的dve功能更强
-ssf filename.fsdb
:打开波形文件
-f filelist.f -top adder
:打开rtl代码,顶层模块名为adder
-nologo
:不显示verdi的启动log信息
常用的如下:
verdi -ssf test.fsdb -f filelist.f -top tb_top -ntb_opts uvm-1.2 -nologo
4.1 verdi使用方法
上面的界面:nTrace
下面的波形:nWave
(1)点击dut里面的信号,右键添加到波形图中,或者crtl+w
也可以点击红色图标,打开对话框去选要添加的信号
(2)快捷命令:
波形图左击选中部分波形
:可以放大波形
按f键
:全屏显示所有的波形
shift+滚轮
:左右移动波形
ctrl+滚轮
:放大或者缩小波形
保存添加到窗口的波形
:save,保留成rc文件,方便查看
追踪信号
:选中信号,点左上面一排的绿色的向右向左的图标
信号分组
:选中信号,按照滚轮移动信号到别的分组,或者一开始的时候就进行分组
统计时钟上下升沿个数
:
data有很多位,包含地址和数据,可以进行分开查看edit bus
:
查看数值logical operation
:选中信号,右键,最下面的选项
然后再去统计个数,就可以知道该信号这个数值有多少次
查找信号Find Scope
:crtl+S
1、编译选项
vlog:questasim的编译命令
-sv
:指示vlog按照systemverilog语法进行编译,编译后会生成一个库,由于以上没有指定,缺省的库名就是work。如果要显式地指定不同的库名,可以追加选项“-work libname”。
2、仿真选项
vsim:仿真的命令
-c
:以命令行的形式执行,不开启图形化界面
-vopt
:进行优化
-novopt
:不进行优化,在调试时通常使用这个选项,这个会使得仿真速度慢一些
-classdebug
:方便调试。仿真后,view的class browser
中,class tree可以清晰的看到各个类的继承关系
-coverage
:在仿真时产生代码覆盖率数据,功能覆盖率数据默认生成,与此项无关
-solvefaileddebug
:使能输出随机化失败等更多调试信息
+UVM_TESTNAME=
: 需要根据代码中不同的test,来决定仿真运行哪一个test,在top文件中则只需要启动run_test( )
函数
-sv_seed
:随机化种子,可以指定,-sv_seed 0
;不指定,-sv_seed random
;
-quiet
:关闭loading信息,不显示
-l
:输出仿真的log文件
-do
:开始仿真后运行tcl脚本(控制文件)
-L
:加载所需要的仿真库
-quiet
:关闭loading的信息
vsim -c -novopt -sv_seed $SEED -l sim.log +TESTNAME=case1
3、vmap:映射逻辑库名到指定的目录
4、在文件开头和尾部加入如下
防止代码被重复编译
ifndef
:编译命令,是if not defined的缩写,主要是根据其后的宏是否存在于当前编译空间来进行分支选择。第一次会执行下面的define
,执行顶层时,该宏已经存在编译空间中,所以不会被重复编译
`ifndef MY_TRANSACTION__SV
`define MY_TRANSACTION__SV
//my_codes
`endif
(问题1-4是连续发生)
问题1:编写makefile脚本后,执行make all,遇到如下问题
解决方法:
(1)按照下面这个办法,打开vcs文件,1200行没有这句话
(2)在编译选项添加-full64
即可,问题解决
问题2:遇到过好几次
collect2: error: ld returned 1 exit status
Makefile:104: recipe for target 'product_timestamp' failed
make: *** [product_timestamp] Error 1
解决方法:确保gcc版本为4.8,然后添加选项
vcs -full64 -cpp g++-4.8 -cc gcc-4.8 -LDFLAGS -Wl,--no-as-needed -sverilog -debug_all -timescale=1ns/1ps -f file.list -l com.log
问题3:
make[1]: g++4.8: Command not found
Makefile:104: recipe for target 'product_timestamp' failed
make[1]: *** [product_timestamp] Error 127
make[1]: Leaving directory '/home/xxx/test/csrc'
Make exited with status 2
CPU time: .107 seconds to compile + .016 seconds to elab + .077 seconds to link
makefile:4: recipe for target 'com' failed
make: *** [com] Error 2
又报错了!哭!破案了!!!!
–no-as-needed复制到makefile里面变成了-no-as-needed,总算解决了
(ps:好多时候都是这种低级错误,然后整好久)
问题4:前面都没问题,dve执行又报错了
ERROR - /home/xxx/synopsys/vcs-2016.06/gui/dve/linux/bin is not valid directory.
Check if DVE variable is valid. If you want to run 64bit, please use -mode64 or -full64 option.
解决方法:暂时没找到解决方法,但是仔细发现,我最开始用的设计里面是没有添加波形的,可能就出错了。然后换了一个设计就跑成功了!!!看到最后面那句话也就是运行成功了。
问题5:2023.2.26
想用vcs去编译整个仿真环境,把文件添加到了ahb2apb/dv/etc/tb.f tc.f
文件夹下,但是找不到这些文件
Error-[SFCOR] Source file cannot be opened
Source file "$DV_ROOT/vip/ahbl_mst/ahbl_mst_pkg.sv" cannot be opened for
reading due to 'No such file or directory'.
Please fix above issue and compile again.
问题原因:
本来是想设置绝对路径去做,在最上面声明项目的绝对路径,这样下次移植时只要修改变量名即可。
在f文件里面使用了makefile文件里面定义的变量,这个变量好像并没有传递到我要去编译的f文件,没有替换到变量名,于是系统无法识别该变量,所以找不到文件。
解决方法:
为什么变量没有传进去,可能是该变量只在makefile文件里面有效?
法一:要用export
!我只写了变量等于什么,并没有export进去!
法二:没有用绝对路径了,改用相对路径,把各个f文件里面的路径修改成相对于makefile文件的路径。在filelist文件中用相对路径的话,都是相对于makefile文件的相对路径。
问题6:语法错误
解决方法:
-f选项只对rtl.f文件产生效果,后面的tb.f tc.f被当成设计文件去编译了
应该加三个-f选项
问题7:
Error-[UST] Undefined System Task Call
/home/heliu/ahb2apb/dv/tb/ahb2apb_tb.sv, 150
Undefined System Task call to '$fsdbDumpfile'.
解决方法:
配置verdi的库文件
编译选项加上-P
问题8:报错说run test函数没有例化对象
发现是+UVM_TESTNAME=${TC}
写成了+UVM_TESTNAME = ${TC}
。中间等号间隔开了就不行。
问题9:(2023.3.16)
我想把每次随机后的种子记录下来写到log文件名称里面。但是生成的文件名称没有log文件后缀,不知道为啥()
解决方法:
在开头声明这个变量,然后后面再去使用,这样就没有报错了,但是原因未知
com_log_name = ${testname}_${SEED}
-l ./log/${com_log_name}.log \