1. 程式人生 > 其它 >FPGA基本結構之Xilinx FPGA的組成部分

FPGA基本結構之Xilinx FPGA的組成部分

FPGA中的基礎邏輯單元--Xilinx

 

Xilinx FPGA的組成部分

本文是以Xilinx Kintex UltraScale+ 系列為參考所寫,其他系列有所不同,可以參考相應的user guide文件。

Xilinx家的FPGA有這麼些基本組成部分:

  1. Configurable Logic Block (CLB)可程式設計邏輯塊
  2. Block Memory儲存器
  3. DSP數字訊號處理器
  4. Transceivers收發器
  5. I/O pins輸入輸出埠

參考文件:Xilinx UltraScale architecture.

從Implemented Design中可以看到FPGA中資源大致分佈如下。中間藍色是CLB可程式設計邏輯塊、DSP或BRAM,兩側的彩色矩形塊是I/O介面和收發器,劃分的方塊是不同的時鐘域

Configurable Logic Block (CLB)可程式設計邏輯塊

CLB是FPGA內部實現可程式設計性的主要成分,其中可以包括:

  1. LUT查詢表
  2. 高速算術邏輯
  3. 分散式儲存distributed memory或移位暫存器shift register logic (SRL) ability

具體內容可以參考這個:UG574 CLB

Look-Up Table (LUT)查詢表

每個CLB中包含一個slice,每個slice提供8個6輸入查詢表LUT和16個暫存器(slice就是CLB中一個小的分割,有的CLB中有兩個,不知道怎麼翻譯這個詞)。每個6輸入LUT可以被設定成1個6輸入查詢表或者2個5輸入查詢表。可以這麼配置的原因跟LUT結構有關。

上圖是一個4輸入查詢表的結構,[ABCD]作為4位二進位制輸入,總共有24=16種輸入,每種輸入對應的1位輸出就存在左側的暫存器中,因此查詢表可以完成每一種二進位制邏輯。在右側可以看到一個4輸入LUT其實是兩個3輸入LUT再加上一個2路複用器MUX,最後的MUX由新加入的一位控制,如果要拆開就把兩個3輸入LUT的結果繞開最後的MUX輸出即可。同樣就可以理解6輸入LUT拆分成兩個5輸入LUT的原因。

之前介紹Altera的ALM時說過,LUT太深或太淺都不好,太深需要很多暫存器,而且MUX層數太多,延遲嚴重;太淺不方便配置邏輯,浪費過多空間。A家和X家根據客戶實際使用情況調查過之後得到的結論相同,6輸入LUT目前來說是最平衡的,如果需要的話就拆成小的LUT,一般以6輸入為主。

LUT的輸出如下,O6是作為6輸入LUT的結果,O5是作為兩個5輸入LUT的結果,有2位。它的結果可以直接作為slice的輸出,也可以傳遞到暫存器中儲存。而存入暫存器的資料也可以不經過LUT,直接從外界讀取。

Xilinx的Toolchain會自動配置這部分內容,但是瞭解細節可以更好的利用FPGA中的資源,比如下面三段程式碼,第一段只用上了LUT查詢表輸出,第二段繞過了LUT輸入到暫存器中,而第三段同時用上了LUT查詢表和暫存器,可以說是對slice利用率最高的。

  1.   // Code 1
  2.   wire [1:0] output;
  3.   wire [5:0] input;
  4.   assign output[0] = input[0]&input[1]|input[2];
  5.   assign output[1] = input[3]|input[4]^input[5];
  1.   // Code 2
  2.   wire clk, rst;
  3.   reg [1:0] output;
  4.   reg [1:0] input; // Coming from previous registers
  5.   always @(posedge clk or posedge rst) begin
  6.   if(rst)
  7.   output <= 2'b00;
  8.   else
  9.   output <= input;
  10.   end
  1.   // Code 3
  2.   wire clk, rst;
  3.   reg [1:0] output;
  4.   wire [5:0] input;
  5.   always @(posedge clk or posedge rst) begin
  6.   if(rst)
  7.   output <= 2'b00;
  8.   else begin
  9.   output[0] <= input[0]&input[1]|input[2];
  10.   output[1] <= input[3]|input[4]^input[5];
  11.   end
  12.   end

在project比較小的時候自然不用注意這麼多,project大大時候toolchain有一定的能力幫你平衡這些資源利用,這種摳牙縫的手段在FPGA特別小,或者程式碼太大,或者時鐘很高時就有用了。在時鐘高時,為了儘可能縮簡訊號之間的佈線距離,能用暫存器緩衝的就要儘量用,但只是用pipeline的形式加入相當於浪費了一些slice中的LUT部分,最好的辦法就是把暫存器加在邏輯中間,這樣利用率就提高了。比如在不優化的情況下,第二段比第一段程式碼更高效,時鐘環境更好(自己做總比不知道toolchain做了什麼要好):

  1.   // Code 1
  2.   wire clk, rst;
  3.   wire [5:0] input;
  4.   reg [1:0] pipeline;
  5.   reg output;
  6.   always @(posedge clk or posedge rst) begin
  7.   if(rst) begin
  8.   pipeline <= 2'b00;
  9.   output <= 1'b0;
  10.   end
  11.   else begin
  12.   pipeline[0] <= &input; // And every bits from input
  13.   pipeline[1] <= pipeline[0]; // Pipeline it
  14.   output <= pipeline[1];
  15.   end
  16.   end
  1.   // Code 2
  2.   wire clk, rst;
  3.   wire [5:0] input;
  4.   reg [1:0] pipeline;
  5.   reg output;
  6.   always @(posedge clk or posedge rst) begin
  7.   if(rst) begin
  8.   pipeline <= 2'b00;
  9.   output <= 1'b0;
  10.   end
  11.   else begin
  12.   pipeline[0] <= &input[2:0]; // And first 3 bits from input
  13.   pipeline[1] <= &input[5:3]; // And last 3 bits from input
  14.   output <= pipeline[0] & pipeline[1];
  15.   end
  16.   end

高速算術邏輯

和Altera中的ALM相似,Xilinx的slice中也有小的加法器,使得小位數的加法、乘法、計數器可以在其中實現。但是高位數的算術運算就不適合在其中實現了,容易出現各種時鐘問題,而且浪費大量邏輯資源,這種運算最好交給之後的DSP資源來實現。

分散式儲存distributed memory或移位暫存器shift register logic (SRL) ability

Slice也分兩種,前面介紹的是普通的SLICEL (logic),也就是邏輯slice,還有一種是強化了儲存功能的SLICEM (memory),也就是儲存slice。SLICEM也可以當作SLICEL用,擁有SLICEL的一切功能,但SLICEM添加了地址線write address埠和寫使能write enable埠,使得6輸入LUT中的26=64個暫存器可以被配置成64-bits RAM,8個6輸入LUT合起來就可以是一個512-bit RAM。

Xilinx還有一個特殊的設計,可以讓這64 bits互相連線變成一個移位暫存器,比起使用後面的register暫存器利用率高很多。舉個栗子的話:

  1.   // Shift registers
  2.   genvar i;
  3.   wire [3:0] addr_1 = 4'd15;
  4.   wire [41:0] D_1;
  5.   wire [41:0] Q_1;
  6.   assign D_1 = input;
  7.   assign output = Q_1;
  8.    
  9.   // 42bit X 16
  10.   generate
  11.   for(i=0; i<42; i=i+1) begin : Shift
  12.   SRL16E #(
  13.   .INIT(16'h0000), // Initial contents of shift register
  14.   .IS_CLK_INVERTED(1'b0) // Optional inversion for CLK
  15.   )
  16.   Shift_UP2_1 (
  17.   .Q(Q_1[i]), // 1-bit output: SRL Data
  18.   .CE(1'b1), // 1-bit input: Clock enable
  19.   .CLK(clk), // 1-bit input: Clock
  20.   .D(D_1[i]), // 1-bit input: SRL Data
  21.   // Depth Selection inputs: A0-A3 select SRL depth
  22.   .A0(addr_1[0]),
  23.   .A1(addr_1[1]),
  24.   .A2(addr_1[2]),
  25.   .A3(addr_1[3])
  26.   );
  27.   end
  28.   endgenerate

也許有人會想,為什麼要考慮那麼多小技巧把程式碼變複雜,硬體程式設計跟軟體程式設計的不同就在這裡,用實際電路的思維來考慮,它的實現情況和用指令集資料庫的軟體程式設計有很多不同點。寫簡單的程式碼有時候被編譯後就變成低效的結構。新手寫RTL程式碼會出現a=b*c;這種,每次看到都會頭皮發麻。

因此設計RTL時,推薦這種優化步驟:

  1. 儘量少用reset,並且不要同時用同步reset和非同步reset
  2. 暫存器很多,能用盡量用,對時鐘環境好(不要用always *,同樣看到頭皮發麻)
  3. 寫暫存器的控制訊號簡單點,儘量也用暫存器pipeline一下
  4. 移位暫存器比較特殊,不要用復位訊號,儘量用上LUT中的SRL,reset訊號會讓tool避免用SRL
  5. 少於64bits的儲存用SLICEM來做,Xilinx tool中一般叫LUTRAM
  6. 位數較高的加法、計數器,以及儘可能所有常常呼叫的乘法用DSP來實現

Block Memory儲存器

在CLB中的LUTRAM之外,Xilinx晶片中的內建儲存器就是BRAM儲存器了。每個BRAM可以被配置成兩個獨立的18kb RAM或者一個36kb RAM,每個BRAM有兩個獨立的讀寫埠


如果一個36kb的BRAM不夠用,還可以把多個BRAM連線在一起:

詳細可參考:Xilinx BRAM

DSP數字訊號處理

Xilinx的FPGA中高位加法和乘法主要是由DSP數字訊號處理器承擔的,其結構如下


根據不同的配置,可以構成一系列公式,比如下面幾種
P = ( A ± D ) ∗ B + C P = B 2 + P P = A ± D ± C P=(A\pm D)*B+C\\ P=B^2+P \\ P=A\pm D\pm CP=(A±D)∗B+CP=B2+PP=A±D±C

和Altera FPGA中的DSP相比,兩個乘法器變成一個,多了平方選項和XOR邏輯,以及比較邏輯。相比起來Xilinx FPGA中的DSP雖然整合度沒有那麼高,但靈活性更高,更方便配置成各種需要的形式,設計FIR這類結構時,可以很明顯感受到Xilinx中的DSP設計出的結構複雜度低很多,不需要考慮兩個乘法器帶來的協同性問題。

呼叫Xilinx的DSP有比較多的注意事項,程式碼也相對較長,之後可以單獨寫一篇。

Transceivers收發器

在Kintex UltraScale+系列中的收發器有Gigabit Transceivers H/Y (GTH/GTY)兩種,後面的H和Y代表不同的傳輸速率,具體是哪個單詞沒有找到。這些高速收發器可以承擔不同的介面任務,常見的有PCIe、SFP、10G網、SATA等。

讓傳輸速率更高一直是通訊行業的核心問題,這個毋庸置疑,無論哪種介面,要在FPGA上實現,不可避免的要用到這些收發器。

這裡的細節太多,全寫一遍可以出一本書,我也只懂些皮毛,這裡放一張大概的結構圖,挖個坑等我邊寫邊填。

I/O pins輸入輸出埠

在Xilinx UltraScale系列中有三種I/O bank,一種是High-performance (HP)高效能、High-density (HD)高密度、High-range(HR)大範圍。HP可以滿足1.8V以下訊號的效能需求,HD可以在支援低速介面的情況下儘可能減小面積,HR可以支援更多的3.3V以下標準。


詳細可參考:UG571 SelectIO

總結

在我看來,和Altera的FPGA相比,Xilinx的FPGA與之最大區別就是DSP的不同。雖說兩個公司對一些資源的名稱不同,分割方式不同,但其邏輯的主體LUT沒有太大區別,BRAM的區別也不大,只有DSP有結構上的不同。至於對外的介面,個人認為對內部邏輯影響不大。