Vitis HLS 学习笔记--AXI_STREAM_TO_MASTER
目录
1. 简介
2. 示例
2.1 示例功能介绍
2.2 示例代码
2.3 顶层函数解释
2.4 综合报告(HW Interfaces)
2.5 关于TKEEP和TSTRB
2.6 综合报告(SW I/O Information)
3. 总结
1. 简介
本文通过“<Examples>/Interface/Streaming/axi_stream_to_master/”示例,展示了如何利用 Vitis HLS 工具,将输入的 AXI Stream 格式的数据流转换为并行存储数据,并通过 AXI Master 接口写入到存储器中。
AXI Stream 接口:是一种轻量级的、无协议的、点对点的数据传输接口,常用于在 FPGA 内部或 FPGA 与外部设备之间传输大量数据。它包括一个数据通道和一个控制信号,通过这两个通道传输数据和标记数据包结束。
AXI Master 接口:是一种高级别的存储器接口,用于 FPGA 设备与外部存储器之间的数据传输。它包括数据通道、地址通道、控制信号等,可以支持高性能的数据读写操作。
2. 示例
2.1 示例功能介绍
本示例包含三个函数:
- getinstream 函数
从输入的 AXI Stream 数据流中读取数据,并将其转换为 data 结构后发送到输出流中。在达到最大计数或读取到最后一个数据包时,将计数值发送到输出计数流中。这个函数主要利用了 AXI Stream 接口进行数据的传输和标记数据包结束。
- streamtoparallelwithburst 函数
从输入的 AXI Stream 数据流和计数流中读取数据,并将数据写入到输出的 AXI Master 接口中。这个函数主要利用了 AXI Master 接口进行数据的存储,支持数据的突发传输。
- example 函数
顶层函数,将这两个操作结合起来,首先将输入流转换为数据流和计数流,然后将数据流传递给 streamtoparallelwithburst 函数进行数据存储操作。最终实现了从 AXI Stream 数据流到 AXI Master 存储器接口的数据处理流程。
2.2 示例代码
#include "ap_axi_sdata.h"
#include "ap_int.h"
#include "hls_stream.h"typedef ap_axiu<64, 0, 0, 0> trans_pkt;// Expects max bandwidth at 64 beats burst (for 64-bit data)
static constexpr int MAX_BURST_LENGTH = 64;
static constexpr int BUFFER_FACTOR = 64;// Buffer sizes
static constexpr int DATA_DEPTH = MAX_BURST_LENGTH * BUFFER_FACTOR;
static constexpr int COUNT_DEPTH = BUFFER_FACTOR;struct data {ap_int<64> data_filed;ap_int<1> last;
};/// Reads from in_stream and in_counts, Write to out_memory
void streamtoparallelwithburst(hls::stream<data>& in_stream,hls::stream<int>& in_counts,ap_uint<64>* out_memory) {data in_val;do {int count = in_counts.read();for (int i = 0; i < count; ++i) {
#pragma HLS PIPELINEin_val = in_stream.read();out_memory[i] = in_val.data_filed;}out_memory += count;} while (!in_val.last);
}void getinstream(hls::stream<trans_pkt>& in_stream,hls::stream<data>& out_stream, hls::stream<int>& out_counts) {int count = 0;trans_pkt in_val;do {
#pragma HLS PIPELINEin_val = in_stream.read();data out_val = {in_val.data, in_val.last};out_stream.write(out_val);count++;if (count >= MAX_BURST_LENGTH || in_val.last) {out_counts.write(count);count = 0;}} while (!in_val.last);
}void example(hls::stream<trans_pkt>& inStreamTop, ap_uint<64> outTop[1024]) {
#pragma HLS INTERFACE axis register_mode = both register port = inStreamTop
#pragma HLS INTERFACE m_axi max_write_burst_length = 256 latency = 10 depth = 1024 bundle = gmem0 port = outTop
#pragma HLS INTERFACE s_axilite port = outTop bundle = control
#pragma HLS INTERFACE s_axilite port = return bundle = control#pragma HLS DATAFLOWhls::stream<data, DATA_DEPTH> buf;hls::stream<int, COUNT_DEPTH> count;getinstream(inStreamTop, buf, count);streamtoparallelwithburst(buf, count, outTop);
}
2.3 顶层函数解释
顶层函数 example 共有两个参数:
- inStreamTop:这是一个输入参数,类型为 hls::stream<trans_pkt>&,表示一个 AXI Stream 接口的数据流。该参数用于传递输入的数据流,其中 trans_pkt 是一个结构体类型,表示一个 AXI Stream 格式的数据包,包含64位的数据字段和一个标记最后一个数据包的信号。
- outTop:这是一个输出参数,类型为 ap_uint<64> outTop[1024],表示一个 AXI Master 接口的存储器。该参数用于指定存储数据的地址,数据将被写入到这个地址指定的存储器中。这里使用了 ap_uint<64> 类型的数组,长度为1024,表示存储器的容量为1024个64位的数据。
编译器指令,只介绍其中第一个,其余的在之前的文章已有分析。
#pragma HLS INTERFACE axis register_mode = both register port = inStreamTop
- axis:这表示我们正在定义一个AXI Stream接口。
- register_mode = both:这指定了数据流的寄存器模式。在这里,both表示数据流的输入和输出都使用寄存器。
- register:表示数据端口将使用寄存器进行数据缓存。
- port = inStreamTop:表示将指定这个接口指令应用于名为 inStreamTop 的输入端口。这个端口将被识别为 AXI Stream 接口,从而在 HLS 综合过程中正确处理数据流。
2.4 综合报告(HW Interfaces)
================================================================
== HW Interfaces
================================================================
* M_AXI
+-------------+------------+---------------+---------+--------+----------+-----------+--------------+--------------+-------------+-------------+
| Interface | Data Width | Address Width | Latency | Offset | Register | Max Widen | Max Read | Max Write | Num Read | Num Write |
| | (SW->HW) | | | | | Bitwidth | Burst Length | Burst Length | Outstanding | Outstanding |
+-------------+------------+---------------+---------+--------+----------+-----------+--------------+--------------+-------------+-------------+
| m_axi_gmem0 | 64 -> 64 | 64 | 10 | slave | 0 | 0 | 16 | 256 | 16 | 16 |
+-------------+------------+---------------+---------+--------+----------+-----------+--------------+--------------+-------------+-------------+* S_AXILITE Interfaces
+---------------+------------+---------------+--------+----------+
| Interface | Data Width | Address Width | Offset | Register |
+---------------+------------+---------------+--------+----------+
| s_axi_control | 32 | 5 | 16 | 0 |
+---------------+------------+---------------+--------+----------+* S_AXILITE Registers
+---------------+----------+--------+-------+--------+----------------------------------+----------------------------------------------------------------------+
| Interface | Register | Offset | Width | Access | Description | Bit Fields |
+---------------+----------+--------+-------+--------+----------------------------------+----------------------------------------------------------------------+
| s_axi_control | CTRL | 0x00 | 32 | RW | Control signals | 0=AP_START 1=AP_DONE 2=AP_IDLE 3=AP_READY 7=AUTO_RESTART 9=INTERRUPT |
| s_axi_control | GIER | 0x04 | 32 | RW | Global Interrupt Enable Register | 0=Enable |
| s_axi_control | IP_IER | 0x08 | 32 | RW | IP Interrupt Enable Register | 0=CHAN0_INT_EN 1=CHAN1_INT_EN |
| s_axi_control | IP_ISR | 0x0c | 32 | RW | IP Interrupt Status Register | 0=CHAN0_INT_ST 1=CHAN1_INT_ST |
| s_axi_control | outTop_1 | 0x10 | 32 | W | Data signal of outTop | |
| s_axi_control | outTop_2 | 0x14 | 32 | W | Data signal of outTop | |
+---------------+----------+--------+-------+--------+----------------------------------+----------------------------------------------------------------------+* AXIS
+-------------+---------------+-------+-------+-------+--------+-------+--------+
| Interface | Register Mode | TDATA | TKEEP | TLAST | TREADY | TSTRB | TVALID |
+-------------+---------------+-------+-------+-------+--------+-------+--------+
| inStreamTop | both | 64 | 8 | 1 | 1 | 8 | 1 |
+-------------+---------------+-------+-------+-------+--------+-------+--------+* TOP LEVEL CONTROL
+-----------+------------+-----------+
| Interface | Type | Ports |
+-----------+------------+-----------+
| ap_clk | clock | ap_clk |
| ap_rst_n | reset | ap_rst_n |
| interrupt | interrupt | interrupt |
| ap_ctrl | ap_ctrl_hs | |
+-----------+------------+-----------+
通过 AXIS 报告项,可以清楚的看到 axi stream 接口的构成:
* AXIS
+-------------+---------------+-------+-------+-------+--------+-------+--------+
| Interface | Register Mode | TDATA | TKEEP | TLAST | TREADY | TSTRB | TVALID |
+-------------+---------------+-------+-------+-------+--------+-------+--------+
| inStreamTop | both | 64 | 8 | 1 | 1 | 8 | 1 |
+-------------+---------------+-------+-------+-------+--------+-------+--------+
- TDATA: 这是数据信号,用于传输实际的数据。在报告中,TDATA的宽度是64位。
- TKEEP: 这是字节使能信号,每个位对应TDATA中的一个字节。如果TKEEP的某位是1,那么对应的TDATA字节是有效的;如果是0,则该字节无效。在报告中,TKEEP的宽度是8位,可以独立控制TDATA中的每个字节。
- TLAST: 这是一个标志信号,用于指示一次传输的最后一个数据包。当TLAST为1时,表示当前的TDATA是当前传输的最后一个数据包。
- TREADY: 这是就绪信号,由接收方控制。当TREADY为1时,表示接收方准备好接收数据;当TREADY为0时,表示接收方未准备好接收数据。
- TSTRB: 这是字节选通信号,与TKEEP类似,用于指示有效的数据字节。在报告中,TSTRB的宽度是8位。
- TVALID: 这是有效信号,由发送方控制。当TVALID为1时,表示发送方正在发送有效的数据;当TVALID为0时,表示当前没有数据被发送。
2.5 关于TKEEP和TSTRB
TKEEP和TSTRB在AXI Stream接口中都是字节使能信号,但它们的用途略有不同。
- TKEEP是用来指示哪些字节是有效的。如果TKEEP的某一位是1,那么对应的TDATA字节是有效的;如果是0,则该字节无效。这个信号通常用于数据包的开始和结束,以及中间的所有字节(如果TKEEP全部为1,则表示所有字节都是有效的)。
- TSTRB也是一个字节使能信号,但它更多地用于指示数据的位置或时序。当TSTRB的某一位是1时,表示对应的TDATA字节在当前时刻是有效的。TSTRB可以用来传输空字节,即使TKEEP为高,TSTRB也可以为低,这意味着需要发送一个空字节。
在大多数情况下,只使用TKEEP信号,因为它可以满足大部分接口的需求。然而,在某些特定的应用中,可能会同时使用TKEEP和TSTRB来提供更精细的控制。
2.6 综合报告(SW I/O Information)
================================================================
== SW I/O Information
================================================================
* Top Function Arguments
+-------------+-----------+---------------------------------------------+
| Argument | Direction | Datatype |
+-------------+-----------+---------------------------------------------+
| inStreamTop | in | stream<hls::axis<ap_uint<64>, 0, 0, 0>, 0>& |
| outTop | out | ap_uint<64>* |
+-------------+-----------+---------------------------------------------+* SW-to-HW Mapping
+-------------+---------------+-----------+----------+------------------------------------+
| Argument | HW Interface | HW Type | HW Usage | HW Info |
+-------------+---------------+-----------+----------+------------------------------------+
| inStreamTop | inStreamTop | interface | | |
| outTop | m_axi_gmem0 | interface | | |
| outTop | s_axi_control | register | offset | name=outTop_1 offset=0x10 range=32 |
| outTop | s_axi_control | register | offset | name=outTop_2 offset=0x14 range=32 |
+-------------+---------------+-----------+----------+------------------------------------+
从 Top Function Arguments 可轻松分析参数类型和方向。
3. 总结
本文详细介绍了如何利用 Vitis HLS 工具将 AXI Stream 格式的数据流转换为并行存储数据,并通过 AXI Master 接口写入到存储器中。通过示例代码和编译器指令的解释,读者可以了解到 AXI Stream 接口和 AXI Master 接口的特点以及在 FPGA 设计中的应用。同时,本文还分析了示例中各个函数的功能和参数,以及综合报告中的重要信息。
相关文章:

Vitis HLS 学习笔记--AXI_STREAM_TO_MASTER
目录 1. 简介 2. 示例 2.1 示例功能介绍 2.2 示例代码 2.3 顶层函数解释 2.4 综合报告(HW Interfaces) 2.5 关于TKEEP和TSTRB 2.6 综合报告(SW I/O Information) 3. 总结 1. 简介 本文通过“<Examples>/Interface…...

WPF之可翻转面板
1,创建翻转面板的资源字典:FlippPanel.xaml。 无外观控件同样必须给样式指定类型( <ControlTemplate TargetType"ss:FlipPanel">),相关详情参考:WPF之创建无外观控件-CSDN博客)…...

【深度学习】--slowfast视频理解数据集处理pipeline
官网指引: facebookresearch SlowFast :https://github.com/facebookresearch/SlowFast 进入dataset:https://github.com/facebookresearch/SlowFast/blob/main/slowfast/datasets/DATASET.md 这里面的东西需要通读,但是不要过于…...

ArcGIS10.2能用了10.2.2不行了(解决)
前两天我们的推文介绍了 ArcGIS10.2系列许可到期解决方案-CSDN博客文章浏览阅读2次。本文手机码字,不排版了。 昨晚(2021\12\17)12点后,收到很多学员反馈 ArcGIS10.2系列软件突然崩溃。更有的,今天全单位崩溃。提示许…...

mysql查询表信息(表名、表结构、字段信息等)
MySQL中,您可以使用以下SQL查询数据库的表信息或者某个表中具体的信息,例如:字段、字段描述、索引等,以下为具体的SQL: 1、查询数据库所有表信息(表名/表描述) SELECTtable_name name,TABLE_C…...

【MySQL探索之旅】JDBC (Java连接MySQL数据库)
📚博客主页:爱敲代码的小杨. ✨专栏:《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 |《MySQL探索之旅》 |《Web世界探险家》 ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更…...

tomcat-GC溢出
背景 一个项目需要导出大量的数据,导致GC但是这个项目在本地能够运行,但是在服务器上就不能运行本地和服务器的区别:NGINX和TOMCATGC和NGINX无关,那么就是Tomcat分配JVM的堆内存的容量不够 错误解决思路 网上教了一些查看JVM的大小…...
结合场景,浅谈深浅度拷贝
有两段代码是这样的: A段: List<String> list1 new ArrayList<>(); Bear B new Bear(); for(Apple apple : apples){B.url apple.url;B.content apple.content;list1.add(Bear); } B段: List<String> list1 new A…...

生成指定范围的随机整数
private static final Random RANDOM new Random();// 生成指定范围的随机整数public static int generateRandomInt(int min, int max) {return RANDOM.nextInt(max - min 1) min;}public static void main(String[] args) {Integer count 5;Integer randomInt generateR…...
少的缓存穿透是缓存击穿,大量的是缓存雪崩
只要请求穿过了缓存层,直接打到了数据库,我就把这个现象理解为缓存穿透。 只要缓存失效了,就会出现缓存穿透,然后根据失效缓存数量的多少,划分出缓存击穿和缓存雪崩 缓存一致性 先改redis再改mysql。...

设备能耗数据在线监测
在追求可持续发展和绿色经济的当下,企业对于设备能耗的管理愈发重视。设备能耗数据在线监测,不仅能帮助企业实时掌握设备的运行状况,还能为企业节能减排、降低运营成本提供有力支持。HiWoo Cloud平台凭借其先进的技术和丰富的经验,…...

springboot整合websocket,超简单入门
springBoot整合webSocket,超简单入门 webSocket简洁 WebSocket 是一种基于 TCP 协议的全双工通信协议,它允许客户端和服务器之间建立持久的、双向的通信连接。相比传统的 HTTP 请求 - 响应模式,WebSocket 提供了实时、低延迟的数据传输能力。…...
代码随想录算法训练营第三十四天| 860.柠檬水找零 406.根据身高重建队列 452. 用最少数量的箭引爆气球
860.柠檬水找零 题目链接 思路 三种情况,一种贪心,在bill为20时,有一次贪心选择:优先考虑先找105,再考虑找3*5,因为5可以用于bill10和bill20两种情况 解题方法 第一种:bill5,直接收 第二种…...

ICode国际青少年编程竞赛- Python-2级训练场-识别循环规律2
ICode国际青少年编程竞赛- Python-2级训练场-识别循环规律2 1、 for i in range(3):Dev.step(3)Dev.turnRight()Dev.step(4)Dev.turnLeft()2、 for i in range(3):Spaceship.step(3)Spaceship.turnRight()Spaceship.step(1)3、 Dev.turnLeft() Dev.step(Dev.x - Item[1].…...

12.轻量级锁原理及其实战
文章目录 轻量级锁原理及其实战1.轻量级锁的核心原理2.轻量级锁的演示2.1.轻量级锁的演示代码2.2.结果分析 3.轻量级锁的分类3.1.普通自旋锁3.2.自适应自旋锁 4.轻量级锁的膨胀 轻量级锁原理及其实战 引入轻量级锁的主要目的是在多线程环境竞争不激烈的情况下, 通过…...

栈结构(c语言)
1.栈的概念 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。 压栈&am…...

【C++】C/C++中新const用法:const成员
欢迎来到CILMY23的博客 本篇主题为: C/C中新const用法:const成员 个人主页:CILMY23-CSDN博客 系列专栏:Python | C | C语言 | 数据结构与算法 | 贪心算法 | Linux 感谢观看,支持的可以给个一键三连,点赞…...

武汉凯迪正大—钢管焊缝裂纹探伤仪
产品概述 武汉凯迪正大无损探伤仪是一种便携式工业无损探伤仪器, 能够快速便捷、无损伤、精确地进行工件内部多种缺陷(裂纹、夹杂、气孔等)的检测、定位、评估和诊断。既可以用于实验室,也可以用于工程现场。 设置简单,…...
为什么 IP 地址通常以 192.168 开头?
在网络配置中,我们经常会遇到以 192.168 开头的 IP 地址,例如 192.168.0.1 或者 192.168.1.100。 这些地址通常用于局域网中,但为什么要选择以 192.168 开头呢? 本文将深入探讨这个问题,并解释其背后的原因和历史渊源…...
elementUi中的el-table合计行添加点击事件
elementUi 文档中,合计行并没有点击事件,这里自己实现了合计行的点击事件。 created() {this.propertyList [{ property: order, label: 序号 },{ property: deptName, label: 单位名称 },{ property: contentPublishQuantity, label: 文章数量 },{ pro…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...

打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用
一、方案背景 在现代生产与生活场景中,如工厂高危作业区、医院手术室、公共场景等,人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式,存在效率低、覆盖面不足、判断主观性强等问题,难以满足对人员打手机行为精…...

JDK 17 序列化是怎么回事
如何序列化?其实很简单,就是根据每个类型,用工厂类调用。逐个完成。 没什么漂亮的代码,只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...

【51单片机】4. 模块化编程与LCD1602Debug
1. 什么是模块化编程 传统编程会将所有函数放在main.c中,如果使用的模块多,一个文件内会有很多代码,不利于组织和管理 模块化编程则是将各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数声明,其他.c文…...
ffmpeg(三):处理原始数据命令
FFmpeg 可以直接处理原始音频和视频数据(Raw PCM、YUV 等),常见场景包括: 将原始 YUV 图像编码为 H.264 视频将 PCM 音频编码为 AAC 或 MP3对原始音视频数据进行封装(如封装为 MP4、TS) 处理原始 YUV 视频…...