[X]关闭
1

S04-CH02 HLS设计流程shift_led实验

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

软件版本:VIVADO2017.4

操作系统:WIN10 64bit

硬件平台:适用米联客 ZYNQ系列开发板

米联客(MSXBO)论坛:www.osrc.cn答疑解惑专栏开通,欢迎大家给我提问!!

2.1 概述

      如同软件开发都是从“Hello Wrold!”进入编程的大门一样,这一章我们就通过HLS封装一个移位流水灯的程序熟悉HLS的开发流程,包括工程的创建,仿真,综合,封装,以及在硬件平台上的实现。通过本章,大家需要掌握HLS的基本开发流程,为下面的课程打下基础。

2.2工程创建、仿真及优化

2.2.1 工程创建

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

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

MZ7XA-7020、MZXB开发板型号选择设置

MZ7XA -7010、MZ7XA -MINI7010开发板型号选择设置

Step3:点击Finish,出现如下界面:

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

Step5:输入文件名和选择保存的路径,然后单击保存。

Step6:双击刚才添加的文件,添加如下程序。

#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;

}

}

}

Step7:按照同样的方法添加一个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

Step8:单击Test Bench,添加一个名为Test_shift_led.cpp的测试文件,并添加如下程序。

#include "shift_led.h"

#include <stdio.h>

 

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%s\n",string);//数据对齐,高位补零

else

fprintf(stdout,"shift_out= %s\n",string);

}

}

2.2.2 代码综合

Step1:点击Project -> Project Settings 出现下图,在Synthesis界面下选择综合的顶层函数名。

Step2:单击Browse指定工程的顶层文件,最后单击OK完成修改。

FF和LUT使用情况

Step4:我们单击方框选中的地方点击选择打开分析报告

Step5:在下图所示1的地方点击出现2所示的shift_led,点击展开后可以看到LED输入和输出位宽均为32位,我们板载是4个LED,那么该怎么去进行优化得到我们想要的结果呢?

2.2.3 代码优化

点击Synthesis切换到工作空间主界面。

        在shift_led.h文件中我们包含一个设置int自定义位宽的头文件"ap_int.h",我们使用ap_fixed()函数自定义int型的bit数,其函数原型为:

class ap_fixed: public ap_fixed_base<_AP_W_AP_Itrue_AP_Q_AP_O_AP_N>,那么这个函数怎么使用呢?它的定义如下:

        ap_fixed<M,N>,第一个M代表数据总位宽,N代表数据整数部分的位宽,那么小数部分的位宽即M – N;在下面的代码中,将

typedef int led_t;

typedef int cnt32_t;

替换成

typedef ap_fixed<4,4> led_t;

typedef ap_fixed<32,32> cnt32_t;

即可实现对端口数据位宽的约束。

      另外我们再进行端口约束。约束方法如下,双击打开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,即输出使能。

对led_i进行同样的约束,mode(optional)我们选为ap_vld。

添加后,查看shift_led.cpp,会发现多了两行代码

最终效果如下,我们再次综合,对比下进行约束以后的资源利用情况

对比发现,经过优化以后,资源利用率降低,这为以后我们对资源进行优化提供了一个参考思路。

2.2.4 仿真实现

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

2.2.4.1 C代码仿真

 

出现如下对话框,选项包括:

Lauch Debugger :编译C代码,自动打开调试窗口。

Build Only:C代码编译,但是模拟器不允许。

Clean Build:在编译代码之前从项目中删除任何现有的可执行文件和目标文件。

Optimized Compile:默认情况下,设计使用调试信息进行编译,允许在调试透视图中分析编译。此选项在编译设计时使用更高级别的优化工作,但会删除调试器所需的所有信息。 这会增加编译时间,但应减少模拟运行时间。

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

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

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


路过

雷人

握手

鲜花

鸡蛋
发表评论

最新评论

引用 缘起的风 2021-11-23 11:23
不全?看着看着突然结尾了?

查看全部评论(1)

本文作者
2019-9-17 09:56
  • 1
    粉丝
  • 3646
    阅读
  • 1
    回复

关注米联客

扫描关注,了解最新资讯

联系人:汤经理
电话:0519-80699907
EMAIL:270682667@qq.com
地址:常州溧阳市天目云谷3号楼北楼201B

关注米联客

扫描关注,了解最新资讯

联系人:汤经理
电话:0519-80699907
EMAIL:270682667@qq.com
地址:常州溧阳市天目云谷3号楼北楼201B

关注米联客

扫描关注,了解最新资讯

联系人:汤经理
电话:0519-80699907
EMAIL:270682667@qq.com
地址:常州溧阳市天目云谷3号楼北楼201B
热门评论
排行榜