Verilog仿真事件队列
仿真规范
verilog中的语句(如initial、always)是并行执行的。在verilog中,对于不同的事件在同一时刻调用时没有规定先执行哪一个,只要在同一层的事件,任意的执行顺序都是可以的
VCS是如何处理事件队列的:
注:RHS:非阻塞赋值符号右侧的语句
m
o
n
i
t
o
r
在
m
o
n
i
t
o
r
域
,
而
monitor在monitor域,而
monitor在monitor域,而display在active域
UDP:user define primitive
PLI:Programming Language Interface
仿真队列的例子
如上图所示,当定义了CASE1时,会并行执行前两个always语句。当检测到clk信号变化时,第一个always语句会将a赋值成1。但与此同时,第二个always语句中的zin会被赋值成a的值。由于这两个操作处于同一时刻,所以就无法确认是a赋值成了1还是zin先被赋值成了a,因为两个语句不同的执行顺序将会造成不同的结果。
使用不同的仿真工具对其进行仿真将会得到不同的结果。例如上图中,使用VCS和用Questa进行仿真,得到的结果就是不同的。
如何避免这种情况的发生:
1、对于时序逻辑,应采用非阻塞赋值(<=)替代阻塞赋值(=)。非阻塞赋值是先将需要赋值的结果算出来,在结束以后才会进行赋值。而阻塞赋值则是直接将结果赋值以后才进行下面的语句。
2、在组合逻辑中使用always块时,最好使用always(*)的方式进行检测敏感列表,这样可以避免遗漏敏感信号。
3、避免#0延时的出现
VCS处理verilog/systemverilog的流程
VCS的编译和仿真
编译命令:vcs +v2k filename.v -debug_all
v2k:支持ieee2001 verilog规范
仿真命令:./simv -gui &
simv:编译产生的可执行文件