在使用VCS进行仿真时,工程师们常常会面对一个极为重要且充满挑战的问题——X态传播行为。X态信号代表了未知或不确定的逻辑值(或者高阻Z态),可能会在设计中引入意想不到的问题,因此如何处理X态成为了芯片设计与仿真中的一个关键议题。
VCS提供了仿真选项-xprop=vmerge/tmerge/xmerge来处理和扩散X态传播问题。本文将深入探讨仿真中的X态传播行为,着重于不同仿真选项对X态传播的影响,以及应对X态隐匿和扩散的一些方法。
对于-xprop,官方给出的解释是:
Verilog和VHDL常用于数字设计建模。设计人员使用RTL构造描述硬件行为。然而,某些RTL仿真语义不足以准确地为硬件行为建模。因此,相比实际硬件行为,仿真结果要么太过乐观,要么太过悲观。
因为这些语义限制,Verilog和VHDL仿真器会忽略掉控制信号上的X不定态,在输出上会分配一个固定的数值。这样造成的结果就是,由于缺少X的传播,RTL仿真器往往无法检测到和X态相关的设计问题。然而,同样的设计问题可以在门级仿真中检测出来,因此许多时候必须运行大量的门级仿真,只是为了调试X相关问题。现在VCS在RTL阶段提供了的全新X传播(X-propagation)支持,使用该技术,工程师可以节省大量用于调试RTL和门级仿真的X建模的差异上的时间和精力。
进一步查询可以明确,不加入-xprop选项时默认的仿真行为是vmerge。从X态传播的严重程度来看,xmerge>tmerge>vmerge,三个选项可以等价理解为悲观预期>合理预期>乐观预期。那么到底是需要X态传播严重些呢还是乐观些呢?单纯从验证的角度,通常我们是希望X态尽可能的传播以便发现更多的隐藏问题;但是如果过于悲观的行为预期又会和实际电路行为有所出入。因此根据个人的经验,数据和运算通路的模块应该能够通过xmege测试,而控制通路的模块至少通过tmerge测试。
好了言归正传,我们来探究下不同-xprop选项对仿真结果的影响,主要对三种常用语句继续探究:assign/case/if-else,那么先上个省流版:
好了接下来咱们来展开聊聊,就从assign说起吧。
assign
assign是对xprop选项最不敏感的语法,无论是在哪种xprop配置反应都是一样的(如有遗漏请不吝赐教)。对于逻辑运算,assign遵循合理X态规则: 如果能确定数值,则传播确定值,否则传播X态 。具体的规则如下:
x & 1 = x
x | 1 = 1
x & 0 = 0
x | 0 = x
x ^ 0 = x
x ^ 1 = x
参考如下代码和波形:
//test0
logic t0_sel0, sel1;
initial begin
t0_sel0 = 1'b0;
`DELAY(20, clk);
t0_sel0 = 1'bx;
end
wire t0_xend0 = t0_sel0 & 1'b1;
wire t0_xend1 = t0_sel0 | 1'b1;
wire t0_xend2 = t0_sel0 & 1'b0;
wire t0_xend3 = t0_sel0 | 1'b0;
wire t0_xend4 = t0_sel0 ^ 1'b1;
wire t0_xend5 = t0_sel0 ^ 1'b0;
-xprop=vmerge/tmerge/xmerge波形均一致:
但是呢,有一个assign语法不太合理(仅仅从RTL角度而不是仿真角度),会呈现X态:
wire t0_xend6 = (t0_sel0 == t0_sel0)
而对于===则会反馈为1,这个也算是很”著名“的==和===的区别,感兴趣的可以自行查阅:
assign对于选择逻辑,配置为vmerge和tmerge遵循的规则仍然是 如果能确定数值,则传播确定值,否则传播X态 ,比如下面这个代码:
wire t2_en2 = t0_sel0 ? t2_data0 : t2_data1;
vmerge和tmerge的波形如下:
而xmerge的波形如下:
不过需要注意的是在xmerge配置下,如果X态出现在数据内那就不无脑X而是合理X了:
wire t2_en3 = t2_data0 ? t0_sel0 : t2_data1;
好的关于assign的X态传播行为就说这么多吧。
case
对于case语句当判断语句中出现X态时,会是什么行为呢?来看下面这段代码:
always @* begin
case(t0_sel0)
0 : t2_en1 = t2_data0;
1 : t2_en1 = t2_data1;
default: t2_en1 = t2_data0;
endcase
end
vmerge仿真结果:
tmerge仿真结果:
xmerge仿真结果:
区别很明显了,那我们总结一下规律,case(sel)选择a or b:
通过表来看,个人认为tmerge是最为合理的策略。而对于X态在数据中的情况,无论什么配置case都是如实的将X态传播出来,比如这个代码:
always @* begin
if(t2_data0)begin
t2_en4 = t0_sel0;
end
else begin
t2_en4 = t2_data1;
end
end
哪怕xmerge的仿真结果也是这样的:
所以大家也看出来了,X态传播中我们真正需要担心的是条件中的X态,数据里的X态一般都能如实的反馈出来。
if-else
直接上代码:
always @* begin
if(t0_sel0)begin
t2_en0 = t2_data0;
end
else begin
t2_en0 = t2_data1;
end
end
vmerge仿真结果:
tmerge仿真结果:
xmerge仿真结果:
虽然vmerge下都没有传播X态,但是显然行为和case时候又不一样了。那么总结一下if(sel) a else b的选择语句结果:
可以发现sel有X态时if-else语句中vmerge选择的是else分支,而case是选择"不变"策略;tmerge和xmerge的结果则是和case语句相同的。
当然了对于X态在数据内,无论什么配置if-else语句也是如实的将X态反馈出来:
always @* begin
if(t2_data0)begin
t2_en5 = t0_sel0;
end
else begin
t2_en5 = t2_data1;
end
end
好的,做了这么多实验,最后还是汇总刚刚的那张表,对于条件有X态的场景,三种语法的规则如下:
对于数据有X态的场景,三种语法均会如实合理的传播X态。本篇内容至此,下次来讨论下如何快速高效的反馈和定位X态传播问题。
-
仿真器
+关注
关注
14文章
1017浏览量
83720 -
VHDL语言
+关注
关注
1文章
113浏览量
18001 -
RTL
+关注
关注
1文章
385浏览量
59759 -
VCS
+关注
关注
0文章
79浏览量
9600
发布评论请先 登录
相关推荐
评论