Quick Start:快速上手
- 准备硬件:FPGA开发板(如Xilinx Artix-7或Intel Cyclone IV)和USB-UART模块(如FT232或CH340)。
- 安装EDA工具:推荐Vivado 2019.1+或Quartus II 18.0+,创建新工程并选择对应器件。
- 编写UART发送模块:配置波特率115200,数据位8,停止位1,无校验。
- 编写UART接收模块:与发送模块共用波特率时钟,确保同步。
- 编写顶层模块:实现loopback模式,将接收到的数据直接回环发送。
- 添加约束文件:使用.xdc(Vivado)或.sdc(Quartus)指定UART TX/RX引脚及时钟周期。
- 综合与实现:运行Synthesis和Implementation,检查无错误。
- 生成比特流并下载:将比特流文件烧录至FPGA。
- 连接串口调试助手:使用PuTTY或sscom,设置波特率115200,连接对应COM口。
- 验证loopback:发送任意字节(如0x55),应能立即收到相同字节,确认通信成功。
前置条件与环境
| 项目 | 推荐值 | 说明 | 替代方案 |
|---|---|---|---|
| FPGA器件 | Xilinx Artix-7 XC7A35T 或 Intel Cyclone IV EP4CE10 | 需足够逻辑单元(>500 LUT) | 任何带足够资源的FPGA |
| EDA工具 | Vivado 2019.1 或 Quartus II 18.0 | 推荐使用稳定版本 | Vivado 2018.3+ / Quartus 17.0+ |
| 仿真器 | Vivado Simulator 或 ModelSim/QuestaSim | 用于功能验证 | GHDL+GTKWave(开源) |
| 时钟 | 50 MHz 板载晶振 | 或任意可用时钟源 | 25/100 MHz(需调整波特率分频) |
| 复位 | 异步低电平复位(板上按键) | 确保初始状态可控 | 同步复位(需修改代码) |
| 接口依赖 | UART TX/RX 引脚连接至 USB-UART 模块 | 需电平匹配(3.3V或5V) | 直接通过GPIO连接PC串口 |
| 约束文件 | 包含时钟周期、I/O引脚位置与电平标准 | 避免时序违例或引脚冲突 | 无约束可能导致不可靠行为 |
目标与验收标准
- 功能点:实现UART发送与接收,支持loopback模式。
- 性能指标:波特率115200(±2%误差内),数据位8,停止位1,无校验。
- 资源上限:逻辑单元消耗不超过500 LUT,块RAM使用不超过1个(可选)。
- 验收方法:通过串口调试助手发送测试数据,验证回环正确性;使用示波器或逻辑分析仪检查波形时序。
实施步骤
步骤1:硬件连接与准备
将USB-UART模块连接至FPGA开发板的GPIO引脚:TX接FPGA的RX引脚,RX接FPGA的TX引脚,GND共地。确保电平标准匹配(通常为3.3V)。
步骤2:创建工程与配置
打开Vivado或Quartus,新建工程,选择目标器件(如XC7A35T)。添加设计源文件(Verilog/VHDL),并设置顶层模块。
步骤3:编写UART发送模块
发送模块的核心是波特率时钟分频器。以50 MHz时钟为例,115200波特率对应的分频系数为:50,000,000 / 115200 ≈ 434。每个数据位持续434个时钟周期。发送过程包括起始位(低电平)、8个数据位(LSB first)、停止位(高电平)。代码中需实现状态机:IDLE → START → DATA → STOP。
步骤4:编写UART接收模块
接收模块同样使用波特率时钟,但需在起始位下降沿后采样中点(即半个位周期后)以避开信号跳变。采样策略:在每个数据位的中点(约第217个时钟周期)读取RX引脚电平,确保稳定。接收状态机:IDLE → START → DATA → STOP。
步骤5:编写顶层模块与loopback逻辑
顶层模块实例化发送和接收模块,将接收模块的输出数据直接连接到发送模块的输入数据端口。当接收完成时,触发发送使能,实现自动回环。注意处理数据有效信号(rx_done)与发送开始信号(tx_start)的时序对齐。
步骤6:添加约束文件
约束文件指定时钟周期(如50 MHz对应20 ns)、引脚位置(如TX分配到J15,RX分配到K16)和电平标准(LVCMOS33)。示例约束(Vivado .xdc):create_clock -period 20.000 [get_ports clk];set_property PACKAGE_PIN J15 [get_ports tx]。
步骤7:综合、实现与下载
运行综合和实现,检查时序报告,确保无建立时间违例。生成比特流文件(.bit),通过JTAG下载至FPGA。
步骤8:验证与调试
打开串口调试助手,设置波特率115200、8数据位、1停止位、无校验。发送十六进制数据0x55(二进制01010101),观察接收窗口是否回显相同数据。若失败,检查硬件连接、波特率分频误差(应<2%)、引脚约束是否正确。
验证结果
成功验证后,串口调试助手应显示发送与接收数据完全一致。使用逻辑分析仪抓取TX/RX波形,可观察到起始位、8个数据位(LSB first)和停止位,位宽约为8.68 μs(115200波特率对应)。
排障指南
- 无回显或数据错误:检查TX/RX引脚是否接反;确认波特率分频系数计算无误;验证时钟频率与约束一致。
- 数据乱码:检查数据位顺序(LSB first)、停止位配置;确保接收采样点位于位中点。
- 时序违例:在约束文件中正确声明时钟;减少组合逻辑延迟,必要时添加流水线。
- 硬件无响应:检查USB-UART模块驱动是否安装;确认FPGA供电正常。
扩展:优化与高级应用
- 支持可变波特率:通过寄存器配置分频系数,实现动态切换。
- 增加FIFO缓冲:使用块RAM实现FIFO,处理连续数据流,防止丢包。
- 多通道UART:复用波特率时钟,实例化多个收发模块,实现多路通信。
- 集成校验位:添加奇偶校验逻辑,增强数据完整性。
参考资源
- 标准文档:ANSI/EIA-232 串行通信标准。
- 工具手册:Vivado Design Suite User Guide (UG910);Quartus II Handbook。
- 开源代码:GitHub上的UART Verilog实现(如ZipCPU的uart.v)。
附录:关键代码片段
波特率分频器示例(Verilog):
localparam BAUD_DIV = 434; // 50MHz / 115200
reg [8:0] baud_cnt;
wire baud_tick = (baud_cnt == BAUD_DIV/2 - 1);
always @(posedge clk or negedge rst_n) begin
if (!rst_n) baud_cnt <= 0;
else if (baud_cnt == BAUD_DIV - 1) baud_cnt <= 0;
else baud_cnt <= baud_cnt + 1;
end发送状态机示例:
always @(posedge clk or negedge rst_n) begin
if (!rst_n) state <= IDLE;
else case (state)
IDLE: if (tx_start) state <= START;
START: if (baud_tick) state <= DATA;
DATA: if (bit_cnt == 7 && baud_tick) state <= STOP;
STOP: if (baud_tick) state <= IDLE;
endcase
end


