Checksum AutoESL TEMAC FIFO IPv4 UDP RAM HDL LAN

活用AutoESL合成工具 UDP封包引擎設計快速達陣

歸功於強化後的三模乙太網路媒體存取控制(Tri-Mode Ethernet Media Access Controller, TEMAC),讓超高速乙太網路(Gigabit Ethernet)成為最常見的互連方法之一,可將工作站(Workstation)或筆記型電腦(Notebook)連接到以現場可編程閘陣列(FPGA)為基礎的嵌入式平台中。
在開發以乙太網路(Ethernet)為基礎的FPGA設計時,最主要的障礙是決定用甚麼處理器來處理網際網路協定(IP)堆疊。

為了解決這個問題,設計人員可採用AutoESL高階綜合工具,來開發高效能網際網路協定第四版(IPv4)使用者資料封包協定(UDP)資料封包傳輸引擎。

在安捷倫(Agilent)測量研究實驗室工作的賽靈思(Xilinx)研發小組,根據網際網路工程任務組中關於UDP、位址解析通訊協定(ARP)和動態主機設定通訊協定(DHCP)各協定間資料封包交換的標準,編寫了原始的C語言程式碼。該設計無需中央處理器(CPU)即可建置硬體資料封包處理引擎。這種架構能夠以線速處理流量,延遲率極低,邏輯資源面積占用少。使用AutoESL則能夠輕鬆調整使用者介面,以適應一個或多個先進先出(FIFO)串流,或多個隨機存取記憶體(RAM)介面埠。AutoESL是賽靈思ISE設計套件的新增功能,在最新Vivado設計套件中又稱為Vivado HLS。

IPv4 UDP較TCP可靠度更高

IPv4是網際網路的主流協定,而其第六版(IPv6)還在漸漸普及的階段。大多數開發人員討論IP時,通常指的是傳輸控制協定(TCP)。這是一種以連接為基礎的協定,可提供可靠度和流量壅塞管理功能。但對於影音串流、網路電話、遊戲或分散式感測器網路(Sensor Networking)等眾多應用而言,增加頻寬與將延遲率控制到最小,比可靠度來得重要。因此,這類應用一般會使用UDP,而不是TCP。

UDP是一種無連接傳輸模式,本身不具可靠度。如果資料封包丟失、被複製或者亂序發送,發送方不會知道,用戶的應用將負責執行封包檢測和處理相關的錯誤。從這方面而言,UDP又稱「不可靠」協定;但與TCP相比,它能提供更高的效能。

每一種支援IP的作業系統,基本上都提供UDP支援。高階軟體程式設計語言將網路串流稱為「通訊端」,而UDP則稱為「資料通訊端」。

安捷倫開發的是一種以區域網路(LAN)為基礎的感測器網路,透過賽靈思Virtex-5 FPGA可連接到一個類比數位轉換器(ADC)。該FPGA負責彙集資料,然後按照請求將一系列取樣發送到預先設定的IP位址,亦即個人電腦(PC)主機。由於FPGA的區塊隨機存取記憶體(Block RAM, BRAM)幾乎全部專用於訊號處理,因此沒有足夠的儲存空間來容納軟處理器的韌體(Firmware)。

然而,也可以選擇建置一組最簡略的網路功能,將感測器(Sensor)資料透過UDP回傳到主機。由於需要高頻寬和低延遲率的特性,UDP資料封包的串流是比較好的網路傳輸模式。

由於資料對於傳輸時間極為敏感,一組全新的取樣資料比重新傳輸丟失的取樣更重要。此時面臨的兩大挑戰之一是避免主機設備超載。

換句話說,必須找到一種能夠有效處理大量輸入取樣的方法。第二大挑戰是在下一組取樣溢出內部緩衝區前迅速將UDP資料封包格式化,並計算所需的IP表頭欄位和選項式(但也是必需的)UDP的承載資料加總檢查值(Checksum)。

HDL初始設計簡單直接

由於有現成的虛擬代碼,資料封包引擎的硬體描述語言(HDL)的執行作業非常簡單直接,但對於賽靈思的FPGA硬體而言卻不是最好的做法。來自各種原始檔案的C語言和虛擬代碼可簡化驗證作業。另外,如Wireshark這樣的網路封包分析工具,以及Java般的高階語言都可以簡化模擬流程和實驗室驗證工作。

透過現成的虛擬代碼來開發Verilog以產生封包表頭,須要對狀態機進行編碼、讀取樣本FIFO,以及將資料封包彙集到RAM的暫存。這裡把設計分為RX Flow、TX Flow和LAN微控制器(MCU)三大模組,如圖1所示。

圖1 UDP資料封包引擎設計由RX Flow、TX Flow和LAN MCU三大模組構成,各模組配置如圖所示。

當來自LAN的資料封包抵達時,RX Flow負責檢查資料封包,並將其發送給設備核心或LAN MCU進行處理。例如,處理ARP或DHCP資料封包時就是採用這種方法。

TX Flow資料封包引擎負責從TX FIFO中讀取N個ADC取樣,並針對UDP加總檢查值計算出所需的作業資料承載量加總檢查值。TX FIFO負責將新到達的取樣暫存起來,同時LAN MCU負責為待傳輸資料封包準備所需的承載資料量。

在獲得最後一個取樣要求後,LAN MCU負責計算剩餘的IP/UDP資料封包的表頭欄位。在網路技術中,這個過程屬於TX Chechsum卸載。

當資料封包的欄位產生後,LAN MCU會將資料封包送到TEMAC待傳送,但LAN MCU會保留資料封包直到TEMAC確認成功發出(而非成功被接收端設備接收)。在第一個資料封包等待TEMAC發出時,新的感測器取樣會抵達TX FIFO。當第一個資料封包傳輸完畢,資料封包引擎會為下一個資料封包釋出儲存緩衝區。

這個過程採用雙緩衝方式。如果TEMAC發出一個錯誤訊號,而且下一個傳輸緩衝區快要溢位時,這個資料封包就不能繼續進行下一個取樣集,但有例外情況時會發出提示。

由於取樣集的時戳(Time-stamping)已包含在資料封包的格式內,主機會發現取樣集的非連續性,並進行適當調節。

發送資料封包的延遲率包括讀取N個ADC取樣所需的週期數,以及產生資料封包表頭欄位所需的週期數。資料封包表頭欄位包括IPv4標誌、來源位址和目的地位址欄位、UDP虛擬表頭,以及IP和UDP的Chechsum。

其中,加總檢查值的計算相當困難,因為它們須要讀取整個資料封包,但其位置又在資料承載量位元組(Byte)的前面。

編寫HDL代碼須顧及資料分析

為滿足感測器網路對高頻寬、低延遲率的要求,需要一種最佳的硬體設計來達到所需的取樣率。在未進行布線規畫的情況下,一開始採用Verilog內直接建置方法,但並不能滿足125MHz的時脈速率要求,而且需要十七個時脈週期才能產生IP/UDP資料封包的表頭欄位。而在開發HDL初期設計時,ChipScope對掌握TEMAC介面的微妙之處有關鍵作用,但也阻礙了達到125MHz時脈速率的目標。額外的邏輯採集電路改變了關鍵路徑,須要手動進行布線規畫,才能達到時序收斂的目標。

關鍵路徑負責計算IP和UDP表頭的加總檢查值,因為在此設計中使用了四運算元(Four-operand)加法器將設計中各種狀態下的多個表頭欄位加總。

在此HDL設計中嘗試了一種「貪心」的排程演算法,試圖在狀態機的每個週期內盡可能完成最多作業。透過刪除ChipScope和進行布線規畫,可達到時序收斂。

HDL設計僅使用了作為資料封包傳輸緩衝區的32位元(Bit)寬Block RAM的一個傳輸埠。此處選擇32位元寬記憶體是因為這是Block RAM的原始寬度,支援Byte Enable寫入存取,進而避免對傳輸緩衝區採用「讀取-修改-寫入」的方式。

採用Byte Enable,有限狀態機(Finite State Machine, FSM)在表頭欄位位元組直接寫入的方法,則須要在RAM位址上做修改。但這個看似優秀並根據底層的賽靈思元件架構和演算法知識建置的設計方案,並不是最佳的方法,因為如果不手動布局四輸入加法器,仍不能滿足時序的要求。

因為UDP演算法已經可以使用各種C語言程式碼編寫,或者已在IP相關的修正意見書(RFC)技術文檔內編寫成虛擬程式碼,所以用C語言重新編寫UDP資料封包引擎並不繁瑣,而且有利於更深入了解資料封包表頭的處理作業。

在虛擬程式碼的基礎上編寫Verilog可以加快編碼速度,但這種方法會影響效能表現,因為缺乏全面分析所需的資料和控制流程。

利用AutoESL優化設計效能

AutoESL能夠將FIFO和RAM介面抽象化,經證明這對效能最佳化有莫大的助益。由於能夠直接用C語言進行編碼,所以可以輕鬆地將ARP和DCHP程式納入資料封包引擎中。

圖2是本文設計的流程圖。其中,HDL設計使用位元組寬度的FIFO介面連接到設計的匯聚和感測器介面,後者仍然保留Verilog設計。另外,Verilog設計利用32位元記憶體介面收集4位元組取樣資料,然後將其以32位元的文字方式儲存在RAM傳輸緩衝區內。

圖2 內置ARP和DHCP的資料封包引擎流程

AutoELS透過陣列重整(Array Reshape)指令為記憶體介面進行最佳化,這樣傳輸緩衝區雖然是用C語言程式碼編寫為8位元記憶體,卻變成了32位元記憶體。這就意味著C語言程式碼不必對表頭欄位進行大量的位元作業,否則需要移動位元才能放入32位元文字。這也減輕了低位優先(Little Endian)與高位優先(Big Endian)的位元排序問題。

藉由這種最佳化的方法,可降低TX卸載功能導致延遲率問題,可讓TX卸載功能計算資料封包加總檢查值與產生表頭欄位所需的時間,從原來用Verilog程式設計所需的十七個時脈週期降到七個時脈週期,同時也輕鬆滿足時序要求。

AutoESL未來還有更多提升空間,因為目前的版本還不能對RAM的寫入執行位元組發揮作用。位元組的記憶體支援,已納入該工具的長期發展規畫中。

由於賽靈思的Block RAM的設計本來就有雙傳輸埠,還意外地發現AutoESL的另一項最佳化功能--能夠同時對記憶體的兩個傳輸埠進行存取。此Verilog設計保留傳輸緩衝區的第二個傳輸埠,因此它連接到TEMAC的介面時可以直接在緩衝區進行存取,而無須進行任何協調作業。

藉由讓AutoESL針對真正的雙埠RAM進行最佳化,它就能夠從緩衝區的兩個不同位置進行讀取或寫入作業,進而讓產生表頭所需的週期數減半。

這種可大幅降低延遲率的方法值得花時間在Verilog建置一個專門用於記憶體第二個傳輸埠的簡單調配器,因此讓TEMAC介面可以對AutoESL占用的記憶體傳輸埠進行存取。

另外,透過指令控制傳輸緩衝區和取樣FIFO介面的位元寬度。然而,令人遺憾的是,AutoESL不會自動對設計進行最佳化,而必須嘗試各種指令,透過反覆試驗的方法找出可以帶來最佳化的指令。

該設計目標就是減少處理資料封包欄位所需的時脈週期,同時能以125MHz的時脈速率運作。

「陣列重整」和迴路「管線」指令對最佳化設計尤其重要。重整指令能夠修改RAM和FIFO介面的位元寬度,最終可讓多個表頭欄位在每個時脈週期內能夠進行平行運算處理,並能寫回到記憶體。將傳輸緩衝區的位元寬設為32,是將時脈週期數降到最少的理想作法。由於不可能強迫取樣的速度變快,因此負責發送ADC取樣的FIFO的寬度對降低總延遲率沒有影響。

環路管線指令也極為重要,因為它可指示編譯器讓來自FIFO介面壓入和彈出(Push and Pop)的環路可以來回進行。另外,如果沒有管線指令,由於調度原因,在FIFO的彈出之間,AutoESL須要占用三至二十個時脈週期。因此在記憶體間傳輸資料時,應盡量使用管線,這對降低延遲率非常重要。

賽靈思的Block RAM還提供一至三個時脈週期的可程式資料輸出延遲率。允許三個週期的讀取延遲率可實現最短的「Clock to Q」時序。要試驗不同的讀取延遲率,只須修改RAM原語或「內核」資源的「延遲率」指令。

由於AutoESL執行的排序演算法對RAM的存取增加三個時脈週期的讀取延遲率,最終,只會讓整體資料封包表頭產生週期增加一個時脈週期,而另外兩個時脈週期的記憶體延遲率可延長設計階段,最終有助於設計的布局布線。

此外,也在AutoESL設計中建置ARP與DHCP程式。由於使用Verilog程式設計工作量很大,所以先前盡量不用這種做法。雖然難度不大,但是將ARP和DHCP同時寫入Verilog所需的作業極為繁瑣,而且還要配合許多情況才能運行。例如,ARP請求/回應交換就需要七十多種狀態。Verilog有限狀態機內的一個編碼錯誤就需要好幾天才能矯正。因此,許多設計人員寧願只用CPU來執行這些日常網路作業。

UDP設計更簡潔

總之,AutoESL擅長為UDP資料封包引擎產生可合成的網表(Netlist)。AutoESL產生的模組嵌入在之前已有的ADC模組和TEMAC介面模組之間,用於產生必要的資料封包欄位和更多的作業項目。

設計人員可以把AutoESL建置的設計整合到內核設計中,並且用明導國際(Mentor Graphics)的ModelSim為設計進行模擬,以驗證其功能。

與最初的HDL設計相比,採用這種簡潔的設計可在減少合成、映對和布局布線工作量的情況下,達到時序收斂的目的,同時擁有更多的功能,包括ARP和DHCP等支援功能。

將採用Verilog編寫的原始設計與為建置「LAN MCU」和「TX Flow」模組而使用AutoESL完成的混合式設計進行比較,結果令人驚豔。表1是查閱資料表(LUT)使用情況對比表。HDL設計的TX Flow模組尺寸縮小37%以上,但AutoESL設計融入了更多功能。最引人矚目的是AutoESL設計將產生資料封包表頭所需的時脈週期數壓縮了59%。表2則列出「TX Offload」演算法的延遲率。

HDL設計的關鍵路徑是計算UDP的加總檢查值。將其與AutoESL設計進行對比,不難發現,HDL設計有十層邏輯,總路徑延遲率達6.4奈秒(ns),而AutoESL經過最佳化後,僅有三層邏輯,路徑延遲率僅為3.5奈秒。本例的HDL設計開發週期大約為一個月。用AutoESL開發的設計雖然所需的時間相當,但可以加入更豐富的功能,同時也能發揮工具的更多功能。

延遲率顯著降低

相較於HDL設計,AutoESL有一項明顯的優勢,在於它能夠進行控管和資料流程分析,並根據分析結果對運算進行重新排序,盡可能降低延遲率和增加流量。在此個案中,所使用的「貪心」演算法,盡可能在每個時脈週期內完成大量數學運算。該工具為加總檢查值的計算重新排序,這樣僅需兩個輸入加法器,但其調度方式能夠避免增加整體延遲率。

軟體編譯器本來就能完成這類工作。隨著狀態機日益複雜,相較於無所不能的編譯器,HDL設計人員處於不利地位。由於設計的時間限制,HDL設計人員一般沒有機會探討兩種以上架構方案的效果。然而,這對實現低功耗設計來說相當重要。

AutoESL工具最明顯的優勢,在於可以讓設計人員嘗試多種方案,例如修改FIFO和RAM的位寬、將大型RAM分區為多個小記憶體、對數學運算進行重新排序、將單埠RAM改為雙埠RAM,這在Verilog設計中會非常繁瑣。

在HDL設計中,每種方案也須要多花一天時間來編寫程式碼,然後修改測試平台,以驗證功能的正確性。而使用AutoESL只需要幾分鐘就可完成上述這些修改,而且整個過程非常順暢,並且無須對原始程式碼大刀闊斧地進行修改。

在Verilog中修改大型狀態機需要非常繁複的過程。AutoESL這類工具的問世不禁讓人想起微處理器設計人員告別為8086和68000等早期微處理器手動編寫微代碼狀態機的日子,並開始使用微程式設計。隨著精簡指令集(RISC)架構和硬體描述語言的誕生,微程式設計所需的技術現在幾乎已失傳,但應該汲取這個教訓,因為「抽象化」是控制複雜度的必然技巧。正如同微程式為狀態機設計提供更高一層的抽象化一樣。整體而言,AutoESL或高階合成工具也是一樣。這種層次的工具能夠讓設計人員更專注於演算法本身,而不是把重心放在那些容易出錯、難以修改並且無法滿足未來需求的低階建置工作上。

(本文作者Nathan Jachimlec任職於安捷倫、Fernando Martinez Vallina任職於賽靈思)

本站使用cookie及相關技術分析來改善使用者體驗。瞭解更多

我知道了!