一周掌握FPGA Verilog HDL语法 day 4

case语句

case语句是一种多分支选择语句,if语句只有两个分支可供选择,而实际问题中常常需要用到多分支选择,Verilog语言提供的case语句直接处理多分支选择。

case语句通常用于微处理器的指令译码,它的一般形式如下:

  1. case(表达式) <case分支项> endcase
  2. casez(表达式) <case分支项> endcase
  3. casex(表达式) <case分支项> endcase case

分支项的一般格式如下:

分支表达式: 语句

缺省项(default项): 语句

说明:

a) case括弧内的表达式称为控制表达式,case分支项中的表达式称为分支表达式。控制表达式通常表示为控制信号的某些位,分支表达式则用这些控制信号的具体状态值来表示,因此分支表达式又可以称为常量表达式。

b) 当控制表达式的值与分支表达式的值相等时,就执行分支表达式后面的语句。如果所有的分支表达式的值都没有与控制表达式的值相匹配的,就执行default后面的语句。

c) default项可有可无,一个case语句里只准有一个default项。下面是一个简单的使用case语句的例子。该例子中对寄存器rega译码以确定result的值。

  reg [15:0] rega; 
  reg [9:0] result;
  
  case(rega) 
      16 'd0: result = 10 'b0111111111; 
      16 'd1: result = 10 'b1011111111; 
      16 'd2: result = 10 'b1101111111; 
      16 'd3: result = 10 'b1110111111; 
      16 'd4: result = 10 'b1111011111; 
      16 'd5: result = 10 'b1111101111; 
      16 'd6: result = 10 'b1111110111; 
      16 'd7: result = 10 'b1111111011; 
      16 'd8: result = 10 'b1111111101; 
      16 'd9: result = 10 'b1111111110; 
      default:result = 'bx; 
  endcase

d) 每一个case分项的分支表达式的值必须互不相同,否则就会出现矛盾现象(对表达式的同一个值,有多种执行方案)。

e) 执行完case分项后的语句,则跳出该case语句结构,终止case语句的执行。

f) 在用case语句表达式进行比较的过程中,只有当信号的对应位的值能明确进行比较时,比较才能成功。因此要注意详细说明case分项的分支表达式的值。

g) case语句的所有表达式的值的位宽必须相等,只有这样控制表达式和分支表达式才能进行对应位的比较。一个经常犯的错误是用'bx, 'bz 来替代 n'bx, n'bz,这样写是不对的,因为信号x, z的缺省宽度是机器的字节宽度,通常是32位(此处 n 是case控制表达式的位宽)。

下面将给出 case, casez, casex 的真值表:

case语句与if_else_if语句的区别主要有两点:

1)与case语句中的控制表达式和多分支表达式这种比较结构相比,if_else_if结构中的条件表达式更为直观一些。

2)对于那些分支表达式中存在不定值x和高阻值z位时,case语句提供了处理这种情况的手段。下面的两个例子介绍了处理x,z值位的case语句。

例1:

  case ( select[1:2] ) 
      2 'b00: result = 0; 
      2 'b01: result = flaga; 
      2 'b0x, 
      2 'b0z: result = flaga? 'bx : 0; 
      2 'b10: result = flagb; 
      2 'bx0, 
      2 'bz0: result = flagb? 'bx : 0; 
      default: result = 'bx; 
  endcase

例2:

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

Verilog HDL针对电路的特性提供了case语句的其它两种形式用来处理case语句比较过程中的不必考虑的情况( don't care condition )。其中casez语句用来处理不考虑高阻值z的比较过程,casex语句则将高阻值z和不定值都视为不必关心的情况。所谓不必关心的情况,即在表达式进行比较时,不将该位的状态考虑在内。这样在case语句表达式进行比较时,就可以灵活地设置以对信号的某些位进行比较。见下面的两个例子:

例3:

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

例4:

  reg[7:0] r, mask; 
  
  mask = 8'bx0x0x0x0; 
  
  casex(r^mask) 
       8 'b001100xx: stat1; 
       8 'b1100xx00: stat2; 
       8 'b00xx0011: stat3; 
       8 'bxx001100: stat4; 
  endcase

由于使用条件语句不当在设计中生成了原本没想到有的锁存器

Verilog HDL设计中容易犯的一个通病是由于不正确使用语言,生成了并不想要的锁存器。下面我们给出了一个在“always"块中不正确使用if语句,造成这种错误的例子

 

检查一下左边的"always"块,if语句保证了只有当al=1时,q才取d的值。这段程序没有写出 al = 0 时的结果, 那么当al=0时会怎么样呢?

在"always"块内,如果在给定的条件下变量没有赋值,这个变量将保持原值,也就是说会生成一个锁存器。

如果设计人员希望当 al = 0 时q的值为0,else项就必不可少了,请注意看右边的"always"块,整个Verilog程序模块综合出来后,"always"块对应的部分不会生成锁存器。

Verilog HDL程序另一种偶然生成锁存器是在使用case语句时缺少default项的情况下发生的。

case语句的功能是:在某个信号(本例中的sel)取不同的值时,给另一个信号(本例中的q)赋不同的值。注意看下图左边的例子,如果sel=0,q取a值,而sel=11,q取b的值。这个例子中不清楚的是:如果sel取00和11以外的值时q将被赋予什么值?在下面左边的这个例子中,程序是用Verilog HDL写的,即默认为q保持原值,这就会自动生成锁存器。

右边的例子很明确,程序中的case语句有default项,指明了如果sel不取00或11时,编译器或仿真器应赋给q的值。程序所示情况下,q赋为0,因此不需要锁存器。

以上就是怎样来避免偶然生成锁存器的错误。如果用到if语句,最好写上else项。如果用case语句,最好写上default项。遵循上面两条原则,就可以避免发生这种错误,使设计者更加明确设计目标,同时也增强了Verilog程序的可读性。

循环语句

在Verilog HDL中存在着四种类型的循环语句,用来控制执行语句的执行次数。

  1. forever 连续的执行语句。
  2. repeat 连续执行一条语句 n 次。
  3. while 执行一条语句直到某个条件不满足。如果一开始条件即不满足(为假), 则语句一次也不能被执行。
  4. for通过以下三个步骤来决定语句的循环执行。
    a) 先给控制循环次数的变量赋初值。
    b) 判定控制循环的表达式的值,如为假则跳出循环语句,如为真则执行指定的语句后,转到第三步。
    c) 执行一条赋值语句来修正控制循环变量次数的变量的值,然后返回第二步。下面对各种循环语句详细的进行介绍。

forever语句

forever语句的格式如下:

forever 语句; 或 forever begin 多条语句 end

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值