PS端配置与写盘功能阶段性进展2608

本阶段主要围绕 PS 端的软件控制和本地写盘功能开展工作。目前已经完成了基本采集参数配置、AXI DMA 接收、DDR 缓冲区管理以及 NVMe SSD 写盘测试。

当前总体判断是:FPGA/PL 到 DDR 的 DMA 接收链路已经基本跑通,PS 端能够获得 DMA 实际接收长度,也可以识别完整数据包和短包。当前主要风险集中在 NVMe SSD 长时间连续写入速度下降,后续需要继续通过新版写盘软件和存储测试来确认是否满足 1MSPS / 2MSPS 连续留盘需求。

1. 配置功能

1.1 当前实现方式

当前 PS 端配置功能主要通过 devmem 直接读写 PL 侧 AXI-Lite 寄存器实现。

这样做的原因是:

  • 调试阶段参数变化频繁,devmem 方式更直接。

  • 可以快速验证寄存器地址、配置值和 PL 响应是否正确。

  • 便于将配置、启动、停止、状态读取拆开测试。

  • 后期只需要将这些 devmem 操作封装成应用程序接口,不需要改变 PL 端寄存器设计。

也就是说,当前使用 devmem 是为了方便调试,并不代表最终交付时仍然要求人工输入命令。最终软件可以把这些配置流程封装成函数、命令行工具。

1.2 当前配置流程

目前一次采集任务的典型配置流程如下:

1. 停止或复位当前采集
2. 写入采样率、采样总点数、采样点数等参数
3. 写入各子卡通道掩码
4. 触发配置更新
5. 启动 DMA 接收程序
6. 启动 PL 采集
7. 采集结束后停止 PL

1.3 配置与状态寄存器表

以下列出 PS 端正式采集流程需要使用的主要寄存器,包括配置、控制、状态和配置快照寄存器;不包含调试过程中新增的 debug 计数寄存器。

基础信息、控制和状态寄存器如下:

偏移地址

绝对地址

名称

方向

说明

0x0000

0xA0010000

ID / MAGIC

设计标识,用于确认 PL 寄存器区域是否存在。当前读数为 0x44444151

0x0004

0xA0010004

VERSION

PL 寄存器版本号,用于确认当前加载的 PL 版本。

0x0008

0xA0010008

CONTROL

控制寄存器,用于复位、配置更新、启动采集和停止采集。

0x000C

0xA001000C

IRQ_ENABLE

读/写

中断使能寄存器,当前阶段主要用于后续驱动封装和中断扩展。

0x0040

0xA0010040

STATUS

PL 工作状态寄存器,可用于判断当前处于空闲、准备、工作或错误状态。

0x0044

0xA0010044

EVENT_STATUS

事件状态寄存器,用于确认配置更新、启动、停止等事件是否发生。

采集配置寄存器如下:

偏移地址

绝对地址

名称

方向

说明

0x0010

0xA0010010

SAMPLE_RATE

采样率配置值。当前测试中 1MSPS 常用配置值为 79

0x0014

0xA0010014

TOTAL_SAMPLE_NUM

固定点数采集时表示本次采集总点数;连续采集时通常设置为较大值。

0x0018

0xA0010018

SAMPLE_POINT_NUM

单次采样相关配置,目前测试中常用值为 20

0x001C

0xA001001C

SAMPLE_MISC

模式控制寄存器,用于配置连续采集、固定点数采集等模式字段。

0x0020

0xA0010020

MODULE0_MASK

子卡 0 通道掩码。

0x0024

0xA0010024

MODULE1_MASK

子卡 1 通道掩码。

0x0028

0xA0010028

MODULE2_MASK

子卡 2 通道掩码。

0x002C

0xA001002C

MODULE3_MASK

子卡 3 通道掩码。

0x0030

0xA0010030

MODULE4_MASK

子卡 4 通道掩码。

状态寄存器如下:

偏移地址

绝对地址

名称

方向

说明

0x0048

0xA0010048

ACTIVE_MISC

当前已经生效的模式配置。

0x0050

0xA0010050

ACTIVE_SAMPLE_RATE

当前已经生效的采样率配置。

0x0054

0xA0010054

ACTIVE_TOTAL_NUM

当前已经生效的采样总点数。

0x0058

0xA0010058

ACTIVE_POINT_NUM

当前已经生效的采样点数配置。

0x0060 - 0x0070

0xA0010060 - 0xA0010070

ACTIVE_MODULE0-4

当前已经生效的各子卡通道掩码。

0x0088

0xA0010088

RAW_MISC

PL 接收到的原始模式配置。

0x0090

0xA0010090

RAW_SAMPLE_RATE

PL 接收到的原始采样率配置。

0x0094

0xA0010094

RAW_TOTAL_NUM

PL 接收到的原始采样总点数。

0x0098

0xA0010098

RAW_POINT_NUM

PL 接收到的原始采样点数配置。

0x00A0 - 0x00B0

0xA00100A0 - 0xA00100B0

RAW_MODULE0-4

PL 接收到的各子卡原始通道掩码。

其中,ACTIVE_* 表示已经被 PL 接收并正式生效的配置,RAW_* 表示 PL 接收到的原始配置。后续封装软件接口时,可以通过对比 currentactiveraw 配置,判断参数是否已经下发成功、是否已经生效。

当前常见控制值如下:

写入地址

写入值

含义

0xA0010008

0x0

清除控制状态 / 空闲控制值。

0xA0010008

0x2

触发配置更新,使 PL 接收新的采集参数。

0xA0010008

0x4

启动采集。

0xA0010008

0x8

停止采集。

后续封装时,可以将上述寄存器读写整理成统一的软件接口。接口大致分为三类:配置接口、控制接口和状态读取接口。

配置接口:
set_sample_rate()
set_total_samples()
set_sample_points()
set_capture_mode()
set_module_mask()
apply_config()

控制接口:
reset_capture()
start_capture()
stop_capture()

状态读取接口:
get_hw_info()
get_status()
get_event_status()
get_active_config()
get_raw_config()
clear_events()

2. 写盘功能

2.1 当前进展

写盘功能目前已经可以支持高采样率下的短时间连续接收和写盘测试。当前测试结果表明,FPGA/PL 到 DDR 的 DMA 接收链路已经基本跑通;PS 端软件可以管理 DMA 缓冲区,并将已接收的数据提交给 Linux 写入 NVMe SSD。

当前数据流向如下:

FPGA/PL
 -> AXI DMA
 -> DDR 缓冲区
 -> PS 端 DMA 驱动
 -> 用户态写盘程序提交写文件请求
 -> Linux 文件系统 / 块层 / NVMe 驱动
 -> NVMe SSD

其中:

  • AXI DMA 负责把 PL 输出的数据搬运到 DDR 缓冲区。

  • PS 端 DMA 驱动负责管理 DDR 缓冲区,判断哪些缓冲区已经接收完成,并获取每块缓冲区的实际接收字节数。

  • 用户态写盘程序主要负责调度写盘流程:获取已完成的缓冲区、确定写入文件的位置、向 Linux 提交写文件请求,并在写盘完成后释放缓冲区。

  • Linux 文件系统、块层和 NVMe 驱动负责把写文件请求转换为 SSD 写入请求。

  • NVMe 控制器最终通过 PCIe DMA 从内存读取数据并写入 SSD。

2.2 当前驱动工作流程

当前驱动采用 Xilinx AXI DMA 的 Scatter/Gather 模式。可以简单理解为:

1. PS 端驱动提前准备多块 DDR 缓冲区,并把这些缓冲区地址交给 AXI DMA。
2. AXI DMA 按顺序把 PL 输出的数据写入 DDR 缓冲区。
3. 某块缓冲区写入完成后,AXI DMA 更新该缓冲区对应的完成状态。
4. PS 端驱动读取完成状态,并获得该缓冲区实际接收的字节数。
5. 用户态写盘程序获取已完成的缓冲区,并向 Linux 提交写文件请求。
6. Linux 文件系统、块层和 NVMe 驱动负责将写文件请求提交给 NVMe SSD。
7. 写盘请求完成后,用户态程序通知驱动释放该缓冲区。
8. 驱动再把该缓冲区交还给 AXI DMA,用于后续采集数据接收。

2.3 已完成测试情况

目前写盘功能采用分层测试方式进行验证。这样可以把整条链路拆开,分别判断问题出现在 DMA 接收、DDR 读取,还是 NVMe SSD 写盘阶段。

1. DMA接收测试

测试方式:只启动 DMA 接收,不进行 SSD 写盘。

测试目的:验证 FPGA/PL 输出的数据能否稳定通过 AXI DMA 写入 DDR 缓冲区。

测试结论:

  • AXI DMA 接收链路可以正常工作。

  • DDR 缓冲区可以循环使用。

  • 驱动可以获取每块缓冲区的实际接收字节数。

  • 长时间运行时未观察到明显的 DMA 错误或驱动层溢出。 因此,目前可以认为 FPGA/PL -> AXI DMA -> DDR 这一段接收链路已经基本可用。

2. DDR读取测试

测试方式:DMA 将数据写入 DDR 后,PS 端软件读取 DDR 缓冲区进行调度,但不写入 SSD。

测试目的:验证 PS 端读取 DDR 缓冲区的速度是否会成为主要瓶颈。

测试结论:

  • PS 端可以持续读取 DDR 缓冲区中的数据。

  • 只读取 DDR、不写 SSD 时,系统处理速度可以满足当前测试需求。 因此,CPU 读取 DDR 缓冲区本身不是当前主要瓶颈。

3. NVMe SSD 写盘测试

测试方式:DMA 接收数据后,由 PS 端软件将数据提交给 Linux,并写入本地 NVMe SSD。

测试目的:验证本地 NVMe SSD 是否能够长期承受连续采集数据写入。

测试结论:

  • 短时间写盘时,系统写入速度可以满足需求。

  • 连续写入几十 GiB 后,SSD 写入速度明显下降。

  • 掉速后写盘速度低于采集数据产生速度。

  • 写盘跟不上会导致 DMA 缓冲区不能及时释放,进而对前端采集链路造成压力。

2.4 当前可能的问题

从目前测试结果看,长时间连续写盘后速度下降,可能主要与 NVMe SSD 的内部写入机制有关。很多消费级或普通 NVMe SSD 在短时间写入时会利用内部缓存机制获得较高速度,例如 SLC Cache、DRAM Cache 或控制器缓存;但当连续写入数据量较大、缓存被写满后,SSD 需要将缓存中的数据整理并写入实际存储介质,此时持续写入速度会明显下降。如果掉速后的写入速度低于采集数据产生速度,DDR 缓冲区就无法及时释放,进而对 AXI DMA 接收和前端 PL 数据输出造成压力。因此,当前问题不一定是 DMA 接收链路异常,而更可能是 SSD 在长时间连续写入场景下的持续写入能力不足。后续需要通过新版写盘软件和更长时间的 SSD 写入测试,进一步区分软件调度开销和 SSD 本身持续写入能力的影响。

2.5 新版写盘软件方向

新版 r9 写盘软件主要改进点:

  • 支持异步写盘,提高 NVMe 写请求调度效率。

  • 支持按固定大小分段写文件,例如每 30GiB 保存为一个文件。

  • 支持识别 DMA 实际接收长度。

  • 对最后一个不完整数据块按真实长度写入。

  • 不自动补齐写入,避免文件中混入非真实采集数据。

这版软件的目的,是进一步区分:

是软件写盘调度不够快,
还是 SSD 本身长时间写入能力不足。

2.6 不使用 DPDK 的原因

目前暂不采用 DPDK,主要原因如下:

  1. DPDK 主要面向高速网络包处理,并不是 Linux 文件系统写 NVMe SSD 的常规方案。

  2. 当前数据最终需要保存为文件。只要要写入 Linux 文件系统,就仍然需要经过 Linux 文件系统、块层和 NVMe 驱动。

  3. 当前瓶颈更可能是 SSD 长时间持续写入能力,而不是网络包处理或普通内存拷贝。

  4. 当前更直接、风险更低的优化路线是:

mmap DDR 缓冲区
 -> O_DIRECT
 -> io_uring 异步写
 -> NVMe SSD

如果后续确认 Linux 文件系统路径本身成为主要瓶颈,再进一步评估 SPDK 或更底层的 NVMe 用户态方案会更合适。

3. 阶段性结论

目前 PS 端配置和写盘基础功能已经基本打通。采集参数配置、配置更新、启动和停止暂时通过 devmem 实现,适合当前调试阶段,后续可封装为正式软件接口。写盘链路方面,FPGA/PL 到 DDR 的 AXI DMA 接收已经跑通,驱动可以管理 DMA 缓冲区并获取实际接收字节数。现阶段主要风险集中在 NVMe SSD 的长时间持续写入能力:测试中已经观察到连续写入较大数据量后 SSD 掉速,若掉速后的速度低于 1MSPS / 2MSPS 所需数据率,就会影响连续留盘。下一阶段将重点测试新版 r9 写盘软件,验证异步写盘、分段写文件等优化手段是否能改善持续写盘表现,并进一步判断当前 SSD 是否满足最终连续采集留盘需求。


本文章使用limfx的vscode插件快速发布