zoukankan      html  css  js  c++  java
  • 【原创】case、casez和casex谁是谁

    Verilogcase语句经常用于多分支表决的结构,case后的表达式会与各分支表达式“全等”那么对应的分支会被执行.其基本结构如下:

    case(expression)

    expr1 : statement_or_null;

    exprn : statement_or_null;

    default : statement_or_null;

    endcase

    虽然一般case经常被使用,但是在构建仿真验证平台时,经常会遇到case后的敏感表达式出现高阻态z和不定态x的情况,而对于部分位出现高阻态z和不定态x的情况有时需要忽略掉,如下例.

    【示例】

    `timescale 1 ns / 1 ps

    module top_tb;

    reg [1:0] d1,d2,d3,d4,d5,d6;

    reg [1:0] sel;

    reg [1:0] dout;

    initial begin

            d1 = 2'b00;d2 = 2'b10;d3 = 2'b0x;

            d4 = 2'bz0;d5 = 2'bxx;d6 = 2'bzz;

           sel = 2'b00;

        #1 sel = 2'b10;

        #1 sel = 2'b00;

        #1 sel = 2'b0x;

        #1 sel = 2'bz0;

        #1 sel = 2'bxx;

        #1 sel = 2'bzz;

        #1 sel = 2'b11;

        #1 $stop;

    end

    always @(sel)

    begin

        case(sel)

            2'b00 : begin

                        dout = d1;

                        $display("Branch 2'b00!");

                    end

            2'b10 : begin

                        dout = d2;

                        $display("Branch 2'b10!");

                    end

            2'b0x : begin

                        dout = d3;

                        $display("Branch 2'b0x!");

                    end

            2'bz0 : begin

                        dout = d4;

                        $display("Branch 2'bz0!");

                    end

            2'b1x : begin

                        dout = d5;

                        $display("Branch 2'b1x!");

                    end

            2'b1z : begin

                        dout = d6;

                        $display("Branch 2'b1z!");

                    end

            default : begin

                          dout = 2'b00;

                          $display("Branch default!");

                      end

        endcase

    end

    endmodule     // top_tb

    【仿真结果】

    Sel   |   Result

    2b00  # Branch 2'b00!

    2b10  # Branch 2'b10!

    2b00  # Branch 2'b00!

    2b0x  # Branch 2'b0x!

    2bz0  # Branch 2'bz0!

    2bxx  # Branch default!

    2bzz  # Branch default!

    2b11  # Branch default!

    示例中确实可以将case后的敏感表达式与分支表达式进行全匹配,匹配包括表达式结果的每一位.但是如果期望2b002b0x或者2b0z选择执行相同的分支,或者2b102b1x或者2b1z选择执行相同的分支,使用原有的case语句是无法实现的,为此,为了满足这种特殊的要求,case语句演变出了两种变体casezcasex.

    casezcasex的用法与传统的case一样,只是在敏感表达式和分支表达式匹配时稍有不同,casez语句中,如果分支表达式的结果中某些位的值位高阻z,那么在对这些位进行比较时会忽略不进行比较,仅考虑其他对应位的比较.同理,casex也是会对某些位为z比进行比较,但是其进一步扩展为对包含x的位也不进行比较.

    【示例】

    `timescale 1 ns / 1 ps

    module top_tb;

    reg [1:0] d1,d2,d3,d4,d5,d6;

    reg [1:0] sel;

    reg [1:0] dout;

    initial begin

            d1 = 2'b00;d2 = 2'b10;d3 = 2'b0x;

            d4 = 2'bz0;d5 = 2'bxx;d6 = 2'bzz;

           sel = 2'b00;

        #1 sel = 2'b10;

        #1 sel = 2'b00;

        #1 sel = 2'b0x;

        #1 sel = 2'bz0;

        #1 sel = 2'bxx;

        #1 sel = 2'bzz;

        #1 sel = 2'b11;

        #1 $stop;

    end

    always @(sel)

    begin

        casez(sel)

            2'b00 : begin

                        dout = d1;

                        $display("Branch 2'b00!");

                    end

            2'b10 : begin

                        dout = d2;

                        $display("Branch 2'b10!");

                    end

            2'b0x : begin

                        dout = d3;

                        $display("Branch 2'b0x!");

                    end

            2'bz0 : begin

                        dout = d4;

                        $display("Branch 2'bz0!");

                    end

            2'b1x : begin

                        dout = d5;

                        $display("Branch 2'b1x!");

                    end

            2'b1z : begin

                        dout = d6;

                        $display("Branch 2'b1z!");

                    end

            default : begin

                          dout = 2'b00;

                          $display("Branch default!");

                      end

        endcase

    end

    endmodule     // top_tb

    【仿真结果】

    Sel   |   Result

    2b00  # Branch 2'b00!

    2b10  # Branch 2'b10!

    2b00  # Branch 2'b00!

    2b0x  # Branch 2'b0x!

    2bz0  # Branch 2'b00!

    2bxx  # Branch default!

    2bzz  # Branch 2'b00!

    2b11  # Branch 2'b1z!

    此处将case替换为casez,从仿真结果可以看出,2bz02bzz2b00结果一致,即不对敏感表达式与分支表达式中对应位存在z的位进行比较.这里需要注意当sel2bzz,因为不对任何位进行全等检查,所以敏感表达式会与第一个分支匹配.可见casez语句中会忽略表达式中的高阻态位.

    【示例】

    `timescale 1 ns / 1 ps

    module top_tb;

    reg [1:0] d1,d2,d3,d4,d5,d6;

    reg [1:0] sel;

    reg [1:0] dout;

    initial begin

            d1 = 2'b00;d2 = 2'b10;d3 = 2'b0x;

            d4 = 2'bz0;d5 = 2'bxx;d6 = 2'bzz;

           sel = 2'b00;

        #1 sel = 2'b10;

        #1 sel = 2'b00;

        #1 sel = 2'b0x;

        #1 sel = 2'bz0;

        #1 sel = 2'bxx;

        #1 sel = 2'bzz;

        #1 sel = 2'b11;

        #1 $stop;

    end

    always @(sel)

    begin

        casex(sel)

            2'b00 : begin

                        dout = d1;

                        $display("Branch 2'b00!");

                    end

            2'b10 : begin

                        dout = d2;

                        $display("Branch 2'b10!");

                    end

            2'b0x : begin

                        dout = d3;

                        $display("Branch 2'b0x!");

                    end

            2'bz0 : begin

                        dout = d4;

                        $display("Branch 2'bz0!");

                    end

            2'b1x : begin

                        dout = d5;

                        $display("Branch 2'b1x!");

                    end

            2'b1z : begin

                        dout = d6;

                        $display("Branch 2'b1z!");

                    end

            default : begin

                          dout = 2'b00;

                          $display("Branch default!");

                      end

        endcase

    end

    endmodule     // top_tb

    【仿真结果】

    Sel   |   Result

    2b00  # Branch 2'b00!

    2b10  # Branch 2'b10!

    2b00  # Branch 2'b00!

    2b0x  # Branch 2'b00!

    2bz0  # Branch 2'b00!

    2bxx  # Branch 2'b00!

    2bzz  # Branch 2'b00!

    2b11  # Branch 2'b1x!

    此处将case替换为casex,从仿真结果可以看出,2b0x2bxx2b00结果一致,2bz02bzz也与结果一致,即不对敏感表达式与分支表达式中对应位存在xz的位进行比较.可见casex语句中会忽略表达式中的高阻态位和不定态.

    【示例】

    `timescale 1 ns / 1 ps

    module top_tb;

    reg [7:0] in;

    reg [7:0] out;

     

    initial begin

           in = 8'b0000_0000;

        #1 in = 8'b0000_0001;

        #1 in = 8'b0000_0010;

        #1 in = 8'b0000_0100;

        #1 in = 8'b0000_1000;

        #1 in = 8'b0001_0000;

        #1 in = 8'b0010_0000;

        #1 in = 8'b0100_0000;

        #1 in = 8'b1000_0000;

        #1 in = 8'b0010_0100;

        #1 in = 8'b1111_0010;

        #1 in = 8'b0000_1111;

        #1 $stop;

     

    end

     

    always @*

    begin

        casez(in)

            8'bzzzz_zzz1 : out = 0;

            8'bzzzz_zz1z : out = 1;

            8'bzzzz_z1zz : out = 2;

            8'bzzzz_1zzz : out = 3;

            8'bzzz1_zzzz : out = 4;

            8'bzz1z_zzzz : out = 5;

            8'bz1zz_zzzz : out = 6;

            8'b1zzz_zzzz : out = 7;

    default      : out = 0;

        endcase

    end

    endmodule

    【仿真结果】

     

    从仿真结果可以看出,在进行匹配时,当有多位匹配成功,从右侧开始第一次匹配成功的分支会被执行.示例中inh24h02的结果是一致的,h0fh01的结果是一致的.

    从上述几例可以看出casecasezcasex在对0/1/z/x进行比较时的对应关系如下表:

    case

    0

    1

    X

    Z

     

    casez

    0

    1

    X

    Z

     

    casex

    0

    1

    X

    Z

    0

    1

    0

    0

    0

     

    0

    1

    0

    0

    1

     

    0

    1

    0

    1

    1

    1

    0

    1

    0

    0

     

    1

    0

    1

    0

    1

     

    1

    0

    1

    1

    1

    X

    0

    0

    1

    0

     

    X

    0

    0

    1

    1

     

    X

    1

    1

    1

    1

    Z

    0

    0

    0

    1

     

    Z

    1

    1

    1

    1

     

    Z

    1

    1

    1

    1

    其中casez语句用来处理不考虑高阻值z的比较过程,casex语句则将高阻态z和不定态都视为忽略,即在表达式进行比较时,不将该位进行比较,这样根据具体需要灵活使用casexcasez.

    综上所述,case进行精确比较,会对每一位不管该位是0/1/z/x的任何值;casez进行忽略z的比较,如果敏感表达式和分支表达式中有一位为z,那么在比较时该位的比较忽略;casex进行忽略xz的比较,如果敏感表达式和分支表达式中有一位为x或者z,那么在比较时该位的比较忽略,当有多位都可匹配时,仅从右侧开始第一次匹配成功的分支会被执行.

  • 相关阅读:
    Kubernetes 再深入一点点
    10分钟完成 mongodb replSet 部署
    网络篇
    p2p 打洞专场(转)
    Dockerfile 编写
    关于github 代码管理,协作开发
    Kubernetes 基于 ubuntu18.04 手工部署 (k8s)
    备忘 ubuntu ip 及 dns 的坑
    各种语言web性能简单对比测试
    vue 按需加载
  • 原文地址:https://www.cnblogs.com/nanoty/p/15083317.html
Copyright © 2011-2022 走看看