計WDT看門狗:從需求拆解到RTL驗證的完整實踐)
在可編程邏輯和芯片設(shè)計的圈子里IPIntellectual Property這個詞聽起來多少有點距離感。說白了它就是一段經(jīng)過驗證、可以反復(fù)復(fù)用的電路功能模塊從串口、I2C到復(fù)雜的總線橋都算。這幾年AI輔助開發(fā)在軟件界已經(jīng)卷成常態(tài)但在硬件設(shè)計領(lǐng)域很多人還是將信將疑總覺得RTL這種東西“AI寫不了”。我自己的態(tài)度是有保留的于是挑了看門狗WDTWatchdog Timer這個經(jīng)典模塊做了一次從零開始的AI輔助設(shè)計。結(jié)果不算驚艷卻非常務(wù)實活兒能干但前提是你得把設(shè)計意圖徹底想清楚不然AI會把定時器做成FPGA Demo而不是一顆能上芯的IP。這篇不是理論課我會把整個流程拆開需求規(guī)格、提示詞設(shè)計、RTL生成、驗證平臺、集成復(fù)盤每個環(huán)節(jié)都放我實際用過的代碼和踩過的坑。就算你沒有接觸過數(shù)字IC設(shè)計看完也能明白AI輔助硬件設(shè)計到底省在哪、難在哪。1. 需求拆解AI設(shè)計的第一步不是寫代碼而是把“邊界”寫清楚1.1 看門狗WDT到底要干哪些活看門狗定時器Watchdog TimerWDT是絕大多數(shù)SoC和單片機里都有的基礎(chǔ)外設(shè)它的職責(zé)非常粗暴用硬件去監(jiān)測系統(tǒng)軟件是否還活著。如果軟件運行正常就會周期性喂狗也就是往WDT某個寄存器寫一個特定值讓計數(shù)器重置如果軟件死循環(huán)、跑飛或者干脆宕機了計數(shù)器就會一路減到零WDT隨即發(fā)出復(fù)位信號或者中斷通知讓系統(tǒng)拉回可控狀態(tài)。聽起來就是一個倒計時器對不對直接按著這個理解去讓AI生成會發(fā)現(xiàn)提示詞根本沒法提取出設(shè)計特征。這個模塊看著邏輯簡單但它有三個容易出問題的邊界。一是窗口喂狗。只做“最長時間到了就復(fù)位”是最低級的看門狗現(xiàn)在主流設(shè)計都會做窗口模式。喂狗太早也不行因為過早喂狗說明程序可能在重復(fù)某段短暫執(zhí)行的邏輯并沒有真正運行到主循環(huán)甚至可能是在死循環(huán)里碰巧經(jīng)過喂狗代碼。窗口模式要求喂狗必須在計數(shù)器值落到某一段區(qū)間內(nèi)才能成功早喂、晚喂都觸發(fā)復(fù)位。二是防誤關(guān)機制。看門狗開關(guān)如果只是一位使能寄存器系統(tǒng)軟件一旦跑飛先給你寫個零把WDT關(guān)了那看門狗就徹底失去了意義。所以常見做法是想要修改控制寄存器必須先在鎖寄存器里寫入一串固定數(shù)值行業(yè)里叫unlock sequence或者寫保護。三是復(fù)位信號的處理。WDT發(fā)的不是普通脈沖它要區(qū)分是上電復(fù)位還是看門狗復(fù)位也要保證復(fù)位電平寬度足夠讓系統(tǒng)里其他模塊完成復(fù)位流程同時又要避免把復(fù)位原因寄存器沖掉。這些細節(jié)直接決定芯片中的復(fù)位管理模塊怎么協(xié)同工作。我最初給的提示詞只寫了“16位遞減計數(shù)器、定時到了輸出復(fù)位信號”AI立刻給我返了個勉強能跑的模塊但計數(shù)器到0只保持了一個周期就自己恢復(fù)成復(fù)位值這在真實系統(tǒng)里完全不夠——很多外設(shè)的復(fù)位邏輯需要幾十甚至上百個時鐘周期才能完成狀態(tài)收斂。所以這次實踐給我的第一個啟發(fā)是給AI寫提示詞本質(zhì)上是在幫它做“可綜合功能的邊界定義”。1.2 分頻、計數(shù)和喂狗序列先把參數(shù)表釘死先確定一下這次設(shè)計的目標參數(shù)。為了讓驗證不過于簡單我把核心計數(shù)器定位32位驅(qū)動時鐘假設(shè)50MHz。這里需要先用一個預(yù)分頻器產(chǎn)生低頻的計數(shù)時鐘否則32位計數(shù)器在50MHz下要跑到85秒才溢滿仿真和功能驗證都要跟著遭殃。我選的分頻系數(shù)是256這樣計數(shù)時鐘約為195312.5Hz計數(shù)步進是5.12微秒。老老實實把全范圍跑完大概需要將近86秒日常調(diào)試如果嫌長可以留一個仿真專用的快速配置寄存器直接改計數(shù)初始值。這里注意一點分頻系數(shù)、計數(shù)寬度、超時閾值都做參數(shù)化不給參數(shù)化會讓后面做SoC集成的人很頭疼因為不同芯片主頻不同WDT的固定時間反而沒通用性。喂狗序列我選了經(jīng)典的雙鍵方式總線先寫0x5A再寫0xA5只有連續(xù)兩次寫入成功才真正把計數(shù)器重裝回初始值。如果第一次寫錯或第二次寫錯都要讓“喂狗狀態(tài)機”清零避免軟件只靠反復(fù)窮舉喂狗序列來碰運氣。再加一層鎖寄存器解鎖碼0xE1E5必須要先寫對解鎖碼控制寄存器里使能位才可以被修改。我把寄存器表做成了一張會說人話的表格寄存器名偏移位寬讀/寫功能說明WDT_CTRL0x002R/Wbit0:使能 bit1:窗口模式使能WDT_LOAD0x0432R/W重裝載值WDT啟動時讀取WDT_FEED0x088W依次寫0x5A、0xA5完成喂狗WDT_LOCK0x0C32W寫0xE1E5解鎖控制寄存器WDT_INT_ST0x101R/W1C中斷標志位寫1清除我建議讀者在做類似設(shè)計時把這張表格當(dāng)作提示詞的一部分直接發(fā)給AI。別小看這個動作我實際對比過不給寄存器表讓AI自由發(fā)揮的版本AI會自己發(fā)明接口生成之后你再跟總線側(cè)對齊改動成本非常高。接口一旦定死AI返工的痛苦就沒有了。1.3 時序和復(fù)位策略不能丟給AI自由發(fā)揮再聊聊時序約束。我說過這個模塊的復(fù)位策略在真實SoC里很微妙。我自己定的復(fù)位策略如下整個模塊使用一個異步復(fù)位信號sys_reset_n上電時有效由芯片復(fù)位管理模塊統(tǒng)一拉低。WDT模塊內(nèi)部所有同步邏輯都統(tǒng)一用這個異步復(fù)位置0在這個復(fù)位樹上消除毛刺的辦法是由復(fù)位管理模塊統(tǒng)一做時鐘域同步WDT本身只管接收。這里很多人會糾結(jié)既然已經(jīng)有了異步復(fù)位做整體復(fù)位為什么中斷、使能寄存器還要額外做同步清除為了穩(wěn)妥。實際項目中跑飛現(xiàn)場經(jīng)常是無規(guī)律的你在頂層硬件上留一個“看門狗復(fù)位清使能”的電平信號比依賴軟件自己重新配置更靠譜。計數(shù)器遞減邏輯反而用同步復(fù)位就夠了。因為異步復(fù)位用于模塊整體復(fù)位計數(shù)器遞減屬于正常運行路徑每一拍都用時鐘沿對齊如果計數(shù)路徑也搞全異步復(fù)位綜合工具在STA階段反而會多出不確定路徑。這個決定是我在生成RTL前端就寫進提示詞的要求AI在這個點上做了但它額外給我加了一句“posedge clk or negedge rst_n”的異步復(fù)位寫法后來審查時被我一處處揪出來改掉了因為我要的就是計數(shù)器內(nèi)部的復(fù)位始終同步。把判斷都在需求階段定好最后會發(fā)現(xiàn)提示詞已經(jīng)不像是在聊天更像一份簡化的RTL spec。這其實就對了AI再怎么聰明也不會替你背“系統(tǒng)的功能性需求”它只是把自然語言翻譯成描述語言和寄存器邏輯的工具。2. 讓AI動手寫RTL提示詞、工具與首輪代碼審查2.1 工具選擇和關(guān)于大模型的幾條心得工具上我嘗試了GitHub Copilot、ChatGPT和Claude。結(jié)論先說寫這種工業(yè)風(fēng)格RTLClaude的完成度高ChatGPT勝在上下文交互Copilot適合在已有框架里補填空。但我最后還是用最笨的辦法把大段提示詞發(fā)給對話工具然后COPY代碼回編輯器。原因很現(xiàn)實IDE里邊的AI補全對我想保持的“從需求出發(fā)”沒有幫助——它太迎合我手頭的半成品代碼而不是從設(shè)計規(guī)范出發(fā)。關(guān)于大模型硬傷我總結(jié)三條其一它對“可綜合性”是盲的會一廂情愿地寫initial塊、fork join、甚至原語其二它會自作聰明添加一些多余的狀態(tài)——看著結(jié)構(gòu)漂亮但綜合出來面積和時序就講故事了其三它對接口的想象非常脆弱如果寄存器表里沒寫明位寬它按時就按32位全量處理而實際設(shè)計中往往是需要位寬匹配的。這些觀點不是紙上談兵是這次設(shè)計里實際撞過的坑。AI生成代碼的過程其實很流暢但你一旦放松審查它會把整個模塊變成“仿真器里正常、綜合器里崩潰”的定時炸彈。2.2 我實際使用的提示詞高成功率模板為了方便快速執(zhí)行我通常會把設(shè)計需求組合成下面這種格式盡量一次給出所有約束。提示詞本身的套路比大家想象得樸素就是把“接口、行為、約束邊界”分開放像填單子一樣一項項寫清楚。這里我給一個我自己實際用過的精簡版提示詞讀者可以直接套請你用Verilog設(shè)計一個32位遞減計數(shù)的看門狗定時器模塊。 接口要求 - 輸入clkrst_nbus_wrbus_addrbus_wdata - 輸出wdt_rstwdt_int以及一個仿真調(diào)試用計數(shù)器值輸出cnt_dbg 行為要求 - 復(fù)位方式模塊入口使用異步復(fù)位計數(shù)器內(nèi)部使用同步復(fù)位 - 分頻對clk做256分頻后產(chǎn)生計數(shù)脈沖但只能作為時鐘使能不能作為獨立時鐘 - 喂狗程序依次向FEED寄存器寫0x5A和0xA5兩個值連續(xù)正確才重載計數(shù)器 - 窗口模式開啟窗口時計數(shù)器大于0x0FF0或小于0x0800時喂狗都觸發(fā)復(fù)位 - 計數(shù)器到0時輸出wdt_rst一個時鐘周期高電平 禁止項 - 不允許使用initial - 不允許在always塊外產(chǎn)生變量 - 所有時序邏輯統(tǒng)一使用posedge clk有意思的是我試過讓AI自己梳理這類需求效果一般它會過度發(fā)揮。反而是把需求和幾個邊界條件直接丟給它干活速度快又準。這個對比很重要AI在硬件設(shè)計里是“承重翻譯”不是“架構(gòu)師”。2.3 對AI生成代碼做的三處手術(shù)AI在第一次就給出了能編譯的主體代碼大約120行。但這120行里我在“使用”之前強制要求自己做了一次完整的review找出三個必須要改的地方。第一個問題是計數(shù)器的遞減條件。AI默認寫成了“只要使能就遞減”完全沒考慮預(yù)分頻和快重裝之間的競爭。我要求遞減信號必須是在分頻計數(shù)滿之后產(chǎn)生的單周期脈沖AI卻把分頻計數(shù)器放在always塊里直接拿分頻輸出作為獨立時鐘節(jié)點。這在仿真中看不出來但綜合工具會報多時鐘警告上板甚至?xí)霈F(xiàn)隨機丟計數(shù)。我把它改為統(tǒng)一時鐘沿驅(qū)動用一個分頻計滿脈沖作為時鐘使能而不是把分頻輸出當(dāng)獨立時鐘。第二個問題是喂狗序列的狀態(tài)寄存器。AI用了一個單字節(jié)變量去記住當(dāng)前寫到第幾位可我要求的是通過一個只有三態(tài)的狀態(tài)機去區(qū)分“空閑、已寫0x5A、成功”這樣既節(jié)省資源也避免了狀態(tài)跳轉(zhuǎn)不完整導(dǎo)致的非法輸入問題。第三個問題也是最隱蔽的AI沒有統(tǒng)計“早到喂狗”。早期版本里只要寫入合法序列就會無條件重載計數(shù)器于是窗口模式形同虛設(shè)。我后來在狀態(tài)機里加了一段比較邏輯用上限和下限控制喂狗有效區(qū)段只要計數(shù)器的當(dāng)前值不在窗口區(qū)間內(nèi)喂狗序列完成也算非法。做完這三處修改整個模塊的代碼仍然保留著AI的骨架我自己只改了20%左右。這個過程讓我明顯感受到AI輔助RTL創(chuàng)作的真實定位它適合生成大框架和模板化代碼不適合承擔(dān)帶有系統(tǒng)策略性的時刻判斷。3. 用驗證平臺來證明AI寫的IP到底能不能信3.1 測試平臺結(jié)構(gòu)從零搭的SystemVerilog仿真環(huán)境代碼寫完只是開始真正驗證AI生成設(shè)計是否可靠的是仿真環(huán)境。用得最多的是SystemVerilog UVMUVM對于這種小外設(shè)反而顯得笨重。我用的是非常輕量的定向testbench加斷言核心思路是搭一個簡單CPU模型模擬軟件通過總線讀寫WDT寄存器觀測WDT的復(fù)位和中斷行為。testbench里最重要的部分是總線模型。因為WDT是外圍設(shè)備我要模擬軟件周期寫0x5A再到寫0xA5的過程??偩€模型里用task封裝一次寫操作task automatic bus_write(input bit [1:0] addr, input bit [31:0] wdata); (posedge clk); bus_wr 1b1; bus_addr addr; bus_wdata wdata; (posedge clk); bus_wr 1b0; endtask我在主測試序列里依次調(diào)用bus_write模擬CPU正常喂狗先寫0x5A到FEED寄存器再寫0xA5兩步做完后WDT內(nèi)部會重裝計數(shù)器。這里如果第二個周期被調(diào)成別的值就要能看到計數(shù)器不重裝繼續(xù)往下運行這是最基本的功能驗證項。配合斷言我用一個只讀的debug信號把計數(shù)器當(dāng)前值引出來在testbench里直接檢查喂狗之后的計數(shù)值約等于重裝載值property p_feed_reload; (posedge clk) disable iff(!rst_n) (wdt_reload_flag) | (cnt_dbg cnt_load_value); endproperty assert property(p_feed_reload);有了這種斷言仿真跑完直接看通過和失敗情況。這種斷言的意義在于讓AI生成邏輯里的隱性bug在仿真階段現(xiàn)形而不是等板子燒出來之后變玄學(xué)。3.2 測試用例清單一種“窗口喂狗”的獨特驗證功能測試用例怎么定其實是整份驗證計劃里最見功力的地方。對于WDT我梳理出下面幾條硬性用例。首先是“正常運行不喂狗計數(shù)器到零時產(chǎn)生復(fù)位”。這是最核心的用例大部分WDT都必須過。仿真把超時配置為很短的初值比如計數(shù)100個主時鐘周期就溢出然后等待wdt_rst信號拉高。然后是“窗口內(nèi)喂狗正常重裝”和“窗口外喂狗觸發(fā)復(fù)位”。窗口模式開啟后我把窗口定義為重裝載值0x1000允許喂狗區(qū)間是0x0800到0x0FFF之間。軟件必須等計數(shù)器落到中段再喂喂太早比如計數(shù)還在0x1000附近和喂太晚比如計數(shù)值已經(jīng)小于0x0800都會被判斷為異常。實現(xiàn)這種驗證最重要的地方是你要給testbench一個“讀取當(dāng)前計數(shù)值”的仿真調(diào)試接口這個接口在真實IP里可能不會暴露給軟件但在仿真階段是查狀態(tài)的關(guān)鍵窗口。還有一個很容易被忽略的用例是“連續(xù)兩步寫正確但中間間隔過長”。為什么單獨提這一條因為喂狗過程中第一步寫0x5A后如果長時間不寫0xA5狀態(tài)機會一直停在中間態(tài)這種中間態(tài)如果被后續(xù)復(fù)位意外觸發(fā)清掉就會導(dǎo)致喂狗邏輯狀態(tài)錯亂。我的處理是在狀態(tài)機加了一段超時自清邏輯如果0x5A寫后256個周期沒等到0xA5就自動回空閑態(tài)。這個特性在第一版提示詞里沒有體現(xiàn)是驗證時發(fā)現(xiàn)仿真狀態(tài)會卡在中間態(tài)回頭補進去的。3.3 覆蓋率統(tǒng)計看看AI生成的RTL有沒有留死角功能仿真通過以后我跑了一遍覆蓋率分析。覆蓋率分兩塊行覆蓋率和狀態(tài)機遷移覆蓋率。行覆蓋率是說RTL里每一行代碼都被執(zhí)行過沒有狀態(tài)機遷移覆蓋率則是狀態(tài)機的每個遷移邊都至少走過一次。行覆蓋率很快跑到了95%左右剩下5%基本都是錯誤分支像“解鎖碼錯誤”路徑如果只在異常注入用例里才走會被算進死角。我為此單獨寫了一個異常注入用例專門往LOCK寄存器寫錯誤值確保錯誤路徑也能覆蓋到。狀態(tài)機遷移覆蓋率就更要重視喂狗狀態(tài)機一共有四個狀態(tài)IDLE、FEED_FIRST、FEED_SECOND、RELOAD。我的用例覆蓋了全部遷移邊的90%剩下一條邊是“兩個階段之間非法跳轉(zhuǎn)”得故意在FEED_FIRST狀態(tài)下連寫兩個0xA5才能踩到加上這個非法序列用例之后狀態(tài)機遷移覆蓋率就到了100%。這些覆蓋率在AI自己寫testbench的時候基本是陪跑需要人工補寫用例因為AI對“覆蓋率優(yōu)化”這種驗證域的認知非常淺——它知道概念卻不知道邊界在哪。這正是驗證工程師的經(jīng)驗所在。4. 綜合前后AI生成代碼最容易翻車的三個環(huán)節(jié)4.1 復(fù)位風(fēng)格不一致仿真里的復(fù)位和綜合里的復(fù)位是兩回事前面在需求階段就說了復(fù)位策略要提前定這里單獨把它作為綜合問題再強調(diào)一次是因為AI默認生成的復(fù)位寫法往往是“全模塊統(tǒng)一異步復(fù)位”。這在做原型驗證的FPGA上問題不大但是在ASIC綜合時如果整個芯片復(fù)位樹已經(jīng)確定你又來了一堆用異步清0的寄存器很容易破壞復(fù)位樹和時鐘樹的平衡。我們這版代碼里計數(shù)器內(nèi)部用同步復(fù)位外部控制寄存器和中斷狀態(tài)寄存器用異步復(fù)位兩種風(fēng)格并存。這在RTL仿真階段很難發(fā)現(xiàn)但綜合工具會幫你插滿某種形式的復(fù)位邏輯時序上平白多出很多需要修的路徑。這種問題本質(zhì)上是設(shè)計風(fēng)格的規(guī)范性。AI不會知道這顆芯片復(fù)位樹的時鐘域分區(qū)它只會機械地根據(jù)自然語言里出現(xiàn)“復(fù)位”的表述選用最常用的寫法。所以提示詞里必須寫明哪個小模塊用異步哪個部分用同步。這話說著簡單實際執(zhí)行起來還是得你自己心里有數(shù)。4.2 預(yù)分頻電路被AI寫成了獨立時鐘綜合立刻教你做人第二個翻車點是預(yù)分頻電路的處理。很多RTL新手和AI都會犯同一個毛病用計數(shù)器產(chǎn)生一個周期信號然后把這個信號當(dāng)成時鐘沿去驅(qū)動下游邏輯。這在模塊仿真里邏輯功能確實對但在綜合工具眼中它就是一個新的時鐘節(jié)點會觸發(fā)CTCClock Tree Cell相關(guān)的違規(guī)整個工程里多個不確定路徑會把你折騰到崩潰。我要求AI生成代碼時明確所有邏輯都在同一個clk域預(yù)分頻輸出只是時鐘使能不是時鐘本身。經(jīng)過這一改綜合工具就不會多報出一個時鐘網(wǎng)了時序只收斂在單一主時鐘上工程簡單一大截。很多讀者可能在軟件領(lǐng)域見過“把定時器回調(diào)當(dāng)成時鐘”的壞味道這句話在RTL里一樣準確。解決思路就是“同源時鐘加使能”而不是“剪出細分時鐘”這個概念建議大家在審查AI代碼時單獨盯一下。4.3 集成角度WDT使能位不能輕易對系統(tǒng)軟件關(guān)閉最后說一個真正會在芯片集成階段救命的點看門狗的使能位必須和系統(tǒng)復(fù)位原因、安全監(jiān)控邏輯綁定在一起。AI給了我一個很直接的使能寄存器en模塊內(nèi)部if(en)才開始計數(shù)理論上沒問題可一旦系統(tǒng)軟件有能力直接關(guān)閉它前面所有的看門狗功能都是擺設(shè)。我在集成階段增加了兩個設(shè)計約束第一WDT_CTRL的寫操作必須受LOCK寄存器保護解鎖成功才能修改第二WDT一旦使能即使發(fā)生復(fù)位也要回到“使能”狀態(tài)除非外部有可靠的上電復(fù)位。這個做法在消費電子芯片里非常常見叫“軟鎖定不可逆使能”策略。在代碼里它不是復(fù)雜邏輯但對安全性的提升非常關(guān)鍵。AI在這一步幫不上忙是我在做集成評審時被安全專家提醒回頭改了一版才鎖住的。5. 常見問題速查與經(jīng)驗總結(jié)5.1 驗證階段遇到的高頻問題清單我把這次開發(fā)過程中遇到的高頻問題整理成一張表方便大家以后直接對照問題現(xiàn)象大概率原因處理方式計數(shù)器遞減永遠停不住預(yù)分頻使能被當(dāng)成持續(xù)高電平信號檢查分頻模塊的“滿僅一個周期”邏輯喂狗成功但計數(shù)器不重裝數(shù)據(jù)比較未在正確邊沿采樣把FEED數(shù)據(jù)的采樣放到wren有效沿窗口模式喂早不觸發(fā)復(fù)位窗口比較寫反或漏了早期判定在斷言里先觀察窗口判定信號復(fù)位輸出電平過窄用組合邏輯直接輸出復(fù)位改為寄存器打拍輸出中斷置位后無法清除沒做W1C寫1清除處理檢查總線讀回邏輯增加寫1清除通路綜合報多時鐘域警告預(yù)分頻輸出驅(qū)動了邏輯改為“同源時鐘時鐘使能”寫法這張表上的前三條我在AI生成的第一版RTL里全中。說實話不意外這幾個問題在行業(yè)里也比較典型很多手工寫RTL的人也會踩但區(qū)別在于手工寫的人會憑著慣性規(guī)避AI不會你敲下來的每個細節(jié)它都會忠實執(zhí)行包括錯誤。5.2 關(guān)于提示詞迭代的一些經(jīng)驗有沒有什么能讓prompt效果更好的技巧我用下來比較靠譜的有幾條把寄存器的地址和位寬全部表格化把復(fù)位策略明確到模塊級別把“只允許一個時鐘域”“不允許initial”“不允許fork”這類禁列直接寫成約束條目最后要求AI在生成代碼的同時說明關(guān)鍵路徑。一旦它解釋不通那地方基本上就是有問題的。這個“反問”法雖然在面向過程的代碼里也一樣管用但放到RTL上特別有效因為可綜合代碼里不允許有“賭一把”的地方。另外我習(xí)慣把提示詞存版本每個版本的提示詞和對應(yīng)的RTL、仿真結(jié)果放同一工程目錄改動一行需求就重新生成一次。時間長了你會發(fā)現(xiàn)提示詞版本歷史就是比代碼注釋更全面的需求變更文檔比很多集成手冊都好用。5.3 一點心頭話回到開頭那句話AI能不能設(shè)計WDT能但它設(shè)計出來的東西跟你“會不會提出正確約束”是強綁定關(guān)系。從頭到尾把提示詞、寄存器表、驗證、綜合跑完我的真實體感是AI至少把我預(yù)研時間壓掉了40%讓我能把精力放到窗口策略、復(fù)位樹和集成安全這些真正的設(shè)計難點上。以后做其他IP這套流程大概率也能復(fù)用先固化接口和時序再讓AI生成代碼然后人工重點審查狀態(tài)機和跨時鐘路徑最后用斷言和覆蓋率把高風(fēng)險功能卡死。最后再分享一個小技巧如果項目時間充裕可以把同樣的設(shè)計需求發(fā)給兩個不同的大模型讓它們各生成一版然后互相當(dāng)reviewer。我在這個項目里就試過把其中一版的問題丟給另一版去檢查它能指出很多人類容易忽略的邊界情況。AI互相挑刺你坐在中間當(dāng)裁判這種感覺挺奇妙的也算是2024年之后硬件設(shè)計工作流里最讓我興奮的變化之一。