当前位置: 首页 > news >正文

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 综合报告&#xff08;HW Interfaces&#xff09; 2.5 关于TKEEP和TSTRB 2.6 综合报告&#xff08;SW I/O Information&#xff09; 3. 总结 1. 简介 本文通过“<Examples>/Interface…...

WPF之可翻转面板

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

【深度学习】--slowfast视频理解数据集处理pipeline

官网指引&#xff1a; facebookresearch SlowFast &#xff1a;https://github.com/facebookresearch/SlowFast 进入dataset&#xff1a;https://github.com/facebookresearch/SlowFast/blob/main/slowfast/datasets/DATASET.md 这里面的东西需要通读&#xff0c;但是不要过于…...

ArcGIS10.2能用了10.2.2不行了(解决)

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

mysql查询表信息(表名、表结构、字段信息等)

MySQL中&#xff0c;您可以使用以下SQL查询数据库的表信息或者某个表中具体的信息&#xff0c;例如&#xff1a;字段、字段描述、索引等&#xff0c;以下为具体的SQL&#xff1a; 1、查询数据库所有表信息&#xff08;表名/表描述&#xff09; SELECTtable_name name,TABLE_C…...

【MySQL探索之旅】JDBC (Java连接MySQL数据库)

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 |《MySQL探索之旅》 |《Web世界探险家》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更…...

tomcat-GC溢出

背景 一个项目需要导出大量的数据&#xff0c;导致GC但是这个项目在本地能够运行&#xff0c;但是在服务器上就不能运行本地和服务器的区别&#xff1a;NGINX和TOMCATGC和NGINX无关&#xff0c;那么就是Tomcat分配JVM的堆内存的容量不够 错误解决思路 网上教了一些查看JVM的大小…...

结合场景,浅谈深浅度拷贝

有两段代码是这样的&#xff1a; A段&#xff1a; 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段&#xff1a; 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…...

少的缓存穿透是缓存击穿,大量的是缓存雪崩

只要请求穿过了缓存层&#xff0c;直接打到了数据库&#xff0c;我就把这个现象理解为缓存穿透。 只要缓存失效了&#xff0c;就会出现缓存穿透&#xff0c;然后根据失效缓存数量的多少&#xff0c;划分出缓存击穿和缓存雪崩 缓存一致性 先改redis再改mysql。...

设备能耗数据在线监测

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

springboot整合websocket,超简单入门

springBoot整合webSocket&#xff0c;超简单入门 webSocket简洁 WebSocket 是一种基于 TCP 协议的全双工通信协议&#xff0c;它允许客户端和服务器之间建立持久的、双向的通信连接。相比传统的 HTTP 请求 - 响应模式&#xff0c;WebSocket 提供了实时、低延迟的数据传输能力。…...

代码随想录算法训练营第三十四天| 860.柠檬水找零 406.根据身高重建队列 452. 用最少数量的箭引爆气球

860.柠檬水找零 题目链接 思路 三种情况&#xff0c;一种贪心&#xff0c;在bill为20时&#xff0c;有一次贪心选择&#xff1a;优先考虑先找105&#xff0c;再考虑找3*5&#xff0c;因为5可以用于bill10和bill20两种情况 解题方法 第一种&#xff1a;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.轻量级锁的膨胀 轻量级锁原理及其实战 引入轻量级锁的主要目的是在多线程环境竞争不激烈的情况下&#xff0c; 通过…...

栈结构(c语言)

1.栈的概念 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则。 压栈&am…...

【C++】C/C++中新const用法:const成员

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

武汉凯迪正大—钢管焊缝裂纹探伤仪

产品概述 武汉凯迪正大无损探伤仪是一种便携式工业无损探伤仪器&#xff0c; 能够快速便捷、无损伤、精确地进行工件内部多种缺陷&#xff08;裂纹、夹杂、气孔等&#xff09;的检测、定位、评估和诊断。既可以用于实验室&#xff0c;也可以用于工程现场。 设置简单&#xff0c…...

为什么 IP 地址通常以 192.168 开头?

在网络配置中&#xff0c;我们经常会遇到以 192.168 开头的 IP 地址&#xff0c;例如 192.168.0.1 或者 192.168.1.100。 这些地址通常用于局域网中&#xff0c;但为什么要选择以 192.168 开头呢&#xff1f; 本文将深入探讨这个问题&#xff0c;并解释其背后的原因和历史渊源…...

elementUi中的el-table合计行添加点击事件

elementUi 文档中&#xff0c;合计行并没有点击事件&#xff0c;这里自己实现了合计行的点击事件。 created() {this.propertyList [{ property: order, label: 序号 },{ property: deptName, label: 单位名称 },{ property: contentPublishQuantity, label: 文章数量 },{ pro…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式&#xff1a;dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一&#xff0c;腐蚀跟膨胀属于反向操作&#xff0c;膨胀是把图像图像变大&#xff0c;而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...