Vitis HLS 学习笔记--理解串流Stream(2)
目录
1. 简介
2. 极简的对比
3. 硬件模块的多次触发
4. 进一步探讨 do-while
5. 总结
1. 简介
在这篇博文中《Vitis HLS 学习笔记--AXI_STREAM_TO_MASTER-CSDN博客》,我分享了关于 AXI Stream 接口的实际应用案例。然而,尽管文章中提供了代码示例,对于代码中使用的编码格式并未进行深入探讨。例如,其中使用了 do-while 循环,但我们需要进一步思考:这个循环是否是必须的?我们如何理解硬件电路是如何实现一个无边界的循环呢?
这一问题的探讨将有助于读者更好地理解硬件描述语言(HDL)与软件编程之间的差异,以及如何在硬件层面有效地利用循环结构。
2. 极简的对比
请仔细对比一下两段代码:
- 代码一,包含 do-while
#include <complex>
#include "ap_axi_sdata.h"
#include "hls_stream.h"typedef hls::axis<std::complex<short int>, 0, 0, 0> data_t;
typedef hls::stream<data_t> mystream;void example_1(mystream &A, mystream &B) {
#pragma HLS INTERFACE axis port=A
#pragma HLS INTERFACE axis port=Bdata_t tmp_a;do {tmp_a = A.read();data_t tmp_b;tmp_b.data.real(tmp_a.data.real() + 5);tmp_b.data.imag(tmp_a.data.imag() + 1);B.write(tmp_b);} while (!tmp_a.last);
}
- 代码二,不包含 do-while
#include <complex>
#include "ap_axi_sdata.h"
#include "hls_stream.h"typedef hls::axis<std::complex<short int>, 0, 0, 0> data_t;
typedef hls::stream<data_t> mystream;void example_2(mystream &A, mystream &B) {
#pragma HLS INTERFACE axis port=A
#pragma HLS INTERFACE axis port=Bdata_t tmp_a;tmp_a = A.read();data_t tmp_b;tmp_b.data.real(tmp_a.data.real() + 5);tmp_b.data.imag(tmp_a.data.imag() + 1);B.write(tmp_b);
}
从软件调用的角度来理解:
在 example_1 中,使用了一个 do-while 循环,它会一直执行直到 tmp_a.last 的值为真。这表示在读取完所有输入数据后才会停止循环。
在 example_2 中,没有使用循环结构,而是直接从输入流 A 中读取一个数据,处理后写入输出流 B。因此,它只执行一次读取、处理和写入操作。
从软件调用的角度来看,以上的分析没有错,但是我们的代码会被硬件来实现,怎么会容忍硬件“只能被调用一次”?
在软件中,我们很容易理解并执行一次性的操作,例如在 example_2 中所示。然而,在硬件描述中,情况稍有不同。
在硬件中,一般情况下,每个操作都会对应一个硬件电路的状态变化或者时钟周期。因此,虽然在软件中我们可以简单地想象每个函数被调用一次,但在硬件中,我们需要考虑每个操作如何在时钟周期内完成。
这里提出一个出人意料的结论:尽管两端代码在软件层面看起来有所不同,但对应的硬件实现功能却完全相同。
3. 硬件模块的多次触发
对于example_2函数,当提到它“只能处理单个数据项”,意思是在一个函数调用中,它只从输入流A读取并处理一个数据项,然后将处理后的数据写入输出流B。在硬件实现上,这意味着它被设计为一次处理一个数据项的操作。
然而,硬件模块本身是可以被多次触发的,可以持续给这个模块喂数据,每次喂一个数据项,模块就处理一次。这是通过在硬件设计中实现一个接口,允许数据连续流入模块,并在每个数据项到来时触发处理逻辑。
在连续运行的情况下,example_2的硬件实现可以看作是一个流水线的单元,每接收到一个新的数据项,就处理这个数据项,并将结果输出。因此,尽管在单次函数调用中,它只处理一个数据项,但在连续运行时,它可以连续处理多个数据项,每次处理一个。
当持续给这个硬件模块喂数据时,模块将会在每个时钟周期(或多个时钟周期,取决于模块的设计和优化)处理一个数据项。
如果模块设计为非阻塞且具有足够的吞吐率,它将能够连续不断地处理流入的数据项,每处理完一个就准备接收下一个。
如果数据到达速度超过模块处理能力,或者模块设计中存在阻塞操作,可能需要引入缓冲机制或调整设计以确保数据可以被有效处理。
4. 进一步探讨 do-while
在这个《Vitis HLS 学习笔记--AXI_STREAM_TO_MASTER-CSDN博客》博文中,有一段示例代码如下:
...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);
}
软件层面的 do-while 循环,它实际上映射了一个硬件状态机的概念。
而这里的循环最重要的功能,就是实现对 count 变量的操作。count 被初始化为 0 后,就进入状态机中执行,直到 count >= MAX_BURST_LENGTH || in_val.last 条件满足,输出 out_counts,被再次清零。
然而清零后并不意味 do-while 循环终止,这段“代码”代码将会继续执行,没有终点。
5. 总结
example_2在硬件中可以被设计为连续处理数据的模块,尽管其代码表面上看只处理一次数据。重要的是要理解硬件设计和软件逻辑之间的差异:硬件模块可以被设计为重复触发,以连续处理数据流,而不仅仅是单个数据项。

相关文章:
Vitis HLS 学习笔记--理解串流Stream(2)
目录 1. 简介 2. 极简的对比 3. 硬件模块的多次触发 4. 进一步探讨 do-while 5. 总结 1. 简介 在这篇博文中《Vitis HLS 学习笔记--AXI_STREAM_TO_MASTER-CSDN博客》,我分享了关于 AXI Stream 接口的实际应用案例。然而,尽管文章中提供了代码示例&…...
Golang | Leetcode Golang题解之第80题删除有序数组中的重复项II
题目: 题解: func removeDuplicates(nums []int) int {n : len(nums)if n < 2 {return n}slow, fast : 2, 2for fast < n {if nums[slow-2] ! nums[fast] {nums[slow] nums[fast]slow}fast}return slow }...
uniapp自定义websocket类实现socket通信、心跳检测、连接检测、重连机制
uniapp自定义websocket类实现socket通信、心跳检测、检测连接、重连机制,仿vue-socket插件功能实现发送序列号进行连接检测,发送消息时42【key,value】格式,根据后端返回数据和需要接收到的数据做nsend与onSocketMessage的修改 //使用socket…...
Hive UDTF之explode函数、Lateral View侧视图
Hive UDTF之explode函数 Hive 中的 explode() 函数是一种用于处理数组类型数据的 User-Defined Table-Generating Function (UDTF)。它将数组拆分成多行,每个数组元素对应生成的一行数据。这在处理嵌套数据结构时非常有用,例如处理 JSON 格式的数据。 …...
智慧公厕打造智慧城市新标杆
公共厕所作为城市基础设施的重要组成部分,直接关系到市民的生活品质和城市形象。传统的公厕管理方式存在着许多问题,如环境脏乱、清洁不及时等,给市民带来了诸多不便和不满。而智慧公厕作为一种全新的管理模式,通过物联网、大数据…...
字节发布文生图模型PuLID:高效身份ID特征定制,单张图像克隆AI虚拟分身
前言 字节研究团队近日提出了一种新型的文生图身份ID定制方法PuLID(Pure and Lightning ID Customization)。相较于传统的微调方法,PuLID无需复杂的参数优化就可以实现高效的身份ID定制,且能最大程度减少对原始模型行为的干扰。 PuLID是通过将轻量级的…...
SpringBoot启动流程分析之创建SpringApplication对象(一)
SpringBoot启动流程分析之创建SpringApplication对象(一) 目录: 文章目录 SpringBoot启动流程分析之创建SpringApplication对象(一)1、SpringApplication的构造方法1.1、推断应用程序类型1.2、设置Initializers1.3、设置Listener1.4、推断main方法所在类 流程分析…...
SSH简介 特点以及作用
引言 SSH(Secure Shell)是一种用于安全远程访问和数据传输的网络协议。它提供了一种安全的机制,使得用户可以在不安全的网络中安全地进行远程登录、命令执行和文件传输。SSH通过加密技术和认证机制来保护数据的安全性,防止数据在…...
MQTT服务搭建及python使用示例
1、MQTT协议 1.1、MQTT介绍 MQTT(Message Queuing Telemetry Transport)是一种轻量级的、基于发布/订阅模式的通信协议,通常用于物联网设备之间的通讯。它具有低带宽、低功耗和开放性等特点,适合在网络带宽有限或者网络连接不稳定…...
Ubuntu如何设置中文输入法
概述 Ubuntu 是一个基于 Debian 构建的开源操作系统,拥有广泛的用户群体和强大的社区支持。是免费、开源的操作系统。被设计为一个适用于个人电脑、服务器和云平台的通用操作系统。Ubuntu的目标是提供一个稳定、易于使用和免费的操作系统,以促进人们在计…...
PostgreSQL的pg_dump和 pg_dumpall 异同点
PostgreSQL的pg_dump和 pg_dumpall 异同点 基础信息 OS版本:Red Hat Enterprise Linux Server release 7.9 (Maipo) DB版本:16.2 pg软件目录:/home/pg16/soft pg数据目录:/home/pg16/data 端口:5777pg_dump 和 pg_dum…...
【Ping】Windows 网络延迟测试 ping 、telnet、tcping 工具
ping 命令 属于网络层的ICMP协议,只能检查 IP 的连通性或网络连接速度, 无法检测IP的端口状态。 telnet telnet命令,属于应用层的协议,用于远程登录,也可用于检测IP的端口状态。但是功能有限,只能检测一时…...
DuDuTalk:4G桌面拾音设备在银行网点服务场景的应用价值
随着科技的飞速发展,银行业也在不断地寻求创新以提高服务质量和效率。在这个过程中,4G桌面拾音设备作为一种新型的智能设备,其在银行网点服务场景中的应用价值逐渐凸显出来。本文将从多个角度探讨4G桌面拾音设备在银行网点服务场景的应用价值…...
QT 设置窗口不透明度
在窗口作为子窗口时,setWindowOpacity设置窗口的不透明度可能会失效。 QGraphicsOpacityEffect *opacityEffect new QGraphicsOpacityEffect(this); opacityEffect->setOpacity(1.0); this->setGraphicsEffect(opacityEffect);// 创建属性动画对象ÿ…...
如何在Python中实现文本相似度比较?
在Python中实现文本相似度比较可以通过多种方法,每种方法都有其适用场景和优缺点。以下是一些常见的文本相似度比较方法: 1. 余弦相似度(Cosine Similarity) 余弦相似度是通过计算两个向量之间夹角的余弦值来确定它们之间的相似…...
韩顺平0基础学Java——第7天
p110-p154 控制结构(第四章) 多分支 if-elseif-else import java.util.Scanner; public class day7{public static void main(String[] args) {Scanner myscanner new Scanner(System.in);System.out.println("input your score?");int s…...
性能远超GPT-4!谷歌发布Med-Gemini医疗模型;李飞飞首次创业瞄准空间智能;疫苗巨头联合OpenAl助力AI医疗...
AI for Science 企业动态速览—— * 谷歌 Med-Gemini 医疗 AI 模型性能远超 GPT-4 * 斯坦福李飞飞首次创业瞄准「空间智能」 * 疫苗巨头 Moderna 与 OpenAl 达成合作 * 美国能源部推动 AI 在清洁能源领域的应用 * 美年健康荣获「2024福布斯中国人工智能创新场景应用企业TOP10」…...
中国科技大航海时代,“掘金”一带一路
文|白 鸽 编|王一粟 “这不就是90年代的内地吗?” 在深度考察完沙特市场后,华盛集团联合创始人兼CEO张霆对镜相工作室感慨道。 在张霆看来,沙特落后的基建(意味着大量创新空间)、刚刚开放…...
ffmpeg7.0 flv支持hdr
ffmpeg7.0 flv支持hdr 自从ffmpeg6.0应用enhance rtmp支持h265/av1的flv格式后,7.0迎来了flv的hdr能力。本文介绍ffmpeg7.0如何支持hdr in flv。 如果对enhance rtmp如何支持h265不了解,推荐详解Enhanced-RTMP支持H.265 1. enhance rtmp关于hdr 文档…...
【教程】极简Python接入免费语音识别API
转载请注明出处:小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你,请不吝给个[点赞、收藏、关注]哦~ 安装库: pip install SpeechRecognition 使用方法: import speech_recognition as srr sr.Recognizer() harvard sr…...
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...
区块链技术概述
区块链技术是一种去中心化、分布式账本技术,通过密码学、共识机制和智能合约等核心组件,实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点:数据存储在网络中的多个节点(计算机),而非…...
C# winform教程(二)----checkbox
一、作用 提供一个用户选择或者不选的状态,这是一个可以多选的控件。 二、属性 其实功能大差不差,除了特殊的几个外,与button基本相同,所有说几个独有的 checkbox属性 名称内容含义appearance控件外观可以变成按钮形状checkali…...
Windows 下端口占用排查与释放全攻略
Windows 下端口占用排查与释放全攻略 在开发和运维过程中,经常会遇到端口被占用的问题(如 8080、3306 等常用端口)。本文将详细介绍如何通过命令行和图形化界面快速定位并释放被占用的端口,帮助你高效解决此类问题。 一、准…...
2025-05-08-deepseek本地化部署
title: 2025-05-08-deepseek 本地化部署 tags: 深度学习 程序开发 2025-05-08-deepseek 本地化部署 参考博客 本地部署 DeepSeek:小白也能轻松搞定! 如何给本地部署的 DeepSeek 投喂数据,让他更懂你 [实验目的]:理解系统架构与原…...
算法250609 高精度
加法 #include<stdio.h> #include<iostream> #include<string.h> #include<math.h> #include<algorithm> using namespace std; char input1[205]; char input2[205]; int main(){while(scanf("%s%s",input1,input2)!EOF){int a[205]…...
深入浅出JavaScript中的ArrayBuffer:二进制数据的“瑞士军刀”
深入浅出JavaScript中的ArrayBuffer:二进制数据的“瑞士军刀” 在JavaScript中,我们经常需要处理文本、数组、对象等数据类型。但当我们需要处理文件上传、图像处理、网络通信等场景时,单纯依赖字符串或数组就显得力不从心了。这时ÿ…...
