考虑x和z在verilog条件语句中的使用情况

描述

首先,考虑x和z在verilog条件语句中的使用情况,然后我们再考虑在verilog中用x和z给其他reg/wire赋值的情况。

  (一)首先,考虑x和z在verilog条件语句中的使用情况。

 
Verilog case语句中,2'b1x和2’b0x造成的仿真器、综合器的mismatch,

举个例子:

Simulators:

match 2'b1x to 11 or 10 

match 2’b0x to 01 or 00

HDL Compiler tool

both 2'b1x and 2’b0x are evaluated to false.   Because of the simulation and synthesis mismatches, the HDL Compiler tool issues an ELAB-310 warning.

case (A)
    2'b1x:... // You want 2'b1x to match 11 and 10 but
              // HDL Compiler always evaluates this comparison to false
    2'b0x:... // you want 2'b0x to match 00 and 01 but
              // HDL Compiler always evaluates this comparison to false
    default: ...
endcase

 

官方说明:我们可以得到两点信息:

Verilog



第一点:


A simulator evaluates an unknown (x) or high impedance (z) as a distinct value different from 0 or 1; however, an x or z value becomes a 0 or 1 during synthesis. 



第二点:



DC工具会直接将verilog比较判断语句中的x or z直接理解为false。所以禁止在verilog比较判断语句中使用x or z。


参见如下代码,DC工具会理解 if (A==1'bx) 为false, 因此DC会直接assigns 1 to reg B 并且报 ELAB-310 warning.

 

module test (
input      A,
output reg B
);
always @(*) begin
    if(A == 1'bx)
        B = 0;
    else
        B = 1;
end
endmodule

 



实际综合如下,果不其然,有意思哇!后面几个稍微复杂点的代码更有趣!

Verilog




再补充z的使用:

Verilog

结论:仿真工具可以理解x、z、0、1状态,但是综合工具遇到带x、z的比较判断条件时,直接理解该条件为false。



 

(二)然后我们再考虑在verilog中用x和z给其他reg/wire赋值的情况。




案例1:z赋值是没问题的,会综合出来三态门,参见如下代码1:

 

module three_state (ENABLE, IN1, OUT1);
input IN1, ENABLE;
output reg OUT1;


always @(ENABLE or IN1) begin
    if (ENABLE)
        OUT1 = IN1;
    else
        OUT1 = 1'bz; //assigns high-impedance state
end
endmodule

 

Verilog

Verilog

Logical buffer of a single input with an active-high output enable. The output is 3-stated when the enable is low.




真值表:

Verilog



案例2:z赋值是没问题的,会综合出来三态门,参见如下代码2:

 

module x_state (IN1, OUT1);
    input      [1:0]  IN1 ;
    output reg [1:0]  OUT1;


    always @(*) begin
        case(IN1)
            2'b00   : OUT1 = 2'b00;
            2'b01   : OUT1 = 2'b01;
            2'b10   : OUT1 = 2'b10;
            default : OUT1 = 2'bzz; //assigns high-impedance state
        endcase
    end
endmodule

 

Verilog

Verilog




再看X赋值是什么情况。


案例1:利用DC综合工具实测如下代码综合效果:

 

module x_state (IN1, OUT1);
    input      [1:0]  IN1 ;
    output reg [1:0]  OUT1;


    always @(*) begin
        case(IN1)
            2'b00   : OUT1 = 2'b01;
            2'b11   : OUT1 = 2'b00;
            default : OUT1 = 2'bxx;
        endcase
    end
endmodule

 

Verilog

可见,x赋值直接被DC工具省略,也没有latch出现。

案例2:

 

module x_state (IN1, OUT1);
    input      [1:0]  IN1 ;
    output reg [1:0]  OUT1;


    always @(*) begin
        case(IN1)
            2'b00   : OUT1 = 2'b00;
            2'b01   : OUT1 = 2'b01;
            2'b10   : OUT1 = 2'b10;
            default : OUT1 = 2'bxx; //assigns high-impedance state
        endcase
    end
endmodule

 

Verilog

可见,x赋值直接被DC工具省略,也没有latch出现。

案例3:注释掉default,非full_case,必然出现latch!

 

module x_state (IN1, OUT1);
    input      [1:0]  IN1 ;
    output reg [1:0]  OUT1;


    always @(*) begin
        case(IN1)
            2'b00   : OUT1 = 2'b00;
            2'b01   : OUT1 = 2'b01;
            2'b10   : OUT1 = 2'b10;
        endcase
    end
endmodule

 

Verilog

因此,尽管x赋值直接被DC工具省略,也没有latch出现,但是仍然建议不要使用x赋值,除非full_case情况下,不会执行default条件下的x赋值分支,写x赋值可以用于仿真查看波形,如下代码所示:

 

always @(*)begin
    case(pmu_state)
        // During power down sequence, shifting pattern to active
        // ISOLATE -> RETAIN -> PWRDOWN
        // and stay unchange during powered down state
        `ARM_POWERING_DOWN, `ARM_POWERED_DOWN: begin
            nxt_isolate_n = 1'b0;
            nxt_retain_n  = ISOLATEn;
            nxt_pwrdown   = ~RETAINn;
        end


        // During power up sequence,  shifting pattern to active
        // PWRDOWN -> RETAIN -> ISOLATE
        `ARM_POWERING_UP, `ARM_POWERED_UP: begin
            nxt_pwrdown   = 1'b0     ;
            nxt_retain_n  = ~PWRDOWN ;
            nxt_isolate_n = RETAINn  ;
        end


        // Propagate X
        default: begin
            nxt_isolate_n = 1'bX;
            nxt_retain_n  = 1'bX;
            nxt_pwrdown   = 1'bX;
        end
    endcase
end

 

  审核编辑:汤梓红

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分