精华内容
下载资源
问答
  • vivado hls教程

    热门讨论 2013-05-20 14:12:06
    vivado hls的官方教程,通过多个实验快速掌握高层次综合
  • 使用 Vivado HLS 和 AXI4-Stream 实现拉普拉斯滤波器示例。 您可以使用 GIMP2 以 RAW 格式查看结果。 原始图像大小为 240x120 像素(输出为 solution1/csim/build/image.data)。 结果图像大小为 238x118 像素...
  • Vivado HLS教程

    2020-04-07 19:11:22
    想学Vivado HLS,这里做个记录。 本着先感性再理性的学习规律,首先学习Xilinx提供的教程ug871,上手操作。 教程描述 本教程是一些较小的教程的集合,这些教程说明和演示了使用高级综合将C,C ++和SystemC代码转换为...

    准备学习Vivado HLS,这里做个记录。
    本着先感性再理性的学习规律,首先翻译Xilinx提供的教程ug871,同步上手操作。

    教程描述

    本教程是一些较小的教程的集合,这些教程说明和演示了使用高级综合将C,C ++和SystemC代码转换为RTL实现的过程中的所有步骤。 本教程介绍了如何创建初始RTL实现,然后在不更改C代码的情况下使用优化指令将其转换为低区域和高吞吐量的实现。 以下各节描述了每个教程的摘要。

    高层次综合简介

    本教程介绍了Vivado高级综合(HLS)。 您可以使用图形用户界面(GUI)和Tcl环境学习执行高级综合的主要任务。

    C验证

    本教程回顾了一个好的C测试平台的各个方面,并演示了Vivado高级综合C调试环境的基本操作。 本教程还显示了如何调试任意精度的数据类型。

    接口综合

    该接口综合教程回顾了为RTL设计创建端口的所有方面。 您可以学习如何控制块级I / O端口协议和端口I / O协议,如何将C函数中的数组实现为多个端口和接口协议类型(RAM,FIFO,AXI4-Stream),以及如何 实现了AXI4总线接口。
    为了创建最佳的设计实现,本教程以一个设计示例作为结束,其中将I / O访问和逻辑一起优化。

    任意精度类型

    本教程中的实验练习将用原生C类型编写的C设计与用Vivado高级综合任意精度类型编写的相同设计进行了对比,显示了后者如何在不牺牲准确性的情况下提高了硬件结果的质量。

    设计分析

    本教程使用DCT函数来解释Vivado高级综合中交互式设计分析功能的特性。 初始设计将带您经历多个分析和优化阶段,这些阶段突出了分析透视图的所有功能,并为设计优化方法提供了基础。

    设计优化

    本教程使用矩阵乘法器示例,回顾了两种设计的优化技术。 设计优化实验室解释了如何对设计进行流水线设计,并与流水线化循环与流水线化功能的方法进行了对比。
    本教程向您展示如何利用从分析中学到的见解来更新初始C代码并创建更优化的设计实现。

    RTL验证

    本教程说明如何使用RTL协同仿真功能自动验证通过综合创建的RTL。 本教程演示了C测试平台的重要性,并向您展示了如何使用RTL验证的输出在Vivado和Mentor Graphics ModelSim模拟器中查看波形图。

    在IPI中使用HLS IP

    本教程说明了如何将由高级综合创建的RTL设计打包为IP,添加到Vivado IP目录中,以及如何在Vivado Design Suite中使用。

    在ZynqSoC设计中使用HLS IP

    除了在Zynq®-7000SoC设计中使用HLS IP模块之外,本教程还介绍了如何将由高级综合创建的C驱动程序文件合并到Zynq处理系统(PS)的软件中。

    在SystemGeneratorforDSP中使用HLS IP

    本教程说明了如何将由高级综合创建的RTL设计打包为IP并在System Generator for DSP中使用。

    展开全文
  • HLS语言的基础教程,分享出来给大家学习学习
  • des算法的hls实现 vivado

    2019-02-27 19:18:49
    这是使用HLS对des算法进行优化的文档,包括了实现代码,testbench和hls文件,可以用于vivado相关硬件实现的课程设计等等
  • VivadoHLS 学习使用Vivado HLS 2018.3开发数字系统所需的高级综合设计方法。 所有项目基于pynq-z2
  • Vivado HLS 教程.pptx

    2020-07-07 08:28:47
    Vivado Hls C入门详解教程,附带有各个流程的使用和配合,并附有代码示例,可在Vivado 2017.4 上进行学习测试
  • Vivado HLS教程.pdf

    2020-11-16 17:08:58
    关于用vivado进行HLS开发的资料,其中有笔记对应的视频链接,可以配套视频进行学习,属于个人学习资料,不喜勿喷
  • Vivado-hls使用实例-详细教程

    千次阅读 2020-04-21 10:05:56
    本系列教程演示如何使用xilinx的HLS工具进行算法的硬件加速。 分为三个部分,分别为HLS端IP设计,vivado硬件环境搭建,SDK端软件控制。 在HLS端,要将进行硬件加速的软件算法转换为RTL级电路,生成便于嵌入式使用的...

    【引言】

    本系列教程演示如何使用xilinx的HLS工具进行算法的硬件加速。

    分为三个部分,分别为HLS端IP设计,vivado硬件环境搭建,SDK端软件控制
    在HLS端,要将进行硬件加速的软件算法转换为RTL级电路,生成便于嵌入式使用的axi控制端口,进行数据的传输和模块的控制。

    点击查看工程源码

    【HLS介绍】

    HLS可以将算法直接映射为RTL电路,实现了高层次综合。vivado-HLS可以实现直接使用 C,C++ 以及 System C 语言对Xilinx的FPGA器件进行编程。用户无需手动创建 RTL,通过高层次综合生成HDL级的IP核,从而加速IP创建。

    HLS的官方参考文档主要为:ug871( ug871-vivado-high-level-synthesis-tutorial.pdf )和ug902(ug902-vivado-high-level-synthesis.pdf)。

    对于Vivado Hls来说,输入包括Tesbench,C/C++源代码和Directives,相应的输出为IP Catalog,DSP和SysGen,特别的,一个工程只能有一个顶层函数用于综和,这个顶层函数下面的子函数也是可以被综合的,会生成相应的VHDL和Verilog代码,所以,C综合后的RTL代码结构通常是跟原始C描述的结构是一致的,除非是子函数功能很简单,所需要的逻辑量很小。并不是所有的C/C++都可以被综合,动态内存分配和涉及到操作系统层面的操作不可以被综合。

    Vivado HLS 的设计流程如下:

    在这里插入图片描述
    在整个流程中,用户先创建一个设计 C、C++ 或 SystemC 源代码,以及一个C的测试平台。通过 Vivado HLS Synthesis 运行设计,生成 RTL 设计,代码可以是 Verilog,也可以是 VHDL。有了 RTL 后,随即可以执行设计的 Verilog 或 VHDL 仿真,或使用工具的C封装器技术创建 SystemC 版本。然后可以进行System C架构级仿真,进一步根据之前创建的 C 测试平台,验证设计的架构行为和功能。设计固化后,就可以通过 Vivado 设计套件的物理实现流程来运行设计,将设计编程到器件上,在硬件中运行和/或使用 IP 封装器将设计转为可重用的 IP。

    Step 1: 新建一个工程

    1,Creat New Project新建文档,输入工程名称和工程路径。完成后点击Next。
    在这里插入图片描述
    2,添加设计文件,并制定顶层函数。完成后点击Next。

    在这里插入图片描述

    3,添加C语言仿真文件。完成后点击Next。

    在这里插入图片描述

    4,:配置Solution Name,一般默认即可。配置Clock Period,单位是ns。配置Uncertainty,默认为空。选择产品型号。完成后点击Finish。

    在这里插入图片描述

    5,工程新建成功后进入的开发界面,HLS是典型的Eclipse界面,和SDK的界面十分相似。

    在这里插入图片描述

    导入的文件的代码如下:

    1,源文件。axi_interfaces.c

    #include "axi_interfaces.h"
    void axi_interfaces (dout_t d_o[N], din_t d_i[N])
    {
    
    	int i, rem;
    // Store accumulated data static
    	dacc_t acc[CHANNELS];
    axi_interfaces_label0:
    	for (i=0;i<CHANNELS;i++)
    			{
    				acc[i] = 0;
    			}
    // Accumulate each channel
    For_Loop:
    	for (i=0;i<N;i++)
     	 	 {
    	 	 	 rem=i%CHANNELS;acc[rem] = acc[rem] + d_i[i];d_o[i] = acc[rem];
     	 	 }
    
    }
    

    2,头文件。axi_interfaces.h

    #ifndef AXI_INTERFACES_H_
    
    #define AXI_INTERFACES_H_
    
    #include <stdio.h>
    
    typedef int din_t;
    
    typedef int dout_t;
    
    typedef int dacc_t;
    
    #define CHANNELS 8
    
    #define SAMPLES  4
    
    #define N CHANNELS * SAMPLES
    
    void axi_interfaces (dout_t d_o[N], din_t d_i[N]);
    
    #endif
    

    3,测试文件。axi_interfaces_test.c

    #include "axi_interfaces.h"
    
    int main () {
    
    // Create input data
    
      din_t d_i[N] = {10, 20, 30, 40, 50, 60, 70, 80,
    
    11, 21, 31, 41, 51, 61, 71, 81,
    
    12, 22, 32, 42, 52, 62, 72, 82,
    
    13, 23, 33, 43, 53, 63, 73, 83};
    
    
    dout_t 		d_o[N];
    
    int i, retval=0;
    
    FILE        *fp;
    
    // Call the function to operate on the data
    
      axi_interfaces(d_o,d_i);
    
    // Save the results to a file
    
    fp=fopen("result.dat","w");
    
    fprintf(fp, "Din Dout\n");
    
    for (i=0;i<N;i++) {
    
        fprintf(fp, "%d   %d\n", d_i[i], d_o[i]);
    
    }
    
    fclose(fp);
    
    // Compare the results file with the golden results
    
    retval = system("diff --brief -w result.dat result.golden.dat");
    
    if (retval != 0) {
    
    printf("Test failed  !!!\n");
    
    retval=1;
    
    } else {
    
    printf("Test passed !\n");
    
      }
    
    // Return 0 if the test passes
    
      return retval;
    
    }
    

    4,测试数据。result.golden.dat

    Din Dout
    10   10
    20   20
    30   30
    40   40
    50   50
    60   60
    70   70
    80   80
    11   21
    21   41
    31   61
    41   81
    51   101
    61   121
    71   141
    81   161
    12   33
    22   63
    32   93
    42   123
    52   153
    62   183
    72   213
    82   243
    13   46
    23   86
    33   126
    43   166
    53   206
    63   246
    73   286
    83   326
    

    Step 2: C源代码验证

    本步骤是对功能代码的逻辑验证,相当于功能前仿。
    1,测试程序的代码入下图。该程序先调用综合的函数,得到计算结果,再和预先的数据集进行比较,最后返回计较的结果。计算结果和预先的数据集一致时,测试通过,不一致时,测试失败。需要查看代码,寻找错误。
    在这里插入图片描述

    按钮,开始C源代码验证。

    在这里插入图片描述

    3,验证的结果显示在控制栏中。如图显示,测试通过。

    在这里插入图片描述

    4,在头文件中,重定义了数据类型,参数,并进行了函数声明。

    在这里插入图片描述

    Step 3: 高层次综合

    本步骤是把功能代码的综合成RTL逻辑。
    1,点击红框中的按钮,将C代码综合成RTL。综合完成后,查看结果。

    在这里插入图片描述
    2,综合完成后,查看综合报告。包括时序,延时,资源占用,端口信息等。
    在这里插入图片描述

    在这里插入图片描述

    3,端口分析。
    (1)控制端口用于控制和显示该模块的工作状态。各个端口的功功能如下,默认情况下会生成下面四个控制端口。
    ap_start(in):为高时,该模块开始处理数据。
    ap_done(out):为高时,表示模块处理数据完成。
    ap_idle(out):表明模块是否处于空闲态。高电平有效。为高时,该处于空闲态。
    ap_ready(out):为高时,表示模块可以接受新的数据。

    (2)数据端口用于传递模块的输入输出参数。
    参数d_o,d_i 为数组类型,故默认状态下回生成内存接口。内存接口 (数组类型参数)数据来自外部的memory,通过地址信号读取相应的数据,输入到该模块中。输入数组从外部内存中读源数据,输出数组从向外部内存写入结果数据。各个端口的定义如下。
    address:地址信号
    ce0:片选信号
    we0:写使能信号
    d0 :数据信号

    4,综合结果分析。
    在分析界面,可以看到模块的运行情况。包括数据依赖关系和各个周期执行的操作,IO口的读写,内存端口的访问等等。

    在这里插入图片描述

    在这里插入图片描述

    Step 4: 综合优化

    在使用高层次综合,创造高质量的RTL设计时,一个重要部分就是对C代码进行优化。
    Vivado HLS拥有自动优化的功能,试图最小化loop(循环)和function(函数)的latency。除了自动优化,我们可以手动进行程序优化,即用在不同的solution中添加不同的directive(优化指令)的方法,进行优化和性能对比。其中,对同一个工程,可以建立多个不同的solution(解决方案),为不同的solution添加directive可以达到如下目的。
    优化的类型可分为如下类别:

    端口优化。指定不同类型的模块端口。
    函数优化。加快函数的执行速度,减小执行周期。
    循坏优化。利用展开和流水线形式,减小循环的执行周期。

    1,点击下面红框的图标,新建solution。

    在这里插入图片描述

    2,不同solution位于不同的文件夹中。
    在这里插入图片描述
    3,选中综合文件。可以在direct框中看可进行优化的标签。

    在这里插入图片描述
    4,双击选择d_o,选择interface,s_axilite。点击ok。将d_o的端口类型设置为s_axilite类型。
    在这里插入图片描述
    5,参考d_o,将d_i的接口类型也设置为s_axilite。将d_i的端口类型设置为s_axilite类型。

    在这里插入图片描述

    6,双击选择函数名称axi_interface,选择interface,s_axilite。点击ok。将控制端口的端口类型设置为s_axilite类型。

    在这里插入图片描述

    7,双击循环标签,选择流水线优化(pipeline),点击ok。
    在这里插入图片描述

    8,双击循环标签,选择循环展开优化(unroll),点击ok。
    在这里插入图片描述
    9,同上,也将标签为for_loop的循环进行流水线和展开优化。
    10,最终的优化情况总结如下。
    在这里插入图片描述

    11,重新进行函数综合,查看综合报告如下。
    在这里插入图片描述

    在这里插入图片描述

    12,分析。
    同未优化相比,优化过后的函数综合后生成的模块的运行时钟大大减小。端口的接口类型也变为了axi_lite端口。但资源占用率有所增加,也体现了用资源换速度的设计理念。在这里插入图片描述

    Step 5: 综合结果文件

    综合完成后,在各个solution的syn文件夹中可以看到综合器生成的RTL代码。包括systemc,VHDL,Verilog。

    在这里插入图片描述

    Step 6: 导出IP

    在菜单里Solution>Export TL,设置如下,点击ok。

    在这里插入图片描述

    IP封装完成后,会在impl文件夹中输出ip文件夹,其中包含了RTL代码(hdl),模块驱动(drivers),文档(doc)等信息,其中包含一个压缩包文件,是用于建立vivado工程所用的IP压缩包。

    在这里插入图片描述

    Step 7: 总结

    本文重点讲解了hls软件的使用方法和优化方法,在C语言模块设计上没有重点讲解。在掌握了hls软件的基本用法和优化方法后,接下来就可以设计更加复杂的C语言模块,进行rtl综合,加快设计开发的速度。

    展开全文
  • QPSK-Vivado-HLS
  • Vivado® 高层次综合(HLS)在所有 Vivado HLx 版本中以免费升级形式提供,可以实现直接使用 C,C++ 以及 System C 语言规范对赛灵思可编程器FPGA件进行编程,无需手动创建 RTL,从而可加速 IP 创建。本文档为其官方...
  • 一文了解Vivado HLS

    千次阅读 2021-03-05 19:58:12
    Xilinx 推出的 Vivado HLS 工具可以直接使用C、C++或 System C 来对 Xilinx 系列的 FPGA 进行编程,从而提高抽象的层级,大大减少了使用传统 RTL描述进行 FPGA 开发所需的时间。 一、高层综合简介 如图 1.1.1 所示...

    以下内容摘自正点原子的:《领航者 ZYNQ 之 HLS 开发指南》

    为了尽快把新产品推向市场,数字系统的设计者需要考虑如何加速设计开发的周期。设计加速主要可以从“设计的重用”和“抽象层级的提升”这两个方面来考虑。Xilinx 推出的 Vivado HLS 工具可以直接使用C、C++或 System C 来对 Xilinx 系列的 FPGA 进行编程,从而提高抽象的层级,大大减少了使用传统 RTL描述进行 FPGA 开发所需的时间。

    一、高层综合简介

    在这里插入图片描述
    如图 1.1.1 所示,FPGA 设计中从底层向上一共存在着四种抽象层级,依次为:结构性的、RTL、行为性的和高层。其中最底层的抽象(结构性的)涉及到对底层硬件单元直接的例化,比如逻辑门,甚至是更底层的 LUT 或者触发器。设计者更常用的是在“寄存器传输级(Register Transfer Level,RTL)” 进行设计,这个层级的抽象隐藏了底层的细节,是在描述寄存器和寄存器之间可执行的操作。更上层的“行为性的”描述是对电路的算法描述,也就是描述电路表现出什么样的功能(行为),而不是描述每个寄存器该如何进行操作。

    前面介绍的几种抽象层级都是在使用硬件描述语言 HDL 进行设计,可以看出,随着抽象层级的提升,设计最终在硬件上实现的细节逐渐被弱化。而本章重点介绍的“高层”设计方法则直接使用高级语言,如C/C++进行设计,然后由 Vivado HLS 编译器将 C 代码综合成 HDL 描述,最后再进行逻辑综合得到网表,这个网表最终会被映射到具体的 FPGA 器件上。

    就像 C 语言或者其他高级语言针对不同的处理器架构有着不同的编译器,Xilinx Vivado High-Level Synthesis(高层综合,HLS)工具同样是一种编译器,只不过它是用来将 C 或者 C++程序部署到 FPGA 上,而不是部署到传统的处理器上。

    在 Vivado HLS 中可以使用三种语言进行设计开发,分别是 C、C++ 和 SystemC。

    二、HLS 设计流程

    Vivado HLS 的功能简单地来说就是把 C、C++ 或 SystemC 的设计转换成 RTL 实现,然后就可以在Xilinx FPGA 或 Zynq 芯片的可编程逻辑中综合并实现了。需要注意的是,这里我们说的使用 C/C++完成的设计与运行在处理器(ZYNQ 中的 ARM 处理器或 MicroBlaze 软核处理器)中的软件代码是截然不同的。在 HLS 中,所有的 C 设计都是要在可编程逻辑中实现的,也就是说,我们仍然是在进行硬件设计,只不过使用的不再是硬件描述语言。

    使用 Vivado HLS 进行设计的流程如下图所示:
    在这里插入图片描述
    HLS 设计的主要输入是一个 C/C++/SystemC 设计,以及一个基于 C 的测试集(TestBench)。我们首先要知道 C 语言的本质就是函数,那么这个测试集就是用于验证 C 设计中的函数,验证过程需要一个“黄金参考”。这个“黄金参考”类似于一个标准答案,用来和 C 设计中函数所产生的输出做比对。

    在对 HLS 设计进行综合之前,我们要先对其进行“功能性验证”,也就是 C 仿真,其目的是验证 HLS 输入的 C 代码的功能是否正确。验证的方式就是在 TestBench 中调用 C 设计的函数,然后将其输出与“黄金参考”进行比对,如果与黄金参考有差异就需要先对 C 设计进行修改调试。

    接下来就是对设计进行高层综合,即 HLS 过程本身。该过程涉及到分析和处理基于 C 的代码,加上用户所给出的指令和约束,来创建 RTL 描述。高层综合结束后会产生一组输出文件,包括以 Veilog 或者VHDL 语言编写的 RTL 设计文件。

    综合过程结束后得到的 RTL 模型,可以在 Vivado HLS 中进行 C/RTL 协同仿真,来进一步验证综合得到的 RTL 设计的正确性。在这个过程中 Vivao HLS 会自动产生一个测试集为 RTL 设计提供输入,然后拿它的输出与预期的值做比对。C 功能性验证和 C/RTL 协同仿真的区别如下图所示:

    在这里插入图片描述
    在图 1.2.2 左侧的功能性验证(C 仿真)中,原始测试集是用户输入的测试文件 TestBench。而右侧的C/RTL 协同仿真所需的 RTL 测试集是由 Vivado HLS 自动产生的,这样就不再需要人工创建了,所产生的测试集包括了原始测试集和被测 RTL 模块之间的数据传递。

    除了对功能进行验证,我们还要评估 RTL 设计的实现和性能。比如,在 FPGA 中所需的资源的数量,设计的延迟、所支持的最高时钟频率等是否满足要求。如果不满足要求,那么就需要设计者通过修改指令和约束,然后再次进行高层综合,如图 1.2.1 中右侧的回路所示。一个设计可能要做多次 HLS 设计迭代,来找到“最佳 ”的解决方案。如果有必要,设计者也可以返回修改 C 设计代码,然后从头开始重新对设计进行验证。

    在设计被验证了之后,而且实现也满足了期望的设计目标,那么就可以集成进更大的系统里了。我们可以直接使用 HLS 过程所产生的 RTL 文件(即 VHDL 或 Verilog 代码),更方便的做法是使用 Vivado HLS 的 IP 打包功能。对 Vivado HLS 所产生的输出打包意味着 HLS 设计能够以 IP 核的形式引入其他 Xilinx 工具中,比如 Vivado 中的 IP 集成器。这两种类型的输出如下图所示:
    在这里插入图片描述

    三、 接口综合

    在做 HLS 的时候,设计者需要分析设计的两个主要方面:

    • 设计的接口,也就是它的顶层连接;
    • 设计的功能,也就是它所实现的算法;

    我们给出一个 HLS 设计中接口和功能的概念图,如图 1.3.1 所示。
    在这里插入图片描述
    在上图中,两端的绿色区域表示设计的输入和输出接口,其中展示了部分接口类型,如 RAM 接口、FIFO 接口,以及总线类型的接口等。这些接口可以是工具从代码中通过接口综合(Interface Synthesis)得到的,也可以由设计者手动指定具体的接口类型。

    图中间黄色的区域表示 HLS 设计具体能够实现的功能,对于不同的应用,其功能也各不相同。在 Vivado HLS 设计中,功能是从输入的代码中,经过算法综合(Algorithm Synthesis)的过程得到的。

    在这里我们先简单介绍一下接口综合。顾名思义,Interface Synthesis 指的是 HLS 设计中对接口的综合,综合出来的接口能够与系统中的其他模块通信,还有可能需要与系统中的处理器进行通信。

    这里接口的概念既包括端口(port),也包含所使用的协议。所有端口的细节(如类型、位宽和方向)是从 C/C++ 文件中顶层函数的参数和返回值里推断出来的;而协议是从端口的表现(行为)推断出来的。比如,最简单的接口可以是一条 1 比特的线(wire),而更复杂的接口,可能要用总线或 RAM 接口。接口综合能够推断出来的接口类型包括:线、寄存器、单向和双向握手信号、FIFO、存储器和总线等。

    下面我们给出一个简单的 C 设计的顶层函数,函数名为 find_average_of_best_X(),其参数如下图所示:

    在这里插入图片描述
    图 1.3.2 中函数内部工作的详细情况无关紧要,不过每个参数的读/写操作将决定综合出来的端口的方向。这个函数定义包含三个参数,数组“sample”和整数“X”是函数的输入,而 average 作为函数的输出。因此,简单来说,这三个函数参数要被 HLS 转换成两个输入接口和一个输出接口,如下图所示:
    在这里插入图片描述

    需要注意的是,图 1.3.3 只是一个简化了的接口示意图。根据所用的协议,这些接口可能包括数据端口自身以外的控制输入或输出,如下图所示:
    在这里插入图片描述
    图 1.3.4 是函数 find_average_of_best_X()经 HLS 综合出来的完整的 RTL 模块的接口图。从图中可以看到由函数的三个参数所综合出来的接口分别拥有了各自的协议,如 ap_memory 协议、ap_none 协议和 ap_vld协议。同时模块还多出来了一些端口,如 ap_clk 和 ap_rst 等,它们使用的是 ap_ctrl_hs 协议。这些协议决定了相应的接口是如何与系统中其他模块进行交互的,至于各协议具体的含义以及如何为接口选择其协议,我们将在后续的章节中介绍。

    四、算法综合

    算法综合关注的是设计的功能,即设计所期望的行为,它是由输入的 C 设计所描述的。算法综合从代码中推出各种运算操作,然后转换成一组 RTL 语句。

    算法综合包括三个主要阶段,依次是:

    1. 解析出数据通路和控制电路;
    2. 调度和绑定;
    3. 优化;

    解析出数据通路和控制电路

    HLS 的第一个阶段是分析 C/C++/SystemC 代码,并且解释所需的功能。Vivado HLS 从以下几个方面分析程序:逻辑和算法的运算、条件语句和分支、数组运算和循环等。

    所产生的实现会具有一个数据通路元件,一般还会有一个控制元件。需要澄清的是,这里的“数据通路”处理指的是在数据样本上作的运算,而“控制”是需要协同数据流处理所需的电路。算法的本质定义出数据通路和控制元件,设计者可以在 HLS 中采取专门的步骤来最小化控制元件的复杂度。

    调度和绑定

    HLS 是由两个主要过程组成的:调度(Scheduling)和绑定(Binding)。它们是交替进行的,彼此互相影响,如下图所示:
    在这里插入图片描述

    • 调度是把由 C 代码解释得到的 RTL 语句翻译成一组运算,每个运算都关联着一定的执行时间,以时钟周期为单位。这个阶段所作的决策,受时钟频率和不确定度、目标芯片的技术和用户所施加的指令所影响。

    • 绑定是调度好了的运算和目标芯片上的实际资源联系起来的过程。这些资源的功能和时序特征可能会影响调度,因此绑定信息会反馈给调度过程。比如使用 DSP48x 资源就表明关键路径比采用逻辑资源的方案要短。

    优化

    • 约束 :设计者可以对设计的某些指标加以限制。比如,可以指定最低的时钟周期。这样就能确保实现结果能够满足要集成进去的系统的要求。类似的,设计者可以选择约束资源的利用情况或其他的指标,从而优化应用的设计。

    • 指令:设计者可以通过指令对 RTL 的实现参数施加更具体的影响。有各种类型的指令,分别映射在代码的某些特征上,比如让设计者可以指定 HLS 引擎如何处理 C 代码中识别出来的循环或数组,或是某个特定运算的延迟。这能导致 RTL 输出的巨大改变。因此,具有了指令的知识,设计者就可以根据应用的需求来做优化了。

    五、 HLS 库

    Vivado HLS 中包含了一系列的 C 库(包括 C 和 C++),方便对一些常用的硬件结构或功能使用 C/C++进行建模,并且能够综合成 RTL。在 Vivado HLS 中提供的 C 库有下面几种类型:

    • 1、任意精度数据类型库
    • 2、HLS Stream 库
    • 3、HLS 数学库
    • 4、HLS 视频库
    • 5、HLS IP 库
    • 6、HLS 线性代数库

    在 HLS 设计中调用库中的函数可以大大提高开发效率。

    展开全文
  • 需要根据HLS端代码中卷积图片的大小调整SDK端代码中SIZE的值。2D卷积是对图像的一种处理,这篇文章主要是将计算部分使用HLS完成,在SDK中将测试数据传到HLS生成的计算IP中,查看返回的结果值(我的结果值貌似不太对...
  • 该方案为hls教程以及例子,按照教程都来一遍,相信你对hls有深入的理解
  • ug902-vivado-high-level-synthesis(1)_high_HLS_vivado的图像处理_ug902.
  • vivado HLS图像处理了解

    2018-06-06 17:14:17
    使用vivado HLS 进行图像处理,需要了解的一些基本知识!
  • Vivado HLS 入门实验

    万次阅读 多人点赞 2017-11-21 12:10:45
    当我们安装好Vivado 的...学习了一段时间的Zynq 7000, 找了一个HLS教程,就开始了如下入门实验,体验高级语言综合设计IP。Vivado HLS是Xilinx 推出的高层次综合工具,采用C/C++语言进行FPGA设计。HLS提供了一些样...

    当我们安装好Vivado 的时候,也同时装好了Vivado HLS.。 这是个什么东西?我就有一种想一探究的感觉。网上一查,Vivado High-Level Synthesis。学习了一段时间的Zynq 7000, 找了一个HLS的教程,就开始了如下入门实验,体验高级语言综合设计IP。Vivado HLS是Xilinx 推出的高层次综合工具,采用C/C++语言进行FPGA设计。HLS提供了一些样例方便大家熟悉其开发流程。另外关于HLS的使用介绍,Xilinx官方提供了2个重要开发文档ug871 和 ug902。里面详细介绍了包括怎么建立HLS 工程,怎么编写Testbench,怎么进行优化等问题。在HLS软件界面,在右侧有个directive, 里面列出了程序中所有用到的变量,函数和循环结构,点右键可以给其配置。

     对循环结构, 一般选择 unroll( 即展开循环) , 可以自己设定展开因子 factor。 为提高程序的并行化处理, 可以给函数选择 PIPELINE。 对应数组, 可以设置为 ARRAY_PARTITION,数组维数可以自己设定。 HLS 软件其实很智能的, 简单的结构, 一般软件自己会优化好。 每一个优化方案都保存在一个 Solution 里, HLS 可以创建多个 Solution, 用于比较不用的优化效果。

    如同软件开发都是从“ Hello Wrold! ” 进入编程的大门一样, 这一个实验我们就通过 HLS 封装一个移位流水灯的程序, 包括工程的创建, 仿真, 综合, 封装, 以及在硬件平台上的实现,来熟悉HLS的开发流程。

    本文参考了米联的zynq 修炼秘籍 网手版。

    实验代码和工程的下载:

    链接: https://pan.baidu.com/s/1WJ-EkX5lx14DClZc8UadkA 提取码: t8xh 

     

    1:HLS工程建立

    打开 Vivado HLS 开发工具, 单击 Creat New Project 创建一个新工程, 设置好工程路
    径和工程名, 一直点击 Next 按照默认设置,

     

    出现如下图所示界面,时钟周期 Clock Period 按照默认 10ns,Uncertaintly 和 Solution
    Name 均按照默认设置, 点击红色圆圈部分选择芯片类型, 然后点击 OK。下图示是选择好后的界面。

     

    下面是选择芯片型号的界面。根据你自己的硬件选择,我的是如图

     

    工程建立完后的界面是这样的。下面就是导入工程里用到的源文件。

     

    需要在工程添加3个源文件。都可以在文件开头介绍的下载地址下载。右键点击source , Add Files 分别添加shift_led.cpp 和 shift_led.h。 右键点击Test Bench , Add Files 添加Test_shift_led.cpp.

    添加完成后效果如下:

    shift_led.h 代码内容:

    #ifndef _SHIFT_LED_H_
    #define _SHIFT_LED_H_
    //
    #include "ap_int.h"
    //#define MAX_CNT 10000/2  //仿真时可以用这个代替下面的行介绍仿真等待时间
    #define MAX_CNT 100000000/2
    #define SHIFT_FLAG  MAX_CNT-2

    //typedef int led_t;
    typedef ap_fixed<4,4> led_t; // 1st: total width. 2nd: integer width
    void shift_led(led_t *led_o,led_t led_i);
    #endif

     

    shift_led.cpp 代码内容:

    #include "shift_led.h"
    void shift_led(led_t *led_o,led_t led_i)
    {
        led_t tmp_led=led_i;
        int i;    //for cycle variables
        for(i = 0;i < MAX_CNT;i++)
        {
            if(i==SHIFT_FLAG)
            {
                //tmp_led = ((tmp_led>>7)&0x01) + ((tmp_led<<1)&0xFE);//left shift 8
                tmp_led = ((tmp_led>>4)&0x01) + ((tmp_led<<1)&0xFE);//left shift 4
                *led_o = tmp_led;
            }
        }
    }

     

     

    Test_shift.led.cpp 代码内容:

    #include "shift_led.h"
    #include <stdio.h>

    using namespace std;
    int main()
    {
        led_t led_o;
        led_t led_i=0xfe;
        const int SHIFT_TIME =8 ;
        int i;
        for(i=0;i<SHIFT_TIME;i++)
        {
            shift_led(&led_o,led_i);
            led_i = led_o;
            char string[25];
            itoa((unsigned int)led_o & 0xf,string,2);
            fprintf(stdout,"shift_out=%s\n",string);
        }
    }

     

    2:工程综合

    工程综合前,需要设置 Top Function。

    点击 Project-> Project Settings ,也可以点击红箭所指那样的快捷键。

    出现如下界面 ,在Syntheses 界面下选择综合的顶层函数名。

     

    因为当前工程中只存在一个Solution, 我们选择Solution ->Run C Sytheses -> Active Solutions 进行综合,菜单旁有个快捷键的图标,所以也有快捷可以直接点取:

    在未经优化的情况下综合报告如图所示, 出现这个界面需要把上下条拉到合适位置, 并收起Latency (Clock cycles)。

     

    3: 优化和添加约束

    在原文中, led_t tmp_led=led_i; 最开始是int , 然后把他定义为4位整数。我这里一开始就是这样,也就没有什么优化了。

    但这里做一下他的约束添加,或者也是优化的内容。

    在主页面里,点击如下3出红箭,如果不是这个界面。选择文件 shift_led.cpp 文件, 选择 synthesis, 选择 directive。

     

    这里把led_o 设置为输出,右键点击led_o 出现Insert Drrective.. ,选择后如下界面:

    选择 INTERFACE  mode 选择 ap_ovld。

     

    同样对led_i 进行基本相同的工作,mode 选择 ap_vld。

     

    进行如上操作后,看看源程序出现的变化。还有Directive 的变化。

    优化和约束就说这么多。

     

    3: 仿真实现

    菜单Project -> Run C Simulation 或者点击快捷键(看菜单旁图示),就开始 C 仿真:

     

    仿真运行的情况是这样的:

     

    4:波形仿真(如果不熟悉ModelSim 就跳过这一节):

    在这之前需要运行Vivado 的编译仿真库,我是开始这个试验前就做了这个设置。


    打开Vivado 后,菜单 Tools -> Compile Simulation Libraries...

     

    出现对话框后,选择Simulator 为 ModelSim, 选择编译库的位置,看红箭。

    做好设置后, 点击Compile 就开始生成仿真库。

     

    如果做好了上面的仿真库编译准备,就可以开始看波形仿真了。

    菜单Solution -> Run C/RTL Cosimulation 运行C协同仿真。做了如图所示选择。

    运行C 协同仿真一段时间后,就可以防线在solution 1目录下多了一个sim 文件夹,在其verilog 文件夹下看到生成的波形文件shift_led.wlf 文件。

    利用ModelSim 打开该文件。在Objects 下选择需要显示的波形信号, Add  wave 到波形显示里。

     

    波形显示就是这样的。

    这就是波形仿真。

     

    5: HLS代码封装

    通过前面的实验,我们进行了HLS的工程创建,仿真,但这只是把算法实现从C 到RTL的转换。下面我们开始把其打包成IP, 在硬件平台上进行测试,也方便Vivado 进行调用,应用。

    菜单 Solution -> Export RTL 也可以点快捷(菜单图示)。

     

    在弹出的对话框中,点击Configuration 对一些参数进行输入,修改,然后点击OK。

    Configuration 的对话框设置。

     

    点击2次OK 之后,就开始IP 打包封装。

    运行结束后,就在solution1 目录下多了一个impl 文件夹,并且在0等待一段时间后在 solution1 目录下多了一个 impl 文件夹, 并且在ip 文件夹中生成了一个压缩包,这就是我们需要的打包好的IP。

     

    6 测试和应用:

    打开Vivado, 新建一个工程,工程名为test_shift_led。

    在Project Manager 中点击 Project Settings。

     

    在这解压刚才建立的IP 压缩包到一个新建的文件夹里,这是在文件管理器里完成的。

    选择IP 设置区的 Repository Manager 页面,然后点击+号, 下面图示是添加后的结果。

     

    进行了以上设置后,开始添加我们的IP包。

    点击Project Manager 下的IP Catalog 。 在右边的IP Catalog 里点开User Repository,然后选择我们建立的IP, 显示的是shifted_led_4bits。这和我们添加其他的ip 是一样的。

     

    可以设置下IP, 名字为shift_led_0

     

    在这个对话框里选择Generate

     

    现在右键 Design Sources ,添加shift_led.v 文件,可以在下载链接出获取。右键Constraints,添加led
    的约束文件。特别注意这个约束文件必须和你硬件的led 引脚定义一致。

    看看下图,ip取名和程序中必须一致,就是左边和右边。

     

    shift_led.v 的代码如下(如果不想下载,也可以复制):


    `timescale 1ns / 1ps
    module shift_led
      #(
        parameter  DATA_WIDTH  = 4
        )
       (
        input                        i_clk,
        input                        i_rst_n,
        output  reg [DATA_WIDTH-1:0] led
        );

    reg             [1:0]  cnt      ;
    reg  [DATA_WIDTH-1:0]  led_i_V  ;
    wire                   ap_start ;
    wire                   led_i_vld;
    wire [DATA_WIDTH-1:0]  led_o_V  ;

    always@(posedge i_clk or negedge i_rst_n)begin
        if(i_rst_n == 1'b0)
            cnt <= 2'd0;
        else if(cnt[1]==1'b0)
            cnt <= cnt + 1'b1;
    end
            
    always@(posedge i_clk or negedge i_rst_n)begin
        if(i_rst_n == 1'b0)
            led_i_V <= 2'd0;
        else if(cnt[0]==1'b1)
            led_i_V <= 8'h1;//
        else if(led_o_vld == 1'b1)
            led_i_V <= led_o_V;
    end

    always@(posedge i_clk or negedge i_rst_n)begin
        if(i_rst_n == 1'b0)
            led <= 1'b0;
        else if(led_o_vld == 1'b1)
            led <= led_o_V;
    end
            
    assign ap_start  = cnt[1];
    assign led_i_vld = cnt[1];

    shift_led_0 u_shift_led_0(
                              .led_o_V_ap_vld  (led_o_vld),// output wire led_o_vld
                              .led_i_V_ap_vld  (led_i_vld),// input wire led_i_vld  
                              .ap_clk          (i_clk    ),// input wire ap_clk          
                              .ap_rst          (~i_rst_n ),// input wire ap_rst          
                              .ap_start        (ap_start ),// input wire ap_start        
                              .ap_done         (         ),// output wire ap_done        
                              .ap_idle         (         ),// output wire ap_idle        
                              .ap_ready        (         ),// output wire ap_ready       
                              .led_i_V         (led_i_V  ),// output wire [7 : 0] led_o_V
                              .led_o_V         (led_o_V  ) // input wire [7 : 0] led_i_V
                              );

    endmodule

     

    zynq.xdc 文件内容如下:

    set_property IOSTANDARD LVCMOS33 [get_ports i_clk]
    set_property IOSTANDARD LVCMOS33 [get_ports i_rst_n]
    set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}]
    set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}]
    set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}]
    set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}]
    set_property PACKAGE_PIN M14 [get_ports {led[0]}]
    set_property PACKAGE_PIN M15 [get_ports {led[1]}]
    set_property PACKAGE_PIN K16 [get_ports {led[2]}]
    set_property PACKAGE_PIN R19 [get_ports {led[3]}]
    set_property PACKAGE_PIN U18 [get_ports i_clk]
    set_property PACKAGE_PIN R18 [get_ports i_rst_n]

     

    下面就和你硬件板提供的 FPGA led 实验程序一样了。综合,执行,生成流文件,下载运行。

    你的led 应该流水运行了。

    展开全文
  • VIVADO HLS视频教程

    2020-03-14 16:29:17
    VIVADO HLS教程: https://mp.weixin.qq.com/mp/homepage?__biz=MzIwNTY4NzM4OQ==&hid=1&sn=797d5e62e3fdb7ddd75f6793d9505bea&scene=18#wechat_redirect 目前更新内容如下,VX扫码关注获取更多内容!...
  • FPGA开始学习verilog、vivado HLS

    千次阅读 热门讨论 2018-05-24 16:44:20
    为什么就没有一个详细的教程vivado HLS怎么装呢?倒是有一大把vivado怎么装。 问题已经解决:原来并不是选择第几个Edition的问题,其实之前我都装成功了,只是不要在/opt/xilinx/下去找HLS,而要...
  • XILINX HLS + Vivado + SDK实现自定义IP通过AXI-Master协议从ARM(PS)传输数组到FPGA(PL)端RAM 简介 最近在使用XILINX ZYNQ的Soc板子做卷积神经网络(CNN)加速器,遇到了个问题:如何从PS传输批量权重到PL端? 网上...
  • Ubuntu16.04 下启动 Vivado HLS

    千次阅读 2018-12-25 12:00:20
    首先需要说明一下:今天遇到的这个问题给了我很大的感触,由于最近正在学习Zynq,从我在网上...在Ubuntu系统下,安装了Vivado系列软件,但是想去学习 Vivado HLS 软件的时候,却怎么也找不到 Vivado HLS软件的入口,...
  • Xilinx FPGA开发工具 ubuntu12.10下VivadoHLS安装笔记
  • vivado_hls_tutorial:使用HLS openCV函数的Xilinx Vivado基本HLS图像处理教程的源代码
  • xilinx vivado HLS 小记

    千次阅读 2018-08-07 19:10:18
    目前FPGA主要用于接口、通信等,HLS的出现使得opencv中的C代码通过综合直接部署到硬件。 HLS主要应用场景在与算法更密切的应用如DSP图像处理。 RTL:寄存器传输级 register transfer level verilog中分级是:系统...
  • 谷歌上说是HLS已经合并到Vivado文件夹中去了。vivado我的确已经安装好啦,跑了一个小例子,还出来了仿真结果!可是谁告诉我HLS在哪里? 已经自己解决! ![图片说明]...
  • Vivado Hls 设计分析

    千次阅读 2016-11-22 08:05:12
    1.在 command 里写入vivado_hls–f run_hls.tcl,如下图 2.再在 command 里写入vivado_hls –p dct_prj step2 查看source code结构 step3 C synthesis 点击C synthesis,得到report: ...
  • 本文整理自高亚军老师的Vivado HLS视频教程,完整的笔记在公众号“Quant_Times"中回复”HLS“即可获取。 System Generator & HLS数字信号处理教程暨FPGA高级数字信号处理教程: System Generator & HLS数字...
  • Vivado HLS学习资料汇总

    2020-05-12 09:55:13
    教程共11章,22个实验,可以帮助工程师理解HLS基本概念,掌握Vivado HLS工具设计流程、接口综合、任意精度数据类型、设计分析方法、设计优化方法、设计验证方法以及在IPI和System Generator中如何使用HLS的综合...
  • Vivado HLS 开发流程简介(高级综合)(FPGA)

    万次阅读 多人点赞 2018-04-18 09:18:38
    而在Xilinx新推出的高生产力设计流程中是以IP为核心的,把所有的模块都看做是IP,封装为IP,最主要的是IP的设计是基于C语言的,最后通过HLS将C语言代码转化为RTL,这能极大的加快设计进程。从这段时间的学习来看,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,684
精华内容 673
关键字:

hls教程vivado