LabVIEW FPGA PCIe開發(fā)講解-7.4節(jié):LabVIEW FPGA PCIe 8通道DMA Socket CLIP

?????? ?本節(jié)我們重點(diǎn)給用戶講解一下我們封裝好的LabVIEW FPGA下的PCIe CLIP組件功能和用法。這個(gè)PCIe CLIP也是我們My FPGA軟件工具包的核心組件之一,我們花費(fèi)了近3個(gè)月的時(shí)間,將Xillybus官方提供的代碼進(jìn)行移植、修改和適配,并進(jìn)行了大量的測(cè)試驗(yàn)證,最終才把底層的精髓部分PCIe DMA IP封裝到LabVIEW FPGA CLIP里面來,并且給用戶提供了極其簡(jiǎn)單的四線握手FIFO接口,所有關(guān)于PCIe協(xié)議本身的通信都封裝到底層去了,用戶不需要了解什么是PCIe,一樣可以使用LabVIEW FPGA來調(diào)用這個(gè)PCIe CLIP進(jìn)而快速開發(fā)出一個(gè)屬于自己的PCIe FPGA設(shè)備來。
?????? ?Xillybus官方提供了4個(gè)版本的PCIe DMA通信IP核,分別是A版本、B版本、XL版本和XXL版本。其中,A版本在PCIe X4模式下的最大吞吐率是400MB/s,X8模式下是800MB/s;B版本在X4模式下是800MB/s,在X8模式下是1.6GB/s;而XL和XXL版本對(duì)應(yīng)的傳輸速度則分別是B版本的2倍和4倍,比如XXL版本可以實(shí)現(xiàn)目前Xilinx最新款的KU芯片PCIe最高傳輸帶寬6.6GB/s。
?????? ?目前我們默認(rèn)提供給用戶使用的是A版本和B版本的Socket CLIP組件,而XL和XXL版本則需要向Xillybus公司發(fā)郵件申請(qǐng),同意之后就可以開發(fā)更高帶寬的PCIe總線設(shè)備了。
?????? ?對(duì)于目前大多數(shù)應(yīng)用來說,800MB/s完全足夠了,相當(dāng)于六七個(gè)千兆以太網(wǎng)同時(shí)并行傳輸了。并且超過800MS/s的應(yīng)用,一般多是RF射頻和高速流盤系統(tǒng),如果直接將超過800MB/s的數(shù)據(jù)放到計(jì)算機(jī)內(nèi)存里面也是瞬間就會(huì)爆掉,所以一般都會(huì)配一個(gè)磁盤陣列來保存數(shù)據(jù),中間的過程,用戶很難在PC端對(duì)數(shù)據(jù)進(jìn)行在線處理,因?yàn)槿魏嗡惴ǘ加锌赡軐?dǎo)致數(shù)據(jù)不連續(xù),如果把算法放到FPGA里面運(yùn)行,對(duì)數(shù)據(jù)進(jìn)行逐點(diǎn)處理,則完全不影響上位機(jī)的數(shù)據(jù)流盤或者顯示。
?????? ?下面我們重點(diǎn)給用戶介紹一下我們封裝好的8上8下的FPGA PCIe DMA Socket CLIP,首先在LabVIEW項(xiàng)目瀏覽器下的“我的電腦”上右擊,選擇新建“終端和設(shè)備”,如圖7-35所示。

? ? ? ? 然后在彈出來的終端設(shè)備新建對(duì)話框里面,找到ARTIX7-100T對(duì)應(yīng)的X4模式下8通道下的A和B兩個(gè)版本的FPGA終端,如圖7-36所示。

? ? ? ??點(diǎn)擊“確定”按鈕后,這兩個(gè)版本的PCIe通信Socket CLIP組件會(huì)自動(dòng)添加到FPGA終端里面來,圖7-37顯示的是A版本的LabVIEW FPGA CLIP,圖7-38顯示的是B版本的LabVIEW FPGA CLIP。
?????? ?展開這兩個(gè)CLIP之后,用戶可以看到一共有50個(gè)EIO節(jié)點(diǎn),雖然多,是因?yàn)槲覀兎庋b了8上8下,也就是16個(gè)通道,每個(gè)通道都是一個(gè)標(biāo)準(zhǔn)的四線握手制FIFO,相當(dāng)于3根線,所以,所有通道的握手信號(hào)就有16×3=48個(gè),再加上1個(gè)100MHz同步時(shí)鐘和反應(yīng)PCIe IP工作狀態(tài)的的4個(gè)LED燈,一共就是48+1+1=50個(gè)EIO節(jié)點(diǎn)。


? ? ? ? 默認(rèn)情況下,我們給這8上8下共計(jì)16個(gè)PCIe通道分配的驅(qū)動(dòng)名稱和帶寬,分別如下面的圖7-39和7-40所示。這兩個(gè)表里面每個(gè)通道的傳輸帶寬也可以自由分配,并不局限于我們的設(shè)置那樣,今后,如果用戶需要修改這些參數(shù)可以聯(lián)系我們神電測(cè)控。


? ? ? ? 可以看出,B版本的位寬和帶寬都要比A版本的高,所以為了盡可能提升PCIe的通信帶寬,接下來我們會(huì)重點(diǎn)以B版本進(jìn)行講解,其他版本其實(shí)除了位寬,其余都是完全一樣的四線握手的FIFO。雖然端口數(shù)量比較多,但是每個(gè)端口的用法都是一樣的,對(duì)于下位機(jī)FPGA來說,用戶需要關(guān)心的就是位寬和速度。
?????? ?為了支持更高端的FPGA芯片以及后續(xù)國產(chǎn)化FPGA(深圳國微和上海復(fù)旦微),我們特地將Xilinx Kintex7家族也進(jìn)行了B版本的LabVIEW PCIe DMA CLIP封裝,如圖7-41所示。新建出來的FPGA PCIe Socket CLIP節(jié)點(diǎn)里面的端口,如圖7-42所示。


? ? ? ? 下面我們給大家逐一講解一下B版本的LabVIEW FPGA PCIe Socket CLIP里面每個(gè)信號(hào)端口的含義和注意事項(xiàng)。通過虛線將50個(gè)CLIP端口劃分成4類:分別是PCIe Socket CLIP輸出狀態(tài)端口(LED)、CLIP同步100M時(shí)鐘、上行(FPGA-->Host)通道以及下行(Host-->FPGA)通道。其中,Host可以直觀的理解成上位機(jī)PC。
?????? ?1)pcie_lv_clip_ip_to_gpio_led

---------------------------------------------------------------------------------------------------------------------
?????? ?2)Clock PCIE_LV_Clock_100M

---------------------------------------------------------------------------------------------------------------------
?????? ?3)pcie_lv_clip_fpga2host_in_64_tdata_ch0
?????? ?4)pcie_lv_clip_fpga2host_out_64_tready_ch0
?????? ?5)pcie_lv_clip_fpga2host_in_64_tvalid_ch0
?????? ?……………………
?????? ?24)pcie_lv_clip_fpga2host_in_8_tdata_ch7
?????? ?25)pcie_lv_clip_fpga2host_out_8_tready_ch7
?????? ?26)pcie_lv_clip_fpga2host_in_8_tvalid_ch7

-------------------------------------------------------------------------------------------------------------
?????? ?27)pcie_lv_clip_host2fpga_out_64_tdata_ch0
?????? ?28)pcie_lv_clip_host2fpga_in_64_tready_ch0
?????? ?29)pcie_lv_clip_host2fpga_out_64_tvalid_ch0
?????? ?……………………
?????? ?48)pcie_lv_clip_host2fpga_out_8_tdata_ch7
?????? ?49)pcie_lv_clip_host2fpga_in_8_tready_ch7
?????? ?50)pcie_lv_clip_host2fpga_out_8_tvalid_ch7

---------------------------------------------------------------------------------------------------------------------
?????? ?備注:中間的省略號(hào)指的是同類端口,只是這些端口的位寬和速度不一樣,但是用法是完全雷同的,所以我們只需要把CLIP里面其中一個(gè)端口的用法講清楚,其余的照搬照抄就可以了,而且真實(shí)應(yīng)用中,這些8上8下的端口一般不會(huì)全部使用,除非是超復(fù)雜的項(xiàng)目。下面我們給用戶詳細(xì)講解一下每個(gè)端口的含義。
?????? ?1)pcie_lv_clip_ip_to_gpio_led
?????? ?Xillybus提供的PCIe IP核里面默認(rèn)預(yù)留了4個(gè)GPIO輸出狀態(tài)口,可以用來通知用戶當(dāng)前這個(gè)IP核所處的工作狀態(tài)。我們?cè)诜庋bLabVIEW FPGA PCIe Socket CLP的時(shí)候,也一并將其封裝進(jìn)來了,關(guān)于這4個(gè)LED狀態(tài)的含義,我們?cè)赬illybus官方論壇上找到了下面一段英文回復(fù),但是Xillybus官網(wǎng)上卻沒有給出;另外,Xillybus最新推出的XillyUSB對(duì)應(yīng)的8個(gè)LED狀態(tài),官網(wǎng)上卻給出了每個(gè)LED的含義,因此,建議官方把Xillybus PCIe IP核的LED含義也放在官網(wǎng)頁面上,不然會(huì)讓用戶找的好辛苦!
?????? ?So we have some kind of progress. If your "custom board" is manufactured by some other hardware vendor, I suggest trying out their test code for PCIe.If it's your own -- please take a look on the LEDs. Their meaning is as follows:
?????? ?GPIO LED 0: Heartbeart. Just blinks.
?????? ?GPIO LED 1: Indicates transmission of data from the FPGA to the CPU
?????? ?GPIO LED 2: Indicates transmission of data from the CPU to the FPGA
?????? ?GPIO LED 3: Indicates that the FPGA is waiting for CPU-to-FPGA data to arrive (i.e. there's at least an outstanding request for reading) OR that the Xillybus logic is held reset (on some platforms).
?????? ?我們簡(jiǎn)單翻譯一下:
?????? ?GPIO LED_0:心跳指示燈,1Hz,當(dāng)PCIe IP核正常加載,且被PC識(shí)別成功,那么LED_0會(huì)按照1Hz的頻率進(jìn)行閃爍;反之,如果不閃爍,說明FPGA里面的代碼寫的有問題或者PC端的驅(qū)動(dòng)沒有正常安裝或者PCIe相關(guān)的引腳約束沒有整對(duì)。
?????? ?GPIO LED_1:顯示上行(FPGA-->PC)數(shù)據(jù)正在發(fā)送指示燈,也就是當(dāng)FPGA把數(shù)據(jù)發(fā)送給主機(jī)PC時(shí),這個(gè)指示燈會(huì)閃爍,發(fā)送頻率越高,閃爍越快;反之,如果不閃爍,要么就是FPGA不發(fā)送數(shù)據(jù),要么就是FPGA程序沒寫好。
?????? ?GPIO LED_2:顯示下行(PC-->FPGA)數(shù)據(jù)正在接收指示燈,也就是當(dāng)PC端把數(shù)據(jù)下發(fā)給FPGA時(shí),這個(gè)指示燈會(huì)閃爍,下發(fā)頻率越高,閃爍越快;反之,如果不閃爍,要么就是PC不下發(fā)數(shù)據(jù),要么就是PC端程序沒寫好。
?????? ?GPIO LED_3:指示FPGA正在等待CPU到FPGA數(shù)據(jù)到達(dá)(即至少有一個(gè)未完成的讀取請(qǐng)求)或Xillybus邏輯保持重置。
?????? ?一般情況下,在開始調(diào)試程序的時(shí)候,建議大家使用這些LED狀態(tài)輸出信號(hào),幫助我們快速定位一些常見的問題,一旦程序完善了,如果FPGA板子上的LED不夠用了,那么可以將PCIe關(guān)聯(lián)的信號(hào)拿掉。
?????? ?實(shí)戰(zhàn)中:用戶可以將FPGA終端下的PCIe CLIP里面的“pcie_lv_clip_ip_to_gpio_led”端口拖拽到FPGA VI程序框圖里面,然后把定點(diǎn)輸出FXP<+4,4>通過“數(shù)值至布爾數(shù)組”轉(zhuǎn)換函數(shù)變成一維字節(jié)數(shù)組,再連到4個(gè)LED上面,如圖7-43所示,這樣就可以在實(shí)驗(yàn)過程中很直觀的看到PCIe IP核的運(yùn)行狀態(tài)了。如果一切正常,可以看到電腦重啟之后,LED1指示燈會(huì)閃爍;發(fā)送上行數(shù)據(jù)時(shí),LED2指示燈會(huì)閃爍;接收下行數(shù)據(jù)時(shí),LED3指示燈會(huì)閃爍;FPGA重置時(shí),LED4指示燈會(huì)常量。

? ? ? ? 2)Clock PCIE_LV_Clock_100M
?????? ?FPGA PCIe IP核用戶時(shí)鐘,默認(rèn)是100MHz,這個(gè)時(shí)鐘是路由出來給用戶自己寫程序用的FIFO同步時(shí)鐘。眾所周知,Xilinx官方給的PCIe IP核配置頁面里面,時(shí)鐘一般是125MHz或者250MHz,但是Xillybus把這些內(nèi)部時(shí)鐘隔離了,預(yù)留出來一個(gè)100MHz的異步時(shí)鐘(相對(duì)于Xilinx PCIe IP核的125MHz時(shí)鐘來說,就是異步)給用戶線程使用,但是這個(gè)100MHz時(shí)鐘跟后面16個(gè)通道對(duì)應(yīng)的四線握手的FIFO是同步的,也就是說,用戶如果要把FPGA里面的數(shù)據(jù)發(fā)送給PC或者接收PC下發(fā)的數(shù)據(jù),必須要使用這個(gè)100MHz時(shí)鐘源,才能保持FIFO同步握手。為此,我們將這個(gè)100MHz時(shí)鐘直接封裝到我們的LabVIEW FPGA PCIe Socket CLIP里面來了,時(shí)鐘信號(hào)名為“Clock PCIE_LV_Clock_100M”。
?????? ?如何使用外部CLIP路由進(jìn)來的時(shí)鐘,跟前面我們封裝的千兆以太網(wǎng)、USB時(shí)鐘一樣,用戶可以直接在FPGA定時(shí)循環(huán)左邊創(chuàng)建一個(gè)時(shí)鐘源常量,然后在下拉列表里面選擇,如圖7-44所示;或者直接雙擊FPGA定時(shí)循環(huán),在彈出來的時(shí)鐘配置頁面里面選擇“PCIE Data\Clock PCIE_LV_Clock_100M”,如圖7-45所示。


? ? ? ? 3)pcie_lv_clip_fpga2host_in_64_tdata_ch0
?????? ?4)pcie_lv_clip_fpga2host_out_64_tready_ch0
?????? ?5)pcie_lv_clip_fpga2host_in_64_tvalid_ch0
?????? ?……………………
?????? ?24)pcie_lv_clip_fpga2host_in_8_tdata_ch7
?????? ?25)pcie_lv_clip_fpga2host_out_8_tready_ch7
?????? ?26)pcie_lv_clip_fpga2host_in_8_tvalid_ch7
?????? ?上面這8個(gè)PCIe發(fā)送通道(3~26)的四線握手信號(hào),其實(shí)就是上行數(shù)據(jù)發(fā)送端口,為了方便不同用戶的項(xiàng)目需求,我們封裝了8個(gè)不同位寬和速度的Pipe管道(或者叫Channel通道),如果是高速的數(shù)據(jù)采集上傳,可以選擇64位或者32位的Channel0或者Channel1,如果是低速的數(shù)據(jù)傳輸可以選擇8位的Channel4~Channel7.
?????? ?每個(gè)上行通道都有3個(gè)握手端口組成,比如,拿64位上行數(shù)據(jù)端口來說:pcie_lv_clip_fpga2host_out_64_tready_ch0、pcie_lv_clip_fpga2host_in_64_tdata_ch0和pcie_lv_clip_fpga2host_in_64_tvalid_ch0。為了讓用戶更加形象的理解和掌握這些握手信號(hào)的用法,我們先給出一個(gè)FPGA PCIe數(shù)據(jù)發(fā)送程序框圖,如圖7-46所示。畢竟LabVIEW框圖看起來顯而易見,一圖勝千言!

? ? ? ? 其中,“fpga2host_out_tready”信號(hào)就是PCIe Socket IP核里面的接收FIFO準(zhǔn)備就緒信號(hào),如果這個(gè)“fpga2host_out_tready”拉高,說明PCIe IP核可以接收FPGA給過來的數(shù)據(jù),然后將其發(fā)送到PC端,因此,我們可以將這個(gè)tready接到FPGA里面的數(shù)據(jù)源FIFO的“輸出就緒”端口上面;再把FPGA里面用戶創(chuàng)建的FIFO輸出的數(shù)據(jù)和有效信號(hào)分別接到PCIe Socket CLIP的“fpga2host_in_tdata”和“fpga2host_in_tvalid”端口上面。
?
?????? ?27)pcie_lv_clip_host2fpga_out_64_tdata_ch0
?????? ?28)pcie_lv_clip_host2fpga_in_64_tready_ch0
?????? ?29)pcie_lv_clip_host2fpga_out_64_tvalid_ch0
?????? ?……………………
?????? ?48)pcie_lv_clip_host2fpga_out_8_tdata_ch7
?????? ?49)pcie_lv_clip_host2fpga_in_8_tready_ch7
?????? ?50)pcie_lv_clip_host2fpga_out_8_tvalid_ch7
?????? ?接下來,剩下的這8個(gè)PCIe接收數(shù)據(jù)通道(27~50)的握手信號(hào),其實(shí)就是下行數(shù)據(jù)接收端口,為了方便不同用戶的項(xiàng)目需求,我們封裝了8個(gè)不同位寬和速度的Pipe管道(或者叫Channel通道),如果需要快速下發(fā)數(shù)據(jù)給FPGA,可以選擇64位或者32位的Channel0或者Channel1,如果是低速的數(shù)據(jù)傳輸可以選擇8位的Channel4~Channel7.
?????? ?每個(gè)下行通道同樣是3個(gè)握手端口組成,比如,拿64位下行數(shù)據(jù)端口來說:pcie_lv_clip_host2fpga_in_64_tready_ch0、pcie_lv_clip_host2fpga_out_64_tdata_ch0和pcie_lv_clip_host2fpga_out_64_tvalid_ch0。為了讓用戶更加形象的理解和掌握這些握手信號(hào)的用法,我們先給出一個(gè)FPGA PCIe數(shù)據(jù)接收程序框圖,如圖7-47所示。畢竟LabVIEW框圖看起來更直觀易懂!

? ? ? ? 其中,“host2fpga_in_tready”信號(hào)就是PCIe Socket IP核內(nèi)部的FIFO數(shù)據(jù)輸出使能信號(hào),相對(duì)于FPGA來說,就是輸入信號(hào),如果給這個(gè)“host2fpga_in_tready”賦高,那么一旦PCIe總線接收到上位機(jī)PC下發(fā)的數(shù)據(jù)后,那么對(duì)應(yīng)的“host2fpga_out_tdata”和“host2fpga_out_tvalid”就會(huì)有效;因此,我們可以將FPGA里面用戶創(chuàng)建的接收FIFO的“輸入就緒”端口接到Socket CLIP的“host2fpga_in_tready”上面;再把“host2fpga_out_tdata”和“host2fpga_out_tvalid”分別接到FPGA里面用戶創(chuàng)建的FIFO數(shù)據(jù)輸入和輸入有效信號(hào)端口上。
?????? ?注意1:其他位寬的PCIe通道也是如此,用戶只需要更改一下FIFO的數(shù)據(jù)類型,使其數(shù)據(jù)寬度跟PCIe Socket CLIP通道位寬一致就可以了。
?????? ?注意2:我們封裝的PCIe上行和下行tdata都是FXP定點(diǎn)數(shù),可以直接接收有符號(hào)或者無符號(hào)整形數(shù)據(jù),而需要提前進(jìn)行轉(zhuǎn)換,當(dāng)然,如果用戶不放心的話,也可以將整形通過“數(shù)值至布爾數(shù)組”將符號(hào)特性去掉,然后再利用“布爾數(shù)組至數(shù)值”轉(zhuǎn)換成FXP定點(diǎn)數(shù)給到PCIe Socket CLIP的tdata端口上面。
?????? ?注意3:Xillybus提供的PCIe IP核內(nèi)部是小端格式,也就是說,低字節(jié)在前,高字節(jié)在后,所以,要么在下位機(jī)FPGA里面提前做翻轉(zhuǎn),要么在上位機(jī)做大小端變換!比如,如果用戶在FPGA里面發(fā)送一個(gè)32位位寬的數(shù)據(jù),那么可以借助“拆分?jǐn)?shù)字”和“交換字節(jié)”兩個(gè)函數(shù)來完成大小端格式的轉(zhuǎn)換,如圖7-48所示。這里,我們給出了3種不同數(shù)據(jù)類型的大小端格式轉(zhuǎn)換,這個(gè)功能將在后續(xù)的實(shí)驗(yàn)部分會(huì)用到,大家可以留心一下。

? ? ? ?可以看出,雖然PCIe協(xié)議本身很復(fù)雜,但是對(duì)于用戶來說,只要理解了FIFO的四線握手編程,就可以搞定所有線程之間的數(shù)據(jù)傳輸問題了,這也就是為什么我們?cè)跁忻總€(gè)實(shí)驗(yàn)里面都反復(fù)強(qiáng)調(diào)四線握手和并轉(zhuǎn)串以及串轉(zhuǎn)并的重要性。