面向 AI 的 FPGA 开发流程:别急着让它写代码,先把方向定好

📅 2026/6/26 5:27:15
面向 AI 的 FPGA 开发流程:别急着让它写代码,先把方向定好
摘要AI 编码助手已经能帮我们写 RTL、补 testbench、查 bug、整理文档但在 FPGA 开发里真正危险的不是“AI 不会写代码”而是它写得太快、改得太多、想得太少。软件代码改错了大不了跑单测、回滚提交FPGA 代码改错了可能仿真是绿的上板是红的时序是炸的资源是超的接口协议还悄悄变味了。所以面向 AI 的 FPGA 开发不能只靠一句“帮我实现这个模块”。更合理的方式是先让 AI 读懂项目再让它写计划然后由工程师审计划最后才让它动代码。本文结合 Codex 的使用方式总结一套适合 FPGA 项目的 AI 辅助开发流程并通过一个典型场景说明如何让 AI 成为可靠的工程助手而不是一个“热情但莽撞的实习生”。一、为什么 FPGA 开发更需要“管住 AI”很多人第一次用 AI 写代码时体验都很相似“帮我写一个 AXI-Stream 模块。”几秒钟后代码出来了。看起来挺像回事端口也有状态机也有注释也有甚至 testbench 都能跑。但 FPGA 项目不是孤立代码片段的拼图游戏。一个 RTL 模块能不能用至少要同时满足下面这些条件接口协议要对时钟复位要对跨时钟域要对时序约束要对资源消耗要可控仿真行为和上板行为要一致代码风格要和项目一致后续维护人员要能看懂。AI 最擅长的是“根据上下文生成内容”但它不天然知道你的项目边界、工程取舍和历史包袱。它可能会为了实现功能引入一个你根本不想要的 FIFO它可能会为了让仿真通过偷偷改接口时序它也可能会重新实现一个项目里已经存在的通用模块。这就是 AI 辅助 FPGA 开发的核心矛盾AI 很会执行但工程判断必须留在人手里。因此我们要做的不是让 AI 自由发挥而是给它一条清晰轨道。二、核心原则先审计划再写代码这套流程的核心只有一句话在你审查并批准计划之前不要让 AI 写一行 RTL。这句话听起来有点“保守”但在 FPGA 开发里非常必要。因为 FPGA 的很多问题不是语法错误而是工程错误。比如valid/ready 握手语义理解错异步信号没有做同步reset 极性和项目规范不一致多周期路径被误当成普通路径状态机多加了一个“看起来很安全”的等待状态本来应该用 BRAM结果被综合成大量 LUTRAM本来项目只允许 Verilog-2001AI 却写了 SystemVerilog 语法。这些问题单靠“生成后再改”会非常痛苦。更好的做法是把 AI 的工作拆成两个阶段思考阶段阅读代码、理解系统、写研究报告和实施计划执行阶段严格按照已经审过的计划修改代码。一句话概括让 AI 先把脑子里的方案写出来工程师确认没跑偏再让它动手。三、Step 0用 AGENTS.md 给项目立规矩进入一个新仓库后第一件事不是提需求而是先让 AI 理解这个项目的“家规”。可以执行codex /init通常会在项目根目录生成一个AGENTS.md文件。这个文件可以理解为给 AI 编码助手看的项目说明书。README 是写给人看的AGENTS.md 是写给 AI 看的。在 FPGA 项目里建议把这些内容写进去# AGENTS.md ## 项目背景 本项目为 FPGA RTL 工程主要语言为 Verilog。 除非明确说明不允许使用 SystemVerilog 语法。 ## 代码规范 - 时序逻辑使用非阻塞赋值。 - 组合逻辑使用阻塞赋值。 - 所有寄存器必须有明确复位策略。 - 模块端口命名遵循现有工程风格。 - 不允许随意修改已有公共模块接口。 ## 时钟与复位 - 不允许在 RTL 中硬编码时钟频率假设。 - 时钟约束统一由 XDC 管理。 - 跨时钟域信号必须说明同步方式。 - 单 bit 控制信号使用两级同步。 - 多 bit 数据跨域优先使用异步 FIFO 或握手机制。 ## 验证要求 - 修改 RTL 后必须同步更新 testbench。 - 必须说明仿真激励覆盖了哪些边界场景。 - 若涉及 AXI / AXIS / APB 等协议必须说明握手时序。 ## 实施要求 - 在修改代码前必须先输出 research.md 和 plan.md。 - 未经确认不允许直接改代码。 - 实施完成后更新 task.md 的完成状态。AGENTS.md 的价值不是“让 AI 变聪明”而是让 AI 少犯低级错误。它就像项目的护栏护栏不能替你开车但能减少冲出赛道的概率。四、Step 1深度研究先让 AI 读懂代码很多 AI 生成代码失败不是因为模型能力不够而是它根本没读懂工程。所以第一个正式步骤应该是让 AI 研究现有代码并把理解写成文档。可以使用类似提示词深入阅读当前目录下的 RTL 和 testbench 文件理解模块功能、接口协议、时钟复位、数据流和已有约束。 完成后将你的研究结果写入 research.md。 先不要修改任何代码。如果是某个子系统可以更聚焦详细研究 axis_packet_parser 相关文件理解输入输出协议、状态机行为、异常处理和 testbench 覆盖情况。 将结论写入 research.md列出你发现的潜在问题和不确定点。 先不要实施。research.md最好包含这些内容# research.md ## 1. 模块功能概述 该模块负责…… ## 2. 输入输出接口 | 信号 | 方向 | 含义 | |---|---|---| | s_axis_tvalid | input | 输入数据有效 | | s_axis_tready | output | 模块接收准备 | | s_axis_tdata | input | 输入数据 | | s_axis_tlast | input | 帧结束标志 | ## 3. 时钟与复位 - 主时钟clk - 复位低有效同步复位 rst_n - 未发现跨时钟域逻辑 ## 4. 状态机分析 状态包括 IDLE、HEADER、PAYLOAD、DROP。 状态跳转条件如下…… ## 5. 已有测试覆盖 当前 testbench 覆盖了正常包、短包、连续包。 未覆盖 backpressure、异常 tlast、空包等场景。 ## 6. 潜在风险 - ready 拉低场景覆盖不足。 - tlast 异常时状态机可能无法回到 IDLE。 - 输出侧没有明确错误标志。这一步非常关键。因为research.md是你和 AI 的第一个对齐界面。你可以通过它判断AI 到底是真读懂了还是只是“看起来读懂了”。五、Step 2写 plan.md把方案摊开给人审研究完成后第二步是让 AI 写实施计划而不是马上动代码。提示词可以这样写基于 research.md针对“增加异常帧检测和错误标志输出”这个需求编写详细 plan.md。 计划中必须包含 1. 要修改的文件路径 2. 接口变更 3. 状态机变更 4. testbench 变更 5. 风险和权衡 6. 关键代码片段示例。 先不要实施。一份合格的plan.md不应该只写“修改状态机增加错误处理”这种空话而应该能让工程师直接判断方案对不对。例如# plan.md ## 1. 目标 为 axis_packet_parser 增加异常帧检测能力。 当输入帧长度小于最小长度或 tlast 出现在非法位置时输出 err_flag。 ## 2. 修改文件 - rtl/axis_packet_parser.v - tb/tb_axis_packet_parser.v - docs/interface.md ## 3. 接口变更 新增输出端口 verilog output reg err_flagerr_flag 在检测到异常帧时拉高一个时钟周期。4. 状态机变更在 PAYLOAD 状态下如果 payload_cnt 小于 MIN_LEN 且 s_axis_tlast 拉高则置位 err_flag下一拍回到 IDLE不改变正常帧输出路径。5. 验证计划新增以下用例正常帧过短帧tlast 提前tready 拉低连续异常帧异常帧后恢复正常帧。这一步的目的是把 AI 的“隐式想法”变成“显式设计”。 只要设计还写在模型脑子里风险就很大。 一旦写成文档工程师就能审、能改、能追踪。 --- ## 六、Step 3标注循环把工程判断注入进去 这是整套流程里最有价值的一步。 AI 写完 plan.md 后不要急着实施。 打开文档像审设计文档一样逐条看。 看到不对的地方直接在文档里写注释。 例如 markdown !-- 这里不对这个信号来自另一个时钟域不能直接采样必须先做两级同步。 --或者!-- 删除这一节。本版本不引入外部 DDR 缓存所有数据只走片上 BRAM。 --再或者!-- valid/ready 是整条 AXIS 通道的握手语义不是单个字段的有效标志。 请按整帧字段同时有效的语义重构这一节。 --然后告诉 AI我已经在 plan.md 中添加了注释。 请处理所有注释并相应更新 plan.md。 先不要实施。注意最后一句先不要实施。这句话很重要。否则 AI 可能一边改计划一边顺手把代码也改了。在 FPGA 项目里这种“顺手”往往就是 bug 的开始。这个循环可以重复 1 到 6 次。不要嫌麻烦。真正节省时间的地方不是少审几分钟计划而是少花几天时间查一个上板才暴露的诡异问题。七、Step 4生成 task.md让实施变成 checklist当plan.md已经审得比较稳之后建议再生成一个任务清单根据 plan.md 生成 task.md。 task.md 需要包含所有实施阶段和具体任务可用于进度跟踪。 先不要实施。示例# task.md ## 阶段一接口修改 - [ ] 在 axis_packet_parser.v 中新增 err_flag 输出端口 - [ ] 更新模块例化处的端口连接 - [ ] 更新 interface.md ## 阶段二状态机修改 - [ ] 增加异常帧检测条件 - [ ] 保证 err_flag 只拉高一个周期 - [ ] 确认正常帧路径不受影响 ## 阶段三验证修改 - [ ] 增加过短帧用例 - [ ] 增加 tlast 提前用例 - [ ] 增加 backpressure 用例 - [ ] 增加异常帧后恢复正常帧用例 ## 阶段四回归检查 - [ ] 运行仿真 - [ ] 检查波形 - [ ] 检查是否使用了不允许的语法 - [ ] 总结修改结果task.md的作用很简单让 AI 不是“边想边改”而是“照单执行”。这对 FPGA 项目尤其重要。因为我们希望 AI 在实施阶段少发挥甚至不发挥。创造性应该发生在计划阶段实施阶段越无聊结果越可靠。八、Step 5实施严格按计划执行到这里才进入真正写代码的阶段。可以使用类似提示词实施 task.md 中的所有内容。 完成每个任务后在 task.md 中标记为已完成。 严格按照 plan.md 执行不要引入计划外功能。 不要添加不必要的注释。 不要使用 SystemVerilog 语法。 完成后运行相关仿真并总结修改内容、验证结果和剩余风险。这里有几个关键点第一严格按照 plan.md 执行。不要让 AI 临场加戏。第二不要引入计划外功能。AI 很容易“顺便优化一下”但 FPGA 项目最怕这种没有审过的顺便。第三完成后必须总结剩余风险。比如仿真通过不代表时序通过功能通过不代表资源合理单模块通过不代表系统集成没问题。实施完成后建议让 AI 输出类似总结# implementation_summary.md ## 修改内容 - 修改 rtl/axis_packet_parser.v - 修改 tb/tb_axis_packet_parser.v - 更新 docs/interface.md ## 验证结果 - 正常帧通过 - 过短帧检测通过 - tlast 提前检测通过 - backpressure 场景通过 ## 未覆盖风险 - 尚未进行综合后资源检查 - 尚未进行时序分析 - 尚未进行板级联调这份总结不是形式主义。它能帮助你快速判断现在只是“代码写完了”还是“工程闭环了”。九、一个 FPGA 场景示例AI 不是直接写模块而是先写方案假设我们要做一个简单需求在现有 AXI-Stream 数据通路中增加异常帧检测发现短帧或非法 tlast 时输出错误标志。错误用法通常是帮我改一下 axis_packet_parser让它支持异常帧检测。这样问AI 很可能直接开始写代码。如果上下文不完整它可能会改错状态机误解 valid/ready漏掉 backpressure忽略已有 testbench把错误标志做成电平保持甚至顺手改了模块接口风格。更稳的方式是第一步研究深入研究 axis_packet_parser 相关 RTL 和 testbench。 理解 AXI-Stream 握手、状态机、异常处理和已有测试覆盖。 将结果写入 research.md。 先不要修改代码。第二步计划基于 research.md设计“异常帧检测”功能的实现方案。 写入 plan.md包含接口变更、状态机变更、验证用例和风险。 先不要实施。第三步人工标注在plan.md中写!-- err_flag 只能拉高一个周期不能保持到下一帧。 -- !-- tready 拉低时不能更新 payload_cnt否则 backpressure 场景会计数错误。 -- !-- 不允许新增 FIFO这个需求只允许修改状态机和计数逻辑。 --第四步更新计划我已经在 plan.md 中添加了注释。 请处理所有注释并更新 plan.md。 先不要实施。第五步生成任务并实施根据 plan.md 生成 task.md列出所有实施任务。 先不要实施。确认后实施 task.md 中的所有任务。 完成后更新 task.md并运行仿真。这套流程的重点不在于提示词多华丽而在于顺序正确。先理解再设计先审查再执行。这就是 AI 参与 FPGA 开发时最朴素、也最有效的纪律。十、Skills把经验封装成可复用流程如果说 AGENTS.md 是项目级规则那么 Skills 更像是“某类任务的标准操作手册”。比如如何写 FPGA 编码规范如何审查 RTL如何生成 testbench如何整理 Markdown 文档如何生成 Mermaid 流程图如何把 Markdown 转成 Word如何检查 AI 写作痕迹。Skills 的本质不是魔法插件而是一份结构化的 Markdown 指令。它告诉 AI遇到某类任务时应该按什么流程做。可以把它理解成把一个资深工程师的习惯动作写成 AI 能重复执行的说明书。例如我们可以创建一个fpga-rtl-reviewSkill要求 AI 每次审 RTL 时都检查# fpga-rtl-review ## 触发场景 当用户要求审查 FPGA RTL、Verilog 模块、testbench 或时序相关代码时使用。 ## 检查清单 1. 接口协议是否清晰 2. valid/ready 握手是否正确 3. 时钟复位是否规范 4. 是否存在跨时钟域风险 5. 是否存在锁存器推断 6. 是否存在组合环路 7. 状态机是否有默认分支 8. testbench 是否覆盖边界条件 9. 是否使用了项目禁止的语法 10. 是否可能引入资源或时序问题。这样下一次你让 AI 审代码时就不用每次重新打一长串要求。这对团队尤其有用。个人经验不再只存在脑子里而是沉淀成可复用的流程资产。十一、文档也要 AI 友好优先 Markdown很多 FPGA 项目不缺代码缺的是能长期维护的文档。推荐内部技术文档优先使用 Markdown原因很简单纯文本方便 Git 管理diff 清晰方便代码审查AI 容易读取和修改格式负担小工程师能专注内容后续可以再转换为 Word、PDF 或网页。建议流程先用 Markdown 写清楚内容让 AI 帮你校对逻辑和表达再用工具导出为 Word 或 PDF最后人工调整格式。不要一开始就纠结字体、页边距和目录样式。文档最重要的是先把事情讲明白。对 AI 来说也是一样结构清晰的 Markdown比一份格式复杂的 Word 更容易处理。十二、常见问题1. AI 写的 RTL 怎么维护关键不是“谁写的”而是有没有留下可审查的工程痕迹。至少保留research.mdplan.mdtask.mdimplementation_summary.md仿真用例代码提交记录只要这些材料完整半年后别人接手时不需要猜当时为什么这么写。2. 怎么避免 AI 改一处炸一片核心做法是限制改动范围。在计划阶段要求 AI 明确修改哪些文件不修改哪些文件哪些接口不能动哪些公共模块不能改哪些行为必须保持兼容。不要让 AI 自由搜索全仓库后随意“优化”。3. 换人接手怎么不断档靠文档不靠口口相传。AGENTS.md 记录项目规范research.md 记录理解过程plan.md 记录设计决策task.md 记录实施步骤summary 记录验证结果和遗留风险。这些都是工程资产。4. 如何确保规范真的被执行把规范写进 AGENTS.md再把检查动作写进任务流程。例如实施完成后检查是否违反 AGENTS.md 中的 Verilog 编码规范。 重点检查 1. 是否使用 SystemVerilog 语法 2. 是否存在跨时钟域直采 3. 是否存在未复位寄存器 4. 是否存在锁存器推断 5. 是否更新 testbench。规范不能只写在文档里还要变成每次任务结束前的检查项。十三、总结AI 负责执行工程师负责判断AI 编码助手正在改变开发方式但 FPGA 开发的底层逻辑没有变协议要严谨时序要收敛资源要可控验证要闭环文档要可继承。所以面向 AI 的 FPGA 开发流程不是“让 AI 替你开发”而是“让 AI 在你的工程框架内高效执行”。推荐工作流可以压缩成一句话深度阅读写研究详细规划反复标注确认无误再让 AI 按任务清单执行。更短一点人定方向AI 干活先审计划再写代码。只要把这个边界守住AI 就不再是一个到处乱改的黑盒而会变成 FPGA 工程师手里一把真正好用的工具。它不会替代工程判断。但它可以把大量重复、繁琐、机械的工作接过去。而我们要做的是把方向盘握稳。