《LabVIEW FPGA開發(fā)寶典:TCP網(wǎng)絡(luò)通信》(入門-->精通-->實(shí)戰(zhàn)-->應(yīng)用)

《LabVIEW FPGA開發(fā)寶典:TCP網(wǎng)絡(luò)通信》
第10章:LabVIEW FPGA TCP網(wǎng)絡(luò)通信開發(fā)
(入門-->精通-->實(shí)戰(zhàn)-->應(yīng)用)
????? ?10.1、FPGA TCP基礎(chǔ)知識和通信概述
????????提到TCP總線通信,其實(shí)大家都不陌生,關(guān)于TCP協(xié)議棧的基本知識和概念,用戶可以自行百度一下,這里我們就不贅述了。圖10-1顯示的是常見的TCP局域網(wǎng)星形拓?fù)浣Y(jié)構(gòu),而本書前面第6章提到的UDP通信一般實(shí)現(xiàn)的都是點(diǎn)對點(diǎn)通信,比如,F(xiàn)PGA直接跟主機(jī)端通過一根網(wǎng)線直連,而TCP則可以很容易實(shí)現(xiàn)主機(jī)同時對多點(diǎn)進(jìn)行互聯(lián)通信。? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? ? ? ? ? ? ??


? ? ? ? 下面我們重點(diǎn)講一些平時積累的通信協(xié)議應(yīng)用技巧和經(jīng)驗(yàn)。
????????在網(wǎng)絡(luò)通信領(lǐng)域,TCP/IP可以說是一個非常基礎(chǔ)又非常重要的通信協(xié)議之一,相比于UDP協(xié)議,TCP屬于長鏈接協(xié)議,只有服務(wù)器與客戶端建立起連接之后二者才能進(jìn)行通信;如果通信過程中發(fā)生數(shù)據(jù)包丟失,TCP協(xié)議棧會自動重發(fā),并且另一端收到之后協(xié)議內(nèi)部會自動發(fā)送Ack響應(yīng),這樣的通信方式非常可靠。
????????因此,只要TCP連接存在,讀取端速度足夠快,理論上TCP通信就不會丟包,這是因?yàn)門CP跟PCIe協(xié)議類似,都是握手類協(xié)議;如果因?yàn)橹鳈C(jī)端系統(tǒng)抖動(比如,Windows或者Linux),造成讀取速度瞬間變慢而丟包,我們可以在中間層加大TCP緩沖區(qū)長度,比如,在FPGA芯片里面開辟較大的上行FIFO緩沖區(qū),或者直接使用FPGA旁邊的DDR3或者DDR4芯片來緩沖大容量數(shù)據(jù);因?yàn)樯衔粰C(jī)所能開辟的TCP緩沖區(qū)是有限制的,這個方法也是解決所有握手類協(xié)議的終極絕招,特別是高速通信協(xié)議,比如TCP和PCIe;系統(tǒng)稍微卡頓一下,即使是ms量級的抖動,也會造成幾K甚至幾十K的數(shù)據(jù)溢出,因此,F(xiàn)PGA中間層的TCP/PCIe上行數(shù)據(jù)FIFO深度,在FPGA資源足夠的情況下,設(shè)置的越大越好,而下行TCP數(shù)據(jù)FIFO不需要設(shè)置很大,這是因?yàn)镕PGA芯片里面的程序?qū)嶋H映射的是硬件電路,永遠(yuǎn)不存在抖動,F(xiàn)PGA的優(yōu)勢就是處理速度快。
????????而UDP協(xié)議最大的問題就在于它不是握手類協(xié)議,一端可以無條件發(fā)送UDP數(shù)據(jù)包,不管對方回不回應(yīng),優(yōu)勢在于UDP吞吐率要比TCP快一些,缺點(diǎn)在于如果網(wǎng)絡(luò)條件不好,或者讀取端讀取速度跟不上的話,容易造成UDP丟包,并且發(fā)送端和接收端無法判斷是否丟包了,除非是人為添加UDP包頭index索引,否則無法判斷何時丟包,以及丟了哪些包。對于不需要長連接和不需要分布式并且是固定數(shù)據(jù)包長度的應(yīng)用來說,UDP相對于TCP協(xié)議棧開銷相對小一些。
????????其實(shí),關(guān)于UDP通信的開發(fā)和應(yīng)用,在寶典第6章里面的第9個實(shí)驗(yàn)有很詳細(xì)的講解,這里不再贅述,本章著重講解基于純FPGA實(shí)現(xiàn)的TCP協(xié)議。
????????這里提到的純FPGA實(shí)現(xiàn)的TCP協(xié)議棧,跟以往大家使用ZYNQ芯片不一樣,ZYNQ里面的PS端也就是ARM端可以跑Linux系統(tǒng),用戶可以在系統(tǒng)層面實(shí)現(xiàn)TCP協(xié)議棧,我們這里要跟大家傳遞的是利用純FPGA可編程邏輯資源實(shí)現(xiàn)的TCP協(xié)議棧,這樣只要是FPGA芯片,無論帶不帶ARM都能實(shí)現(xiàn)TCP協(xié)議棧了,當(dāng)然ZYNQ里面的PL部分也可以運(yùn)行我們這個TCP協(xié)議棧。
????????這里介紹的基于FPGA純邏輯資源實(shí)現(xiàn)的TCP協(xié)議棧與傳統(tǒng)的ZYNQ里面PS端(ARM)實(shí)現(xiàn)的TCP有啥區(qū)別呢?我認(rèn)為有以下幾點(diǎn)優(yōu)勢:
????????1)純FPGA實(shí)現(xiàn)的TCP協(xié)議棧,擺脫了FPGA的局限性,只要是FPGA芯片,無論是哪個廠家的,都能加載這個TCP網(wǎng)表文件進(jìn)行編譯,可以選擇的FPGA種類更加靈活,硬件成本也更容易控制(比如,Spartan6、Artix7、Kintex7、Virtex7)。
????????2)純FPGA芯片內(nèi)部運(yùn)行的TCP協(xié)議棧,本質(zhì)上映射的是FPGA芯片內(nèi)部的硬件電路,因此,不存在芯片死機(jī)、卡頓、數(shù)據(jù)丟包等問題,穩(wěn)定性和可靠性要比ZYNQ里面的ARM高很多,值得一提的是,很多BP大物理裝置里面的核心設(shè)備,需要長時間高可靠性運(yùn)行的設(shè)備,往往都是采用純FPGA實(shí)現(xiàn)的TCP協(xié)議棧(比如日本的SiTCP),而非ZYNQ和ARM芯片。
????????3)?純FPGA實(shí)現(xiàn)的TCP協(xié)議棧很容易實(shí)現(xiàn)百兆、千兆和萬兆帶寬,這一點(diǎn)ARM芯片和ZYNQ的PS端是無法企及的,特別是萬兆協(xié)議,除非用ZYNQ里面的PL來實(shí)現(xiàn),本質(zhì)上也就類似我們的純FPGA邏輯資源跑TCP協(xié)議棧了。
????????4)相較于UDP通信,TCP網(wǎng)絡(luò)一般不丟包,更容易實(shí)現(xiàn)物聯(lián)網(wǎng)多節(jié)點(diǎn)互傳等分布式應(yīng)用。
????????5)純FPGA實(shí)現(xiàn)的TCP協(xié)議棧更穩(wěn)定,速度更快,帶寬更高,只要對等端讀取速度跟的上,F(xiàn)PGA端的TCP速度性能就能發(fā)揮到最大,遠(yuǎn)遠(yuǎn)超過ARM、ZYNQ以及運(yùn)行在系統(tǒng)(Windows、Linux)里面的TCP傳輸速度。
????????由于UDP協(xié)議棧自身的缺陷,現(xiàn)在越來越多的客戶希望能在FPGA芯片內(nèi)部實(shí)現(xiàn)TCP協(xié)議通信,這也是正是我們決定將TCP協(xié)議棧移植到純FPGA芯片中的原因之一,就像PCIe協(xié)議一樣好用,至此,我們的LabVIEW FPGA又多了一種可靠的對外交互通信方式。
????????相對于傳統(tǒng)的串口和USB通信,基于FPGA實(shí)現(xiàn)的TCP千兆和萬兆以太網(wǎng)通信協(xié)議支持熱插拔和斷點(diǎn)續(xù)傳,接線和拓?fù)浣Y(jié)構(gòu)更加靈活方便。
????????如果用戶希望自己的FPGA硬件也具備TCP通信能力,一般有兩種實(shí)現(xiàn)方法:
????????一是采用專用的TCP協(xié)議棧芯片,比如采用外置專用芯片(W5500、W5300)那樣,這樣處理器的選擇余地就很大了,比如ARM、DSP、FPGA都可以,因?yàn)門CP通信協(xié)議這塊交給了專用ASIC芯片來完成了,簡化了MCU端的編程復(fù)雜度;
????????另外一種,就是直接采用我們神電測控開發(fā)移植的純FPGA實(shí)現(xiàn)的TCP軟件IP核(My FPGA TCP Socket CLIP),直接在FPGA芯片內(nèi)部搞定TCP協(xié)議棧所有的通信過程,關(guān)于這個FPGA TCP協(xié)議棧的具體介紹和應(yīng)用我們會在后續(xù)章節(jié)詳細(xì)展開。
????????那么具備TCP通信能力的FPGA硬件板卡或者開發(fā)板通常長什么樣子呢?這里用戶可以看一下圖10-2展示的實(shí)物圖,這款黑金ARTIX7 FPGA開發(fā)板(AX7103)開發(fā)板上面集成了兩路千兆PHY芯片(KSZ9031),也就是本書(LabVIEW My FPGA Pro5)配套的實(shí)驗(yàn)平臺;當(dāng)然了,如果用戶覺得黑金的FPGA開發(fā)板價格貴了,也可以選擇正點(diǎn)原子的、米聯(lián)客或者璞致的FPGA開發(fā)板或者核心板;圖10-3顯示的是正點(diǎn)原子的達(dá)芬奇Pro開發(fā)板(Artix7),上面集成的PHY芯片由原先臺灣瑞昱的RTL8211FD換成了國產(chǎn)的YT8511C,進(jìn)一步降低了硬件成本;圖10-4顯示的是Kintex7-325T FPGA核心板,上面集成了一顆RTL8211FD芯片。



? ? ? ? 因此,可以看出,F(xiàn)PGA外圍只需要一顆價格很便宜的PHY芯片即可實(shí)現(xiàn)TCP通信。特別是對于后期需要自己設(shè)計(jì)做板子的用戶來說,常用的PHY芯片可以選擇KSZ9031、RTL8211、YT8511,當(dāng)然還有博通的B50610系列;現(xiàn)在的PHY芯片基本上都是RGMII接口的,占用引腳少,只需要4bit;當(dāng)然,對于像RTL8211EG這樣的GMII芯片,我們的TCP IP協(xié)議棧也是支持的。
????????本書針對上面提到的這些FPGA硬件提供了配套的資料和例程,其他廠家的FPGA板子,我們的LabVIEW My FPGA也能完美適配,因?yàn)槲覀冏龅木褪情_源的RIO解決方案。
?
????????本書重點(diǎn)是教會用戶使用LabVIEW來開發(fā)FPGA芯片里面的TCP通信程序,然后自己根據(jù)實(shí)際項(xiàng)目和產(chǎn)品功能需求,購買通用的FPGA板子或者使用FPGA核心板+底板的方式,來擺脫NI、簡儀、凌華等這些廠商的硬件控制,真正做到硬件自由化,軟件開發(fā)圖形化,移植成本代價最小化,綜合效益最大化;同時也是為了下一步純國產(chǎn)化FPGA方案提供了切實(shí)可行的方案,比如用戶可以選擇深圳國微或者上海復(fù)旦微電子的K7、V7芯片來代替Xilinx的FPGA芯片,然后做出百分百國產(chǎn)化帶TCP高速接口的自定義LabVIEW FPGA板卡出來,真正為軍工企業(yè)或者有可能被卡脖子的行業(yè)做出一份貢獻(xiàn)?。?!
? ? ???10.2、目前主流的3大FPGA TCP網(wǎng)絡(luò)通信IP核講解(日本SiTCP IP、GitHub部分開源TCP IP、美國ComBlock公司的TCP IP):結(jié)論是美國ComBlock IP簡單易用更方便!
????????要開發(fā)一個帶TCP網(wǎng)絡(luò)通信接口的FPGA板卡出來,除了硬件本身外,比如PHY芯片,最重要的就是FPGA芯片里面的TCP通信代碼編寫,俗稱下位機(jī)FPGA編程以及上位機(jī)PC端的應(yīng)用程序開發(fā)。
????????其中,主機(jī)端(比如上位機(jī)PC)一般都可以使用C語言或者LabVIEW或者Python進(jìn)行開發(fā),但是下位機(jī)FPGA里面的TCP通信代碼一般會采用VHDL或者Verilog進(jìn)行編寫,難度比較大,尤其是TCP協(xié)議棧本身還區(qū)分客戶端和服務(wù)器端兩類復(fù)雜的通信協(xié)議,開發(fā)難度和工作量會非常大,這就導(dǎo)致很多應(yīng)用工程師在做TCP相關(guān)的FPGA嵌入式開發(fā)時,碰到了不少坑,投入了很多精力和時間也沒有把FPGA TCP做穩(wěn)定。
????????本章重點(diǎn)就是告訴用戶如何使用LabVIEW在FPGA芯片里面編寫TCP通信程序,徹底解決下位機(jī)FPGA代碼編寫的痛點(diǎn),讓LabVIEW圖形化編程語言深入到FPGA骨髓里面去,降低FPGA TCP嵌入式開發(fā)門檻,真正發(fā)揮出TCP協(xié)議穩(wěn)定可靠的通信能力。
?
????????上面雖然介紹了基于純FPGA實(shí)現(xiàn)的TCP協(xié)議棧的諸多優(yōu)點(diǎn),唯一的缺點(diǎn)就是純FPGA TCP協(xié)議棧,目前沒有看到即好用又免費(fèi)的,為此,我們調(diào)研分析了一下整個FPGA IP核市場,發(fā)現(xiàn)了比較有價值的3類TCP協(xié)議棧供大家參考。
1)?日本SiTCP IP核
2) GitHub上的開源TCP IP 核
3)?美國ComBlock TCP IP核
????????下面我們簡單介紹一下這3種方案。
????????1)?說到日本的SiTCP協(xié)議棧,估計(jì)很多做BP大物理裝置設(shè)備的用戶并不陌生,因?yàn)樵诩僃PGA芯片內(nèi)部開發(fā)這個SiTCP協(xié)議棧的作者本身就是從事BP領(lǐng)域的科研人員。隨著SiTCP的應(yīng)用越來越廣泛,并且在全球諸多BP領(lǐng)域的大裝置里面長年累月不停機(jī)的運(yùn)行測試,使其聲名大噪,后來逐步商業(yè)化擁抱更為寬闊的自動化和通信領(lǐng)域。缺點(diǎn)就是SiTCP協(xié)議棧IP核以網(wǎng)表形式出售,綁定MAC地址,價格非常貴,一般的個體戶和小企業(yè)不一定能買的起,更不適合廣大開源愛好者。
????????2)說到開源免費(fèi),大家首先想到的估計(jì)就是GitHub,確實(shí)里面有一些基于純FPGA實(shí)現(xiàn)的TCP Demo,但是缺乏維護(hù),而且底層代碼似乎也存在不少Bug,例程比較老舊,如果想把GitHub上的TCP協(xié)議棧吃透的話,需要大家對精通傳統(tǒng)的FPGA開發(fā)才行,同時還要花費(fèi)大量的測試時間以及準(zhǔn)備好打補(bǔ)丁工作,為此,我們放棄了GitHub這類沒有工程師實(shí)時維護(hù)的代碼。
????????3)最后,我們發(fā)現(xiàn)美國有一個ComBlock軟件公司,專門基于純FPGA開發(fā)了各種各樣的通信協(xié)議棧IP核,源碼采用VHDL編寫,消耗資源少,執(zhí)行效率高,關(guān)鍵是授權(quán)費(fèi)用低,并且提供全部源碼而非網(wǎng)表,這使得用戶可以直接看到底層協(xié)議棧編寫邏輯,一定程度上可以借鑒和學(xué)習(xí)。感興趣的用戶登錄ComBlock公司網(wǎng)站查看https://www.comblock.com/product_list_IP.html
?
????????難能可貴的是,ComBlock這家公司有點(diǎn)像我們之前說過的以色列Xillybus那樣,專門在FPGA軟件IP核上下功夫,國內(nèi)目前還缺乏這樣專注于FPGA算法和協(xié)議棧的純軟件公司,希望國內(nèi)以后有越來越多的FPGA軟件IP協(xié)議和算法出現(xiàn)。這樣我們就能移植封裝到LabVIEW My FPGA軟件工具包來了。
????????為此,我們專門花錢買了ComBlock公司的TCP客戶端和服務(wù)器端兩個版本的源代碼授權(quán)。然后將其進(jìn)行模塊化封裝、移植到我們的LabVIEW My FPGA軟件工具包,并且編寫了大量基于該TCP客戶端和服務(wù)器端兩個版本的FPGA VI和例程(分為下位機(jī)FPGA和上位機(jī)PC),大家只要懂一點(diǎn)LabVIEW,就可以直接在FPGA里面調(diào)用我們封裝好的TCP Socket CLIP VI了,然后自動編譯成bit文件、下載到FPGA芯片里面運(yùn)行,真正做到學(xué)以致用。之所以將寶典和例程寫的詳細(xì)并且提供實(shí)戰(zhàn)應(yīng)用案例,就是為了照顧一些初學(xué)者,讓他們也能在短時間內(nèi)成為FPGA高手。
PS:如果哪位大神有更好的純FPGA實(shí)現(xiàn)的TCP協(xié)議棧IP的話,歡迎與我們神電測控聯(lián)系。
郵箱:DLW30@126.com
微信:myview30
?????? 其中,ComBlock開發(fā)的TCP Server IP核系統(tǒng)工作框圖,如圖10-5所示;該TCP Server IP核在Spartan6這樣的很low的FPGA芯片里面消耗的資源也是極少的,如圖10-6所示。至于TCP Client IP核這里就不展示了,后面我們會講解在LabVIEW FPGA下面如何調(diào)用純FPGA實(shí)現(xiàn)的TCP Client和Server兩個版本的IP核。
? ? ? ? ? ? ? ? ? ? ?

? ? ? ?

? ? ? ? ? ??總結(jié):對于我們傳統(tǒng)的嵌入式工程師來說,選擇一個合適的FPGA TCP驅(qū)動IP非常重要,不僅可以節(jié)約大量開發(fā)時間,關(guān)鍵是穩(wěn)定性要比我們自己寫的更好,畢竟很多商業(yè)FPGA驅(qū)動IP核和驅(qū)動inf文件都是經(jīng)過了大量企業(yè)實(shí)踐檢驗(yàn)過的,而很多所謂的開源代碼,實(shí)際上用起來總是有這樣或者那樣的bug和坑,需要用戶自己花費(fèi)大量的時間去調(diào)試、修改和維護(hù),有時候得不償失。如果是做產(chǎn)品的話,個人愚見,還是用成熟的企業(yè)版軟件工具包和FPGA驅(qū)動IP核,畢竟穩(wěn)定勝于一切,社會分工不一樣。
?????? ?經(jīng)過上面的講解和分析,最終我們選擇了美國ComBlock作為我們LabVIEW FPGA底層TCP驅(qū)動IP核的候選,我們將整個TCP客戶端和服務(wù)器端兩個版本的FPGA TCP IP核以CLIP的方式重新封裝到LabVIEW My FPGA工具包下面,這樣用戶就能通過LabVIEW圖形化的方式直接調(diào)用這個IP核了(關(guān)于這個FPGA TCP CLIP的詳細(xì)介紹,后面專門會有一節(jié)進(jìn)行講解),用戶只需要會一點(diǎn)點(diǎn)LabVIEW就可以將最為復(fù)雜的FPGA TCP通信輕松拿下。
?????? ?旁白:我們也衷心地希望國內(nèi)有更多的牛人、高手或者企業(yè)能夠像以色列Xillybus和美國ComBlock公司那樣專注于做一件事情,然后把這件事做到極致,做出屬于我們中國人自己的底層FPGA TCP IP核。我相信這一天早晚會到來!
? ? ???10.3、FPGA TCP網(wǎng)絡(luò)通信開發(fā)過程(2個步驟)
?????? ?要想開發(fā)出一個完整的基于TCP網(wǎng)絡(luò)通信的FPGA板卡,需要經(jīng)歷以下2個步驟才能算是完成。
?????? ?首先,用戶需要根據(jù)實(shí)際情況,編寫FPGA芯片里面的邏輯代碼,比如做一個基于TCP網(wǎng)絡(luò)傳輸?shù)腄AQ采集卡,那么用戶需要在FPGA里面利用LabVIEW編寫一個ADC采集程序,然后將采集到的數(shù)據(jù)通過FIFO轉(zhuǎn)移到我們封裝出來的TCP CLIP對應(yīng)的上行通道里面,或者將上位機(jī)下發(fā)的數(shù)據(jù)從FPGA FIFO里面讀取出來。這部分代碼開發(fā),我們稱之為下位機(jī)FPGA程序編寫,采用LabVIEW進(jìn)行開發(fā)。關(guān)于下位機(jī)LabVIEW FPGA程序開發(fā),也是貫徹本書的重點(diǎn),前面每個實(shí)驗(yàn)基本上都著重講解了LabVIEW開發(fā)FPGA下位機(jī)程序這部分。
?????? ?接下來,當(dāng)我們利用LabVIEW編寫好FPGA程序(里面包含TCP CLIP),編譯成bit文件,下載到FPGA芯片里面運(yùn)行后,然后,我們還需要編寫一個上位機(jī)應(yīng)用程序來跟下位機(jī)FPGA進(jìn)行通信,如果上位機(jī)大家也準(zhǔn)備用LabVIEW開發(fā)的話,可以直接參考LabVIEW自帶的原始以太網(wǎng)TCP通信例程,當(dāng)然,推薦大家參考我們重寫的上位機(jī)LabVIEW網(wǎng)絡(luò)通信例程,有能力的用戶也可以直接調(diào)用LabVIEW TCP函數(shù)選板里面的VI自己實(shí)現(xiàn);對于那些不會LabVIEW的用戶也可以使用C\C++\C#\Python等文本語言實(shí)現(xiàn)TCP網(wǎng)絡(luò)通信,關(guān)于這方面的資料和例程,網(wǎng)上有很多,上位機(jī)TCP通信本身不復(fù)雜, 基本都是現(xiàn)成的。
?????? ?至此,我們就把一個基于TCP的FPGA項(xiàng)目或者產(chǎn)品做完了,然后就可以將FPGA板卡、FPGA程序框圖和上位機(jī)應(yīng)用程序交付給最終用戶。用戶只需要會LabVIEW開發(fā)FPGA芯片里面的代碼以及上位機(jī)PC端的程序就可以了,非常簡單省事。
?????? ?特別需要注意的是:部分用戶在做后續(xù)FPGA跟上位機(jī)之間的TCP通信實(shí)驗(yàn)時,發(fā)現(xiàn)下位機(jī)FPGA TCP帶寬超過20MB/s就會產(chǎn)生FIFO溢出,數(shù)據(jù)丟包,無法達(dá)到我們寶典里面測試的75MB/s~95MB/s(如圖10-7和10-8所示),這是因?yàn)檫@類用戶測試的上位機(jī)電腦中,安裝了消耗CPU和網(wǎng)絡(luò)資源的軟件,特別是像todesk、anydesk、teamview、向日葵這類遠(yuǎn)程軟件;雖然這些軟件不占用直連的網(wǎng)卡資源,但是這類軟件會造成CPU卡頓和侵占部分網(wǎng)絡(luò)資源。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

?

? ? ? ??因此,建議大家:在測試我們封裝的FPGA TCP極限傳輸帶寬(吞吐率),最好把上位機(jī)所有影響CPU和網(wǎng)絡(luò)的軟件統(tǒng)統(tǒng)關(guān)閉,并且關(guān)閉上位機(jī)應(yīng)用程序里面的波形圖顯示也會進(jìn)一步提高下位機(jī)FPGA的TCP傳輸帶寬。
?????? ?提醒:最好把上位機(jī)網(wǎng)卡屬性里面的接收緩沖區(qū)和傳輸緩沖區(qū)改到最大值,也就是2048,如圖10-9所示,這樣可以一定程度上提高TCP的傳輸帶寬,更重要的是前面我們提到的,要在FPGA下位機(jī)里面增加TCP上行FIFO深度,因?yàn)樯衔粰C(jī)能改的Buffer深度太小了,只有2048,下位機(jī)FPGA可以申請的FIFO深度可以到幾十KB都行,必要的時候還可以動用DDR3或者DDR4來做更大的數(shù)據(jù)緩沖。

?
?????? ?下面,我們分別對這2個步驟進(jìn)行詳細(xì)的講解。
?? ?10.3.1、下位機(jī)FPGA TCP通信程序開發(fā)(bit文件,用LabVIEW FPGA進(jìn)行開發(fā))
?????? ?當(dāng)我們做一個FPGA TCP硬件時,首先需要準(zhǔn)備好一個支持TCP通信的FPGA板子,比如黑金的AX7103開發(fā)板,上面的ARTIX7 FPGA芯片外加1個PHY芯片(比如KSZ9031、RTL8211FD、YT8511C)即可實(shí)現(xiàn)TCP或者UDP通信。這塊FPGA開發(fā)板也是本書配套的實(shí)驗(yàn)平臺,關(guān)于這個板子各個功能模塊的講解,前面第6、7、8章每個實(shí)驗(yàn)都詳細(xì)驗(yàn)證過了。
?????? ?當(dāng)FPGA硬件準(zhǔn)備好之后,接下來,我們就可以大刀闊斧的按照我們實(shí)際的項(xiàng)目或者產(chǎn)品需求,在FPGA芯片里面利用LabVIEW進(jìn)行編程了。這里用LabVIEW編寫的FPGA代碼,我們稱之為下位機(jī)FPGA程序開發(fā)。
?????? ?比如,我們要在FPGA里面開發(fā)一個DAQ采集程序,我們可以直接將前面第6章里面的各種ADC采集線程拷貝到本節(jié)實(shí)驗(yàn)里面來,然后再配上我們封裝的FPGA TCP IP節(jié)點(diǎn),就變成了一個帶TCP傳輸接口的DAQ設(shè)備了;如果將前面的DAC信號輸出線程拷貝到本節(jié)實(shí)驗(yàn)里面來,配上FPGA TCP IP核,就變成了一個任意信號信號發(fā)生器板卡了;如果把前面的雙目攝像頭圖像采集框圖拷貝到本節(jié)實(shí)驗(yàn)里面來,配上FPGA TCP IP核,就變成了一個支持TCP網(wǎng)絡(luò)通信的圖像采集卡了。
?????? ?關(guān)于這個下位機(jī)FPGA里面的代碼編寫,相信用戶在學(xué)習(xí)了本書的第5章和第6章之后,就不會陌生了,而且很多下位機(jī)FPGA端的代碼都可以直接從前面第6章對應(yīng)的實(shí)驗(yàn)程序里面進(jìn)行拷貝,無需重頭編寫。
?????? ?當(dāng)下位機(jī)FPGA端的LabVIEW程序框圖編寫完成之后,點(diǎn)擊運(yùn)行可以自動編譯生成對應(yīng)的FPGA bit文件和bin/mcs文件,我們把這個文件稱之為下位機(jī)可執(zhí)行文件或者固件程序。當(dāng)然,如果用戶對VHDL或者Verilog十分精通的話,也可以用文本語言編程,但是我們推薦大家使用LabVIEW開發(fā),效率更高。
?????? ?下面我們直接通過一個示意圖來表達(dá)一下下位機(jī)FPGA里面的代碼編寫過程,如圖10-10所示。其中,生成中間VHDL代碼和編譯成bit文件都是在后臺自動完成的,即使用戶完全不懂FPGA也沒有用過Xilinx任何IDE軟件,只要會LabVIEW就可以搞定一切!

? ? ? ??備注:詳細(xì)的LabVIEW FPGA TCP CLIP代碼講解,可以參考后面10.4節(jié)的相關(guān)內(nèi)容。
?? ?10.3.2、上位機(jī)PC端TCP通信應(yīng)用程序開發(fā)(LabVIEW/C/Python都有完善的例程)
?????? ?當(dāng)下位機(jī)FPGA TCP網(wǎng)絡(luò)通信程序編譯下載運(yùn)行后,我們就可以編寫一個上位機(jī)PC端的應(yīng)用程序來與之通信,進(jìn)行數(shù)據(jù)交互了。如果下位機(jī)FPGA跑的是TCP Client客戶端協(xié)議棧的話,那么上位機(jī)PC就要跑TCP Sever服務(wù)器程序,反之亦然。
?????? ?本身上位機(jī)程序我們以LabVIEW為例進(jìn)行講解,因?yàn)長abVIEW是圖形化編程語言,相比于傳統(tǒng)的C和Python等文本編程語言,更加簡單易懂,并且LabVIEW軟件自身就有大量的網(wǎng)絡(luò)通信函數(shù)VI和豐富的例程;圖10-11顯示的LabVIEW軟件里面自帶的TCP函數(shù)選板;圖10-12顯示的是LabVIEW范例查找器里面自帶的TCP通信Demo例程,雙擊其中Simple TCP例程,可以看到該項(xiàng)目瀏覽器同時具備Server和Client兩個Demo程序,如圖10-13所示。



? ? ? ? PS:關(guān)于上位機(jī)采用LabVIEW編寫的TCP客戶端和服務(wù)器端Demo例程,我們會在后續(xù)實(shí)驗(yàn)環(huán)節(jié)里面給大家做詳細(xì)的講解;如果大家擅長C或者Python這樣的編程語言,上位機(jī)網(wǎng)絡(luò)通信程序自行腦補(bǔ)(也可以問問ChatGPT)。
? ? ???10.4、LabVIEW FPGA TCP Socket CLIP 講解(神電測控獨(dú)家提供TCP客戶端和服務(wù)器兩個版本)
?????? ?本節(jié)我們重點(diǎn)給用戶講解一下我們封裝好的LabVIEW FPGA下的TCP CLIP組件功能和用法。這個TCP CLIP也是我們My FPGA軟件工具包的核心組件之一,我們花費(fèi)了近3個月的時間,將美國COmBlock公司提供的TCP VHDL協(xié)議棧代碼進(jìn)行移植、修改和適配,并進(jìn)行了大量的測試驗(yàn)證,最終才把底層客戶端和服務(wù)器兩個版本的TCP IP核封裝到LabVIEW FPGA CLIP里面來,并且給用戶提供了極其簡單的四線握手FIFO接口,所有關(guān)于TCP網(wǎng)絡(luò)協(xié)議自帶的通信功能都封裝到底層去了,用戶不需要深入了解底層FPGA TCP代碼,一樣可以使用LabVIEW FPGA來調(diào)用這個TCP Socket CLIP進(jìn)而快速開發(fā)出一個屬于自己的TCP FPGA設(shè)備來。
?????? ?ComBlock官方提供了2個版本的TCP通信IP核,分別是Client客戶端版本和Server服務(wù)器版本。其中,TCP Client協(xié)議棧版本在FPGA里面運(yùn)行之后,可以將FPGA變成TCP客戶端角色,最大極限吞吐率是95MB/s;TCP Server協(xié)議棧版本在FPGA里面運(yùn)行之后,可以將FPGA變成TCP服務(wù)器角色,最大極限吞吐率也是95MB/s。
?????? ?目前我們將下位機(jī)FPGA TCP客戶端和服務(wù)器兩個版本的協(xié)議棧都封裝成了LabVIEW FPGA Socket CLIP組件供大家使用。
?????? ?對于目前大多數(shù)工業(yè)自動化和測試測量等領(lǐng)域的應(yīng)用來說,95MB/s的TCP網(wǎng)絡(luò)傳輸帶寬完全足夠了,雖然只比UDP巔峰時期的118MB/s少一點(diǎn),但是TCP屬于握手類長鏈接傳輸協(xié)議,更加可靠和穩(wěn)定。
?
?????? ?下面重點(diǎn)給用戶介紹一下我們神電測控封裝好的FPGA TCP Client和Server Socket CLIP,首先在LabVIEW項(xiàng)目瀏覽器下的“我的電腦”上右擊,選擇新建“終端和設(shè)備”,如圖10-14所示。
? ? ? ? ? ? ? ? ? ? ? ?

? ? ? ? 然后在彈出來的終端設(shè)備新建對話框里面,展開ARTIX7-100T,找到后綴帶TCP_Server和TCP_Client的黑金AX7103或者正點(diǎn)原子達(dá)芬奇Pro對應(yīng)的FPGA終端,如圖10-15所示。




? ? ? ? 這里我們選擇“ARTIX7_XC7A100T_2FGG484_AX7103_PCIe_X4_B_8CMs_TCP_Client”和“ARTIX7_XC7A100T_2FGG484_AX7103_PCIe_X4_B_8CMs_TCP_Server”這兩個終端進(jìn)行講解。點(diǎn)擊“確定”按鈕后,這兩個版本的TCP通信Socket CLIP組件會自動添加到FPGA終端里面來,圖10-16顯示的是帶TCP Client客戶端版本的LabVIEW FPGA CLIP(TCP_Client Data),圖10-17顯示的是TCP Server服務(wù)器版本的LabVIEW FPGA CLIP(TCP_Server Data)。
?????? ?展開這兩個TCP Socket CLIP之后,可以看到一共有15個EIO節(jié)點(diǎn),雖然多,但是有規(guī)律可循,除去第一個TCP CLIP復(fù)位(lv_tcp_client_reset)和最后的125MHz時鐘外(Clock lv_tcp_client_125M_clk_out),余下的就是TCP MAC地址和IP端口等參數(shù)設(shè)置,最后就是TCP收發(fā)數(shù)據(jù)的四線握手信號。
?????? ?可以看出,這兩個TCP Socket CLIP與我們前面封裝的UDP CLIP接口形式上面差不多,這樣做的目的是為了讓大家更容易理解和方便調(diào)用。


? ? ? ? 可以看出,TCP Client版本與TCP Server版本封裝出來的接口和參數(shù)除了名稱不一樣,功能上面很類似,這樣方便大家使用和記憶。也就說,用戶只要掌握了其中一個版本的調(diào)用,另外一個也就觸類旁通了;如果要改變下位機(jī)FPGA的TCP通信角色,比如FPGA原先跑的TCP客戶端協(xié)議,現(xiàn)在想變成服務(wù)器,那就直接右擊FPGA VI里面的TCP Client Socket CLIP節(jié)點(diǎn),逐個替換成TCP Server Socket CLIP下面的節(jié)點(diǎn)即可。
?????? ?為了支持更高端的FPGA芯片以及國產(chǎn)化FPGA(深圳國微和上海復(fù)旦微),我們特地將Xilinx Kintex7家族也進(jìn)行了TCP協(xié)議棧的LabVIEW Socket CLIP封裝,如圖10-18(abcdef)所示。圖10-19和10-20顯示的是分別集成了TCP Client和TCP Server Socket CLIP節(jié)點(diǎn)的Kintex7 FPGA終端和端口信息。








?????? ?下面我們給大家逐一講解一下TCP Client和TCP Server兩個版本的LabVIEW FPGA TCP Socket CLIP里面每個信號端口的含義和注意事項(xiàng)。通過虛線將15個CLIP端口劃分成4類:分別是TCP IP核服務(wù)信號、TCP CLIP 125M運(yùn)行時鐘、TCP鏈接狀態(tài)信號、上行(FPGA-->Host)通道以及下行(Host-->FPGA)通道的數(shù)據(jù)和握手信號。其中,Host可以直觀的理解成上位機(jī)PC。
?? ?10.4.1、TCP Client客戶端版本的FPGA EIO節(jié)點(diǎn)講解(下位機(jī)):
?????? ?1)lv_tcp_client_reset
-------------------------------------------------------------------
?????? ?2)Clock lv_tcp_client_125M_clk_out
--------------------------------------------------------------------
?????? ?3)lv_tcp_client_connect_status
--------------------------------------------------------------------
?????? ?4)lv_tcp_client_board_mac
?????? ?5)lv_tcp_client_board_ip
?????? ?6)lv_tcp_client_board_port
?????? ?7)lv_tcp_client_board_gate_way
?????? ?8)lv_tcp_client_board_subnet_mask
?????? ?9)lv_tcp_client_pc_ip
?????? ?10)lv_tcp_client_pc_port
---------------------------------------------------------------------
????????11)lv_tcp_client_tx_data_in
?????? ?12)lv_tcp_client_tx_data_in_vld
?????? ?13)lv_tcp_client_tx_data_req_en
?????? ?14)lv_tcp_client_rx_data_out
?????? ?15)lv_tcp_client_rx_data_out_vld
------------------------------------------------------------------
?????? ?下面我們給用戶詳細(xì)講解一下TCP Client每個端口的含義。
?????? ?1)lv_tcp_client_reset(下位機(jī)FPGA TCP客戶端IP核復(fù)位信號)
?????? ?為了防止FPGA芯片內(nèi)部的TCP Client協(xié)議棧IP核在某些極端條件下出現(xiàn)死機(jī)等問題,我們特地將底層TCP Client IP核的復(fù)位信號拉到LabVIEW FPGA里面來,這樣用戶就能通過LabVIEW隨時隨地對這個TCP Client IP核進(jìn)行復(fù)位清零等工作。需要復(fù)位的時候,將這個“l(fā)v_tcp_client_reset”信號端口拉高(True),平時給個低電平(Flase)即可。當(dāng)然,最直接的方式就是在FPGA VI前面板上創(chuàng)建一個布爾型的按鍵,連到“l(fā)v_tcp_client_reset”端口上,如圖10-21所示;這樣就可以利用我們特有的LabVIEW FPGA在線前面板調(diào)試模式,直接利用鼠標(biāo)對TCP IP核進(jìn)行動態(tài)復(fù)位,方便用戶測試下位機(jī)FPGA程序。

? ? ? ? 2)Clock lv_tcp_client_125M_clk_out(下位機(jī)FPGA TCP客戶端IP核運(yùn)行時鐘域)
?????? ?FPGA TCP Client IP核運(yùn)行時鐘,默認(rèn)是125MHz,這個時鐘是路由出來給用戶自己寫程序用的FIFO同步時鐘。眾所周知,千兆模式下的TCP運(yùn)行時鐘和用戶時鐘都是125MHz,也就是說,用戶如果要把FPGA里面的數(shù)據(jù)通過TCP發(fā)送給PC(上行)或者接收PC下發(fā)的數(shù)據(jù)(下行),必須要使用這個125MHz時鐘源,才能保持FIFO同步握手。為此,我們將這個125MHz時鐘直接封裝到我們的LabVIEW FPGA TCP Client CLIP里面來了,時鐘信號名為“Clock lv_tcp_client_125M_clk_out”。
?????? ?如何使用TCP Client CLIP路由進(jìn)來的時鐘呢?跟前面我們封裝的PCIe總線、UDP千兆以太網(wǎng)、USB時鐘一樣,用戶可以直接在FPGA定時循環(huán)左邊創(chuàng)建一個時鐘源常量,然后在下拉列表里面選擇,如圖10-22所示;或者直接雙擊FPGA定時循環(huán),在彈出來的時鐘配置頁面里面選擇“TCP_Client Data\ Clock lv_tcp_client_125M_clk_out”,如圖10-23所示。


? ? ? ? 3)lv_tcp_client_connect_status(下位機(jī)FPGA客戶端是否與服務(wù)器建立起連接狀態(tài))
?????? ?由于TCP協(xié)議跟PCIe協(xié)議都是握手類協(xié)議,也就是說,只有與對等端建立起鏈接之后才能進(jìn)行后續(xù)的發(fā)送和接收等傳輸工作,為了方便用戶觀察和調(diào)試TCP通信過程,我們將TCP Client IP核底層的是否建立起鏈接這個狀態(tài)封裝到LabVIEW FPGA里面來了;比如,這里下位機(jī)FPGA運(yùn)行TCP Client協(xié)議之后,上位機(jī)PC充當(dāng)服務(wù)器,那么當(dāng)上位機(jī)服務(wù)器端偵聽到下位機(jī)FPGA的TCP連接請求之后,一旦成功建立起連接之后,這個“l(fā)v_tcp_client_connect_status”端口就會輸出高電平(True),因此,我們可以將這個信號端口連接到FPGA VI前面板上面的LED指示燈,如圖10-24所示;這樣就能通過這個LED燈的亮滅來判斷下位機(jī)FPGA(TCP客戶端)與主機(jī)端(比如上位機(jī)PC服務(wù)器端)是否建立起TCP通信連接。

?????? ?4)lv_tcp_client_board_mac(下位機(jī)FPGA客戶端MAC地址)
?????? ?5)lv_tcp_client_board_ip(下位機(jī)FPGA客戶端IP地址)
?????? ?6)lv_tcp_client_board_port(下位機(jī)FPGA客戶端端口)
?????? ?7)lv_tcp_client_board_gate_way(下位機(jī)FPGA客戶端網(wǎng)關(guān))
?????? ?8)lv_tcp_client_board_subnet_mask(下位機(jī)FPGA客戶端子網(wǎng)掩碼)
?????? ?9)lv_tcp_client_pc_ip(下位機(jī)FPGA客戶端發(fā)起連接的遠(yuǎn)程服務(wù)器IP地址)
?????? ?10)lv_tcp_client_pc_port(下位機(jī)FPGA客戶端發(fā)起連接的遠(yuǎn)程服務(wù)器端口)
?????? ?上面這7個信號端口(4~10)一看名稱就明白,它們是用來配置TCP通信的參數(shù),依次是下位機(jī)FPGA客戶端的MAC地址、IP地址、Port端口、網(wǎng)關(guān)、子網(wǎng)掩碼和需要連接的遠(yuǎn)程服務(wù)器端(比如上位機(jī)PC)IP地址和Port端口。需要注意的是,為了方便大家記憶,我們將下位機(jī)FPGA形象的稱呼為板子board,服務(wù)器端稱呼為pc電腦,因此,名稱里面帶board的都是指下位機(jī)FPGA參數(shù),帶pc的都是指上位機(jī)參數(shù),不要被前綴“l(fā)v_tcp_client”迷惑了,這個前綴是指FPGA當(dāng)前封裝的TCP協(xié)議棧是Client客戶端。通過下面圖10-25所示的程序框圖,對TCP通信參數(shù)的設(shè)置和理解更加直觀和一目了然。

? ? ? ? 提醒:如果下位機(jī)FPGA接入的是局域網(wǎng),MAC地址一般可以隨便設(shè)置,如果是廣域網(wǎng),那么設(shè)置的MAC地址不能與公網(wǎng)上的MAC相同,否則會產(chǎn)生沖突。
?????? ?某些用戶英文不是很好,為了照顧大家,我們特地在上圖10-25的參數(shù)旁邊加了備注,特別是下位機(jī)FPGA里面的IP地址不支持點(diǎn)號,必須要用16進(jìn)制表示。
?
?????? ?11)lv_tcp_client_tx_data_in(下位機(jī)FPGA TCP客戶端需要發(fā)送的上行數(shù)據(jù))
?????? ?12)lv_tcp_client_tx_data_in_vld(下位機(jī)FPGA TCP客戶端發(fā)送的上行數(shù)據(jù)是否有效)
?????? ?13)lv_tcp_client_tx_data_req_en(下位機(jī)FPGA TCP客戶端發(fā)送上行數(shù)據(jù)的請求信號)
?????? ?上面這3個FPGA TCP客戶端發(fā)送通道(11~13)的四線握手信號,其實(shí)就是上行數(shù)據(jù)發(fā)送端口,跟本書前面第7章提到的8位PCIe發(fā)送通道類似,這里的TCP端口數(shù)據(jù)位寬也是8位的,也就是1個Byte字節(jié),同樣,每個上行通道都有3個握手端口組成。為了讓用戶更加形象的理解和掌握這些握手信號的用法,我們先給出一個FPGA TCP客戶端數(shù)據(jù)發(fā)送程序框圖,如圖10-26所示。畢竟LabVIEW框圖看起來顯而易見,一圖勝千言!

? ? ? ? 其中,“l(fā)v_tcp_client_tx_data_req_en”信號就是TCP Client Socket IP核內(nèi)部的接收FIFO準(zhǔn)備就緒信號或者稱之為主動向FPGA用戶程序請求數(shù)據(jù)信號,如果這個“l(fā)v_tcp_client_tx_data_req_en”拉高,說明TCP Client IP核可以接收FPGA給過來的數(shù)據(jù),然后將其發(fā)送到上位機(jī)PC服務(wù)器端。因此,我們可以將這個“l(fā)v_tcp_client_tx_data_req_en”接到FPGA里面用戶創(chuàng)建的數(shù)據(jù)源FIFO(FIFO_TCP_Send_U8)的“輸出就緒”端口上面;再把該FIFO輸出的數(shù)據(jù)和有效信號分別接到TCP Client Socket CLIP的“l(fā)v_tcp_client_tx_data_in”和“l(fā)v_tcp_client_tx_data_in_vld”端口上面。
?????? ?需要注意的是:如果對等端(比如服務(wù)器端)讀取速度慢,那么需要加大下位機(jī)FPGA里面的Send FIFO(FIFO_TCP_Send_U8)深度,否則TCP數(shù)據(jù)包容易溢出丟失,因?yàn)樯衔粰C(jī)網(wǎng)卡自身往往沒有辦法增加TCP緩沖區(qū),只有下位機(jī)FPGA能夠加大FIFO或者利用DDR來緩沖數(shù)據(jù);通常情況下,握手類協(xié)議的上行數(shù)據(jù)緩沖區(qū)FIFO一般設(shè)置大一些比較好,這個我們在前面也多次提到過了,切記!
?
?????? ?14)lv_tcp_client_rx_data_out
?????? ?15)lv_tcp_client_rx_data_out_vld
?????? ?最后,剩下的這2個TCP Client接收數(shù)據(jù)通道(14~15)的握手信號,其實(shí)就是下行數(shù)據(jù)接收端口,這里TCP接收到服務(wù)器下發(fā)的下行數(shù)據(jù)位寬也是8位,跟PCIe類似,TCP下行通道同樣是2個握手端口組成。為了讓用戶更加形象的理解和掌握這些下行數(shù)據(jù)握手信號的用法,我們先給出一個FPGA TCP Client客戶端數(shù)據(jù)接收程序框圖,如圖10-27所示。畢竟LabVIEW框圖看起來更直觀易懂!

? ? ? ? 其中,一旦下位機(jī)FPGA客戶端接收到上位機(jī)PC服務(wù)器端下發(fā)的TCP數(shù)據(jù)包后,那么對應(yīng)的“l(fā)v_tcp_client_rx_data_out”和“l(fā)v_tcp_client_rx_data_out_vld”就會有效;因此,我們可以將“l(fā)v_tcp_client_rx_data_out”和“l(fā)v_tcp_client_rx_data_out_vld”分別接到FPGA里面用戶創(chuàng)建的接收緩沖區(qū)FIFO(FIFO_TCP_Receive_U8)對應(yīng)的數(shù)據(jù)輸入和輸入有效信號端口上。
?????? ?需要注意的是:與上行數(shù)據(jù)FIFO緩沖區(qū)不一樣,握手類協(xié)議的下行數(shù)據(jù)緩沖區(qū)FIFO一般不需要設(shè)置很大,避免過多浪費(fèi)FPGA Block RAM資源,這是因?yàn)镕PGA自身的讀取和處理速度是非??斓模淮嬖诳D或者抖動一說;因此,可以看出,如果其中一方速度慢于另一方,那么速度快的這一方通常需要加大FIFO深度;假設(shè)雙方是兩個讀取和處理速度都很快的FPGA進(jìn)行互聯(lián)的話,那么無論是發(fā)送FIFO還是接收FIFO,實(shí)際上都不需要設(shè)置很大,因?yàn)镕PGA可以完全高速的逐點(diǎn)處理,而上位機(jī)PC通常做不到。
?
?????? ?提醒:我們封裝的TCP客戶端上行和下行data都是U8字節(jié)整形數(shù)據(jù),如果用戶需要發(fā)送或者接收小數(shù)或者定點(diǎn)數(shù),那么需要提前進(jìn)行轉(zhuǎn)換,比如,將定點(diǎn)數(shù)通過“數(shù)值至布爾數(shù)組”將符號和小數(shù)點(diǎn)特性去掉,然后再利用“布爾數(shù)組至數(shù)值”轉(zhuǎn)換成整形數(shù)據(jù),最后再進(jìn)行拆分組合變成U8字節(jié)數(shù)組,反之亦然。
?
?????? 結(jié)論:可以看出,雖然TCP協(xié)議本身很復(fù)雜,但是對于用戶來說,只要理解了FIFO的四線握手編程,就可以搞定所有線程之間的數(shù)據(jù)傳輸問題了,這也就是為什么我們在書中每個實(shí)驗(yàn)里面都反復(fù)強(qiáng)調(diào)四線握手和并轉(zhuǎn)串以及串轉(zhuǎn)并的重要性。
? ??10.4.2、TCP Server服務(wù)器版本的FPGA EIO節(jié)點(diǎn)講解(下位機(jī)):
?????? ?1)lv_tcp_server_reset
------------------------------------------------------------------
?????? ?2)Clock lv_tcp_server_125M_clk_out
------------------------------------------------------------------
?????? ?3)lv_tcp_server_connect_status
-----------------------------------------------------------------
?????? ?4)lv_tcp_server_board_mac
?????? ?5)lv_tcp_server_board_ip
?????? ?6)lv_tcp_server_board_port
?????? ?7)lv_tcp_server_board_gate_way
?????? ?8)lv_tcp_server_board_subnet_mask
?????? ?9)lv_tcp_server_pc_ip
?????? ?10)lv_tcp_server_pc_port
-----------------------------------------------------------------
????????11)lv_tcp_server_tx_data_in
?????? ?12)lv_tcp_server_tx_data_in_vld
?????? ?13)lv_tcp_server_tx_data_req_en
?????? ?14)lv_tcp_server_rx_data_out
?????? ?15)lv_tcp_server_rx_data_out_vld
----------------------------------------------------------------
?????? ?下面我們給用戶詳細(xì)講解一下TCP Server每個端口的含義。
?????? ?1)lv_tcp_server_reset(下位機(jī)FPGA TCP服務(wù)器IP核復(fù)位信號)
?????? ?為了防止FPGA芯片內(nèi)部的TCP Server協(xié)議棧IP核在某些極端條件下出現(xiàn)死機(jī)等問題,我們特地將底層TCP Server IP核的復(fù)位信號拉到LabVIEW FPGA里面來,這樣用戶就能通過LabVIEW隨時隨地對這個TCP Server IP核進(jìn)行復(fù)位清零等工作。需要復(fù)位的時候,將這個“l(fā)v_tcp_server_reset”信號端口拉高(True),平時給個低電平(Flase)即可。當(dāng)然,最直接的方式就是在FPGA VI前面板上創(chuàng)建一個布爾型的按鍵,連到“l(fā)v_tcp_server_reset”端口上,如圖10-28所示;這樣就可以利用我們特有的LabVIEW FPGA在線前面板調(diào)試模式,直接利用鼠標(biāo)對TCP IP核進(jìn)行動態(tài)復(fù)位,方便用戶測試下位機(jī)FPGA程序。

? ? ? ? 2)Clock lv_tcp_server_125M_clk_out(下位機(jī)FPGA TCP服務(wù)器IP核運(yùn)行時鐘域)
?????? ?FPGA TCP Server IP核運(yùn)行時鐘,默認(rèn)是125MHz,這個時鐘是路由出來給用戶自己寫程序用的FIFO同步時鐘。眾所周知,千兆模式下的TCP運(yùn)行時鐘和用戶時鐘都是125MHz,也就是說,用戶如果要把FPGA里面的數(shù)據(jù)通過TCP發(fā)送給PC(上行)或者接收PC下發(fā)的數(shù)據(jù)(下行),必須要使用這個125MHz時鐘源,才能保持FIFO同步握手。為此,我們將這個125MHz時鐘直接封裝到我們的LabVIEW FPGA TCP Server CLIP里面來了,時鐘信號名為“Clock lv_tcp_server_125M_clk_out”。
?????? ?如何使用TCP Server CLIP路由進(jìn)來的時鐘呢?跟前面我們封裝的PCIe總線、UDP千兆以太網(wǎng)、USB時鐘一樣,用戶可以直接在FPGA定時循環(huán)左邊創(chuàng)建一個時鐘源常量,然后在下拉列表里面選擇,如圖10-29所示;或者直接雙擊FPGA定時循環(huán),在彈出來的時鐘配置頁面里面選擇“TCP_Server Data\ Clock lv_tcp_server_125M_clk_out”,如圖10-30所示。


? ? ? ? 3)lv_tcp_server_connect_status(下位機(jī)FPGA服務(wù)器是否與客戶端建立起連接狀態(tài))
?????? ?由于TCP協(xié)議跟PCIe協(xié)議都是握手類協(xié)議,也就是說,只有與對等端建立起連接之后才能進(jìn)行后續(xù)的發(fā)送和接收等傳輸工作,為了方便用戶觀察和調(diào)試TCP通信過程,我們將TCP Server IP核底層的是否建立起鏈接這個狀態(tài)封裝到LabVIEW FPGA里面來了;比如,這里下位機(jī)FPGA運(yùn)行TCP Server協(xié)議之后,上位機(jī)PC充當(dāng)客戶端,那么當(dāng)下位機(jī)FPGA(服務(wù)器端)偵聽到上位機(jī)(客戶端)的TCP連接請求之后,一旦成功建立起連接之后,這個“l(fā)v_tcp_server_connect_status”端口就會輸出高電平(True),因此,我們可以將這個信號端口連接到FPGA VI前面板上面的LED指示燈,如圖10-31所示;這樣就能通過這個LED燈的亮滅來判斷下位機(jī)FPGA(TCP服務(wù)器端)與主機(jī)端(比如上位機(jī)PC客戶端)是否建立起TCP通信連接。

? ? ? ? 4)lv_tcp_server_board_mac(下位機(jī)FPGA服務(wù)器端MAC地址)
?????? ?5)lv_tcp_server_board_ip(下位機(jī)FPGA服務(wù)器端IP地址)
?????? ?6)lv_tcp_server_board_port(下位機(jī)FPGA服務(wù)器端端口)
?????? ?7)lv_tcp_server_board_gate_way(下位機(jī)FPGA服務(wù)器端網(wǎng)關(guān))
?????? ?8)lv_tcp_server_board_subnet_mask(下位機(jī)FPGA服務(wù)器端子網(wǎng)掩碼)
?????? ?9)lv_tcp_server_pc_ip(下位機(jī)FPGA服務(wù)器偵聽來自遠(yuǎn)程客戶端的IP地址)
?????? ?10)lv_tcp_server_pc_port(下位機(jī)FPGA服務(wù)器偵聽來自遠(yuǎn)程客戶端的端口)
?????? ?上面這7個信號端口(4~10)一看名稱就明白,它們是用來配置TCP通信的參數(shù),依次是下位機(jī)FPGA服務(wù)器的MAC地址、IP地址、Port端口、網(wǎng)關(guān)、子網(wǎng)掩碼和偵聽來自遠(yuǎn)程客戶端(比如上位機(jī)PC)的IP地址和Port端口。需要注意的是,為了方便大家記憶,我們將下位機(jī)FPGA形象的稱呼為board(板子),對等端稱呼為pc電腦,因此,名稱里面帶board的都是指下位機(jī)FPGA參數(shù),帶pc的都是指上位機(jī)參數(shù),不要被前綴“l(fā)v_tcp_server”迷惑了,這個前綴是指FPGA當(dāng)前封裝的TCP協(xié)議棧是Server服務(wù)器。通過下面圖10-32所示的程序框圖,對TCP通信參數(shù)的設(shè)置和理解更加直觀和一目了然。

? ? ? ? 提醒:如果下位機(jī)FPGA接入的是局域網(wǎng),MAC地址一般可以隨便設(shè)置,如果是廣域網(wǎng),那么設(shè)置的MAC地址不能與公網(wǎng)上的MAC相同,否則會產(chǎn)生沖突。
?????? ?某些用戶英文不是很好,為了照顧大家,我們特地在上圖10-32的參數(shù)旁邊加了備注,特別是下位機(jī)FPGA里面的IP地址不支持點(diǎn)號,必須要用16進(jìn)制表示。
?
?????? ?11)lv_tcp_server_tx_data_in(下位機(jī)FPGA TCP服務(wù)器需要發(fā)送的上行數(shù)據(jù))
?????? ?12)lv_tcp_server_tx_data_in_vld(下位機(jī)FPGA TCP服務(wù)器發(fā)送的上行數(shù)據(jù)是否有效)
?????? ?13)lv_tcp_server_tx_data_req_en(下位機(jī)FPGA TCP服務(wù)器發(fā)送上行數(shù)據(jù)的請求信號)
?????? ?上面這3個FPGA TCP服務(wù)器發(fā)送通道(11~13)的四線握手信號,其實(shí)就是上行數(shù)據(jù)發(fā)送端口,跟本書前面第7章提到的8位PCIe發(fā)送通道類似,這里的TCP端口數(shù)據(jù)位寬也是8位,也就是1個Byte字節(jié),同樣,每個上行通道都有3個握手信號組成。為了讓用戶更加形象的理解和掌握這些握手信號的用法,我們先給出一個FPGA TCP服務(wù)器端數(shù)據(jù)發(fā)送程序框圖,如圖10-33所示。畢竟LabVIEW框圖看起來顯而易見,一圖勝千言!

? ? ? ? 其中,“l(fā)v_tcp_server_tx_data_req_en”信號就是TCP Server Socket IP核內(nèi)部的接收FIFO準(zhǔn)備就緒信號或者稱之為主動向FPGA用戶程序請求數(shù)據(jù)的信號,如果這個“l(fā)v_tcp_server_tx_data_req_en”拉高,說明TCP Server IP核可以接收FPGA給過來的數(shù)據(jù),然后將其發(fā)送到上位機(jī)PC客戶端。因此,我們可以將這個“l(fā)v_tcp_server_tx_data_req_en”接到FPGA里面用戶創(chuàng)建的數(shù)據(jù)源FIFO(FIFO_TCP_Send_U8)的“輸出就緒”端口上面;再把該FIFO輸出的數(shù)據(jù)和有效信號分別接到TCP Server Socket CLIP的“l(fā)v_tcp_server_tx_data_in”和“l(fā)v_tcp_server_tx_data_in_vld”端口上面。
?????? ?需要注意的是:如果對等端(比如客戶端)讀取速度慢,那么需要加大下位機(jī)FPGA服務(wù)器里面的Send FIFO(FIFO_TCP_Send_U8)深度,否則TCP數(shù)據(jù)包容易溢出丟失,因?yàn)樯衔粰C(jī)網(wǎng)卡自身往往沒有辦法增加TCP緩沖區(qū),只有下位機(jī)FPGA能夠加大FIFO或者利用DDR來緩沖數(shù)據(jù);通常情況下,握手類協(xié)議的上行數(shù)據(jù)緩沖區(qū)FIFO一般設(shè)置大一些比較好,這個我們在前面也多次提到過了,切記!
?
?????? ?14)lv_tcp_server_rx_data_out
?????? ?15)lv_tcp_server_rx_data_out_vld
?????? ?最后,剩下的這2個TCP Server接收數(shù)據(jù)通道(14~15)的握手信號,其實(shí)就是下行數(shù)據(jù)接收端口,這里TCP接收到遠(yuǎn)程客戶端下發(fā)的下行數(shù)據(jù)位寬也是8位,跟PCIe類似,TCP下行通道同樣是2個握手端口組成。為了讓用戶更加形象的理解和掌握這些下行數(shù)據(jù)握手信號的用法,我們先給出一個FPGA TCP Server服務(wù)器端數(shù)據(jù)接收程序框圖,如圖10-34所示。畢竟LabVIEW框圖看起來更直觀易懂!

? ? ? ? 其中,一旦下位機(jī)FPGA服務(wù)器接收到上位機(jī)PC客戶端下發(fā)的TCP數(shù)據(jù)包后,那么對應(yīng)的“l(fā)v_tcp_server_rx_data_out”和“l(fā)v_tcp_server_rx_data_out_vld”就會有效;因此,我們可以將“l(fā)v_tcp_server_rx_data_out”和“l(fā)v_tcp_server_rx_data_out_vld”分別接到FPGA里面用戶創(chuàng)建的接收緩沖區(qū)FIFO(FIFO_TCP_Receive_U8)對應(yīng)的數(shù)據(jù)輸入和輸入有效信號端口上。
?????? ?需要注意的是:與上行數(shù)據(jù)FIFO緩沖區(qū)不一樣,握手類協(xié)議的下行數(shù)據(jù)緩沖區(qū)FIFO一般不需要設(shè)置很大,避免過多浪費(fèi)FPGA Block RAM資源,這是因?yàn)镕PGA自身的讀取和處理速度是非??斓模淮嬖诳D或者抖動一說;因此,可以看出,如果其中一方速度慢于另一方,那么速度快的這一方通常需要加大FIFO深度;假設(shè)雙方是兩個讀取和處理速度都很快的FPGA進(jìn)行互聯(lián)的話,那么無論是發(fā)送FIFO還是接收FIFO,實(shí)際上都不需要設(shè)置很大,因?yàn)镕PGA可以完全高速的逐點(diǎn)處理,而上位機(jī)PC通常做不到。
?
?????? ?提醒:我們封裝的TCP服務(wù)器上行和下行data都是U8字節(jié)整形數(shù)據(jù),如果用戶需要發(fā)送或者接收小數(shù)或者定點(diǎn)數(shù),那么需要提前進(jìn)行轉(zhuǎn)換,比如,將定點(diǎn)數(shù)通過“數(shù)值至布爾數(shù)組”將符號和小數(shù)點(diǎn)特性去掉,然后再利用“布爾數(shù)組至數(shù)值”轉(zhuǎn)換成整形數(shù)據(jù),最后再進(jìn)行拆分組合變成U8字節(jié)數(shù)組,反之亦然。
?
?????? 結(jié)論:可以看出,雖然TCP協(xié)議本身很復(fù)雜,但是對于用戶來說,只要理解了FIFO的四線握手編程,就可以搞定所有線程之間的數(shù)據(jù)傳輸問題了,這也就是為什么我們在書中每個實(shí)驗(yàn)里面都反復(fù)強(qiáng)調(diào)四線握手和并轉(zhuǎn)串以及串轉(zhuǎn)并的重要性。
? ? ???10.5、修改底層XDC約束文件以適配用戶自己做的或者第三方的FPGA TCP硬件
?????? ?本節(jié)我們重點(diǎn)講解一下一個非常重要的問題:那就是如果用戶自己做的板子沒有參考黑金AX7103原理圖,或者網(wǎng)上買了其他家成熟的帶PHY網(wǎng)口的FPGA硬件,那么用戶需要注意哪些地方才能讓我們封裝的LabVIEW FPGA TCP Socket CLIP完美適配呢?
?????? ?不知道大家還記不記得我們曾在第五章里面,告訴大家如何修改FPGA引腳來適配自己板子上的晶振時鐘,讓FPGA能夠運(yùn)行起來;同理,TCP與UDP對應(yīng)的PHY芯片也有幾個非常重要的引腳可以在xdc頂層約束文件里面修改。編譯的時候會自動覆蓋底層網(wǎng)表文件里面的引腳定義。
?????? ?首先,找到我們需要修改的FPGA終端模板文件里面的xdc約束文件,比如本書配套的ARTIX7開發(fā)板AX7103,默認(rèn)的路徑如圖10-35所示,找到里面的xdc約束文件,如圖10-36所示:
C:\Program Files (x86)\National Instruments\LabVIEW 2018\Targets\NI\FPGA\NiAdept
C:\Program Files (x86)\National Instruments\LabVIEW 2019\Targets\NI\FPGA\NiAdept
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

?

? ? ? ? 然后,右擊通過notepad++打開這個xdc約束文件,找到PHY網(wǎng)口芯片引腳定義的地方,如圖10-37所示。

? ? ? ? 因?yàn)槊總€廠家做的FPGA板子給外設(shè)分配的引腳可能都不盡相同,所以用戶需要根據(jù)板子實(shí)際的原理圖來修改這個xdc頂層文件。以黑金AX7103開發(fā)板舉例說明,先打開對應(yīng)底板原理圖,找到PHY網(wǎng)絡(luò)芯片相關(guān)針腳定義,如圖10-38所示。這些引腳其實(shí)可以分成4類:PHY芯片復(fù)位引腳、PHY芯片寄存器參數(shù)配置的IIC引腳(mdc和mdio)、PHY芯片收發(fā)125MHz時鐘引腳;PHY芯片收發(fā)數(shù)據(jù)引腳(GMII:8bit;RGMII:4bit)。
?????? ?這4類引腳在前面圖10-37里面都定義過了,如果用戶自己畫的板子或者網(wǎng)上買的其他家的板子引腳定義不一樣,那么照葫蘆畫瓢對應(yīng)修改一下就可以了。

? ? ? ? 然后,打開AX7103開發(fā)板上插著的核心板AC7100原理圖,如圖10-39所示,可以看到黑金AX7103開發(fā)板上第1路和第2路KSZ9031 PHY芯片都掛在了FPGA BANK16上面。

