研究背景及基礎知識
FPGA是實現高性能計算與網絡的重要工具,得益于其高度的并行性與用戶可編程的特性,FPGA得到了越來越廣泛的應用。FPGA由CLB(Configurable Logic Block,可編程邏輯單元)、BRAM(Block RAM,塊RAM)、DSP48E1(專用數字處理單元)、可編程布線資源、可編程IO資源等部分組成,其中,CLB是實現邏輯功能的基礎,Xilinx 7系列FPGA CLB內部結構如圖1.1所示[1]。
從圖1.1中我們可以看到,一個CLB由兩個SLICE組成,而SLICE可以分為SLICEL和SLICEM,SLICEL僅可以實現邏輯功能,而SLICEM除了可以實現邏輯功能外,還可以實現位寬為1bit、深度為64bit的RAM, SLICEL和SLICEM的結構如圖1.2和圖1.3所示[1],SLICEL和SLICEM都是由4個6輸入LUT(Look up table,查找表)、3個MUX(數據選擇器)、1個Carry Chain(進位鏈)和8個Flip-Flop(觸發器)組成,其中,LUT本質是一塊6地址輸入1數據輸出的存儲器(不考慮5輸入LUT的情況),通過改變其內容,可以得到各種各樣的真值表,也就得到了各種各樣的邏輯功能,這是FPGA可編程性的基礎之一。
比圖1.2和圖1.3可以發現,SLICEL的4個LUT,只有6bit地址輸入和1bit數據輸出(不考慮5輸入LUT的情況),當bitstream文件配置下去后,用戶是無法對LUT內容進行更改的,可以將之看作是一塊ROM;而SLICEM除6bit讀地址輸入和1bit數據輸出外,還有6bit的寫地址輸入(圖1.2中W6:W1)和1bit的寫數據使能(圖1.2中WEN),2bit的寫數據輸入(DI1和DI2),這也是SLICEM的LUT可以被配置為位寬為1bit、深度為64bit的RAM的原因。
研究目的
在7系列FPGA中,將近2/3的SLICE是SLICEL,其余的是SLICEM[1],也就是說,FPGA內2/3的資源在bitstream文件下載后,其邏輯功能就無法更改了,除非修改代碼并生成新的bitstream文件。這給可重構計算、基于LUT的高帶寬查找算法等研究帶來了很大的困擾:這些研究希望在設備運行時對LUT的內容進行動態修改,而只有SLICEM的LUT存在寫數據接口,也就是這些研究中的算法只能利用1/3的LUT資源。
作者在研究基于FPGA的高性能可重構CRC算法時,就遇到了上述問題,可編程CRC的關鍵計算模塊由LUT實現,而為了實現CRC生成式的可編程,必須要使用SLLICEM的LUT,導致時序不理想,且需要額外使用復雜的配置電路。
作者收到啟發,發現使用Xilinx 提供的HWICAP IP核即可實現對SLICEL的LUT的動態編程,無需Vivado軟件參與 ,即可實現ms乃至us級別的重配置速度[2][3],該方案是基于FPGA實現高性能可重構CRC的理想選擇。
然而,網上關于該研究的資料是十分稀缺的;Xilinx官方提供的內容也十分分散且有限,部分內容還被有意地忽略了;學術界的論文大多集中在如何設計高性能的ICAP控制器,以取代性能較低的HWICAP控制器。到目前為止,還無法找到關于如何使用HWICAP,實現單個LUT的內容重配置的內容。作者經過1個多月的摸索,基本打通了單個LUT重配置的各個環節,最終基于Artix-7 FPGA開發板,搭建了一套演示環境,實現了單個LUT內容的讀取與重配置,該項研究的各項內容如下所述:
第二節介紹LUT的尋址與配置方式,只有知道LUT如何尋址,才能對特定位置的LUT進行重配置;第三節介紹LUT的信息提取,包括LUT位置提取與LUT引腳映射關系提取;第四節對rbt文件進行解析(僅限于LUT內容部分),只有了解LUT初始值是如何映射到rbt文件中,才能利用HWICAP實現LUT內容的正確配置;第五節介紹HWICAP的具體操作,包括HWICAPIP核的操作與ICAP的操作命令;第六節搭建了驗證系統,基于Artix-7FPGA開發板,在Vivado環境下,使用TCL命令,實現單個LUT的重配置;第七節對上述工作進行總結,指出后面的工作方向。
LUT尋址與配置方式
一、FPGA的基本結構
想要對LUT進行尋址,必須要知道LUT在FPGA中的組織方式,也就是知道FPGA的結構,需要說明的是,Xilinx 7系列FPGA與其前代產品相比,組成出現了較大的變化,在這里介紹Virtex-5 FPGA與Artix-7 FPGA的具體結構。
Virtex-5系列FPGA和Artix-7系列FPGA都是基于ASMBL(AdvancedSilicon Modular Block)架構的(但是Virtex-5基于二代ASMBL技術,Artix-7基于四代ASMBL技術) ,這里以7系列FPGA為例,對ASMBL架構進行簡單介紹。
7系列FPGA ASMBL架構如圖1.1所示,該架構的關鍵在于,資源按列排布,同一列的資源是相同的,通過組合不同的列,可以得到面向各種應用、滿足各種功能的FPGA,該架構的模塊化思想,大大簡化了FPGA的設計。我們來看一張真實的FPGA的內部結構圖(器件型號為XC7A100T 該圖通過Vivado軟件得到),如圖1.2所示,該FPGA分為8個區域(8個Clock Region),圖中大量的淡藍色非規則部分,是已經被占用的模塊,我們選擇比較“干凈”的X0Y3區域進行介紹;
X0Y3區域放大后的圖片如圖1.3所示,圖中最左側橘色部分為IO接口,藍色部分為CLB,紅色部分為BRAM資源(RAM36E1),綠色部分為DSP資源(DSP48E1),這樣的資源組織方式與前面說的ASMBL架構是完全吻合的。我們再次將圖2中的藍色方塊放大,如圖1.4所示,可以看到,每個藍色方塊內部,都由2個SLICE組成。
作者肉眼數了一下,一列藍色方塊中,藍色方塊的數量是50個,也就是一列CLB中包含50個CLB(這個知識后面要用到);一列紅色方塊中,紅色方塊的數量是10個,也就是一列BRAM中包含10個RAM36E1;一列綠色方塊中,紅色方塊的數量是20個,也就是一列DSP中包含20個DSP48E1;
需要特別注意的是,在FPGA的中間部分,是一組BUFG,如圖1.5所示(圖1.2放大,觀察FPGA正中央),在BUFG的上方,是FPGA的上半部分(top),FPGA的下方是下半部分(bottom),這個知識后面會用到,可能有人會有疑問,圖1.2結構如此對稱,上半部分和下半部分不是一目了然的么?但是我們需要知道,不是所有的FPGA都是四行兩列八個ClockRegion的,如圖1.6(芯片型號為XC7Z020),為三行了兩列六個Clock Region,這時只能通過觀察BUFG的位置(圖1.6中白框所在位置),判斷哪幾行是top部分,哪幾行是bottom部分。
再來看一下Virtex-5FPGA的內部結構,如圖1.7所示,可以看到,Virtex-5FPGA的結構與7系列FPGA很相似,都是模塊化的、按列排布的;我們重點關注一下CLB方面的區別,對比圖1.3和圖1.7可以發現,7系列FPGA一列CLB包含CLB的個數為50個,而Virtex-5FPGA一列CLB包含CLB的個數為20個,這種差別在后期介紹LUT尋址時會體現出來。
二、FPGA配置幀格式與尋址格式
FPGA配置數據的最小單位是幀,下面先以Virtex-5為例,介紹配置幀的格式與尋址方式;然后介紹7系列FPGA與Virtex-5在配置幀格式與尋址方式方面的區別。
1. Virtex-5 FPGA配置幀格式與尋址格式
Virtex-5配置幀格式如圖1.8所示,圖中共有36個幀,每個幀包含41個word,每個word由32bit組成,圖中“X odd”部分代表一個CLB中編號為奇數的SLICE,而“X even”代表編號為偶數的SLICE,也就是“X odd”代表圖1.4中右側的SLICE,“X odd”代表圖1.4中左側的SLICE;Frame26-Frame29和Frame32-Frame35已經可以用來配置一個CLB內的8個LUT了,為什么配置一個CLB需要36個幀呢?因為除了需要配置LUT外,還需要配置觸發器、連接線等其他的部分,因為我們僅需要研究LUT內容是如何重配置的,因此我們不對這些內容進行研究;另外,想要配置一個LUT,使用1個幀是搞不定的,因為1個幀只能配置1個LUT的2個字節(6輸入LUT初始值為64bit,也就是8字節),需要4個幀才能配置一個LUT,但是,一個幀又同時涉及到了20個LUT的配置信息,也就是一個幀會對一列SLICE中的LUT進行配置(前面提到過,Virtex-5一列CLB中,CLB數量是20),這也是為什么要使用RMW(read-modify-write)的思想,也就是想配置1個LUT,需要先把這個LUT對應的4個幀讀出來,修改該LUT對應的內容后,再將這4個幀寫回去,這樣才能保證其他的LUT不受影響。
細心的讀者可以發現,圖1.8中一個配置幀包含41個word,而一列SLICE包含20個SLICE,2個word可以配置一個SLICE的4個LUT,怎么多出了一個word?答案在圖1.9中可以找到,一個配置幀的前20個word和后20個word都是用于配置LUT的,而中間的LUT用于其它功能,更多信息可以參考Xilinx官方文檔:UG191。
Virtex-5 FPGA配置幀的尋址格式如圖1.10所示,Virtex-5系列FPGA配置幀的地址由24bit組成,其中,bit23-bit21作用是指示配置對象的類型,如取值為000代表對CLB進行配置;bit20作用是指示配置的對象在FPGA的上半部分還是下半部分(相關內容參考圖1.5及圖1.6);bit19-bit15是選擇行的,如圖1.2所示,該FPGA有4行,但是其編址方式是不是從上到下為0、1、2、3呢?
當然不是的,其編址方式如圖1.11所示,上半部分(top)和下半部分(bottom)是分開編址的,接近中間的行,地址為1,遠離中間的行,地址依次加1,舉個例子,圖2.2中X0Y2、X1Y2、X0Y3、X1Y3位于上半部分,X0Y2、X1Y2行地址為0,X0Y3、X1Y3行地址為1;圖2.2中X0Y0、X1Y0、X0Y1、X1Y1位于上半部分,X0Y1、X1Y1行地址為0,X0Y0、X1Y0行地址為1;bit14-bit7是列地址,需要注意的是,列地址是不分clock region的,比如圖2.2中X0Y2、X0Y3的第一列,地址是相同的,另外,CLB、BRAM、DSP等列是統一編址的,列地址可以利用Viavdo軟件,通過TCL命令提取出來;bit6-bit0是選擇具體某一幀的地址,由圖1.8可知,配置1個CLB(或者說配置一列CLB),需要36個幀,但是在對LUT重配置的時候,并不是所有幀都要重新進行RMW操作,只需要對與該LUT相關的四個幀進行RMW操作即可,對36個幀中某一具體的幀進行尋址,就需要用到minor address了。
2.7系列FPGA配置幀格式與尋址格式
7系列FPGA配置幀格式與圖1.8基本類似,但是由于7系列FPGA一列CLB由50個CLB組成(而Virtex-5為20個),因此一個7系列FPGA配置幀包含101個word;
7系列FPGA的配置幀的尋址格式如圖1.12所示,7系列FPGA的配置幀地址由26bit組成,與圖1.10比較之后,可以發現,7系列FPGA 列地址為10個bit,而Virtex-5FPGA列地址為8bit,這是由于FPGA規模變大所致;地址其他部分基本沒有發生變化。
rbt文件解析
rbt文件和bit文件一樣,都是FPGA的配置文件,bit文件是二進制的,觀察起來是很不方便的,然而rbt文件相當于bit文件的ASCII版本因而我們選擇rbt文件作為我們解析的對象。
一、做rbt文件解析的原因
為什么要做rbt文件解析?因為上節講述配置幀格式的研究中,還存在一個不清楚的地方:圖1.8中半個word可以配置1個LUT的1/4,那這半個word的bit順序,與Verilog代碼中LUT初始值的bit順序,是否是一致的?是否存在某種映射關系?為了探索這一點,我首先想到的是對rbt文件進行解析,具體來說,建立一個工程,對一個LUT進行初始化,生成bit文件后,觀察rbt文件中相應的初始化值是怎樣的。后來發現,進行這項研究是十分必要的,研究結果表明,LUT的初始化值與rbt文件中對應的內容,并不是相等的,二者存在特定的映射關系, 且SLICEL和SLICEM中的LUT,映射關系是不一樣的。
下面對研究過程進行介紹。
二、準備工作
rbt文件中的配置數據是二進制格式的,觀察十分不方便,因此第一項準備工作就是將二進制的rbt文件轉換為十六進制,這項工作是通過一個python腳本實現的(位置:代碼/rbt_translation.py),如圖2.2所示,因為作者此前沒有寫過python腳本,因此代碼很不完善,下面結合代碼說明需要注意的地方:
(1)rbt文件的前7行是rbt文件的介紹信息,如圖2.3所示,在用腳本轉換進制之前,這7行需要手動去掉(作者python水平太低);
(2)圖2.2第一行的NUM值為956447,這是rbt文件去除前7行后的行數;需要注意的是,本工程針對的FPGA型號是XC7A100T,每個型號的FPGA規模不同,NUM的值也要相應變化;
(3)圖2.2第三、四行為原始rbt文件的路徑(后綴改為txt)與轉換后文件的路徑,這個路徑是絕對路徑,需要根據實際情況進行修改。
在UG470中,專門有一部分介紹bitstream的組成,這部分需要重點了解,詳細內容見UG470的table 5-19。
三、具體流程
首先建立一個工程,在工程中例化一個LUT,這個LUT的位置必須是固定的,方便進行多次對照試驗,如圖3.4所示,例化LUT的位置為SLICE_X57Y53的LUT-D,如圖2.4所示,為了簡單起見,該LUT的初始值設置為“0x6996966996696996”,為什么設置成這個值呢?因為LUT初始值為該值時,作用為一個六輸入一輸出異或門,而異或門是CRC算法中的基本單元。
綜合工程(工程在:工程/jtag_axi_icap_lut_AX7103_simple_lut_6996文件夾下),生成rbt文件后,將rbt文件轉成十六進制(見上述準備工作),結果如表2.1所示:
表2.1 rbt文件對應行數和值-1
|
|
|
|
|
|
|
|
|
|
觀察表2.1可以發現,rbt文件對應值的行數,總是差了101個word,與之前描述的配置幀格式是可以對應上的。那是不是可以說Verilog代碼中LUT初始值的bit順序(圖2.4)和rbt中的bit順序,是一致的呢?還不能這么說,因為“6”的二進制表示是“0110”,9的二進制表示為“1001”,可以發現這兩個值都是十分對稱的值。
為了進一步驗證是否存在某種bit順序映射關系,建立新的工程。LUT位置不變,但初始化值設置為“0x0123456789ABCDEF”,如圖2.5所示,綜合工程(工程在:工程/jtag_axi_icap_lut_AX7103_simple_lut_0123文件夾下),生成rbt文件后,將rbt文件轉成十六進制(上述操作),結果如表2.2所示:
表3.2 rbt文件對應行數和值-2
rbt文件行數 |
rbt文件值 |
510521 |
0x fe760000 |
510622 |
0x ba320000 |
510723 |
0x 98100000 |
510824 |
0x dc540000 |
可以發現,rbt文件值與LUT初始化值完全不一樣,可以證明,確實存在某種特殊的映射關系。如何確定這種映射關系呢?最簡單的是,建立多個工程,每個工程初始化值只有1bit(如0x0000000000000001、0x0000000000000002、0x0000000000000004、0x0000000000000008等),觀察生成rbt文件中對應值的位置,理論上需要建立64個工程才能完全確定這個關系(但其實存在規律,不用這么多),成功破譯了其對應關系,測試原始數據如表2.3所示(為了簡單起見,將1個LUT的4部分數據寫到一起,作為一個完整的word,“X”代表0x0000):
表2.3 測試原始數據-1
LUT初始值 |
rbt數據 |
0x X_X_X_0001 |
0x 8000_X_X_X |
0x X_X_X_0002 |
0x X_8000_X_X |
0x X_X_X_0004 |
0x 4000_X_X_X |
0x X_X_X_0008 |
0x X_4000_X_X |
0x X_X_X_0010 |
0x 2000_X_X_X |
0x X_X_X_0020 |
0x X_2000_X_X |
0x X_X_X_0040 |
0x 1000_X_X_X |
0x X_X_X_0080 |
0x X_1000_X_X |
0x X_X_X_0100 |
0x X_X_X_8000 |
0x X_X_X_0200 |
0x X_X_8000_X |
0x X_X_X_0400 |
0x X_X_X_4000 |
0x X_X_X_0800 |
0x X_X_4000_X |
0x X_X_X_1000 |
0x X_X_X_2000 |
0x X_X_X_2000 |
0x X_X_2000_X |
0x X_X_X_4000 |
0x X_X_X_1000 |
0x X_X_X_8000 |
0x X_X_1000_X |
0x 0100_X_X_X |
0x X_X_X_0008 |
0x 0200_X_X_X |
0x X_X_0008_X |
0x X_0100_X_X |
0x X_X_X_0080 |
0x X_0200_X_X |
0x X_X_0080_X |
0x X_X_0100_X |
0x X_X_X_0800 |
0x X_X_0200_X |
0x X_X_0800_X |
0x 0001_X_X_X |
0x 0008_X_X_X |
0x 0002_X_X_X |
0x X_0008_X_X |
0x X_0001_X_X |
0x 0080_X_X_X |
0x X_0002_X_X |
0x X_0080_X_X |
0x X_X_0001_X |
0x 0800_X_X_X |
0x X_X_0002_X |
0x X_0800_X_X |
將64bit初始值的最高位(MSB)定義為bit-64,最低位(LSB)定義為bit-1,則LUT初始值與rbt文件的位置映射關系如表2.4所示:
LUT初始值 |
rbt數據 |
1 |
64 |
2 |
48 |
3 |
63 |
4 |
47 |
5 |
62 |
6 |
46 |
7 |
61 |
8 |
45 |
9 |
16 |
10 |
32 |
11 |
15 |
12 |
31 |
13 |
14 |
14 |
30 |
15 |
13 |
16 |
29 |
57 |
4 |
58 |
20 |
41 |
8 |
42 |
24 |
25 |
12 |
26 |
28 |
49 |
52 |
50 |
36 |
33 |
56 |
34 |
40 |
17 |
60 |
18 |
44 |
觀察規律后,將該映射規律用python代碼(文件位置:代碼/map_SliceL.py)表示出來,如圖2.6所示,
后來又發現,SLICEL和SLICEM的LUT,從verilog代碼初始值到rbt文件值的映射關系還是不一樣的,上面是SLICEL的映射關系,SLICEM(位置是SLICE_X56Y53)的測試數據、映射關系、python代碼分別如表2.5、表2.6、圖2.7所示,表2.6中紅色字體,代表這幾組數據是推測得來的(后來證實推測正確)。
表2.5 測試原始數據-1
LUT初始值 |
rbt數據 |
0x X_X_X_0001 |
0x X_X_8000_X |
0x X_X_X_0002 |
0x X_X_X_8000 |
0x X_X_X_0004 |
0x X_X_4000_X |
0x X_X_X_0008 |
0x X_X_X_4000 |
0x X_X_X_0010 |
0x X_X_2000_X |
0x X_X_X_0020 |
0x X_X_X_2000 |
0x X_X_X_0040 |
0x X_X_1000_X |
0x X_X_X_0080 |
0x X_X_X_1000 |
0x X_X_X_0100 |
0x 8000_X_X_X |
0x X_X_X_0200 |
0x X_8000_X_X |
0x 0100_X_X_X |
0x 0008_X_X_X |
0x 0200_X_X_X |
0x X_0008_X_X |
0x X_0100_X_X |
0x 0080_X_X_X |
0x X_0200_X_X |
0x X_0080_X_X |
0x X_X_0100_X |
0x 0800_X_X_X |
0x X_X_0200_X |
0x X_0800_X_X |
0x 0001_X_X_X |
0x X_X_0008_X |
0x 0002_X_X_X |
0x X_X_X_0008 |
0x X_0001_X_X |
0x X_X_0080_X |
0x X_0002_X_X |
0x X_X_X_0080 |
0x X_X_0001_X |
0x X_X_0800_X |
0x X_X_0002_X |
0x X_X_X_0800 |
表2.6 映射關系-1
LUT初始值 |
rbt數據 |
1 |
32 |
2 |
16 |
3 |
31 |
4 |
15 |
5 |
30 |
6 |
14 |
7 |
29 |
8 |
13 |
9 |
64 |
10 |
48 |
11 |
63 |
12 |
47 |
13 |
62 |
14 |
46 |
15 |
61 |
16 |
45 |
57 |
52 |
58 |
36 |
41 |
56 |
42 |
40 |
25 |
60 |
26 |
44 |
49 |
20 |
50 |
4 |
33 |
24 |
34 |
8 |
17 |
28 |
18 |
12 |
上述關系推導出來之后,還是得不到表2.2的結果,理論上,初始化值映射后,結果應如表2.7所示,經過多次探索嘗試后,發現原因:Verilog代碼中例化的LUT與FPGA上LUT的管腳的映射關系是不同的,通過一個例子說明,如圖2.8所示,Verilog代碼例化的LUT,初始化值“0x0123456789ABCDEF”,對應的6位地址是I5-I0,但實際FPGA內部的LUT如圖2.9所示,對應的地址是A6-A1。
表2.7 rbt文件對應行數和值-3
rbt文件行數 |
rbt文件值 |
510521 |
0x d8d80000 |
510622 |
0x ffaa0000 |
510723 |
0x 55000000 |
510824 |
0x d8d80000 |
而Verilog代碼例化的LUT與實際的LUT,地址引腳的對應關系如圖2.10所示,二者又存在一種映射關系,發生這種情況的原因是,綜合工具Vivado會綜合考慮各種情況,選擇最優的布線,為了達到這種最優,允許一個LUT的地址線進行某種翻轉。
為了支持上述的翻轉,作者寫了一個簡單的python腳本(目錄:代碼/lut_pin_map.py),如圖3.11所示,假如數據m是Verilog代碼中的LUT初始化值,則n是映射到實際FPGA中的LUT初始化值。
四、總結
從Verilog代碼中的LUT初始值到rbt文件中的LUT初始值,遵循的流程如圖2.12所示,經過兩次轉換后,Verilog代碼中的LUT初始值可以轉換為rbt文件中的LUT初始值。
LUT信息提取
我們如何知道待配置的LUT,其位置是多少?代碼中的LUT與實際的LUT引腳映射關系是怎樣的?當然可以通過Verilog代碼中的位置約束(如BEL="D6LUT",LOC="SLICE_X57Y53")和xdc文件中的引腳鎖定約束(如set_property LOCK_PINS {I0:A1 I1:A2 I2:A3 I3:A4 I4:A5 I5:A6}[get_cells u_xor_lut/LUT6_inst_D_right]),在生成rbt文件之前,人為地分配好一切,但是,這樣做可能會導致設計性能下降,因為Vivado的綜合實現算法,是Xilinx公司多年研究的成果,可以認為其是最優的。因此,作者不建議通過添加位置約束和LUT引腳鎖定約束的方式,確定待配置LUT的信息,而是生成rbt文件之后,通過Vivado軟件和TCL命令,將LUT的位置信息和引腳約束信息提取出來。
以圖1.1中例化的LUT為例,生成rbt文件后,
LUT位置信息提取命令是:
get_tiles-of_objects [get_property SITE [get_cells -hierarchical"*LUT6_inst_D_right*" ]]
得到的結果是:CLBLM_L_X34Y53
上述結果給出的是LUT所在CLB的位置,其中X的值(34)就是前文的圖1.12中的columnaddress,可以通過Y的地址,換算前文圖1.12中的top/bottom address和row address。
LUT引腳映射關系提取命令是:
get_bel_pins-of_objects [get_pins -hierarchical "*LUT6_inst_D_right*"]
得到的結果是:
SLICE_X57Y53/D6LUT/O6
SLICE_X57Y53/D6LUT/A1
SLICE_X57Y53/D6LUT/A2
SLICE_X57Y53/D6LUT/A3
SLICE_X57Y53/D6LUT/A4
SLICE_X57Y53/D6LUT/A5
SLICE_X57Y53/D6LUT/A6
上述結果與前文圖2.10中的映射關系是一致的。
HWICAP操作方法
前面的工作解決了配置幀尋址與配置幀內容怎么寫的問題,下面要開始介紹ICAP原語和HWICAP IP核。ICAP原語是Xilinx公司開放給用戶的FPGA內部配置接口,如圖2.1所示,使用ICAP原語,需要寫一個控制器,處理接口時序的問題,Xilinx提供了這個控制器,就是HWICAP IP核,如圖2.2所示,這個IP核對外呈現AXI4-LiteSlave接口,使用者可以通過該接口,間接地操縱ICAP原語。
一、ICAP操作方法
ICAP操作方法主要參考UG953與UG470,尤其是UG470,第五節Configuration Details介紹了大量有用信息,需要重點關注的有:
(1)BitstreamComposition小節,介紹了bit文件/rbt文件的組成形式,可以從中看出一些配置流程相關的信息;
(2)ConfigurationMemory Frames 小節,與前文第一節介紹的幀格式是對應的;
(3)ConfigurationPackets小節,介紹了ConfigurationPackets的細節,上面說的ConfigurationMemory Frames主要是用于傳輸配置內容(如LUT的初始化值),而Configuration Packets主要用于傳輸一些配置相關的指令,如讀寫配置寄存器。ConfigurationPackets分為兩種,即Type 1packet和Type 2 packet,Type 2報文必須跟在Type 1報文后面,個人認為Type 2報文的作用是對Type 1 報文進行補充,因為Type 1 報文word count字段僅有11bit,只支持2048個word傳輸,而Type 2報文word count字段有27bit,支持134217728個word,具體內容請參考UG470 Table 5-20、Table 5-21、Table 5-22;
(4)ConfigurationRegisters小節,配置相關寄存器,如圖2.3所示,詳細內容請參考UG470 ConfigurationRegisters小節。
從圖2.2可知,HWICAP IP核僅支持AXI4-Lite接口,也就是我們操作HWICAP IP核的時候,其實是在配置寄存器,那么該IP核有哪些寄存器呢?如圖2.4所示。
下面重點介紹幾個用到的寄存器。我們先分析一下我們將配置幀傳輸進去,需要哪些操作。
寫配置幀:(1)將幀寫入FIFO(2)寫完后開始配置。
上面第一步,將幀寫入FIFO,對應的是WriteFIFO Keyhole Register(keyhole就是鑰匙孔,可以說十分形象了),寄存器格式如圖2.5所示;第二步,開始配置,對應的寄存器是Control Register,該寄存器可以控制讀,也可以控制寫,寄存器格式如圖2.6所示。
讀配置幀:(1)告訴IP核讀幾幀(2)開始讀。
第一步對應的寄存器是Size Register,定義如圖2.7所示,第二步對應的還是ControlRegister,如圖5.6所示。
其他的寄存器也有各自的用處,建議讀者參考PG134,進一步了解。
驗證系統
前面做的大量調研與學習,目的是為了能夠做到對單個LUT的在線讀和寫,如何證明我們前面做的工作是正確的呢?答案是建立一個驗證系統,在實際的FPGA系統中,將FPGA內部某個特定的LUT內容在線讀出來,然后在線將某些內容寫進去,如果可以成功做到這一點,可以說研究工作基本成功了。下面我們來介紹驗證系統搭建的詳細流程。
一、開發板與連接拓補
開發板連接拓撲如圖3.1所示,FPGA開發板型號為黑金AX7103,如圖3.2所示,讀者也可以用其他Xilinx FPGA板卡搭建驗證系統(前文的知識適用于所有的7系列FPGA),但是Zynq系列暫時還無法調通,應該是作者忽略了些什么;PC與FPGA通過JTAG連接,PC上運行Vivado軟件,在Vivado TCL Console中輸入TCL命令,可以做到PC與FPGA的交互。
二、FPGA內部模塊設計
FPGA內部模塊設計如圖3.3所示(工程位置:工程/jtag_axi_icap_lut_AX7103_0123),JTAG2AXI IP核和HWICAP IP核負責實現接收PC的控制指令,實現對LUT內容的讀寫;目標LUT是被讀寫的對象,其Verilog例化如圖3.4所示。
讀LUT內容怎么驗證?
答案:在PC的Vivado軟件TCL Console內,寫TCL命令,讀取目標LUT內容,讀取內容與rbt文件的相應位置比對(參見前文表2.7,為了簡單起見,我們采用set_property LOCK_PINS{I0:A1 I1:A2 I2:A3 I3:A4 I4:A5 I5:A6} [get_cells u_xor_lut/LUT6_inst_D_right]命令,保證代碼例化LUT與真實LUT管腳一一對應,避免出現圖2.10的情況)。
寫LUT內容怎么驗證?
答案:在PC的Vivado軟件TCL Console內,寫TCL命令,配置目標LUT內容,配置完成后,觀察ILA。在配置之前,目標LUT初始值是0x0123456789ABCDEF,計數器產生遞減的地址,因此可以用ILA觀察到變化的數據;配置內容為全0,配置完成后,ILA觀察到的內容為全0,證明配置成功。
三、如何編寫TCL代碼
學習TCL本身的語法,需要參考Xilinx官方文檔,UG835、UG894,熟悉TCL基本操作,另外,Xilinx高級SAE高亞軍老師的TCL系列教程寫的也很好;
學習第5節HWICAP和ICAP的具體操作方法,可以參考Xilinx給的HWICAP官方驅動(其中的example和src部分讓作者受益匪淺),作者也給出了讀寫LUT需要的TCL代碼(位置:代碼/讀LUT-TCL指令 和代碼/寫LUT-TCL指令),作者寫的這些代碼大量參考了Xilinx給的驅動(可以從作者代碼的注釋中看出來),另外一定要注意,TCL文件里面的路徑是絕對路徑,要修改成自己電腦上的路徑。
四、驗證結果
讀LUT內容:
下載工程“jtag_axi_icap_lut_AX7103_0123”的bit程序(記得通過VIO復位,復位是低電平復位),運行“read_frame_510521.tcl”文件,該文件讀取LUT的1/4的內容,對應rbt文件的510521行(見前文表2.7),讀出的結果如圖3.5所示(如果讀出的結果不能完全顯示出來,使用“set_param messaging.defaultLimit 5000”命令,修改TCLConsole顯示的消息數量限制),可以發現是對應的(其他三行的讀操作可以運行同目錄下的其他TCL文件,結果都是正確的)。
寫LUT內容
仍然是同樣的bit文件,在配置LUT內容之前,ILA可以看到的數據如圖3.6所示,從上到下的三個信號,分別是LUT的輸入(地址),LUT的輸出,與LUT輸出的并行化(LUT輸出不方便觀察,并行化之后,方便觀察LUT初始值);在Vivado TCL Console行“source_write_all.tcl”文件后(記得改地址!!!),LUT的內容被重置為全0,如圖3.8所示,配置成功。
驗證系統
獲得的成果:
基本打通了單個LUT動態讀寫的流程,包括LUT尋址、LUT配置幀格式、rbt文件解析(對照用)、LUT信息提取、LUT配置方法(HWICAP和ICAP操作)、演示驗證系統搭建。
后期還需要做的工作:
(1)后期需要用嵌入式CPU實現對HWICAP IP核的操作,而不是PC,因為PC+Vivado+TCL的方式效率太低了;作者對軟件開發了解有限,需要一個精通軟件的人員,協助作者開發上層軟件及應用,比如開發文獻中的配表系統;
(2)上述操作方法不適用于Zynq系列,原因未知,目前懷疑是某些操作不到位,Zynq系列的單個LUT動態讀寫,還需要進一步研究。
參考文獻
[1].UG474Xilinx.7 Series FPGAs Configurable Logic Block,
[2].ReviriegoP, Ullah A, Pontarelli S. PR-TCAM: Efficient TCAM Emulation on Xilinx FPGAsUsing Partial Reconfiguration[J]. IEEE Transactions on Very Large ScaleIntegration (VLSI) Systems, 2019.
[3].CardonaL A, Ferrer C. AC_ICAP: A flexible high speed ICAP controller[J]. InternationalJournal of Reconfigurable Computing, 2015, 2015: 9.
[4].DS100 Xilinx. Virtex-5 FamilyOverview
[5].UG191 Xilinx. Virtex-5 FPGAConfiguration User Guide
[6].Project X-Ray. https://github.com/SymbiFlow/prjxray
[7].UG472 Xilinx. 7 Series FPGAsClocking Resources
[8].UG470 Xilinx. 7 Series FPGAs Configuration
[9].UG953 Xilinx. Vivado DesignSuite 7 Series FPGA and Zynq-7000 SoC Libraries Guide
[10].PG134 Xilinx. AXI HWICAP v3.0LogiCORE IP Product Guide
[11].AX7103 User Guide. ALINX http://www.alinx.vip:81/ug/AX7103_UG.pdf
[12].UG835 Xilinx.Vivado DesignSuite Tcl Command Reference Guide
[13].UG894 Xilinx. Vivado DesignSuite User Guide: Using Tcl Scripting
[14].TCL知識庫.https://mp.weixin.qq.com/s/5xHYli4NqCVLkrJXUPXT2w
[15].HWICAP驅動https://github.com/Xilinx/embeddedsw/tree/master/XilinxProcessorIPLib/dr...
編輯:hfy
-
FPGA
+關注
關注
1626文章
21678瀏覽量
602023 -
cpu
+關注
關注
68文章
10829瀏覽量
211193 -
Xilinx
+關注
關注
71文章
2164瀏覽量
121039
發布評論請先 登錄
相關推薦
評論