DIY编程器网

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1051|回复: 0
打印 上一主题 下一主题

[待整理] Verilog HDL基础之:条件语句

[复制链接]
跳转到指定楼层
楼主
发表于 2014-10-12 16:33:38 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
        if语句

        if语句是用来判定所给定的条件是否满足,根据判定的结果(真或假)决定执行给出的两种操作之一。Verilog HDL语言提供了3种形式的if语句。
        (1)无分支。
        语法形式:
         
        if (表达式)  语句;
         
        例如:
        if (a > b)  out1 <= int1;     //若a大于b,将int1赋予out1
         
        (2)单级分支。
        语法形式:
         
        if(表达式)语句1;
        else 语句2;
         
        例如:
        if(a>b) out1<=int1;       //若a大于b,将int1赋予out1;否则,将int2赋予out1
        else out1<=int2;
         
        (3)多级分支
        语法形式:
         
        if(表达式1)          语句1;
        else  if(表达式2)   语句2;
        else  if(表达式3)   语句3;
        ...
        else  if(表达式m)   语句m;
        else                   语句n;
         
        例如:
        if(a>b)            out1<=int1;        //若a大于b,将int1赋予out1
        else  if(a==b)    out1<=int2;        //否则,如果a等于b,将int2赋予out1
        else                 out1<=int3;        //否则,将int3赋予out1
         
        关于if语句有如下6点说明:
        (1)3种形式的if语句中,在if后面都有“表达式”,一般为逻辑表达式或关系表达式。系统对表达式的值进行判断,若为0、x或z,按“假”处理;若为1,按“真”处理,执行指定的语句。
        (2)第二、第三种形式的if语句中,在每个else前面有一分号,整个语句结束处有一分号。
        这是由于分号是Verilog HDL语句中不可缺少的部分,这个分号是if语句中的内嵌套语句所要求的。如果无此分号,则出现语法错误。
        但应注意,不要误认为上面是两个语句(if语句和else语句)。它们都属于同一个if语句。else子句不能作为语句单独使用,它必须是if语句的一部分,与if配对使用。
        (3)在if和else后面可以包含一个内嵌的操作语句,也可以有多个操作语句,此时用begin和end这两个关键词将几个语句包含起来成为一个复合块语句如下所示。
         
        if(a>b)begin                        //使用begin_end语句实现多个赋值操作
             out1<=int1;
             out2<=int2;
        end
        else begin
             out1<=int2;
             out2<=int1;
        end
         
                                                                        注意
                       
                                                                        在end后不需要再加分号,因为begin_end内是一个完整的复合语句,不需再附加分号。
                       
         
        (4)允许一定形式的表达式简写方式,例如:
         
        if(expression)  等同于  if( expression == 1 )
        if(!expression) 等同于  if( expression != 1 )
         
        (5)if语句的嵌套。
        在if语句中又包含一个或多个if语句,称为if语句的嵌套,一般形式如下:
         
        if(expression1)
             if(expression2)     语句1     (内嵌if)
             else   语句2
        else if(expression3)    语句3     (内嵌if)
        else   语句4
         
        应当注意if与else的配对关系,else总是与它上面的最近的if配对。如果if与else的数目不一样,为了实现程序设计者的企图,可以用begin_end块语句来确定配对关系,例如:
         
        if() begin
             if()  语句1     (内嵌if)
        end
        else  语句2
         
        这时begin_end块语句限定了内嵌if语句的范围,因此else与第一个if配对。注意begin_end块语句在if_else语句中的使用,因为有时begin_end块语句的不慎使用会改变逻辑行为,如下所示:
         
        if(index>0)                                         //内嵌for语句,无else分支
            for(scani=0;scani<index;scani=scani+1)    //内嵌if语句
              if(memory[scani]>0) begin              //使用begin_end语句,有else分支
                   $display("...");
                   memory[scani]=0;
              end
              else                                            //此处为内嵌if语句的分支
                   $display("error-indexiszero");
        ...
        尽管程序设计者把else写在与第一个if(外层if)同一列上,希望与第一个if对应,但实际上else是与第二个if对应,因为它们相距最近。正确的写法如下:
         
        if(index>0) begin                                //内嵌for语句,有else分支
             for(scani=0;scani<index;scani=scani+1)  //内嵌if语句
                  if(memory[scani]>0) begin          //使用begin_end语句,无else分支
                      $display("...");
                      memory[scani]=0;
                end
        end
        else                                                //此处为外部if语句的分支
             $display("error-indexiszero");
         
        (6)if_else例子。
        下面这段程序用if_else语句来检测变量index以决定modify-seg1、modify-seg2、modify-seg3中哪一个的值应当与index相加作为memory的寻址地址。并且将相加值存入寄存器index以备下次检测使用。程序的前10行定义寄存器和参数。
         
        reg [31:0]  instruction, segment_area[255:0];   //定义寄存器
        reg [7:0]   index;
        reg [5:0]   modify_seg1, modify_seg2, modify_seg3;
        parameter                                              //定义参数
              segment1=0,  inc_seg1=1,
              segment2=20, inc_seg2=2,
              segment3=64, inc_seg3=4,
              data=128;
        //检测寄存器index的值
        if(index<segment2) begin                          //index<20时,执行下列操作
              instruction = segment_area[index + modify_seg1];
              index = index + inc_seg1;
        end
        else  if(index<segment3) begin                   //20<index<64时,执行下列操作
              instruction = segment_area[index + modify_seg2];
              index = index + inc_seg2;
        end
        else  if (index<data) begin                    //64<index<128时,执行下列操作
              instruction = segment_area[index + modify_seg3];
              index = index + inc_seg3;
        end
        else                                                //index>128时,执行下列操作
              instruction = segment_area[index];
         
        case语句

        case语句是一种多分支选择语句,if语句只有两个分支可供选择,而实际问题中常常需要用到多分支选择。Verilog语言提供的case语句直接处理多分支选择。case语句通常用于微处理器的指令译码,它的一般形式如下:
        (1)case (表达式)      <case分支项>   endcase
        (2)casez(表达式)      <case分支项>   endcase
        (3)casex(表达式)      <case分支项>   endcase
        <case分支项>的一般语法格式如下:
         
        分支表达式:       语句
        缺省项(default项):      语句
         
        关于case语句的几点说明如下。
        (1)case括弧内的表达式称为控制表达式,case分支项中的表达式称为分支表达式。控制表达式通常表示为控制信号的某些位,分支表达式则用这些控制信号的具体状态值来表示,因此分支表达式又可以称为常量表达式。
        (2)当控制表达式的值与分支表达式的值相等时,就执行分支表达式后面的语句。如果所有的分支表达式的值都没有与控制表达式的值相匹配的,就执行default后面的语句。
        (3)default项可有可无,一个case语句里只能有一个default项。下面是一个简单的使用case语句的例子。该例子中对寄存器rega译码以确定result的值。
         
        reg [15:0]  rega;
        reg [9:0]   result;
        case(rega)
             16 'd0:  result = 10 'b0111111111;       //rega等于0时
             16 'd1:  result = 10 'b1011111111;       //rega等于1时
             16 'd2:  result = 10 'b1101111111;       //rega等于2时
             16 'd3:  result = 10 'b1110111111;       //rega等于3时
             16 'd4:  result = 10 'b1111011111;       //rega等于4时
             16 'd5:  result = 10 'b1111101111;       //rega等于5时
             16 'd6:  result = 10 'b1111110111;       //rega等于6时
             16 'd7:  result = 10 'b1111111011;       //rega等于7时
             16 'd8:  result = 10 'b1111111101;       //rega等于8时
             16 'd9:  result = 10 'b1111111110;       //rega等于9时
             default: result = 'bx;                     //rega不等于上面的值时
        endcase
         
        (4)每一个case分项的分支表达式的值必须互不相同,否则就会出现矛盾现象(对表达式的同一个值,有多种执行方案)。
        (5)执行完case分项后的语句,则跳出该case语句结构,终止case语句的执行。
        (6)在用case语句表达式进行比较的过程中,只有当信号的对应位的值能明确进行比较时,比较才能成功,因此要详细说明case分项的分支表达式的值。
        (7)case语句的所有表达式的值的位宽必须相等,只有这样控制表达式和分支表达式才能进行对应位的比较。一个经常犯的错误是用&#39;bx、&#39;bz 来替代n&#39;bx、n&#39;bz,这样写是不对的,因为信号x、z的缺省宽度是机器的字节宽度,通常是32位(此处 n 是case控制表达式的位宽)。
         
        case语句与if语句的区别主要有以下两点。
        (1)与case语句中的控制表达式和多分支表达式相比,if结构中的条件表达式更为直观一些。
        (2)对于那些分支表达式中存在不定值x和高阻值z时,case语句提供了处理这种情况的手段。下面的两个例子介绍了处理x、z值case语句。
        例1:case语句1。
        case (select[1:2])
              2 'b00:  result = 0;               //select[1:2]等于00时
              2 'b01:  result = flaga;          //select[1:2]等于01时
              2 'b0x,
              2 'b0z:  result = flaga? 'bx: 0; //select[1:2]等于0x和0z时,执行表达式
              2 'b10:  result = flagb;          //select[1:2]等于10时
              2 'bx0,
              2 'bz0:  result = flagb? 'bx :0; //select[1:2]等于x0和z0时,执行表达式
              default: result = 'bx;            //select[1:2]不等于上面的值时
        endcase
         
        例2:case语句2
         
        case(sig)
             1 'bz:    $display("signal is floating"); //sig为高阻时,打印输出
             1 'bx:    $display("signal is unknown");  //sig为不定状态时,打印输出
             default:  $display("signal is %b", sig);  //为其他时,即0或1时,打印输出
        endcase
         
        针对电路的特性,Verilog HDL提供了case语句的其他两种形式用来处理不必考虑的情况(don't care condition)。其中casez语句用来处理不考虑高阻值z的比较过程,casex语句则将高阻值z和不定值都视为不必关心的情况。
        所谓不必关心的情况,即在表达式进行比较时,不将该位的状态考虑在内。这样在case语句表达式进行比较时,就可以灵活地设置,以对信号的某些位进行比较。如表3.10所示为case、casez、casex 的真值表:
        表3.10                                                           case语句真值表
                                                                        case
                       
                                                                        0
                       
                                                                        1
                       
                                                                        x
                       
                                                                        z
                       
                               
                                        0

                       
                               
                                        1

                       
                               
                                        0

                       
                               
                                        0

                       
                               
                                        0

                       
                               
                                        1

                       
                               
                                        0

                       
                               
                                        1

                       
                               
                                        0

                       
                               
                                        0

                       
                               
                                        x

                       
                               
                                        0

                       
                               
                                        0

                       
                               
                                        1

                       
                               
                                        0

                       
                               
                                        z

                       
                               
                                        0

                       
                               
                                        0

                       
                               
                                        0

                       
                               
                                        1

                       
                                                                        casez
                       
                                                                        0
                       
                                                                        1
                       
                                                                        x
                       
                                                                        z
                       
                               
                                        0

                       
                               
                                        1

                       
                               
                                        0

                       
                               
                                        0

                       
                               
                                        1

                       
                               
                                        1

                       
                               
                                        0

                       
                               
                                        1

                       
                               
                                        0

                       
                               
                                        1

                       
                               
                                        x

                       
                               
                                        0

                       
                               
                                        0

                       
                               
                                        1

                       
                               
                                        1

                       
                               
                                        z

                       
                               
                                        1

                       
                               
                                        1

                       
                               
                                        1

                       
                               
                                        1

                       
                                                                        casex
                       
                                                                        0
                       
                                                                        1
                       
                                                                        x
                       
                                                                        z
                       
                               
                                        0

                       
                               
                                        1

                       
                               
                                        0

                       
                               
                                        1

                       
                               
                                        1

                       
                               
                                        1

                       
                               
                                        0

                       
                               
                                        1

                       
                               
                                        1

                       
                               
                                        1

                       
                               
                                        x

                       
                               
                                        1

                       
                               
                                        1

                       
                               
                                        1

                       
                               
                                        1

                       
                               
                                        z

                       
                               
                                        1

                       
                               
                                        1

                       
                               
                                        1

                       
                               
                                        1

                       
         
        下面给出两个例子来分别说明casez语句和casex语句。
        例3:casez语句。
         
        reg[7:0] ir;
        casez(ir)
             8 'b1???????: instruction1(ir);             //只判断ir的最高位
             8 'b01??????: instruction2(ir);             //只判断ir的高2位
             8 'b00010???: instruction3(ir);             //只判断ir的高5位
             8 'b000001??: instruction4(ir);             //只判断ir的高6位
        endcase
         
        例4:casex语句。
         
        reg[7:0] r, mask;
        mask = 8'bx0x0x0x0;
        casex(r^mask)                                       //判断r^mask的结果
             8 'b001100xx: stat1;                           //不考虑低2位
             8 'b1100xx00: stat2;                           //不考虑第3、4位
             8 'b00xx0011: stat3;                           //不考虑第5、6位
             8 'bxx001100: stat4;                           //不考虑高2位
        Endcase
         
        其他条件语句

        上面提到的if语句和case语句都只能应用于always语句内部。如果需要在always语句之外应用条件语句,可以采样这样的语法结构:
         
        assign data = (sel)?  a : b;
         
        上面的语句的含义相当于:
        if (sel = 1)
             data = a;
        else
             data =  b;
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏 分享分享 支持支持 反对反对
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|文字版|手机版|DIY编程器网 ( 桂ICP备14005565号-1 )

GMT+8, 2025-8-3 05:33 , 耗时 0.084779 秒, 18 个查询请求 , Gzip 开启.

各位嘉宾言论仅代表个人观点,非属DIY编程器网立场。

桂公网安备 45031202000115号

DIY编程器群(超员):41210778 DIY编程器

DIY编程器群1(满员):3044634 DIY编程器1

diy编程器群2:551025008 diy编程器群2

QQ:28000622;Email:libyoufer@sina.com

本站由桂林市临桂区技兴电子商务经营部独家赞助。旨在技术交流,请自觉遵守国家法律法规,一旦发现将做封号删号处理。

快速回复 返回顶部 返回列表