tag 标签: 循环语句

相关博文
  • 热度 18
    2012-12-6 07:58
    5918 次阅读|
    0 个评论
      11.1.3 有限的while 我们有了定数的循环和永远的循环,貌似还是少了什么,当我们需要在一定条件下实现有限的循环的时候,又怎么办呢?Verilog这个时候告诉你还有while呢,其格式如下: while(条件表达式)          begin          end while语句是执行块语句直到某个条件不满足,如果一开始条件就不满足,则while中的块语句一条也不执行,这个与C语言中的用法相同,例如:我们用while对数据中1的个数进行计算,程序代码段如下:                             while(data_while)                             begin                                      if(data_while )                                      begin                                                data_count = data_count+1;                                                data_while = data_while1;                                      end                                      else                                      begin                                                data_while = data_while1;                                      end                             end       上图中红色所圈数据分别是输入数据,和while语句统计的结果,明显地,while语句实现了我们想要的功能,同样地,while语句还是只能仿真,并不能形成电路,最终为我们所用,对于写测试文件,还是会很有帮助的。   11.2特立独行的for 前面我们介绍了只能仿真的循环语句,在实际实现的过程中,似乎它们都帮不上什么忙,但是Verilog中还有一个特立独行的for,它能够在电路中实现循环,可是它也存在着弊端,下面我们会通过具体的例子看看Verilog中的for语句存在什么样的问题。   11.2.1 for的基本形态 Verilog中的for循环与C语言中的for循环有着相同的使用方式,它是while和repeat的结合体,在满足一定条件下做次数确定的循环。其格式如下: for(表达式1;表达式2;表达式3) 执行语句 相信这样的表达形式对于写过代码的人都非常熟悉,“表达式1”是循环变量赋初值,它只在第一次循环开始之前被执行一次;“表达式2”是循环执行条件,它在每次循环开始之前都会执行;“表达式3”是循环变量增量,而它是在每次循环结束之后被执行。一般来说,循环变量赋初值即表达式1和循环变量增量即表达式3是两条过程赋值语句,循环执行条件即表达式2是一个逻辑表达式,在每次执行循环体之前都需要判断该表达式是否成立。 有了Verilog中for的基本形态,我们就通过具体的例子来看看这个可以综合的for,以及前面我们提到的for的弊端,且看下节。   11.2.2可以综合的for Verilog中for的基本形态和C语言中一样,就连它的使用也与C语言大同小异,不同之处在于Verilog中的for循环要放在always块语句中,下面是一个用for循环来实现输入数据阶乘的一个简单程序: moduleLoopingFor(                                                         data,                                                         clk,                                                         rst,                                                         out                                                    );   input data; inputclk; inputrst;   output wire out;   reg out_temp=16'd1; reg j;   always @(data) begin          out_temp=16'd1;          for(j=data;j!=0;j=j-1)                    begin                             out_temp = out_temp*j;                    end end   assign out = out_temp;   endmodule       上图是程序的仿真结果,仿真我们是实现了,但是当我们对上述程序进行综合时,会发现有着这样的问题:   for(j=data;j!=0;j=j-1)中表达式1,即循环变量赋初值必须是确定的数值,不能用输入信号进行赋值,也就是说,对于可综合的for循环,for中的三个表达式必须是能计算出来且不再变化的表达式,输入信号出现在三个表达式的任何一个表达式中都不能综合。将上面的例子改为可以综合的for循环,例如: always @(data) begin          out_temp=32'd1;          for(j=4'd1;j=4'd16;j=j+1)                    begin                             out_temp = (j=data)?(out_temp*j):out_temp;                    end end 所以并不是所有的for都能综合,有的for语句是只能仿真,不能综合,只有当for的三个表达式满足一定条件时才能两面皆能,既仿真又综合,比如下面这个例子,我们对输入数据中1的个数进行计数,程序代码段如下: always @(posedgeclk) begin          if(!rst)          begin                    count_1=4'd0;          end          else          begin                    count_1=4'd0;                    for(j=0;j=3;j=j+1)                             begin                                      if(data )                                                count_1 = count_1+1;                                      else;                                                                  end          end end 仿真结果如下:   计数输出比输入数据晚一个时钟周期,如图中红线所圈,通过仿真,我们知道该代码段实现了我们想要的功能,同时也能完成综合。 不管怎样,在Verilog编程中,还是建议少使用for循环语句,尤其是过大的for循环,因为循环几次就意味着几个相同电路单元的出现,这样容易造成组合过大,而for循环要在一个时钟周期内执行完毕,过大的for循环可能会导致一些时序问题,不仅仅如此,还会造成资源的浪费,是一种比较懒的编程语句,它仅仅节省了代码长度,但是对于硬件上的实现,却要花费意想不到的代价,得不偿失。 漂亮姑娘不一定适合做老婆,所以好看的程序也不一定适合硬件实现,for循环也正是如此,所以,我还是觉得尽量用别的方式来实现,比如计数,总归是能找到替代品的,正所谓天涯何处无芳草,循环别把for来找。