計全解析:從算法策略到協(xié)議約束與調(diào)試實戰(zhàn))
AXI總線仲裁器這個話題說實話是很多做SoC集成和FPGA開發(fā)的同事容易忽略又不得不面對的東西。剛開始接觸AXI的時候可能大家都會把精力放在valid/ready握手、outstanding傳輸、亂序返回這些協(xié)議細節(jié)上但一旦系統(tǒng)里掛了多個master——比如CPU、DMA、以太網(wǎng)MAC、USB控制器——你會發(fā)現(xiàn)總線仲裁器的設(shè)計直接決定了整個系統(tǒng)的帶寬分配和延遲表現(xiàn)。這篇是“AXI協(xié)議理解”系列的第一篇專門把仲裁器這塊拆開講清楚它到底解決什么問題、常用的仲裁策略有哪些、AXI協(xié)議給仲裁器設(shè)計埋了哪些坑、以及我自己在實際項目里踩過的雷。適合剛?cè)腴TAXI的FPGA/IC工程師也適合做了幾年集成但沒仔細摳過仲裁細節(jié)的朋友。1. 為什么AXI總線需要仲裁器1.1 AXI總線的基本結(jié)構(gòu)與仲裁器位置AXIAdvanced eXtensible Interface是ARM AMBA協(xié)議家族里的高性能總線協(xié)議它的核心特點是通道獨立讀地址通道AR、讀數(shù)據(jù)通道R、寫地址通道AW、寫數(shù)據(jù)通道W、寫響應(yīng)通道B各自獨立工作。這種設(shè)計讓讀和寫可以同時進行也讓outstanding未完成傳輸?shù)臄?shù)量可以做得很大從而隱藏內(nèi)存訪問延遲。但通道獨立帶來一個直接問題多個master同時發(fā)起訪問時誰先誰后比如CPU要讀DDR里的指令DMA要往DDR寫一幀圖像數(shù)據(jù)以太網(wǎng)控制器也要讀取描述符這幾個請求幾乎同時到達。從設(shè)備比如DDR控制器只有一個地址端口同一時刻只能接收一個請求這時候就必須有一個仲裁器來決定放行哪個請求。仲裁器就位于master和slave之間在多master互聯(lián)的場景下它承擔(dān)著“交通警察”的角色。在典型SoC里仲裁器通常不是獨立存在的而是集成在互聯(lián)矩陣Interconnect或者NICNetwork Interconnect里。比如ARM的NIC-400、NIC-450或者Xilinx的AXI Interconnect IP內(nèi)部都包含了仲裁邏輯。但理解仲裁器本身的設(shè)計思路比直接調(diào)IP更有價值——因為很多性能問題歸根結(jié)底是仲裁策略選擇不當(dāng)造成的。1.2 沒有仲裁器會發(fā)生什么總線沖突的現(xiàn)場要是沒有仲裁器多個master同時驅(qū)動地址總線和數(shù)據(jù)總線結(jié)果就是總線沖突兩個master的電平互相打架協(xié)議層面完全失效??赡苡腥藭f那讓每個master分時使用總線不就行了但問題在于AXI是通道獨立的不同通道的仲裁需要分別做。比如master A的寫地址可以仲裁通過master B的寫數(shù)據(jù)也需要仲裁通過如果兩者割裂處理數(shù)據(jù)通道和地址通道就可能對不上。還有一個容易被忽略的點AXI并沒有規(guī)定仲裁應(yīng)該放在哪個通道上。按照協(xié)議master發(fā)出請求后slave通過valid/ready握手來接收。仲裁器介入的時機可以是地址通道決定誰的命令先被slave接收也可以是數(shù)據(jù)通道決定誰的數(shù)據(jù)先傳輸。更常見的做法是在地址通道上做仲裁因為地址通道的請求頭包含了完整的傳輸信息地址、突發(fā)長度、ID等仲裁器只需要決定這些請求頭誰先通過數(shù)據(jù)通道就順著走就行了。我之前見過一個實際的項目工程師把仲裁放在了數(shù)據(jù)通道上結(jié)果出現(xiàn)了兩個master的寫數(shù)據(jù)在總線上一半一半交錯傳輸?shù)脑幃惉F(xiàn)象協(xié)議仿真能過但上板之后DDR的數(shù)據(jù)就是錯亂的。后來追查下來問題就出在仲裁位置放錯了寫數(shù)據(jù)通道一旦被分片寫響應(yīng)和寫數(shù)據(jù)之間的配對關(guān)系就亂了。這個案例后面會細說。1.3 仲裁器在SoC設(shè)計中的實際部署仲裁器的部署位置通常有三種。第一種是點對點互聯(lián)一個master連一個slave一般不需要仲裁器除非這個master內(nèi)部有多個請求源。第二種是共享總線式的多master互聯(lián)仲裁器集中管理所有master對單個slave的訪問這種結(jié)構(gòu)簡單但容易成為性能瓶頸適合對帶寬要求不高的系統(tǒng)。第三種是交叉開關(guān)矩陣Crossbar每個slave端口都有一個獨立的仲裁器多個master可以同時訪問不同的slave這時仲裁器分布在交叉開關(guān)的每個輸出端口上。在Xilinx的AXI Interconnect IP里打開配置界面就能看到每個slave端口對應(yīng)的仲裁策略選項比如Round Robin或者Priority。默認的Round Robin通常不會出大問題但如果你有實時性要求高的master就必須按優(yōu)先級來配否則延遲抖動會非常明顯。這個選擇需要結(jié)合具體業(yè)務(wù)來確定不能一張配置單打天下。2. 常見的AXI仲裁算法與選型分析2.1 固定優(yōu)先級仲裁簡單但餓死風(fēng)險高固定優(yōu)先級仲裁Fixed Priority是最直覺的做法給每個master分配一個優(yōu)先級編號仲裁時直接選出編號最高的請求。這個方案邏輯最簡單一個比較器加一個多路選擇器就能搞定占用資源極少時序也容易收斂。但它的缺點和優(yōu)點一樣明顯低優(yōu)先級master可能永遠得不到服務(wù)這就是所謂的餓死starvation問題。舉個實際例子CPU和UART的DMA訪問同一個DDR控制器如果CPU永遠是最高優(yōu)先級而CPU又持續(xù)有緩存未命中的讀請求UART的DMA可能幾毫秒都拿不到總線。對于UART這種需要實時從FIFO搬運數(shù)據(jù)的設(shè)備來說幾毫秒的空窗就意味著FIFO溢出數(shù)據(jù)直接丟失。我之前做過一個帶AXI UART16550核的項目默認配置里CPU是最高優(yōu)先級低優(yōu)先級里掛了一個UART DMA通道。調(diào)試串口經(jīng)常出現(xiàn)亂碼剛開始懷疑是波特率不匹配后來抓了總線的波形才發(fā)現(xiàn)UART的讀請求經(jīng)常被CPU的突發(fā)讀插隊DMA服務(wù)間隔不穩(wěn)定FIFO發(fā)生了下溢。改成UART DMA的優(yōu)先級高于CPU之后問題當(dāng)場就消失了。所以固定優(yōu)先級仲裁不是不能用而是要用對地方。如果高優(yōu)先級master的請求頻率有上限或者低優(yōu)先級master本身容忍大延遲那固定優(yōu)先級反而是最優(yōu)選擇因為它的延遲是可預(yù)測的資源耗費也最低。2.2 輪詢仲裁保證公平性的基礎(chǔ)方案輪詢仲裁Round-Robin是解決餓死問題最直接的策略多個master的請求排成一個圈仲裁指針每拍移動到下一個master有請求就放行沒請求就跳過。這個方案保證了所有master在長期統(tǒng)計下能獲得大致相等的總線訪問機會。設(shè)計上有兩個變體需要注意。一種是固定順序輪詢指針永遠按0→1→2→3的順序移動無論當(dāng)前master是否有請求。另一種是跳過式輪詢指針會跳到有請求的master減少無效輪詢周期。后者的效率更高但實現(xiàn)上需要額外的查找邏輯時序要稍微緊一點。不過輪詢仲裁也有它的軟肋它對延遲不敏感也沒有優(yōu)先級概念。如果某個master對實時性要求很高比如視頻解碼器需要每幀固定的帶寬輪詢給出的只是統(tǒng)計學(xué)意義上的公平延遲抖動依然存在。這時候就需要加權(quán)輪詢或者QoS機制來調(diào)節(jié)。在實際工程里一個常見的折中方案是“輪詢?yōu)橹鲀?yōu)先級為輔”默認所有master按輪詢仲裁但每當(dāng)某個高優(yōu)先級master連續(xù)等待超過設(shè)定周期時臨時把仲裁結(jié)果切給它。這種自適應(yīng)方案兼顧了公平和實時不過狀態(tài)機復(fù)雜度會明顯上升。2.3 加權(quán)輪詢按帶寬需求分配總線時間加權(quán)輪詢Weighted Round-Robin解決的是“公平但不夠用”的問題。比如DMA需要70%的帶寬CPU只需要30%簡單的輪詢會各分50%DMA的帶寬就欠了。加權(quán)的思路是給每個master分配一個權(quán)重值權(quán)重大的master在每輪仲裁中獲得更多的服務(wù)次數(shù)。實現(xiàn)上有兩種常見做法。第一種是令牌式每個周期給所有master發(fā)放與權(quán)重成正比的令牌數(shù)請求消耗令牌令牌多的master自然獲得更多服務(wù)。第二種是分槽式把仲裁周期切成與總權(quán)重等長的槽位按權(quán)重比例分配槽位給各個master。第一種方式更靈活第二種更容易做到嚴(yán)格周期。加權(quán)輪詢的難點在于權(quán)重怎么定。理論上可以根據(jù)系統(tǒng)帶寬模型來計算但在實際SoC里主master的帶寬需求往往是動態(tài)的——比如CPU的DDR訪問量隨負載波動非常大。如果權(quán)重是固定的要么浪費帶寬要么仍然不夠用。所以更先進的仲裁器會引入動態(tài)權(quán)重調(diào)整這已經(jīng)接近QoS的思路了。2.4 基于QoS的仲裁AXI4標(biāo)準(zhǔn)里的QoS接口AXI4協(xié)議在ARID和AWID之外增加了一個QOS信號寬度是4位表示每次傳輸?shù)姆?wù)質(zhì)量等級。從0到15數(shù)值越大優(yōu)先級越高。這給仲裁器設(shè)計提供了一個標(biāo)準(zhǔn)化的優(yōu)先級接口仲裁器不需要知道m(xù)aster是誰只需要看QOS值就能做仲裁決定。QOS信號的價值在于它把“誰的請求重要”這個決策從硬件架構(gòu)層搬到了軟件可配置層。系統(tǒng)軟件可以在運行時動態(tài)調(diào)整某個master的QOS值從而改變總線服務(wù)的偏向。比如視頻播放時提高顯示控制器的QOS保證幀不撕裂后臺跑基準(zhǔn)測試時降低CPU的QOS給存儲控制器的維護操作騰帶寬。不過QOS只是一個提示信號AXI協(xié)議并不強制仲裁器必須響應(yīng)它。我在設(shè)計仲裁器的時候通常會把QOS值映射為動態(tài)優(yōu)先級再結(jié)合輪詢機制做一個混合仲裁器優(yōu)先級高的先服務(wù)相同優(yōu)先級之間輪詢。這種方式兼顧了靈活性和公平性是目前比較推薦的實現(xiàn)思路。3. AXI協(xié)議對仲裁器設(shè)計的特殊約束3.1 valid/ready握手與仲裁時機的選擇AXI協(xié)議里每個通道的數(shù)據(jù)傳輸都通過valid/ready握手完成。發(fā)起方拉高valid表示數(shù)據(jù)有效接收方拉高ready表示可以接收兩者同時為高時傳輸發(fā)生。仲裁器介入后實際上扮演了“接收方發(fā)起方”的雙重角色對上游master來說是slave對下游slave來說是master。仲裁時機的選擇直接關(guān)系到一個問題是等master的valid信號拉高之后再仲裁還是提前預(yù)判我的經(jīng)驗是對于地址通道通常等valid拉高后再仲裁就夠了因為地址通道的請求不是每拍都有的仲裁器本身也要等請求到來才能做決定。但對于數(shù)據(jù)通道如果希望做到背靠背傳輸back-to-back預(yù)判是必要的——在最后一拍數(shù)據(jù)還沒傳完時就開始仲裁下一筆傳輸?shù)臄?shù)據(jù)通路。握手還有一個重要的特性一旦valid拉高發(fā)起方就不能撤銷必須等到握手完成。這意味著仲裁器一旦向某個master給出了ready信號就必須完成這筆傳輸。如果這時發(fā)現(xiàn)仲裁錯了——比如出現(xiàn)了更高優(yōu)先級的請求——也不能反悔只能等當(dāng)前傳輸結(jié)束。這在設(shè)計里叫“不可搶占”特性是AXI仲裁與普通CPU總線仲裁的重要區(qū)別。3.2 outstanding傳輸與ID管理的仲裁影響AXI協(xié)議允許master在未收到前一筆傳輸響應(yīng)之前就發(fā)起后續(xù)傳輸這就是outstanding。這個特性極大提升了總線利用率但也給仲裁器帶來了麻煩仲裁器不能只看當(dāng)前一筆請求還要考慮master發(fā)出的請求隊列深度。比如一個DMA控制器可以同時發(fā)出16筆讀突發(fā)但如果仲裁器一筆一筆地處理每筆之間還要等DDR的響應(yīng)返回DMA的outstanding能力就浪費了。正確的做法是仲裁器也維護一個與master對應(yīng)的未完成傳輸計數(shù)只要計數(shù)沒到上限就允許master連續(xù)發(fā)起新的請求。ID信號的管理更加微妙。AXI的ID信號用于標(biāo)記傳輸?shù)臍w屬支持亂序返回。仲裁器在合并多個master的請求時必須為每個master的ID做映射避免兩個master的ID沖突。比如master A和master B都用了ID0如果不做映射slave返回的數(shù)據(jù)就無法區(qū)分屬于哪個master。我踩過一個ID映射的坑當(dāng)時在做一個AXI to AXI Bridge兩個master的ID都是4位寬度理論上直接級聯(lián)就行。但其中一個master發(fā)起了亂序讀另一個master的ID恰好和它重疊導(dǎo)致返回數(shù)據(jù)被Bridge分發(fā)到了錯誤的master。最后不得不給Bridge增加了一個ID remap機制把每個master的ID空間獨立開才徹底解決。3.3 寫通道仲裁的特殊性AW、W、B三個通道的配合很多剛開始接觸AXI仲裁的人會犯一個錯誤只仲裁AW通道忽略了W通道。實際上寫操作涉及三個通道AW寫地址、W寫數(shù)據(jù)、B寫響應(yīng)。如果AW和W的仲裁策略不一致就會出現(xiàn)地址通道選了master A數(shù)據(jù)通道卻傳著master B的數(shù)據(jù)結(jié)果這兩個master的寫操作互相串?dāng)_。為了保證寫操作的正確性仲裁器通常需要把AW和W通道綁定在同一仲裁域里。也就是說當(dāng)仲裁器決定為master A的寫操作打開閘門時它的AW請求和W請求都必須被同時放行。這帶來一個數(shù)據(jù)緩沖的問題如果下游slave暫時無法接收W數(shù)據(jù)仲裁器要把master A的寫數(shù)據(jù)緩存下來這就涉及FIFO深度設(shè)計。AW和W還有一個同步問題AXI協(xié)議不要求W數(shù)據(jù)和AW請求嚴(yán)格同拍到達但要求所有W數(shù)據(jù)必須在對應(yīng)的AW請求之后到達。仲裁器需要記錄每個master的寫請求狀態(tài)確保不會出現(xiàn)AW還沒放行W數(shù)據(jù)先到的情況。實際實現(xiàn)中最簡單的策略是AW和W按同一個仲裁結(jié)果走仲裁為誰服務(wù)就把兩個通道的閘門都打開。3.4 多master訪問DDR時的死鎖與屏障處理多master并發(fā)訪問DDR時最頭痛的問題是死鎖??紤]一個場景master A正在對slave X做讀操作master B正在對slave Y做寫操作而這兩個slave內(nèi)部又相互依賴。仲裁器如果不加約束理論上就可能互相等待。AXI協(xié)議本身沒有定義屏障Barrier機制但AXI4增加了屏障事務(wù)Barrier Transaction的概念當(dāng)一個master發(fā)出屏障請求時它要求在此之前所有outstanding的傳輸都完成之后的新傳輸才能開始。仲裁器在收到屏障請求后需要暫時停止對這個master放行新請求直到它的所有未完成傳輸全部返回。系統(tǒng)級死鎖的預(yù)防還需要考慮更宏觀的因素——比如CPU核和DMA之間通過外設(shè)寄存器的握手邏輯。如果CPU在等待DMA完成中斷而DMA又在等待CPU釋放某個外設(shè)鎖兩邊都卡在總線訪問上系統(tǒng)就死鎖了。這類問題通??砍瑫r計數(shù)器來兜底仲裁器里的每筆請求都應(yīng)該維護一個超時標(biāo)志超時后強制丟棄或上報。4. 實操從零搭建一個AXI仲裁器4.1 接口設(shè)計與仲裁狀態(tài)機下面給出一個精簡的AXI仲裁器設(shè)計思路重點展示地址通道的仲裁邏輯。這個設(shè)計假設(shè)有4個master端口每個端口都遵循AXI4協(xié)議仲裁器輸出到一個slave端口。module axi_arbiter #( parameter ID_WIDTH 4, parameter ADDR_WIDTH 32, parameter DATA_WIDTH 64, parameter N_SLAVES 4 )( input clk, input rst_n, // 4個master端口的AR通道輸入 input [N_SLAVES-1:0] ar_valid_i, output [N_SLAVES-1:0] ar_ready_o, input [N_SLAVES*ADDR_WIDTH-1:0] ar_addr_i, input [N_SLAVES*ID_WIDTH-1:0] ar_id_i, // 輸出到slave的AR通道 output reg ar_valid_o, input ar_ready_i, output reg [ADDR_WIDTH-1:0] ar_addr_o, output reg [ID_WIDTH-1:0] ar_id_o );仲裁器的核心是一個狀態(tài)機狀態(tài)包括IDLE、ARB、WAIT_HANDSHAKE。IDLE狀態(tài)檢測是否有AR請求ARB狀態(tài)根據(jù)仲裁算法選擇winnerWAIT_HANDSHAKE狀態(tài)等待slave的ar_ready握手完成后回到IDLE。如果采用輪詢算法還要維護一個指針寄存器。// 輪詢指針 reg [N_SLAVES-1:0] grant_ptr; wire [N_SLAVES-1:0] req_vec ar_valid_i; wire [N_SLAVES-1:0] masked_req req_vec ~(grant_ptr - 1); wire [N_SLAVES-1:0] grant masked_req ? (masked_req ~(masked_req - 1)) : (req_vec ~(req_vec - 1));上面這段是經(jīng)典的總線仲裁輪詢算法優(yōu)先服務(wù)當(dāng)前指針之后的最低有效位請求如果沒有再從最低位開始找。這個寫法簡潔高效FPGA綜合后只會占用很少的LUT。4.2 寫數(shù)據(jù)通道的FIFO緩沖與背壓處理地址通道仲裁只是第一步。為了讓寫數(shù)據(jù)W通道能夠與AW通道解耦仲裁器內(nèi)部通常需要為每個master設(shè)置一個寫數(shù)據(jù)FIFO。master的數(shù)據(jù)先寫入FIFO仲裁器按仲裁結(jié)果從對應(yīng)FIFO讀出數(shù)據(jù)送往slave。FIFO深度怎么選經(jīng)驗公式是FIFO深度 ≥ 最大突發(fā)長度 × 數(shù)據(jù)寬度 / 8以字節(jié)為單位如果max burst是16 beats數(shù)據(jù)寬度是64位8字節(jié)那FIFO深度至少要128字節(jié)。這里還要考慮burst類型和地址對齊的情況。實際項目中我一般會多留25%的余量因為AXI的W通道允許數(shù)據(jù)提前到達FIFO太淺會造成背壓。背壓Backpressure是AXI里一個重要的概念。當(dāng)FIFO滿時仲裁器必須拉低W通道的ready信號這相當(dāng)于告訴master“我暫時收不了數(shù)據(jù)”。這個信號會一級一級向上游傳遞最終可能讓DMA暫停搬運。如果背壓處理不好就可能出現(xiàn)總線上某個master長時間占有數(shù)據(jù)通路、而其他master被餓死的現(xiàn)象。為了解決這個問題我給仲裁器的每個FIFO都加了一個almost_full信號當(dāng)FIFO快滿時就不再對該master進行仲裁。這個細節(jié)在實際調(diào)試中幫了大忙否則DMA在突發(fā)傳輸中途被插斷恢復(fù)起來非常影響性能。4.3 讀數(shù)據(jù)返回通道的仲裁與ID重映射讀數(shù)據(jù)通道R的仲裁和寫數(shù)據(jù)通道不同。R通道方向是從slave返回master仲裁器需要把從slave收到的讀數(shù)據(jù)分發(fā)給對應(yīng)的master。這里的關(guān)鍵是ID信號slave返回數(shù)據(jù)時帶上ID仲裁器通過ID判斷這筆數(shù)據(jù)屬于哪個master。但如果多個master的ID空間重疊——比如都用了ID 0、1、2——仲裁器就必須做ID重映射。通常的做法是給每個master的ID增加高位前綴將master編號編入ID。比如master 0的ID保持原樣master 1的ID最高位加1依此類推。slave端看到的ID就是唯一的返回時仲裁器根據(jù)高位前綴決定數(shù)據(jù)分發(fā)到哪個master再把前綴去掉。這種方案在Xilinx的AXI Interconnect里也采用了類似的機制叫做ID Width Adaptation。值得注意的是ID重映射會改變ID的總線寬度如果原設(shè)計里ID寬度是4位4個master映射后slave端ID可能需要6位。這會影響后續(xù)slave的設(shè)計務(wù)必提前規(guī)劃。4.4 驗證方法直接看時序圖比什么都直觀仲裁器設(shè)計的驗證除了跑仿真外我還習(xí)慣抓取總線時序圖來人工檢查。重點看幾個信號arb_grant當(dāng)前仲裁勝利者、ar_ready地址通道握手、以及各master的ar_valid。抓時序圖時最容易發(fā)現(xiàn)的問題是仲裁切換過快或過慢。仲裁切換過快一個master還沒發(fā)完一筆突發(fā)請求就被切走會導(dǎo)致slave端收到碎片化的請求序列切換太慢則可能在其他master有高優(yōu)先級請求時仍然占用總線。一個常見的時序圖場景是master A的ar_valid持續(xù)拉高但ar_ready只在某些周期有效。如果仲裁器在ar_ready無效時切換了grant下一拍ar_ready有效時slave端看到的可能是master B的請求這時master A的請求就被“餓”了一拍。好的仲裁器設(shè)計應(yīng)該在grant切換和握手完成之間插入一個同步邏輯確保grant只在握手完成后的空拍切換。這些細節(jié)都可以從波形上直觀觀察到。5. 線上調(diào)試中的常見問題與排查技巧5.1 問題速查表癥狀可能原因排查方法DMA傳輸數(shù)據(jù)錯亂寫數(shù)據(jù)通道仲裁與地址通道不一致抓W和AW通道波形對比仲裁結(jié)果UART/串口亂碼低優(yōu)先級master被餓死FIFO溢出檢查仲裁策略提高UART優(yōu)先級或加輪詢總線延遲抖動大fixed priority下高優(yōu)先級請求過于頻繁改用RRQOS混合仲裁或增加權(quán)重讀數(shù)據(jù)返回亂序錯亂ID重映射錯誤多個master的ID沒有隔離檢查仲裁器的ID映射表系統(tǒng)卡死總線一直busyoutstanding計數(shù)溢出或死鎖加超時計數(shù)器檢查屏障處理帶寬遠低于預(yù)期仲裁周期太長FIFO背壓頻繁配置仲裁器預(yù)取模式增加FIFO深度5.2 實測案例AXI UART16550的DMA傳輸異常這個案例我印象特別深。項目里用了一個帶AXI接口的UART16550核收發(fā)數(shù)據(jù)走DMA。DMA通過AXI總線訪問UART的寄存器FIFO實際上就是AXI讀寫寄存器操作但請求頻率不高——每次就4字節(jié)的讀或?qū)?。系統(tǒng)里還有一個千兆以太網(wǎng)MAC其DMA會發(fā)起長突發(fā)讀和寫DDR。一開始UART在現(xiàn)代調(diào)試串口上偶爾丟字符沒太當(dāng)回事直到有一天從FPGA上采集到UART的DMA請求延遲超過了100微秒才意識到問題嚴(yán)重。排查過程是這樣的先看仲裁器的grant信號發(fā)現(xiàn)UART的AXI讀請求雖然一直有效但grant經(jīng)常被以太網(wǎng)MAC搶走。仲裁策略是固定優(yōu)先級以太網(wǎng)MAC的優(yōu)先級高于UART。后來我改成了加權(quán)輪詢給UART一個最低權(quán)重確保每個輪詢周期至少服務(wù)一次。改完之后抓波形UART DMA請求的服務(wù)間隔穩(wěn)定在2微秒以內(nèi)丟字符問題徹底消失。這個案例告訴我們仲裁策略的設(shè)計不能只盯著高帶寬設(shè)備低帶寬但實時性要求高的設(shè)備同樣需要照顧。從系統(tǒng)的角度看仲裁器應(yīng)該是一個“按需分配”的機構(gòu)而不是簡單的“強者恒強”。5.3 AXI Quad SPI與DDR讀寫并發(fā)時的帶寬分配另一個常見場景是AXI Quad SPIQSPI控制器和CPU同時訪問DDR。QSPI需要周期性讀寫Flash速度不快但每次訪問的延遲必須穩(wěn)定因為Flash的時序窗口很窄——如果QSPI的讀請求被DDR的長突發(fā)卡住太久Flash的讀命令就可能超時。我在這類設(shè)計里通常的做法是給QSPI控制器分配一個獨立的仲裁槽位即使它只有1/8的權(quán)重也能保證每個仲裁周期內(nèi)至少服務(wù)一次。這樣DDR的大塊讀寫可以吃滿剩余帶寬而QSPI的訪問延遲始終可控。另一種思路是讓QSPI走專用的低延遲路徑繞過主仲裁器。在SoC里這叫做側(cè)信道sideband專門給對延遲敏感但帶寬需求低的控制面通信使用。這個方案在復(fù)雜的SoC里經(jīng)??吹讲贿^會增加布線復(fù)雜度。選擇哪種方案需要綜合評估系統(tǒng)對延遲的容忍度和對布局面積的約束。5.4 驗證過程中值得注意的邊界情況仲裁器的驗證最容易漏掉的是邊界情況。我總結(jié)了幾類必測的場景多個master同時發(fā)起請求且ID完全相同驗證ID重映射的正確性。master在握手期間突然拉低valid這在協(xié)議里是違法的仲裁器應(yīng)該能容忍并記錄錯誤。outstanding計數(shù)達到上限后master繼續(xù)發(fā)出請求仲裁器必須忽略多余的請求并反壓。某個slave長時間不響應(yīng)仲裁器應(yīng)該能通過超時機制釋放總線否則整個系統(tǒng)會被一個slave拖死。上電復(fù)位瞬間仲裁器指針初始值可能隨機必須確保不會把grant輸出到?jīng)]有請求的master。這些邊界場景如果只用隨機約束仿真很難全部覆蓋。我推薦的做法是在驗證環(huán)境里直接定向?qū)戇@些case每個case都配合波形來確認。對于超時機制還要額外驗證超時時間參數(shù)是否可配置方便后期調(diào)試。6. 我對AXI仲裁器設(shè)計的一些心得做了幾年AXI相關(guān)的IP集成和調(diào)試我對仲裁器最大的感觸是它看似簡單實則處處是權(quán)衡。你很難設(shè)計出一個在所有場景下都最優(yōu)的仲裁器所以好的設(shè)計者一定是先搞清楚系統(tǒng)的真實需求再選擇合適的仲裁策略。如果你正在做一個對帶寬不敏感的小系統(tǒng)固定優(yōu)先級仲裁足夠用省資源、時序好、行為可預(yù)測。如果你面對的是多master、多業(yè)務(wù)的SoC那就要認真考慮輪詢、加權(quán)和QOS的組合。沒有萬能的仲裁器只有適配具體場景的仲裁器。最后分享一個調(diào)試技巧遇到AXI總線相關(guān)的性能問題時不要一上來就看代碼或者仿真先抓一段真實總線波形。波形能直觀告訴你哪個master在占總線、哪個master在等待、仲裁器的grant切換頻率是多少。很多時候波形的異常一眼就能定位問題比盲猜代碼高效得多。下一篇文章里我打算聊聊AXI的outstanding和ID管理這套機制和仲裁器配合得好不好直接決定了多master系統(tǒng)的最終性能。到時候把亂序返回、ID寬度擴展、以及和DDR控制器交互的那些坑一起講清楚。