使用 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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序仿网易严选(附精选源码32套,涵盖商城团购等)

商城主要实现的功能 首页、专题、分类、购物车、我的小程序授权登陆获取用户信息首页包含品牌制造页、品牌制造详情页面、新品首发页面、人气推荐页面、各分类列表商品详情页面,包含常见问题、大家都在看商品列表、加入购物车、收藏商品、立即购买、下订单、选择收…

在表格中显示字典的内容(根据后端返回的数据)vue3

进入页面,调接口,后端返回数据,indexType为0或者1,要用这个数据显示字典的内容 用插槽拿到数据 写一个函数,在模板中使用 const { proxy } getCurrentInstance(); // 字典-指标类型 const { index_type } proxy.u…

6.保留两位小数【2023.11.28】

1.问题描述 题中将给出一个具有许多小数位的浮点数,请将这个数字保存至小数点后两位,并输出。 2.解决思路 输入一个浮点数。 程序将浮点数保留两位小数并输出。 例如: formatted_float "{:.2f}".format(input_float)3.代码实…

echarts图表滚动条带动页面窗口滚动条的问题

网上搜了很多方法不管用,后来发现每次滚动echarts或者左右滑动echarts下方都会报错,报错提示如下,看看你们的图表是否这样报错: 报错信息如下:Unable to preventDefault inside passive event listener invocation 原…

三大录屏软件推荐,让你轻松录制屏幕

录屏软件的应用变得越来越广泛,无论是记录屏幕上的内容以方便日后查阅,还是与他人分享操作过程,录屏软件都发挥着重要作用。然而,市面上的录屏软件种类繁多,质量参差不齐。那有没有好用的录屏软件推荐呢?在…

金字塔原理

金字塔原理 来自于麦肯锡公司的第一位女性咨询顾问芭芭拉•明托的著作《金字塔原理》。 原理介绍 此原理是一种重点突出、逻辑清晰、主次分明的逻辑思路、表达方式和规范动作。 金字塔的基本结构是:中心思想明确,结论先行,以上统下&#xff…

小功能实现(十九)生成shp文件

引入依赖 <!--shp文件相关工具--><dependency><groupId>org.geotools</groupId><artifactId>gt-shapefile</artifactId><version>${geotools.version}</version></dependency><dependency><groupId>org.geo…

矩阵连乘问题

1、求解矩阵连乘问题。 要求: 分别用自底向上的动态规划方法和自顶向下的备忘录方法计算最优值并构造最优解&#xff0c;通过实例比较两种方法的结果和效率。 思路 1)寻找最优子结构&#xff1a; 此问题最难就在于此&#xff0c;对于乘积的任意位置加括号都会将序列在某个…

Java 基础学习(三)循环流程控制与数组

1 循环流程控制 1.1 循环流程控制概述 1.1.1 什么是循环流程控制 当一个业务过程需要多次重复执行一个程序单元时&#xff0c;可以使用循环流程控制实现。 Java中包含3种循环结构&#xff1a; 1.2 for循环 1.2.1 for循环基础语法 for循环是最常用的循环流程控制&#xff…

智慧公厕为高速服务区公厕做出的贡献

在现代社会&#xff0c;科技的飞速发展改变了人们的生活方式&#xff0c;也深刻影响着城市的基础设施和公共服务。而在这个数字化时代的背景下&#xff0c;智慧公厕作为城市智能化管理的一部分&#xff0c;为高速服务区公厕带来了一系列的创新和贡献&#xff0c;为旅客的出行提…

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); }类的构造…

\n\r:解析java中的\r、\n、\r\n、\n\r的区别

1 \r 1.1 内容 回车符,将光标定义到当前行行首 1.2 在idea中测试 1.2.1 表现形式 在\r后有新内容时,会先删除之前以前存在过的文本,即只打印\r后面的内容 1.2.2 示例代码 package Work; public class Test05 { public static void main(String[] args) { System.…

docker-compose Install OrangeHRM

OrangeHRM 前言 OrangeHRM 是一个全面的人力资源管理(HRM) 系统,它包含任何企业所需的所有基本功能。OrangeHRM旨在支持任何规模的团队,包括初创企业、中小企业以及大型跨国组织。 OrangeHRM 提前条件 OrangeHRMdocker & docker-composer 安装or

会议预告 | 求臻医学受邀参加2023·Inno China 产业创新大会

INNO CHINA 中国产业创新大会聚焦于数据驱动产业变革升级、医疗科技与产业转型升级、企业数字化转型升级、产业服务生态构建及商业智能融合发展等领域。如今&#xff0c;已成为中国新兴科技、热门赛道行业论坛、创新成果展示、参与、共创的高维度学术与产业年度相聚的节日&…

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

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

搭建一个可以发送邮箱验证码的接口,内含前端处理 接口返回、请求处理

环境搭建 在node安装好的情况下&#xff08;一般vue环境有的node也有 没有可以使用winr回车输入node -v 有版本号则已经安装好 找一个空文件夹作为此项目文件夹 点击上面的地址栏输入cmd回车 输入npm init -y 再输入npm install nodemailer安装发送邮件的插件 环境配置 使用v…

C++学习之路(十一)C++ 用Qt5实现一个工具箱(增加一个进制转换器功能)- 示例代码拆分讲解

上篇文章&#xff0c;我们用 Qt5 实现了在小工具箱中添加了《时间戳转换功能》功能。为了继续丰富我们的工具箱&#xff0c;今天我们就再增加一个平时经常用到的功能吧&#xff0c;就是「 进制转换 」功能。下面我们就来看看如何来规划开发一个这样的小功能并且添加到我们的工具…

苹果提醒事项怎么用?几个简单步骤就能学会!

苹果提醒事项可以帮助你轻松管理待办事项&#xff0c;让你更好地安排自己的时间和工作。但是&#xff0c;有些小伙伴可能对如何使用这个功能还有一些疑问。苹果提醒事项怎么用&#xff1f;不要担心&#xff0c;小编将为大家提供使用提醒事项的方法&#xff0c;帮助你学会如何使…

轻量级web开发框架:Flask本地部署及实现公网访问界面

轻量级web开发框架&#xff1a;Flask本地部署及实现公网访问界面 文章目录 轻量级web开发框架&#xff1a;Flask本地部署及实现公网访问界面前言1. 安装部署Flask2. 安装Cpolar内网穿透3. 配置Flask的web界面公网访问地址4. 公网远程访问Flask的web界面 前言 本篇文章讲解如何…

应用在智能手环距离检测领域的数字红外接近检测模块

智能手环是现代人日常生活中的一种智能配件&#xff0c;可以帮助我们记录运动数据、监测身体健康状况等。然而&#xff0c;对于许多用户来说&#xff0c;关注的问题之一就是智能手环的有效距离和精准度。智能手环通过内置传感器收集数据并将其发送到手机或其他设备上进行处理。…