今天給大家推薦今年FCCM2021上的一篇文章,介紹了一種可以在線Xilinx FPGA內(nèi)部RAM內(nèi)容的工作,重點(diǎn)是論文相關(guān)的工作還是開(kāi)源的。
摘要:XBERT是一個(gè)API和設(shè)計(jì)工具集,用于使用設(shè)備的配置路徑零成本訪問(wèn)Xilinx體系結(jié)構(gòu)上的片上SRAM塊。XBERT API是高級(jí)別的,允許開(kāi)發(fā)人員根據(jù)應(yīng)用程序源代碼中的邏輯內(nèi)存指定類似DMA的內(nèi)存內(nèi)容數(shù)據(jù)傳輸,因此基本上適用于任何針對(duì)Xilinx設(shè)備的設(shè)計(jì)。應(yīng)用程序開(kāi)發(fā)人員可以廣泛地訪問(wèn)XBERT,它隱藏了物理映射和比特流編碼的底層細(xì)節(jié)。XBERT是高效的,消耗的可重構(gòu)資源為零,對(duì)Fmax沒(méi)有影響。XBERT在Xilinx UltraScale+MPSoC Zynq上實(shí)現(xiàn)了每秒3–14兆字節(jié)(MB/s)的帶寬,并在不到0.5毫秒的時(shí)間內(nèi)完成了36Kb塊RAM中內(nèi)存的回讀和轉(zhuǎn)換。
1. 簡(jiǎn)介
今天的FPGA結(jié)構(gòu)包括大量的分布式、嵌入式RAM塊。雖然這些嵌入式RAMs最常見(jiàn)的用途是在FPGA結(jié)構(gòu)上提供和存儲(chǔ)計(jì)算過(guò)程中使用的數(shù)據(jù),但從結(jié)構(gòu)外部加載數(shù)據(jù)或輸入或檢索存儲(chǔ)為計(jì)算輸出的數(shù)據(jù)是必要的。
我們可以使用FPGA結(jié)構(gòu)資源和專用結(jié)構(gòu)輸入/輸出通道(例如AXI通道)來(lái)將數(shù)據(jù)移入和移出這些嵌入式存儲(chǔ)器,但這會(huì)消耗FPGA結(jié)構(gòu)資源以及嵌入式RAM原語(yǔ)上有限的讀/寫端口。而且,這種額外的邏輯可能會(huì)對(duì)滿足應(yīng)用程序計(jì)時(shí)要求帶來(lái)挑戰(zhàn)[1]。
這些嵌入式RAMs的內(nèi)容也可以通過(guò)現(xiàn)有的專用片上網(wǎng)絡(luò)(比特流重新配置路徑)訪問(wèn)。因此,應(yīng)該可以使用比特流重新配置路徑來(lái)在不消耗任何FPGA結(jié)構(gòu)資源的情況下將數(shù)據(jù)移入和移出這些嵌入式RAM塊。此外,在具有嵌入式處理器的SoC FPGAs上,處理器可以作為系統(tǒng)計(jì)算的一部分來(lái)管理重構(gòu)。
然而,將原始設(shè)計(jì)源中的邏輯內(nèi)存映射到FPGA結(jié)構(gòu)上的物理內(nèi)存是一項(xiàng)具有挑戰(zhàn)性的任務(wù)。一旦實(shí)現(xiàn)工具將一個(gè)較大的邏輯內(nèi)存映射到多個(gè)較小的內(nèi)存上,那么識(shí)別哪個(gè)物理BRAM原語(yǔ)保存特定的邏輯數(shù)據(jù)對(duì)于應(yīng)用程序編程人員來(lái)說(shuō)是不容易發(fā)現(xiàn)的,并且每次更改設(shè)計(jì)源并將其重新映射到FPGA時(shí)都可能發(fā)生變化。此外,用于比特流編程的數(shù)據(jù)格式與存儲(chǔ)數(shù)據(jù)的邏輯格式不同邏輯存儲(chǔ)器的位在BRAM初始化字符串中沒(méi)有整齊地按升序排列,并且這些初始化字符串中的位隨后分散在多個(gè)配置幀中。
為了滿足這些需求,我們創(chuàng)建了Xilinx Bitstream Embedded RAM Transmission(XBERT)API,以提供一個(gè)高級(jí)接口來(lái)讀取和寫入邏輯內(nèi)存的內(nèi)容,正如應(yīng)用程序開(kāi)發(fā)人員在源代碼級(jí)(如RTL、HLS、IP塊)設(shè)計(jì)中看到的那樣[1]。
透析(Transfusion)操作是讀寫操作的結(jié)合,它提取舊的BRAM內(nèi)容并提供新的BRAM內(nèi)容。重要的是,這些合并的輸入操作可以比使用單獨(dú)的讀寫操作更有效。
我們的自動(dòng)工具流提取有關(guān)邏輯內(nèi)存如何映射到物理嵌入式RAMs的信息,以允許XBERT API對(duì)這些內(nèi)存進(jìn)行操作。我們的API能夠在幾分之一毫秒內(nèi)讀取結(jié)果數(shù)據(jù)并將其轉(zhuǎn)換為邏輯內(nèi)存格式,從而提供以MB/s為單位的有效數(shù)據(jù)傳輸速率。這不如專用高速鏈路(例如,5 GB/s的AXI通道)快,但對(duì)于不經(jīng)常訪問(wèn)的內(nèi)存(例如,在啟動(dòng)時(shí)使用唯一數(shù)據(jù)編程或在程序完成時(shí)恢復(fù)數(shù)據(jù))或中等帶寬(例如,周期性參數(shù)調(diào)整)足夠,具體可見(jiàn)節(jié)II和III-F。值得注意的是,這是在不減少Fmax或FPGA資源消耗的情況下實(shí)現(xiàn)的。
我們的貢獻(xiàn)包括:
一個(gè)API,用于提供對(duì)存儲(chǔ)在FPGA結(jié)構(gòu)的嵌入式RAM中的內(nèi)存的邏輯訪問(wèn)(第五節(jié))
UltraScale+MPSoC Zynq的XBERT API的開(kāi)源實(shí)現(xiàn),包括提取邏輯?單個(gè)內(nèi)存位的物理映射和運(yùn)行時(shí)支持讀取和寫入正在運(yùn)行的FPGA內(nèi)存內(nèi)容(在[2]處在線)
邏輯到物理位映射的定制壓縮技術(shù),將轉(zhuǎn)換表大小從兆字節(jié)減少到千字節(jié)(第七節(jié))
基于表格的加速,可減少單個(gè)BRAM轉(zhuǎn)換時(shí)間,與DMA傳輸時(shí)間(第八節(jié))
API實(shí)現(xiàn)性能的表征(第九節(jié))
2. 用場(chǎng)景
XBERT提供的一般功能有許多用例。編程BRAM配置的覆蓋架構(gòu)是不經(jīng)常修改嵌入式RAM內(nèi)容的一個(gè)明顯需求,包括更新嵌入式軟處理器中的程序內(nèi)存內(nèi)容,如RISC-V處理器核[3]、[4]、自定義VLIW[5]、自定義的VLIW[5]、[6]和向量[7]、[8]處理器。這種需要加載的指令也適用于更專業(yè)的覆蓋結(jié)構(gòu)的加載配置,如專用的FSM評(píng)估器[9]、[10]和神經(jīng)網(wǎng)絡(luò)[11]或模擬器[12]。
另一個(gè)用例是FPGA構(gòu)建塊的高速單元測(cè)試,在這里需要以全速率向被測(cè)模塊提供數(shù)據(jù)并捕獲結(jié)果。這可以用一個(gè)存儲(chǔ)器將數(shù)據(jù)源輸入被測(cè)模塊,用另一個(gè)存儲(chǔ)器記錄結(jié)果。類似地,在使用內(nèi)部邏輯分析器(ILA)或跟蹤緩沖區(qū)[13]、[14]進(jìn)行實(shí)時(shí)調(diào)試以在操作期間捕獲數(shù)據(jù)時(shí),我們?cè)跍y(cè)試后卸載這些數(shù)據(jù)的速度通常并不重要。
最后,在極端情況下,XBERT功能可以提供一種廉價(jià)的方式來(lái)支持當(dāng)前FPGA上的高級(jí)抽象,如CoRAM[15]。CoRAM提議增加專用的基礎(chǔ)設(shè)施來(lái)管理嵌入式RAMs和中央內(nèi)存之間的數(shù)據(jù)移動(dòng),并演示了在FPGA上構(gòu)建覆蓋網(wǎng)絡(luò)的原型。使用XBERT,可以使用現(xiàn)有的重配置路徑硬件支持提供相同的功能,而無(wú)需增加覆蓋邏輯。
3. XBERT:概述、挑戰(zhàn)和解決方案
本節(jié)介紹XBERT,包括XBERT這樣的系統(tǒng)面臨的挑戰(zhàn)和操作要求,以及解決這些問(wèn)題的方法和由此帶來(lái)的好處。
》3.1 基本單BRAM操作
首先,考慮一下將映射到單個(gè)36Kb BRAM的簡(jiǎn)單邏輯內(nèi)存的內(nèi)容進(jìn)行更改的簡(jiǎn)單用例。如果邏輯內(nèi)存恰好是XPM實(shí)例化的內(nèi)存,那么在主機(jī)上運(yùn)行的Xilinx的UpdateMem程序可以更改完整比特流中的BRAM。運(yùn)行Update Mem需要4秒來(lái)更改比特流以反映新的BRAM內(nèi)容,而將完整的比特流加載到XCU3EG需要9毫秒。這既慢又需要使用單獨(dú)的主機(jī)。
使用XBERT中最簡(jiǎn)單的write API(bert_write),我們可以在Zynq的嵌入式APU內(nèi)核上運(yùn)行代碼時(shí)執(zhí)行更新,并在1.04毫秒(快3900倍)內(nèi)編寫B(tài)RAM。這包括0.71 ms用于轉(zhuǎn)換位(將邏輯存儲(chǔ)器位描述轉(zhuǎn)換為部分比特流)和0.25 ms用于通過(guò)Zynq PCAP將部分比特流寫入設(shè)備;寫入速度達(dá)到3.9MB/s帶寬。重要的是,這個(gè)XBERT寫操作適用于任何邏輯內(nèi)存,而不僅僅是那些用XPM實(shí)例化的內(nèi)存。
》3.2 基于表的轉(zhuǎn)換、壓縮和加速
UpdateMem運(yùn)行時(shí)使用完整的Xilinx設(shè)備數(shù)據(jù)庫(kù)(用于部件)和完整的設(shè)計(jì)檢查點(diǎn)數(shù)據(jù)集(用于設(shè)計(jì)),XBERT將此信息替換為一個(gè)最小的轉(zhuǎn)換表,該表描述每個(gè)邏輯內(nèi)存位映射到比特流的位置。XBERT中的原始轉(zhuǎn)換表最初需要238KB,但是使用壓縮可以將其減少到2.3KB(第七節(jié))。
上述1.04 ms XBERT時(shí)間的主要組成部分是翻譯(0.71 ms),主要包括從邏輯存儲(chǔ)器圖像計(jì)算各個(gè)位的比特流位置。當(dāng)我們向XBERT(第八節(jié))添加一個(gè)加速的、基于表的多位翻譯功能時(shí),我們可以將其減少到0.28毫秒,因此整個(gè)寫操作在0.62毫秒內(nèi)完成,吞吐量為6.59 MB/s—大約是未加速情況下的兩倍。
》3.3 Transfusion-組合操作以提高性能
談到單個(gè)BRAM內(nèi)存的最小DMA傳輸時(shí)間,我們注意到它很大(0.25毫秒),部分原因是寫入發(fā)生在幀中,需要為UltraScale+體系結(jié)構(gòu)中共享一幀的所有12個(gè)內(nèi)存寫入數(shù)據(jù)(圖3)。如果我們需要在一個(gè)幀中寫入多個(gè)BRAM,或者因?yàn)橐粋€(gè)邏輯內(nèi)存使用多個(gè)BRAM,或者因?yàn)槲覀冃枰獙懭攵鄠€(gè)恰好共享一個(gè)物理幀的邏輯內(nèi)存,那么我們可以減少每個(gè)BRAM的DMA傳輸時(shí)間。在極端情況下,我們將每BRAM DMA傳輸成本降低了12倍,約為0.021 ms,因此每BRAM總寫入成本約為0.32 ms(或11.75 MB/s的吞吐量,約為單次加速吞吐量的兩倍)。因此,有一個(gè)scatter-gather接口是非常有效的,它允許我們指定要作為單個(gè)操作寫入的完整邏輯內(nèi)存集,這樣API就可以最小化所需的幀寫入次數(shù)。我們的transfuse API接口提供了此功能(第五節(jié))。
雖然有寫使能允許我們一次在一個(gè)幀中寫入一個(gè)36Kb的BRAM,但是沒(méi)有寫使能控制在一個(gè)36Kb的BRAM中獨(dú)立地寫入兩個(gè)18Kb的內(nèi)存。要單獨(dú)寫入一個(gè)18Kb內(nèi)存,我們可能需要先讀取整個(gè)幀,以便在塊中保留伙伴18Kb內(nèi)存的值。XBERT transfuse API可以將此回讀與同一物理幀(秒)中其他邏輯內(nèi)存的讀取結(jié)合起來(lái)(第五節(jié))。
》3.4 處理較大內(nèi)存-邏輯到物理內(nèi)存映射
為了簡(jiǎn)單起見(jiàn),上面的示例使用了只映射到單個(gè)BRAM的邏輯內(nèi)存。在實(shí)踐中,邏輯記憶常常映射到多個(gè)物理內(nèi)存。當(dāng)這種情況發(fā)生時(shí),有很多選擇如何將位打包到內(nèi)存中。例如,在一個(gè)32×10000內(nèi)存,我們已經(jīng)看到Vivado將內(nèi)存的底部18b([17:0])映射為5個(gè)18×2048RAMB36s,下一個(gè)9b([26:18])到三個(gè)9×4096RAMB36s,下一個(gè)4b([30:27])到兩個(gè)4×8192 RAMB36s,最后一位([31])為1×16384RAM36s;這種非均勻映射只使用11個(gè)RAMB36,而在其他設(shè)計(jì)中,我們看到Vivado將一個(gè)大小類似的內(nèi)存映射到一組16個(gè)RAMB36內(nèi)存,每個(gè)內(nèi)存寬2位,深16K個(gè)字。
最后,對(duì)于小于單個(gè)BRAM的內(nèi)存,Vivado可能會(huì)將高階地址位綁定到0以外的值,這意味著內(nèi)存的邏輯0位置不會(huì)從正常預(yù)期的位置(物理BRAM的幀集的第一幀)開(kāi)始。
為了解決這些復(fù)雜而繁瑣的物理映射問(wèn)題,XBERT工具流自動(dòng)從Vivado Design CheckPoint(DCP)文件或項(xiàng)目中提取這些映射細(xì)節(jié),作為其邏輯到物理內(nèi)存映射功能的一部分。因此,應(yīng)用程序開(kāi)發(fā)人員不需要處理這些問(wèn)題,他們能夠?qū)iT處理邏輯內(nèi)存內(nèi)容,XBERT對(duì)他們隱藏了許多映射細(xì)節(jié)(第五節(jié))。
》3.5 XBERT設(shè)計(jì)流程摘要
圖1示出了XBERT的主機(jī)側(cè)準(zhǔn)備工具流程。從頂部開(kāi)始,對(duì)用戶的設(shè)計(jì)(以設(shè)計(jì)檢查點(diǎn)的形式最少地表示)進(jìn)行處理,以提取原始設(shè)計(jì)源中包含的邏輯內(nèi)存的信息,從而生成一個(gè)MDD文件(第4-D節(jié))。然后將其與從Xilinx生成的.ll文件中提取的比特流信息結(jié)合起來(lái),為設(shè)計(jì)創(chuàng)建邏輯到物理內(nèi)存映射信息的完整表示(mydesign_uncompressed.{c,h})。然后對(duì)其進(jìn)行壓縮和可選的加速,以生成一個(gè)mydesign.c文件,其中包含作為c數(shù)據(jù)結(jié)構(gòu)的該信息的壓縮版本。
在圖的底部,最終的XBERT應(yīng)用程序由三組源代碼組成:(1)XBERT運(yùn)行時(shí)源代碼(bert.c),(2)mydesign.c文件,以及(3)用戶的應(yīng)用程序代碼(application.c)。
這與XBERT的擴(kuò)展xilfpga庫(kù)(第六節(jié)) 進(jìn)入最終可執(zhí)行的應(yīng)用程序。
圖1:XBERT工具流程
》3.6 一個(gè)充分激勵(lì)的例子
考慮開(kāi)發(fā)一個(gè)包含四個(gè)獨(dú)立存儲(chǔ)器的哈夫曼編碼加速器。這個(gè)哈夫曼編碼器接收字節(jié)流,并通過(guò)將每個(gè)字節(jié)映射到一個(gè)可變長(zhǎng)度的代碼來(lái)壓縮它。而且,為了獲得好的壓縮效果,哈夫曼碼應(yīng)該調(diào)整到被編碼的數(shù)據(jù)。
我們將編碼器設(shè)計(jì)為使用編碼表(內(nèi)存#1)進(jìn)行任何編碼,并且可以在更改編碼時(shí)使用XBERT更新其內(nèi)容。HDL源代碼中的編碼表是只讀的,但是我們可以使用bert_write來(lái)加載它的內(nèi)容。加載表需要1.1毫秒。如果沒(méi)有XBERT,我們將需要使用AXI端口來(lái)執(zhí)行加載,這樣會(huì)更快,但會(huì)在設(shè)計(jì)中添加LUT和寄存器(表1)。
表1:在HUFFMAN示例中添加AXI訪問(wèn)對(duì)內(nèi)存的影響
當(dāng)我們第一次設(shè)計(jì)編碼器時(shí),我們通常希望在將數(shù)據(jù)源和數(shù)據(jù)使用者添加到設(shè)計(jì)中之前測(cè)試它的功能和速度。我們可以通過(guò)添加一個(gè)內(nèi)存來(lái)保存輸入數(shù)據(jù)(內(nèi)存2)和一個(gè)內(nèi)存來(lái)存儲(chǔ)輸出數(shù)據(jù)(內(nèi)存3)。使用XBERT我們不需要其他東西。我們可以使用bert_write將編碼器要壓縮的新數(shù)據(jù)加載到輸入存儲(chǔ)器中,并使用bert_read恢復(fù)壓縮的輸出。
我們還添加了一個(gè)直方圖內(nèi)存,使用256個(gè)元素的內(nèi)存(內(nèi)存4)捕獲輸入數(shù)據(jù)的特征。使用bert_read,我們可以在0.45毫秒內(nèi)讀回這個(gè)內(nèi)存的內(nèi)容。如果我們每個(gè)周期壓縮一個(gè)字節(jié),這個(gè)直方圖需要在每個(gè)周期上執(zhí)行讀寫操作,這意味著它的兩個(gè)端口都被使用。對(duì)于提供回讀的非XBERT設(shè)計(jì),它需要共享一個(gè)端口或復(fù)制內(nèi)存以有效地提供另一個(gè)讀端口。對(duì)于XBERT,兩者都不是必需的。
使用XBERT我們可以讀取或?qū)懭朐O(shè)計(jì)中的四個(gè)存儲(chǔ)器中的任何一個(gè)。我們可以讀取直方圖內(nèi)存內(nèi)容,根據(jù)輸入數(shù)據(jù)流計(jì)算新的編碼表,然后將新的編碼表寫回到設(shè)計(jì)中,所有這些都在1.2ms內(nèi)完成。
選項(xiàng)卡。我展示了在設(shè)計(jì)中添加AXI接口的影響(面積,F(xiàn)max)。我們?cè)贏XI子系統(tǒng)和Huffman解碼器之間使用MMCM,這樣后者就可以以最大時(shí)鐘速率運(yùn)行,而不受最大AXI時(shí)鐘速率333MHz的限制。由于這個(gè)Huffman示例很小,因此提供對(duì)BRAMs的訪問(wèn)的Fmax影響很小。在更大、高度擁擠的設(shè)計(jì)中,[1]聲稱消除AXI-BRAM訪問(wèn)可以實(shí)現(xiàn)高達(dá)63%的Fmax改進(jìn)(第4-C節(jié))。
4. 相關(guān)工作
》4.1 物理BRAM操作應(yīng)用程序和工具
許多工具都利用了這樣的情況,即它們可以提供有用的功能來(lái)處理原始BRAMs,而不需要映射或轉(zhuǎn)換回邏輯級(jí)別。早在2000年,Xilinx就為嵌入式RAM的部分重新配置回讀和重新加載提供了實(shí)驗(yàn)性的低級(jí)別支持[16],[17],主要用于內(nèi)存回讀和清理[18]。最近,ReconOS使用比特流讀寫進(jìn)行多任務(wù)處理[19](通過(guò)比特流加載和卸載BRAM內(nèi)容)。Metawire使用比特流將數(shù)據(jù)從BRAM移動(dòng)到BRAM,以提供片上網(wǎng)絡(luò)(NoC)功能;由于它們控制著B(niǎo)RAM映射并從一個(gè)BRAM轉(zhuǎn)移到另一個(gè)BRAM,因此它們避免了從物理映射到邏輯映射的轉(zhuǎn)換[20]。
類似地,有幾部著作將直接BRAM寫入特定的應(yīng)用程序,包括[21]-[23]。
》4.2 物理比特流API
最近的工作希望為物理層的比特流操作提供一個(gè)API。BITMAN pro提供了一個(gè)通用的物理層訪問(wèn)機(jī)制,可以訪問(wèn)BRAM內(nèi)容通過(guò)change_BRAM_content(X,Y,new_config)API[24]。與上述工具一樣,它需要一些更高級(jí)別的接口或手動(dòng)開(kāi)發(fā)操作干預(yù)來(lái)確定哪些BRAM位置需要更改,并格式化配置數(shù)據(jù),包括將邏輯位洗牌到它們?cè)谖锢砼渲糜成渲械奈恢谩?/p>
類似地,最近在[25]中的工作提倡使用比特流回讀和編輯來(lái)讀寫B(tài)RAM內(nèi)容的方法,并演示了如何在BRAM之間復(fù)制數(shù)據(jù)。但是,它不涉及識(shí)別哪些物理內(nèi)存用于特定的邏輯內(nèi)存。它也沒(méi)有提供完整的描述或高級(jí)工具,允許開(kāi)發(fā)人員將其HLS或RTL邏輯內(nèi)存內(nèi)容映射到比特流中,或者提取比特流內(nèi)容并重建HLS或RTL內(nèi)存的狀態(tài)。
》4.3 專用邏輯內(nèi)存操作
Maxeler探索使用比特流路徑來(lái)加載和讀取他們的“映射內(nèi)存”,而不是單獨(dú)的低速總線[1]。他們表明,去掉低速總線及其對(duì)結(jié)構(gòu)資源的相關(guān)需求,可以將他們?cè)O(shè)計(jì)的性能提高高達(dá)63%。他們的比特流接口實(shí)現(xiàn)了高達(dá)2MB/s的數(shù)據(jù)傳輸帶寬。
Maxeler的用法可能與XBERT提供的最為相似。然而,Maxeler(a)僅將此BRAM路徑用于編譯器內(nèi)部生成的內(nèi)存的特定用途,(b)不提供可供開(kāi)發(fā)人員用于任何內(nèi)存或任何工具鏈的通用API(c)他們的工具必須控制邏輯內(nèi)存到BRAMs的映射,因?yàn)樗麄儧](méi)有足夠的信息來(lái)確定Xilinx工具如何將邏輯內(nèi)存映射到物理內(nèi)存。
類似地,Xilinx Vivado提供了對(duì)更改比特流中配置存儲(chǔ)器初始值的支持,主要是為了支持微LAZE處理器的指令存儲(chǔ)器[26]。這包括一個(gè)BRAM內(nèi)存映射信息(MMI)文件,該文件記錄用于支持MicroBlaze和Xilinx參數(shù)化宏(XPM)內(nèi)存的物理BRAM,以及一個(gè)UpdateMEM工具,該工具可以使用邏輯內(nèi)存文件中的數(shù)據(jù)更新比特流[27]。Vivado生成的MMI并沒(méi)有覆蓋設(shè)計(jì)中的所有邏輯內(nèi)存,UpdateMEM只生成一個(gè)完整的比特流。
XBERT通過(guò)提供對(duì)比特流讀寫路徑的開(kāi)源邏輯級(jí)訪問(wèn),填補(bǔ)了上述相關(guān)工作中的所有空白。它容納了所有的設(shè)計(jì),所有的記憶,以及所有通過(guò)DCPs的工具流。
》4.4 現(xiàn)有的比特流操作支持
有許多工具可用于創(chuàng)建比特流操作工具。XBERT系統(tǒng)在一定程度上是基于其中一些。
Xilinx工具長(zhǎng)期以來(lái)一直為內(nèi)存生成邏輯位置(LL)文件,作為比特流回讀生成的一部分[28]。LL文件包含物理BRAM中每個(gè)數(shù)據(jù)位的幀和位位置,但不提供有關(guān)邏輯內(nèi)存以及如何將邏輯內(nèi)存映射到多個(gè)物理BRAM塊的映射信息。盡管如此,LL文件對(duì)于破譯XBERT內(nèi)的BRAM的幀和位位置是有用的,如圖1所示。
X-Ray項(xiàng)目[29]和最近的U-Ray項(xiàng)目[30]提供了將Xilinx 7系列和UltraScale+設(shè)備中的配置位映射到幀和位位置的數(shù)據(jù)庫(kù)。它們不包含特定設(shè)計(jì)中邏輯到物理內(nèi)存映射的信息,但提供了用于比特流編碼的信息和工具(了解比特流中物理內(nèi)存位的位置)。
在X-Ray項(xiàng)目的基礎(chǔ)上,BYU開(kāi)發(fā)了一個(gè)開(kāi)源工具prjxray-bram-patch[31],它的作用與Vivado的UpdateMEM類似,但適用于設(shè)計(jì)中的所有邏輯內(nèi)存和所有設(shè)計(jì)流。bram-patch工具定義了一個(gè)內(nèi)存描述數(shù)據(jù)(MDD)文件,該文件的作用與Xilinx MMI文件類似。MDD文件源自使用Tcl的Vivado設(shè)計(jì),它為設(shè)計(jì)中的每個(gè)邏輯內(nèi)存描述了邏輯內(nèi)存映射到的物理內(nèi)存集合、邏輯內(nèi)存位在物理內(nèi)存之間的分區(qū)方式以及位如何打包到物理RAMB原語(yǔ)的INIT字符串中。XBERT系統(tǒng)將此信息用作邏輯到物理映射步驟的一部分(圖1)。
5. XBERT API
XBERT設(shè)計(jì)用于在Zynq SoC上的嵌入式APU內(nèi)核上運(yùn)行。如圖2所示,它提供了邏輯級(jí)接口,高于由xilfpga提供的接口或由諸如BITMAN的物理級(jí)比特流操作工具提供的接口[24]。它通過(guò)擴(kuò)展xilfpga來(lái)實(shí)現(xiàn)這一點(diǎn),并為BRAM寫入提供部分重新配置支持和命令生成(第六節(jié))。
圖2:XBERT的API分層
注:Xilinx提供的淺紅色;本工程提供淺藍(lán)色;來(lái)自[24]的淺綠色。
入門級(jí)XBERT接口是一對(duì)簡(jiǎn)單的例程,提供一個(gè)類似DMA的接口來(lái)讀取或?qū)懭胝麄€(gè)邏輯內(nèi)存。
這些例程處理內(nèi)存的幀格式和邏輯格式之間的位洗牌,以及執(zhí)行所需的部分重新配置讀寫。
為了支持這些API調(diào)用,XBERT預(yù)處理工具處理MDD文件(第IV-D節(jié))生成文件mydesign.h和mydesign.c(圖1)。其中包括設(shè)計(jì)中特定內(nèi)存的C代碼定義,包括邏輯到物理的轉(zhuǎn)換表。
上述簡(jiǎn)單API的一個(gè)限制是,每個(gè)讀或?qū)懻{(diào)用首先執(zhí)行邏輯到物理內(nèi)存的轉(zhuǎn)換,然后對(duì)設(shè)備執(zhí)行比特流讀或?qū)懖僮?。如果?yīng)用程序需要讀取或更新映射到同一配置幀的多個(gè)不同邏輯內(nèi)存,則這可能是低效的。
為了實(shí)現(xiàn)更高效的傳輸,XBERT還提供了一個(gè)API,可以讀寫一組多個(gè)內(nèi)存,就像分散-聚集DMA操作一樣。這是bert_transfuse()調(diào)用,允許XBERT執(zhí)行一組幀讀取、轉(zhuǎn)換,然后執(zhí)行一組幀寫入,覆蓋可能共享一組幀的所有邏輯內(nèi)存:
Bert_transfuse例程使用一個(gè)數(shù)組來(lái)描述邏輯內(nèi)存集合上的操作。為了描述每個(gè)transfusion操作,它使用了一個(gè)結(jié)構(gòu)(bert_meminfo)。結(jié)構(gòu)指定了內(nèi)存、操作(讀或?qū)懀┮约拔覀冋趦?nèi)存中讀或?qū)懙倪壿嫷刂贩秶?。為了支持?4b更寬的數(shù)據(jù),這支持一個(gè)數(shù)組,每個(gè)數(shù)組槽有多個(gè)數(shù)據(jù)字。并且,通過(guò)指定起始地址和長(zhǎng)度,我們?cè)试S對(duì)邏輯內(nèi)存中的字子集進(jìn)行操作。這允許訪問(wèn)和更新與保存邏輯存儲(chǔ)器的數(shù)據(jù)的BRAMs相關(guān)聯(lián)的幀的子集,當(dāng)僅需要讀取或?qū)懭氪鎯?chǔ)器的一部分時(shí),這是更有效的。傳輸操作還將寫入數(shù)據(jù)集與PCAP控制指令一起排列,以便可以使用單個(gè)DMA寫入傳輸來(lái)執(zhí)行這些操作,從而最小化DMA設(shè)置的開(kāi)銷。
APIs假定執(zhí)行讀寫操作是安全的。應(yīng)用程序負(fù)責(zé)將計(jì)算置于安全狀態(tài),即在讀或?qū)戇^(guò)程中不寫入內(nèi)存。例如,使用Vivado/VitisHLS生成的標(biāo)準(zhǔn)Xilinx IP塊級(jí)接口協(xié)議[32],可以監(jiān)視要完成的塊(ap_done),執(zhí)行XBERT操作,然后重新啟動(dòng)模塊(ap_start)。
6. 部分重構(gòu)
部分重配置是在不影響剩余資源運(yùn)行的情況下加載一部分FPGA資源的配置數(shù)據(jù)。在現(xiàn)代Xilinx設(shè)備中,配置的原子單元是沿FPGA列組織的幀。在Xilinx UltraScale+系列中,每幀有93個(gè)32b字。由于BRAM數(shù)據(jù)只占總比特流的一小部分,因此使用部分重新配置僅訪問(wèn)BRAM幀與完整的比特流讀寫相比減少了比特流讀寫時(shí)間。
在現(xiàn)代FPGA設(shè)備中,嵌入式ram被放置在列中。UltraScale+系列具有36Kb內(nèi)存(RAMB36),每個(gè)內(nèi)存可以交替配置為一對(duì)18Kb內(nèi)存(RAMB18)。Xilinx UltraScale+系列設(shè)備中的每個(gè)幀包含12個(gè)RAMB36存儲(chǔ)器[33,第8章,配置幀],每個(gè)RAMB36具有144b,兩個(gè)RAMB18中的每個(gè)具有72b。覆蓋BRAM組需要256幀(參見(jiàn)圖3)。幀中每個(gè)BRAM的144b組被分組為240b塊。在大致位于240b塊中間的幀中,每個(gè)144b RAMB36組有一個(gè)寫使能位。寫入允許一次更新單個(gè)BRAM36,但始終需要以幀為單位傳輸數(shù)據(jù)。BRAM數(shù)據(jù)幀與保持路由或LUT配置的幀是分開(kāi)的。
Zynq設(shè)備包括一個(gè)處理器配置訪問(wèn)端口(PCAP),允許嵌入式處理器讀寫配置幀。對(duì)于高速接入,處理器可以配置DMA數(shù)據(jù)傳輸?shù)絇CAP以執(zhí)行部分重新配置操作。UltraScale+PCAP的帶寬為4B,峰值工作頻率為200 MHz,最高支持800 MB/s[33,第8章,配置時(shí)間]。
Xilinx提供了xilfpga庫(kù)[34](圖2),用于在Zynq UltraScale+組件上執(zhí)行DMA比特流傳輸。它允許對(duì)包含到PCAP的控制命令頭的.bit文件進(jìn)行完全比特流加載、回讀和部分比特流加載。
圖3:UltraScale+BRAM內(nèi)容的框架組織
XBERT提供了xilfpga API中例程的擴(kuò)展版本(圖2)。xilfpga沒(méi)有提供一個(gè)基本的比特流回讀操作,因此我們修改了讀操作以同時(shí)接收幀地址和幀數(shù)。XBERT還提供了write的一個(gè)版本,它接受原始幀數(shù)據(jù)并填充配置命令來(lái)設(shè)置幀地址和指定寫操作,因?yàn)閷⒃紟瑪?shù)據(jù)轉(zhuǎn)換為適當(dāng)?shù)牟糠直忍亓餍枰@些命令。這種擴(kuò)展是支持寫操作所必需的,因?yàn)槲覀冋谏勺约旱膸⑶覜](méi)有通常由Vivado生成比特流時(shí)生成的比特流配置命令頭。
由于缺乏流量控制,F(xiàn)PGA讀回操作只能以低于200 MHz峰值操作(秒)的速率可靠運(yùn)行(第六節(jié)。2019.2 xilfpga版本中的默認(rèn)配置使用PCAP時(shí)鐘發(fā)生器配置(PCAP _CTRL(CRL _APB)寄存器)將時(shí)鐘設(shè)置為23.8 MHz,最高吞吐量為95 MB/s。我們的經(jīng)驗(yàn)表明,150MHz可能工作可靠,最高吞吐量為600MB/s。
7. 壓縮轉(zhuǎn)換表
邏輯到物理轉(zhuǎn)換表(第三節(jié)) 可能很大。如果我們簡(jiǎn)單地在一個(gè)BRAM中為每個(gè)位存儲(chǔ)一個(gè)32b幀地址和一個(gè)16b位位置,那么轉(zhuǎn)換表至少是48位× 比我們希望繪制的BRAM數(shù)據(jù)總量還要大。幸運(yùn)的是,有一些結(jié)構(gòu)。通常情況下,當(dāng)多個(gè)位在同一幀中時(shí),我們不需要為每個(gè)位存儲(chǔ)幀。這樣可以節(jié)省3倍。
為了進(jìn)一步壓縮,我們利用了位位置在幀間重復(fù)的方式。為了說(shuō)明這一點(diǎn),我們先來(lái)考慮一個(gè)簡(jiǎn)單的BRAM設(shè)計(jì)案例。單個(gè)幀將在其144位中保存一定數(shù)量的邏輯字。在72b寬的邏輯存儲(chǔ)器的情況下,這可以是2個(gè)邏輯字;對(duì)于8b寬的邏輯內(nèi)存,這可能是16個(gè)邏輯字。將Wframe定義為該值(上面的2或16)。對(duì)于每個(gè)連續(xù)的Wframe字組,幀內(nèi)的偏移位置是相同的,這允許我們通過(guò)算法確定幀偏移量(邏輯地址/Wframe),并重用幀內(nèi)(最多144)位到幀內(nèi)偏移量的單個(gè)位映射。對(duì)于這種單BRAM設(shè)計(jì),這意味著我們只需要存儲(chǔ)一個(gè)幀地址(基址)和(最多)144位偏移地址(對(duì)于一幀中的2976位可以使用12b,但是我們舍入到16b)。所以,我們最多需要32+144×16=2336b而不是48×36864=1.7 Mbits,無(wú)壓縮。
一般來(lái)說(shuō),我們必須支持邏輯內(nèi)存映射到物理內(nèi)存的各種方法。這可能意味著并行組織多個(gè)BRAMs以支持邏輯字寬度(例如,8個(gè)BRAMs,每個(gè)BRAMs提供32b字的4b),多個(gè)BRAMs覆蓋不同的地址范圍以處理深度內(nèi)存(例如,2個(gè)BRAMs覆蓋36x2048內(nèi)存,其中一個(gè)處理地址0到1023,另一個(gè)處理地址1024到2047),或其組合。甚至在某些情況下,組件BRAMs具有不均勻的子寬度和子深度(例如第三節(jié)) 是的。因此,一般的壓縮情況更需要處理這些額外的不規(guī)則性。盡管如此,幀之間還是有規(guī)律性的,可以用算法來(lái)描述。這使我們能夠概括單個(gè)BRAM觀測(cè)值,形成一個(gè)通用的壓縮策略。利用這些觀察,我們顯著地壓縮了翻譯表(表3)。
8. 加速翻譯
正如我們?cè)诒?中看到的,一旦我們加快了讀DMA的速度,翻譯時(shí)間就比DMA傳輸時(shí)間慢。即使使用預(yù)編譯的表,代碼仍然是一次提取和插入一位。我們實(shí)現(xiàn)了一種多位加速轉(zhuǎn)換,其中我們預(yù)先計(jì)算字(或幀)中的位序列(例如,一個(gè)字節(jié))的影響,以創(chuàng)建要應(yīng)用于幀(或字)的位向量,并將它們存儲(chǔ)在表中。
這減少了處理器周期,但需要更大的轉(zhuǎn)換表。我們目前的實(shí)現(xiàn)支持這些針對(duì)單個(gè)BRAM存儲(chǔ)器的轉(zhuǎn)換表。
9. 評(píng)價(jià)
如第三章和貫穿本文的重點(diǎn),XBERT傳輸?shù)拇笮『托阅芨叨纫蕾囉谠O(shè)計(jì),依賴于API的使用,并且受到我們的優(yōu)化的影響。在本節(jié)中,我們將評(píng)估API在多個(gè)場(chǎng)景中的性能,以具體描述這些不同場(chǎng)景的性能影響。
》9.1 方法論
我們的實(shí)驗(yàn)使用Vivado 2018.3,包括SDK。嵌入式ARM處理器代碼編譯-O3。實(shí)驗(yàn)在Ultra96 v2板上進(jìn)行,該板包括一個(gè)包含216個(gè)RAMB36的XCZU3EG。設(shè)計(jì)是在裸機(jī)配置上運(yùn)行的。我們集成了2019.2版的xilfpga源代碼,原因是2018.3版的xilfpga存在缺陷。
一個(gè)主要的性能指標(biāo)是有效吞吐量。有效吞吐量解釋了這樣一個(gè)事實(shí),即有用的數(shù)據(jù)只是在幀中傳輸?shù)臄?shù)據(jù)的子集。例如,如果我們只想在UltraScale+設(shè)備幀中包含一個(gè)RAMB36的內(nèi)容,則每幀可獲得144個(gè)相關(guān)位,但必須傳輸整個(gè)2976位幀。
為了說(shuō)明典型的應(yīng)用場(chǎng)景,我們提供了兩個(gè)完整的設(shè)計(jì)。這些給出了幀如何從多個(gè)邏輯存儲(chǔ)器共享BRAMs的一些指示。
哈夫曼編碼-我們的Verilog設(shè)計(jì)來(lái)自第三章F節(jié)。它有4個(gè)邏輯內(nèi)存,消耗4個(gè)18和3903個(gè)LUT。每個(gè)邏輯內(nèi)存都可以放在一個(gè)內(nèi)存中。
翻譯-演示用的網(wǎng)表來(lái)自于Rosetta HLS基準(zhǔn)電路 [35]。它有11個(gè)邏輯存儲(chǔ)器,消耗41個(gè)ramb36、9個(gè)ramb18和11109個(gè)LUTs。一些內(nèi)存是大的,需要很多的BRAMs。有些內(nèi)存在沒(méi)有定義位的地方有間隙。
》9.2 結(jié)果
① 原始比特流數(shù)據(jù)傳輸
表2顯示原始比特流傳輸時(shí)間和原始有效吞吐量。這將顯示DMA傳輸性能和含義,而不需要翻譯所需的時(shí)間,這將在下一節(jié)中分開(kāi)。注意,訪問(wèn)一個(gè)幀中的所有BRAM(單個(gè)BRAM幀集行)可以提供最高的有效吞吐量。由于BRAM幀中的大多數(shù)位是BRAM數(shù)據(jù)位,因此有效帶寬超過(guò)原始帶寬的一半。請(qǐng)注意,即使我們關(guān)心芯片上所有BRAM中的每一位BRAM,該有效帶寬也高于完整的比特流讀寫,因?yàn)椴糠肿x取只是讀取保存BRAM數(shù)據(jù)的幀。
表2:XCZU3EG上的原始比特流讀寫時(shí)間
注:“幀集”是包含單個(gè)BRAM的內(nèi)容的256幀的集合(圖3)。
24MHz是xilfpga中的讀取速度;150MHz是我們能夠可靠運(yùn)行DMA回讀的最高速度。
② 翻譯
表III報(bào)告了轉(zhuǎn)換表的大小和時(shí)間,以及在邏輯和框架表示之間進(jìn)行轉(zhuǎn)換的有效吞吐量。
表3:XCZU3EG上的翻譯時(shí)間
表III表明我們可以將大約兩個(gè)數(shù)量級(jí)的轉(zhuǎn)換表縮減到千字節(jié)范圍內(nèi)(第七節(jié))。壓縮會(huì)稍微減慢翻譯速度。加速度(第八節(jié)) 大約減半翻譯時(shí)間,同時(shí)添加大約與未壓縮表一樣大的表。在渲染的11個(gè)內(nèi)存中,有7個(gè)是單BRAM內(nèi)存,但是這些內(nèi)存只占4%的位,所以在轉(zhuǎn)換所有內(nèi)存時(shí),加速的影響很小。
③ BERT API操作
單內(nèi)存:表4總結(jié)了讀寫一篇簡(jiǎn)單的文章的表現(xiàn)×64個(gè)內(nèi)存,填充一個(gè)36塊。第一行顯示默認(rèn)的讀取速度(第六節(jié)) 第二個(gè)顯示了將PCAP DMA讀取速度提高到150mhz(600MB/s)的影響。第三行顯示壓縮的影響;在這種情況下,它會(huì)稍微減慢翻譯速度。第四行顯示了加速度的影響,這大約是平移時(shí)間的一半。
表4:基于XZCU3EG的BERT-API單RAM36性能
注:24MHz是xilfpga中的讀取速度;150MHz是我們能夠可靠運(yùn)行DMA回讀的最高速度。
接下來(lái)的三行(標(biāo)記為“Frameset”)查看傳輸共享同一幀集的所有12個(gè)內(nèi)存。第一種情況捕獲對(duì)每個(gè)內(nèi)存執(zhí)行分離 bert_read和bert_write操作的總時(shí)間;這大約需要12倍于單個(gè)BRAM情況的時(shí)間,因?yàn)樗皇菃蝹€(gè)時(shí)間的總和,并且實(shí)現(xiàn)了相同的帶寬。中間一行使用bert_transfuse在一次操作中讀取或?qū)懭胨?2個(gè)存儲(chǔ)器;結(jié)果,DMA傳輸時(shí)間與每個(gè)BRAM讀取中的傳輸時(shí)間相當(dāng),而轉(zhuǎn)換時(shí)間幾乎是12倍,因?yàn)槊總€(gè)存儲(chǔ)器必須單獨(dú)轉(zhuǎn)換。由于DMA傳輸時(shí)間與單個(gè)RAMB36讀寫中的轉(zhuǎn)換時(shí)間大致相當(dāng),因此這將導(dǎo)致大約兩倍的凈吞吐量。幀集的最后一行顯示了執(zhí)行單個(gè)傳輸操作的影響,該操作同時(shí)讀取和寫入所有內(nèi)存。
表中的最后一行顯示從RAMB36中讀寫一幀(兩個(gè)64b字)。這比讀或?qū)懻麄€(gè)記憶和翻譯所有的框架要花更少的時(shí)間。這里的翻譯時(shí)間可以很短。然而,由于在設(shè)置DMA操作時(shí)有相當(dāng)多的固定時(shí)間,因此凈吞吐量很低。
④ BERT API操作
應(yīng)用層:?jiǎn)蝹€(gè)BRAM和所有BRAM在Tab中的幀集cases中的轉(zhuǎn)換,在表4中預(yù)期典型表現(xiàn)。表5表示當(dāng)我們讀取或?qū)懭胨写鎯?chǔ)器時(shí)應(yīng)用程序的透析性能。哈夫曼展示了一個(gè)2-3×透析操作的改進(jìn)。渲染幾乎沒(méi)有什么好處,在轉(zhuǎn)換的情況下,轉(zhuǎn)換需要更多的時(shí)間,這可能是由于緩存效果對(duì)于容納所有內(nèi)存所需的大幀內(nèi)存造成的。由于主導(dǎo)時(shí)間通常是在翻譯中,所以在讀寫數(shù)據(jù)時(shí),總輸入時(shí)間基本上是線性的。
表5:基于XZCU3EG的BERT-API應(yīng)用性能
注:150MHz是我們能夠可靠運(yùn)行DMA回讀的最高速度。
10. 結(jié)論
現(xiàn)代FPGA上的配置路徑提供了對(duì)嵌入式存儲(chǔ)器的訪問(wèn)。就FPGA資源而言,它是一個(gè)輕量級(jí)接口,用于從嵌入式存儲(chǔ)器中獲取數(shù)據(jù)。XBERT提供了一個(gè)用戶級(jí)API,使應(yīng)用程序開(kāi)發(fā)人員可以輕量級(jí)地使用此功能。使用XBERT訪問(wèn)邏輯內(nèi)存就像API調(diào)用一樣簡(jiǎn)單。這有助于在程序啟動(dòng)時(shí)加載初始內(nèi)存狀態(tài),在程序完成、調(diào)試時(shí)恢復(fù)最終數(shù)據(jù)和狀態(tài),以及在FPGA結(jié)構(gòu)和嵌入式內(nèi)核之間進(jìn)行不頻繁的數(shù)據(jù)傳輸。XBERT API負(fù)責(zé)邏輯到物理的轉(zhuǎn)換,包括壓縮必要的轉(zhuǎn)換信息和最小化必須傳入和傳出FPGA的數(shù)據(jù)的優(yōu)化。XBERT工具流自動(dòng)生成API所需的翻譯信息?! ?/p>
評(píng)論
查看更多