0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

通过HLS封装一个移位流水灯的程序案例

454398 来源:csdn 作者:leon_zeng0 2020-10-14 15:17 次阅读

当我们安装好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 修炼秘籍 网手版。

实验代码和工程的下载

链接: http://pan.baidu.com/s/1c1BXkvm 密码:h2i2

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 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 {
if(i==SHIFT_FLAG)
{
//tmp_led = ((tmp_led>>7)&0x01) + ((tmp_led tmp_led = ((tmp_led>>4)&0x01) + ((tmp_led *led_o = tmp_led;
}
}
}

Test_shift.led.cpp 代码内容:

#include "shift_led.h"
#include

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_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 else if(cnt[1]==1'b0)
cnt end

always@(posedge i_clk or negedge i_rst_n)begin
if(i_rst_n == 1'b0)
led_i_V else if(cnt[0]==1'b1)
led_i_V else if(led_o_vld == 1'b1)
led_i_V end

always@(posedge i_clk or negedge i_rst_n)begin
if(i_rst_n == 1'b0)
led else if(led_o_vld == 1'b1)
led 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 应该流水运行了。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA设计
    +关注

    关注

    9

    文章

    428

    浏览量

    26671
  • Xilinx
    +关注

    关注

    71

    文章

    2172

    浏览量

    122388
  • C++
    C++
    +关注

    关注

    22

    文章

    2114

    浏览量

    73951
  • Vivado
    +关注

    关注

    19

    文章

    815

    浏览量

    66984
收藏 人收藏

    评论

    相关推荐

    #中国香河英茂科工#STC32G12K128#屠龙刀三.2 流水灯例程

    流水灯
    丙丁先生
    发布于 :2025年01月19日 14:19:35

    【正点原子STM32H7R3开发套件试用体验】流水灯

    工程,之后使用 Keil MDK IDE 编译代码,实现流水灯的项目流程。从配置过程中发现,系统核心具有极高的运行速率,STM32H7系列具有32位Arm Cortex®-M7内核,运行频率高达 600 MHz,因此可以更快速地运行项目程序,为实现更高速的采样频率提供了可
    发表于 12-28 18:51

    低成本单片机方案——触摸流水灯开关控制

    概述本方案旨在提供种基于低成本单片机的触摸流水灯开关控制解决方案。该方案结合了单片机技术、电容式触摸传感技术和LED驱动技术,实现了通过触摸操作控制流水灯的效果。
    的头像 发表于 12-26 16:37 294次阅读
    低成本单片机方案——触摸<b class='flag-5'>流水灯</b>开关控制

    基于51单片机的跑马灯/流水灯系统

    具体实现功能(1)9种LED流水灯模式通过按键进行切换,数码管显示流水灯模式。(2)通过加减按键可以切换每种LED流水灯的速度。仿真演示视频
    的头像 发表于 10-22 14:12 340次阅读
    基于51单片机的跑马灯/<b class='flag-5'>流水灯</b>系统

    优化 FPGA HLS 设计

    30 到 70 种用于综合和布局布线的设置。可能的组合太多了。可以编写脚本来创建不同的运行并尝试推荐的标准指令/策略。 最后挑战问题是计算能力不足。典型的嵌入式应用程序是在单台计算机
    发表于 08-16 19:56

    种在HLS中插入HDL代码的方式

    很多人都比较反感用C/C++开发(HLS)FPGA,大家第拒绝的理由就是耗费资源太多。但是HLS也有自己的优点,除了快速构建算法外,还有
    的头像 发表于 07-16 18:01 858次阅读
    <b class='flag-5'>一</b>种在<b class='flag-5'>HLS</b>中插入HDL代码的方式

    移位寄存器右移是怎么移位

    移位寄存器是种在数字电路和计算机科学中广泛使用的存储设备,它可以用来存储和传输数据。在移位寄存器中,数据可以通过移位操作来实现数据的传输和
    的头像 发表于 07-12 10:14 1837次阅读

    如何在esp32的程序体中指定变量的绝对地址,或者相对于程序首地址的固定偏移位置?

    请问下如何在esp32的程序体中指定变量的绝对地址,或者相对于程序首地址的
    发表于 06-21 08:12

    FPGA 实验流水灯模块

    实验流水灯模块 对于发展商而言,动土仪式无疑是最重要的任务。为此,流水灯实验作为低级建模II的动土仪式再适合不过了。废话少说,我们还是开始实验吧。 图1.1 实验建模图。 如图
    发表于 06-10 09:38

    单片机POV LED流水灯制作

    电子发烧友网站提供《单片机POV LED流水灯制作.docx》资料免费下载
    发表于 05-28 14:34 3次下载

    【紫光同创盘古PGX-Nano教程】——(盘古PGX-Nano开发板/PG2L50H_MBG324第三章)键控流水灯实验例程

    功能 3种流水灯模式有按键传递过来的计数控制切换,每一个LED的显示状态完整后进入下模式初始化。根据需求可得到如下信息: 输入信号:时钟,流水灯模式控制信号;出信号:8bit位宽的
    发表于 04-29 16:06

    【紫光同创盘古PGX-MINI-4K教程】——(盘古PGX-MINI-4K开发板/PGC4KD-6ILPG144第二章)LED 流水灯实验例程

    LED 以 0.5s 间隔接替闪烁 四:实验原理相比上一个 LED 闪烁的实现,只需要改变 LED 的状态。将 8 LED 灯流水式的点亮; 在 C 语言中做流水灯的实验需要用
    发表于 03-26 16:24

    什么是PLC循环移位指令 PLC循环移位的特点

    PLC循环移位指令包括循环左移指令和循环右移指令。在循环移位过程中,移出的位并不会丢失,而是会放回空出的位上,形成环形移位
    的头像 发表于 03-07 16:57 2356次阅读
    什么是PLC循环<b class='flag-5'>移位</b>指令 PLC循环<b class='flag-5'>移位</b>的特点

    51单片机流水灯制作

    流水灯是学习51单片机的基本项目,是我们对单片机IO口输出认识的基本项目。当然学会了花样流水灯也很好玩。 下面就分享种51单片机
    的头像 发表于 02-26 10:06 1741次阅读
    51单片机<b class='flag-5'>流水灯</b>制作

    如何优化HLS仿真脚本运行时间

    需求:由于自己目前 HLS 仿真脚本需要运行 1多小时,先打算通过打印时间戳的方式找出最耗时的部分,然后想办法优化。
    的头像 发表于 02-23 09:29 810次阅读