Verilog编程之道 - case语句

case语句,是包含在case和endcase之间的代码,逻辑上等价于if-else语句,使用方法如下:

case (case_expression)
    case_item1 : case_item_statement1;
    case_item2 : case_item_statement2;
    case_item3 : case_item_statement3;
    case_item4 : case_item_statement4;
    default    :  case_item_statement5;
endcase

casez语句,允许"z" 和 "?"值在比较时被当作不关心,"z" 和 "?"时等价的。

        注意:当编写可综合代码时,要小心使用casez;使用casez时,最好使用"?" 表示不关心,不能使用"z" 表示不关心。

casex语句,允许"x" "z" 和 "?"值在比较时被当作不关心.

        注意:当编写可综合代码时,不要使用casez

case语句执行过程:

        1. 每次执行case语句时,括号内case expression 只计算一次,然后按照从上到下的顺序与每个case item比较。

        2. 如果有case default ,那么在这个从上到下的比较过程中忽略它。

        3. 如果有一个case item 与 case expression 匹配上,那么就执行此case item语句,然后终止case语句。

·        4. 如果所有比较都失败,而且有case default,那么就执行case default语句,然后终止case语句。

          5.如果所有比较都失败,而且没有case default,那么就终止case语句。

注意:1  排在前面的case item 具有更高的优先级。

           2 所有的case expression 和 case item的位长都将调整到最长的位长。

           3 如果有一个时unsigned,那么所有都按照unsigned调整。

  

case应用

        case可以检查x和z

case (sig)
    1'bz : $display ("signal is floating");
    1'bx : $display ("signal is unknown");
    default : $display ("signal is %b" ,sig);
endcase

      case item中有x和z时,这段代码时不可综合的

      可使用反向case语句,而且是优先级编码器。

reg [2:0] encode;
case (1) 
    encode[2] :$display ("Select Line 2");
    encode[1] :$display ("Select Line 1");
    encode[0] :$display ("Select Line 0");
    default   :$display ("Error: Only one of the bits is expected ON");
endcase

        case 语句可以时full 和parallel :若是full,就不会产生latch ; 若是parallel ,就不会产生优先级编码器。综合工具一般可以自由推导出是否是full 或parallel。

// 这段代码就是full 又是 parallel ,因此既不会生产Latch 也不会生成优先级编码器

always @ (*)
    begin
        case (sel)
            2'b00: outc = a;
            2'b01: outc = b;
            2'b10: outc = c;
            2'b11: outc = d;
        endcase
    end

       

// 若使用if ,就会生成优先级编码器。

always @ (*)
begin
    if(sel == 2'b00) outi = a;
    else if (sel == 2'b01) outi = b;
    else if (sel == 2'b10) outi = c;
    else                   outi = d;
end

 casez应用

        在case item中,0 1 z x都要进行比较,z和?对应的bit在比较时忽略,x不会被忽略。常用于实现优先编码器。

//实现指令译码,优先级编码器

reg [7:0] ir;
casez (ir)
    8'b1??????? : instruction1(ir);
    8'b01?????? : instruction2(ir);
    8'b00010??? : instruction3(ir);
    8'b000001?? : instruction4(ir);
endcase

casex 会导致设计出现问题, 把x当作不关心,前后防结果不一致。复位前的高阻值在复位后将初始化错误隐藏。

// 在case语句前给输出赋一个默认值,综合会当成full的case语句,不会产生Latch
// 在case前给出输出信号默认值,不会出现前后仿真不一致的情况。

module mux3c (y, a, b, c, sel);
    output     y;
    input    [1:0] sel;
    input        a, b, c;
    reg        y;
    always @ ( a or b or c or sel )
        y = 1'b0 ;    //<====== default value
        case (sel)    
            2'b00 : y = a;
            2'b01 : y = b;
            2'b10 :y = c;
        endcase
endmodule



//使用full_case综合指令
//仿真时,sel = 2'b11 ,y 表现为Latch;综合时,工具把sel == 2'b11时y输出当做不关心,从而导致前后防真不一致。

module mux3c (y, a, b, c, sel);
    output     y;
    input    [1:0] sel;
    input        a, b, c;
    reg        y;
    always @ ( a or b or c or sel )
        case (sel)        // synopsys full_case
            2'b00 : y = a;
            2'b01 : y = b;
            2'b10 :y = c;
        endcase
endmodule

full_case会优化设计,导致设计结果出错。

full_case还是有可能生成Latch(case中对多个输出进行赋值)

消除Latch最简单的方法:在always块的敏感表下面,在执行case语句之前为每个输出都赋一个默认值。

parallel_case是指case expression只能匹配一个case item的语句。如果发现case expression能够匹配超过一个的case item,那么这些匹配的case item被称为overlapping case item,这个case语句就不是parallel

// Synopsys dc_shell 在读入Verilog文件时,如果full_case语句用在不是full的case语句上会报告warning
// Non_full case statement with "full_case" directive

// parallel_case同样会出现警告。

//该警告会使设计崩溃。

case语句的编码原则

        1 对于编写表达式并行的设计,case语句是不错的选择,可使代码更加整洁

        2 在设计可综合代码时,要小心使用casez语句,不要是要casex语句

        3 要小心使用反向case语句,最好只针对时parallel的case语句使用

        4 要小心使用casez设计优先级编码器,可以用if-else-if语句实现优先级编码器,这样意图更明显

        5 在使用casez语句时,用?表示不关心的位。

        6 最好为case语句添加case default,而且不要把输出值赋值未x

  • 3
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值