實(shí)戰(zhàn):從規(guī)格書到可綜合RTL的AXI與仲裁器生成)
1. 從一份規(guī)格書到可綜合電路我為什么要折騰這套流程去年年底接手一個(gè)中等規(guī)模的IP模塊功能不復(fù)雜但接口協(xié)議是AXI4寄存器組有幾十個(gè)還帶一個(gè)輕量級(jí)的仲裁邏輯。按老路子我得先啃完兩百多頁的規(guī)格書手寫RTL再搭驗(yàn)證環(huán)境最后跑綜合看時(shí)序。整個(gè)過程下來光是把規(guī)格書里的文字翻譯成可綜合的Verilog就花了我將近三周。更別提中間因?yàn)槔斫馄罘倒さ哪菐状巍拇嫫鞯刂酚成溴e(cuò)了一位仲裁優(yōu)先級(jí)搞反了AXI的BVALID握手時(shí)序沒對(duì)齊每一個(gè)都是低級(jí)錯(cuò)誤但每一個(gè)都要花半天到一天去定位。后來我就在想規(guī)格書本身就是結(jié)構(gòu)化的描述寄存器表、狀態(tài)機(jī)、接口時(shí)序這些東西本質(zhì)上都是可以被機(jī)器理解的。如果能讓AI先幫我生成一版RTL骨架我再在上面做優(yōu)化和修正是不是能把重復(fù)勞動(dòng)壓縮掉這就是我開始嘗試AI-Native IP研發(fā)流程的起點(diǎn)。所謂AI-Native不是簡單地在寫代碼時(shí)用一下補(bǔ)全工具而是把AI嵌入到從規(guī)格解析、架構(gòu)設(shè)計(jì)、RTL生成、驗(yàn)證用例生成到綜合約束的每一個(gè)環(huán)節(jié)里讓整個(gè)流程圍繞AI的能力重新組織。這篇文章適合誰看如果你正在做FPGA或ASIC的IP開發(fā)手頭有AXI、APB、SPI這類標(biāo)準(zhǔn)接口的模塊要寫或者你是一個(gè)SoC集成工程師需要快速評(píng)估第三方IP的接口行為那這套思路你可以直接參考。如果你只是好奇AI能不能寫RTL那也可以看看我在哪些環(huán)節(jié)踩了坑、哪些環(huán)節(jié)確實(shí)省了時(shí)間。我不會(huì)吹噓AI能替代工程師但我會(huì)告訴你在哪些具體步驟上它確實(shí)能把你的效率提升一個(gè)檔次。2. 整體流程設(shè)計(jì)把規(guī)格書拆成AI能吃的“飼料”2.1 為什么選擇以Spec為中心驅(qū)動(dòng)傳統(tǒng)RTL開發(fā)是“人讀Spec人寫RTL人寫Testbench”整個(gè)鏈條里Spec是給人看的不是給機(jī)器看的。AI-Native流程的第一步就是把Spec變成機(jī)器可解析的結(jié)構(gòu)化數(shù)據(jù)。我試過兩種方式一種是直接把PDF丟給大模型讓它生成RTL另一種是先人工把Spec拆成結(jié)構(gòu)化的YAML或JSON再讓AI基于結(jié)構(gòu)化數(shù)據(jù)生成RTL。實(shí)測下來第二種方式靠譜得多。原因很簡單。PDF里的表格、腳注、跨頁引用對(duì)AI來說都是噪聲。你讓它從一段“寄存器0x10的bit[3:0]用于配置時(shí)鐘分頻系數(shù)默認(rèn)值為4”的文字里提取信息它可能給你生成一個(gè)帶復(fù)位值的寄存器也可能忘了復(fù)位值還可能把bit范圍搞錯(cuò)。但如果我先把這個(gè)寄存器寫成結(jié)構(gòu)化的描述AI的出錯(cuò)率會(huì)大幅下降。所以我的做法是人工做一次“Spec結(jié)構(gòu)化”把關(guān)鍵信息提取成機(jī)器可讀的格式后續(xù)所有AI生成環(huán)節(jié)都基于這份結(jié)構(gòu)化數(shù)據(jù)。2.2 結(jié)構(gòu)化Spec的字段設(shè)計(jì)我用的是一份YAML文件核心字段包括模塊名、接口列表、寄存器映射、狀態(tài)機(jī)描述、時(shí)序約束。接口列表里每個(gè)接口要寫清楚協(xié)議類型AXI4、APB、SPI等、數(shù)據(jù)位寬、地址位寬、ID位寬。寄存器映射里每個(gè)寄存器要有偏移地址、復(fù)位值、字段列表每個(gè)字段要有位范圍、讀寫屬性、功能描述。狀態(tài)機(jī)描述里要有狀態(tài)列表、轉(zhuǎn)移條件、輸出信號(hào)。時(shí)序約束里要寫清楚時(shí)鐘頻率、建立保持時(shí)間要求、跨時(shí)鐘域處理方式。這份YAML不是給AI看的最終產(chǎn)物而是我用來和AI對(duì)話的“底稿”。我會(huì)把這份YAML連同模塊的功能描述一起發(fā)給AI讓它生成RTL。這樣做的好處是AI不需要從自然語言里猜意圖它只需要把結(jié)構(gòu)化數(shù)據(jù)翻譯成Verilog語法。我試過同一個(gè)模塊直接丟PDF給AI生成的RTL有七處錯(cuò)誤用結(jié)構(gòu)化YAML錯(cuò)誤降到兩處而且都是可以快速修正的語法問題。2.3 工具鏈選型與AI模型選擇工具鏈方面我用的是開源的Verilator做仿真Yosys做綜合GTKWave看波形。AI模型方面我試過幾個(gè)主流的大語言模型最后固定用兩個(gè)一個(gè)擅長代碼生成一個(gè)擅長代碼審查。代碼生成的模型用來出RTL初稿代碼審查的模型用來找時(shí)序問題和協(xié)議違規(guī)。兩個(gè)模型交叉驗(yàn)證比單用一個(gè)模型靠譜。這里有個(gè)細(xì)節(jié)不要用同一個(gè)模型既生成又審查。我試過它對(duì)自己的錯(cuò)誤有“盲區(qū)”審查時(shí)經(jīng)常放過自己生成的bug。換一個(gè)模型來審它能挑出不少問題。另外AI生成的RTL一定要過Lint工具。我用的Verilator自帶Lint能抓出位寬不匹配、未驅(qū)動(dòng)信號(hào)、組合環(huán)路這些問題。Lint過了再進(jìn)仿真能省很多調(diào)試時(shí)間。3. 核心細(xì)節(jié)解析AXI接口與仲裁邏輯的AI生成要點(diǎn)3.1 AXI4接口的握手時(shí)序怎么讓AI理解AXI4的握手時(shí)序是AI生成RTL時(shí)最容易出錯(cuò)的地方。VALID和READY的依賴關(guān)系、BVALID和BREADY的握手、RLAST和RVALID的配合這些如果只靠自然語言描述AI很容易搞混。我的做法是在結(jié)構(gòu)化Spec里專門寫一段“時(shí)序規(guī)則”用偽代碼的形式描述握手行為。比如對(duì)于寫地址通道我會(huì)寫“AWVALID由主機(jī)置高直到AWREADY為高后的下一個(gè)時(shí)鐘沿拉低。AWREADY由從機(jī)置高表示可以接收地址。AWVALID和AWREADY同時(shí)為高的時(shí)鐘沿地址被采樣?!边@段偽代碼發(fā)給AI后它生成的RTL里AWVALID和AWREADY的握手邏輯基本正確。但BVALID的生成邏輯它經(jīng)常出錯(cuò)——BVALID應(yīng)該在寫數(shù)據(jù)接收完成后置高而不是在寫地址接收完成后。這個(gè)細(xì)節(jié)我在Spec里專門加了一條注釋“BVALID的置高條件是WLAST和WVALID同時(shí)為高且WREADY為高與AW通道無關(guān)?!奔恿诉@條之后AI生成的BVALID邏輯就對(duì)了。3.2 仲裁器的優(yōu)先級(jí)反轉(zhuǎn)問題仲裁器是另一個(gè)容易出問題的地方。我設(shè)計(jì)的仲裁器支持四個(gè)主設(shè)備優(yōu)先級(jí)可配置。AI生成的初版仲裁器用的是固定優(yōu)先級(jí)高優(yōu)先級(jí)設(shè)備一直占用總線低優(yōu)先級(jí)設(shè)備餓死。我在Spec里寫的是“輪詢仲裁”但AI理解成了“固定優(yōu)先級(jí)”。后來我在Spec里加了一段狀態(tài)轉(zhuǎn)移描述明確寫了“每次仲裁完成后優(yōu)先級(jí)指針移向下一個(gè)設(shè)備”AI才生成正確的輪詢邏輯。這里有個(gè)經(jīng)驗(yàn)對(duì)于仲裁器、狀態(tài)機(jī)這類有明確狀態(tài)轉(zhuǎn)移的邏輯最好在Spec里畫出狀態(tài)轉(zhuǎn)移表用表格形式列出當(dāng)前狀態(tài)、輸入條件、下一狀態(tài)、輸出信號(hào)。AI對(duì)表格的理解能力比純文字強(qiáng)得多。我試過用文字描述狀態(tài)機(jī)AI生成了五個(gè)狀態(tài)但轉(zhuǎn)移條件錯(cuò)了三個(gè)換成表格后一次通過。3.3 寄存器組的自動(dòng)生成與地址映射寄存器組是IP里最枯燥的部分但也是AI最擅長的部分。只要Spec里的寄存器表足夠清晰AI生成的寄存器讀寫邏輯基本不會(huì)出錯(cuò)。我的做法是在YAML里定義每個(gè)寄存器的偏移地址、復(fù)位值、字段位寬和讀寫屬性然后讓AI生成一個(gè)寄存器文件模塊包含地址譯碼、讀寫使能、字段拼接。這里要注意的是地址對(duì)齊。AXI4的地址是字節(jié)地址但寄存器通常是32位對(duì)齊的。AI有時(shí)候會(huì)把地址譯碼寫成按字地址譯碼導(dǎo)致偏移量錯(cuò)位。我在Spec里明確寫了“地址位[31:2]用于寄存器選擇位[1:0]忽略”AI生成的譯碼邏輯就正確了。另外對(duì)于只讀寄存器AI有時(shí)候會(huì)生成寫邏輯雖然綜合時(shí)會(huì)優(yōu)化掉但Lint會(huì)報(bào)warning。我在Spec里標(biāo)注了每個(gè)寄存器的讀寫屬性AI生成的代碼就干凈了。4. 實(shí)操過程從YAML到可綜合RTL的完整步驟4.1 第一步手工提取Spec關(guān)鍵信息到Y(jié)AML這一步不能省。我試過讓AI直接從PDF提取結(jié)果它把兩個(gè)寄存器的地址搞混了還把一個(gè)保留字段當(dāng)成了有效字段。手工提取雖然花時(shí)間但這是整個(gè)流程里唯一需要人工深度參與的部分大概占整個(gè)項(xiàng)目時(shí)間的20%。提取的時(shí)候我習(xí)慣用雙屏左邊開PDF右邊開YAML編輯器逐條對(duì)照。YAML的結(jié)構(gòu)我固定為幾個(gè)頂層字段module、interfaces、registers、fsm、timing。interfaces下面每個(gè)接口有name、protocol、data_width、addr_width、id_width。registers下面每個(gè)寄存器有name、offset、reset_value、fieldsfields下面每個(gè)字段有name、bits、access、description。fsm下面有states和transitions。timing下面有clock_freq、cdc_handling、handshake_rules。4.2 第二步用AI生成RTL骨架把YAML和一段簡短的模塊功能描述拼成一個(gè)prompt發(fā)給代碼生成模型。Prompt的模板我固定為“你是一個(gè)資深RTL工程師請根據(jù)以下結(jié)構(gòu)化規(guī)格生成可綜合的Verilog RTL。要求使用同步復(fù)位復(fù)位信號(hào)低有效所有寄存器輸出AXI接口遵循AXI4協(xié)議仲裁器使用輪詢策略。規(guī)格如下[YAML內(nèi)容]?!鄙傻臅r(shí)候我習(xí)慣讓AI分模塊生成而不是一次性生成整個(gè)IP。先讓它生成AXI接口模塊再生成寄存器文件再生成仲裁器最后生成頂層連線。分模塊生成的好處是每個(gè)模塊可以單獨(dú)Lint和仿真出了問題容易定位。一次性生成整個(gè)IP出了問題你得在幾千行代碼里找效率反而低。4.3 第三步Lint與仿真驗(yàn)證AI生成的RTL先過Verilator Lint。我用的命令是verilator --lint-only -Wall -Wno-DECLFILENAME top.v axi_if.v reg_file.v arbiter.vLint過了之后寫一個(gè)簡單的Testbench跑仿真。Testbench不用手寫讓AI根據(jù)Spec生成。我通常會(huì)讓AI生成一個(gè)帶隨機(jī)激勵(lì)的Testbench覆蓋寄存器讀寫、AXI突發(fā)傳輸、仲裁切換這幾個(gè)場景。仿真跑起來后用GTKWave看波形重點(diǎn)看握手信號(hào)和狀態(tài)轉(zhuǎn)移。這里有個(gè)技巧讓AI生成Testbench時(shí)要求它加入斷言assertion。比如“AWVALID拉高后AWREADY必須在10個(gè)周期內(nèi)置高”、“BVALID拉高后BREADY必須在5個(gè)周期內(nèi)置高”。這些斷言能在仿真時(shí)自動(dòng)抓出協(xié)議違規(guī)比人工看波形快得多。4.4 第四步綜合與時(shí)序檢查仿真通過后用Yosys做綜合看資源占用和時(shí)序報(bào)告。我用的命令是yosys -p read_verilog top.v axi_if.v reg_file.v arbiter.v; synth; stat綜合報(bào)告里重點(diǎn)看兩個(gè)東西一是LUT和寄存器的數(shù)量二是關(guān)鍵路徑的延遲。如果關(guān)鍵路徑延遲超過時(shí)鐘周期的80%就得考慮優(yōu)化。AI生成的RTL有時(shí)候會(huì)有冗余邏輯比如重復(fù)的地址譯碼、不必要的多路選擇器。這些可以在綜合后手動(dòng)優(yōu)化也可以讓AI重新生成一版在Prompt里加上“優(yōu)化關(guān)鍵路徑”的要求。5. 常見問題與排查技巧實(shí)錄5.1 AI生成的RTL仿真不通過怎么辦先看Lint有沒有過。Lint沒過先修Lint。Lint過了仿真不過大概率是握手時(shí)序或狀態(tài)轉(zhuǎn)移的問題。我的排查順序是先看復(fù)位是否正常釋放再看時(shí)鐘是否正常翻轉(zhuǎn)再看狀態(tài)機(jī)是否進(jìn)入預(yù)期狀態(tài)最后看輸出信號(hào)是否符合預(yù)期。AI生成的RTL有時(shí)候會(huì)忘記復(fù)位狀態(tài)機(jī)的狀態(tài)寄存器導(dǎo)致仿真時(shí)狀態(tài)機(jī)停在未知狀態(tài)。這個(gè)在Lint里不一定能抓出來但仿真波形一看就知道。5.2 AXI突發(fā)傳輸數(shù)據(jù)錯(cuò)位怎么定位AXI突發(fā)傳輸?shù)臄?shù)據(jù)錯(cuò)位通常是地址對(duì)齊或數(shù)據(jù)計(jì)數(shù)的問題。我遇到過AI生成的RTL里突發(fā)長度計(jì)數(shù)器在WLAST時(shí)沒有正確清零導(dǎo)致下一筆傳輸?shù)臄?shù)據(jù)錯(cuò)位。排查方法是在Testbench里發(fā)一筆4拍的寫突發(fā)看波形里WSTRB和WDATA的對(duì)應(yīng)關(guān)系。如果第一拍數(shù)據(jù)對(duì)了第二拍開始錯(cuò)那就是計(jì)數(shù)器的問題。讓AI重新生成時(shí)在Spec里明確寫“突發(fā)長度計(jì)數(shù)器在WLAST和WVALID同時(shí)為高且WREADY為高時(shí)清零”。5.3 仲裁器優(yōu)先級(jí)不生效的排查仲裁器優(yōu)先級(jí)不生效通常是優(yōu)先級(jí)編碼邏輯的問題。我遇到過AI生成的仲裁器里優(yōu)先級(jí)掩碼沒有正確更新導(dǎo)致高優(yōu)先級(jí)設(shè)備釋放總線后低優(yōu)先級(jí)設(shè)備仍然拿不到授權(quán)。排查方法是在Testbench里讓兩個(gè)設(shè)備同時(shí)請求看授權(quán)信號(hào)給誰。如果總是給同一個(gè)設(shè)備那就是輪詢邏輯沒生效。讓AI重新生成時(shí)在Spec里用表格形式寫出狀態(tài)轉(zhuǎn)移明確每個(gè)狀態(tài)下哪個(gè)設(shè)備獲得授權(quán)。5.4 常見問題速查表問題現(xiàn)象可能原因排查方法修正方式仿真時(shí)狀態(tài)機(jī)停在未知狀態(tài)狀態(tài)寄存器未復(fù)位看波形里狀態(tài)信號(hào)在Spec里明確復(fù)位值A(chǔ)XI寫數(shù)據(jù)錯(cuò)位突發(fā)計(jì)數(shù)器未清零看WLAST和WVALID波形在Spec里寫明清零條件仲裁器優(yōu)先級(jí)不生效優(yōu)先級(jí)掩碼未更新看授權(quán)信號(hào)波形用表格描述狀態(tài)轉(zhuǎn)移寄存器讀寫地址錯(cuò)位地址譯碼位寬錯(cuò)誤看地址譯碼邏輯明確地址位[31:2]用于譯碼綜合后關(guān)鍵路徑過長冗余邏輯未優(yōu)化看綜合時(shí)序報(bào)告讓AI重新生成并優(yōu)化6. 我在這套流程里踩過的坑和總結(jié)的經(jīng)驗(yàn)第一個(gè)坑是過度依賴AI。我試過讓AI一次性生成整個(gè)IP的RTL結(jié)果生成了兩千多行代碼Lint報(bào)了三十多個(gè)warning仿真跑了三天沒跑通。后來改成模塊化生成每個(gè)模塊單獨(dú)驗(yàn)證效率反而高。第二個(gè)坑是Spec結(jié)構(gòu)化做得不夠細(xì)。我一開始只寫了寄存器地址和位寬沒寫復(fù)位值和讀寫屬性AI生成的寄存器文件里有一半的寄存器沒有復(fù)位值仿真時(shí)全是X。后來把復(fù)位值和讀寫屬性補(bǔ)上問題就解決了。第三個(gè)坑是忽略了跨時(shí)鐘域處理。我的IP里有一個(gè)異步FIFOAI生成的RTL里沒有做同步處理仿真時(shí)數(shù)據(jù)丟失。后來在Spec里明確寫了“跨時(shí)鐘域信號(hào)需要兩級(jí)同步器”AI才生成正確的同步邏輯。第四個(gè)坑是Testbench的覆蓋率不夠。AI生成的Testbench只覆蓋了正常讀寫場景沒有覆蓋錯(cuò)誤注入和邊界條件。后來我讓AI生成Testbench時(shí)加上“隨機(jī)注入錯(cuò)誤響應(yīng)”和“邊界地址訪問”的要求覆蓋率才上去。這套流程跑下來我的體會(huì)是AI能幫你省掉重復(fù)勞動(dòng)但不能幫你做架構(gòu)決策。Spec結(jié)構(gòu)化、模塊劃分、時(shí)序約束這些關(guān)鍵決策還是得人來定。AI的價(jià)值在于你定好框架后它能快速填充細(xì)節(jié)讓你把精力集中在真正需要思考的地方。我現(xiàn)在做一個(gè)中等規(guī)模的AXI IP從Spec到可綜合RTL大概兩周左右其中AI生成占三天人工修正和驗(yàn)證占一周剩下四天是綜合優(yōu)化和文檔。比傳統(tǒng)流程快了一倍多但前提是Spec結(jié)構(gòu)化做得足夠好。如果你也想試這套流程我的建議是先從一個(gè)小模塊開始比如一個(gè)帶AXI-Lite接口的寄存器組跑通整個(gè)流程后再擴(kuò)展到復(fù)雜模塊。別一上來就搞大IP容易翻車。