使用 DMA 在 FPGA 中的 HDL 和嵌入式 C 之间传输数据

使用 DMA 在 FPGA 中的 HDL 和嵌入式 C 之间传输数据

该项目介绍了如何在 PL 中的 HDL 与 FPGA 中的处理器上运行的嵌入式 C 之间传输数据的基本结构。

fa7cd425bda05eebcab41baa47fb8187.png

介绍

鉴于机器学习和人工智能等应用的 FPGA 设计中硬件加速的兴起,现在是剥开几层“云雾”并讨论 HDL 之间来回传递数据(主要指FPGA 的可编程逻辑 (PL) 中运行的代码以及 FPGA 中的硬核或软核处理器上运行的相应软件之间传输数据)的基础知识的好时机。

硬件加速可以总结为在硬件(也称为 FPGA 的可编程逻辑)中实现某些功能的基本思想,这些功能之前在位于主机 PC 上或在 FPGA 上处理器(软核或者硬核)运行的软件。因此,要成为一名高效的设计人员,就必须掌握如何在硬件和软件之间来回传递数据的技巧。

在本例中,使用的是 Zynq SoC(片上系统)FPGA,它具有硬核 ARM 处理器。该 ARM 核心和外设称为处理系统或 PS。

虽然有几种不同的方法可以完成 PL 和 PS 之间的数据传输,包括编写自己的自定义接口,但我认为最常见的机制是通过直接内存访问 (DMA) 传输。这是因为 DMA 允许 ARM 内核的 CPU 简单地启动自身与 DDR 之间的数据传输,而 CPU 无需等待传输完成后再执行任何其他任务。DMA 还允许 CPU 启动外部设备和 DDR 之间的传输。

在此项目中,将通过使用 Xilinx DMA IP 演示 DMA 的功能,该IP可通过 AXIS 总线将内存映射接口转换为stream接口。将 32 字节写入嵌入式 C 中的内存,然后通过内存映射将其传输到 PL 到流 (MM2S) AXIS,通过寄存器处理每个值,然后通过流将数据传输回内存DMA IP 的内存映射 (S2MM) 端口。

虽然这个示例对于重型硬件加速应用来说过于简单,但当刚接触 FPGA 时,这种高速数据传输水平可能会变得非常复杂/难以学习。该项目重点介绍 DMA 的使用及其行为。虽然打算让这个项目更多地关注数据处理方面,但在 DMA 事务实现中发现了很多小“陷阱”,因此不得不将数据处理重点留给另一个项目。

094a74cee8ee6e3f179e95f918d9a6ab.png

使用 AXI DMA 控制 PL 中的 HDL 与 PS 中的 C 代码之间的数据传输有两个主要层:

  1. Memory Map to Stream (MM2S) 和 Stream to Memory Map (S2MM) 通道上 PL 的 HDL 代码中的 AXI 流握手信号(DMA 的控制通道是使用普通 AXI 写入的,但这就是全部由 Vivado 自动处理,因此在这里只关注 AXI stream接口)。

  1. PS 的 C 代码中寄存器读/写 DMA 的顺序。

Verilog 中的 AXI-Stream握手

AXI stream接口使用一组简单的握手信号机制,用于嵌入式设计中的数据交换。AXI stream接口中有许多可选信号,但与 DMA MM2S 和 S2MM 数据交换相关且必需的信号是 tdata、tvalid、tready、tlast 和 tkeep。AXI stream中发送数据为主接口,接收数据为从接口。

  • tdata:数据总线

  • tvalid:当放置在 tdata 总线上的数据有效时,由主接口置位

  • tredy:当从机处于准备接收 tdata 总线上的数据的状态时,由从机置位

  • tlast:由主设备在 tdata 总线上流中最后一个数据包的持续时间内断言,以告诉从设备该数据包之后不会有数据

  • tkeep:由主设备设置的 tdata 总线上数据包的二次验证,指示数据包是否是流的一部分

AXI DMA IP 究竟如何实现此握手接口将数据传输出内存 (MM2S) 并传输到内存 (S2MM),这一点非常变化无常,尤其是在 S2MM 方面……

然而,我们首先需要了解的是有关 AXI DMA 的 S2MM 事务的信息,大部分可以总结为一句话:必须设置 S2MM 事务,并且在尝试向 DMA 发送任何数据之前,以适当的顺序写入 DMA 中的适当控制寄存器来启动事务,一旦 S2MM 通道看到 tlast 信号,它就会停止事务。

数据传输发生在每个时钟周期的 S2MM 和 MM2S 事务中的 tdata 总线上,其中tready 和 tvalid 均被置位(true)。因此,当负责断言 tvalid 时,在 AXI 接口的主端必须小心,当从从机传入的 trety 信号也为 tvalid 断言时,不要让 tvalid 断言超过一个时钟周期。否则,从设备将在同一个数据包计时两次,作为两个单独的数据包。并且因为必须在控制寄存器中指定传输中有多少字节,所以 DMA 通道(在本例中为 S2MM)会在看到提供 tlast 信号之前认为交换已结束,因为计数已关闭。

184d8214198a018e4b1ae65cba9e471f.png

我用 Verilog 编写了一个简单的状态机,它实现了一个从 AXI stream接口来从 DMA 的 MM2S 通道接收数据,通过寄存器传递stream中的每个数据包,然后实现一个主 AXI strean接口来将数据流发回到S2MM通道。来自 tdata 总线的数据通过的寄存器旨在充当占位符,用于为硬件加速进行任何自定义数据处理。

从 Vivado 中的 ILA 中截取了一张屏幕截图,显示使用状态机实现的时序图。顶部是 MM2S 侧,底部是 S2MM 侧。

这是 Verilog 状态机的流程图,实际文件附在本文末尾。值得注意的是,流程图中的主/从接口是从 Verilog 状态机的角度来看的。

0b61c1b80bb2f3da3dee285bac1a48b4.png

对于 DMA IP 的具体设置,因为在直接寄存器模式下使用 DMA,所以未选中分散收集选项。然后,将其他所有设置保留为默认设置,并选中允许未对齐传输的选项,我发现在将自定义 AXI 流接口写入 DMA 时,这给了更多的自由空间。

ba0ba61b667b130e9ae8e4483afcab4b.png

为了将 Verilog 状态机添加到模块设计中,我右键单击模块设计的空白区域,然后选择“添加模块...”选项,该选项将显示 Vivado 可以在设计源中找到的所有有效 Verilog 模块在BD中使用的文件。

21faac3aadc99f17d4215c4b07087e1c.png

值得注意的是,信号命名约定分别遵循从接口和主接口的“s_axis”和“m_axis”标准。

d507ddb8ebb8ccc1a175a7d557e29aa4.png

DMA 寄存器读/写控制序列

以下是裸机使用 DMA 时更简单的顺序:

  • 1.通过将 1 写入 MM2S(偏移量 0x00)和 S2MM(偏移量 0x30)控制寄存器的位 2 来复位 DMA。

  • 2.将 S2MM 通道要写入数据的 DDR 中位置的目标地址写入 S2MM DMA 目标地址寄存器(偏移量 0x48)。

  • 3.通过将 1 写入 S2MM 控制寄存器(偏移量 0x30)的位 0 来启动 DMA S2MM 通道。

  • 4.通过将 S2MM 通道上要读入内存的总字节数值写入 S2MM 缓冲区长度寄存器(偏移量 0x58),写入 S2MM 通道缓冲区的长度。这将启动 S2MM 传输,以便 DMA 准备好从 FPGA 逻辑中的设备接收数据流(直到实际馈送数据并且 AXI 流总线上的 tvalid 由 FPGA 逻辑中的设备断言后,该过程才会真正启动)逻辑)。

  • 5.将 MM2S 通道要读取的数据的 DDR 中的源地址写入 MM2S DMA 源地址寄存器(偏移量 0x18)。

  • 6.通过将 1 写入 MM2S 控制寄存器的位 0(偏移量 0x00)来启动 DMA MM2S 通道。

  • 7.通过将要发送的总字节数值写入 MM2S 传输长度寄存器(偏移量 0x28),写入 MM2S 通道的传输长度。这将启动从 DMA 到 FPGA 逻辑中的接收设备的 MM2S 传输。

还记得之前提到过,在 PL 中的设备尝试向 S2MM 通道发送数据之前,必须启动并运行 S2MM 通道吗?嗯,这就是为什么要按顺序执行上述步骤。步骤 2 - 4 配置并启动 S2MM 通道,步骤 5 - 7 配置并启动 MM2S 通道。

在步骤 4 和 5 之间发生一些其他进程是可以的,但步骤 2 - 4 必须在步骤 5 - 7 之前发生。执行步骤 4 后,S2MM AXI 流通道将断言其 Tready 信号,此时 HDL 代码可以开始向其发送数据。

这也解释了当我第一次开始使用 DMA 时,在 SDK/Vitis 中的示例 DMA 项目中注意到的一些事情。总是认为示例代码似乎是在使用 MM2S - XAXIDMA_DMA_TO_DEVICE 传输从 DDR 中写入任何内容之前尝试将数据拉入 DDR(通过首先执行 S2MM - XAXIDMA_DEVICE_TO_DMA 传输)。然而,S2MM 通道必须准备好并等待接收数据才能正常工作并且不会锁定。

在 FPGA 设计中,DMA 似乎是一种棘手的入门方法,但一旦你弄清楚它就会非常有帮助。

代码

https://github.com/suisuisi/FPGATechnologyGroup/tree/main/AXIS-DMA

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/180966.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Peter算法小课堂—高精度减法

给大家看个小视频高精度减法_哔哩哔哩_bilibili 基本思想 计算机模拟人类做竖式计算,从而得到正确答案 大家还记得小学时学的“减法竖式”吗?是不是这样 x-y问题 函数总览: 1.converts() 字符串转为高精度大数 2.le() 判断大小 3.sub() …

【技术干货】宇视IPC音频问题解决步骤

近期技术人员从宇视官网下载sdk进行二次开发时,在启动实时直播,并通过回调函数拿到流数据,发现没有音频流数据。 通过下面的数据发现,codeType此字段一直是28,代表的是H.264数据,但未没发现有音频的数据包…

什么是Geo Trust OV证书

一、GeoTrust OV证书的介绍 GeoTrust OV证书是由GeoTrust公司提供的SSL证书,它是一种支持OpenSSL的数字证书,具有更高的安全性和可信度。GeoTrust是全球领先的网络安全解决方案提供商,为各类用户提供SSL证书和信任管理服务。GeoTrust OV证书…

如何使用ArcGIS实现生态廊道模拟

生态廊道是指一种连接不同生态系统的走廊或通道,其建立有助于解决人类活动对野生动植物栖息地破碎化和隔离化的问题,提高生物多样性,减轻生态系统的压力。在城市化和农业开发不断扩张的背景下,生态廊道对于野生动植物的生存和繁衍…

Hive安装与配置

你需要掌握: 1.Hive的基本安装; 2.Mysql的安装与设置; 3.Hive 的配置。 注意:Hive的安装与配置建立在Hadoop已安装配置好的情况下。 hadopp安装与配置 Hive 的基本安装 从 官网 下载Hive二进制包,下载好放在/op…

万人拼团团购小程序源码系统+拼团设置+拼团管理 附带完整的搭建教程

随着互联网的快速发展,电子商务和社交电商的兴起,团购作为一种高效的营销策略和消费方式,受到了广大消费者的热烈欢迎。在此背景下,我们开发了一款基于微信小程序的万人拼团团购系统,旨在为用户提供一种更加便捷、高效…

python爬虫进阶教程之如何正确的使用cookie

文章目录 前言一、获取cookie二、程序实现三、动态获取cookie四、其他关于Python爬虫技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Python工具包②Python实战案例③Python小游戏源码五、面试资料六、Pytho…

lxml 总结

xm 和 lxml库 哪个更好用点 1. 性能: lxml 通常比 xml.etree.ElementTree 更快。lxml 使用了 C 编写的底层解析器,因此在处理大型 XML 文档时可能更高效。 如果性能对你的应用很重要,特别是在处理大型 XML 文件时,选择 lxml 可能…

这款高性能分布式ID生成器,现在是你的了~

这是DDD&微服务系列的第17篇,欢迎持续关注~ 概述 在软件开发过程中,我们经常会遇到需要生成全局唯一流水号的场景,例如各种流水号和分库分表的分布式主键ID。特别是在使用MySQL数据库时,除了要求流水号具有“全局唯一”性外&…

继电保护-变压器纵联差动保护MATLAB仿真模型

微❤关注“电气仔推送”获得资料(专享优惠) 原理概述 差动保护是在两端设置的保护,通过比较两端测回来的电气量,进而看是否需要动作,纵联差动保护是变压器主保护。 纵联差动保护基本原则 双绕组变压器实现纵联差动…

泄密零容忍!迅软科技打造设计图纸安全防线,助您无忧创作!

对于建筑设计、鞋服设计、动漫设计、平面设计等设计行业而言,海量设计图纸都以电子数据的形式存在企业的终端电脑上,这些图纸蕴含着企业的核心竞争资源,一旦泄露将给企业带来巨大的经济损失。 因此,迅软科技采用了先进的数据加密技…

Ruoyi-cloud / 若依 SpringCloud服务器部署

1、redis 环境 服务器安装redis ,注意 密码 端口 2、mysql 环境 服务器安装 mysql 5.7 以上的版本 代码中的sql 文件夹中有 sql 文件 创建数据库ry-cloud并导入数据脚本ry_2021xxxx.sql(必须),quartz.sql(可选&…

同旺科技 USB 转 RS-485 适配器 -- 隔离型

内附链接 1、USB 转 RS-485 适配器 隔离版主要特性有: ● 支持USB 2.0/3.0接口,并兼容USB 1.1接口; ● 支持USB总线供电; ● 支持Windows系统驱动,包含WIN10 / WIN11 系统32 / 64位; ● 支持Windows …

使用vue-admin-template时,需要注意的问题,包括一定要去除mock.js注释

在使用vue-admin-template等前端框架时,如果你没有打算用他们的mock数据,在生产环境下一定要注释mock引用的代码,虽然它没有被调用,但是如果你不注释,就会被打包进去。 找到main.js,看如下代码&#xff1a…

八、Lua数组和迭代器

一、Lua数组 数组,就是相同数据类型的元素按一定顺序排列的集合,可以是一维数组和多维数组。 在 Lua 中,数组不是一种特定的数据类型,而是一种用来存储一组值的数据结构。 实际上,Lua 中并没有专门的数组类型&#xf…

根据端口查找进程

关闭kibana kibana自带命令 kibana没有提供关闭命令,通过命令 ps -ef|grep kibana查找不到kibana相关的信息。 可以通过进程暴露的端口来查找 netstat -anltp|grep 5601获取到进程号,然后kill掉进程 kill -9 进程号Docker管理Kibana 但是如果使用D…

OpenHarmony亮相MTSC 2023 | 质量效率共进,赋能应用生态发展

11月25日,MTSC 2023第十二届中国互联网测试开发大会在深圳登喜路国际大酒店圆满举行。大会以“软件质量保障体系和测试研发技术交流”为主要目的,旨在为行业搭建一个深入探讨和交流的桥梁和平台。OpenAtom OpenHarmony(简称“OpenHarmony”&a…

Linux概述

Linux概述 1、操作系统 ​ 定义:操作系统(Operating System,简称OS)是管理计算机硬件与软件资源的计算机程序 ​ 作用:是把计算机系统中对硬件设备的操作封装起来,供应用软件调用,也是提供一个让用户与系统交互的操…

C++基础 -10- 类的构造函数

类的构造函数类型一 使用this指针给类内参数赋值 class rlxy {public:int a;rlxy(int a, int b, int c){this->aa;this->bb;this->cc;cout << "rlxy" << endl;}protected:int b;private:int c; };int main() {rlxy ss(10, 20, 30); }类的构造…

winform 程序多语言

新建一个winform程序添加资源文件 在多语言的资源文件中设置key以及value设置button根据环境选择语言文件 namespace WindowsFormsMulLang {public partial class Form1 : Form{public Form1(){InitializeComponent();}public static ResourceManager rm new ResourceManager(…