基于FPGA的时间数字转换器(TDC)抖动(jitter)测试系统
项目概述
本项目实现了一个完整的FPGA系统,用于通过SPI接口控制和读取AS6501 TDC芯片。系统包括SPI主控模块、控制模块、测试序列器、Block RAM结果存储、UART批量传输模块和Python数据分析工具,支持完整的测试与分析流程:
上电命令→配置寄存器写入/回读验证→Init命令启动测量→中断驱动的连续测量(默认10000次)→结果存入Block RAM→按键触发UART批量传输到上位机→Python解析数据并计算Jitter
核心特性
- 批量测量模式: 连续采集MAX_MEASUREMENTS次(默认10000)后自动停止
- Block RAM存储: 48位×10000条测量数据,使用Vivado Block RAM推断
- UART批量传输: BTN[1]按键触发,115200 baud,8字节数据包格式
- 电平触发中断: 支持AS6501中断始终为低电平的模式(直接再次读取)
- Python Jitter分析: 解析UART数据→计算时钟周期/TIE→生成6子图分析报告
硬件平台
- FPGA芯片: XC7A35T-2FGG484I (Artix-7系列)
- 时钟频率: 50MHz (引脚 Y18)
- 接口:
- SPI接口 (12.5MHz时钟频率)
- SCLK: E16
- MOSI: D14
- MISO: E13
- CS: F13
- AS6501中断信号 (低电平有效)
- INT_N: C13
- REFCLK: A13 ( Output 10Mhz)
- UART接口 (115200 baud, 8N1)
- TX: G16
- RX: G15
- 4个LED: F19, E21, D20, C20 (共阳极,低电平点亮)
- 4个按键: M13, K14, K13, L13 (低电平有效,按下时为低电平)
- 1个复位按键: F20 (低电平有效)
- SPI接口 (12.5MHz时钟频率)
- IO电压: 3.3V
- BRAM预估: ~15-20 / 50 Block RAMs (用于10000×48位结果存储)
SPI通信参数
- 频率: 12.5MHz
- 模式: CPOL=0, CPHA=1 (Mode 1)
- 数据传输: MSB先行
- 时序要求: CS拉高前,需要距离最后一个SCLK下降沿半个周期的时间
- AS6501协议格式:
- 单字节命令:
0x30= Power ON 命令0x18= Init 命令
- 写配置寄存器:
[0x80 + 地址][数据](2字节) - 读结果寄存器:
[0x60 + 地址]←[数据](1字节发送,1字节接收) - 读配置寄存器:
[0x40 + 地址]←[数据](1字节发送,1字节接收)
- 单字节命令:
项目结构
fpga_a7_tdc_jitter_test_solution/ ├── rtl/ # RTL设计文件 │ ├── top_module.v # 顶层模块 (含中断同步器/BTN[1]边沿检测/RAM/UART) │ ├── spi_master.v # SPI主控模块 │ ├── spi_controller.v # SPI控制器 │ ├── test_sequencer.v # 测试序列器 (16状态, 含STOPPED状态/测量计数) │ ├── result_ram.v # 双端口Block RAM (存储测量结果) │ ├── uart_result_sender.v # UART批量传输模块 (RAM→UART) │ ├── uart_tx.v # UART发送模块 (ALINX, 115200 baud) │ ├── uart_rx.v # UART接收模块 (ALINX, 115200 baud) │ └── clk_divider.v # 时钟分频器 (50MHz→50kHz) ├── sim/ # 仿真文件 │ ├── as6501_model.v # AS6501行为模型 (支持always-low中断) │ ├── tb_top_module.v # 顶层测试平台 (10次测量+批量UART验证) │ └── tb_top_module.gtkw # GTKWave波形配置 ├── constraints/ # 约束文件 │ └── fpga_constraints.xdc # Vivado约束文件 (含中断引脚C13) ├── scripts/ # 脚本文件 │ ├── run_simulation.bat # Windows仿真脚本 │ ├── run_simulation.sh # Linux/Mac仿真脚本 │ ├── check_syntax.bat # 语法检查脚本 │ ├── create_vivado_project.tcl # 创建Vivado工程 │ ├── run_synthesis.tcl # 完整综合实现 │ ├── run_synthesis_only.tcl # 仅综合检查 │ ├── create_project.bat # 创建工程批处理 │ ├── run_vivado_synthesis.bat # 完整构建批处理 │ ├── run_vivado_synth_only.bat # 仅综合批处理 │ └── open_vivado_gui.bat # 打开Vivado GUI ├── plans/ # 设计规划文件 │ ├── AS6501_SPI_Plan # SPI通信设计规范 │ └── AS6501_LVDS_Plan # LVDS通信计划 (未来阶段) ├── guides/ # 指南文档 │ ├── QUICKSTART.md # 快速开始指南 │ ├── DEBUG_METHODS.md # 调试方法总结 │ ├── debug_guide_ila.md # ILA调试指南 │ └── clock_generation_guide.md # 时钟生成指南 ├── parse_tdc_data.py # Python数据解析与Jitter分析工具 ├── TDC_RAW_Data.txt # TDC原始UART数据 (hex字节) ├── TDC_RAW_Data_parsed.csv # 解析后的CSV数据 ├── TDC_RAW_Data_jitter_analysis.png # Jitter分析图表 (6子图) ├── README.md # 本文件 ├── CHANGELOG.md # 版本更新日志 └── filelist.txt # 文件清单 系统架构
信号流向说明
控制流:
按键触发 → Test Sequencer → SPI Controller → SPI Master → AS6501芯片 ← 状态反馈 ← 数据返回 ← SPI应答 ← 主要信号接口:
| 接口 | 信号 | 方向 | 说明 |
|---|---|---|---|
| Test ↔ Controller | req, rw, addr, wdata | → | 请求控制信号 |
| rdata, ready, valid | ← | 响应数据和状态 | |
| Controller ↔ Master | start, rw, addr, din | → | SPI事务启动 |
| dout, busy, done | ← | SPI事务状态 | |
| Master ↔ AS6501 | SCLK, MOSI, CS | → | SPI主控信号 |
| MISO | ← | SPI从机数据 | |
| AS6501 → FPGA | INT_N | ← | 中断信号 (低电平=测量完成) |
| Test → RAM | wr_en, wr_addr, wr_data | → | 测量结果写入 |
| RAM ↔ UART Sender | rd_addr / rd_data | ↔ | 批量读取传输 |
| UART Sender → TX | tx_data, tx_data_valid | → | UART字节发送 |
| FPGA → PC | UART TX (G16) | → | 数据包传输 |
模块说明
1. spi_master.v
SPI主控模块,实现AS6501专用SPI协议(CPOL=0, CPHA=1)。
- 输入50MHz时钟,生成12.5MHz SPI时钟
- 支持4种命令类型:CMD_ONLY, CMD_WRITE, CMD_READ_RESULT, CMD_READ_CONFIG
- 可变长度传输:1字节命令或2字节数据传输
- 自动处理命令和数据字节的发送/接收
- 提供忙碌和完成信号
2. spi_controller.v
SPI控制器模块,提供简化的用户接口。
- 封装SPI主控模块
- 提供请求/应答接口
- 支持AS6501的4种命令类型
- 自动处理命令时序
3. test_sequencer.v
测试序列器模块,执行自动测试序列(16个状态)。
- 发送Power ON命令 (0x30)
- 批量写配置寄存器0-16(共17个寄存器)
- 写入指定的配置值:0x11, 0x81, 0x1F, 0x40, 0x0D, 0x03, 0xC0, 0x53, 0xA1, 0x13, 0x00, 0x0A, 0xCC, 0xCC, 0xF1, 0xFD, 0x04
- 批量读配置寄存器0-16进行验证
- 自动比对读回数据与写入数据
- 发送Init命令 (0x18) 启动AS6501测量
- 等待AS6501中断信号(低电平有效)触发
- 读取结果寄存器8-13(index_result和stop_result)
- 将结果寄存器组合为24位值:index_result[23:0]、stop_result[23:0]
- 测量计数 (meas_count):每次测量完成后递增,用作RAM写地址
- 批量测量循环:DONE状态检查计数,未达MAX_MEASUREMENTS则继续,达到后进入STOPPED
- 电平触发中断:DONE状态检查int_n电平,低电平直接进READ_RESULT,高电平回WAIT_INT
- STOPPED状态 (4’d15):所有测量完成,等待BTN[1]触发UART批量传输
- 参数
MAX_MEASUREMENTS(默认10000) 可通过顶层模块配置 - 提供测试状态、验证结果和meas_count/meas_stopped输出
4. result_ram.v
双端口Block RAM模块,存储测量结果。
- 参数化深度(默认10000条)
- 数据宽度:48位
{index_result[23:0], stop_result[23:0]} - 写端口:test_sequencer在result_valid脉冲时写入,meas_count作为地址
- 读端口:uart_result_sender按顺序读取,1周期读取延迟
- 使用
(* ram_style = "block" *)属性确保Vivado推断为Block RAM - BRAM使用量:约15-20个(XC7A35T共50个Block RAM)
5. uart_result_sender.v
UART批量传输模块,从RAM读取数据发送到上位机。
- 触发方式:send_start脉冲(BTN[1]按下且meas_stopped有效)
- 传输流程:顺序读取RAM → 每条数据组成8字节数据包 → UART TX发送
- 数据包格式(每条测量8字节):
[0xAA]帧头[index_b3][index_b2][index_b1]index_result高→低字节[stop_b3][stop_b2][stop_b1]stop_result高→低字节[0x55]帧尾
- 状态机:S_IDLE → S_LOAD → S_LATCH → S_WAIT_READY → S_SEND → S_WAIT_DONE
- RAM读取延迟处理:S_LOAD发出地址,S_LATCH锁存数据(2周期)
- 输出busy和send_done状态信号
6. uart_tx.v / uart_rx.v
ALINX UART收发模块。
- 波特率:115200 baud
- 格式:8N1(8数据位,无校验,1停止位)
- uart_tx:data[7:0] + valid → ready握手 → TX引脚
- uart_rx:RX引脚 → data[7:0] + valid + ready握手
- 参数:CLK_FRE(MHz), BAUD_RATE
7. top_module.v
顶层模块,集成所有子模块。
- 参数
MAX_MEASUREMENTS(默认10000) - 连接FPGA引脚(SPI, UART, LED, BTN, INT_N)
- 实例化所有子模块(spi_master, spi_controller, test_sequencer, result_ram, uart_result_sender, uart_tx, uart_rx)
- 3级中断同步器(亚稳态保护)
- BTN[1]下降沿检测:btn1_pressed信号,触发UART批量传输
- RAM写入逻辑:ram_wr_en=result_valid, ram_wr_addr=meas_count, ram_wr_data={index_result, stop_result}
- UART发送触发:uart_send_start = btn1_pressed & meas_stopped
- 复位同步器
- 提供LED状态指示
- 处理按键输入
8. clk_divider.v
时钟分频器模块,生成50kHz时钟。
- 输入50MHz,输出50kHz(1000分频)
- 50%占空比输出
- 用于TDC_STOPA信号生成
9. as6501_model.v (仿真)
AS6501 TDC芯片的行为模型,用于仿真。
- 实现完整的AS6501 SPI协议
- 包含配置寄存器和结果寄存器(各64字节)
- 支持Power ON和Init命令
- 支持配置寄存器读写
- 支持结果寄存器读取
- 两种中断模式:
- 正常模式 (INT_ALWAYS_LOW=0):Init后50μs拉低中断,结果读完释放
- 始终低电平模式 (INT_ALWAYS_LOW=1):中断拉低后不释放,每次结果读完自动更新数据
- 结果数据自动递增(每次测量后结果值+1)
- 初始值:index=24’hA1B2C3, stop=24’hD4E5F6
- 第N次:index={A1+N, B2+N, C3+N}, stop={D4+N, E5+N, F6+N}
- 预初始化测试数据
状态机设计
本项目包含三个主要状态机,协同工作完成SPI通信和测试序列。
1. Test Sequencer 状态机 (test_sequencer.v)
测试序列控制状态机,负责执行完整的AS6501测试流程。
状态定义:
IDLE (0) - 空闲状态,等待按键触发 POWER_CMD (1) - 发送Power ON命令 (0x30) WAIT_POWER (2) - 等待Power ON命令完成 WRITE_CFG (3) - 写配置寄存器 (地址0-16,共17个) WAIT_WRITE (4) - 等待写操作完成 READ_CFG (5) - 读配置寄存器 (地址0-16,共17个) WAIT_READ_CFG (6) - 等待读操作完成 VERIFY (7) - 验证读回数据与写入数据是否一致 INIT_CMD (8) - 发送Init命令 (0x18) 启动测量 WAIT_INIT (9) - 等待Init命令完成 WAIT_INT (10) - 等待AS6501中断 (低电平=测量完成) READ_RESULT (11) - 读结果寄存器8-13 WAIT_READ_RESULT (12) - 等待结果寄存器读取完成 COMBINE_RESULT (13) - 组合字节为24位结果,触发RAM写入 DONE (14) - 测量计数检查,未込MAX则继续,否则进STOPPED STOPPED (15) - 所有测量完成,等待BTN[1]UART传输 状态转换: