Verdi 简单使用

使用Verdi 代替VCS 查看波形

使用VCS 生成FSDB, Verdi 打开FSDB

使用VCS 生成FSDB 波形文件

编译工程

1
vcs +vcs+lic+wait +v2k +systemverilogext+.sv +verilog2001ext+.v -Mupdate  -debug_acc+all -debug_region+cell+encrypt +lint=all,noIEELMME,noTMR,noVCDE -timescale=1ns/1ps -lca -kdb -debug_access+all -debug_access+r+w+nomemcbk -debug_region+cell +vpi -CFLAGS -DVCS -f filelist.f | tee ./compile_vcs.log

运行 simv 生成fsdb

1
./simv -l ./my_verdi.log -ucli -i my_verdi.tcl 1ms

my_verdi.tcl 主要用于指定控制生成fsdb 的行为, 内容如下:

1
2
3
4
5
6
# 设置fsdb 的名字
fsdbDumpfile "my_tb.fsdb"
# 设置波形的顶层和层次,表示将tb_top作为顶层,Dump所有层次
fsdbDumpvars 0 "tb"      
run 1ms
exit

使用Verdi 打开fsdb

1
verdi -ssf my_tb.fsdb

当打开fsdb 之后, 如果设计改变了, 只需要重新生成 fsdb 文件, 然后在Verdi 中按Shift+l 即可Reload Design 非常方便

完整的Makefile 示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#TOP MAKEFILE
SRC_DIR = /mnt/hgfs/plh_work/work/G3001/G3001
RUN_CMD = cd ~/G3001_sim; export MY_SRC_DIR=$(SRC_DIR); cp $(SRC_DIR)/systerms/tb/my_* .;
FILE_LIST = $(SRC_DIR)/filelist.f

export DEMO_NAME=G3001

# VCS_OPTIONS = +vcs+lic+wait +v2k +systemverilogext+.sv +verilog2001ext+.v -Mupdate  -debug_all +lint=all,noIEELMME,noTMR,noVCDE -timescale=1ns/1ps
# -debug_acc+all -debug_region+cell+encrypt instead -debug_all to destroy Wrong
VCS_OPTIONS = +vcs+lic+wait +v2k +systemverilogext+.sv +verilog2001ext+.v -Mupdate  -debug_acc+all -debug_region+cell+encrypt +lint=all,noIEELMME,noTMR,noVCDE -timescale=1ns/1ps

# VCS_OPTIONS = -debug_access+all -debug_region+cell +vpi +systemverilogext+.sv +verilog2001ext+.v -CFLAGS -DVCS -timescale=1ns/1ps

VCS_GUI_OPTIONS = -gui +vcs+lic+wait +vcs+flush+log

VCS_NOGUI_OPTIONS = +vcs+lic+wait +vcs+flush+log +vcs+loopreport

# VERDI_OPTIONS_COMPILE = -lca -kdb -debug_access+all +acc +vpi -CFLAGS -DVCS
# -debug_access+r+w+nomemcbk -debug_region+cell instead +ass to destroy Wrong
VERDI_OPTIONS_COMPILE = -lca -kdb -debug_access+all -debug_access+r+w+nomemcbk -debug_region+cell +vpi -CFLAGS -DVCS

VERDI_OPTIONS_RUN = -verdi

# compile
vcs_compile:
	export MY_SRC_DIR=$(SRC_DIR)
	$(RUN_CMD) vcs $(VCS_OPTIONS) -f $(FILE_LIST) | tee ./compile_vcs.log
vcs_run:
	$(RUN_CMD) ./simv
vcs_all:
	export MY_SRC_DIR=$(SRC_DIR)
	$(RUN_CMD) vcs $(VCS_OPTIONS) -f filelist.f | tee ./compile_vcs.log
	$(RUN_CMD) ./simv

vcs_verdi_fsdb:
	pkill dve.exe || true
	$(RUN_CMD) vcs $(VCS_OPTIONS) $(VERDI_OPTIONS_COMPILE) -f $(FILE_LIST) | tee ./compile_vcs.log
	$(RUN_CMD) ./simv -l $(MY_VCS_LOG) -ucli -i my_verdi.tcl 1ms

verdi:
	$(RUN_CMD) verdi -ssf $(DEMO_NAME).fsdb

vcs_verdi_compile:
	pkill dve.exe || true
	$(RUN_CMD) vcs $(VCS_OPTIONS) $(VERDI_OPTIONS_COMPILE) -f $(FILE_LIST) | tee ./compile_vcs.log
vcs_verdi:
	$(RUN_CMD) ./simv $(VERDI_OPTIONS_RUN) -l $(MY_VCS_LOG)

# 
vcs_all_nogui :
	pkill dve.exe || true
	$(RUN_CMD) vcs $(VCS_OPTIONS) -f $(FILE_LIST) | tee ./compile_vcs.log
	$(RUN_CMD) ./simv $(VCS_NOGUI_OPTIONS) -l $(MY_VCS_LOG) -ucli -i my_command_nogui.tcl 1s

# 如果存在 dve.exe 进程则杀掉
vcs_all_gui :
	pkill dve.exe || true
	export MY_SRC_DIR=$(SRC_DIR)
	$(RUN_CMD) vcs $(VCS_OPTIONS) -f $(FILE_LIST) | tee ./compile_vcs.log
	$(RUN_CMD) ./simv $(VCS_GUI_OPTIONS) -l $(MY_VCS_LOG) -i my_command.tcl
#	 $(RUN_CMD) ./simv $(VCS_GUI_OPTIONS) -l $(MY_VCS_LOG) -i my_command.tcl 2s wave.vpd.tcl

clean:
	$(RUN_CMD) rm -rf csrc/ simv.daidir/ simv

my_verdi.tcl 内容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
global env  
puts "$env(DEMO_NAME)"
# tcl脚本引用环境变量,Makefile中通过export定义 
# 设置波形文件名,受环境变量env(DEMO_NAME)控制 
# demo_name在makefile中使用export DEMO_NAME=xxx 
fsdbDumpfile "$env(DEMO_NAME).fsdb"
# 设置波形的顶层和层次,表示将tb_top作为顶层,Dump所有层次
fsdbDumpvars 0 "tb"      

if {[lindex $argv 4] != ""} {
    puts "run"
    run [lindex $argv 4]
}
exit

运行 make vcs_verdi_fsdb 可以编译并生成 fsdb 文件
运行 make verdi 可以查看fsdb 波形
在打开Verdi 后, 如果设计改变了, 只需要重新 make vcs_verdi_fsdb 然后再Verdi 中 Shift + l 即可 Reload Design 非常方便

Interactive Debug With Verdi (使用VCS 编译生成simv 然后 vcs 调用 verdi 查看波形)

编译生成 simv

1
vcs +vcs+lic+wait +v2k +systemverilogext+.sv +verilog2001ext+.v -Mupdate  -debug_acc+all -debug_region+cell+encrypt +lint=all,noIEELMME,noTMR,noVCDE -timescale=1ns/1ps -lca -kdb -debug_access+all -debug_access+r+w+nomemcbk -debug_region+cell +vpi -CFLAGS -DVCS -f filelist.f | tee ./compile_vcs.log

调用 verdi 查看波形

1
./simv -verdi

这种方法运行仿真后会生成默认的 inter.fsdb , 感觉不怎么灵活

如果设计改变的话, 可以在Verdi 中Simulation -> Rebuild and Restart


Custom Command 如下:

1
cd /mnt/hgfs/plh_work/work/G3001/G3001/; make vcs_verdi_compile 

先进入到Makefile 所在的目录再make 目标
完整Makefile 见完整的Makefile 示例

使用 nCompare 对比fsdb波形

生成差异信息

1
nCompare -fsdb G3001.fsdb -fsdb G3001_old.fsdb
_20220727_200406screenshot.png 这会生成 nCompareLog 文件夹, 里面比较有用的是 Default.nce 这个是错误文件

使用Verdi 查看波形差异

  1. 打开Verdi

  2. 打开波形窗口

  3. 在波形窗口下 Tools => nCompare

  4. 在nCompare 窗口 File => Open Err File 打开生成的 .nce 文件
    双击差异信号可以在波形窗口中查看差异

nWave 打开信号(signal)文件(xxx.rc) 并把信号重新排序

保存信号到文件

File => Save Signal 保存为 .rc 文件

编辑信号文件

_20220728_150904screenshot.png 假如想要对nWave 中的信号进行排序整理有两种方法:
  1. 一种办法是直接在nWave 里拖信号或者用m 移动到黄线处
  2. 直接编辑保存好的信号文件, 然后关闭波形窗口, 再新建一个nWave 窗口再打开 .rc 即可看到效果

查看覆盖率 (Verdi Coverage)

生成覆盖率

VCS 版本大于等于 2013.06

在编译时加入使能参数

1
2
3
vcs -debug_pp -P $(VERDI_HOME)/share/PLI/VCS/LINUX64/novas.tab \
    $(VERDI_HOME)/share/PLI/VCS/LINUX64/pli.a \
-f file_list.vc -cm line+tgl+fsm+cond+branch+assert -sverilog

-debug_pp -P $(VERDI_HOME)/share/PLI/VCS/LINUX64/novas.tab \
$(VERDI_HOME)/share/PLI/VCS/LINUX64/pli.a -cm line+tgl+fsm+cond+branch+assert
其中 -debug_pp -P $(VERDI_HOME)/share/PLI/VCS/LINUX64/novas.tab $(VERDI_HOME)/share/PLI/VCS/LINUX64/pli.a 指定了生成覆盖率需要的文件路径
-cm line+tgl+fsm+cond+branch+assert 指定了要收集哪些覆盖率

  • line
    源代码覆盖率
  • tgl
    信号翻转覆盖率
  • fsm
    状态机覆盖率
  • cond
    条件 覆盖率
  • branch
    分支覆盖率
  • assert
    断言覆盖率

在跑仿真时加入使能参数

1
./simv -cm line+tgl+branch+fsm+cond+assert

如果代码中有包含 UPF 文件, 还需要加入 -power=coverage+dump_hvp

1
2
3
4
> vcs -debug_pp -P $VERDI_HOME/share/PLI/VCS/LINUX/novas.tab \
    $VERDI_HOME/share/PLI/VCS/LINUX/pli.a \
    -sverilog <your design> -upf <your UPF power design> \
    -cm line+tgl+fsm+cond+branch+assert -power=coverage+dump_hvp

必须拥有Verdi license 🙂

查看覆盖率

1
2
> verdi -cov &
> verdi -cov -covdir simv.vdb &

上面那条而今只是打开了Verdi 的查看覆盖率的GUI 并没有导入数据库, 需要 File => Open database
下面那条命令是直接打开数据库可以立即看到覆盖率

忽略信号 ( excusion signal )

通常有一些常量被赋值给了 多bit 的 wire 或者 reg 就会导致有一些bit 是绝对不可能覆盖到翻转的
可以把这些信号排除在覆盖率检查上

在CovDetali 窗口中对着信号右键 => Exclude => Exclude

在源码窗口选中信号 右键 => Exclude 或者直接用快捷键 Shift + E

重新计算覆盖率

在Exclusion Manager 中右键 => Recalculate

把Exclusion 信号保存为文件 然后再Load 即可

File => Save all Exclusions
File => Load Exclusions => Load Exclusions from file

合并多个 coverage db (merge multile multi coverage db )

1
urg -dir sim1.vdb -dir sim2.vdb -dir simx.vdb -dbname merged.vdb 

或者 使用 filelist

1
urg -full64 -f vdb_filelist -dbname merge.vdb

波形窗口显示Radix prefix

Tools => Preferences => General => Miscellaneous 勾选 Display Radix Prefix

折叠一段波形 ( compress Time Range )

nWave 窗口下 View => Compress Time Range 然后填好时间后点Insert 就可以看到对应时间内的波形已经被折叠了

打开一段时间的波形 (open Dump File Time Range)

File => Open

需要改变显示时间范围的话可以 File => Set View Time Range

添加波形的几种方法 (add waveform)

默认添加module 下的所有信号( 除端口外还有本地信号 ) Include Local Signal

Tools => Preferences => Waveform => View Options => Miscellaneous => 选中 Include Local Signal(s)

_20221117_114201screenshot.png 不过这样选了之后, 加进去的波形的顺序会乱掉...

直接从Instance 窗口加

直接从源码加

可以选中一段代码, 直接拖到波形窗口( 或 Ctrl + w ), 或者鼠标放在信号上按Ctrl+w

在Signal 窗口加

通过OneSearch 快速查找到信号然后双击跳到源码窗口, 进而拖到波形窗口

通过Find Scope (Shift + s) 或者 Find Signal (Shift + a) 查找信号之后按Ctrl + w

调试Glitch

没试成功, 参考 https://www.bilibili.com/video/BV1Bd4y167VX/?spm_id_from=333.999.0.0&vd_source=f7f5b636932d6126d4d0bf40209e43db

编译选项

1
vcs ... -cm_glitch 1

1 是指一个 timescale 的 timeunit, 并且一定要是整数, 如果`timescale 1ns/1ps 的话, -cm_glitch 就是指过滤掉不超过1ns 的毛刺

一般来说-cm_glitch 1 是默认的数值, 也是推荐值

因为当使用 -cm_glitch 0 的时候, delta 里面必须是四舍五入后为0 实际情况是, delta 0 cycle 里面不是真正的0, 信号必然有先后顺序,
当波形中所谓的delta 0 很接近于0.1 ( 也可能是0.01 ) 的时候, 就不会还是 -cm_glitch 0 能够过滤掉的了, 所以, 一般情况下还是使用 -cm_glitch 1
如果时钟频率大于1 G 的话需要把timescal 设成 100ps/1ps

运行选项

1
simv ... +fsdb+delta

+fsdb+delta 等价于 +fsdb+glitch=0 +fsdb+sequential +fsdb+region

快速查找信号的memory 值

在源码中选中信号=> 右键 => Debug Memory => Show Memory Contents

快速对比两个fsdb (compare fsdb)

打开一个新的Verdio 不包含设计 ( 即直接命令行敲verdi )

打开第一个fsdb 放到一个容器里

nWave => Window => Dock to => New Container Window

打开第二个fsdb 放到第一个fsdb 所在的容器里

横向分屏

开启同步功能

快速获得一个信号的值 (fsdbreport)

使用 fsdbreport 工具

1
fsdbreport -h

使用 fsdbreport 成功之后会生成一个 report.txt 文件, 里面记录了目标信号的所有值

Examples:

  1. Assign the begin time and end time for the report.
    %fsdbreport verilog.fsdb -s /system/addr -bt 1000ps -et 2000ps

  2. Report a slice of a bus signal.
    %fsdbreport verilog.fsdb -s “/system/addr[7:4]”

  3. Report signals in the signal list with different formats.
    %fsdbreport fsdb/vhdl_typecase.fsdb -nocase -s top/A_SIMPLE_REC.FIELD3
    -a simple.field3 -w 15 TOP/A_COMPLEX_REC.F1.FIELD3 -a complex.f1.field3
    -w 20 top/a_std_logic_vector -af sean2.alias -of a -o output.txt
    -bt 1000 -et 2000

  4. Report a scope and its descendants. Multiple scopes may be specified.
    %fsdbreport rtl.dump.fsdb -bt 10 -et 100 -s “/system/i_cpu/*”
    -level 3 /system/i_pram/clock -cn 0

  5. Report the results for the specified strobe point using -strobe.
    %fsdbreport verilog.fsdb -strobe “/system/clock==1” -s /system/data
    /system/addr

  6. Report the results when the expression value changes to true.
    %fsdbreport verilog.fsdb -exp “/system/addr==‘h30 & /system/clock==1”
    -s /system/data

  7. Report the force, release or deposit information of the specified signals using -find_forces.
    %fsdbreport rtl.fsdb -find_forces -s “/system/i_cpu/*” -level 2 -o report.txt

  8. Report the force of the specified signals using -find_forces and -exclude_scope.
    %fsdbreport rtl.fsdb -find_forces -s “/system/i_cpu/*” -exclude_scope “/system/i_cpu/s1/*” “/system/i_cpu/s2” -o report.txt

设置Verdi 的Title

启动项中加入 -preTitle xxx 可以设置当前title

在波形窗口把某一个信号导出到文件

选中信号

nWave => File =>Report Selected Signals

箭头处是设置位宽, 如果数据比较小的话可以不设, 默认只有9 位

使用Verdi 调试约束 ( constains )

1
./simv -verdi

直拉交互模式 或者 进入verdi 之后 Window => Interactive Debug Mode

dump 数据到 fsdb

可用于约束Dump 的类型有:

把所有寄存器Dump 到 fsdb

  1. 在TCL 中或者源文件中
    1
    
        $fsdbDumpvars("Reg_Only")
    
  2. 使用 runtim option : ./simv +fsdb+reg_only
  3. 设置环境变量
    setenv FSDB_REG_ONLY 1

只Dump 指定路径下的信号

1
2
$fsdbDumpvars(0, "tb.dut.inst1");
$fsdbDumpvars(0, "tb.dut.inst2");

其中:

  • 0: all signals in all scopes
  • 1: all signals in current scopes
  • 2: all signals in current scopes and all scopes one level below
  • n: all signals in current scopes and all scopes n-1 level below

指定 fsdb 文件名

1
$fsdbDumpvars(0, "system", "+fsdbfile+novas.fsdb");

Verdi 显示状态机的名字

对于本身是parameter 或者 enum 定义的状态机变量, 可以直接设置Radix 为 ASCII 或者 Enum 即可

另一种办法

在Instance 中选中含有状态机的module 然后 Tools => Extract Interactive FSM => All Stages => OK
然后在出现的状态机上面按鼠标中键之把状态机拖到nWave 窗口即可 ( 不过我没有成功, 可能是状态机不规范… )