關於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循環來作。
相關文章
相關標籤/搜索