LabVIEW FPGA PCIe開發講解-7.2節:目前主流的4大Xilinx FPGA PCIe DMA通訊IP核講解

1、要開發一個帶PCIe或者PXIe介面的FPGA板卡出來,除了硬體本身外,最重要的就是FPGA晶片裡面的PCIe通訊程式碼撰寫,俗稱下位機FPGA程式設計;還有中間層的驅動檔案撰寫以及上位機PC端的應用程式開發。

2、其中,中間層驅動和上位機PC端一般都可以使用C語言或者LabVIEW進行開發,但是下位機FPGA裡面的PCIe程式碼一般會採用VHDL或者Verilog進行撰寫,難度比較大,尤其是涉及到PCIe DMA這類複雜的通訊協定,開發難度和工作量會非常大,導致很多應用工程師在做PCIe相關的FPGA嵌入式開發時,碰到了不少坑,投入了很多精力和時間也沒有把FPGA PCIe DMA做穩定。

3、本章重點就是告訴使用者如何使用LabVIEW在FPGA晶片裡面撰寫PCIe DMA程式,徹底解決下位機FPGA程式碼撰寫的痛點,讓LabVIEW圖形化程式設計語言深入到FPGA骨髓裡面去,降低FPGA PCIe嵌入式開發門檻,真正發揮出PCIe匯流排高速通訊的能力。

4、目前Xilinx FPGA晶片是全球出貨量最多的,同時晶片種類也是最多的,所以我們重點需要研究的就是Xilinx FPGA晶片的PCIe通訊IP核。目前市面上現有的支援Xilinx FPGA晶片的PCIe DMA通訊IP主要有以下4家:
? Xilinx官方推出的XAPP1052和XMDA IP核
? 以色列Xillybus FPGA PCIe DMA IP核
? GitHub上的RIFFA(AReusable Integration Framework For FPGA Accelerators)IP 核
? 北大無線可重構體系結構課題小組的框架:EPEE(Efficient and Flexible Host-FPGA PCIe Communication Library)

下面我們簡單介紹一下這4家方案。
1)Xilinx官方的PCIe IP核有兩個版本:一個是很古老的XAPP1052,一個是近些年才推出的XDMA IP核。其中,XAPP1052 IP核和常式提供了全部的底層Verilog原始碼,便於使用者去理解和掌握PCIe通訊協定在FPGA裡面是怎麼實現的,但是這些程式碼據說在使用的時候,存在一些坑,儘管網上有很多高手給出了方案,但是對於沒有經驗的使用者來說,可能會造成不必要的困擾;後來,Xilinx下定決心,重新開發了一個也就是現在大家所熟知的XDMA IP核框架,這個也是目前主流的開發板廠商採用的方案。國內做Xilinx FPGA開發板業務比較大的當屬黑金和米聯客,其中米聯客對Xilinx提供的XAPP1052和XDMA都有詳細的教學和影片,當然是收費的;而黑金現在基本上都是基於XDMA撰寫的FPGA PCIe常式。

Xilinx官方提供的XDMA IP核方案有一個不足的地方,就是PCIe通訊時的通道數量有限制,使用者無法靈活配置,只能兩上兩下,無法實現8上8下這種,除非使用者自己透過軟體撰寫實現,這樣工作量就會無比巨大。另外,Xilinx官方提供的驅動檔案沒有經過微軟數值簽名認證,無法正常安裝,只能將windows系統設定到測試模式下才行,這點對於普通使用者來說,比較麻煩。

2)以色列XILLYBUS公司推出的Xillybus FPGA PCIe DMA驅動IP核。這家公司技術實力非常全面,在很早的時候,就把複雜的FPGA PCIe DMA通訊技術透過自己的封裝變成傻瓜化,讓使用者能夠輕輕鬆鬆整合到自己的專案和產品應用中。與此同時,該公司還把USB 3.0協定進一步封裝成非常易用的FPGA IP核,以及將Xilinx ZYNQ平台裡面的AXI4匯流排重新封裝了。除此之外,Xillybus不僅僅支援Xilinx公司帶PCIe的全系列FPGA晶片,還支援Altera公司帶PCIe的全系列FPGA 晶片。

XILLYBUS公司這樣做的目的就是為了降低開發者的門檻,節約軟體工程師大量的開發時間成本。其實,這個本應該是Xilinx公司該乾的事情,但是Xilinx卻沒有這樣做,很多原創公司做的軟體其實都太偏底層了,應用層和易用性都不太好。

下面,我們來看看,Xillybus是如何將一個複雜的PCIe DMA封裝成傻瓜式的IP核,讓使用者不費吹灰之力就能嵌到自己的FPGA程式裡面。先看圖7-5所示。

圖7-5:Xillybus PCIe IP核內部連結示意圖

首先,Xillybus將Xilinx或Altera公司的底層PCIe介面IP core,接入到它自己的Xillybus IP core,然後再透過四線握手的Application FIFO介面將收發TX、RX通道對映出來給到FPGA。結構非常清晰,使用者即使完全不懂PCIe通訊協定,也可以很簡單的在FPGA裡面透過呼叫Xillybus提供的收發FIFO介面,將資料發送到上位機PC或者接收上位機PC下發的資料,因為Xillybus直接將底層的IP核全部遮罩了,使用者只需要按照標準的四線握手協定來操作對應的FIFO緩衝區就可以了。而上位機PC端更加簡單,只需要透過開啟被系統(Windows和Linux都支援)識別出來的名為xillybus的PCIe裝置,然後呼叫標準的檔案讀寫函式,進行檔案讀寫即可控制底層FPGA晶片裡面的FIFO資料的收發。

這個控制過程其實就跟全雙工的序列埠通訊一樣簡單,使用者只需要關心資料存放在哪裡,到哪裡去讀資料就可以了;另外,Xillybus還提供了一個web配置頁面,使用者可以直接在上面自由的分配FPGA端的PCIe通道數量和通道傳輸速率,非常方便,例如,在一個既有高速採集又有很多控制命令和引數傳輸的應用中,如果我們直接在頁面上配置多個不同位寬不同傳輸速度的Channel,那麼使用者在FPGA裡面程式設計和上位機解析的時候就會非常方便,因為每個通道都是一個獨立的存在,例如將需要高速採集傳輸的資料流透過64位位寬的Channel0發送給PC(上行),將上位機低速的控制引數透過8位位寬的Channel4發送給FPGA(下行),如圖7-6所示。
圖7-6:Xillybus PCIe IP通道引數配置頁面

在後續我們封裝出來給使用者的LabVIEW FPGA PCIe CLIP裡面,我們預設提供了8上8下,一共16個通道,這樣極大的方便了使用者今後在自己的專案裡面使用PCIe通訊,而無需考慮因為通道不夠導致資料不好解析的尷尬。從上位機PC端的角度來看,其實這8上8下的PCIe通道,本質上有點類似8對序列埠通訊,只不過PCIe的傳輸速度遠快於序列埠、USB、網口而已。因此,使用者在上位機就可以像操作序列埠那樣透過PCIe匯流排來操作和訪問FPGA裡面的資料了,開發過程非常簡單,只要會一點LabVIEW就能輕鬆搞定。

3)GitHub上的RIFFA(AReusable Integration Framework For FPGA Accelerators)IP 核

RIFFA(用於FPGA加速器的可重用整合框架),它是用於透過PCIe匯流排從主機CPU到FPGA相互之間進行資料互動的簡單框架。該框架要求具有PCIe的上位機PC或者工控機和帶有PCIe介面的FPGA硬體。RIFFA中間層驅動支援Windows和Linux,底層驅動FPGA PCIe IP核支援Xilinx和Altera晶片,上位機應用層支援LabVIEW、C / C ++、Python、Matlab和Java。
軟體方面,RIFFA有兩個主要功能:資料發送和資料接收。上層提供C / C ++、Python、MATLAB、Java下的DLL連結庫。中間層驅動程式在每個系統(Linux和Windows作業系統)下支援識別多個FPGA(最多5個)。

硬體方面,使用者訪問具有獨立發送和接收訊號的介面(全雙工),無需了解匯流排地址,緩衝區大小或者PCIe資料包格式。只需在FIFO介面上發送資料並在FIFO介面上接收資料即可。RIFFA不依賴於PCIe橋接器,因此不受橋接器實現的限制。取而代之的是,RIFFA直接與PCIe端點一起使用,RIFFA使用直接記憶體訪問(DMA)傳輸和中斷訊號傳輸資料。這樣可以在PCIe鏈路上實現高頻寬。軟體和硬體介面都已大大簡化。
關於RIFFA PCIe IP核的工作示意圖,如圖7-7所示。

圖7-7:RIFFA PCIe IP工作示意圖

FPGA底層整合了Xilinx的PCIe core,然後使用TX、RX引擎,經過通道仲裁對映到最多12個TX、RX通道上。結構與PIO、BMD的結構類似,增加了通道擴展的功能,這樣使用者就不需要自己去寫仲裁程式碼了。

上位機PC端主要就是基本的驅動、應用結構,PCIe的訪問空間對映到了PC的記憶體上;中間層的RIFFA驅動負責記憶體以及PCIe介面的管理,RIFFADLL檔可以被使用者應用程式呼叫,從而實現對底層RIFFA驅動的呼叫,並最終實現PCIe的資料通訊。
可以看出,這個RIFFA的框架跟上面的Xillybus框架其實很類似,只不過Xillybus更強大更靈活,基於Web的通道配置頁面裡面可以實現最多128個通道的任意分配和頻寬設定,遠多於RIFFA的12個通道。

4)北大的EPEE(Efficient and Flexible Host-FPGA PCIe Communication Library)

最後一個就是曇花一現的北大開源組織做的EPEE,圖7-8是其系統框圖,感興趣的使用者可以自行分析,因為目前可以找到這個EPEE的資料和應用非常少,這裡就不在介紹了。

總結:對於我們傳統的嵌入式工程師來說,選擇一個合適的FPGA PCIe驅動IP非常重要,不僅可以節約大量開發時間,關鍵是穩定性要比我們自己寫的更好,畢竟很多商業的FPGA驅動IP核和驅動inf檔案都是經過了大量企業實踐檢驗過的,而很多所謂的開原始碼,實際上用起來總是有這樣那樣的bug和坑,需要使用者自己花費大量的時間去除錯、修改和維護,有時候得不償失。如果是做產品的話,個人愚見,還是用成熟的企業版軟體工具包和FPGA驅動IP核,畢竟穩定勝於一切,社會分工不一樣。

經過上面的講解和分析,最終我們選擇了以色列的Xillybus作為我們LabVIEW FPGA底層PCIe驅動IP核的候選,我們將整個Xillybus的FPGA PCIe IP核以CLIP的方式重新封裝到LabVIEW My FPGA下面,這樣使用者就能透過LabVIEW圖形化的方式直接呼叫這個IP核了(關於這個PCIe DMA CLIP的詳細介紹,後面專門會有一節進行講解),使用者只需要會一點點LabVIEW就可以將最為複雜的FPGA PCIe DMA通訊輕鬆拿下。

旁白:我們也衷心地希望國內有更多的牛人、高手或者企業能夠像以色列Xillybus公司那樣專註於做一件事情,然後把這件事做到極致,做出屬於我們中國人自己的底層FPGA PCIe IP核、中間層驅動inf和上層應用層DLL。我相信這一天早晚會到來!