热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

HLS编程环境入门——LED灯闪烁

目录一、HLS简介二、点亮LED灯——入门级HLS程序(一)、仿真1、新建工程2、添加源文件3、添加c仿真文件4、进行C仿真与C综合(二)、烧录1、导出HLS工程生成的IP核2、v

目录

      • 一、HLS简介
      • 二、点亮LED灯——入门级HLS程序
        • (一)、仿真
          • 1、新建工程
          • 2、添加源文件
          • 3、添加c仿真文件
          • 4、进行 C 仿真与 C 综合
        • (二)、烧录
          • 1、导出 HLS 工程生成的 IP 核
          • 2、vivado工程导入ip
          • 3、在 IP Catalog 中选中由 HLS 生成的 IP,双击并生成该 IP
          • 4、烧录
          • 5、结果

一、HLS简介

1、HLS是什么
HLS是高层综合(High level Synthesis)
是将C或者c++语言编译为FPGA能够读懂和运行的RTL级别的语言
2、与VHDL或者verilog的比较
优点:用高级语言完成期望在硬件电路上实现的功能,更加抽象和容易实现。
缺点:尽管是用高级语言描述实现在硬件电路上实现功能,但会有很多限制,例如动态分配内存等函数或定义的禁用,也有很多不足,例如循环的优化始终是个大难题。
3、HLS关键技术
将高级语言转化为RTL电路;循环优化,并行处理

二、点亮LED灯——入门级HLS程序

(一)、仿真

环境:xilinx20.2
板子: Z7-Lite7020

1、新建工程

《HLS编程环境入门——LED灯闪烁》
《HLS编程环境入门——LED灯闪烁》
选择定成函数 这里直接next
《HLS编程环境入门——LED灯闪烁》
添加c仿真文件,testbench文件,next
《HLS编程环境入门——LED灯闪烁》
《HLS编程环境入门——LED灯闪烁》
《HLS编程环境入门——LED灯闪烁》
这里选择xc7z020clg400-2,对应Z7-Lite7020
《HLS编程环境入门——LED灯闪烁》
《HLS编程环境入门——LED灯闪烁》
新建工程完成页面
《HLS编程环境入门——LED灯闪烁》

2、添加源文件

《HLS编程环境入门——LED灯闪烁》
《HLS编程环境入门——LED灯闪烁》
同样方法添加头文件
《HLS编程环境入门——LED灯闪烁》
led.h代码

#ifndef _SHIFT_LED_H_
#define _SHIFT_LED_H_
#define CNT_MAX 100000000
//#define CNT_MAX 100
#define FLASH_FLAG CNT_MAX-2
typedef int led_t;
typedef int cnt_t;
void flash_led(led_t *led_o , led_t led_i);
#endif

其中计数最大值 CNT_MAX 100000000 是在 100M 时钟频率下计数一秒钟所需要的计数次数
FLASH_FLAG 是 LED 闪烁的标志,当计数到该值
时,LED 发生变化
flash_led是该工程需要设计的定成函数
后续优化代码
led.h

#ifndef _SHIFT_LED_H_
#define _SHIFT_LED_H_
#include "ap_int.h"
#define CNT_MAX 100000000
//#define CNT_MAX 100
#define FLASH_FLAG CNT_MAX-2
//typedef int led_t;
//typedef int cnt_t;
typedef ap_int<1>led_t;
typedef ap_int<32>cnt_t;
void flash_led(led_t *led_o , led_t led_i);
#endif

led.h代码

#include "led.h"
void flash_led(led_t *led_o , led_t led_i){
cnt_t i;
for(i=0;i<CNT_MAX;i++){
if(i==FLASH_FLAG){
*led_o = ~led_i;
}
}
}

变量 i 计数到 FLASH_FLAG 时 led_o 的状态发生变化

3、添加c仿真文件

《HLS编程环境入门——LED灯闪烁》
《HLS编程环境入门——LED灯闪烁》
test_led.cpp代码

#include "led.h"
#include
int main(){
led_t led_i=0x01;
led_t led_o;
const int SHIFT_TIME = 4;
int i;
for(i=0;i<SHIFT_TIME;i++){
flash_led(&led_o , led_i);
led_i = led_o;
printf("shift_out is %d \n",(int)(led_o&0x01));
}
}

后续优化设置
《HLS编程环境入门——LED灯闪烁》
《HLS编程环境入门——LED灯闪烁》
《HLS编程环境入门——LED灯闪烁》
《HLS编程环境入门——LED灯闪烁》
《HLS编程环境入门——LED灯闪烁》

4、进行 C 仿真与 C 综合

选择 flash_led 作为顶层函数
《HLS编程环境入门——LED灯闪烁》
《HLS编程环境入门——LED灯闪烁》
c仿真
《HLS编程环境入门——LED灯闪烁》
c仿真结果与预期相符
《HLS编程环境入门——LED灯闪烁》
c综合
《HLS编程环境入门——LED灯闪烁》
结果成功
Latency 指的是,设计电路完成一次任务需要的时间
Interval 指的是两次任务之间的时间间隔
FF触发器数量:62
LUT查找表数量:105
《HLS编程环境入门——LED灯闪烁》
联合仿真
《HLS编程环境入门——LED灯闪烁》
《HLS编程环境入门——LED灯闪烁》
结果:和c仿真结果一致
《HLS编程环境入门——LED灯闪烁》

(二)、烧录

1、导出 HLS 工程生成的 IP 核

《HLS编程环境入门——LED灯闪烁》
不做改变,直接OK
《HLS编程环境入门——LED灯闪烁》
导出的 IP 核将在 Solution 这个文件夹中可以找到
《HLS编程环境入门——LED灯闪烁》

2、vivado工程导入ip

打开vivado,新建工程
《HLS编程环境入门——LED灯闪烁》
《HLS编程环境入门——LED灯闪烁》
《HLS编程环境入门——LED灯闪烁》
《HLS编程环境入门——LED灯闪烁》
《HLS编程环境入门——LED灯闪烁》
《HLS编程环境入门——LED灯闪烁》
《HLS编程环境入门——LED灯闪烁》
添加ip
《HLS编程环境入门——LED灯闪烁》
定位到solution
《HLS编程环境入门——LED灯闪烁》
添加成功后应用
《HLS编程环境入门——LED灯闪烁》
添加成功
《HLS编程环境入门——LED灯闪烁》

3、在 IP Catalog 中选中由 HLS 生成的 IP,双击并生成该 IP

《HLS编程环境入门——LED灯闪烁》
《HLS编程环境入门——LED灯闪烁》
向工程中添加一个新的文件,用于完成本次实验
《HLS编程环境入门——LED灯闪烁》
《HLS编程环境入门——LED灯闪烁》
《HLS编程环境入门——LED灯闪烁》
《HLS编程环境入门——LED灯闪烁》
led.v是代码将生成的 HLS IP 例化进工程当中


//
// Company:
// Engineer:
//
// Create Date: 2021/05/22 14:40:22
// Design Name:
// Module Name: led
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//


`timescale 1ns / 1ps
module flash_led(
input wire clk ,
input wire rst_n ,
output wire led_o
);

wire rst ;//同步复位
wire ap_ready ;//当前可以接收下一次数据
reg ap_start ;//IP 开始工作
reg led_i_vld ;//输入数据有效
wire led_o_vld ;
reg led_i ;//输入的 led 信号
wire led_o_r ;
wire ap_done ;
wire ap_idle ;
reg [1:0] delay_cnt ;
assign rst = ~rst_n ;
assign led_o = led_o_r ;

//----------------delay_cnt------------------
always @(posedge clk) begin
if (rst==1'b1) begin
delay_cnt <= 'd0;
end
else if(delay_cnt[1]==1'b0) begin
delay_cnt <= delay_cnt + 1'b1;
end
end

//----------------ap_start------------------
always @(posedge clk) begin
if (rst==1'b1) begin
ap_start <= 1'b0;
end
else if(delay_cnt[1]==1'b1)begin
ap_start <= 1'b1;
end
end

//----------------led_i_vld------------------
always @(posedge clk) begin
if (rst==1'b1) begin
led_i_vld <= 1'b0;
end
else if(delay_cnt[1]==1'b1)begin
led_i_vld <= 1'b1;
end
end

//----------------ap_i------------------
always @(posedge clk) begin
if (rst==1'b1) begin
led_i <= 1'b0;
end
else if(led_o_vld==1'b1)begin
led_i <= led_o_r ;
end
end


flash_led_0 inst_flash_led (
.led_o_ap_vld(led_o_vld), // output wire led_o_V_ap_vld
.led_i_ap_vld(led_i_vld), // input wire led_i_V_ap_vld
.ap_clk(clk), // input wire ap_clk
.ap_rst(rst), // input wire ap_rst
.ap_start(ap_start), // input wire ap_start
.ap_done(ap_done), // output wire ap_done
.ap_idle(ap_idle), // output wire ap_idle
.ap_ready(ap_ready), // output wire ap_ready
.led_o_V(led_o_r), // output wire [0 : 0] led_o_V
.led_i_V(led_i) // input wire [0 : 0] led_i_V
);

endmodule

接下来是添加约束文件

《HLS编程环境入门——LED灯闪烁》
《HLS编程环境入门——LED灯闪烁》
top_pin.xdc

##############LED define##################
set_property PACKAGE_PIN P15 [get_ports { led_o}]
set_property IOSTANDARD LVCMOS33 [get_ports { led_o}]
##############Reset define##################
set_property PACKAGE_PIN P16 [get_ports { rst_n}]
set_property IOSTANDARD LVCMOS33 [get_ports { rst_n}]
##############50M CLK define##################
create_clock -period 20.000 -name clk -waveform { 0.000 10.000} [get_ports clk]
set_property PACKAGE_PIN N18 [get_ports { clk}]
set_property IOSTANDARD LVCMOS33 [get_ports { clk}]

添加ila观察中间过程
《HLS编程环境入门——LED灯闪烁》
这个ip对应.v文件中的
《HLS编程环境入门——LED灯闪烁》
生成bit流文件
《HLS编程环境入门——LED灯闪烁》

4、烧录

完成后打开硬件烧录页面
《HLS编程环境入门——LED灯闪烁》
将板子连接电脑,点击自动连接就会自动寻找已连接的板子
《HLS编程环境入门——LED灯闪烁》
右键点击Program Device
《HLS编程环境入门——LED灯闪烁》
《HLS编程环境入门——LED灯闪烁》
这里就会自动将可烧录的程序填入,点击Program即可烧录
《HLS编程环境入门——LED灯闪烁》

5、结果

《HLS编程环境入门——LED灯闪烁》


推荐阅读
  • 题目描述:给定n个半开区间[a, b),要求使用两个互不重叠的记录器,求最多可以记录多少个区间。解决方案采用贪心算法,通过排序和遍历实现最优解。 ... [详细]
  • golang常用库:配置文件解析库/管理工具viper使用
    golang常用库:配置文件解析库管理工具-viper使用-一、viper简介viper配置管理解析库,是由大神SteveFrancia开发,他在google领导着golang的 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • C++实现经典排序算法
    本文详细介绍了七种经典的排序算法及其性能分析。每种算法的平均、最坏和最好情况的时间复杂度、辅助空间需求以及稳定性都被列出,帮助读者全面了解这些排序方法的特点。 ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • 本文基于刘洪波老师的《英文词根词缀精讲》,深入探讨了多个重要词根词缀的起源及其相关词汇,帮助读者更好地理解和记忆英语单词。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • c# – UWP:BrightnessOverride StartOverride逻辑 ... [详细]
  • 数据库内核开发入门 | 搭建研发环境的初步指南
    本课程将带你从零开始,逐步掌握数据库内核开发的基础知识和实践技能,重点介绍如何搭建OceanBase的开发环境。 ... [详细]
  • 在前两篇文章中,我们探讨了 ControllerDescriptor 和 ActionDescriptor 这两个描述对象,分别对应控制器和操作方法。本文将基于 MVC3 源码进一步分析 ParameterDescriptor,即用于描述 Action 方法参数的对象,并详细介绍其工作原理。 ... [详细]
author-avatar
EMBRACE-老王
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有