Claude Code 辅助 Verilog FPGA 开发实践
Verilog 开发门槛正被 AI 重新定义。通过 Claude Code 辅助,在不查阅手册的情况下完成了 UART、FSM 及 PWM 控制的 FPGA 模块设计与验证。实测显示 AI 能生成参数化 RTL 代码、三段式状态机及 Self-Checking Testbench,效率提升显著。但需注意位宽截断与锁存器隐患,人工 Review 仍不可或缺。硬件工程师重心将转向架构设计与 AI 生成模块验证。

Verilog 开发门槛正被 AI 重新定义。通过 Claude Code 辅助,在不查阅手册的情况下完成了 UART、FSM 及 PWM 控制的 FPGA 模块设计与验证。实测显示 AI 能生成参数化 RTL 代码、三段式状态机及 Self-Checking Testbench,效率提升显著。但需注意位宽截断与锁存器隐患,人工 Review 仍不可或缺。硬件工程师重心将转向架构设计与 AI 生成模块验证。

作为一名 FPGA 工程师,日常工作往往在'连线'和'看波形'中度过。一个简单的串口模块,虽然原理简单,但手写起来:计数器位宽算不对、状态机跳转条件漏写、Reset 信号极性搞反……这些低级错误往往要消耗半天时间 Debug。
既然 Claude Code 在软件界大杀四方,那它懂时序逻辑吗?它能分清阻塞赋值(=)和非阻塞赋值(<=)吗?今天我决定用一个经典项目来验证它的成色。
目标:在 Xilinx Artix-7 平台上,设计一个智能呼吸灯控制器。
功能需求:
0xAA (帧头) + [PWM_VAL] (亮度) + 0x55 (帧尾)。PWM_VAL 调整 LED 亮度。工具链:VS Code + Claude Code (插件版) + Vivado 2017.4
在 Verilog 中,计算分频系数总是很烦人。我直接向 Claude 提问。
Prompt:
'我需要一个 Verilog 模块
uart_rx。 输入时钟clk为 50MHz,波特率 115200。 需处理亚稳态(双触发器同步),使用过采样逻辑保证稳定性。 输出:rx_data_valid和rx_data[7:0]。'
Claude Code 秒回了代码,并且做对了两件关键的事:
parameter CLK_FREQ 和 parameter BAUD_RATE,并在代码内部自动计算了分频计数器 CLKS_PER_BIT = CLK_FREQ / BAUD_RATE。r_rx_d1, r_rx_d2 来同步异步信号,这是初学者最容易忽略的。// Claude 生成的代码片段
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
r_rx_d1 <= 1'b1;
r_rx_d2 <= 1'b1;
end else begin
r_rx_d1 <= rx_in;
r_rx_d2 <= r_rx_d1; // 同步处理
end
end
体验:这一步直接省去了我拿计算器算时钟周期的 10 分钟。
协议解析是本次挑战的核心。不仅要处理数据移位,还要判断帧头帧尾。
Prompt:
'编写一个名为
cmd_parser的模块。 接收rx_data和rx_valid。 实现一个三段式状态机: IDLE -> WAIT_HEAD(检测 0xAA) -> WAIT_DATA -> WAIT_TAIL(检测 0x55) -> UPDATE。 只有完整接收包后,才更新输出led_pwm_duty。'
Claude Code 生成的状态机逻辑非常清晰,甚至使用了 localparam 定义状态,代码风格堪比教科书:
// Claude 生成的 FSM 逻辑
localparam IDLE = 3'd0;
localparam CHECK_HEAD = 3'd1;
localparam GET_DATA = 3'd2;
// ...
always @(*) begin
next_state = current_state;
case (current_state)
IDLE: begin
if (rx_valid && rx_data == 8'hAA) next_state = GET_DATA;
end
GET_DATA: begin
if (rx_valid) next_state = CHECK_TAIL;
end
// ...
// Claude 甚至处理了异常回退逻辑,如果不符合协议直接回 IDLE
endcase
end
避坑:Claude 第一次生成的代码中,Reset 逻辑使用的是高电平复位,而我的开发板是低电平复位。
修正 Prompt:'请将所有复位逻辑修改为 negedge rst_n。' ——它在 3 秒内完成了全局替换。
写 Testbench 是所有硬件工程师的痛。要模拟 UART 的串行时序非常麻烦。
Prompt:
"为上述模块编写一个 Testbench。生成 50MHz 时钟。编写一个
task send_byte(input [7:0] data)模拟 UART 发送时序(包含起始位、停止位)。构造三个测试用例:正常包、帧头错误的包、帧尾错误的包。使用$display自动打印测试是否通过。"
这是 Claude Code 最让我惊艳的地方。它不仅写了 TB,还写了 Task!
// Testbench 片段
task uart_send_byte;
input [7:0] data;
integer i;
begin
rx_line = 0; // Start bit
#(BIT_PERIOD);
for (i=0; i<8; i=i+1) begin
rx_line = data[i];
#(BIT_PERIOD);
end
rx_line = 1; // Stop bit
#(BIT_PERIOD);
end
endtask
initial begin
// Test Case 1: Valid Packet
uart_send_byte(8'hAA);
uart_send_byte(8'h80); // 50% brightness
uart_send_byte(8'h55);
#1000;
if (pwm_val_out == 8'h80) $display("TC1 PASSED: PWM Updated correctly");
else $display("TC1 FAILED");
end
虽然 Claude Code 很强,但在 Verilog 开发中不能盲信。实测中发现两个问题需要人为干预:
always @(*) 中,如果 if 没有配套的 else,会产生 Latch。好在 Claude Code 大部分时候会补全 default 分支,但作为工程师必须 Review 这一点。Prompt 技巧: 在生成代码前,加上这句话:'请遵循严格的 RTL 编码规范,禁止生成 Latch,所有时序逻辑使用非阻塞赋值。'
| 维度 | 传统开发方式 | Claude Code 辅助开发 | 提升幅度 |
|---|---|---|---|
| 模块定义 | 手写端口列表,查漏补缺 (15 mins) | 描述需求,自动生成 (1 min) | 15x |
| 状态机编写 | 画图 -> 翻译代码 -> 调试跳转 (60 mins) | 描述状态流转 -> 生成代码 (5 mins) | 12x |
| Testbench | 最耗时的部分,需手写激励 (90 mins) | 自动生成 Task 和 Check 逻辑 (10 mins) | 9x |
| Debug | 对着波形图找刺 (45 mins) | 粘贴报错 log,AI 分析逻辑漏洞 (5 mins) | 9x |
| 总耗时 | 约 3.5 小时 | 约 25 分钟 | ~800% |
这次实战让我意识到,对于标准接口(SPI, I2C, UART)和常见逻辑,Claude Code 的代码质量已经超过了 80% 的初级工程师。
但这并不意味着硬件工程师失业了。恰恰相反,我们的重心将从 '如何写出符合语法的 Verilog' 转移到 '如何设计系统架构'和'如何验证 AI 生成的模块'。
在未来,Design 可能是 AI 做的,但 Sign-off(签核) 依然必须是人。拥抱 Claude Code,把我们从繁琐的连线中解放出来,去思考更复杂的架构设计吧!

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online