
1. 从一份规格书到可综合电路我为什么要折腾这套流程去年年底接手一个中等规模的IP模块功能不复杂但接口协议是AXI4寄存器组有几十个还带一个轻量级的仲裁逻辑。按老路子我得先啃完两百多页的规格书手写RTL再搭验证环境最后跑综合看时序。整个过程下来光是把规格书里的文字翻译成可综合的Verilog就花了我将近三周。更别提中间因为理解偏差返工的那几次——寄存器地址映射错了一位仲裁优先级搞反了AXI的BVALID握手时序没对齐每一个都是低级错误但每一个都要花半天到一天去定位。后来我就在想规格书本身就是结构化的描述寄存器表、状态机、接口时序这些东西本质上都是可以被机器理解的。如果能让AI先帮我生成一版RTL骨架我再在上面做优化和修正是不是能把重复劳动压缩掉这就是我开始尝试AI-Native IP研发流程的起点。所谓AI-Native不是简单地在写代码时用一下补全工具而是把AI嵌入到从规格解析、架构设计、RTL生成、验证用例生成到综合约束的每一个环节里让整个流程围绕AI的能力重新组织。这篇文章适合谁看如果你正在做FPGA或ASIC的IP开发手头有AXI、APB、SPI这类标准接口的模块要写或者你是一个SoC集成工程师需要快速评估第三方IP的接口行为那这套思路你可以直接参考。如果你只是好奇AI能不能写RTL那也可以看看我在哪些环节踩了坑、哪些环节确实省了时间。我不会吹嘘AI能替代工程师但我会告诉你在哪些具体步骤上它确实能把你的效率提升一个档次。2. 整体流程设计把规格书拆成AI能吃的“饲料”2.1 为什么选择以Spec为中心驱动传统RTL开发是“人读Spec人写RTL人写Testbench”整个链条里Spec是给人看的不是给机器看的。AI-Native流程的第一步就是把Spec变成机器可解析的结构化数据。我试过两种方式一种是直接把PDF丢给大模型让它生成RTL另一种是先人工把Spec拆成结构化的YAML或JSON再让AI基于结构化数据生成RTL。实测下来第二种方式靠谱得多。原因很简单。PDF里的表格、脚注、跨页引用对AI来说都是噪声。你让它从一段“寄存器0x10的bit[3:0]用于配置时钟分频系数默认值为4”的文字里提取信息它可能给你生成一个带复位值的寄存器也可能忘了复位值还可能把bit范围搞错。但如果我先把这个寄存器写成结构化的描述AI的出错率会大幅下降。所以我的做法是人工做一次“Spec结构化”把关键信息提取成机器可读的格式后续所有AI生成环节都基于这份结构化数据。2.2 结构化Spec的字段设计我用的是一份YAML文件核心字段包括模块名、接口列表、寄存器映射、状态机描述、时序约束。接口列表里每个接口要写清楚协议类型AXI4、APB、SPI等、数据位宽、地址位宽、ID位宽。寄存器映射里每个寄存器要有偏移地址、复位值、字段列表每个字段要有位范围、读写属性、功能描述。状态机描述里要有状态列表、转移条件、输出信号。时序约束里要写清楚时钟频率、建立保持时间要求、跨时钟域处理方式。这份YAML不是给AI看的最终产物而是我用来和AI对话的“底稿”。我会把这份YAML连同模块的功能描述一起发给AI让它生成RTL。这样做的好处是AI不需要从自然语言里猜意图它只需要把结构化数据翻译成Verilog语法。我试过同一个模块直接丢PDF给AI生成的RTL有七处错误用结构化YAML错误降到两处而且都是可以快速修正的语法问题。2.3 工具链选型与AI模型选择工具链方面我用的是开源的Verilator做仿真Yosys做综合GTKWave看波形。AI模型方面我试过几个主流的大语言模型最后固定用两个一个擅长代码生成一个擅长代码审查。代码生成的模型用来出RTL初稿代码审查的模型用来找时序问题和协议违规。两个模型交叉验证比单用一个模型靠谱。这里有个细节不要用同一个模型既生成又审查。我试过它对自己的错误有“盲区”审查时经常放过自己生成的bug。换一个模型来审它能挑出不少问题。另外AI生成的RTL一定要过Lint工具。我用的Verilator自带Lint能抓出位宽不匹配、未驱动信号、组合环路这些问题。Lint过了再进仿真能省很多调试时间。3. 核心细节解析AXI接口与仲裁逻辑的AI生成要点3.1 AXI4接口的握手时序怎么让AI理解AXI4的握手时序是AI生成RTL时最容易出错的地方。VALID和READY的依赖关系、BVALID和BREADY的握手、RLAST和RVALID的配合这些如果只靠自然语言描述AI很容易搞混。我的做法是在结构化Spec里专门写一段“时序规则”用伪代码的形式描述握手行为。比如对于写地址通道我会写“AWVALID由主机置高直到AWREADY为高后的下一个时钟沿拉低。AWREADY由从机置高表示可以接收地址。AWVALID和AWREADY同时为高的时钟沿地址被采样。”这段伪代码发给AI后它生成的RTL里AWVALID和AWREADY的握手逻辑基本正确。但BVALID的生成逻辑它经常出错——BVALID应该在写数据接收完成后置高而不是在写地址接收完成后。这个细节我在Spec里专门加了一条注释“BVALID的置高条件是WLAST和WVALID同时为高且WREADY为高与AW通道无关。”加了这条之后AI生成的BVALID逻辑就对了。3.2 仲裁器的优先级反转问题仲裁器是另一个容易出问题的地方。我设计的仲裁器支持四个主设备优先级可配置。AI生成的初版仲裁器用的是固定优先级高优先级设备一直占用总线低优先级设备饿死。我在Spec里写的是“轮询仲裁”但AI理解成了“固定优先级”。后来我在Spec里加了一段状态转移描述明确写了“每次仲裁完成后优先级指针移向下一个设备”AI才生成正确的轮询逻辑。这里有个经验对于仲裁器、状态机这类有明确状态转移的逻辑最好在Spec里画出状态转移表用表格形式列出当前状态、输入条件、下一状态、输出信号。AI对表格的理解能力比纯文字强得多。我试过用文字描述状态机AI生成了五个状态但转移条件错了三个换成表格后一次通过。3.3 寄存器组的自动生成与地址映射寄存器组是IP里最枯燥的部分但也是AI最擅长的部分。只要Spec里的寄存器表足够清晰AI生成的寄存器读写逻辑基本不会出错。我的做法是在YAML里定义每个寄存器的偏移地址、复位值、字段位宽和读写属性然后让AI生成一个寄存器文件模块包含地址译码、读写使能、字段拼接。这里要注意的是地址对齐。AXI4的地址是字节地址但寄存器通常是32位对齐的。AI有时候会把地址译码写成按字地址译码导致偏移量错位。我在Spec里明确写了“地址位[31:2]用于寄存器选择位[1:0]忽略”AI生成的译码逻辑就正确了。另外对于只读寄存器AI有时候会生成写逻辑虽然综合时会优化掉但Lint会报warning。我在Spec里标注了每个寄存器的读写属性AI生成的代码就干净了。4. 实操过程从YAML到可综合RTL的完整步骤4.1 第一步手工提取Spec关键信息到YAML这一步不能省。我试过让AI直接从PDF提取结果它把两个寄存器的地址搞混了还把一个保留字段当成了有效字段。手工提取虽然花时间但这是整个流程里唯一需要人工深度参与的部分大概占整个项目时间的20%。提取的时候我习惯用双屏左边开PDF右边开YAML编辑器逐条对照。YAML的结构我固定为几个顶层字段module、interfaces、registers、fsm、timing。interfaces下面每个接口有name、protocol、data_width、addr_width、id_width。registers下面每个寄存器有name、offset、reset_value、fieldsfields下面每个字段有name、bits、access、description。fsm下面有states和transitions。timing下面有clock_freq、cdc_handling、handshake_rules。4.2 第二步用AI生成RTL骨架把YAML和一段简短的模块功能描述拼成一个prompt发给代码生成模型。Prompt的模板我固定为“你是一个资深RTL工程师请根据以下结构化规格生成可综合的Verilog RTL。要求使用同步复位复位信号低有效所有寄存器输出AXI接口遵循AXI4协议仲裁器使用轮询策略。规格如下[YAML内容]。”生成的时候我习惯让AI分模块生成而不是一次性生成整个IP。先让它生成AXI接口模块再生成寄存器文件再生成仲裁器最后生成顶层连线。分模块生成的好处是每个模块可以单独Lint和仿真出了问题容易定位。一次性生成整个IP出了问题你得在几千行代码里找效率反而低。4.3 第三步Lint与仿真验证AI生成的RTL先过Verilator Lint。我用的命令是verilator --lint-only -Wall -Wno-DECLFILENAME top.v axi_if.v reg_file.v arbiter.vLint过了之后写一个简单的Testbench跑仿真。Testbench不用手写让AI根据Spec生成。我通常会让AI生成一个带随机激励的Testbench覆盖寄存器读写、AXI突发传输、仲裁切换这几个场景。仿真跑起来后用GTKWave看波形重点看握手信号和状态转移。这里有个技巧让AI生成Testbench时要求它加入断言assertion。比如“AWVALID拉高后AWREADY必须在10个周期内置高”、“BVALID拉高后BREADY必须在5个周期内置高”。这些断言能在仿真时自动抓出协议违规比人工看波形快得多。4.4 第四步综合与时序检查仿真通过后用Yosys做综合看资源占用和时序报告。我用的命令是yosys -p read_verilog top.v axi_if.v reg_file.v arbiter.v; synth; stat综合报告里重点看两个东西一是LUT和寄存器的数量二是关键路径的延迟。如果关键路径延迟超过时钟周期的80%就得考虑优化。AI生成的RTL有时候会有冗余逻辑比如重复的地址译码、不必要的多路选择器。这些可以在综合后手动优化也可以让AI重新生成一版在Prompt里加上“优化关键路径”的要求。5. 常见问题与排查技巧实录5.1 AI生成的RTL仿真不通过怎么办先看Lint有没有过。Lint没过先修Lint。Lint过了仿真不过大概率是握手时序或状态转移的问题。我的排查顺序是先看复位是否正常释放再看时钟是否正常翻转再看状态机是否进入预期状态最后看输出信号是否符合预期。AI生成的RTL有时候会忘记复位状态机的状态寄存器导致仿真时状态机停在未知状态。这个在Lint里不一定能抓出来但仿真波形一看就知道。5.2 AXI突发传输数据错位怎么定位AXI突发传输的数据错位通常是地址对齐或数据计数的问题。我遇到过AI生成的RTL里突发长度计数器在WLAST时没有正确清零导致下一笔传输的数据错位。排查方法是在Testbench里发一笔4拍的写突发看波形里WSTRB和WDATA的对应关系。如果第一拍数据对了第二拍开始错那就是计数器的问题。让AI重新生成时在Spec里明确写“突发长度计数器在WLAST和WVALID同时为高且WREADY为高时清零”。5.3 仲裁器优先级不生效的排查仲裁器优先级不生效通常是优先级编码逻辑的问题。我遇到过AI生成的仲裁器里优先级掩码没有正确更新导致高优先级设备释放总线后低优先级设备仍然拿不到授权。排查方法是在Testbench里让两个设备同时请求看授权信号给谁。如果总是给同一个设备那就是轮询逻辑没生效。让AI重新生成时在Spec里用表格形式写出状态转移明确每个状态下哪个设备获得授权。5.4 常见问题速查表问题现象可能原因排查方法修正方式仿真时状态机停在未知状态状态寄存器未复位看波形里状态信号在Spec里明确复位值AXI写数据错位突发计数器未清零看WLAST和WVALID波形在Spec里写明清零条件仲裁器优先级不生效优先级掩码未更新看授权信号波形用表格描述状态转移寄存器读写地址错位地址译码位宽错误看地址译码逻辑明确地址位[31:2]用于译码综合后关键路径过长冗余逻辑未优化看综合时序报告让AI重新生成并优化6. 我在这套流程里踩过的坑和总结的经验第一个坑是过度依赖AI。我试过让AI一次性生成整个IP的RTL结果生成了两千多行代码Lint报了三十多个warning仿真跑了三天没跑通。后来改成模块化生成每个模块单独验证效率反而高。第二个坑是Spec结构化做得不够细。我一开始只写了寄存器地址和位宽没写复位值和读写属性AI生成的寄存器文件里有一半的寄存器没有复位值仿真时全是X。后来把复位值和读写属性补上问题就解决了。第三个坑是忽略了跨时钟域处理。我的IP里有一个异步FIFOAI生成的RTL里没有做同步处理仿真时数据丢失。后来在Spec里明确写了“跨时钟域信号需要两级同步器”AI才生成正确的同步逻辑。第四个坑是Testbench的覆盖率不够。AI生成的Testbench只覆盖了正常读写场景没有覆盖错误注入和边界条件。后来我让AI生成Testbench时加上“随机注入错误响应”和“边界地址访问”的要求覆盖率才上去。这套流程跑下来我的体会是AI能帮你省掉重复劳动但不能帮你做架构决策。Spec结构化、模块划分、时序约束这些关键决策还是得人来定。AI的价值在于你定好框架后它能快速填充细节让你把精力集中在真正需要思考的地方。我现在做一个中等规模的AXI IP从Spec到可综合RTL大概两周左右其中AI生成占三天人工修正和验证占一周剩下四天是综合优化和文档。比传统流程快了一倍多但前提是Spec结构化做得足够好。如果你也想试这套流程我的建议是先从一个小模块开始比如一个带AXI-Lite接口的寄存器组跑通整个流程后再扩展到复杂模块。别一上来就搞大IP容易翻车。