Vitis HLS 学习笔记--资源绑定-使用URAM

目录

1. 简介

2. 代码解析

2.1 代码总览

2.2 优化指令

2.3 综合报告

3. 总结


1. 简介

Vivado IP 流程中的 AP_Memory,它用于与存储器资源(如 BRAM 和URAM)进行通信。不同于全局存储器(DDR),对此专用存储器执行的访问称为本地数据访问,比如 BRAM/URAM 中存储的数据。此类访问十分快速。

本地数据交互的唯一方式是通过其输出端口和输入端口。

使用本地存储器 (BRAM/LUTRAM/URAM) 访问时,存储器端口的数量可能限制对数据的访问带宽,导致流水打拍循环内出现 II 违例。

ap_memory 协议同样遵循地址和数据阶段方式来进行操作。该协议首先请求读/写资源,并等待至它收到资源可用确认为止。随后,它会发起读/写的数据传输阶段。

使用UltraRAM(URAM)有几个关键意义和优势,特别是对于需要处理大量数据或需要高性能内存解决方案的应用。以下是使用URAM的主要理由和好处:

  • 增加内存容量:URAM提供了比Block RAM (BRAM)更大的存储容量。在Xilinx一些FPGA设备中,URAM可以提供高达288Kb的存储容量,这是BRAM容量的四倍。使用URAM可以在不牺牲FPGA上其他资源的情况下,增加设计的内存容量。
  • 改善资源利用率:对于需要大量内存的设计,使用URAM可以更有效地利用FPGA的内存资源。通过用更少的URAM实现相同的存储需求,可以释放BRAM资源供其他用途使用,这有助于优化整体的资源分配和利用率。
  • 提高性能:URAM能够提供与BRAM相似的访问速度,同时提供更大的存储容量。对于大规模数据处理和存储密集型应用,使用URAM可以减少数据访问延迟,提高系统的数据吞吐量和性能。
  • 降低功耗:相对于使用多个BRAM实现同等存储容量,使用URAM可以在一定程度上降低系统的总体功耗。因为减少了所需内存单元的数量,从而降低了功耗。
  • 优化数据局部性:通过在设计中合理地使用URAM,可以优化数据的局部性,减少对外部存储的访问需求。这对于那些对延迟和性能有严格要求的应用来说是非常重要的。
  • 支持高级特性:在Vitis HLS中,URAM可以支持一些高级的内存管理和访问特性,如双端口访问、异步读写等,这为复杂的算法实现提供了更多的灵活性和可能性。

2. 代码解析

2.1 代码总览

以下代码展示了一个在Vitis HLS环境中设计的简单存储器模型。它实现了一个可读写的存储器,其中使用UltraRAM(URAM)作为存储介质:

#include "ap_int.h"

#define ADDRBITS 14
#define NWORDS 1 << ADDRBITS

typedef ap_uint<128> data_t;
typedef ap_uint<ADDRBITS> addr_t;

void example(bool wren, bool rden, addr_t addrW, data_t datain,
                   addr_t AddrR, data_t* dataout) {
#pragma HLS PIPELINE II = 1

    static data_t buffer[NWORDS];
#pragma HLS DEPENDENCE   variable = buffer inter WAR false
#pragma HLS BIND_STORAGE variable = buffer type = ram_2p impl = uram

    if (rden)
        *dataout = buffer[AddrR];

    if (wren)
        buffer[addrW] = datain;
}

其中,

ADDRBITS 定义了地址位数,这里是14位。

NWORDS 定义了存储器的地址数,通过左移操作计算得到,即1 << 14,表示存储器中有16384(2^14)个地址。

以上代码生成的IP:

  • wren:写使能信号。
  • rden:读使能信号。
  • addrW:写操作的地址。
  • datain:写入的数据。
  • AddrR:读操作的地址。
  • dataout:读出的数据。 

2.2 优化指令

#pragma HLS PIPELINE II = 1

这条指令指示 HLS 工具尝试以流水线方式执行这个函数,每个时钟周期开始一个新的操作(迭代间隔II=1)。

static data_t buffer[NWORDS];
#pragma HLS DEPENDENCE variable = buffer inter WAR false
#pragma HLS BIND_STORAGE variable = buffer type = ram_2p impl = uram

这段定义了一个静态的 buffer 数组,大小为 NWORDS,用作存储数据。
#pragma HLS DEPENDENCE指示编译器这个变量(buffer)不存在写后读(WAR)的数据依赖问题,优化并行执行。
#pragma HLS BIND_STORAGE将buffer绑定为双端口RAM(ram_2p),并指定实现为URAM。这使得buffer在FPGA上的物理实现是使用URAM资源。

2.3 综合报告

================================================================
== HW Interfaces
================================================================
* REGISTER
+-----------+---------+----------+
| Interface | Mode    | Bitwidth |
+-----------+---------+----------+
| AddrR     | ap_none | 14       |
| addrW     | ap_none | 14       |
| datain    | ap_none | 128      |
| dataout   | ap_none | 128      |
| rden      | ap_none | 1        |
| wren      | ap_none | 1        |
+-----------+---------+----------+

================================================================
== Bind Storage Report
================================================================
+--------------+------+------+--------+----------+---------+------+---------+
| Name         | BRAM | URAM | Pragma | Variable | Storage | Impl | Latency |
+--------------+------+------+--------+----------+---------+------+---------+
| + example    | 0    | 8    |        |          |         |      |         |
|   buffer_V_U | -    | 8    | pragma | buffer_V | ram_2p  | uram | 1       |
+--------------+------+------+--------+----------+---------+------+---------+

================================================================
== Pragma Report
================================================================
* Valid Pragma Syntax
+--------------+---------------------------------------------+---------------------------+
| Type         | Options                                     | Location                  |
+--------------+---------------------------------------------+---------------------------+
| pipeline     | II = 1                                      | example.cpp:12 in example |
| dependence   | variable = buffer inter WAR false           | example.cpp:15 in example |
| bind_storage | variable = buffer type = ram_2p impl = uram | example.cpp:16 in example |
+--------------+---------------------------------------------+---------------------------+

 从综合报告来看,我们成功绑定了 URAM 作为 buffer 的实现方式,并且II=1。

3. 总结

本文提供了对使用 URAM 进行高性能内存解决方案设计的全面理解,详细介绍了在 Vivado IP 流程中使用 AP_Memory 进行与存储器资源通信的方法,并介绍了使用 UltraRAM(URAM)的优势和意义。通过代码解析,展示了在 Vitis HLS 环境中设计的一个简单存储器模型。

  • 25
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值