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

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

写在前面


本文使用UG871的示例工程,第一个工程说明什么是块级 I/O 协议以及如何控制它们;第二个工程进行设置端口IO协议;第三个工程对数组接口进行设计;第四个工程使用AXI接口设计。

块级接口协议


新建工程并添加文件


添加UG871提供的文件如下:

将adders.c和adders.h添加到source。

adders.c

#include "adders.h"
int adders(int in1, int in2, int in3) {
// Prevent IO protocols on all input ports
#pragma HLS INTERFACE ap_none port=in3
#pragma HLS INTERFACE ap_none port=in2
#pragma HLS INTERFACE ap_none port=in1
  int sum;
  sum = in1 + in2 + in3;
  return sum;
}

adders.h

#ifndef ADDERS_H_
#define ADDERS_H_
int adders(int in1, int in2, int in3);
#endif

完成添加后进行c综合。

此时生成的报告中的接口列表如下:

image.png

此时可以看到,在接口列表中,出现了start、done、idle、ready、return等信号,这些信号也可以称为块级IO的控制信号,用于对数据传输的控制。块级 I/O 协议允许 RTL 设计由独立于数据 I/O 端口的附加端口控制。 此 I/O 协议与功能本身相关联,而不与任何数据端口相关联。 默认的块级 I/O 协议称为 ap_ctrl_hs。

下表分析了ap_ctrl_hs中各个信号的功能。

image.png

从波形中也可以看出每个信号的功能

image.png

修改块级接口


在directive中,点击函数名,然后进行添加指令。

image.png

  • ap_ctrl_none:无块级 I/O 控制协议。
  • ap_ctrl_hs:块级I/O 控制握手协议。
  • ap_ctrl_chain:用于控制链接的块级I/O协议。这个I/O协议主要用于将流水线块链接在一起。
  • s_axilite: 可以应用在ap_ctrl_hs或ap_ctrl_chain之外,作为AXI Slave Lite接口来实现块级I/O协议,以代替单独的离散I/O端口。

如果选择无块级 I/O 控制协议,将不会出现相应的IO控制接口信号。如下图:

image.png

端口IO协议


新建工程并添加文件


新建工程并添加文件,添加UG871提供的文件如下: 将adders_io.c和adders_io.h添加到source。

adders_io.c

#include "adders_io.h" 
void adders_io(int in1, int in2, int *in_out1) {  
  *in_out1 = in1 + in2 + *in_out1; 
}            

adders_io.h

#ifndef ADDERS_IO_H_
#define ADDERS_IO_H_
void adders_io(int in1, int in2, int *in_out1);
#endif

完成添加后进行c综合。

此时默认生成的端口列表如下:

image.png

修改端口IO接口


在directive中,点击需要修改端口的变量,然后进行添加指令。

image.png

ap_none:指定端口不添加I/0协议。这个端口的参数被实现为一个没有其他相关信号的数据端口。ap none模式是标量输入的默认模式。

ap_stable模式:用于只在设备处于重置模式时才会改变的配置输入。

ap_ovld与in-out参数一起使用。当将in-out分为单独的输入端口和输出端口时,ap_none应用于输入端口,ap_vld应用于输出端口。

ap_ovld:这是指针实参的默认值,可读可写。

如果把in1修改成ap_vld,in2修改成ap_ack。综合生成的信号列表将会出现一个in1的有效信号,和一个in2的响应信号。如下图:

image.png

数组接口设计


新建工程并添加文件


添加UG871提供的文件如下: 将array_io.c和array_io.h添加到source。

array_io.c

#include "array_io.h"
void array_io (dout_t d_o[N], din_t d_i[N]) {
  int i, rem;
  // Store accumulated data
  static dacc_t acc[CHANNELS];
  dacc_t temp;
  // Accumulate each channel
  For_Loop: for (i=0;i<N;i++) {
    rem=i%CHANNELS;
    temp = acc[rem] + d_i[i];
    acc[rem] = temp;
    d_o[i] = acc[rem];
  }
}

array_io.h

#ifndef ARRAY_IO_H_
#define ARRAY_IO_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 array_io (dout_t d_o[N], din_t d_i[N]);
#endif

完成添加后进行c综合。

此时默认生成的端口列表如下:

image.png

默认情况下,只要数组在顶级函数上,就会使用ap_memory。无论数组的类型是什么(input, output, in/out), ap_memory都是默认值。

修改数组接口设计


将数组参数合成到 RAM 端口是默认设置。 可以使用许多其他选项来控制这些端口的实现方式。 如使用单端口或双端口 RAM 接口;使用FIFO接口;划分为离散端口。

HLS将 RAM 接口指定为单端口或双端口。 如果不进行选择,Vivado HLS 会自动分析设计并选择端口数量以最大化数据速率。

在这个设计中,如果想使用多个 RTL 端口实现一个数组参数,必须进行展开 for 循环并允许所有内部操作并行发生,否则多个端口没有任何好处。for 循环确保一次只能读取(或写入)一个数据样本。

所以为了将数组接口转换为双端口,首先要进行数组的循环展开优化。

在directive界面选择loop的标签进行添加循环展开优化。

image.png

尝试将端口设置为双端口RAM和FIFO,假设设置d_i为双端口RAM接口,d_o为FIFO接口。同样的方法进行插入相关指令。

image.png

数组参数d_o 已实现为具有16 位数据端口(d_o_din) 和相关输出写入(d_o_write) 和输入FIFO 满(d_o_full_n) 端口的FIFO 接口。 参数d_i 已实现为双端口RAM 接口。

image.png

性能报告:

image.png

通过使用双端口 RAM 接口,该设计可以以两倍于先前设计的速率接受输入数据。 由于 for 循环已展开,因此循环中的逻辑能够以该速率消耗数据。 默认情况下,每个循环迭代都会依次执行。 此实现代码将逻辑限制为在每次迭代中对 d_i 进行一次读取。 展开循环允许执行更多读取(但会创建 N 个逻辑副本)。 但是,在输出上使用单端口 FIFO 接口,输出数据速率与以前相同

目录
相关文章
|
Web App开发 弹性计算 编解码
最佳实践:如何扩展你的SRS并发能力?
当我们用SRS快速搭建了视频服务,业务也开始上线运行了,很快就会遇到一个问题:如何支持更多的人观看?如何支持更多的人推流?这本质上就是系统的水平扩展能力,SRS当然是支持的,而且有多种扩展的方法,这篇文章就就详细分析各种扩展的方案,以及各种方案的应用场景和优缺点。
2584 0
最佳实践:如何扩展你的SRS并发能力?
|
SQL 消息中间件 缓存
接口优化的常见方案实战总结
接口优化的常见方案实战总结
HLS实践 - 03 - 接口优化设计(二)
HLS实践 - 03 - 接口优化设计
391 0
HLS实践 - 03 - 接口优化设计(二)
|
存储 人工智能 监控
HLS实践 - 06 - 优化设计(一)
HLS实践 - 06 - 优化设计
290 0
HLS实践 - 06 - 优化设计(一)
|
缓存 数据处理 索引
HLS实践 - 06 - 优化设计(二)
HLS实践 - 06 - 优化设计
219 0
HLS实践 - 06 - 优化设计(二)
|
存储
HLS开发学习-10- 接口综合
HLS开发学习-10- 接口综合
570 0
HLS开发学习-10- 接口综合
HLS开发学习-14- Vivado HLS 函数层面的优化
HLS开发学习-14- Vivado HLS 函数层面的优化
337 0
HLS开发学习-14- Vivado HLS 函数层面的优化
|
存储 缓存 算法
HLS设计方法论 - 数据访问模式
HLS设计方法论 - 数据访问模式
146 0
HLS设计方法论 - 数据访问模式
|
编译器 异构计算 索引
HLS设计方法论 - 结构优化策略
HLS设计方法论 - 结构优化策略
240 0
HLS设计方法论 - 结构优化策略
|
XML JSON 前端开发
优化封装方案实现| 学习笔记
快速学习优化封装方案实现。
优化封装方案实现| 学习笔记