同設(shè)計:FPGA帶IP核工程的時序收斂與效率優(yōu)化)
做過大型FPGA工程的朋友應(yīng)該都有過這種體驗RTL寫起來很快真正折磨人的是綜合布局布線那動輒幾個小時的等待以及怎么調(diào)都收不攏的時序。我?guī)н^好幾版帶高速接口和復(fù)雜IP核的工程早期全部壓在Vivado一條流水線里每次迭代都像在熬鷹。后來切換到Synplify與Vivado協(xié)同設(shè)計的流程綜合時間縮短了將近一半時序收斂的迭代次數(shù)也明顯減少。這篇文章就圍繞這套協(xié)同設(shè)計方法聊聊帶IP核的FPGA工程到底該怎么組織、怎么跑通、有哪些坑必須避開。這套流程的核心價值在于讓專業(yè)工具干專業(yè)的事Synplify負責(zé)邏輯綜合和時序預(yù)估Vivado只專注在布局布線和最終實現(xiàn)上。對于使用Aurora、CAN-FD、FFT、除法器等IP核的工程尤其是圖像處理、信號發(fā)生器、串口升級這些需要反復(fù)迭代的項目這套協(xié)同設(shè)計帶來的收益非??捎^。不管你是在校學(xué)生做FPGA入門課設(shè)還是工程師在推進量產(chǎn)級項目下面這些基于實際項目踩坑總結(jié)出來的流程和心得都能直接用得上。1. 為什么在Vivado時代還要用Synplify做綜合先解決一個最常見的疑問Vivado自帶綜合引擎已經(jīng)很成熟了為什么還要繞一圈用Synplify綜合完再導(dǎo)回Vivado布局布線這個問題的答案要從綜合這個環(huán)節(jié)的本質(zhì)說起。1.1 Synplify的差異化優(yōu)勢到底在哪里綜合的本質(zhì)是把RTL代碼翻譯成由查找表和觸發(fā)器構(gòu)成的網(wǎng)表。Vivado自帶綜合器在標(biāo)準(zhǔn)流程下表現(xiàn)不錯但Synplify在幾個關(guān)鍵維度上有明顯優(yōu)勢。首先是綜合策略的成熟度。Synplify在FPGA領(lǐng)域耕耘了二十多年它的有限狀態(tài)機優(yōu)化、資源共享、retiming這些算法經(jīng)過大量工業(yè)級項目的打磨綜合出來的網(wǎng)表在面積和頻率上通常比默認綜合結(jié)果更好。其次是綜合速度。我?guī)н^一個包含DDR控制器、PCIe硬核和視頻處理邏輯的工程RTL代碼量大概在十幾萬行Vivado默認綜合需要跑三四十分鐘Synplify在相同機器上十分鐘左右就能跑完。這個速度差異在頻繁修改RTL做驗證的階段非常寶貴每次綜合省二十分鐘一天迭代十幾輪省出來的時間相當(dāng)可觀。第三是跨平臺和版本迭代的靈活性。Synplify可以獨立于Vivado版本運行對于使用多種FPGA平臺的團隊統(tǒng)一用Synplify做綜合可以保證綜合結(jié)果的一致性不會因為Vivado版本更新導(dǎo)致綜合策略變化。這一點在團隊協(xié)作中常被忽視但實際影響很大。第四個優(yōu)勢也是我覺得最關(guān)鍵的一點是Synplify對時序的早期預(yù)估能力。它在綜合階段就能依據(jù)物理約束做粗略的時序估算告訴你哪條路徑可能時序緊張。這意味著時序問題可以在綜合階段就暴露出來而不是等到布局布線跑完才被一通亂報嚇一跳。1.2 什么樣的工程適合走協(xié)同設(shè)計流程不是所有工程都需要Synplify和Vivado協(xié)同設(shè)計。我總結(jié)下來具備以下特征的工程比較適合走這套流程。首先是IP核數(shù)量多、類型復(fù)雜的工程。比如用到Aurora 8B/10B高速收發(fā)器、CAN-FD控制器、各類DSP IP核的工程IP核的綜合結(jié)果直接影響整體時序Synplify對IP核網(wǎng)表的處理更加精細。特別是使用Xilinx的Aurora IP它的GT復(fù)位邏輯和時鐘結(jié)構(gòu)非常復(fù)雜用Synplify綜合時對復(fù)位和時鐘樹的處理更容易滿足要求。其次是邏輯規(guī)模大、時序約束緊的工程。當(dāng)工程資源利用率超過60%或者主頻要求接近器件極限時綜合質(zhì)量對布局布線的影響會急劇放大。Synplify綜合出的網(wǎng)表質(zhì)量在這種場景下更穩(wěn)定。第三是需要頻繁迭代RTL邏輯的項目。比如FPGA圖像處理算法調(diào)試階段經(jīng)常要改幾行代碼就跑一次綜合看效果。用Synplify做綜合等于把整個迭代周期壓縮了。1.3 什么時候不建議用協(xié)同設(shè)計說句公道話Synplify也不是萬能的。如果你的工程只用了一兩個標(biāo)準(zhǔn)IP核邏輯規(guī)模也不大直接用Vivado一條龍反而更省事。原因很簡單多一個工具就多一層銜接成本EDIF網(wǎng)表的生成、約束文件的轉(zhuǎn)換、IP核的重新定位每一步都可能引入新的問題。另外如果工程大量依賴Vivado獨有的綜合特性比如使用Vivado的自動流水線插入、全局時鐘緩存優(yōu)化等那強行套用Synplify反而可能丟掉這些優(yōu)化機會。我在實際中遇到過類似情況某個工程大量使用Vivado的宏和綜合屬性Synplify綜合后功能雖然正確但性能和資源比Vivado直接綜合差了不少。所以協(xié)同設(shè)計是一個可選工具不是一個必選流程。明確這一點后面做方案選型思路會清晰很多。2. 協(xié)同設(shè)計的整體思路與工程組織如果決定走協(xié)同設(shè)計先別急著開工具花點時間把工程結(jié)構(gòu)理清楚。協(xié)同設(shè)計最怕的就是兩個工具各管一段、接口混亂。下面這套工程組織方式是我在多個項目里驗證過的能夠有效減少銜接階段的低級錯誤。2.1 雙工具流水線的核心流程協(xié)同設(shè)計的核心流水線說白了就是四個環(huán)節(jié)IP核生成、邏輯綜合、網(wǎng)表交付、布局布線。整個流程中設(shè)計源文件只有一個來源所有RTL代碼統(tǒng)一維護IP核統(tǒng)一在Vivado中生成Synplify只做綜合和網(wǎng)表輸出最后的布局布線又回到Vivado完成。這種流水線里最需要嚴格管控的是IP核。很多項目習(xí)慣在Vivado里生成IP核后直接例化使用但在協(xié)同設(shè)計流程里IP核文件需要分兩路走一路是RTL仿真模型給仿真用另一路是綜合網(wǎng)表交給Synplify做綜合。如果IP核版本沒對齊很容易出現(xiàn)仿真通過但綜合后功能對不上的情況。2.2 IP核在哪里生成與維護聽過一種說法說協(xié)同設(shè)計要把IP核拿到Synplify里去生成這個說法并不準(zhǔn)確。Synplify對Xilinx IP核的處理方式是“讀入并識別”不是“生成”。IP核本身必須由Vivado生成Synplify做的是把IP核的網(wǎng)表文件讀入到綜合流程中和用戶邏輯一起進行綜合優(yōu)化。具體操作時每個IP核在Vivado中生成后會附帶一個工程文件里面包含IP核的所有配置參數(shù)和生成文件列表。在Synplify中需要將這個工程文件或者IP核的網(wǎng)表文件添加到工程里。以Vivado生成一個FIFO IP核為例生成完成后要把IP核的輸出網(wǎng)表文件通常是NGC或EDIF格式以及相關(guān)的約束文件都納入工程管理。這里有一個容易踩坑的點。Vivado不同版本生成的IP核文件格式可能不一樣。使用較老版本IP核時生成的是NGC格式用新版Vivado生成時可能輸出的是EDIF或其他格式。Synplify對這兩種格式的支持程度不同導(dǎo)致綜合結(jié)果也會不同。我踩過這個坑同一個DDR控制器IP核在Vivado 2018.2版本下生成后Synplify綜合沒問題換到Vivado 2020.2生成后Synplify綜合直接報錯原因是網(wǎng)表格式和約束文件的兼容性問題。解決方案是查Synplify版本對應(yīng)的Xilinx IP核支持列表必要時做版本匹配。2.3 工程目錄與版本管理的幾點建議協(xié)同設(shè)計工程的目錄組織直接決定了交接效率。推薦用下面的結(jié)構(gòu)組織工程文件rtl/存放所有RTL源碼包括頂層、子模塊和IP核的例化文件ip/存放Vivado生成的所有IP核文件按IP核名稱分子目錄syn/存放Synplify工程文件、綜合腳本和綜合結(jié)果constraints/存放時序約束和物理約束文件impl/存放Vivado布局布線工程、比特流和調(diào)試文件sim/存放仿真測試文件和波形這套結(jié)構(gòu)有兩點好處。一是職責(zé)清晰每個工具都有自己的工作目錄不會互相污染二是方便腳本化后續(xù)要跑自動化回歸只需要在syn/目錄下執(zhí)行綜合腳本再到impl/目錄下執(zhí)行布局布線腳本不用到處找文件。版本管理方面建議把所有源文件納入Git管理但生成文件不要提交。尤其是Synplify生成的各種中間網(wǎng)表文件體積大且每次綜合都會變化提交到Git里只會帶來無盡的沖突和倉庫膨脹。IP核的生成文件原則上也不提交團隊協(xié)作時每個人都應(yīng)該有自己的本地IP核生成路徑提交ip/目錄下的IP核配置描述文件即可。2.4 工具版本匹配的注意事項版本匹配問題在協(xié)同設(shè)計里被討論得最多也是最容易被忽視的。Synplify和Vivado的版本如果不匹配輕則綜合結(jié)果不理想重則直接無法識別IP核或報錯中斷。這里分享一個務(wù)實的匹配策略不要追求版本完全對應(yīng)而是以Synplify的IP核支持清單為準(zhǔn)。每次Synplify發(fā)布新版本都會附帶一個詳細的支持列表標(biāo)明該版本支持哪些廠商的哪些器件型號以及IP核的哪些版本。在開始一個項目之前先確定Synplify版本再根據(jù)支持列表選擇Vivado版本。比如如果你用的Synplify版本明確支持Vivado 2020.2生成的IP核那就統(tǒng)一用Vivado 2020.2不要團隊里有人用2019.1、有人用2021.1。還有一點IDEA模式下的IP核管理。Synplify通過IP核識別時需要指定IP核的生成目錄。這些目錄在Vivado中生成IP核時是絕對路徑換一臺機器就失效了。所以協(xié)同設(shè)計通常要打開Synplify的“Use Relative Paths”之類的選項讓工程相對路徑化這樣才能保證在不同機器上都能打開工程。這個細節(jié)在團隊協(xié)作中非常關(guān)鍵解決不了這個每次換機器都要重新指定一遍IP核路徑非常痛苦。3. 實操流程從RTL到比特流的完整鏈路理論說了一大堆接下來進入實操環(huán)節(jié)。這個部分我會按照完整流程逐步拆解從IP核生成、Synplify綜合、約束處理到Vivado布局布線每一步都給出可以直接操作的方法。3.1 第一步在Vivado里生成和配置IP核在Vivado中生成IP核是協(xié)同設(shè)計的起點。具體操作是在Vivado中新建一個IP核或打開已有的IP核工程配置好參數(shù)后生成輸出文件。這里有幾個參數(shù)需要額外注意。首先是IP核的輸出文件格式盡量選擇EDIF或NGC格式作為綜合網(wǎng)表輸出。在Vivado的IP核自定義設(shè)置中通常有輸出產(chǎn)品選項比如綜合網(wǎng)表、仿真模型、約束文件等。在協(xié)同設(shè)計流程里綜合網(wǎng)表中的EDIF文件是Synplify做綜合時主要使用的文件。其次是IP核的約束文件處理。Vivado為每個IP核生成的約束文件包括引腳約束、時序約束和區(qū)域約束。這些約束文件在協(xié)同設(shè)計中需要統(tǒng)一收集后續(xù)交給Synplify或者Vivado使用。比較穩(wěn)妥的做法是在生成IP核時設(shè)置輸出約束文件到一個特定目錄比如放在constraints/ip目錄下后續(xù)統(tǒng)一處理。第三是復(fù)位和高電平有效這類配置選項。Aurora IP核里關(guān)于GT復(fù)位、power_down的配置和CAN-FD IP核的中斷配置直接決定了后續(xù)RTL邏輯的接口語義。務(wù)必在Vivado配置階段把每個接口搞清楚否則后面到了Synplify里要根據(jù)IP核接口改RTL那代價就大了。3.2 第二步Synplify綜合與約束傳遞IP核準(zhǔn)備妥當(dāng)后打開Synplify新建一個綜合工程。RTL源碼的添加方式很直接把所有.v或者.vhd文件加進工程。這里有個小建議把RTL文件按模塊分目錄管理添加到Synplify工程時也保持同樣的目錄層級這樣綜合報告定位模塊時會更直觀。IP核的添加方式有兩種。一種是直接把Vivado生成的EDIF網(wǎng)表文件作為輸入添加進去另一種是使用Synplify的IP核管理功能。兩種方式在普通工程中差別不大但對于包含大量IP核的工程第二種方式更推薦因為Synplify能自動識別IP核之間的依賴關(guān)系并且能正確讀取IP核的約束文件。約束文件的處理是協(xié)同設(shè)計的核心環(huán)節(jié)之一。Vivado工程使用XDC格式的約束而Synplify綜合時使用SDC格式的約束。這兩個約束格式并不完全等價XDC中包含的大量物理約束和時序例外在SDC中都無法完整表達。操作上可以這樣處理在Synplify中設(shè)置時序約束時只設(shè)置核心的時鐘周期、輸入輸出延遲等基礎(chǔ)約束用于指導(dǎo)綜合器做時序優(yōu)化而物理約束和詳細的時序例外則保留在XDC中等網(wǎng)表交付給Vivado后讓布局布線工具去處理。在綜合屬性設(shè)置上有幾點經(jīng)驗值可以參考。對于目標(biāo)頻率建議把約束的時鐘周期設(shè)置得比實際需求略嚴格一些預(yù)留5%到10%的余量。這個“超頻設(shè)約束”的做法是因為Synplify綜合階段的時序估算和最終布局布線的真實延遲存在偏差留出余量可以避免網(wǎng)表交到Vivado后大量路徑違反時序。頻率策略選擇“Performance Balanced”這個選項在面積和速度之間相對均衡適合大多數(shù)工程。映射選項方面如果資源足夠可以嘗試開啟“Use Full Mapping”或類似的選項讓綜合器做更充分的邏輯優(yōu)化。完成約束設(shè)置后點擊綜合按鈕開始綜合。綜合完成后重點看三個方面時序報告中的最差負時序裕量、資源利用率報告、以及警告信息。如果最差負時序裕量為負說明存在路徑不滿足時序要求需要回到RTL層或約束層做優(yōu)化。資源利用率方面如果查找表或觸發(fā)器使用率超過70%需要檢查是否存在冗余邏輯或優(yōu)化空間。警告信息里經(jīng)常包含未連接端口、多驅(qū)動信號等潛在問題建議逐條查看不要直接忽略。3.3 第三步把EDIF網(wǎng)表交還給Vivado布局布線Synplify綜合完成后會輸出多種文件其中最核心的是EDIF格式的網(wǎng)表文件。在Synplify工程中將綜合結(jié)果導(dǎo)出為EDIF網(wǎng)表這就是交給Vivado做布局布線的源文件。在Vivado側(cè)新建一個工程器件型號必須和Synplify綜合時選的型號一致否則在導(dǎo)入網(wǎng)表時會報錯。工程的RTL源碼不需要再添加了因為Synplify已經(jīng)綜合成了網(wǎng)表Vivado只需要網(wǎng)表文件和約束文件就能完成布局布線。導(dǎo)入EDIF網(wǎng)表后還需要添加同步生成的約束文件。建議把XDC約束文件中的時序約束包括時鐘定義、輸入輸出延遲等和物理管腳約束都加進去。如果約束文件之前在Synplify里同步做過設(shè)置這里需要注意避免約束重復(fù)。一個常見問題是同樣的時鐘約束在SDC和XDC里各定義了一次導(dǎo)致Vivado布局布線時報告約束沖突。解決辦法是在Synplify綜合時不導(dǎo)出時序約束文件只保留物理管腳約束在XDC中時序約束統(tǒng)一在Vivado側(cè)管理。但如果不熟悉兩邊的約束分工更穩(wěn)妥的做法是在Vivado側(cè)只保留管腳約束和物理約束時序約束全部從Synplify導(dǎo)入后在Vivado中重新生成和審查。導(dǎo)入完成后運行布局布線。如果一切正常會生成比特流文件可直接用于硬件調(diào)試或固件發(fā)布。到這里Synplify和Vivado協(xié)同設(shè)計的基本流程就走通了。3.4 第四步時序收斂與設(shè)計迭代布局布線完成后第一件事不是急著生成比特流而是打開時序報告查看最差負時序裕量和總負時序裕量這兩個關(guān)鍵指標(biāo)。如果時序違規(guī)嚴重先回Synplify調(diào)整綜合約束不要直接在Vivado里硬調(diào)布局布線選項。這是因為布局布線層面的優(yōu)化手段有限能做的無非是改變布局策略、優(yōu)化時鐘樹等效果往往不理想。而回到綜合階段可以通過調(diào)整約束、修改RTL流水線結(jié)構(gòu)、調(diào)整寄存器復(fù)制策略等方式從源頭解決問題。我在多次實踐中發(fā)現(xiàn)時序違規(guī)的根因大多數(shù)在RTL設(shè)計層面比如組合邏輯鏈路過長、復(fù)位邏輯時序不滿足、跨時鐘域路徑約束不當(dāng)?shù)?。?dāng)Synplify綜合后的時序報告顯示最差負時序裕量為正但Vivado布局布線后出現(xiàn)少量違規(guī)時可以嘗試在Vivado中調(diào)節(jié)布局布線策略。將布局布線模式設(shè)為Explore或者嘗試PerformanceExplore這些策略通過嘗試不同的布線算法組合來優(yōu)化時序。但要注意這些策略會顯著增加運行時間建議在集中收尾階段使用。時序收斂達標(biāo)后進入迭代設(shè)計階段。這里的迭代包括兩種情況一種是修改RTL代碼后重新綜合布局布線這時候只修改了部分邏輯理論上可以只對變化的部分做增量布局布線另一種是修改IP核配置后重新生成IP核此時需要重新在Synplify里做綜合。增量布局布線對工程管理要求較高我一般建議在工程穩(wěn)定之前還是做全量流程等設(shè)計凍結(jié)后再考慮增量手段。3.5 高帶寬IP核協(xié)同設(shè)計的細節(jié)處理在帶IP核的FPGA工程里Aurora 8B/10B、CAN-FD這些IP核的使用頻率很高而且它們的協(xié)同處理方式有特殊性。這里單獨說幾個細節(jié)。Aurora 8B/10B IP核的協(xié)同設(shè)計最需要注意的是GT復(fù)位邏輯。Aurora IP核的復(fù)位接口通常包括gt_reset和system_reset等這些復(fù)位信號直接影響GT收發(fā)器的初始化過程。在RTL中如果對復(fù)位信號做了同步處理或延遲處理在Synplify綜合時務(wù)必保證這些復(fù)位邏輯不被優(yōu)化掉。有幾次我在綜合工具里看到未連接的復(fù)位接口被自動優(yōu)化結(jié)果上板后發(fā)現(xiàn)Aurora鏈路無法建立。解決辦法是在RTL中把復(fù)位信號聲明為合理的屬性防止綜合器將其判定為無影響的冗余邏輯。CAN-FD IP核相對簡單但要注意時鐘域的劃分。CAN-FD控制器通常有總線時鐘域、處理器接口時鐘域和波特率時鐘域,不同時鐘域之間的握手信號必須經(jīng)過正確的同步。在Synplify綜合時如果跨時鐘域約束沒有在SDC中聲明綜合器可能將這些路徑當(dāng)作普通路徑處理導(dǎo)致布局布線后出現(xiàn)亞穩(wěn)態(tài)問題。建議在SDC中為每個跨時鐘域路徑添加set_false_path約束并配合RTL中的兩級同步器邏輯。另外FFT IP核、除法器等運算類IP核的協(xié)同設(shè)計相對直接因為它們通常是純組合邏輯和寄存器邏輯的組合不涉及太多跨時鐘域問題。但要注意FIFO IP核的讀時鐘和寫時鐘可能來自不同時鐘域這時候FIFO IP核的復(fù)位和時鐘約束同樣需要仔細設(shè)置。FIFO IP核使用異步時鐘時如果復(fù)位信號處理不當(dāng)會出現(xiàn)功能仿真通過但上板后數(shù)據(jù)錯位的問題。4. 常見問題與排查技巧實錄協(xié)同設(shè)計流程跑多了必然會遇到五花八門的報錯和異常。這里把我在多個項目里遇到的高頻問題整理成速查表并分享排查思路。4.1 Vivado DRC報錯與Implement變紅的經(jīng)典場景在協(xié)同設(shè)計流程里Vivado的DRC檢查經(jīng)常被觸發(fā)。特別是在布局布線完成后DRC報告里報出一堆RTSTAT-2錯誤很多新手就懵了。這個RTSTAT-2這類DRC規(guī)則的實質(zhì)是約束設(shè)置和實際物理實現(xiàn)之間的沖突。舉個例子XDC里如果一個管腳被分配到了某個BANK的低電壓域但實際連接的IP核或邏輯需要的電壓等級不同DRC就會報錯。在協(xié)同設(shè)計流程中由于管腳約束在XDC中定義而時序約束從Synplify導(dǎo)入兩邊信息不完整就很容易導(dǎo)致這類DRC報錯。排查思路是先分清DRC錯誤的具體類型是針對引腳、時鐘、還是區(qū)域的沖突然后針對性修改XDC。如果是引腳電壓域沖突修改引腳的IOSTANDARD屬性如果是時鐘約束沖突檢查是否在SDC和XDC中重復(fù)定義了時鐘。Implement變紅往往伴隨著DRC錯誤或布局布線資源不足這時候的排查優(yōu)先級是先處理DRC錯誤再檢查資源利用率最后才是時序違例。這里有一個經(jīng)驗DRC錯誤不要攢著到最后才看。Synplify生成的網(wǎng)表和Vivado中IP核的物理布局如果存在潛在沖突DRC檢查在布局布線前就應(yīng)該做一次作為獨立步驟運行。Vivado支持在布局布線前單獨運行DRC檢查盡早發(fā)現(xiàn)物理實現(xiàn)層面的沖突能在源頭上減少排錯成本。4.2 復(fù)位信號引起的跨時鐘域與亞穩(wěn)態(tài)問題FPGA設(shè)計中復(fù)位信號的處理是一個高頻踩坑點。在協(xié)同設(shè)計流程中復(fù)位信號的問題尤其隱蔽因為Synplify綜合時對復(fù)位信號的處理邏輯可能和Vivado直接綜合不一樣。先解釋一下亞穩(wěn)態(tài)。簡單來說當(dāng)觸發(fā)器的數(shù)據(jù)輸入在時鐘邊沿附近發(fā)生變化時觸發(fā)器的輸出可能進入一個不確定狀態(tài)既不是穩(wěn)定的高電平也不是穩(wěn)定的低電平這就是亞穩(wěn)態(tài)。如果這個不確定狀態(tài)被后續(xù)邏輯采樣就會導(dǎo)致功能錯誤。復(fù)位信號如果處理不當(dāng)很容易引起亞穩(wěn)態(tài)特別是異步復(fù)位信號在釋放時與時鐘邊沿關(guān)系不確定時。很多工程師在RTL里把異步復(fù)位、同步釋放掛在嘴邊但實際寫代碼時只做了一半。比如復(fù)位同步釋放邏輯只處理了復(fù)位釋放的同步但沒有處理復(fù)位拉低時的同步導(dǎo)致復(fù)位信號在不同模塊間釋放時間不一致出現(xiàn)系統(tǒng)部分模塊已經(jīng)運行、部分模塊還在復(fù)位的狀態(tài)。更隱蔽的情況是設(shè)計了復(fù)位同步邏輯但在Synplify綜合時沒有對復(fù)位信號設(shè)置合理的綜合屬性綜合器認為復(fù)位信號上連接的同步邏輯是冗余的直接優(yōu)化掉了。排查這類問題時先打開Synplify的綜合報告查看復(fù)位信號是否被推斷為全局復(fù)位網(wǎng)絡(luò)以及復(fù)位同步器的寄存器是否被保留。然后在Vivado布局布線后使用時序分析工具查看復(fù)位釋放路徑的時序裕量。這兩個步驟能覆蓋大多數(shù)復(fù)位問題。4.3 布局布線變紅并不全是時序問題有一次一個工程跑完布局布線直接把路由資源用爆了Implement直接變紅。第一反應(yīng)是邏輯規(guī)模太大但仔細排查后發(fā)現(xiàn)問題的根因不在邏輯規(guī)模而在時鐘資源分配不合理。問題出在我用的是同步時鐘卻在RTL里通過時鐘分頻創(chuàng)造了多個派生時鐘。在Synplify綜合時這些派生時鐘被識別為獨立的時鐘網(wǎng)絡(luò)綜合器為每個時鐘網(wǎng)絡(luò)都預(yù)留了獨立的時鐘資源。在布局布線階段這些時鐘網(wǎng)絡(luò)爭搶全局時鐘資源最終導(dǎo)致布線擁塞。排查這個問題的思路是通過Vivado的時鐘報告檢查所有時鐘網(wǎng)絡(luò)的物理資源使用情況。這種問題在協(xié)同設(shè)計里很常見因為綜合階段看到的是邏輯資源而布局布線階段才暴露物理資源沖突。解決辦法是在RTL里盡量減少邏輯分頻產(chǎn)生的時鐘改用FPGA的時鐘管理單元生成所需的時鐘這樣在綜合和布局布線時時鐘網(wǎng)絡(luò)規(guī)劃會更清晰。4.4 常用IP核的協(xié)同設(shè)計注意事項速查把幾種高頻使用的IP核在協(xié)同設(shè)計中的表現(xiàn)整理成一張速查表方便參考。IP核類型協(xié)同設(shè)計重點常見問題解決思路Aurora 8B/10BGT復(fù)位與初始化邏輯鏈路無法建立、誤碼率高檢查復(fù)位接口保留約束GT時鐘和復(fù)位路徑FIFO IP核異步時鐘與復(fù)位處理數(shù)據(jù)錯位、讀寫指針不同步約束跨時鐘域路徑確保復(fù)位同步釋放FFT IP核數(shù)據(jù)位寬與時序輸入時鐘受限、數(shù)據(jù)溢出在Vivado里配置位寬參數(shù)Synplify綜合時設(shè)置充分余量除法器IP核流水線結(jié)構(gòu)選擇延遲過大不滿足時序配置更高的流水線級數(shù)或改用并行結(jié)構(gòu)CAN-FD IP核多時鐘域同步總線數(shù)據(jù)錯誤、幀丟失完善跨時鐘域握手邏輯SDC設(shè)置false_pathROM/RAM IP核初始化文件路徑仿真正常但綜合后數(shù)據(jù)丟失將初始化文件路徑改為相對路徑確保Synplify能正確讀取這張表里列的每一條都是我在實際項目中遇到過或者同事反饋過的真實問題。ROM/RAM IP核初始化文件路徑這個問題特別想多說一句在Vivado中生成ROM IP核時如果指定的COE文件是通過絕對路徑引用的Synplify在綜合時可能因為找不到路徑而跳過初始化導(dǎo)致生成的網(wǎng)表里帶了空的存儲內(nèi)容。上板之后表現(xiàn)出來的現(xiàn)象就是讀出來的數(shù)據(jù)全是0仿真階段卻一切正常。這個坑非常隱蔽排查手段只有去Synplify的網(wǎng)表文件里檢查存儲器的初始化內(nèi)容。4.5 綜合面積與布局布線優(yōu)化的小技巧綜合面積和布局布線優(yōu)化是FPGA工程師的必修課。在協(xié)同設(shè)計流程里兩者的優(yōu)化手段有一些不同。綜合階段Synplify提供了多種綜合選項比如自動寄存器復(fù)制、資源共享、有限狀態(tài)機重新編碼等。開啟這些選項可以優(yōu)化面積和時序。但開啟之后一定要對比綜合報告因為有些選項對特定設(shè)計反而有害。比如資源共享在數(shù)據(jù)通路上通常有效但在控制邏輯上可能增加布線延遲反而讓時序變差。所以綜合選項不是開得越多越好而是要在每個工程里試驗后確定最優(yōu)組合。布局布線階段Vivado提供的物理優(yōu)化手段相對較少但有一個技巧很實用在綜合階段保留層次化結(jié)構(gòu)。也就是說讓Synplify在綜合時不要做全局扁平化而是保留模塊的層次邊界。這樣做的好處是在布局布線階段Vivado可以根據(jù)模塊邊界做更合理的物理布局避免邏輯碎片化。Synplify里有類似“Flatten”的選項建議保持關(guān)閉。還有一個細節(jié)容易被忽視FFT或濾波類IP核的輸入輸出位寬問題。FPGA圖像處理里經(jīng)常要算定點數(shù)如果IP核配置的是浮點接口在Synplify綜合時很可能無法正確映射到DSP48資源造成資源和時序的浪費。這種情況下的做法是在RTL層做定點數(shù)轉(zhuǎn)換IP核接口統(tǒng)一用定點數(shù)。我在圖像處理工程里吃過這個虧后來統(tǒng)一改定點數(shù)接口DSP48利用率從55%降到了30%左右時序收斂也輕松了不少。4.6 高速接口與專用硬核的處理建議帶Aurora、LVDS、QSPI這類高速接口的工程在協(xié)同設(shè)計里有一些特殊的處理建議。高速收發(fā)器接口的RTL邏輯和普通邏輯不同它們依賴于FPGA內(nèi)部的專用硬核資源比如收發(fā)器通道、高速時鐘管理單元等。在Synplify綜合時這些硬核資源不會被綜合成查找表和觸發(fā)器而是保持為原語實例。所以RTL代碼里必須使用Xilinx提供的原語模塊比如Aurora IP核內(nèi)部已經(jīng)封裝好了這些原語。RTL代碼里直接實例化這些IP核Synplify綜合時會把它們當(dāng)作黑盒處理。這個黑盒處理方式帶來了一個問題黑盒接口的時序無法在綜合階段預(yù)估。解決思路是在SDC里手動為這些黑盒接口設(shè)置合理的輸入輸出延遲讓綜合器有一個明確的時序目標(biāo)。否則綜合器會認為這些路徑?jīng)]有時序約束優(yōu)化時直接跳過到了Vivado布局布線階段才暴露時序問題而這時候修改RTL的代價已經(jīng)很大了。LVDS接口的協(xié)同處理相對簡單主要關(guān)注數(shù)據(jù)對齊和位滑移控制邏輯。這類邏輯通常在RTL中實現(xiàn)通過例化Xilinx的LVDS收發(fā)原語完成。在Synplify綜合時保持原語實例不被優(yōu)化是關(guān)鍵可以用綜合屬性來標(biāo)記這些原語。QSPI接口如果涉及Flash配置和Multiboot功能在協(xié)同設(shè)計流程中沒有額外負擔(dān)但有一點要和綜合工具強調(diào)QSPI接口相關(guān)的時序約束通常是寬松的建議在SDC中設(shè)置成set_false_path或者較寬松的multicycle path避免給布局布線工具增加不必要的約束難度。5. 協(xié)同設(shè)計的效率提升與團隊協(xié)作流程跑通之后下一步就是優(yōu)化效率特別是團隊多人協(xié)同時。這一節(jié)分享腳本化、自動化方面的實踐以及多人協(xié)作時容易忽略的細節(jié)。5.1 用腳本把重復(fù)勞動自動化協(xié)同設(shè)計流程里重復(fù)性的操作很多打開工具、添加文件、設(shè)置約束、跑綜合、跑布局布線這些可以通過腳本一口氣完成。Synplify支持通過命令行方式運行工程也支持使用Tcl腳本。在工程穩(wěn)定之后把綜合流程腳本化每次修改RTL后只需要運行一條命令就能完成綜合。記得把綜合次數(shù)、綜合時間、時序結(jié)果輸出到日志文件里方便追溯。Vivado側(cè)同樣支持Tcl腳本。布局布線的腳本化需要注意一點每次運行前清空之前的布局布線結(jié)果目錄否則可能因為存在殘留文件導(dǎo)致流程異常。腳本化還有一個附加好處CI集成。如果在服務(wù)器上建立了自動化流程每次代碼提交后自動跑一遍綜合加布局布線團隊每個人都能在第一時間看到自己修改對時序和資源的影響。這個能力對多人協(xié)作的FPGA團隊價值巨大能顯著減少集成階段的沖突和返工。5.2 IP核版本與參數(shù)凍結(jié)的協(xié)作規(guī)范團隊協(xié)作中最頭疼的問題之一就是IP核版本和參數(shù)不統(tǒng)一。兩個人同時改一個IP核的參數(shù)互相不知道最后集成到一起直接亂套。協(xié)同設(shè)計流程能夠天然緩解這個問題因為IP核統(tǒng)一在Vivado中生成只要約定好IP核的配置基線在版本管理上鎖定IP核的配置文件所有成員都從同一個基線生成IP核就不會出現(xiàn)版本漂移。具體操作上建議在Git中為每個IP核建立一個配置文件跟蹤機制。IP核的參數(shù)配置通常保存在一個配置文件里這個文件用文本格式記錄便于diff和版本比較。每個IP核參數(shù)變更都需要通過Merge Request流程由專人review合并后才允許團隊成員更新本地IP核。這個規(guī)范在Aurora這類復(fù)雜IP核上尤其重要。Aurora IP核的配置參數(shù)有幾十個包括線速率、通道數(shù)量、數(shù)據(jù)位寬、流控模式等任何一個參數(shù)不一致都會導(dǎo)致鏈路互連異常。把規(guī)范前置到IP核配置階段能節(jié)省大量聯(lián)調(diào)時間。5.3 時序報告與設(shè)計評審該看哪些關(guān)鍵指標(biāo)周期性地做設(shè)計評審是保證工程健康度的關(guān)鍵手段。在協(xié)同設(shè)計流程里評審時重點看幾個指標(biāo)綜合后的時序報告、布局布線后的時序差異、資源利用率變化趨勢、以及DRC報告中的警告數(shù)量。綜合后時序報告和布局布線后時序差異是重點。如果Synplify綜合后顯示時序滿足要求但Vivado布局布線后大量路徑不滿足說明綜合階段的時序預(yù)估和實際物理實現(xiàn)偏差過大。這通常意味著SDC約束設(shè)置有問題比如時鐘定義不完整、輸入輸出延遲設(shè)置不合理等。反過來如果綜合階段就報告時序違規(guī)那問題更大概率在RTL邏輯本身。資源利用率的變化趨勢也值得關(guān)注。如果每輪迭代資源都在漲需要及時定位是什么邏輯引起的。有些邏輯膨脹是正常的比如增加了新的功能模塊有些則是綜合策略導(dǎo)致的比如代碼風(fēng)格不合適、模塊復(fù)用不當(dāng)?shù)?。早發(fā)現(xiàn)早優(yōu)化總比到最后快收尾時發(fā)現(xiàn)資源不夠要強。DRC報告里的警告類型盡量清零。DRC警告雖然不會直接導(dǎo)致功能錯誤但往往是隱患的信號。一個不完整的I/O約束、一個未使用的時鐘域都可能在某個特定條件下變成真正的bug。建議每個迭代周期都目標(biāo)性地清理DRC警告保持工程健康。5.4 調(diào)試手段從Vivado到硬件的閉環(huán)帶IP核的工程上板調(diào)試是繞不開的環(huán)節(jié)。Synplify和Vivado協(xié)同設(shè)計流程中調(diào)試手段需要和純Vivado流程有所區(qū)分。一個重要區(qū)別是Synplify綜合后的網(wǎng)表在Vivado里是黑盒狀態(tài)。使用Vivado的ILA調(diào)試核時需要注意信號的可觀測性。ILA核的探針信號需要在綜合時保留但在Synplify綜合的網(wǎng)表里很多內(nèi)部信號可能已經(jīng)被優(yōu)化或重命名無法直接作為ILA探針。解決辦法是在RTL里用綜合屬性標(biāo)記需要保留的信號比如標(biāo)記為keep或mark_debug。另一個調(diào)試手段是使用Vivado的邏輯分析儀功能但前提是網(wǎng)表中的信號層次清晰。這就回應(yīng)了之前說的保留層次化結(jié)構(gòu)的重要性。如果Synplify綜合時把層次打平了Vivado的邏輯分析儀根本無法定位到具體信號調(diào)試就會變得非常困難。上板階段比特流生成和固話操作本身和純Vivado流程沒有區(qū)別。QSPI Flash的燒寫、Multiboot配置、固化程序的生成這些操作在Vivado硬件管理器中完成。唯一要注意的是固話用的比特流必須和最終驗證通過的布局布線結(jié)果一致不要在最后關(guān)頭為了省時間用舊比特流。6. 從經(jīng)驗到方法論我的幾點體會最后談幾點比較主觀的體會是我做完幾個協(xié)同設(shè)計項目后沉淀下來的想法。第一工具鏈的選擇要服務(wù)于迭代效率而不是服務(wù)于“用上了新工具”的成就感?,F(xiàn)在很多項目上來就要用最新的Vivado版本貪圖新特性但對于一個已經(jīng)跑得很穩(wěn)的工程升級工具鏈并帶來直接的收益反而平添變量。協(xié)同設(shè)計同樣如此如果你的工程規(guī)模不大、時序不緊用Vivado一條龍完全夠了不必強行上Synplify。我見過一些團隊為了追求協(xié)同設(shè)計而協(xié)同設(shè)計結(jié)果在IP核版本兼容上花費了大量時間反而降低了效率。第二時序問題的根因90%在RTL設(shè)計層面工具能做的只是錦上添花。經(jīng)過多個工程的數(shù)據(jù)積累我發(fā)現(xiàn)長期無法收斂的時序問題深層原因基本都是邏輯鏈路過長、跨時鐘域處理不當(dāng)、復(fù)位設(shè)計混亂這類RTL問題。Synplify的時序預(yù)估能力和Vivado的布局布線優(yōu)化只能緩解表面癥狀真正解決問題的路徑是審視設(shè)計本身。所以在跑工具之前先把RTL代碼評審一遍把能預(yù)見的時序問題提前消化掉。第三個人比較推薦的做法是把Synplify的快速綜合當(dāng)作設(shè)計過程中的日常檢查手段。不一定要把協(xié)同設(shè)計作為最終交付流程但在RTL開發(fā)階段每完成一個模塊就丟進Synplify快速綜合一次看看資源占用和時序預(yù)估。這個習(xí)慣能讓你在開發(fā)的早期就發(fā)現(xiàn)很多問題而不是等整個工程集成完才發(fā)現(xiàn)某個模塊把整塊邏輯拖垮了。這個習(xí)慣養(yǎng)成之后你會發(fā)現(xiàn)后期布局布線的迭代次數(shù)大大減少。第四PDCA的思路用在FPGA工程管理上同樣適用。每完成一個迭代周期記錄下這一輪的時序結(jié)果、資源使用、DRC報告、遇到的問題和解決方法。積累三輪之后回看你會發(fā)現(xiàn)問題集中在哪幾個方面然后有針對性的在RTL設(shè)計規(guī)范、約束文件管理、IP核配置這些環(huán)節(jié)做標(biāo)準(zhǔn)化改進。寫到這里這套基于Synplify與Vivado協(xié)同設(shè)計處理帶IP核FPGA工程的方法基本已經(jīng)完整鋪開了。無論是流程組織、IP核管理、約束處理還是時序收斂和團隊協(xié)作最終的目標(biāo)都是讓FPGA開發(fā)變得更可預(yù)測、更高效。我用這套流程完成了多個項目的交付每一次迭代優(yōu)化都在不斷印證同一條經(jīng)驗工具鏈只是手段真正決定項目成敗的還是對設(shè)計本身的理解和對流程細節(jié)的堅持。希望這篇基于實際項目踩坑經(jīng)驗寫下的文章能在你構(gòu)建或優(yōu)化自己的FPGA開發(fā)流程時提供一些真正有用的參考。