栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

vivado HLS c++

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

vivado HLS c++

1. c++基本知识
  1. 宏定义
    typedef int led_t;
    typedef int cnt32_t;//计数器

  2. using namespace std;
    itoa (int, char*, int);//函数

    # include 
    # include 
    
    void main (void)
    {
    int num = 100;
    char str[25];
    itoa(num, str, 10);
    printf("The number 'num' is %d and the string 'str' is %s. n" ,
    num, str);
    }
    

    第一个参数是要转换的数字,第二个参数是要写入转换结果的目标字符串,第三个参数是转移数字时 所用的基数。在上例中,转换基数为10。10:十进制;2:二进制…

  3. 指针

    1. 数据在内存中存储时是分块存储的。变量都是存储东西的

    2. 指针变量是存储了一个指针,int *p;同变量定义相同,定义了一个p变量,但他属于指针型,但他存储的是地址。

    3. 变量的指针和指针变量:前者是指变量的存储地址,指针理解为地址;后者是是一个变量,这个变量存储的是一个地址。

    4. 指针变量的定义

      int *p;
      

      使用
      p = &a;//p是一个指针变量,指针变量是存储地址的一块空间,这块空间是存储变量a的地址

    5. “&”和“*”的结合方向

2.1 HLS 设计流水灯实验【包括包括工程的创建,仿真,综合,封装,以及在硬件平台上的实现】
  1. 打开 Vivado HLS 开发工具,单击 Creat New Project 创建一个新工程,设置好工程路径和工程名,一直点击Next

  2. 选择芯片型号,zynq7010,点击next

  3. 右单击 Source,选择 New file,添加一个设计源文件。

  4. 功能文件shift_led.cpp 一定要带上后缀

    #include "shift_led.h"
    
    void shift_led(led_t *led_o,led_t led_i)
    {
    		led_t tmp_led;
    	cnt32_t i;//for循环的延时变量
    	tmp_led = led_i;
    	for(i = 0;i < MAX_CNT;i++)
    	{
    		if(i==SHIFT_FLAG)
    		{
    			tmp_led = ((tmp_led>>3)&0x1) + ((tmp_led<<1)&0xE);//左移
    			*led_o = tmp_led;
    		}
    	}
    }
    
    
  5. 添加一个 shift_led.h 文件

    #ifndef _SHIFT_LED_H_
    #define _SHIFT_LED_H_
    
    //加入设置int自定义位宽的头文件
    #include "ap_int.h"
    //设置灯半秒动一次,开发板时钟频率是100M
    //#define MAX_CNT 1000/2 //仅用于仿真,不然时间较长
    
    #define MAX_CNT 100000000/2
    #define SHIFT_FLAG MAX_CNT-2
    typedef int led_t;
    typedef int cnt32_t;//计数器
    
    //typedef ap_fixed<4,4> led_t; //第一个4代表总位宽,第二个4代表整数部分的位宽是4,则小数部分位宽=4-4=0
    //typedef ap_fixed<32,32> cnt32_t;
    
    void shift_led(led_t *led_o,led_t led_i);
    #endif
    
    
  6. 单击 Test Bench,添加一个名为 Test_shift_led.cpp 的测试文件,并添加如下程序

    #include "shift_led.h"
    #include 
    using namespace std;
    int main()
    {
    led_t led_o;
    led_t led_i = 0xE;// 1110
    const int SHIFT_TIME = 4;
    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);;//&oxF是为了取led_o的4位,转化为二进制数出
    	if(i == 2)
    		fprintf(stdout,"shift_out= 0%sn",string);//数据对齐,高位补零
    	else
    		fprintf(stdout,"shift_out= %sn",string);
    }
    }
    
2.2代码综合
  1. :点击 Project -> Project Settings在 Synthesis 界面下选择综合的顶层函数名

  2. 因为当前工程中只存在一个 Solution(解决方案),我们选择 Solution –> Run C Synthesis–>Active Solutions 或者直接点击 进行综合,等待一段时间,在未经优化的情况下综合报告如图所示,我们可以看到 FF 和 LUT 使用情况

  3. 单击方框选中的地方点击选择打开分析报告
  4. 在下图所示 1 的地方点击出现 2 所示的 shift_led,点击展开后可以看到 LED 输入和输出位宽均为 32 位,板载是 4 个 LED,那么该怎么去进行优化得到我们想要的结果呢?
2.3代码优化
  1. 点击 Synthesis 切换到工作空间主界面


    另外再进行端口约束。约束方法如下,双击打开 shift_led.cpp,在需综合的 shift_led.cpp 文件中的 Directive目录下的 led_o 上右键选择 Insert Directive。
    因为 led_o 是接口,所以 Directive 选择为 INTERFACE,Destination 选择为 Source File,那么有的会问了,这两个有什么区别吗?区别就是 Source File 是针对所有的 Solution 采用同一个优化手段,而 Directive File 是对当前的 Solution 有效,mode(optional)我们选为 ap_ovld,即输出使能。


    完成后重新综合,查看资源明显减少。
2.4程序仿真

仿真分为 C 代码仿真和 C/RTL 联合仿真。其中 C/RTL 联合仿真可以使用 Vivado 自带的仿真软件仿真,也可以使用第三方仿真软件 Modelsim 进行联合仿真。

C语言仿真

  1. 单击 Project 下的 Run C Simulation 或直接单击 开始 C 仿真

  2. 勾选 Optimized Compile,加载编译仿真窗口

  3. 等待一段时间,仿真结果如下,我们可以看到数据循环左移了一位,达到了我们想要的实验效果

  4. 加载调试窗口,出现调试界面,可以添加断点观察调试信号数据



    C/RTL 联合仿真
    vivado自带仿真工具

    1. 单击 Solution 下的 Run C/RTL cosimulation 运行协同仿真

    2. 设置如下,点击 OK,开始仿真。Dump Trace 选择 all,可以查看到 RTL 仿真波形

    3. 点击图标,打开波形窗口,添加观察信号

      这个过程非常花时间需要耐心等待



    这可是非常卡卡卡卡!

  5. 波形文件位置

使用 Modelsim 联合仿真

  1. 单击 Solution 下的 Run C/RTL cosimulation 运行协同仿真

  2. 运行协同仿真一段时间后,我们可以发现在 solution1 目录下多了一个 sim 文件夹,在其 verilog 文件夹下可以看到生成的波形文件 shift_led.wlf

  3. 通过 modelsim 打开该文件,看关键接口的时序。首先打开 modelsim,然后单击 File 菜单下的 open命令

  4. 在 objects 设置区,按住 ctrl 键选中要查看波形的信号, Add wave

2.5HLS封装

HLS 只是把你的算法实现从 C 到 RTL的转化,而不能在硬件平台上进行测试,需要把 HLS 工程打包成一个 IP 以便于 Vivado 进行调用。

  1. 单击 Solution 菜单下的 Export RTL 或直接单击 导出 RTL 级

  2. 点击 configuration 对一些参数进行补充

    如果出现这种报错,把电脑时钟设置成2019年以前就能通过编译

  3. 等待一段时间后在 solution1 目录下多了一个 impl 文件夹,并且在 ip 文件夹生成了一个压缩包,这就是打包好的 IP,在 Vivado 中进行使用

2.6硬件平台
  1. 按照zynq新建工程

  2. 完成后,压缩包解压然后,选择 IP->Repository,进入添加 IP 设置区、

    设置IP名字,在顶层中例化IP

  3. 创建一个名为 shift_led 的 Verilog 文件

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 <= 4'd0;
 else if(cnt[0]==1'b1)
 led_i_V <= 4'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 [3 : 0] led_o_V
  .led_o_V (led_o_V ) // input wire [3 : 0] led_i_V 
  );
 endmodule
 
 
  1. 引脚约束,下载调试
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/883082.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号