Vitis HLS 学习笔记--基本指针和算术指针

news2024/11/26 12:33:36

目录

1. 简介

2. 基本指针

3. 算术指针

4. 疑点解答

4.1 疑点1

4.2 疑点2

5. 总结


1. 简介

在 C/C++ 语言中,指针被广泛用来表示内存中的地址信息,它们是理解和使用这些语言的核心概念之一。然而,在 Vitis HLS 中,指针的使用有着显著的差异。尽管 Vitis HLS 支持指针的综合,但在某些情况下,使用指针可能会导致综合后的 RTL 接口与设计时的预期不符,尤其是在以下情况下:

  • 在同一函数内多次访问(读取或写入)指针时。
  • 使用指针数组时,每个指针都必须指向一个标量或标量数组(而不是另一个指针)。
  • 仅支持标准 C/C++ 语言类型间的指针强制转换。

虽然 Vitis HLS 支持指针的使用,但通常建议避免在代码中使用指针,尤其是在需要高效硬件实现的情况下。

在顶层函数的接口上使用指针时,应该特别注意指针的实现方式,以确保综合结果符合设计要求。在某些情况下,可能需要通过修改代码或选择不同的接口类型来解决由指针使用引起的问题。

2. 基本指针

基本指针,指的是直接指向数据的指针,而不需要复杂的指针操作,如指针数组或指针算术。

在 Vitis HLS 中,如果一个函数的顶层接口使用了基本指针,这通常不会对硬件综合产生负面影响。

用一个简单的比喻来理解这个概念:

你有一栋大楼(这里指的是你的硬件设计),而指针就像是大楼里的电梯。基本指针就像是一个直达特定楼层的电梯,它可以直接带你到达你想去的地方(即直接访问数据)。在 Vitis HLS 中,这样的电梯(基本指针)是可以被很好地管理和综合,因为它们的行为很直接,很容易预测。

现在,有两种方式可以让这些电梯(指针)工作:

  • 有线接口:这就像是一个普通的电梯,它在你按下按钮时就开始工作。在硬件中,有线接口意味着数据可以直接从一个地方传输到另一个地方,没有复杂的控制逻辑。
  • 握手接口协议:这更像是一个智能电梯,它会在确认你准备好了之后才开始运行。在硬件中,握手接口会在收到一个特定的信号(ready)后才开始数据传输。这种方式允许更精细的控制数据流,但也更复杂一些。

只要你的指针像一个直达电梯那样简单直接,Vitis HLS 就能够很好地处理它,无论是通过有线接口还是握手接口协议。这样的指针不会给硬件综合带来问题,因为它们的行为很容易在硬件中实现。

void example(int *d) {
  static int acc = 0;

  acc += *d;
  *d = acc;
}

测试代码:

#include <stdio.h>
extern void example(int *d);

int main() {
  int d;
  int i;

  printf(" Din Dout\n");

  // Create input data
  // Call the function to operate on the data
  for (i = 0; i < 4; i++) {
    d = i;
    example(&d);
    printf("  %d   %d\n", i, d);
  }

  // Return 0 if the test passed
  return 0;
}

 输出的结果:

Call   Din  Dout
1st     0    0
2nd     1    1
3rd     2    3
4th     3    6

查看综合报告 HW Interfaces 部分:

================================================================
== HW Interfaces
================================================================
* REGISTER
+-----------+---------+----------+
| Interface | Mode    | Bitwidth |
+-----------+---------+----------+
| d_i       | ap_none | 32       |
| d_o       | ap_none | 32       |
+-----------+---------+----------+

 可以看到,指针d是通过 ap_none 接口实现的。 

3. 算术指针

在 Vitis HLS 中,指针算术的使用与传统的连线、握手或 FIFO 接口的数据访问方式存在显著差异。

算术指针允许开发者进行无序访问,即可以直接通过地址运算来访问任意位置的数据,如下代码:

void example(int *d) {
  static int acc = 0;
  int i;

  for (i = 0; i < 4; i++) {
    acc += *(d + i + 1);
    *(d + i) = acc;
  }
}

在这段代码中,指针 d 被用来访问和修改数组中的元素,且访问顺序不是连续的。

对应生成的IP:

对应的测试代码: 

#include <stdio.h>
extern void example(int *d);

int main() {
  int d[5], ref[5];
  int i;

  // Create input data
  for (i = 0; i < 5; i++) {
    d[i] = i;
    ref[i] = i;
  }

  // Call the function to operate on the data
  example(d);

  printf(" Din Dout\n");
  for (i = 0; i < 4; i++) {
    printf("  %d   %d\n", ref[i], d[i]);
  }

  return 0;
}

如果直接运行 C Simulation,那么仿真是通过的。

这种方式在软件编程中非常灵活,但在硬件设计中可能会引入问题。

相比之下,连线、握手或 FIFO 接口则要求数据必须按照固定的顺序进行访问。这意味着数据的读取和写入操作必须从数组的第一个元素开始,然后依次进行。这种顺序性要求与算术指针的灵活性相冲突。

  • 连线接口:当数据准备就绪时,接口会读取数据。这种方式适合于数据流的连续处理。
  • 握手和 FIFO 接口:当控制信号允许时,接口会执行读写操作。这种方式适合于需要同步控制的场景。

由于 Vitis HLS 不支持对连线、握手或 FIFO 接口建立数据索引,因此在硬件实现中,如果使用了算术指针,就需要某种形式的数据索引机制。为了解决这个问题,可以将指针替换为数组,并通过 RAM (ap_memory) 接口来实现代码,如下所示:

void example(int d[5]) {
  static int acc = 0;
  int i;

  for (i=0; i<4; i++) {
    acc += d[i+1];
    d[i] = acc;
  }
}

查看综合报告 HW Interfaces 部分:

================================================================
== HW Interfaces
================================================================
* AP_MEMORY
+------------+----------+
| Interface  | Bitwidth |
+------------+----------+
| d_address0 | 3        |
| d_address1 | 3        |
| d_d0       | 32       |
| d_q1       | 32       |
+------------+----------+

可以看到,数组d已经通过 ap_memory 接口来实现了。 

4. 疑点解答

4.1 疑点1

基本指针代码输出的IP如下,这个模块是在每个周期执行一次吗?

答:不是。执行状态受块级控制协议 ap_hs 控制,在使能期间,每个周期可以执行一次。对应到仿真程序上,调用 example(&d) 则执行一次。

4.2 疑点2

void example(int d[5]) {
  static int acc = 0;
  int i;

  for (i=0; i<4; i++) {
    acc += d[i+1];
    d[i] = acc;
  }
}

对应的IP如下,通过块级控制协议启动一次,就能实现对存储器中4个元素进行操作吗?

答:是的。启动该IP后, HLS core 会自动操作存储器4次,完成数据的读写,完毕后,使能 ap_done信号。

5. 总结

在Vitis HLS中,指针的使用与传统的C/C++环境存在显著差异,尤其是在涉及硬件综合时。基本指针可以直接指向数据,并且通常不会对硬件综合产生负面影响,但在顶层函数的接口中使用时需要注意指针的实现方式。另一方面,算术指针的灵活性在软件编程中很有用,但在硬件设计中可能引入问题,因为硬件需要按照固定顺序访问数据。为了克服这些问题,可以通过使用数组和RAM接口来替代指针,以更好地满足硬件设计的需求。总之,在进行Vitis HLS设计时,需要仔细考虑指针的使用方式,以确保最终的硬件实现符合设计要求。

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

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

相关文章

Unity射击游戏开发教程:(20)增加护盾强度

在本文中,我们将增强护盾,使其在受到超过 1 次攻击后才会被禁用。 Player 脚本具有 Shield PowerUp 方法,我们需要调整盾牌在被摧毁之前可以承受的数量,因此我们将声明一个 int 变量来设置盾牌可以承受的击中数量。

【大模型】fineturn Q-wen

github上下载qwen1_5源码 修改finetun.sh 然后在路径qwen1_5/examples/sft下修改finetun.sh, 内容如下 #!/bin/bash export CUDA_DEVICE_MAX_CONNECTIONS1 DIRpwd# Guide: # This script supports distributed training on multi-gpu workers (as well as single-worker trai…

大数据Hadoop之-工具HIVE(一)

大数据Hadoop之——数据仓库Hive HIVE介绍Hive是基于Hadoop的一个数据仓库(Data Aarehouse,简称数仓、DW),可以将结构化的数据文件映射为一张数据库表,并提供类SQL查询功能。是用于存储、分析、报告的数据系统。 在Hadoop生态系统中,HDFS用于存储数据,Yarn用于资源管理…

WSL调用docker

WSL&#xff08;windows subsystem linux&#xff09;是window系统的原生linux子系统&#xff0c;用于代码开发很方便。 希望在wsl里面运行docker&#xff0c;首先要安装docker在WSL中使用&#xff0c;大部分人的第一想法肯定是用以下命令行安装&#xff08;个人不推荐&#x…

大语言模型本地部署与使用_ollama_open-webui

概述 本文主要记录如何使用ollama运行开源的大语言模型如llama3等&#xff0c;以及如何使用open-webui进行交互。 ollama支持MacOS、Linux、Windows等操作系统&#xff0c;这里主要以Linux和Windows为主&#xff0c;讲述如何在本地运行大语言模型。 一 安装ollama 1.1 Wind…

centos 8.5 yum 更换阿里云源

在CentOS 8上更换为阿里云源,步骤操作&#xff1a; 1 备份当前的yum源配置文件 cp -a /etc/yum.repos.d /etc/yum.repos.d.backup 2 清理原来 官方默认源 rm -rf /etc/yum.repos.d/*.repo 3 下载阿里云CentOS 8的yum源配置文件 curl -o /etc/yum.repos.d/CentOS-Base.rep…

桌面藏线大法

1有线改无线&#xff1a; 蓝牙鼠标 蓝牙键盘 蓝牙耳机 2将排插贴到桌子底下 购物软件上搜 3断舍离 不要的电子产品统统扔掉 4 洞洞板和挂钩 这个不用介绍了

由于找不到mfc140u.dll怎么办,介绍5种靠谱有效的解决方法

当您的电脑显示“mfc140u.dll丢失”的错误时&#xff0c;通常是因为系统中缺少了某个必要的动态链接库文件。这个问题可能会导致某些应用程序无法正常运行&#xff0c;给用户带来困扰。下面我将详细介绍解决该问题的五种方法。 一&#xff0c;关于mfc140u.dll文件的概述 mfc14…

如何在 ASP.NET Core 中实现中间件管道

概述:借助 ASP.NET Core,中间件流水线可以作为一种轻量级、灵活的机制,使开发人员能够在请求流水线的不同阶段插入功能。这些中间件组件可以执行各种任务,例如日志记录、身份验证、授权、异常处理等。它们提供了一种封装和组织代码的方法,促进了更简洁、更易于维护的应用程…

Java类和对象(五)—— 抽象类、接口、Object类和内部类

抽象类 在继承体系下&#xff0c;父类有些方法可能是要被重写的&#xff0c;如果我们事先就知道某些方法需要重写的话&#xff0c;我们可以不用在父类里面具体实现这个方法&#xff0c;这时候我们会用到抽象方法&#xff0c;这时候我们会用到关键字abstract关键字来修饰 publ…

618值得买的好物清单,这些数码好物你千万不能错过!

​随着618购物节的距离越来越近&#xff0c;你是不是已经开始疯狂浏览购物app&#xff0c;准备大肆采购一番了&#xff1f;但是在购物之前&#xff0c;还是得先做一做功课&#xff0c;避免陷入购物陷阱&#xff0c;而作为一名经验丰富的数码爱好者&#xff0c;想通过这次机会给…

Xinstall助力实现App间直接跳转,提升用户体验

在移动互联网时代&#xff0c;App已成为我们日常生活中不可或缺的一部分。然而&#xff0c;在使用各类App时&#xff0c;我们经常会遇到需要在不同App之间切换的情况&#xff0c;这时如果能够直接跳转&#xff0c;将会大大提升用户体验。而Xinstall正是这样一款能够帮助开发者实…

Python语法学习之 - 生成器表达式(Generator Expression)

第一次见这样的语法 本人之前一直是Java工程师&#xff0c;最近接触了一个Python项目&#xff0c;第一次看到如下的代码&#xff1a; i sum(letter in target_arr for letter in source_arr)这条语句是计算source 与 target 数组中有几个单词是相同的。 当我第一眼看到这样…

Docker镜像源自动测试镜像速度,并选择速度最快的镜像

国内执行如下代码 bash <(curl -sSL https://gitee.com/xjxjin/scripts/raw/main/check_docker_registry.sh)国外执行如下代码 bash <(curl -sSL https://github.com/xjxjin/scripts/raw/main/check_docker_registry.sh)如果有老铁有比较不错的镜像源&#xff0c;可以提…

浏览器API与协议

现代浏览器是一个囊括了数百个组件的操作系统&#xff0c;包括进程管理、安全沙箱、分层的优化缓存、JavaScript虚拟机、图形渲染和GPU管道、存储系统、传感器、音频和视频&#xff0c;网络机制等等。 在浏览器上运行的应用的性能。&#xff0c;取决于多个组件&#xff1a;解析…

完整的数据可视化方法集

在当前的大数据时代&#xff0c;了解如何可视化数据是UI/UX设计师技能的重要组成部分。如今&#xff0c;几乎所有的公司都需要良好的数据可视化作为确定业务方向和决策的参考。数据的可视化结果越好&#xff0c;用户的决策就越科学。 1、什么是数据可视化 数据可视化是将信息…

The Missing Semester of Your CS Education(计算机教育中缺失的一课)

Shell 工具和脚本(Shell Tools and Scripting) 一、shell脚本 1.1、变量赋值 在bash中为变量赋值的语法是foobar&#xff0c;访问变量中存储的数值&#xff0c;其语法为 $foo。 需要注意的是&#xff0c;foo bar &#xff08;使用空格隔开&#xff09;是不能正确工作的&…

Html中,想利用JS引入Jquery文件;$.getScript()无效

在使用$.getScript()时&#xff0c;会爆出错误&#xff1a;ReferenceError: $ is not defined &#xff0c;这是因为没有在JS文件前引入Jquery。 那么可以这样使用&#xff1a;(这个方式只适合放在页面代码最后面使用) (function () {var script window.document.createEleme…

我把PostgreSQL最核心的插件撸干净了!!!

作者&#xff1a;IT邦德 中国DBA联盟(ACDU)成员&#xff0c;10余年DBA工作经验&#xff0c; Oracle、PostgreSQL ACE CSDN博客专家及B站知名UP主&#xff0c;全网粉丝10万 擅长主流Oracle、MySQL、PG、高斯及Greenplum备份恢复&#xff0c; 安装迁移&#xff0c;性能优化、故障…

华为手机卡顿(仅针对于部分人来说,我也不清楚是否真的有用)

关机&#xff01; 之前一段时间手机变得特别卡顿&#xff0c;然后网上搜了一堆教程一点用没有&#xff0c;结果因为昨天下午在考试所以把手机关机了一个多小时&#xff0c;再打开之后手机就变得很流畅&#xff0c;原因不详&#xff0c;但效果显著&#xff0c;如有需要可尝试一…