摘要:在近期的硬件开发中,AI 工具正在改变 HDL 的编写方式。本文记录了一次利用 Claude Code 辅助完成包含 UART 通信、协议解析(FSM)及 PWM 控制的完整 FPGA 模块设计与验证的过程。
背景与动机
作为 FPGA 工程师,日常工作中难免陷入'连线'和'看波形'的细节里。一个简单的串口模块,虽然原理清晰,但手写时容易遇到计数器位宽算错、状态机跳转条件遗漏或 Reset 信号极性搞反等问题,这些低级错误往往消耗大量 Debug 时间。
既然 AI 在软件领域表现突出,它是否也能胜任时序逻辑?能否区分阻塞赋值与非阻塞赋值?我决定用一个经典项目来验证它的实际能力。
项目挑战:从串口到 LED 的全链路设计
目标:在 Xilinx Artix-7 平台上,设计一个智能呼吸灯控制器。
功能需求:
- 通信层:通过 UART(波特率 115200)接收上位机指令。
- 协议层:解析指令包
0xAA(帧头) +[PWM_VAL](亮度) +0x55(帧尾)。 - 控制层:根据解析的
PWM_VAL调整 LED 亮度。 - 验证层:提供完整的 ModelSim/Vivado 仿真激励。
工具链:VS Code + Claude Code (插件版) + Vivado 2017.4
RTL 设计实录
基础设施:波特率发生器与 UART RX
在 Verilog 中,计算分频系数总是很繁琐。我直接向 AI 提问。
Prompt:
'我需要一个 Verilog 模块
uart_rx。输入时钟clk为 50MHz,波特率 115200。需处理亚稳态(双触发器同步),使用过采样逻辑保证稳定性。输出:rx_data_valid和rx_data[7:0]。'
Claude Code 秒回了代码,并且做对了两件关键的事:
- 参数化设计:使用了
parameter CLK_FREQ和parameter BAUD_RATE,并在代码内部自动计算了分频计数器。 - 打拍处理:自动生成了
r_rx_d1,r_rx_d2来同步异步信号,这是初学者最容易忽略的地方。
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
这一步直接省去了拿计算器算时钟周期的时间。
核心难点:让 AI 写三段式状态机(FSM)
协议解析是本次挑战的核心。不仅要处理数据移位,还要判断帧头帧尾。
Prompt:
'编写一个名为
cmd_parser的模块。接收rx_data和rx_valid。实现一个三段式状态机:IDLE -> WAIT_HEAD(检测 0xAA) -> WAIT_DATA -> WAIT_TAIL(检测 0x55) -> UPDATE。只有完整接收包后,才更新输出led_pwm_duty。'
生成的状态机逻辑非常清晰,甚至使用了 localparam 定义状态,代码风格堪比教科书:


