1.环境介绍
linux发行版:ubantu20.0_64位
synosys2016 版本
gcc 4.4 g++4.4
资源下载地址:链接https://pan.baidu.com/s/1zXy7O7FfAr0kz_klye4y3w
提取码:yt7i
经过几天的学习,终于会了synopsys公司的VCS软件,在此做一个小小的总结,分享自己得学习心得。希望对大家有所帮助,也希望大家多多指教,谢谢!
2. verilog 仿真规范
首先介绍一下verilog语言的仿真的一些规范:
verilog语言的仿真时基于分层的思想来实现的,首先会创建一个执行事件的队列,然后计算仿真时间。verilog的仿真会首先执行零延迟的事件,然后将仿真的起止时间设置为0,这样为后面的延迟时间语句提供了一个参考点,便于后续有延迟事件能按一定的时间顺序执行。
特别注意:在verilog仿真中,当多个事件(并发)在同一时刻来调度执行,该执行哪一个呢?
随便执行哪一个都行,verilog语法并没有规定,所以这是后续我们在处理一些设计问题需要考虑的问题。
2.1 verilog仿真队列
理解仿真队列有什么用?我们直接上手VCS不好吗?
理解VCS会有助于你理解我们将写的code交给VCS后执行的是什么样的操作,理解仿真的原理,有利于解决在后续仿真过程中出现的各种问题。verilog仿真队列图如下:
VCS工具将仿真过程分为5个区域:
- VCS首先读入用户写的语句块(initial,always,assgin等),然后执行没有延迟的语句(例如初始化语句),再将仿真时间设置为0。–上述文字有降到。
- 然后进入active区,首先执行一些原语(就是一些逻辑门语句,简单MOSE电路,上拉下拉语句,$display,无延迟的assign语句,阻塞赋值语句)值得注意的是,在active 阻塞赋值语句是完全执行的,例如 a = z+y; 在这个区,阻塞赋值语句执行了z+y的计算,还执行了赋值的过程,但是对于非阻塞赋值,在active区只执行了z+y的计算,并没有执行赋值过程,所以在这里内存里存的非阻塞赋值的值还是更新前的值
- 然后进入 inactive区,主要作用执行延迟语句#(time);
- 然后进入nonblack区,这个区执行非阻塞赋值功能。
- 然后进入monitor区,执行monitor函数信号跟踪。和display很像,但是运行的区不一样,结果和功能也不一样。
2.2 仿真有趣的现象
在仿真的过程中有许多有趣的现象:有些代码在不同厂家的仿真工具中仿真的结果不一样,到底谁对谁错?可以说没有对错之分,各个厂家对语法没提及到的一些现象,设置是不同的。下面来看个例子:
module test;
reg clk,a,z,zin;
always @(posedge clk) begin
a = 1'b1;
#0 a = 1'b0;
end
`ifdef CASE1
always @(a) #0 z = zin;
always @(a) zin=a;
`else
always @(a) z= zin;
always @(a) #0 zin=a;
`endif
initial begin
#50 clk = 1'bz;
#50 clk = 1'b0;
#50 clk = 1'b1;
#50 clk = 1'b0;
#50 $finish;
end
endmodule
VCS 仿真情况:
得出的稳定结果是a=0,z=1,zin=0;
ModelSim 仿真结果:
仿真结果是a=0,z=0,zin=0;
当然上述例子还有很多代码风格上不足的缺点:
- 在描述时序电路时候应该用阻塞赋值
- 在always块中使用#0延迟
3.在组合逻辑电路中的敏感列表要完整,否者会产生锁存器,为了不漏掉敏感信号可以写成always @(*)。
2.3 学习VCS需要的工具
- verilog语言
- linux操作系统
- GVIM编辑器
- debug 和 设计优化
- 覆盖率的操作