news 2026/4/17 17:55:31

ZCU106开发板PYNQ实战:手把手教你配置DMA回环测速(附完整代码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ZCU106开发板PYNQ实战:手把手教你配置DMA回环测速(附完整代码)

ZCU106开发板PYNQ实战:从零构建DMA回环测速系统

第一次拿到ZCU106开发板时,看着这块集成了Zynq UltraScale+ MPSoC的硬件平台,既兴奋又忐忑。作为嵌入式开发者,我们常需要处理PS(处理器系统)与PL(可编程逻辑)之间的数据交互,而DMA(直接内存访问)正是实现高效数据传输的利器。本文将带你完整实现一个DMA回环测速系统,从Vivado配置到PYNQ实测,手把手解决每个环节可能遇到的问题。

1. 硬件环境准备与Vivado工程搭建

在开始之前,确保你已经完成以下准备工作:

  • 安装Vivado 2018.3或更高版本(本文以2018.3为例)
  • ZCU106开发板及配套电源、线缆
  • 已生成PYNQ镜像并成功启动(参考前序教程)

创建Vivado工程的关键步骤

  1. 新建RTL工程,选择ZCU106开发板型号
  2. 添加ZYNQ UltraScale+ MPSoC IP核到Block Design
  3. 配置ZYNQ核时,务必在PS-PL Configuration中启用一个HP(High Performance)端口

注意:DMA传输需要通过HP端口访问DDR内存,这是后续数据传输的物理通道

2. DMA IP核配置与硬件设计

DMA IP核是构建PS与PL数据通道的核心组件。在Vivado的Block Design中添加AXI DMA IP后,需要进行以下关键设置:

配置项推荐值说明
Enable Scatter Gather关闭简单回环测试无需SG模式
Width of Buffer Length Register23决定最大传输长度
Memory Map Data Width64匹配HP端口位宽
Stream Data Width32常见数据位宽

连接示意图

S_AXIS_S2MM → M_AXIS_MM2S (输入) (输出)

这种回环连接方式可以直接测试DMA本身的传输性能,无需额外逻辑。

完成连接后,记得:

  • 验证地址映射是否正确
  • 生成HDL Wrapper
  • 执行综合与实现

3. 生成PYNQ可用的Overlay文件

硬件设计完成后,需要准备三个关键文件供PYNQ使用:

  1. .bit文件:包含FPGA配置比特流

    • 路径:<工程目录>/<项目名>.runs/impl_1/*.bit
  2. .hwh文件:硬件描述文件

    • 路径:<工程目录>/<项目名>.srcs/sources_1/bd/<bd_name>/hw_handoff/*.hwh
  3. .tcl文件:Block Design重建脚本

    • 通过菜单"File → Export → Export Block Design"生成

将这三个文件复制到PYNQ板的/home/xilinx目录下备用。这里有个常见坑点:文件权限问题。建议使用chmod 644命令确保Jupyter有访问权限。

4. Jupyter Notebook中的DMA测速实现

打开PYNQ的Jupyter环境,新建Notebook,我们分步骤实现测速功能:

4.1 初始化Overlay与DMA

from pynq import Xlnk, Overlay import numpy as np import time # 加载Overlay ol = Overlay('/home/xilinx/zcu106_dma/dma.bit') dma = ol.axi_dma_0 # 获取DMA实例

4.2 内存分配与数据准备

PYNQ通过Xlnk管理CMA(连续内存分配器)内存:

xlnk = Xlnk() # 分配25MB的输入输出缓冲区 input_buffer = xlnk.cma_array(shape=(6553600,), dtype=np.uint32) output_buffer = xlnk.cma_array(shape=(6553600,), dtype=np.uint32) # 填充测试数据(可选) for i in range(len(input_buffer)): input_buffer[i] = i % 256

4.3 DMA传输与性能测试

核心测速代码实现:

def measure_dma_speed(data_size): # 重置缓冲区 output_buffer[:] = 0 # 执行传输并计时 start = time.time() dma.sendchannel.transfer(input_buffer[:data_size]) dma.recvchannel.transfer(output_buffer[:data_size]) dma.sendchannel.wait() dma.recvchannel.wait() end = time.time() # 计算速度 time_cost = end - start speed = (data_size * 4) / (time_cost * 1024 * 1024) # MB/s return time_cost, speed

4.4 多规模测试与结果分析

建议测试不同数据量下的表现:

test_sizes = [64*1024, 1*1024*1024, 10*1024*1024, 25*1024*1024] # 64KB到25MB results = [] for size in test_sizes: time_cost, speed = measure_dma_speed(size//4) # 除以4因为uint32占4字节 results.append((size, time_cost, speed)) print(f"Size: {size/1024/1024:.1f}MB | Time: {time_cost:.3f}s | Speed: {speed:.2f}MB/s")

典型结果可能如下:

数据量耗时(秒)传输速率(MB/s)
64KB0.001252.08
1MB0.018554.05
10MB0.18254.95
25MB0.45554.95

5. 常见问题排查与优化建议

在实际操作中,你可能会遇到以下情况:

问题1:DMA传输速度远低于预期(如<100MB/s)

  • 检查HP端口是否已启用
  • 确认Vivado中DMA配置的位宽设置
  • 尝试增加传输数据量(小数据量测试开销占比高)

问题2:Jupyter报错"Unable to allocate memory"

  • 检查PYNQ镜像版本(建议v2.6+)
  • 尝试减小测试数据量
  • 重启kernel释放内存

问题3:传输数据校验失败

  • 使用np.array_equal(input_buffer, output_buffer)验证
  • 检查DMA是否配置为回环模式
  • 确认buffer数据类型一致

性能优化技巧

  • 增大DMA缓冲区长度寄存器位宽
  • 尝试使用多个HP端口并行传输
  • 考虑使用HLS优化数据流

6. 扩展应用:实际场景中的DMA使用

掌握了基础DMA操作后,可以尝试以下进阶应用:

  1. 图像处理加速:将摄像头数据通过DMA传输到PL进行实时处理
  2. 网络数据加速:实现TCP/IP协议栈与自定义硬件的快速数据交换
  3. 多DMA通道管理:同时控制多个数据传输流

一个实用的技巧是封装DMA操作为Python类:

class DMAController: def __init__(self, bitfile_path): self.ol = Overlay(bitfile_path) self.dma = self.ol.axi_dma_0 self.xlnk = Xlnk() def transfer(self, data): in_buf = self.xlnk.cma_array(shape=data.shape, dtype=data.dtype) out_buf = self.xlnk.cma_array(shape=data.shape, dtype=data.dtype) np.copyto(in_buf, data) start = time.time() self.dma.sendchannel.transfer(in_buf) self.dma.recvchannel.transfer(out_buf) self.dma.sendchannel.wait() self.dma.recvchannel.wait() return out_buf, time.time() - start

在实际项目中,我发现DMA性能与内存访问模式密切相关。连续的大块传输通常能获得最佳性能,而随机小数据包会导致吞吐量显著下降。建议根据应用特点设计合适的数据缓冲策略。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 17:53:11

Axure8从零到精通的实战指南(附资源与技巧)

1. Axure8入门&#xff1a;从安装到界面初探 第一次打开Axure8时&#xff0c;很多人会被它复杂的界面吓到。别担心&#xff0c;这就像刚拿到新手机需要熟悉按键位置一样正常。我们先从最基础的安装开始说起。 Axure8的安装过程其实非常简单&#xff0c;双击安装包后跟着向导一步…

作者头像 李华
网站建设 2026/4/17 17:51:10

告别漫长等待:巧用编译依赖为Source Insight打造极速Linux内核源码工程

1. 为什么你的Source Insight加载Linux内核这么慢&#xff1f; 每次打开Linux内核源码工程都要等上大半天&#xff1f;同步一次代码索引电脑就卡死&#xff1f;这可能是大多数使用Source Insight阅读大型开源项目的开发者都遇到过的噩梦。我当年第一次用Source Insight导入Linu…

作者头像 李华
网站建设 2026/4/17 17:51:00

Python m3u8下载器终极指南:轻松解密加密流媒体视频

Python m3u8下载器终极指南&#xff1a;轻松解密加密流媒体视频 【免费下载链接】m3u8_downloader 项目地址: https://gitcode.com/gh_mirrors/m3/m3u8_downloader 你是否曾经遇到过想要保存在线视频却束手无策的情况&#xff1f;m3u8加密视频下载器就是你的救星&#…

作者头像 李华