1、进程误触发
最近在做NANDflash控制器,碰到一个进程误触发的问题,即从波形图上看,某些进程的触发条件并没有成立,但是实际在VCS仿真的时候,该进程却被触发了,进而导致控制器工作不正常,而这种不正常只有在用VCS仿真时才会发生,用modelsim做仿真时并没有发现该问题,甚是诡异。
查了很久,做了许多小试验,最后发现导致该问题的原因竟然是组合逻辑先赋值的代码风格。
举例来说,比如有一个组合逻辑块:
Always @ * 进程1
Begin
WENeg = 1;
……
Case (condition)
…
Condition1 : WENeg = 0;
…
endcase
end
always @ ( posedge WENeg ) 进程2
begin … end
假设condition1满足,那么WENeg为0,如果进程1的代码很多,vcs仿真器运行完进程1所需的delt 时间够长,每次当进程1被触发的时候,WENeg都会先被拉为1,由于delt时间够长,进程2将感应到一个WENeg的上升沿,从而导致进程2被误触发。这种现象是VCS独有的,modelsim仿真器没有出现过此类问题。
解决的办法有两种:
1)在进程2中添加延时和条件判断语句:#1 ; if ( WENeg ) …
2) 修改进程1,即改变电路结构,将WENeg信号寄存,引入新变量WENeg_nxt作为WENeg的线信号,而将WENeg放入时序模块中,将其寄存,做法如下:
Always @ *
Begin
WENeg_nxt = WENeg ;
…
Case(condition)
…
Condition1: WENeg_nxt = 0;
…
endcase
end
always @(posedeg) WENeg <= WENeg_nxt ;
-----------------------------------------------------------------------------------
2、task和敏感列表
verilog2001的语法中有这样一条规定,即在写组合逻辑的时候,如果用*代替敏感信号列表(always @ *),则 仿真器会自动将进程中处在等式右边和作为判断条件的变量添加到敏感列表中。但是如果在always中调用task,而刚好task内有变量没有在always程序块中出现过,则该信号不会被添加到敏感列表,这可能导致功能仿真都不正常。这点在使用task编写组合逻辑的时候要特别注意,解决的办法是:尽量保证所有出现在task中的变量也能出现在always程序块中。
-----------------------------------------------------------------------------------
3、仿真器死机问题
当测试程序中出现 wait 和 @(posedge signal ) 等判断等待语句的时候,极有可能因为程序运行不正常而出现死机,解决的办法是:将等待判断语句注释掉,然后在相应位置加以一定的延时,跑完仿真后,查看造成条件无法满足的原因,问题解决后,再将测试程序修改回来。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/fengyelin126/archive/2009/01/07/3719294.aspx