端口级 I/O:存储器接口协议 - 2021.2 Chinese

Vitis 高层次综合用户指南 (UG1399)

Document ID
UG1399
Release Date
2021-12-15
Version
2021.2 Chinese

默认情况下,阵列实参作为 ap_memory 接口来实现。这是含数据、地址、芯片使能和写使能端口的标准块 RAM 接口。

ap_memory 接口可作为单端口接口或双端口接口来实现。如果 Vitis HLS 可判定使用双端口接口将缩短启动时间间隔,那么它将自动实现双端口接口。BIND_STORAGE 编译指示或指令用于指定存储器资源,如果在含单端口块 RAM 的阵列上指定该指令,那么将实现单端口接口。相反,如果使用 BIND_STORAGE 编译指示指定双端口接口,并且 Vitis HLS 判定此接口并无益处,那么它将自动实现单端口接口。

如果按顺序访问阵列,可使用 ap_fifo 接口。就像 ap_hs 接口一样,如果 Vitis HLS 判定未按顺序进行数据访问,那么它将停止;如果无法判定是否采用顺序访问,则将发出警告;如果判定已采用顺序方式访问,则不发出任何消息。ap_fifo 接口只能用于读取或写入,不能用于同时读写。

ap_memory,bram

ap_memorybram 接口端口级 I/O 协议用于实现阵列实参。当实现要求随机访问存储器地址位置时,这种类型的端口级 I/O 协议可以与存储器元件(例如,RAM 和 ROM)通信。

注释: 如果只需顺序访问存储器元件,请改用 ap_fifo 接口。ap_fifo 接口可以减少硬件开销,因为不执行地址生成。

ap_memorybram 接口端口级 I/O 协议相同。唯一的区别是 Vivado IP integrator 显示块的方式:

  • ap_memory 接口显示为离散端口。
  • bram 接口显示为单一端口(已组合)。在 IP integrator 中,可使用单一连接来创建到所有端口的连接。

使用 ap_memory 接口时,请使用 BIND_STORAGE 编译指示指定阵列目标。如果没有为阵列指定目标,则 Vitis HLS 会判定是使用单端口还是双端口 RAM 接口。

提示: 运行综合前,请使用 BIND_STORAGE 编译指示确保将阵列实参定向到正确的存储器类型。使用更正后的存储器进行重新综合可能会导致调度和 RTL 不同。

下图显示了一个名为 d 的阵列,该阵列指定为单端口块 RAM。端口名称基于 C/C++ 函数实参。例如,如果 C/C++ 实参为 d,则根据 BRAM 的 output/q 端口,芯片使能为 d_ce,输入数据为 d_q0

图 1. ap_memory 接口的行为

复位后,将执行以下操作:

  • 应用 start 后,该块开始正常操作。
  • 通过在断言输出信号 d_ce 有效的同时在输出地址端口上应用地址来执行读取。
    注释: 对于默认的块 RAM,设计期望在下一个时钟周期中,输入数据 d_q0 可用。您可以使用 BIND_STORAGE 编译指示来指示 RAM 具有更长的读取时延。
  • 通过断言输出端口 d_ced_we 有效并同时应用地址和输出数据 d_d0 来执行写操作。

ap_fifo

写入输出端口时,当设计需要访问存储器元件并且访问始终以顺序方式执行时,即不需要随机访问,则与其关联的输出 valid 信号接口是最节省硬件的方法。ap_fifo 端口级 I/O 协议支持以下操作:

  • 允许端口连接到 FIFO
  • 启用完整的双向 empty-full 通信
  • 适用于阵列、指针和按引用传递实参类型
注释: 可以使用 ap_fifo 接口的函数通常使用指针,并且可能多次访问同一变量。要了解使用这种编码样式时 volatile 限定符的重要性,请参阅 接口上的多重访问指针

在以下示例中,in1 是一个指针,该指针访问当前地址,然后访问当前地址上面的两个地址,最后访问下面的一个地址。

void foo(int* in1, ...) {
 int data1, data2, data3;  
       ...
 data1= *in1; 
 data2= *(in1+2);
 data3= *(in1-1);
 ...
}

如果将 in1 指定为 ap_fifo 接口,则 Vitis HLS 会检查访问、判定访问并非按顺序进行,随即发出错误消息并中止。要从非顺序地址读取,请使用 ap_memorybram 接口。

您不能在同时支持读取和写入的实参上指定 ap_fifo 接口。您只能在输入或输出实参上指定 ap_fifo 接口。含输入实参 in 和输出实参 out(指定为 ap_fifo 接口)的设计的行为如下图所示。

图 2. ap_fifo 接口的行为

对于输入,将执行以下操作:

  • 应用 ap_start 后,该块开始正常操作。
  • 如果输入端口已准备好读取,但输入端口 in_empty_n 处于低电平状态,指示 FIFO 为空,则设计将停滞并等待数据可用。
  • 当输入端口 in_empty_n 处于高电平状态,指示 FIFO 包含数据时,将断言输出确认 in_read 为高电平有效以指示当前周期中已读取数据。

对于输出,将执行以下操作:

  • 应用 start 后,该块开始正常操作。
  • 如果输出端口已准备好写入,但 out_full_n 处于低电平状态,指示 FIFO 已满,则数据将置于输出端口上,但设计将停滞并等待 FIFO 中的空间可用。
  • out_full_n 处于高电平状态,指示 FIFO 中有可用空间时,将断言输出确认信号 out_write 有效以指示输出数据为 valid
  • 如果顶层函数或顶层循环已使用 -rewind 选项进行流水打拍,则 Vitis HLS 将创建另一个后缀为 _lwr 的输出端口。当最后一次写入 FIFO 接口完成时,_lwr 端口将变为高电平有效。