FPGA_YOLO(四)用HLS实现循环展开以及存储模块

Vivado HLS(High-Level Synthesis,高层次综合)是赛灵思(Xilinx)在其 Vivado 设计套件 中提供的一款工具,用于将 高级编程语言(如 C、C++、SystemC) 直接转换为 硬件描述语言(HDL,如 VHDL 或 Verilog),从而快速生成可编程逻辑(如 FPGA 或 SoC)的硬件电路设计。


HLS 的核心作用

传统的硬件设计需手动编写 RTL(寄存器传输级)代码(如 Verilog/VHDL),而 HLS 允许开发者:

  1. 用更抽象的软件语言描述算法或功能。
  2. 自动生成优化的 RTL 代码,显著提升开发效率。
  3. 尤其适合算法密集型任务(如信号处理、图像处理、AI加速等)。

HLS 的主要功能与特点

  1. 支持高级语言
    用 C/C++/SystemC 描述硬件行为,无需手动编写 HDL 代码。

  2. 自动化硬件优化
    通过添加编译指令(如 #pragma HLS),指导工具优化流水线、并行性、资源分配等。

  3. 仿真与验证
    在软件层面验证功能正确性,减少后期硬件调试时间。

  4. 与 Vivado 无缝集成
    生成的 RTL 可直接用于 Vivado 进行综合、布局布线,并生成比特流文件下载到 FPGA。

  5. 灵活生成 IP 核
    输出为可重用的 IP 核,方便在更大系统中调用。


HLS 的典型应用场景

  • 算法加速:将计算密集型算法(如矩阵运算、加密解密)硬件化,提升性能。
  • 快速原型开发:软件工程师无需精通 HDL 即可参与 FPGA 开发。
  • 异构计算:在 FPGA 上实现与 CPU/GPU 协同的定制加速模块。
  • 复杂控制逻辑:简化状态机、接口协议(如 AXI)的开发。

HLS 的优势 vs 传统 RTL 开发

优势说明
开发速度快减少手动编码和调试时间。
易于维护修改软件代码后重新综合即可。
跨平台复用C/C++ 代码可同时用于软件和硬件。
降低门槛软件工程师也能参与硬件开发。

适用人群

  • 需要硬件加速的算法工程师。
  • 希望快速实现 FPGA 功能的开发团队。
  • 希望减少 HDL 编码工作的硬件工程师。

 一:(两个向量对应元素相加工程)

1:创建工程 

 2  加法运算创建文本 写代码

点击综合 将c语言转化成verilog

加法运算代码如下

 

#include "vector_add.h"


#define MAXNUM 50000
void vertor_add_top (float A[MAXNUM] , float B[MAXNUM] , float C[MAXNUM]) {
	for (int i=0 ; i <MAXNUM ; i++)
		C[i] =A[i] +B[i];
}

 会报错

 将文件设置为顶层

 

 依次点击即可将刚刚写的设置为顶层

 3:分析报告

 如上图

这依次是布局的时钟(我认为就是写代码然后映射verilog的时间),目标的时间10,预估的时间7.177ns 

 总的时间 从开始输入到输出的时间400001 代表多少个时钟周期,一个时钟周期7.177ns,400001*7.177/10^9  大约3ms能够计算完50000个浮点数相加。

 下图是资源占用情况

 3.1 DSPLUTFF是什么

    在 FPGA/SoC 设计中,DSPLUTFF 是三种核心硬件资源的缩写,它们直接影响设计的性能、功耗和资源占用率。以下是它们的定义和作用:


1. DSP(Digital Signal Processor,数字信号处理器块)
  • 用途
    专为高效执行 数学运算(乘法、乘累加、浮点运算等) 设计的硬件模块。
    适用于信号处理、滤波器、AI加速、矩阵运算等场景。

  • 特点

    • 高并行性:单时钟周期完成乘法或乘累加(MAC)。
    • 低延迟:比用 LUT/FF 手动搭建等效电路更快更省资源。
  • 示例
    实现 C = A * B + C 的乘累加操作时,优先占用 DSP 资源,而非 LUT/FF。

  • FPGA中的位置
    DSP 块通常以阵列形式分布在 FPGA 的逻辑单元中。


2. LUT(Look-Up Table,查找表)
  • 用途
    FPGA 中最基础的 组合逻辑单元,用于实现任意逻辑函数。
    相当于一个真值表,通过配置存储的值定义输入到输出的映射关系。

  • 结构

    • 通常为 4~6 输入、1 输出的可编程查找表(如 Xilinx 的 6 输入 LUT)。
    • 可分割为更小的 LUT 以实现更复杂的逻辑。
  • 特点

    • 灵活性高:可配置为实现与、或、非等逻辑功能。
    • 资源敏感:复杂逻辑会消耗大量 LUT,可能制约整体设计规模。
  • 示例
    实现一个加法器时,除了进位链外,逻辑运算由 LUT 完成。


3. FF(Flip-Flop,触发器)
  • 用途
    用于存储 时序逻辑的当前状态(1 比特数据)。
    通过时钟信号同步更新数据,是设计 寄存器、状态机、流水线 的关键元件。

  • 结构
    与 LUT 常绑定为 Slice(例如 Xilinx 的 CLB 每个 Slice 包含多个 LUT 和 FF)。
    FF 包括触发条件(如上升沿/下降沿)和复位/置位功能。

  • 特点

    • 时序控制:保证数据在时钟边沿稳定传输。
    • 资源平衡:FF 的利用率直接影响时序收敛(如时钟频率)。
  • 示例
    流水线架构中,每级流水线需要 FF 暂存中间结果。


4.三者的资源占用关系
  1. 算法决定资源分配

    • 计算密集型任务(如矩阵乘法)会消耗大量 DSP
    • 复杂逻辑和条件判断依赖 LUT
    • 时序控制和数据缓冲需要 FF
  2. 资源总量限制
    FPGA 芯片中 DSP/LUT/FF 的数量是固定的,设计需确保不超过目标芯片的可用资源。
    资源冲突会导致布局布线失败或降低时钟频率。

  3. 资源优化策略

    优化手段目的
    使用 DSP 代替 LUT 实现运算降低功耗,提升速度
    逻辑简化(如状态机优化)减少 LUT 和 FF 的消耗
    流水线设计平衡 FF 利用率与时钟频率
    代码重构(HLS中)避免生成冗余逻辑

5.在 Vivado HLS 中的应用
  • DSP 的使用
    若代码中的循环或函数包含乘法/累加操作,HLS 会优先调用 DSP,也可通过 #pragma HLS BIND_OP 强制指定实现方式。

  • LUT 与 FF 的平衡
    HLS 会根据代码生成组合逻辑(LUT)和时序逻辑(FF),通过 #pragma HLS PIPELINE 或调节时钟频率优化两者的分配。

  • 资源报告
    综合后查看资源利用率报告,分析是否需重构代码或调整约束。


6.总结
  • DSP 是高性能运算的“加速引擎”,用于数学密集型任务。
  • LUT 是实现灵活逻辑的基础单元,但易成为性能瓶颈。
  • FF 是时序逻辑的基石,影响设计的时钟频率和稳定性。
    合理规划和优化这三者的使用,是 FPGA 设计的关键!

 4.修改数据的类型

4.1 将float 改为 int

代码如下将float 改为 int

#include "vector_add.h"


#define MAXNUM 50000
void vertor_add_top (int A[MAXNUM] , int B[MAXNUM] , int C[MAXNUM]) {
	for (int i=0 ; i <MAXNUM ; i++)
		C[i] =A[i] +B[i];
}

 下面是报告

 

根据上图可以计算总得时间连1ms都不到

 4.2 将int改为自定义的定点型数据

代码如下:

#include "ap_fixed.h"

typedef ap_fixed<32 , 16 , AP_RND,AP_SAT> D32;
#include "vector_add.h"


#define MAXNUM 50000
void vertor_add_top (D32 A[MAXNUM] , D32 B[MAXNUM] , D32 C[MAXNUM]) {
	for (int i=0 ; i <MAXNUM ; i++)
		C[i] =A[i] +B[i];
}

这里是  typedef ap_fixed<32 , 16 , AP_RND,AP_SAT> D32;

typedef是自定义类型 名字叫ap_fixed 总共有32为 16位的整数,剩下的AP_RND为小数部分,AP_SAT这个是溢出类型应该,归一。

分析报告

可以算出时间比int多,但是比float少

总结:根据上述实验可以知道,int和自定义的类型没有用到dsp 浮点数用到了dsp、时间dloat > d32>int

二(并行加速)

1代码unroll

选中代码,然后点开右边的directive

然后找到for statement 右击 

 

 选择 将并行插入到代码中点击ok

 可以看到一部分并行一部分串行还是在串行

可以看到在read还是串行,应为ram 最大就是双端口,50个数很大所以得串行。

多了一个时钟周期 

 

 2整个完全展开  代码#pragma HLS ARRAY_PARTITION variable=A complete dim=1

完整代码如下

#include "vector_add.h"


#define MAXNUM 50
void vertor_add_top (D32 A[MAXNUM] , D32 B[MAXNUM] , D32 C[MAXNUM]) {
#pragma HLS ARRAY_PARTITION variable=A complete dim=1
#pragma HLS ARRAY_PARTITION variable=B complete dim=1
#pragma HLS ARRAY_PARTITION variable=C complete dim=1
	for (int i=0 ; i <MAXNUM ; i++){
		#pragma HLS UNROLL
C[i] =A[i] +B[i];
}
}

 操作:

如下找到ABC右击A

 找到ARRAY_PARTITION函数 然后compelte是整体展开

 

 报告分析

我们可以看到只用了组合逻辑电路,其他的都没有用到

 

 3.分块展开

#pragma HLS ARRAY_PARTITION variable=A block factor=2 dim=1

完整代码

#include "vector_add.h"


#define MAXNUM 50
void vertor_add_top (D32 A[MAXNUM] , D32 B[MAXNUM] , D32 C[MAXNUM]) {
#pragma HLS ARRAY_PARTITION variable=A block factor=2 dim=1
#pragma HLS ARRAY_PARTITION variable=B block factor=2 dim=1
#pragma HLS ARRAY_PARTITION variable=C block factor=2 dim=1
	for (int i=0 ; i <MAXNUM ; i++){
		#pragma HLS UNROLL
C[i] =A[i] +B[i];
}
}

选择block 分块因子为2

 报告分析

并不是只用了组合逻辑

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值