verilog语法中if else 和case语句是不能传递x态的。if(1'bx)会默认为0即false,对于case(1'bx),如果有默认default的分支语句,则会匹配到default的语句,如果没有default语句则不会匹配到任何语句。如下代码和波形:
module top_module();
reg sel;
reg [1:0]out1;
reg [1:0]out2;
reg [1:0]out3;
wire [2:0]out4;
reg [2:0]out5;
`probe(out1);
`probe(out2);
`probe(out3);
`probe(out4);
`probe(out5);
`probe(sel);
initial `probe_start;
initial begin
sel<=0;
#10;
sel<=1;
#10;
sel<=0;
#10;
sel<=1'bx;
#10;
$finish;
end
always @(*)begin
if (sel)
out1 = 2'b11;
else
out1 = 2'b00;
end
always @(*)begin
case (sel)
1'b1: out2 = 2'b11;
1'b0: out2 = 2'b00;
default: out2 = 2'b01;
endcase
end
always @(*)begin
case (sel)
1'b1: out3 = 2'b11;
1'b0: out3 = 2'b00;
endcase
end
assign out4 = sel ? 2'b11 : 2'b00;
always @(*) begin
out5 = sel ? 2'b11 : 2'b00;
end
endmodule
波型:
这样的问题是:如果使用if和case由于其不能传递X态,因此在仿真时就不能很好的去debug和不定态相关的bug。所以在代码中尽量使用assign+条件表达式(其实本质上是条件表达式,比如out5没有使用assign)代替case和if else。IEEE官方语法手册中写道,条件表达式,在条件是x时,表达式结果是后两个表达式结果的按位计算结果,计算规则如下:
vcs中提供的编译选项-xprop=tmerge/xmerge可以扩散X态传播。
如上所述,tmerge更符合实际硬件表象,所以用的更多。
除此之外,默认如果不加-xprop选项,那么默认是vmerge模式,即verilog语法模式。
综上vmerge是最乐观的,tmerge最符合实际电路,xmerge最悲观。
具体可以见下面这个例子:
使用xprop config文件xprop.cfg:
merge = xmerge;
tree {top} {xpropOff};
instance {top.DUT} {xpropOn};
module {dwc_mipi_cdphy_rx_4l3t_ns} {xpropOff};
instance {top.DUT.lb_mipi_rx_top_pre_u.mipi_csi_rx_uint0.mipi_csi_rx_uint_pre.wrapper_dwc_mipi_csi2_rx.cdphy_u} {xpropOff};
instance {top.DUT.lb_mipi_rx_top_pre_u.mipi_csi_rx_uint1.mipi_csi_rx_uint_pre.wrapper_dwc_mipi_csi2_rx.cdphy_u} {xpropOff};
instance {top.DUT.lb_mipi_rx_top_pre_u.mipi_csi_rx_uint2.mipi_csi_rx_uint_pre.wrapper_dwc_mipi_csi2_rx.cdphy_u} {xpropOff};
instance {top.DUT.lb_mipi_rx_top_pre_u.mipi_csi_rx_uint3.mipi_csi_rx_uint_pre.wrapper_dwc_mipi_csi2_rx.cdphy_u} {xpropOff};
instance {top.DUT.lb_mipi_rx_top_pre_u.mipi_csi_rx_uint4.mipi_csi_rx_uint_pre.wrapper_dwc_mipi_csi2_rx.cdphy_u} {xpropOff};
instance {top.DUT.lb_mipi_rx_top_pre_u.mipi_csi_rx_uint5.mipi_csi_rx_uint_pre.wrapper_dwc_mipi_csi2_rx.cdphy_u} {xpropOff};