HLS实践 - 03 - 接口优化设计(二)

简介: HLS实践 - 03 - 接口优化设计

分割RAM和FIFO接口


三种数组分割的方法 进行数组分割的三种方法如下,

Block:可以进行设置Block的方式进行分割,该分组方式是顺序分割的。

Cycllc:可以进行设置Cycllc的方式进行分割,该分组方式是轮序分割的。

Register:设置为register发方式,循环将会展开成完全并行。指令的参数设置为complete

性能评估对比:Block、Cycllc的性能基本一致,而Register(complete)的方式是最佳的。

将设计中的d_o进行分割,设置分割类型为Block,在 Vivado HLS Directive Editor 对话框中,将因子设置为 4。点击OK完成设置。

image.png

也可以对d_i进行添加分割指令,设置分割类型为Block,在 Vivado HLS Directive Editor 对话框中,将因子设置为2。点击OK完成设置。

image.png

完成插入指令后进行C综合。接口列表如下:

image.png

性能报告:

image.png

经过优化设计后,整体的执行延时降低,接口根据分割指令增加了相应的个数。

修改进行全分割


新建解决方案,修改成分割指令为完全分割。

image.png

在 Directive 选项卡中,选择 d_i 上的 RESOURCE 指令,用鼠标右键单击并选择 Remove Directive。 如果数组被划分为单独的元素,则不能将其分配给块 RAM。

完成插入指令后进行C综合。接口列表如下:

image.png

性能报告:

image.png

对比资源和性能分析:

image.png

从该图中可以看出,对数组进行展开设计可以优化性能,在一定情况下可以优化资源的使用。

AXI接口设计


新建工程并添加文件


添加UG871提供的文件如下: 将axi_interfaces.c和axi_interfaces.h添加到source,函数和上个设计相同。

axi_interfaces.c

#include "axi_interfaces.h"
// The data comes in organized in a single array.
// - The first sample for the first channel (CHAN)
// - Then the first sample for the 2nd channel etc.
// The channels are accumulated independently
// E.g. For 8 channels:
// Array Order :  0  1  2  3  4  5  6  7  8     9     10    etc. 16       etc...
// Sample Order:  A0 B0 C0 D0 E0 F0 G0 H0 A1    B1    C2    etc. A2       etc...
// Output Order:  A0 B0 C0 D0 E0 F0 G0 H0 A0+A1 B0+B1 C0+C2 etc. A0+A1+A2 etc...
void axi_interfaces (dout_t d_o[N], din_t d_i[N]) {
  int i, rem;
  // Store accumulated data
  static dacc_t acc[CHANNELS];
  // Accumulate each channel
  For_Loop: for (i=0;i<N;i++) {
    rem=i%CHANNELS;
    acc[rem] = acc[rem] + d_i[i];
    d_o[i] = acc[rem];
  }
}

axi_interfaces.h

#ifndef AXI_INTERFACES_H_
#define AXI_INTERFACES_H_
#include <stdio.h>
typedef short din_t;
typedef short dout_t;
typedef int dacc_t;
#define CHANNELS 8
#define SAMPLES  4
#define N CHANNELS * SAMPLES
void axi_interfaces (dout_t d_o[N], din_t d_i[N]);
#endif

使用 AXI4-Stream 接口创建优化设计


在本工程中,指定要实现为 AXI4-Stream 接口的数组参数。 如果阵列被划分为通道,您可以通过设计并行传输每个通道的样本。如果 I/O 端口被配置为提供和使用单独的通道数据流,部分展开 for 循环可以确保专用硬件处理每个通道。

首先进行数据通道展开,也就是使用数组分割进行优化输出,确保可以同时输出8个通道的数据。对d_o进行添加分割指令,设置分割类型为cyclic,在 Vivado HLS Directive Editor 对话框中,将因子设置为8。点击OK完成设置。

image.png

同时设置d_o的接口为axis类型的,也就是axi-stream流的接口。

image.png

同理对输入的d_i进行设置,设置完成后在指令辅助界面如下所示:

image.png

然后对循环进行优化处理,期望把循环进行展开8份,所以使用UNROLL进行展开,部分展开的系数设置为8。

image.png

然后为了进一步并行化,可以使用pipeline指令进行流水展开操作。并且勾选上rewind操作。

在未使用rewind操作时,每执行一次for循环中间会有一个时钟周期的延时,在使用了rewind操作后,执行完上一个循环后,下一个for循环直接进流水,而不需要等待一个时钟周期的延迟。

指令优化界面此时如下图所示:

image.png

因为使用AXI协议,所以在层级接口可以使用AXI-Lite接口进行对模块进行控制。在指令控制界面添加块级的接口,声明为s_axilite。

运行c综合后出现对应的AXI总线接口,

image.png

并会自动综合生成相关驱动文件,以方便调用。

image.png

reference


  1. UG871
目录
相关文章
HLS实践 - 03 - 接口优化设计(一)
HLS实践 - 03 - 接口优化设计
275 0
HLS实践 - 03 - 接口优化设计(一)
|
存储 人工智能 监控
HLS实践 - 06 - 优化设计(一)
HLS实践 - 06 - 优化设计
241 0
HLS实践 - 06 - 优化设计(一)
|
缓存 数据处理 索引
HLS实践 - 06 - 优化设计(二)
HLS实践 - 06 - 优化设计
185 0
HLS实践 - 06 - 优化设计(二)
|
存储
HLS开发学习-10- 接口综合
HLS开发学习-10- 接口综合
449 0
HLS开发学习-10- 接口综合
HLS开发学习-14- Vivado HLS 函数层面的优化
HLS开发学习-14- Vivado HLS 函数层面的优化
258 0
HLS开发学习-14- Vivado HLS 函数层面的优化
|
存储 缓存 算法
HLS设计方法论 - 数据访问模式
HLS设计方法论 - 数据访问模式
104 0
HLS设计方法论 - 数据访问模式
|
编译器 异构计算 索引
HLS设计方法论 - 结构优化策略
HLS设计方法论 - 结构优化策略
185 0
HLS设计方法论 - 结构优化策略
|
存储 测试技术 文件存储
HLS开发学习-09- 描述高效的C测试平台
HLS开发学习-09- 描述高效的C测试平台
724 0
HLS开发学习-09- 描述高效的C测试平台
|
异构计算
HLS开发学习-13- 数组优化
HLS开发学习-13- 数组优化
382 0
HLS开发学习-13- 数组优化
|
算法 Serverless 调度
HLS开发学习-02-HLS工作机制
HLS开发学习-02-HLS工作机制
331 0
HLS开发学习-02-HLS工作机制