Vivado HLS使用接口类型ap_ctrl_none,ap_ctrl_hs和ap_ctrl_chain来指定是否使用块级握手信号实现RTL。块级握手信号指定以下内容:
您可以给函数或者函数的返回值指定这些块级I/O协议。如果C代码不返回一个值,您同样可以给函数的返回指定一个块级I/O协议。如果C代码使用了一个函数返回,Vivado HLS会为返回值创建一个 ap_return 输出端口。
ap_ctrl_hs 块级I/O协议是默认使用的协议,下图展示了Vivado HLS在函数上实现ap_ctrl_hs时产生的RTL端口和行为。在这个例子中,函数利用return语法返回一个值,因而Vivado HLS在RTL设计创建了一个ap_return输出端口。如果C代码中不包含函数的return语法,这一个端口就不会生成。
ap_ctrl_chain 接口模式类似于ap_ctrl_hs,但是提供了附加的输入信号 ap_continue 来施加反压。Xilinx建议将Vivado HLS块链接在一起时使用ap_ctrl_chain块级I / O协议。
如果您指定使用 ap_ctrl_none 块级I/O协议,那么上图中的握手信号端口(ap_start,ap_idle,ap_ready 和 ap_done)就不会被创建。如果您没有在设计中指定块级I/O协议,那么您在使用C / RTL协同仿真来验证RTL设计时,必须遵守 接口综合要求 中所述的条件。
下图展示了由ap_ctrl_hs I/O协议为非流水线设计而创建的块级握手(handshake)信号的行为。
复位完成后,将发生以下事件:
① 所设计的块等待 ap_start 置高电平以开始它的操作
② 输出 ap_idle 立刻置低电平以指示此时所设计的块不再空闲
③ ap_start 信号必须保持高电平直到 ap_ready 置高,一旦 ap_ready 置高:
④ 数据可以被输入端口读取(注意:输入端口可以使用独立于此块级I / O协议的端口级I / O协议)
⑤ 数据可以被写到输出端口(注意:输出端口可以使用独立于此块级I / O协议的端口级I / O协议)
⑥ 当设计的块完成操作时,输出 ap_done 置高(注意:如果有ap_return端口,则当ap_done为“高”时,此端口上的数据有效。 因此,ap_done信号还指示输出ap_return上的数据何时有效)
⑦ 当设计准备好接受新输入时,ap_ready 信号变为高电平。 以下是有关ap_ready信号的其他信息:
⑧ ap_idle 信号指示设计何时处于空闲状态且未运行。 以下是有关ap_idle信号的其他信息:
ap_ctrl_chain 块级I/O协议类似于 ap_ctrl_hs 协议,但提供了一个名为 ap_continue 的附加输入端口。高电平有效的ap_continue信号指示消耗输出数据的下游块已准备好进行新的数据输入。如果下游块无法使用新的数据输入,则ap_continue信号为低电平,这将阻止上游块生成附加数据。
下游块的 ap_ready 端口可以直接驱动 ap_continue 端口。 以下是有关ap_continue端口的其他信息:
在下面的图中,因为当ap_done为高时,ap_continue为高,所以第一个事务完成,并且第二个事务立即启动。 但是,设计将在第二个事务结束时停止,直到将ap_continue声明为高为止。
ap_none端口级I/O协议是最简单的接口类型,并且没有其他信号与其关联。输入数据信号和输出数据信号都没有关联的用于指示何时读取或写入数据的控制端口。 RTL设计中唯一的端口是源代码中指定的端口。
ap_none接口不需要其他硬件开销,尽管如此,ap_none接口需要满足以下条件:
注意:ap_none接口不能与数组参数一起使用。
与ap_none一样,ap_stable端口级I/O协议不会在设计中添加任何接口控制端口。 ap_stable类型通常用于可更改但在正常操作期间保持稳定的数据,例如提供配置数据的端口。 ap_stable类型将以下内容通知给Vivado HLS:
注意:ap_stable类型只能应用于输入端口。 当应用于inout端口时,仅端口的输入被认为是稳定的。
ap_hs端口级I/O协议在开发过程中提供了最大的灵活性,允许自下而上和自上而下的设计流程。 双向握手可以安全地执行所有块内通信,且可以正确操作不需要手动干预或假设。 ap_hs端口级I/O协议提供以下信号:
下面的图显示了ap_hs接口在输入和输出端口上的行为,在此示例中,输入端口命名为 in,输出端口命名为 out。
注意:控制信号的名称是基于原始端口名称确定的。 例如,用于输入数据的有效端口名为in_vld。
对于输入,发生以下事件:
对于输出,发生以下事件:
ap_ack端口级I/O协议是ap_hs接口类型的子集,它提供以下信号:
注意:在执行写操作后,设计将暂停并等待直到输入确认为高电平为止,这表明输出已由使用者块读取。 但是,没有关联的输出端口指示何时可以使用数据。不能使用C / RTL协同仿真来验证在输出端口上使用ap_ack的设计!
ap_vld是ap_hs接口类型的子集。 ap_vld端口级I/O协议提供以下信号:
ap_ovld是ap_hs接口类型的子集。 ap_ovld端口级I/O协议提供以下信号:
ap_memory和bram接口端口级I/O协议用于实现数组参数。 当需要随机访问内存地址位置时,这种类型的端口级I/O协议可以与存储元件(例如RAM和ROM)通信。
注意:如果只需要对存储元素的顺序访问,请改用ap_fifo接口。 ap_fifo接口可减少硬件开销,因为不执行地址生成。
ap_memory和bram接口端口级别的I/O协议是相同的。 唯一的不同是Vivado IP集成器显示块的方式:
使用ap_memory接口时,请使用RESOURCE指令指定数组目标。 如果没有为阵列指定目标,则Vivado HLS会自动决定是使用单端口还是双端口RAM接口。(TIP提示:在运行综合之前,请确保使用RESOURCE指令将数组参数定位到正确的内存类型。 使用更正后的内存进行重新合成可能会导致时间表和RTL不同)
下图显示了一个名为d的数组,该数组指定为单端口Block RAM, 端口名称基于C函数中的参数名称。 例如,如果C参数名为d,则片使能命名为d_ce;基于BRAM的output / q端口,输入数据会命名为d_q0。
若一个输出端口被写入,当设计需要访问存储元件并且访问总是以顺序的方式进行时,即不需要随机访问时,与其相关联的输出有效信号接口是最节省硬件的方法。 ap_fifo端口级I/O协议支持以下内容:
注意:可以使用ap_fifo接口的函数通常使用指针,并且可以多次访问相同的变量。 若要了解使用这种编码样式时volatile限定符的重要性,请参考:《Mult-Access Pointer Interfaces: Streaming Data》。
在下面的示例中,in1是一个指针,该指针访问当前地址,然后访问当前地址的上两个地址,最后访问下一个地址。
void foo(int* in1, ...) {
int data1, data2, data3;
...
data1= *in1;
data2= *(in1+2);
data3= *(in1-1);
...
}
如果将in1指定为ap_fifo接口,则Vivado HLS会检查访问的方式,确定访问不是按顺序进行的,然后发出错误信息并暂停。 要从 非顺序地址位置 读取数据,需要使用 ap_memory 或 bram 接口。
您不能在读写(既要读又要写)的参数上指定ap_fifo接口。 您只能在输入或输出参数上指定ap_fifo接口。输入参数为in且输出参数为out且都指定为ap_fifo的设计的行为如下图所示。
对于输入,发生以下事件:
对于输出,发生以下事件:
ap_bus 接口可以与总线桥进行通信。 由于ap_bus接口未遵循特定的总线标准,因此可以将此接口和与系统总线进行通信的总线桥一起使用,其中总线桥必须能够缓存所有突发写入。
注意:可以使用ap_bus接口的函数使用指针,并且可能多次访问同一变量。 若要了解使用这种编码样式时volatile限定符的重要性,请参考:《Mult-Access Pointer Interfaces: Streaming Data》。
您可以通过以下方式使用ap_bus接口:
注意:通过memcpy函数访问的数组不能划分为寄存器。
以下示例显示了将 ap_bus 接口应用于参数 d 时标准模式下的读写操作的行为。
void foo (int *d) {
static int acc = 0;
int i;
for (i=0;i<4;i++) {
acc += d[i+1];
d[i] = acc;
}
}
以下示例显示了使用C函数memcpy和突发模式时的行为。
void bus (int *d) {
int buf1[4], buf2[4];
int i;
memcpy(buf1,d,4*sizeof(int));
for (i=0;i<4;i++) {
buf2[i] = buf1[3-i];
}
memcpy(d,buf2,4*sizeof(int));
}
复位完成后,将发生以下事件:
② 标准模式下的ap_bus写数据操作行为如下图所示。
③ 突发模式下的ap_bus读取数据操作行为如下图所示。
④ 突发模式下的ap_bus写入数据操作行为如下图所示。
axis模式指定了AXI4-Stream I/O协议。 有关AXI4-Stream接口的完整描述,包括时序和端口,请参见《 Vivado Design Suite: AXI Reference Guide》(UG1037)。 有关使用此I/O协议的完整功能的信息,请参考《Using AXI4 Interfaces》。
s_axilite模式指定AXI4-Lite slave I/O协议。有关AXI4-Lite slave接口的完整描述,包括时序和端口,请参见《 Vivado Design Suite: AXI Reference Guide》(UG1037)。有关使用此I/O协议的完整功能的信息,请参考《Using AXI4 Interfaces》。
m_axi模式指定AXI4 master I/O协议。有关AXI4 master接口的完整描述,包括时序和端口,请参见《 Vivado Design Suite: AXI Reference Guide》(UG1037)。有关使用此I/O协议的完整功能的信息,请参考《Using AXI4 Interfaces》。