在工业视觉检测、雷达信号采集这类场景中,设备往往需要连续记录每秒数百MB甚至上GB的原始数据。传统方案通常让FPGA通过AXI总线将数据先传输到Zynq处理系统(PS)的内存,再由CPU搬运到存储设备。这种"FPGA→PS DDR→SSD"的路径存在两个致命瓶颈:一是AXI-HP接口带宽限制(实测约130MB/s),二是数据在PS端的内存拷贝会消耗大量CPU资源。
我曾在某半导体检测设备项目中遇到这个问题——当相机分辨率提升到8K时,原始方案连5秒的连续录制都无法完成。后来改用PL端直连NVMe SSD的设计,实测写入速度直接突破1GB/s。这种架构的核心思路是:让FPGA专注数据搬运(DMA引擎),PS端仅负责存储管理(文件系统),通过硬件加速的数据通道避开软件瓶颈。
Zynq芯片的独特优势在于PS(ARM处理器)和PL(FPGA)的深度协同。在我们的存储系统中:
实测表明,当PL直接管理PCIe DMA传输时,相比PS端搬运方案可降低约70%的CPU占用率。下图是典型的硬件连接示意:
code复制[传感器] → [PL GTX接口] → [DDR缓存] → [PCIe DMA引擎] → [NVMe SSD]
↑控制信号 ↑文件系统管理
[PS端Linux系统]
选择M.2接口的NVMe SSD时要注意三个关键参数:
在Vivado中配置XDMA IP核时,建议关闭MSI-X中断改用Legacy INTx,因为Zynq的中断控制器需要特殊映射。我曾遇到一个坑:某国产SSD的FLUSH命令响应超时导致数据丢失,最终通过修改PL端DMA引擎的超时检测机制解决。
标准的NVMe驱动需要做以下定制:
c复制// 示例:禁用PS端DMA映射
static unsigned int zynq_nvme_dma_mask = 0x0;
pci_set_dma_mask(dev, zynq_nvme_dma_mask);
// 启用PL端DMA独占模式
nvmeq->q_dmadev = pl_dma_device_register();
关键点包括:
io_uring替代传统块设备IO队列在/etc/fstab中应添加这些参数:
bash复制/dev/nvme0n1p1 /mnt/data ext4 noatime,nodelalloc,data=writeback,journal_async_commit 0 2
其中journal_async_commit能提升小文件写入性能约30%。对于持续写入场景,建议禁用ext4的delayed allocation(nodelalloc),否则可能引发写入突增。
使用Xilinx的AXI SmartConnect IP实现双端口DDR控制器:
verilog复制// 乒乓切换逻辑示例
always @(posedge pcie_clk) begin
if (wr_bank_switch) begin
wr_bank_sel <= ~wr_bank_sel;
wr_ptr <= 0;
end else if (wr_en) begin
wr_ptr <= wr_ptr + 1;
end
end
每个Bank建议配置为2MB大小,这样在1GB/s速率下切换间隔约2ms,给PS端足够的处理时间。
PL端需要实现三类状态监控:
一个实用的调试技巧是在Vivado ILA中添加AXI协议检查器,可以捕获到PCIe TLP包的异常情况。
在某工业相机项目中,我们测得以下数据(Zynq XC7Z045芯片):
| 测试项 | 传统方案 | PL直连方案 |
|---|---|---|
| 持续写入速度 | 130MB/s | 1.1GB/s |
| CPU占用率(4核平均) | 85% | 12% |
| 延迟波动(μs) | ±500 | ±20 |
常见问题及解决方法:
对于需要更高可靠性的场景,可以考虑:
我在最近一个雷达项目中发现,将EXT4的journal大小从默认的128MB减小到32MB,能显著降低碎片化导致的性能衰减。