草庐IT

Vitis HLS 构建项目并生成IP核(Vivado HLS)

菜鸡渣渣一个 2025-04-24 原文

前言

Vitis HLS,可以通过它,用C和C++建立和封装一个IP核,从Vivado 2021的版本开始内置,用于替代Vivado HLS,由于它太新了,网上有关教程很少(2020的版本还是Vivado HLS),所以这个系列的文章,用于记录如何使用Vitis HLS。

使用Vitis HLS开发时,最好不要再使用C语言,而是C++,同时,使用一些旧教程中提到的"ap_cint.h"头文件会报错,这点请看后文提到的“错误1”。所以本文所有代码将使用C++。

新建工程

建立工程

打开软件后,新建一个工程。

设置好工程目录和工程名。

一路next,它要我们添加两个文件,我们这里略过。到了选择器件一栏。

我这里使用的是xc7z020clg400-2。

点击ok,然后点击finish,就到了开发界面。

编辑源码

一开始,我们关注左上角的窗口。

在Source一栏,我们新建两个源文件。

在工程目录下新建一个“src”文件夹用于存放代码文件。这里新建一个h头文件和一个cpp文件。由于使用的是C++,文件名后缀是cpp。

新建好了后,窗口会显示。

这里给出两个文件的代码。

  • led_twinkle.h
#include <ap_int.h>
void led_twinkle(ap_int<1> *led);
  • led_twinkle.cpp
#include "led_twinkle.h"

#define DELAY_TIME 50000000
#define DELAY_TIME_HALF 25000000 //optimize
//50000000

void led_twinkle(ap_int<1> *led){
	int i;
	for(i = 0;i < DELAY_TIME;i++){
		if(i < DELAY_TIME_HALF)
			*led=0;
		else
			*led=1;
	}
}

注意:以下所有截图中代码都有错,请按上面列出的代码运行

设置端口

在led_twinkle.cpp文件下,关注右上角的窗口。

给函数添加一个指令。

按照下面图片设置。注意,这里如果设置成ap_ctrl_none,在C/RTL仿真时会报错,具体参见错误4(当然也可以跳过C/RTL仿真)。

给输出端口也添加一个指令。

同样地,要按下图设置,设置成ap_none会弹警告,具体参见错误4(也可以不理会,设置成ap_none)。

设置好了后,源码中会自动添加有关代码,这里不建议自己添加,最好用软件自动生成。

添加测试

在“Test Bench”里,新建一个源文件,叫做led_twinkle_test.cpp。

源码如下。

  • led_twinkle_test.cpp
#include "led_twinkle.h"

ap_int<1> led_1;

int main(){
	led_twinkle(&led_1);
	printf("Run successfully!");
	return 0;
}

然后需要设置顶层函数。

选择刚刚设置好的函数。

验证测试

要想正确生成IP核,以下四个测试都必须通过。

C语言仿真

运行C语言仿真。

除了本身的语法错误会报错,如果用的是C语言写的,而非C++,此处也会报错,见错误1。printf代码的结果,会在这里显示,和C语言的控制台一样,输出一些自己编写的测试信息。

C语言综合

运行C语言综合。

如果没有安装最新的补丁,此处可能会报错,见错误2。而如果端口设置错误,会出现错误4。仿真结束后会接口信息等有关的信息。

C/RTL仿真

运行C/RTL仿真。

按照如下的设置。

结束之后会出现结果。如果将函数设置成ap_ctrl_none,会报错,具体参见错误4(当然也可以跳过C/RTL仿真)。

导出RTL

运行导出RTL。

默认即可,可以不用设置输出目录。

会提示导出成功。

IP核被生成在默认的目录下。

最终结果

生成的IP核可以在Vivado中显示了。验证和测试将放到下一篇文章。

如果函数和端口分别设置"ap_ctrl_none"和"ap_none",则是下面这样。在下一篇验证IP核的文章将使用按这样设置产生的IP核。

报错集合

错误1

unexpected top argument type: type of the parameter is C language  Arbitray-precesion type

找了很久的答案,发现了问题,是<ap_cint.h>这个头文件出错。从Vitis 2021开始(Vivado 2021),官方明确不再支持这个头文件,同时推荐使用C++开发。而很多老旧教程的代码中依然使用这个头文件,它们用的是C语言。

官方给出的说明和解决方法:

Vitis HLS:C 语言支持

解决方法是将引用的<ap_cint.h>改为<ap_int.h>,同时有关的数据类型需要进行修改。

错误2

clang compile failed: child process exited abnormally

其实这里已经提示了,找不到有关的头文件,但是头文件明明是包含在工程中的。

其实是因为使用include的时候,双引号引用和尖括号引用的区别。在本次错误中,错误地使用了双引号引用。

改成双引号引用即可。

错误3

Failed to generate IP

这个报错。控制台中没有给出具体的信息,其实只要安装最新的补丁即可。参考下面的链接。

Export IP Invalid Argument / Revision Number Overflow Issue (Y2K22)

将下载好的补丁解压到软件目录中,按住Shift键再按鼠标右键,打开控制台。

输入README中给出的代码即可。

运行结果。补丁安装成功,重启软件就可以了。

错误4

出现警告

WARNING: [RTGEN 206-101] Port 'led' with mode 'ap_none' may require an associated data valid signal to correctly communicate with other blocks or a test bench; automatic C/RTL co-simulation may not be able to verify such a port.

出现错误

ERROR: [COSIM 212-4] *** C/RTL co-simulation finished: FAIL ***  

出现类似错误的,都是因为端口设置出错。很多旧教程中,说到函数要设置成"ap_ctrl_none",以及端口设置成"ap_none",但是这会带来不确定性。正确的做法是设置成"ap_ctrl_hs"以及"ap_hs",这样就不会报错了,结果也是一致的。

但是设置将函数设置成"ap_ctrl_hs",也就是一种双向协议,会引入很多IO口。使用"ap_ctrl_none"也是可以的,就是需要跳过C/RTL仿真。

错误5

Vitis IDE launch failed

这个错误在使用SDK开发的时候会出现。一些教程中会教你,使用Vivado生成PS核之后,用Vitis生成顶层文件。但是如果安装软件的时候选择的是免费版,或者选择第二项Vivado,则会少安装Vitis这个软件。

注意:Vitis HLS和Vitis是两个不同的软件。免费版不包含Vitis。

解决方法很简单,从下图进入,重新安装Vitis即可。

以后在新安装软件的时候,记得选择第一项安装。

有关Vitis HLS 构建项目并生成IP核(Vivado HLS)的更多相关文章

  1. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  2. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  3. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  4. ruby - 如何使用 Ruby aws/s3 Gem 生成安全 URL 以从 s3 下载文件 - 2

    我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A

  5. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  6. ruby-on-rails - 新 Rails 项目 : 'bundle install' can't install rails in gemfile - 2

    我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="

  7. ruby - 从 Ruby 中的主机名获取 IP 地址 - 2

    我有一个存储主机名的Ruby数组server_names。如果我打印出来,它看起来像这样:["hostname.abc.com","hostname2.abc.com","hostname3.abc.com"]相当标准。我想要做的是获取这些服务器的IP(可能将它们存储在另一个变量中)。看起来IPSocket类可以做到这一点,但我不确定如何使用IPSocket类遍历它。如果它只是尝试像这样打印出IP:server_names.eachdo|name|IPSocket::getaddress(name)pnameend它提示我没有提供服务器名称。这是语法问题还是我没有正确使用类?输出:ge

  8. ruby-on-rails - Ruby on Rails - 为文本区域和图片生成列 - 2

    我是Rails的新手,所以请原谅简单的问题。我正在为一家公司创建一个网站。那家公司想在网站上展示它的客户。我想让客户自己管理这个。我正在为“客户”生成一个表格,我想要的三列是:公司名称、公司描述和Logo。对于名称,我使用的是name:string但不确定如何在脚本/生成脚手架终端命令中最好地创建描述列(因为我打算将其设置为文本区域)和图片。我怀疑描述(我想成为一个文本区域)应该仍然是描述:字符串,然后以实际形式进行调整。不确定如何处理图片字段。那么……说来话长:我在脚手架命令中输入什么来生成描述和图片列? 最佳答案 对于“文本”数

  9. Ruby 从大范围中获取第 n 个项目 - 2

    假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit

  10. ruby-on-rails - 如何生成传递一些自定义参数的 `link_to` URL? - 2

    我正在使用RubyonRails3.0.9,我想生成一个传递一些自定义参数的link_toURL。也就是说,有一个articles_path(www.my_web_site_name.com/articles)我想生成如下内容:link_to'Samplelinktitle',...#HereIshouldimplementthecode#=>'http://www.my_web_site_name.com/articles?param1=value1¶m2=value2&...我如何编写link_to语句“alàRubyonRailsWay”以实现该目的?如果我想通过传递一些

随机推荐