Code Coverage
- VCS 中 Code Coverage 的类型
- Code Coverage Flow
- 代码覆盖率选项
- Lab Code Coverage
- 初步尝试
- 其他格式的覆盖率报告
- 屏蔽部分代码
- 屏蔽整个模块
设计和验证到底要做到什么程度? 这里其中一个指标就是 Code Coverage。
代码覆盖率一般考虑以下几个方面:
RTL代码的每一行都执行了吗? 行覆盖率,一般要求为 100%。否则可能为冗余,造成面积浪费。
状态机的每一个状态都用到了吗?
分支语句的每一个分支( if 、case 等)都仿真到了吗?
功能覆盖率:
是否覆盖了所有的功能?(所有可能的指令组合是否都被验证到?)
设计的边界(corner cases)是否被测试到?(一些比较特殊的使用场景,设计时可能没有考虑到的使用场景)
VCS 中 Code Coverage 的类型
- 正常信号都是由跳变的,不跳变可能会存在问题
- 对于 Verilog 而言,主要对 Register、Wires、Memories进行检查,其中对 Memories 的检查需要在编译的时候添加
+memcbk
选项。 - 耗时
对于没有覆盖到条件,是漏掉了,还是因为是一种不可能出现的场景。
每一条分支语句,就代表的是一条路径。
不同的抽象层级对应的代码覆盖率:
Code Coverage Flow
(当前一般不会用 -cm_pp 命令来查看波形,一般用的是DVE。)
RTL源代码中会有一些内容是用于调试等其他作用的,希望在计算 RTL 代码覆盖率的不考虑该部分内容,这个时候是需要告诉工具不去分析这一部分内容的,如果不做说明,工具会考虑在内。
在Verilog中,可以使用如下注释来告诉VCS工具那一部分内容在计算覆盖率的时候不考虑在内,
// VCS coverage on
// VCS coverage off
Synopsys公司还提供了一种特殊的注释,如下:
// synopsys translate_on
// synopsys translate_off
这个注释是 Synopsys 的可以识别的,注释包含的那一部分内容在逻辑综合的时候是不考虑的(比如RTL代码中的 display 语句。)。该注释选项,同时也可以关闭对该部分内容的覆盖率计算。
上面的注释只是针对某些特殊的代码段进行屏蔽,如果在编译或者报告的时候(compile time/report time)使用 -cm_hier <name_of _file>
是可以实现对任何实例、模块、文件等进行屏蔽。
代码覆盖率选项
(主要关注红色部分)
使用 -cm_dir e
可以指定输出的覆盖路数据保存的路径,默认情况的的覆盖率文件的后缀名是 .vdb
。
(一般情况下, case 语句的 default 是不会执行到的,所以是可以在计算覆盖率的时候忽略该语句的,通过-cm_nocasedef
实现)
(方法②就是使用 -o
选项得到不同 testbench 对应得仿真可执行文件,然后分别执行这些仿真之后,将覆盖率数据合并。这是使用最多得方法)
不同的测试用例对代码覆盖率的贡献程度是不同的,使用 Autograding
功能就可以得到不同测试用例对覆盖率得贡献情况。
Lab Code Coverage
这里使用的还是fsm的例子。
初步尝试
Makefile文件内容如下:
.PHONY: com cov clean debug
OUTPUT = simv_fsm_moore
ALL_DEFINE = +define+DUMP_VPD
#Code Coverage command
CM = -cm line+cond+fsm+branch+tgl
CM_NAME = -cm_name $(OUTPUT)
CM_DIR = -cm_dir ./$(OUTPUT).vdb
#vdp file name
VPD_NAME = +vpdfile+$(OUTPUT).vpd
# Compile command
VCS = vcs -sverilog +v2k -timescale=1ns/1ns \
-simprofile \
-debug_acc+all \
+notimingcheck \
+nospecify \
+vcs+flush+all \
$(CM) \
$(CM_NAME) \
$(CM_DIR) \
$(ALL_DEFINE) \
$(VPD_NAME) \
-o $(OUTPUT) \
-l compile.log
# Simulation command
SIM = ./$(OUTPUT) \
$(CM) $(CM_NAME) $(CM_DIR) \
$(VPD_NAME) \
-l $(OUTPUT).log
# Start Compile
com:
$(VCS) -f file_list
# Start simulation
sim:
$(SIM)
# Show the Coverage
cov:
dve -covdir *.vdb &
debug:
dve -vpd $(OUTPUT).vpd &
# Start Clean
clean:
rm -rf ./csrc *.daidir *.log *.vpd *.vdb simv* *.key *race.out* \
*profileReport* *simprofile* \
编译仿真:
仿真之后产生的文件内容:
覆盖率查看:
打开之后的界面如下:
点击某一种类型的代码覆盖率,进图如下界面,代码会有高亮显示。
Toggle 覆盖率:
FSM 覆盖率:
分支覆盖率:
其他格式的覆盖率报告
除了通过DVE查看覆盖率报告之外,还可以通过其他形式。
在 DVE 界面,File >> Generate URG … 选项可以生成网页格式的覆盖率报告文件。
也可以在输入命令生成:
两者是一样的,都会得到一个 urgReport 文件夹,该文件夹的内容如下:
其中一个文件的内容如下:
这些文件在Window下也可以查看,而且还可以点击进行点击操作,非常便于交流。
屏蔽部分代码
如下图所示,
现在如何让 display 语句不在覆盖率的计算范围之内呢?
方法一:使用 VCS coverage on/off 注释
方法二:使用 synopsys translate_on/off 注释
(这里注意看,注释的颜色都变了,其实是工具可以识别的关键字)
VCS coverage on/off
只有不统计覆盖率的功能,该开关主要是在逻辑综合的时候告诉DC工具不综合,同时也具有不计算代码覆盖率的功能。
屏蔽整个模块
当前的覆盖率计算是包含两个模块的,如下:
如何只计算 DUT 的代码覆盖率,而不计算 testbench 的代码覆盖率?
① 新建一个文件,在文件中放入如下内容:
② 在编译命令中添加如下选项:
这样得到的覆盖率计算情况如下:
如果是想要只计算某一个模块的覆盖率,就是把 vcs_cov.cfg 中的内容修改为:+module fsm_top
类似的还有如下命令:
+tree fsm_top.fsm_moore
:只查看 fsm_top 模块中的 fsm_moore 模块
+file fsm_top.v
:整个文件内容都不看
类似的还有很多, 可以在文档里面查看。+
是查看,-
是不查看。