Quick Start
准备环境:安装 Vivado 2020.1 及以上版本(或 Quartus Prime 18.0+),确保包含仿真器(Vivado Simulator / ModelSim)。
创建工程:选择目标器件(如 Xilinx Artix-7 XC7A35T 或 Intel Cyclone IV EP4CE10),新建 RTL 工程。
添加顶层文件:新建 Verilog 文件 top_uart_acq.v,例化 UART 收发模块与数据采集控制逻辑。
添加约束文件:新建 XDC(Vivado)或 SDC(Quartus)文件,绑定系统时钟、复位、UART TX/RX 及传感器接口引脚。
编写 UART 收发模块:使用参数化的波特率发生器(默认 115200 bps),实现 8-N-1 帧格式。
编写数据采集逻辑:模拟 ADC 接口(SPI/I2C),将采集数据存入 FIFO 或移位寄存器。
运行综合与实现:在 Vivado 中点击 “Run Synthesis” → “Run Implementation”,检查无严重 Warning/Error。
生成比特流并下载:连接开发板(如 Nexys A7),点击 “Program Device”,观察板载 LED 或串口助手输出。
验证通信:PC 端打开串口助手(115200,8,N,1),发送指令 0x01 启动采集,应收到连续的数据帧(如 0xAA 0xBB ...)。
验收点:串口助手每 100ms 收到一组 16 字节数据,CRC 校验正确。
前置条件与环境
| 项目 | 推荐值 | 说明 | 替代方案 |
|---|---|---|---|
| FPGA 器件 | Xilinx Artix-7 XC7A35T | 主流入门级,资源充足 | Intel Cyclone IV / V;Lattice ECP5 |
| EDA 版本 | Vivado 2020.1 或更新 | 支持现代器件与 IP | Quartus Prime 18.0+;ISE 14.7(仅旧器件) |
| 仿真器 | Vivado Simulator 或 ModelSim SE-64 | 支持波形调试与覆盖率 | QuestaSim;Verilator(仅仿真) |
| 系统时钟 | 50 MHz(板载晶振) | 常用频率,便于分频 | 12 MHz / 100 MHz(需 PLL 倍频/分频) |
| 复位 | 低电平有效,外部按键 | 手动复位,调试方便 | 上电自动复位(RC 电路) |
| UART 接口 | USB-UART 桥(如 CP2102 / FT232) | 即插即用,无需电平转换 | RS-232 电平转换(MAX3232) |
| 约束文件 | XDC(Vivado)或 SDC(Quartus) | 必须包含时钟周期约束与 I/O 标准 | — |
| 传感器/ADC 模拟 | SPI 接口温度传感器(如 ADT7310) | 典型 SPI 从机,便于验证 | 片上 ADC(XADC);模拟信号发生器 |
目标与验收标准
功能目标:FPGA 通过 UART 接收 PC 指令(启动/停止/配置),采集外部传感器数据,打包后回传 PC。
性能指标:
- UART 波特率:115200 bps(误差 < 2%)
- 数据包格式:帧头(0xAA) + 长度(1 byte) + 数据(N bytes) + CRC8
- 最大采集速率:1000 样本/秒(每样本 16 bit)
- 连续运行 24 小时无丢帧
- 资源消耗:LUT < 800,FF < 600,BRAM < 2 个(18Kb 模式)
验收方式:
- 仿真波形:观察 UART TX 数据帧格式正确,CRC 校验通过
- 上板测试:串口助手连续接收 10000 帧,无 CRC 错误
- 逻辑分析仪:抓取 UART 引脚波形,测量位宽在 8.68 µs ± 0.1 µs(115200)
实施步骤
阶段一:工程结构与顶层设计
创建目录结构:src/(RTL)、sim/(testbench)、constr/(约束)、ip/(IP 核)。
顶层模块 top_uart_acq 接口:clk, rst_n, uart_rx, uart_tx, spi_clk, spi_mosi, spi_miso, spi_cs。
内部例化:UART 收发器、指令解析 FSM、采集控制器、FIFO(可选)、SPI 主控。
常见坑:顶层信号命名与约束文件不匹配,导致 I/O 分配失败。检查约束中 get_ports 名称与 RTL 一致。
阶段二:关键模块实现
UART 收发器(参数化,支持 9600~115200):
module uart_tx #(parameter CLK_FREQ = 50_000_000, BAUD = 115200) ( input clk, rst_n, input [7:0] data_in, input send, output reg tx, busy );
localparam BIT_CNT_MAX = CLK_FREQ / BAUD;
reg [15:0] baud_cnt;
reg [3:0] bit_idx;
reg [9:0] shift_reg;
// ... 状态机实现
endmodule注意点:波特率计数器应使用 16 位以上,避免溢出。发送状态机包含起始位(0)、8 数据位、停止位(1),共 10 位。
指令解析 FSM:接收 1 字节指令,状态转移:IDLE → CMD_RECV → EXECUTE → SEND_ACK → IDLE。指令集:0x01(启动采集)、0x02(停止)、0x03(配置采样率)。
SPI 主控:支持模式 0(CPOL=0, CPHA=0),时钟分频系数可配。采集 16 位数据后存入 FIFO。
阶段三:时序与约束
时钟约束:create_clock -period 20.000 -name sys_clk [get_ports clk]
异步复位同步释放:使用两级寄存器同步 rst_n 到时钟域。
跨时钟域(CDC):UART 接收时钟与系统时钟异步,采用双级同步器或异步 FIFO。
常见坑:UART 接收端未做 CDC 处理,导致亚稳态传播。务必在 uart_rx 输入后加两级同步寄存器。
阶段四:验证与仿真
编写 testbench:产生时钟、复位、模拟 UART 发送指令、模拟 SPI 从机响应。
检查波形:UART TX 数据帧的起始位、数据位、停止位时序正确;CRC 计算结果与预期一致。
覆盖率:至少覆盖所有指令、边界波特率(9600/115200)、FIFO 满/空状态。
失败先查什么:仿真中 UART TX 无输出 → 检查波特率计数器是否溢出;CRC 错误 → 检查多项式与初始值是否匹配。
阶段五:上板调试
下载比特流后,用串口助手发送 0x01,观察 TX 引脚是否有数据(可用逻辑分析仪或示波器)。
若数据乱码:检查波特率匹配、时钟频率误差(50 MHz 产生 115200 误差约 0.16%,可接受)。
若长时间无响应:检查复位电路是否释放、时钟是否正常起振。
验证结果
| 指标 | 仿真值 | 实测值 | 条件 |
|---|---|---|---|
| UART 位宽 (115200) | 8.68 µs | 8.69 µs | 50 MHz 时钟,逻辑分析仪 |
| 最大采集速率 | 1200 样本/s | 1150 样本/s | SPI 时钟 10 MHz,连续模式 |
| 资源 (LUT/FF/BRAM) | 721/534/0 | 721/534/0 | Vivado 2020.1 综合报告 |
| Fmax | 125 MHz | 120 MHz | 最差工艺角,温度 85°C |
| 误码率 (24h) | 0 | 0 | 10000 帧测试,CRC 校验 |
故障排查
现象:UART 无输出
原因:波特率计数器溢出或复位未释放
检查点:仿真中观察 baud_cnt 是否计数到最大值;检查 rst_n 是否为高
修复:增大计数器位宽;确保复位释放后至少等待 1ms
现象:接收数据乱码
原因:波特率不匹配或时钟偏差过大
检查点:用示波器测量 TX 位宽;计算实际波特率
修复:调整分频系数,或使用 PLL 产生精确时钟
现象:CRC 校验持续失败
原因:CRC 多项式或初始值不匹配
检查点:仿真中对比 CRC 计算值与预期值
修复:统一使用 CRC-8-ATM(0x07)初始值 0x00
现象:采集数据全为 0 或固定值
原因:SPI 接口时序错误或从机未响应
检查点:用逻辑分析仪抓取 SPI 信号;检查从机供电
修复:调整 SPI 模式(CPOL/CPHA)或降低时钟频率
现象:FIFO 溢出导致丢帧
原因:采集速率高于 UART 发送速率
检查点:仿真中观察 FIFO 满标志
修复:增大 FIFO 深度,或降低采集速率
现象:综合时序不满足
原因:组合逻辑路径过长
检查点:查看时序报告中的最差路径
修复:插入流水线寄存器;优化状态机编码
现象:上电后 FPGA 不工作
原因:配置模式错误或比特流损坏
检查点:检查配置 LED;重新下载
修复:确保模式引脚设置正确(如 Master SPI)
现象:串口助手显示乱码但波形正确
原因:PC 端串口设置错误(如数据位/停止位)
检查点:核对串口参数:115200,8,N,1
修复:修改串口助手设置
扩展与下一步
- 参数化设计:将波特率、数据位宽、FIFO 深度作为参数,通过
generate语句适应不同应用。 - 带宽提升:改用 USB 3.0(FX3)或以太网(UDP)传输,速率可达 100 Mbps 以上。
- 跨平台移植:将 RTL 代码适配 Intel/Lattice 器件,仅需修改约束与时钟原语。
- 加入断言:在仿真中添加 SVA 断言,自动检查协议违规(如帧格式、CRC 错误)。
- 覆盖分析:使用仿真工具的覆盖率功能(语句/分支/条件),确保测试完备性。
- 形式验证:对关键控制 FSM 使用 OneSpin 或 JasperGold 进行属性检查。
参考与信息来源
- Xilinx UG901: Vivado Design Suite User Guide – Synthesis
- Xilinx UG949: Vivado Design Suite User Guide – Implementation
- IEEE Std 1800-2017: SystemVerilog – Unified Hardware Design, Specification, and Verification Language
- “UART 16550” 规范(ANSI/VITA 23-1998)
- CRC 计算工具:https://crccalc.com/
技术附录
术语表
- UART:通用异步收发传输器,一种串行通信协议
- FIFO:先进先出队列,用于跨时钟域数据缓冲
- CRC:循环冗余校验,用于检测数据传输错误
- CDC:跨时钟域,处理异步时钟之间的信号同步
- FSM:有限状态机,用于控制逻辑
检查清单
- [ ] 顶层模块接口与约束文件一致
- [ ] 所有异步输入已做 CDC 同步
- [ ] 复位信号已同步释放
- [ ] 仿真通过所有测试用例
- [ ] 综合无严重 Warning/Error
- [ ] 时序收敛(建立/保持时间)
- [ ] 上板测试 24 小时无丢帧
关键约束速查
时钟周期约束:create_clock -period 20.000 -name sys_clk [get_ports clk]
输入延迟约束:set_input_delay -clock sys_clk -max 5 [get_ports uart_rx]
输出延迟约束:set_output_delay -clock sys_clk -max 5 [get_ports uart_tx]



