Verilog和SystemVerilog定义了4种描述信号状态: 1, 0, X, and Z。1和0无疑是真实存在的信号状态. 而Z用来表示高阻态,X用来表示不确定的状态。
X信号可以有意或无意地被创建,最常见的X信号存在于未被初始化的memory register,这里X用来表示这些memory在reset之前的的未知状态 。其他一些可以产生X的场景包括了不同的driver驱动同一块逻辑到不同的逻辑值,或者是在low power中的关断信号,又或者是一些超过选择范围的多比特信号。 有些设计者会对design中那些dont care的信号设为X,让综合工具在做优化的时候来随机选择0或者1进行优化。也有些设计者为了debug的目的在设计中对那些不会用到的逻辑值设X,这样在做仿真的时候如果使用到这些逻辑,说明电路有问题,而仿真工具产生的X可以检查到这些逻辑。有意地设置一些X信号是比较有争议的做法。在做lint检查的时候也会被标识出来。但是有些X状态由于仿真器识别的原因(verilog X optimism)会产生错误的仿真结果。这就属于RTl的bug了。
第一个verilog X optimism的例子来自if...else语句:
1 2 3 4 5 6 |
always_ff@(posedge clk)begin if(cond) c <= a; else c <= b; end |
Verilog LRM 指出如果if...else的条件是X状态,那么这个条件就会被当作false处理,在这里只有else语句会被执行。
在实际设计中有一种情况可能会产生这种问题:cond信号来自于memory。比如汉明码SECDED(single error correction double error detection)解码器,其检测的序列是储存汉明码的寄存器,这段序列是否错误的cond是由这些寄存器经过一段组合逻辑产生,当cond为TRUE时输出错误信号error=1。在reset之前这些寄存器都是X状态,原本错误信号应该是error=1,但是在仿真中由于verilog X optimism这种特性,寄存器的X经过组合逻辑传播到cond,导致最后将cond=X判断为FALSE,输出错误信号为0,这就与实际电路行为相违背了。
Verilog X optimism的另外一个例子是case语句:
1 2 3 4 5 6 |
always_ff@(posedge clk)begin case(cond) 1'b0 : c = a; 1'b1 : c = b; endcase end |
在case语句中如果cond为X的话,c将会保留原值。这里原本是描述了一个mux的行为,但由于X optimism的原因,仿真行为与RTL描述不一致。
此外,Verilog X optimism还会影响到0/1->X/Z的处理。下面的这些状态转移都会被视为posedge:
0->1, 0->X, 0->Z, X->1, Z->1
0->X or X->1实际上不一定是posedge,但在仿真中,他们都会被当作posedge处理。
全部0条评论
快来发表一下你的评论吧 !