戰(zhàn)指南:從原理到工程應(yīng)用的系統(tǒng)梳理)
“FPGA”這個(gè)詞做硬件的人基本天天掛在嘴邊但真要一句話說清楚它是什么反而有點(diǎn)難開口。我從讀研開始接觸FPGA到現(xiàn)在做無線通信基帶處理快十年前后用過Altera的Cyclone系列、Xilinx的Spartan到Virtex UltraScale國產(chǎn)的復(fù)旦微也沒少折騰。這篇就當(dāng)是給準(zhǔn)備入門的同學(xué)、以及想了解FPGA實(shí)際價(jià)值的非FPGA工程師一份系統(tǒng)梳理把那些文檔里不寫、論壇里問不到的東西盡量說透。我見過太多人一上來就買開發(fā)板、跑流水燈然后卡在時(shí)序約束上懷疑人生。也見過軟件工程師轉(zhuǎn)過來寫出來的代碼綜合出來一大片LUT根本跑不了高速。問題出在哪兒出在只學(xué)“怎么操作”沒搞懂“為什么要這樣設(shè)計(jì)”。所以這篇文章我不會只堆概念而是盡量把原理、流程、坑點(diǎn)和真實(shí)項(xiàng)目里的取舍都拆開講基帶、接口、圖像、SoC這些方向都會覆蓋到。1. 先搞清楚FPGA為什么存在1.1 “硬件可以改”到底意味著什么FPGA的完整英文是Field Programmable Gate Array現(xiàn)場可編程門陣列。關(guān)鍵詞不是“門陣列”而是“現(xiàn)場可編程”——意思是芯片到了用戶手上你依然可以改變它內(nèi)部的電路功能。這是一個(gè)非常反直覺的特性因?yàn)閭鹘y(tǒng)芯片出廠即定型功能是死的而FPGA的電路結(jié)構(gòu)是可以反復(fù)燒寫的。用個(gè)生活化的類比CPU像一家固定菜單的飯店你只能從菜單里點(diǎn)菜菜的做法、上菜順序都是由后廚定的你改變不了ASIC像你包下整個(gè)后廚按你的需求定制灶臺和流程但一旦建好就不能改FPGA則像給你一堆食材、廚具和一個(gè)可自由布置的廚房烹飪方法寫在菜譜里而這個(gè)菜譜就是Verilog代碼隨時(shí)可以重寫隨時(shí)可以換菜。這就是FPGA最核心的價(jià)值兼顧了“硬件級的并行和低延遲”與“軟件級的可重構(gòu)性”。你可以把一段算法真正地用硬件邏輯實(shí)現(xiàn)而不是像CPU那樣一條一條指令取指執(zhí)行。代價(jià)是開發(fā)門檻更高代碼即電路寫代碼的過程本質(zhì)是在設(shè)計(jì)電路而不是在寫指令序列。很多人剛開始不適應(yīng)這個(gè)思維轉(zhuǎn)換就會覺得FPGA難。1.2 芯片內(nèi)部到底長什么樣FPGA內(nèi)部不是一堆無規(guī)則的門電路而是由幾種基本資源按陣列排布的。理解了這些資源你才能理解為什么某段代碼綜合出來占資源多、為什么某些設(shè)計(jì)跑不快??膳渲眠壿媺KCLB由查找表LUT和觸發(fā)器FF組成。LUT本質(zhì)上是一個(gè)小RAM輸入信號作為地址輸出是對應(yīng)地址里存的值。6輸入LUT可以實(shí)現(xiàn)任意6輸入布爾函數(shù)這是FPGA能實(shí)現(xiàn)任意邏輯的基礎(chǔ)。觸發(fā)器則用來寄存狀態(tài)構(gòu)成時(shí)序邏輯的基礎(chǔ)單元。塊RAMBRAM嵌入式的存儲陣列可以用來做FIFO、緩存、ROM。圖像處理里的行緩存、通信里的數(shù)據(jù)緩沖基本都靠BRAM實(shí)現(xiàn)。BRAM的容量和數(shù)量決定了你能否在片上存儲足夠多的中間數(shù)據(jù)。DSP Slice硬件乘法器、累加器專門為數(shù)字信號處理設(shè)計(jì)的。FIR濾波器、FFT、CIC補(bǔ)償濾波這些運(yùn)算密集型的模塊如果不走DSP Slice而是用LUT搭資源消耗和時(shí)序會非常難看。IO資源支持各種電平標(biāo)準(zhǔn)比如LVCMOS、LVDS、HSTL。熱詞里問的“dxn和dxp引腳”就是LVDS差分對的命名規(guī)則dxp是正極dxn是負(fù)極接差分信號時(shí)這兩個(gè)腳要成對使用布線時(shí)也要走差分線。高速串行收發(fā)器SerDesXilinx叫GTX/GTH/GTYIntel叫Transceiver。硬件上集成了高速串并轉(zhuǎn)換、時(shí)鐘恢復(fù)、編解碼邏輯支持PCIe、SRIO、萬兆以太網(wǎng)、JESD204B這些協(xié)議。硬核IP有些FPGA內(nèi)部直接集成了PCle硬核、DDR控制器硬核甚至ARM處理器比如Zynq。硬核性能和穩(wěn)定性遠(yuǎn)超邏輯實(shí)現(xiàn)的軟核能用硬核的場合默認(rèn)優(yōu)先用硬核。我經(jīng)常跟新人說FPGA設(shè)計(jì)其實(shí)是在“管理資源”——LUT、FF、BRAM、DSP、IO、SerDes這些資源是有限的你的設(shè)計(jì)能不能在這個(gè)資源預(yù)算內(nèi)實(shí)現(xiàn)、滿足時(shí)序要求才是真正考驗(yàn)功力的事。1.3 FPGA、CPU、GPU、ASIC到底怎么選在實(shí)際項(xiàng)目里選型從來不是“誰好誰壞”而是“誰更合適”。我把幾類器件的特性放在一起對比維度CPUGPUFPGAASIC計(jì)算模型串行指令流大規(guī)模并行SIMD并行流水線硬件邏輯專用硬件邏輯延遲高微秒級高微秒級極低納秒級極低納秒級確定性不確定受OS影響不確定強(qiáng)確定強(qiáng)確定靈活性軟硬件均可改軟件可改硬件可重構(gòu)出廠即定型功耗較高很高中等最低開發(fā)周期短中中長很長批量成本——中高攤薄后極低這套對比對應(yīng)到實(shí)際場景很清晰需要跑復(fù)雜的操作系統(tǒng)、復(fù)雜業(yè)務(wù)邏輯用CPU需要大量浮點(diǎn)并行計(jì)算、做AI訓(xùn)練用GPU需要極致低延遲、高確定性、算法還在迭代且批量不大比如軟件無線電、醫(yī)療設(shè)備、工業(yè)控制、高速信號采集用FPGA產(chǎn)品定死了、出貨量百萬級比如消費(fèi)電子芯片才值得去做ASIC。我常舉一個(gè)例子一個(gè)基站的數(shù)字中頻模塊要求處理時(shí)延嚴(yán)格可控算法還在根據(jù)現(xiàn)場情況迭代整機(jī)出貨量也就是幾千套這種場景FPGA是唯一合適的選擇。ASIC開發(fā)成本幾千萬起CPU延遲和并行度都達(dá)不到。這也是FPGA在通信、軍工、航天領(lǐng)域始終占有一席之地的根本原因。2. 開發(fā)流程與工具鏈“寫代碼”其實(shí)是“畫電路”2.1 語言選什么Verilog、VHDL、SystemVerilog還是HLS很多新手第一件事就是在論壇上問“學(xué)Verilog還是VHDL”這個(gè)問題其實(shí)早就不該糾結(jié)了。目前業(yè)界的事實(shí)標(biāo)準(zhǔn)是Verilog和SystemVerilog通信、接口、SoC這些領(lǐng)域幾乎全是Verilog的天下。VHDL在軍工和歐洲有些存量項(xiàng)目還在用但新項(xiàng)目已經(jīng)很少選了你可以了解不必深學(xué)。SystemVerilog在驗(yàn)證方面的能力遠(yuǎn)強(qiáng)于傳統(tǒng)Veriloginterface、class、斷言、覆蓋率這些特性做復(fù)雜IP驗(yàn)證、搭建UVM驗(yàn)證平臺的時(shí)候都繞不開。如果你未來的方向是做數(shù)字IC或大規(guī)模FPGA設(shè)計(jì)VerilogSystemVerilog是必選項(xiàng)。RTL設(shè)計(jì)部分用可綜合的Verilog子集驗(yàn)證部分用SystemVerilog。至于HLS高層次綜合用C/C描述算法然后自動生成RTL適合算法工程師快速評估硬件實(shí)現(xiàn)方案比如通信物理層算法、圖像處理算法。但它生成的電路質(zhì)量仍比不過手工RTL時(shí)序和資源控制精度也不夠。我的建議是算法探索階段用HLS加速評估產(chǎn)品化階段還是要落到RTL上精調(diào)。純做RTL的工程師也建議了解HLS因?yàn)楹退惴▓F(tuán)隊(duì)溝通時(shí)能聽懂他們在說什么。2.2 從RTL到比特流的完整流程FPGA的工程流程核心是一條從設(shè)計(jì)到比特流的流水線。以Xilinx Vivado為例完整過程是這樣的RTL設(shè)計(jì)寫Verilog/SystemVerilog代碼。代碼風(fēng)格、模塊劃分直接決定后端的時(shí)序和資源結(jié)果。功能仿真用testbench驗(yàn)證邏輯功能是否正確。這一步不涉及時(shí)序信息只驗(yàn)證功能。綜合Synthesis把RTL代碼映射到LUT、FF、DSP、BRAM這些實(shí)際資源上生成網(wǎng)表。綜合約束決定了面積和速度的優(yōu)化方向。實(shí)現(xiàn)Implementation包括布局Placement、布線Routing和時(shí)序優(yōu)化。布局把邏輯放到具體位置布線把它們連起來。這一步最耗時(shí)也是時(shí)序收斂的關(guān)鍵。時(shí)序分析檢查設(shè)計(jì)是否滿足建立時(shí)間、保持時(shí)間要求。時(shí)序不滿足功能再對也可能在某些條件下跑飛。生成比特流把最終的設(shè)計(jì)數(shù)據(jù)打包成下載文件通過JTAG或主動配置方式燒進(jìn)FPGA。Vivado里用Tcl命令可以完整跑一遍自動化流程實(shí)際項(xiàng)目中我都是這么干的read_verilog top.v read_xdc constraints.xdc synth_design -top top -part xc7k325tffg900-2 opt_design place_design route_design write_bitstream -force top.bit如果跑的是國產(chǎn)復(fù)旦微FPGA用的是Procise工具鏈流程類似但要特別注意器件庫和原語的差異。國產(chǎn)工具鏈這幾年進(jìn)步很快但某些IP的成熟度還有待提高跨平臺移植時(shí)不要想當(dāng)然。配置約束文件XDC里的時(shí)鐘約束是最基本也最重要的create_clock -period 10.000 -name sys_clk [get_ports clk]這條約束告訴工具clk這個(gè)端口的時(shí)鐘周期是10ns即100MHz。工具所有的時(shí)序優(yōu)化都是以此為基準(zhǔn)的所以這個(gè)約束要是錯(cuò)了后面全盤皆輸。2.3 仿真和在線調(diào)試真正花時(shí)間去磨的地方有了綜合、實(shí)現(xiàn)這一套流程后最大的問題是功能對不對時(shí)序滿不滿足這時(shí)候就需要仿真和在線調(diào)試兩大手段。功能仿真是FPGA開發(fā)中最花時(shí)間的一環(huán)。testbench里給激勵(lì)、檢查輸出邏輯錯(cuò)誤在仿真階段發(fā)現(xiàn)并修掉比在板子上用示波器查信號效率高一個(gè)數(shù)量級。我強(qiáng)烈建議RTL寫一段、仿真一段不要等整個(gè)模塊寫完了再一起仿真否則出了問題組合爆炸的debug范圍會讓你崩潰。module tb_uart_top(); reg clk; reg rst_n; reg rx; wire tx; uart_top dut( .clk(clk), .rst_n(rst_n), .rx(rx), .tx(tx) ); initial begin clk 0; rst_n 0; #100 rst_n 1; // 發(fā)送一個(gè)字節(jié) rx 1; #8700 rx 0; // start bit // ... 數(shù)據(jù)位、停止位 end always #5 clk ~clk; endmodule在線調(diào)試用的是FPGA廠商集成的邏輯分析儀IP。Xilinx叫ILAIntegrated Logic AnalyzerIntel叫SignalTap。原理都是把要觀察的信號實(shí)時(shí)采樣到BRAM里通過JTAG回傳到PC界面顯示波形。使用它的一個(gè)關(guān)鍵點(diǎn)是你想觀測的信號不能綜合時(shí)被優(yōu)化掉所以建議加(* keep true *)這類綜合屬性把信號固定下來。調(diào)試高速串行收發(fā)器時(shí)還有一套更專業(yè)的工具叫IBERT。它利用FPGA內(nèi)部的硬核收發(fā)器生成和檢查偽隨機(jī)序列能直接測量誤碼率、眼圖。調(diào)參數(shù)是重頭戲——發(fā)送端的預(yù)加重、擺幅接收端的均衡器、采樣點(diǎn)位置都要反復(fù)試。我調(diào)過的板子里誤碼率高的主要原因往往不是芯片壞了而是參數(shù)沒配對典型問題是差分走線過長又沒有做阻抗匹配這時(shí)候加大接收端均衡檔位往往能救回來。3. 實(shí)際項(xiàng)目里FPGA到底在跑什么3.1 無線通信與信號處理FPGA的核心主場FPGA在無線通信系統(tǒng)中的作用可以說就是它的誕生初衷。從2G到5G數(shù)字中頻、基帶處理、波束成形這些對處理延遲和并行度要求極高的工作基本都是FPGA在扛。熱詞里提到“fpga實(shí)現(xiàn)cic”“DVB-S2解調(diào)器fpga實(shí)現(xiàn)”都是典型的通信信號處理場景。CIC濾波器級聯(lián)積分梳狀濾波器是抽取/內(nèi)插最常用的結(jié)構(gòu)優(yōu)點(diǎn)是無需乘法器資源消耗極低適合在采樣率很高的地方做第一級抽取。它的積分器和梳狀器的結(jié)構(gòu)非常規(guī)則寫RTL時(shí)就照搬結(jié)構(gòu)關(guān)鍵是位寬計(jì)算。CIC濾波器每個(gè)積分器都會增長位寬增長量是log2(抽取倍數(shù)×差分延遲×級數(shù))向上取整算錯(cuò)了就會溢出輸出信號就會在“某個(gè)整數(shù)倍處突然跳變”。我見過有人直接把MATLAB仿真好的信號接進(jìn)來結(jié)果頻譜上一堆雜散就是因?yàn)槲粚挍]算夠。JESD204B則是當(dāng)前高速ADC/DAC和FPGA之間的主流接口標(biāo)準(zhǔn)從鏈路建立到確定性延遲都有一套復(fù)雜的握手協(xié)議。熱詞里“從鏈路建立失敗到頻譜干凈的完整復(fù)盤”寫得非常好這類問題的排查思路基本是固定的先看時(shí)鐘是否穩(wěn)定再看SYSREF是否滿足建立保持時(shí)間然后檢查鏈路參數(shù)組L、M、F、S、K是否匹配最后才懷疑數(shù)據(jù)通路的對齊問題。很多工程師在JESD204B上卡一周最后發(fā)現(xiàn)是參考時(shí)鐘抖動超標(biāo)。3.2 圖像處理與視頻流水線思維的最佳訓(xùn)練場圖像處理是FPGA另一大應(yīng)用方向熱詞里的“fpga圖像處理”“圖像畸變校正fpga”就是這個(gè)方向。圖像處理算法的特點(diǎn)是數(shù)據(jù)量大、逐像素處理天然適合流水線結(jié)構(gòu)。一幀1080p圖像大概200萬個(gè)像素要在毫秒級處理完CPU逐像素循環(huán)根本來不及FPGA流水線則可以做到每個(gè)時(shí)鐘周期處理一個(gè)甚至多個(gè)像素。以畸變校正為例鏡頭的徑向畸變和切向畸變會導(dǎo)致圖像變形畸變校正的本質(zhì)是把輸出圖像的每個(gè)像素坐標(biāo)映射回去從原始圖像取像素值。但這涉及到非整數(shù)的坐標(biāo)映射需要做雙線性插值。映射表可以預(yù)先算好存到BRAM或DDR里FPGA運(yùn)行時(shí)查表獲取源坐標(biāo)然后做插值計(jì)算。這個(gè)過程的難點(diǎn)不是插值本身而是數(shù)據(jù)訪問模式——畸變映射的坐標(biāo)是跳躍的不是順序讀取所以DDR帶寬利用率和緩存策略的設(shè)計(jì)才是真正的硬骨頭。用FPGA做圖像處理會強(qiáng)迫你建立“流水線思維”一個(gè)操作拆成多個(gè)級級與級之間用寄存器打拍pipeline register整個(gè)設(shè)計(jì)從頭到尾只有一個(gè)主時(shí)鐘在驅(qū)動。這是FPGA跟軟件思維最大的不同——軟件是一步一步串行做硬件是所有人同時(shí)干活數(shù)據(jù)像流水線一樣順著各級往下流。3.3 高速接口與系統(tǒng)互聯(lián)沒有接口的FPGA是孤島FPGA再強(qiáng)如果只跑內(nèi)部邏輯不跟外部通信價(jià)值就大打折扣。而外部通信恰恰是FPGA的看家本領(lǐng)之一。PCIe、SRIO、萬兆以太網(wǎng)、LVDS、DDR3/DDR4這些接口在熱詞里高頻出現(xiàn)說明實(shí)際項(xiàng)目里大家天天在處理這類問題。PCIe是計(jì)算機(jī)系統(tǒng)中最重要的互連協(xié)議。Xilinx UltraScale里的PCIe硬核集成度很高你只需要關(guān)注應(yīng)用層AXI接口物理層和鏈路層都是硬核自己處理的。真正的難點(diǎn)通常在DMA引擎設(shè)計(jì)——怎么樣把高速數(shù)據(jù)流高效搬運(yùn)到主機(jī)內(nèi)存而不讓CPU參與每一個(gè)數(shù)據(jù)包的搬運(yùn)。PCIe DMA設(shè)計(jì)里最常踩的坑是描述符環(huán)descriptor ring的管理和中斷合并策略這兩塊沒做好跑到高帶寬時(shí)就會掉鏈子。SRIOSerial RapidIO在嵌入式信號處理板卡中很常見比如多板卡級聯(lián)的雷達(dá)信號處理系統(tǒng)。SRIO的特點(diǎn)是基于包交換、支持直接IO和消息傳遞物理層也是跑在串行收發(fā)器上的。調(diào)試SRIO鏈路時(shí)同樣要用IBERT先把物理層打通確認(rèn)無誤碼之后再調(diào)事務(wù)層。我見過有人跳過這一步直接調(diào)應(yīng)用結(jié)果一會通一會斷排查了三天才發(fā)現(xiàn)是TX端預(yù)加重不足偶發(fā)誤碼導(dǎo)致鏈路反復(fù)重訓(xùn)練。LVDS接收算是比較基礎(chǔ)的高速接口了但熱詞里有“fpga的lvds接收”和“pxie x4的差分對接”說明它依然是很多人的門檻。LVDS調(diào)試的典型問題有三個(gè)一是差分對的極性接反dxn和dxp對調(diào)了圖像或數(shù)據(jù)全亂二是沒加終端匹配電阻或沒使能DIFF_TERM信號反射導(dǎo)致誤碼三是跨bank放置差分對導(dǎo)致布線長度差太大時(shí)序滿足不了。這些問題歸納起來就是一個(gè)思路接口調(diào)試先查物理層再查鏈路層最后查應(yīng)用層不要跳級。3.4 SoC與嵌入式Zynq不是“帶ARM的FPGA”而是“帶FPGA的處理器系統(tǒng)”Zynq這類SoC平臺把ARM處理器和FPGA邏輯放在同一顆芯片里用AXI總線連接。熱詞里有“zynq移植mister fpga”“fpga ddr3”說明這塊也是大家關(guān)注的焦點(diǎn)。Zynq的正確理解方式是ARM Cortex-A9/A53是主處理器FPGA是可編程邏輯外設(shè)兩者是主從關(guān)系。ARM運(yùn)行Linux或裸機(jī)程序通過AXI總線訪問FPGA側(cè)的寄存器、DMA傳輸數(shù)據(jù)。ARM和FPGA之間的高帶寬低延遲互連讓“軟硬協(xié)同”成為可能——復(fù)雜的控制流程和協(xié)議棧跑在ARM上實(shí)時(shí)性要求高的信號處理跑在FPGA上。DDR3控制器是Zynq和FPGA開發(fā)共同的高頻難點(diǎn)。Xilinx的MIG IP核封裝了DDR3/DDR4控制器但使用它需要認(rèn)真核對Pin out和Bank電壓——DDR3的VCCIO必須是1.5VVREF要接對引腳分配要嚴(yán)格按MIG生成的pinout不能想當(dāng)然改。DDR3調(diào)不通的最常見原因是引腳分配錯(cuò)誤或者時(shí)鐘約束不對其次是PHY訓(xùn)練失敗。這類問題排查難度大所以一定要嚴(yán)格按IP的約束和引腳定義來布線不要自由發(fā)揮。4. 新手避坑指南這些年我踩過的坑4.1 入門路線怎么規(guī)劃才不會走彎路結(jié)合我這些年的經(jīng)驗(yàn)給準(zhǔn)備入門FPGA的同學(xué)一條相對高效的學(xué)習(xí)路徑補(bǔ)數(shù)字電路基礎(chǔ)組合邏輯、時(shí)序邏輯、觸發(fā)器、狀態(tài)機(jī)。不補(bǔ)這塊直接學(xué)Verilog你會寫代碼但不知道它對應(yīng)什么電路這是最致命的。學(xué)Verilog語法重點(diǎn)是可綜合子集不是所有語法都能綜合成電路initial在可綜合設(shè)計(jì)里基本看不到for循環(huán)也要小心使用。初學(xué)階段就要分清哪些是仿真語法、哪些是綜合語法。跑通第一個(gè)小項(xiàng)目流水燈、按鍵消抖、UART收發(fā)不用貪大關(guān)鍵是走通“寫代碼→仿真→綜合→下載→板級調(diào)試”的完整流程。掌握仿真和在線調(diào)試方法testbench怎么寫、ILA怎么抓信號這些是后續(xù)所有項(xiàng)目的基本功。啃時(shí)序約束create_clock、set_input_delay、set_output_delay、set_false_path、異步時(shí)鐘域處理這是從入門到進(jìn)階的分水嶺。很多人卡在這一步但必須跨過去。做接口項(xiàng)目UART、SPI、IIC、DDR3、PCIe、JESD204B依次遞進(jìn)。每個(gè)接口后面都藏著相應(yīng)的協(xié)議知識。選一個(gè)應(yīng)用方向深入通信基帶、圖像處理、接口控制、AI加速選一個(gè)方向深耕FPGA只是個(gè)平臺應(yīng)用領(lǐng)域知識才是護(hù)城河。工具鏈選擇上Xilinx的Vivado是目前生態(tài)最成熟的選擇學(xué)習(xí)資料多、IP豐富。Intel的Quartus也有不少存量用戶。國產(chǎn)復(fù)旦微的Procise在逐步完善支持國產(chǎn)化平臺時(shí)可能會用到。沒必要糾結(jié)“用哪家”核心能力是一通百通的。4.2 時(shí)序約束和跨時(shí)鐘域快時(shí)鐘到慢時(shí)鐘1.2倍怎么搞時(shí)序約束是FPGA工程師的必修課也是區(qū)分新手和老手的關(guān)鍵分水嶺。熱詞里有個(gè)非常具體的問題“fpga快時(shí)鐘到慢時(shí)鐘1.2倍 怎么設(shè)置時(shí)序約束”。這個(gè)問題看著簡單但背后是跨時(shí)鐘域處理的完整知識體系。先說結(jié)論1.2倍不是整數(shù)倍關(guān)系所以不能用set_clock_groups -asynchronous這么簡單粗暴地一扔了之。99%的情況下兩種選擇要么按異步時(shí)鐘域處理把兩個(gè)時(shí)鐘域之間的信號用異步FIFO或握手協(xié)議同步要么按同步時(shí)鐘域處理但必須有實(shí)際的主從關(guān)系。1.2倍的比例說明兩者是獨(dú)立時(shí)鐘源本質(zhì)上應(yīng)該按異步處理。具體操作上先創(chuàng)建兩個(gè)時(shí)鐘create_clock -period 10.000 -name fast_clk [get_ports clk_fast] create_clock -period 12.000 -name slow_clk [get_ports clk_slow]然后聲明它們異步set_clock_groups -asynchronous -group [get_clocks fast_clk] -group [get_clocks slow_clk]但這里有個(gè)前提你必須在RTL里真正處理好轉(zhuǎn)接信號的同步問題否則約束是掩耳盜鈴。跨時(shí)鐘域信號至少要經(jīng)過兩級觸發(fā)器同步打兩拍復(fù)雜一點(diǎn)的要走異步FIFO。如果只是快時(shí)鐘域打出來的脈沖信號在慢時(shí)鐘域里被采到極大概率會采到亞穩(wěn)態(tài)導(dǎo)致數(shù)據(jù)錯(cuò)誤。熱詞里問“如何約束內(nèi)部時(shí)鐘信號”思路也一樣MMCM/PLL輸出時(shí)鐘要讓工具自動識別如果是自己分頻出來的慢時(shí)鐘要手動create_generated_clock否則工具不知道它是從哪來的時(shí)序分析就是盲人摸象。4.3 程序固化與配置bit文件只能臨時(shí)用上電加載要靠Flash寫FPGA的代碼綜合出的bit文件下載到芯片里能跑但掉電就沒了。真正的產(chǎn)品必須把程序固化到配置Flash里上電自動加載。Xilinx叫“Configuration”Intel叫“Active Serial”熱詞里“fpga固化程序”“startup2原語”就是在問這個(gè)。Xilinx 7系列的固化流程是把.bit轉(zhuǎn)成.bin或.mcs格式然后通過Vivado的Hardware Manager燒到SPI Flash或BPI Flash里。上電時(shí)FPGA會從Flash加載配置建立好內(nèi)部邏輯后釋放Done信號進(jìn)入正常工作狀態(tài)。選Flash容量的原則是程序大小加上余量幾十MB的bit文件就需要大容量的QSPI Flash。STARUP2原語在Xilinx FPGA里是個(gè)不起眼但關(guān)鍵的東西。它負(fù)責(zé)把用戶邏輯里的時(shí)鐘信號引入到配置邏輯中用于配置完成之后繼續(xù)驅(qū)動一些內(nèi)部時(shí)鐘網(wǎng)絡(luò)。在7系列里Vivado默認(rèn)會自動實(shí)例化STARTUP原語某些場景比如你需要自定義配置時(shí)鐘頻率或者內(nèi)部時(shí)鐘要驅(qū)動STARTUPE2可能就要手動例化STARTUP #(.PROG_USR(FALSE)) startup_inst ( .CFGMCLK(), .CLK(config_clk), .EOS(), .GSR(), .GTS(), .KEY(), .PACK(), .USRCCLKO(), .USRCCLKTS() );Intel FPGA那邊.sof文件是調(diào)試用的SRAM對象文件斷電丟失。固化時(shí)用“Convert Programming Files”功能把.sof轉(zhuǎn)成.jic寫入EPCS或CFI Flash。熱詞里問“如何為intel fpga .sof添加bootloader”其實(shí)是問怎么把軟核處理器的啟動代碼bootloader和FPGA配置合并然后通過.configuration device上電加載。這一步的關(guān)鍵點(diǎn)是啟動代碼和配置文件的偏移地址要匹配否則處理器上電后找不到啟動代碼。4.4 常見問題排查一張速查表幫你在板級Debug時(shí)少走彎路我把這些年遇到的典型問題整理成一張速查表方便你板級調(diào)試時(shí)對照現(xiàn)象可能原因排查思路程序下載成功但板子沒反應(yīng)時(shí)鐘沒起來、復(fù)位一直有效、管腳約束錯(cuò)誤先查時(shí)鐘是否起振再查復(fù)位邏輯最后用ILA抓內(nèi)部信號UART完全無輸出波特率配置錯(cuò)誤、時(shí)鐘頻率跟實(shí)際不符核對時(shí)鐘頻率檢查波特率分頻參數(shù)用示波器量TX腳有沒有電平變化LVDS圖像花屏差分對極性接反、終端電阻沒使能、時(shí)鐘相位不對檢查dxp/dxn是否接反使能DIFF_TERM用ILA抓像素?cái)?shù)據(jù)格式DDR3初始化失敗MIG引腳分配錯(cuò)誤、Bank電壓不對、時(shí)鐘約束缺失用MIG自帶的測試程序跑一遍確認(rèn)PHY training是否通過檢查VCCIO1.5VJESD204B鏈路建立失敗參考時(shí)鐘不穩(wěn)、SYSREF時(shí)序不滿足、鏈路參數(shù)不匹配先查時(shí)鐘抖動指標(biāo)再抓SYSREF對時(shí)鐘沿的時(shí)序核對默認(rèn)參數(shù)IBERT誤碼率高TX預(yù)加重不足、RX均衡檔位錯(cuò)誤、走線長度不匹配在IBERT界面上調(diào)大TX預(yù)加重和RX均衡觀察誤碼率變化時(shí)序報(bào)告大量violation時(shí)鐘約束錯(cuò)誤、代碼不寫流水線、綜合策略不對先確認(rèn)約束正確優(yōu)化關(guān)鍵路徑邏輯級數(shù)必要時(shí)加pipeline級數(shù)固化后上電不啟動Flash型號選錯(cuò)、配置模式引腳設(shè)置錯(cuò)誤、bit文件轉(zhuǎn)換格式不對核對配置模式Master SPI/BPI檢查Flash型號重新生成固化文件IIC仿真卡住無響應(yīng)沒有給scl/sda設(shè)置初始值或沒有模擬上拉電阻testbench中給scl/sda初始為1模擬開漏加上拉的實(shí)際情況這張表解決的是“看到問題不知道從何查起”的困境。真正排查時(shí)我的思路永遠(yuǎn)是先確認(rèn)物理層電源、時(shí)鐘、復(fù)位再確認(rèn)鏈路層協(xié)議時(shí)序、信號完整性最后才懷疑應(yīng)用層代碼邏輯。反過來查很容易被表象帶偏。5. 摸爬滾打十年我的一些心里話寫到這里想跟還在FPGA這條路上摸索的朋友分享幾句實(shí)在話。第一一定要建立“硬件思維”。FPGA開發(fā)的本質(zhì)是設(shè)計(jì)電路不是寫軟件。同一段代碼軟件工程師看到的是“邏輯”FPGA工程師看到的應(yīng)該是“觸發(fā)器、組合邏輯、布線資源”。每寫一行代碼心里都要清楚它綜合出來是什么電路占多少LUT、會不會成為時(shí)序瓶頸。這種思維不是天生的是靠大量讀代碼、看綜合報(bào)告、看原理圖訓(xùn)練出來的。第二仿真做的越充分板子上越輕松。這個(gè)道理我吃了很多虧才徹底搞懂。很多新手急著上板點(diǎn)燈結(jié)果一個(gè)簡單的邏輯錯(cuò)誤在板子上用ILA查了兩天如果仿真里多花半小時(shí)就發(fā)現(xiàn)了。FPGA開發(fā)的時(shí)間分配上仿真和算法驗(yàn)證應(yīng)該占到60%以上的精力時(shí)序分析和板級調(diào)試最多占30%。反過來做項(xiàng)目必延期。第三時(shí)序收斂能力決定你能走多遠(yuǎn)。寫功能代碼只是FPGA開發(fā)的入門讓設(shè)計(jì)在目標(biāo)頻率下穩(wěn)定跑起來才是硬功夫。流水線設(shè)計(jì)、關(guān)鍵路徑優(yōu)化、約束文件管理、跨時(shí)鐘域處理這些能力需要大量實(shí)踐才能真正掌握。建議新手從100MHz的設(shè)計(jì)開始練逐步挑戰(zhàn)更高頻率時(shí)序報(bào)告從全綠到滿江紅再到全綠的反復(fù)打磨過程就是能力提升的過程。第四不要埋頭做項(xiàng)目而不反思方法論。每個(gè)項(xiàng)目做完花點(diǎn)時(shí)間復(fù)盤哪些問題本該在早起發(fā)現(xiàn)哪些流程可以自動化哪些工具能力還沒用上我見過干了五年還是原地踏步的工程師也見過三年就能帶項(xiàng)目的年輕人差別就在于有沒有在項(xiàng)目之后形成自己的方法論和工具庫?;氐阶畛醯膯栴}FPGA到底值不值得花時(shí)間去學(xué)我的答案是值得但要把心思用在理解硬件本質(zhì)上而不是表面上會幾個(gè)工具操作。無論你以后是去做專用芯片、做通信算法、做嵌入式還是繼續(xù)深耕FPGA這段經(jīng)歷都能讓你獲得從底層理解計(jì)算系統(tǒng)的能力這是一條越走越寬的路。