1. 程式人生 > >Verilog中 for 語句

Verilog中 for 語句

[轉載]https://www.cnblogs.com/xd-elegant/p/4520920.html

在C語言中,經常用到for迴圈語句,但在硬體描述語言中for語句的使用較C語言等軟體描述語言有較大的區別。

     在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位)

//Leftshift for 4 bits
module For_Leftshift(
input wire [3:0]inp,
input wire L_EN,
output reg [7:0]result
);
 
integer i;
[email protected](inp or L_EN)
begin
 result[7:4] = 0;
 result[3:0] = inp;
 if(L_EN == 1)
 begin
  for(i=4;i<=7;i=i+1)
  begin
   result[i] = result[i-4];
  end
  result[3:0] = 0;
 end
end
 
endmodule

綜合結果(RTL檢視,實際是一個4位選擇器)

1.jpg

 

示例三:for不僅可以用在組合邏輯中,而且還可以用在時序邏輯中,用於在1個週期類完成整個for迴圈。

舉例:在一個週期類完成對輸入匯流排中高電平位的計數,則利用for迴圈實現加法器

module For_Counter(
input wire clk,
input wire rst_n,
input wire [12:0] data,
output wire [3:0] numout
);
integer i;
reg[3:0] num;
 
always @(posedge clk)
 begin
 if(!rst_n)
  num = 0;
 else
  begin
  for(i=0;i<13;i=i+1)
   if(data[i]) num = num + 1;
  end
 end
 
assign numout = num;

綜合結果(RTL檢視,加法器+觸發器)

 

2.jpg

 

綜上,可以看出for迴圈是可以綜合的,而且效率很高。但所消耗的邏輯資源較大。在對速度(時鐘週期數)要求不是很高的情況下,可以多用幾個時鐘週期完成任務,而沒有必要用for迴圈來做