关于Verilog 中的for语句的探讨

  在C语言中,常常用到for循环语句,但在硬件描述语言中for语句的使用较C语言等软件描述语言有较大的区别。html

     在Verilog中除了在Testbench(仿真测试激励)中使用for循环语句外,在Testbench中for语句在生成激励信号等方面使用较广泛,但在RTL级编码中却不多使用for循环语句。主要缘由就是for循环会被综合器展开为全部变量状况的执行语句,每一个变量独立占用寄存器资源,每条执行语句并不能有效地复用硬件逻辑资源,形成巨大的资源浪费。简单的说就是:for语句循环几回,就是将相同的电路复制几回,所以循环次数越多,占用面积越大,综合就越慢。算法

     在RTL硬件描述中,遇到相似的算法,推荐的方法是先搞清楚设计的时序要求,作一个reg型计数器。在每一个时钟沿累加,并在每一个时钟沿判断计数器状况,作相应的处理,能复用的处理模块尽可能复用,即便全部的操做不能复用,也采用case语句展开处理。测试

对于下面的for循环语句:  优化

1 for(i=0;i<16;i++) 2   DoSomething();

能够采用以下代码实现:
 
reg [3:0] counter; always @(posedge clk) if(syn_rst) counter<=4'b0;
  else counter<=counter+1; always @(posedge clk) begin case(counter) 4'b0000:
        4'b0001:
 ...... default: endcase end
     另外,有几个语法的细节须要注意一下。for(i=0;i<16;i=i+1)中的i既能够是reg型的变量也能够是integer类型的变量,可是当i是reg型的变量时,须要注意由于判断语句i<16的缘故,i应定义为reg[4:0] i而不是reg[3:0] i 。因为verilog中没有自增运算符,文中提到的for语句不能写成for(i=0;i<16; i++)的形式。

下面简单的列举几个用for实现的程序代码:
示例一:

verilog代码优化之for语句 - 初学者 - 既然选择了远方,便只顾风雨兼程!

 

 仿真结果以下:编码

 
仿真后的结果,因为采用了非阻塞赋值语句,因此每次在always借宿后才把值付给左边的寄存器。
 
不过在使用了阻塞赋值语句后,获得了目的,可是因为for语句的综合效率不高,且在时序逻辑中通常采用非阻塞赋值,所以最好不能这样写   ----转自特权同窗《深刻浅出玩转FPGA》
 
示例二: for用在纯组合逻辑中
举例:4位左移器(将低4位输入的数移到高4位)
 1 //Leftshift for 4 bits
 2 module For_Leftshift(  3 input wire [3:0]inp,  4 input wire L_EN,  5 output reg [7:0]result  6 );  7  
 8 integer i;  9 always@(inp or L_EN) 10 begin 11  result[7:4] = 0; 12  result[3:0] = inp; 13  if(L_EN == 1) 14  begin 15   for(i=4;i<=7;i=i+1) 16  begin 17    result[i] = result[i-4]; 18  end 19   result[3:0] = 0; 20  end 21 end 22  
23 endmodule

综合结果(RTL视图,实际是一个4位选择器)spa

1.jpg
 
示例三:for不只能够用在组合逻辑中,并且还能够用在时序逻辑中,用于在1个周期类完成整个for循环。
举例:在一个周期类完成对输入总线中高电平位的计数,则利用for循环实现加法器
 1 module For_Counter(  2 input wire clk,  3 input wire rst_n,  4 input wire [12:0] data,  5 output wire [3:0] numout  6 );  7 integer i;  8 reg[3:0] num;  9  
10 always @(posedge clk) 11  begin 12  if(!rst_n) 13   num = 0; 14  else
15  begin 16   for(i=0;i<13;i=i+1) 17    if(data[i]) num = num + 1; 18  end 19  end 20  
21 assign numout = num; 22  
23 endmodule

综合结果(RTL视图,加法器+触发器)设计

 
2.jpg
 
综上,能够看出for循环是能够综合的,并且效率很高。但所消耗的逻辑资源较大。在对速度(时钟周期数)要求不是很高的状况下,能够多用几个时钟周期完成任务,而没有必要用for循环来作。
相关文章
相关标签/搜索