news 2026/6/26 5:27:09

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
面向 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-2001,AI 却写了 SystemVerilog 语法。

这些问题,单靠“生成后再改”会非常痛苦。

更好的做法是把 AI 的工作拆成两个阶段:

  1. 思考阶段:阅读代码、理解系统、写研究报告和实施计划;

  2. 执行阶段:严格按照已经审过的计划修改代码。

一句话概括:

让 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_flag

err_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 或网页。

建议流程:

  1. 先用 Markdown 写清楚内容;

  2. 让 AI 帮你校对逻辑和表达;

  3. 再用工具导出为 Word 或 PDF;

  4. 最后人工调整格式。

不要一开始就纠结字体、页边距和目录样式。
文档最重要的是先把事情讲明白。

对 AI 来说也是一样:
结构清晰的 Markdown,比一份格式复杂的 Word 更容易处理。


十二、常见问题

1. AI 写的 RTL 怎么维护?

关键不是“谁写的”,而是有没有留下可审查的工程痕迹。

至少保留:

  • research.md

  • plan.md

  • task.md

  • implementation_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 工程师手里一把真正好用的工具。

它不会替代工程判断。
但它可以把大量重复、繁琐、机械的工作接过去。

而我们要做的,是把方向盘握稳。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/26 5:24:21

帮优不帮劣吗

一.很多时候优势和劣势该怎么帮对线优势的话,尽量去围绕着优势路打,然后去拿到更多的资源二.这个理论是正确的吗不一定是正确的,需要根据实际情况而来,例如狗头这是发育性的尽量去让他发育,但是不能让优势路变成劣势路三.扫描还是假眼大多的时候在gank一波以后换成扫描,如果自己…

作者头像 李华
网站建设 2026/6/26 5:23:32

[MongoDB小技巧19]MongoDB Oplog 深度解析:原理、配置与最佳实践

一、Oplog 概述 1.什么是 Oplog&#xff1f; Oplog&#xff08;operations log&#xff0c;操作日志&#xff09;是 MongoDB 中一个特殊的定容集合&#xff08;capped collection&#xff09;。它记录了对数据库中数据发起的所有修改操作——包括插入、更新、删除以及 DDL 命令…

作者头像 李华
网站建设 2026/6/26 5:21:35

边界驱动调和模型:非平衡稳态的遍历性与涨落分析

1. 从“非平衡”到“涨落”&#xff1a;一个统计物理的硬核视角如果你在统计物理或者复杂系统领域摸爬滚打过一阵子&#xff0c;大概率会对“平衡态”和“遍历性”这两个词感到既熟悉又敬畏。熟悉&#xff0c;是因为它们是整个统计物理大厦的基石&#xff1b;敬畏&#xff0c;是…

作者头像 李华
网站建设 2026/6/26 5:20:59

Strix Halo 前瞻,下一代 AMD APU 能否终结端侧 AI 的显存焦虑

Strix Halo 的架构野心&#xff1a;端侧 AI 的显存破局点 最近 AMD 放出的 Strix Halo 架构信息&#xff0c;在硬件圈子里激起了不小的水花。对于咱们这些折腾本地大模型的技术爱好者来说&#xff0c;最让人兴奋的莫过于它可能彻底解决移动端运行 AI 的“显存焦虑”。过去我们在…

作者头像 李华
网站建设 2026/6/26 5:20:46

Thead子类创建线程vsThead直接创建进程

采用继承 Thread 子类创建线程时&#xff0c;由于 Java 是单继承机制&#xff0c;该类无法再继承其他父类&#xff0c;线程对象和业务执行逻辑绑定在一起&#xff0c;多个线程实例之间无法共享任务资源&#xff1b;而实现 Runnable 接口配合 Thread 创建线程不受单继承限制&…

作者头像 李华
网站建设 2026/6/26 5:20:17

AI赋能下全链路标准化数据流动安全风险监测平台技术与落地研究

一、概要在《数据安全法》《网络数据安全管理条例》等制度约束与数字基础设施建设的双重驱动下&#xff0c;数据安全监测已从传统合规工具&#xff0c;演进为政企数字化治理的核心基础能力。当前企业业务架构云化、接口化、跨域化特征显著&#xff0c;数据流转路径复杂、节点分…

作者头像 李华