前言:
参考视频:仿真工具实践VCS视频教程
零、Verilog Simulation Event Oueue
VCS对verilog模型进行仿真包括两个步骤:
-
编译verilog文件成为一个可执行的二进制文件命令为:vcs source_files
-
运行该可执行文件:./simv
类似于NC, 也有单命令行的方式:vcs source_files -R
-R 命令表示, 编译后立即执行。
Verilog仿真事件队列
Verilog内建仿真规范
- IEEE1364: Verilog语言的仿真基于分层的事件队列
- 执行事件的队列
- 仿真时间的计算
- Verilog仿真器先从没有延退的事件开始,执行他们,然后把时间设成0,然后按照时间循序一次执行各个事件
- Verilog语言规范没有规定当多个事件被安排在同一个时刻来调度时,应该执行那个
- 只要在同一层的事件,什么执行循序都是可以的
- 设计师必须理解 Verilog的分层次仿真事件队列
逻辑仿真队列
-
VCS首先会读取initial和always block,执行没有延时的语句。
-
将时间设置成t=0
-
进入active region:
(1)首先执行原语(包括UDP即用户定义的原语),例如简单的与门或门、上拉下拉等
(2)$display
(3)continuous assignments例如assign
(4)阻塞赋值,先计算右边的表达式再赋给左边;非阻塞赋值只计算右边的表达式,没有完成赋值过程,这一块结束才赋值成功。
-
进入inactive region:处理#0语句
-
进入nonblocking assign region:非阻塞赋值在这个模块执行
-
进入monitor region: m o n i t o r 在 这 个 模 块 执 行 , 与 monitor在这个模块执行,与 monitor在这个模块执行,与display不同,只有变量值出现变化才会输出监测值。因此 m o n i t o r 显 示 的 一 定 是 赋 值 之 后 的 新 值 , monitor显示的一定是赋值之后的新值, monitor显示的一定是赋值之后的新值,display可能显示的是旧值。
-
进入future region
一、VCS simulation basics
vcs编译型仿真器
同一段代码,交给不同仿真器,仿真结果不一样;
VCS可以支持多种级别的描述方式:
行为级描述
RTL(寄存器传输级)
Gate-level(门级),与具体工艺库有关
Compile-time option examples
vcs-help
lists compile options, run-time options, environment variables
Command line options(commonly used):
-Mupdate
//Incremental compilation (only changed files are compiled)
//增量编译,类比增量备份。
-R//Run after compilation(编译完成立即执行仿真)
-gui//Starts the DVE gui at runtime(仿真时启用DVE图形界面)
-I <filename>//Set log file name
//把编译过程写入compile.log文件,便于查看(log在词源中,好像就有记录的意思)
-sverilog//Enable Systemverilog language support(支持SV语言)
+v2k//Compile with support for Verilog 2001 extensions(支持verilog 2001标准)
Run-time options example
加入宏定义define的三种方法
-
在原文件中加入 :`define INC_COUNTER。
-
在头文件中加入:新建立一个文件,在文件中加入 `define INC_COUNTER 并在原文件中引用这个文件
`include "file"需要启用+incdir+选项指定目录。
- 在命令行中加入:编译时启用选项+define+INC_COUNTER
二、VCS debugging basics
Unit Objectives
- Describe three methods of debugging Verilog code using VCS
- Invoke UCLI debugger
- Debug Verilog designs using UCLI
- 第一个是敲一行执行一行,显得比较笨拙!
-
DVE用的情况较多,但现在用的更多的是verdi,
-
verdi只用作debug,不用做编译和仿真,Windows也有对版本debuging,不是Synopsys公司。
debug四个因素:
- simulation speed
取决于电脑、代码的质量、开关选项(debug_pp或_all)以及仿真的级别。其中,级别越高,集成的就多仿真速度越慢,所以就是rtl等能解决的问题就不要拖到系统级。
-
signal visibility
-
signal tractability第二点与第三点分不开
-
usability UCLI命令行的可用性比DVE要差一些
-
$display打印的是变量赋值之前的值(执行早)
-
$monitor检测到的是变量赋值之后的值
-
$time显示的是仿真时间,是simulation time(用`timescale定义之后的),不是cpu时间
-
$readmemh,readmemb指读取到存储单元(如RAM、ROM、FIFO)
-
$readmemh,readmemb把文件里的数据读入存储单元中,方便初始化
-
readmdmh读取16进制文件,readmemb读取二进制文件,其它用法完全相同。
例子
-
monitor检测后面四个数据变化,只要一变化,就打印出来!
-
$stop就是断点,UCLI%会停下来,用run还要继续执行
Compile and invoke UCLI debugger
第一种:一步走
第二种:两步走
-gui,用dve打开,和-R的两种方式,
几个debug选项的区别(userguide可以查):
-debug只打开一部分开关;
-debug_pp保证打开足够多开关的情况下,对性能影响最小(老工程师一般用这个);
-debug_all打开所有开关(速度最慢)。
-l log_filename;
-i input_filename;
-k key_filename用的不多
scope显示当前在那个目录下面
没有人会这么配置时间!
仿真的问题:零延迟的循环
如果写出延迟为0的循环则有可能陷入死循环,此时按ctrl+c(ctrl+Z是退出当前界面,在后台运行)强制退出仿真,也可以用ps找出进程号(PID),使用 “kill PID=76820” 关闭程序。
- 开发过程中在循环语句里插入$display信息,如果进程卡死,可以判断卡在哪里
三 、Debugging with DVE
Unit Objectives
DVE模式介绍
软件安装目录下面有很多自带的PDF软件(开发者写的,权威):
DVE两种模式
Interactive 实时 :就像老师现场改作业(设计初期使用)
post-simulation analysis 后处理:就像 回房间改(一定要喜欢用脚本语言去调用)
用Interactive模式打开dve:
$vcs source.v -R -gui -debug_all
$simv -gui
用Post-Process Mode打开dve:
- vcd占用的磁盘容量太大,才推出vpd
$dve &
$dve -vpd
打开database(后缀为vcd/vpd)即可以查看波形文件,波形文件一般会比较大。
注意用来debug的Verdi的波形文件是.fsdb格式。
(注意对比#、$、&)
实际操作介绍(与questasim、modlism差不多)
-
group signals分组
-
value search查找搜索功能
-
搜索某一个信号是否出现了某个值,甚至查找下一个上升沿。
-
setbus中 new_dout降序
-
compare比较功能:
-
DPI/PLI接口
-
C程序,然后在verilog中通过DPI接口调用这个文件
四、Post-processing with VCD+ files
后处理模式VCD
互动模式(interactive):动态debug,前面两节课都是。
后处理模式(post-processing):先仿真完成后打开波形文件查看。
$vcdpluson
当项目趋于收敛时(即比较稳定)时,不会干预仿真,而是等仿真执行完毕。
仿真速度:大型项目的仿真很耗时间
什么时候使用后处理模式:
1.仿真比较成熟的项目时
2.需要并行处理波形文件时
VCD+
启用$vcdpluson选项来记录波形文件。可以记录所有波形也可以只记录一些模块的模型,不带参数则默认记录所有波形;选项可以放在testbench也可以放在RTL代码中
vcd可以转化为vcd+
产生的文件是.vpd
$vcdpluson(level_number,module_instance,…|net_or_reg)
$vcdplusoff(lmodule_instance,…|net_or_reg)
level_number用来标记记录的深度,不标记则表明含有这个语句的模块以及它所含有的所有子模块的信息都会被记录下来。
应用实例:
$readmemb自动加载进去,2进制
$readmemh自动加载进去,16进制
产生VCD+文件时的编译选项:
dve &相当于dve -vpd vcdplus.vpd
vcs中一般都有默认文件,可以打开开关修改文件
注意:
1.尽量不要记录Verilog statements exectuion
2.只记录某些小模块的数据
3.使用+vcdbufsize+nn 来控制memory buffer的大小 防止最后的vcd+文件过大。
如果定义了参数宏,就会调用。编译`ifdef语句可以避免反复的注释和去注释。
实例:初学者建议观看视频
波形文件只显示一层可以用以下选项:
$vcdpluson(1,fsm_top);
显示memory中的数值可以用以下选项(可以用来记录数组):
v c d p l u s m e m o n ( ) ; 辅 助 宏 不 同 地 方 输 出 一 样 的 信 息 如 vcdplusmemon(); 辅助宏 不同地方输出一样的信息如 vcdplusmemon();辅助宏不同地方输出一样的信息如display(“Hello verilog!”),开启一些宏辅助输出其它信息,以供定位。
$display(“Hello verilog!”,__FILE__,
LINE);
__是两个下划线,__FILE__和__LINE__可以分别输出display语句所在的文件和行数。
五、Debugging simulation mismatches
Unit Objectives
Race conditions(race:竞争冒险)
- The most common causes of simulation mismatches are race conditions
- A race condition is a coding style for which there could be several correct result the code is ambiguous
- All race conditions are some variation of using (read)or setting(write)a data value at the same time it is changing
- Race conditions may result in logic that behaves unexpectedly, and should be fixed before synthesis
仿真事件队列
active ->blocking->nonblocking!
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210204141411839.png? -oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hhb2ppZV9kdWFu,size_16,color_FFFFFF,t_70)
只有在仿真的时候才有不定态,真实电路中不存在x态的,要么是0要么是1.
- 不要有多驱动源(在不同的always块中给一个变量赋值)
六、Fast Rtl-level verification
- 好的编码风格
VCS Architecture
- 第一遍就要考虑怎样把它做好!
General coding Guidlines
- 后仿比仿慢很多!
- readmemh;(writememh);
- 文本比波形打开得快得多!
时序逻辑中避免下面的(除了case)
避免做一些事情
UDP:就是nmos啥的!
- 做模拟的用cadence去做仿真
vcs的选项(+rad)
VCS选项(+prof)
七、 Fast Gate-level verification
用DC工具将rtl综合成门级网表
SDF门级验证
后仿中,看不到覆盖率,只看toggle。因为后仿综合后都看不到状态机什么的!
后仿中,涉及到建立时间,保持时间!
八、Code coverage(cov_ref参考文档!)
- 是不是每行都执行了?
- 芯片的面积决定芯片的成本!代码上取决于always块?
- line coverage
- toggle coverage(0到1没有切换过)
- conditional coverage
- fsm coverage
- path coverage路径覆盖率
- cm_hier <name_of_file>
- -cm cond+tgl+lin+fsm+path(开关选项);
Merge 不同场景的覆盖率
-o 可以跑多个testcase
不综合,也不统计覆盖率!
不看一个模块(-)
只看一个模块(+)