请问一下怎样去使用HLS创建IP呢

目前我们已经单独使用 hls 创建了ip(见上一节)。在本实践中,我们将实际实现 hls 组件作为 fpga 设计的一部分。首先我们将学习如何做到这一点,然后我们将创建硬件来解决一些实际问题。
首先使用上一节的文件创建一个新的 hls 项目:
重新综合一下
每次我们更改硬件时,我们都需要告诉 hls 将其导出为硬件描述语言并生成 vivado 需要的所有各种源数据。
选择solution → export rtl → 选择 vivado ip for system generator → 单击确定
接下来我们需要告诉 vivado 我们的新 ip 在哪里
回到 vivado,打开 block design。单击window -> ip catalog以打开 ip 目录。单击左侧 flow navigator 中的设置。选择 ip,然后选择存储库。按加号图标。从文件浏览器中选择 hls 项目目录,然后单击选择。vivado 将扫描 hls 项目,并弹出一个框,显示 ip 已添加到项目中。单击确定。
回到 block design,单击图表左侧的 add ip 按钮。ip 核将被称为之前创建ip时输入的显示名称,或者 toplevel 。双击 ip 进行添加。
要允许 ip 内核访问 ddr 存储器,需要在 zynq 处理系统上启用 axi 从接口。双击 zynq ip ,选择“ps-pl configuration”,展开“hp slave axi interface”,勾选 s axi hp0 interface. 单击确定,应该会看到 zynq 模块上出现一个新端口。
现在可以使用连接自动化来完成连接。运行连接自动化并检查 s_axi_hp0. 应该建议连接到 m_axi ip 核上的端口。
同样在连接自动化检查 s_axi_axilites和s_axi_control. 应该连接到m_axi_gp0 处理系统上。单击确定。
现在,ip将通过其从接口连接到processing_system7_0_axi_periph,并通过其主接口连接到axi_mem_intercon。
现在可以保存模块设计、生成比特流并再次导出硬件。覆盖现有的硬件规范(xsa 文件)。
连接自动化问题
如果对使用连接自动化生成的 axi 总线有问题(即,如果它们与上述结构不同),请尝试删除所有axi 互连模块并再次运行它。
一般原则是, zynq 模块的 m_axi 应该可追溯至 ip 内核上的所有 s_axi,而 ip 内核的 m_axi 应可追溯至 zynq 模块上的 s_axi_hp0。
在 vitis 中使用 ip
当 hls 导出我们的 ip 时,它帮助我们自动生成了一个软件驱动程序。但是我们需要告诉 vitis 在哪里可以找到这个驱动程序。
在 vitis 中,选择 xilinx → repositories。在 local repositories 下,单击 new 并选择 hls 项目的文件夹。单击重新扫描存储库,然后单击确定。
右键单击design_1_wrapper  平台并单击“update hardware specification”以更新我们已更改硬件的问题。
我们现在应该能够看到新 ip 及其驱动程序。
在 board support package 设置下的platform.spr  文件中,应该能够看到列出的 ip,以及它使用驱动程序.
现在可以与ip进行交互了,如下例所示。
#include #include platform.h#include xil_printf.h#include xparameters.h#include xtoplevel.h#include xil_cache.h u32 shared[1000]; int main() {    int i;    xtoplevel hls;     init_platform();    xil_dcachedisable();     print(hls test);    for(i = 0; i < 100; i++) {        shared[i] = i;    }    shared[0] = 8000;     xtoplevel_initialize(&hls, xpar_toplevel_0_device_id);    xtoplevel_set_ram(&hls, (u32) shared);    xtoplevel_start(&hls);    while(!xtoplevel_isdone(&hls));     printf(arg2 = %luarg3 = %lu, xtoplevel_get_arg2(&hls), xtoplevel_get_arg3(&hls));     cleanup_platform();    return 0;}  
对 fpga 进行编程并启动此代码,应该会看到以下内容:
hls testarg2 = 12950arg3 = 3050  
如您所见,目前组件可以使用xtoplevel_start启动,xtopleevel_isdone会告诉你何时完成。xtoplevel_set_ram告诉hls组件共享内存在主内存中的位置。允许hls读写,就像ram从0开始一样,但实际上它将指向我们的共享内存。不要忘记设置ram偏移量,否则hls组件将写入随机内存位!
当更改 hls 时
当更改 hls 代码时,请执行以下步骤以确保的最终文件已更新。
重新运行综合。
重新导出 ip 核。
在 vivado 中,应该已经识别到了变化,并且会出现一条消息说“ip catalog is out-of-date”。
如果没有,请单击 ip status,然后单击重新运行报告
单击刷新 ip 目录
在“generate output products”对话框中,单击“generate”。
单击生成比特流。
导出硬件(包括比特流)。
在 vitis 中重新编程 fpga 并运行软件。
如果更改了硬件接口,可能需要重新生成系统并将应用程序项目移入其中。
测量执行时间
下面将举例使用 arm 处理系统中的计时器来测量执行一段代码需要多长时间,然后演示可以在硬件中更快地执行相同的操作。我们要测量的代码实现了对collatz(柯拉兹) 猜想的测试。该猜想指出:
柯拉兹猜想
取任何 正整数n(其中n不为0)。如果 n 是偶数,则除以 2 得到 n  / 2。如果 n 是奇数,则将其乘以 3 并加 1 得到 3 n  + 1。无限重复该过程。猜想是,无论你从哪个数字开始,你最终总会达到 1。
创建一个 hls 组件来测试前 1000 个整数,以验证如果执行上述步骤,它们最终都会收敛到 1。将在共享数组中输出每个数字达到 1 所需的步数。
下面的代码是使用的arm软件:
#include #include platform.h#include xil_printf.h#include xparameters.h#include xtoplevel.h#include xil_cache.h int shared[1000];xtoplevel hls; unsigned int collatz(unsigned int n) {    int count = 0;    while(n != 1) {        if(n % 2 == 0) {            n /= 2;        } else {            n = (3 * n) + 1;        }        count++;    }    return count;} void software() {    int i;    for(i = 0; i < 1000; i++) {        shared[i] = collatz(i + 1);    }} void hardware() {    //start the hardware ip core    xtoplevel_start(&hls);    //wait until it is done    while(!xtoplevel_isdone(&hls));} void print_shared() {    int i;    for(i = 0; i < 1000; i++) {        xil_printf(%d , shared[i]);    }    xil_printf();} void setup_shared() {    int i;    for(i = 0; i < 1000; i++) {        shared[i] = i+1; //(we use i+1 because collatz of 0 is an infinite loop)    }} int main() {    init_platform();    xil_dcachedisable();    //initialise the hls driver    xtoplevel_initialize(&hls, xpar_toplevel_0_device_id);    xtoplevel_set_ram(&hls, (int) shared);    xil_printf(start);      setup_shared();    software();    print_shared();     setup_shared();    hardware();    print_shared();     cleanup_platform();    return 0;}  
检查此代码。该函数software()是前 1000 个整数的 collatz 迭代阶段的软件实现,将迭代计数放在全局数组shared中。该main函数设置 shared为 1 到 1001 的整数,运行software(),然后将结果打印出来。然后它重置共享并运行hardware()并打印结果。
在 hls 中实现一个硬件组件来计算前 1000 个整数的 collatz 计数(就像 arm 软件一样)。从以下顶级结构开始:
#include  // required for memcpy()  uint32 workingmem[1000]; uint32 toplevel(uint32 *ram, uint32 *arg1, uint32 *arg2, uint32 *arg3, uint32 *arg4) {    #pragma hls interface m_axi port=ram offset=slave bundle=maxi    #pragma hls interface s_axilite port=arg1 bundle=axilites    #pragma hls interface s_axilite port=arg2 bundle=axilites    #pragma hls interface s_axilite port=arg3 bundle=axilites    #pragma hls interface s_axilite port=arg4 bundle=axilites    #pragma hls interface s_axilite port=return bundle=axilites     //read in starting values    memcpy(workingmem, ram, 4000);     //calculate the collatz results.    //workingmem[x] = collatz(workingmem[x]);    //...your code here...     //burst copy workingmem to main memory    memcpy(ram, workingmem, 4000);    return 0;}  
因为 collatz 循环是无界的,所以 hls 将只有问号而不是时间估计。
然后将 ip 核放入设计中并运行 ip 核以测试它是否输出正确的答案。以上main.c应该可以驱动 ip 内核。
那么,硬件或软件更快?


如何将多个分散点模拟信号无线传输到PLC
一种更简单的测试集成模数转换器的方法
仲量科技旗下产品睿见数据获RICS年度地产科技创新成就奖
2023第21届亚洲消费电子展
选择科氏力质量流量计时需要考虑什么
请问一下怎样去使用HLS创建IP呢
M5141-000005-100PG在液压机械的应用要求
5G智慧交通系统 赋能现代城市交通数字化升级
阐述接地和割地的区别
电动自行车电池DIY
电流表和电压表如何接线
骨感耳机最好的品牌是哪些?骨感耳机排行榜
LXI数字化仪为混合模式测试新增I/O线
一款简单的单声道功放电路
RECOM高可靠性大功率转换器满足铁路标准
BI工具足以打造数据驱动型文化吗?
如何为开关电源选择反激式变压器
多功能测电笔的制作与原理
健身房中的智能显示屏让你爱上智能健身空间
国产超低功耗温湿度传感器芯片替代SHTC3