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

报告分析

并不是只用了组合逻辑

相关推荐
kisshuan1239614 小时前
Ghost卷积瓶颈轻量化改进YOLOv26双阶段压缩与残差学习协同突破
学习·yolo
WJSKad123514 小时前
DPCF双路径交叉融合改进YOLOv26多尺度特征融合精度与效率
yolo
房开民15 小时前
使用cuda核函数加速 yolov5后处理
yolo·macos·cocoa
WJSKad123515 小时前
Ghost瓶颈轻量化改进YOLOv26双路径特征生成与残差学习协同突破
学习·yolo
AAD5558889916 小时前
AAttn区域注意力机制改进YOLOv26特征感知与表达能力提升
人工智能·yolo·目标跟踪
kisshuan1239616 小时前
Focus空间通道转换改进YOLOv26特征浓缩与深度可分离卷积双重突破
yolo·机器学习·目标跟踪
kisshuan1239617 小时前
ERM增强残差融合模块改进YOLOv26多尺度特征融合精度与边缘检测能力
人工智能·深度学习·yolo
童话名剑1 天前
YOLO v3(学习笔记)
人工智能·深度学习·yolo·目标检测
南极星10051 天前
视觉项目(k230+opencv+yolo)--云台实时追踪项目
人工智能·opencv·yolo
子夜江寒1 天前
YOLO目标检测算法简介
算法·yolo·目标检测