pragma HLS interface 端口综合

这是针对pragma HLS interface 语法的翻译笔记,可以作为原英文文档的辅助文档,原文地址是SDSoc Development Help

正文

在vivado HLS基于C的设计中,函数形式参数代表了输入和输出操作。但是在RTL设计中,必须设计接口来执行这些输入和输出操作,并且通常使用特定的I / O(输入-输出)协议进行操作。有关更多信息,请参考《Vivado Design Suite用户指南:高级综合(UG902)》中的“Ch.1 Manage Interface” 。(推荐参考:对ug902中manage interface部分的优质翻译

INTERFACEpragma指定如何在接口合成期间依据函数定义创建RTL端口。
RTL实现中的端口派生自:

  • 指定的任何函数级协议
  • 函数参数
  • 由顶级函数访问的,并且是在其作用域之外定义的全局变量

Function-level protocols(函数层级的协议)也称为block-level I/O protocols(块级I/O协议),用于提供信号来控制函数何时开始操作,并指示函数操作何时结束、空闲和准备好接受新的输入。函数级协议的实现:

  • 由值指定为三种模式ap_ctrl_noneap_ctrl_hsap_ctrl_chain。其中的 ap_ctrl_hs是默认的块级I / O协议。
  • 与函数名相关联。

port-level (I/O) interface protocol(端口级I / O接口协议):可以为每个函数参数指定port-level (I/O) interface protocol(端口级I / O接口协议),如有效握手(ap_vld)或确认握手(ap_ack)。如果函数会返回一个值,则为顶层函数和函数返回中的每个参数创建端口级I/O接口协议。创建的默认I/O协议取决于C参数的类型。在使用块级IO协议启动块的操作后,使用端口级IO协议对数据进行序列输入和输出

如果访问了全局变量,但所有读和写操作都是design的本地操作,即是在design中创建资源,那么在RTL中不需要I/O端口。如果全局变量是外部源或地址,则以类似的方式将其接口指定为标准函数参数。参见下面的示例。
INTERFACEpragma用于子函数时,只能使用register选项。子函数不支持< mode>选项。

提示:Vivado HLS自动确定任何子函数使用的I/O协议。除了指定端口是否寄存外,您无法控制这些端口。

语法

将pragma放在函数内。

#pragma HLS interface <mode> port=<name> bundle=<string> \
register register_mode=<mode> depth=<int> offset=<string> \
clock=<string> name=<string> \
num_read_outstanding=<int> num_write_outstanding=<int> \
max_read_burst_length=<int> max_write_burst_length=<int>

其中各部分含义:

  • < mode>:为函数参数、函数使用的全局变量或block-level control protocols指定接口协议模式。有关这些不同模式的详细描述,请参阅Vivado Design Suite用户指南中的“界面综合参考”:高级综合(UG902)。模式可以指定为以下方式之一:
    ap_none:没有协议。接口是一个数据端口。
    ap_stable:没有协议。接口是一个数据端口。Vivado HLS假设数据端口在重置后总是稳定的,这允许内部优化来删除不必要的寄存器。(这个没懂什么意思,打算再去看看ug902)
    ap_vld:(valid)实现一个与数据端口相关联的端口,以指示数据何时可供读写。
    ap_ack:(acknowledge)实现一个与数据端口相关联的端口,以确认数据已被读写。
    ap_hs:实现与数据端口关联的valid端口和acknowledge端口。以提供双向握手信号,指示数据何时对读写有效,以及确认数据已被读写。
    ap_ovld:实现与输出数据端口关联的valid端口,以指示数据何时可以读写。
    IMPORTANT!: Vivado HLS使用模式ap_none实现输入参数或任何读/写参数的输入一半。
    ap_fifo:使用标准的FIFO接口实现端口。使用数据输入和输出端口以及相关的active-Low FIFO空端口和满端口。(英文没读懂,大致意思就是为流水型的数组数组接口额外配置了FIFO模块)
    Note:只能在读参数或写参数上使用此接口。ap_fifo模式不支持双向读/写参数。
    ap_bus:实现指针和按引用传递端口作为总线接口。
    ap_memory:将数组参数实现为标准RAM接口。如果在Vivado IP integrator中使用RTL设计,则内存接口将显示为离散的端口。
    bram:将数组参数实现为标准RAM接口。如果在Vivado IP integrator中使用RTL设计,那么内存接口将作为单个端口出现。
    axis:将所有端口实现为一个AXI4-Stream接口。
    s_axilite:将所有端口实现为一个AXI4-Lite接口。Vivado HLS在导出RTL过程中生成一组相关的C驱动程序文件。
    m_axi:实现所有端口作为一个AXI4接口。可以使用config_interface命令指定32位(默认)或64位地址端口,并控制任何地址偏移量。
    (AXI的我都不懂,需要看ug902)
    ap_ctrl_none:没有块级I/O协议。
    注意:使用ap_ctrl_none模式可能会阻止使用C/RTL co-simulation 验证设计。
    ap_ctrl_hs:实现一组块级控制端口,以启动设计操作,并指示设计何时空闲、完成和准备好接受新的输入数据。
    注意:ap_ctrl_hs模式是默认的块级I/O协议。
    ap_ctrl_chain:实现一组块级控制端口,以启动设计操作、继续操作,并指示设计何时空闲、完成和准备好接受新的输入数据。注意:(和ap_ctrl_hs的区别)ap_ctrl_chain接口模式类似于ap_ctrl_hs,但是它提供了一个额外的输入信号ap_continue来apply back pressure。Xilinx建议在将Vivado HLS块链接在一起时使用ap_ctrl_chain块级I/O协议。

  • port=< name>:指定接口pragma应用到的函数参数、函数返回值或全局变量的名称。
    提示:可以将块级I/O协议(ap_ctrl_none、ap_ctrl_hs或ap_ctrl_chain)分配给函数返回值的端口,如:

#pragma HLS INTERFACE ap_ctrl_none port = return 
  • bundle=< string>:将函数参数分组到AXI接口端口。默认情况下,Vivado HLS将指定为AXI4-Lite (s_axilite)接口的所有函数参数组到单个AXI4-Lite端口。类似地,所有指定为AXI4 (m_axi)接口的函数参数都被分组到一个AXI4端口中。该选项将具有相同bundle=< string>的所有接口端口显式地分组到相同的AXI接口端口中,并将RTL端口命名为< string>指定的值。

  • register:一个可选的关键字,用于寄存信号和任何相关协议信号,并使信号至少持续到函数执行的最后一个周期。此选项适用于以下界面模式:
    在这里插入图片描述
    提示:config_interface命令的-register_io选项可以全局控制寄存所有顶层函数的输入/输出。有关更多信息,请参阅Vivado Design Suite用户指南:高级合成(UG902)。

  • register_mode= <forward|reverse|both|off>:与register关键字一起使用,该选项指定是在forward路径(TDATA和TVALID)、reverse路径、both路径 (TDATA, TVALID和TREADY)、或都不(off),放置寄存器。默认的register_mode是both。AXI-Stream(axis) side-channel signals被认为是数据信号,并且每当TDATA被register时它就会被register。

  • depth=< int>:指定testbench要处理的最大样本数目。此设置指示Vivado HLS为RTL co-simulation创建的verification adapter 中所需的FIFO的最大尺寸。提示:虽然深度通常是一个选项,但是对于m_axi接口来说它是必需的。

  • offset=< string>:控制AXI4- lite (s_axilite)和AXI4 (m_axi)接口中的地址偏移量。
    对于s_axilite接口,<string>指定寄存器map中的地址。
    对于m_axi接口,<string>指定了以下值:
    direct:生成一个标量输入偏移端口。
    slave:生成一个偏移端口,并自动将其映射到AXI4-Lite从接口。
    off:不生成偏移端口。
    提示:config_interface命令的-m_axi_offset选项全局控制了设计中所有M_AXI接口的偏移端口。

  • clock=< name>:是可选的,只用于s_axilite模式。这定义了接口要使用的时钟信号。默认情况下,axis - lite接口时钟与系统时钟相同。此选项用于为axis - lite (s_axilite)接口指定单独的时钟。
    提示:如果使用bundle选项将多个顶级函数参数分组到一个axis - lite接口中,那么只需要在一个bundle成员上指定时钟选项。

  • num_read_outstanding=:对于AXI4 (m_axi)接口,这个选项指定在设计停止之前,在没有响应的情况下,可以向AXI4总线发出多少读取请求。这显示了设计之中的内部存储——一个FIFO的大小:num_read_outstanding*max_read_burst_length*word_size

  • num_write_outstanding=:对于AXI4 (m_axi)接口,这个选项指定在设计停止之前,在没有响应的情况下,可以向AXI4总线发出多少写请求。这显示了设计之中的内部存储——一个FIFO的大小:num_write_outstanding*max_write_burst_length*word_size

  • max_read_burst_length=:对于AXI4 (m_axi)接口,这个选项指定了在突发传输期间所读取的数据值的最大的数量。

  • max_write_burst_length=:对于AXI4 (m_axi)接口,这个选项指定在突发传输期间写入的数据值的最大数量。

  • name=:此选项用于根据您自己的意愿重命名端口。生成的RTL端口将使用这个名称。

例子1

在本例中,两个函数参数都是使用AXI4-Stream接口实现的:

void example(int A[50], int B[50]) {
  //Set the HLS native interface types
  #pragma HLS INTERFACE axis port=A
  #pragma HLS INTERFACE axis port=B
  int i;
  for(i = 0; i < 50; i++){
    B[i] = A[i] + 5;
  }
}

例子2

下面关闭块级I/O协议,并赋给函数返回值:

#pragma HLS interface ap_ctrl_none port=return

函数参数InData被指定为使用ap_vld接口,并且还表明输入应该被寄存:

#pragma HLS interface ap_vld register port=InData

例子3

此示例定义了顶级transpose函数的端口的接口标准。注意使用bundle=选项对信号进行分组。

// TOP LEVEL - TRANSPOSE
void transpose(int* input, int* output) {
	#pragma HLS INTERFACE m_axi port=input offset=slave bundle=gmem0
	#pragma HLS INTERFACE m_axi port=output offset=slave bundle=gmem1

	#pragma HLS INTERFACE s_axilite port=input bundle=control
	#pragma HLS INTERFACE s_axilite port=output bundle=control
	#pragma HLS INTERFACE s_axilite port=return bundle=control

	#pragma HLS dataflow

猜你喜欢

转载自blog.csdn.net/Leonie_/article/details/107781900
HLS