HLS之AXI接口使用
转发:
HLS接口类型:
在HLS中Xilinx有很多接口类型可以选择,主要记录有关AXI的接口使用,在HLS中一共有三种AXI接口,分别是m_axi、s_axilite、axis。
m_axi:
仅在阵列和指针(以及C++中的引用)上指定。m_axi模式用于指定AXI4存储器映射接口。可以将多个实参组合到单个m_axi接口内。
-
m_axi优势:
1、此接口具有独立的读取通道和写入通道。
2、它基于突发的访问,潜在性能可达~17GB/S。
3、它可为未完成传输事务提供支持(我理解就是具备缓存多个读或写命令)。
-
vivado ip流程默认设置:
1、默认操作模式为offset = off,但可对此进行更改。
2、已分配的指针和阵列实参都映射到单个接口捆绑。
3、vivado ip流程中默认对齐设置为1个字节。
4、默认情况下,最大读/写突发长度设置为16。
-
单独数据传输:
在图一中,显示了官方单独数据传输的代码,(acc += *d;)为读数据操作,(*d = acc;)为写操作。

图一
自己测试编写代码:

图二
仿真验证,图三可以看到一开始axi发出了一个读事务,地址为0x0000_0000_43c0_0000;至于为什么的地址是64位而不是32位,是因为默认设置是64位,可以通过修改变为32位地址。

图三
在图四中可以看到,axi产生了一个写事务,地址为0x0000_0000_43c0_0000;数据为1,为什么数据是1,是因为读回来的数据为0,在程序中加了1,所以数据为1,方便区分。后面就一直在循环这个读写过程。

图四
以上传输的地址其实都是基地0x0000_0000_43c0_0000;至于基地址如何设置后面再说,接下来修改代码如图五。

图五
这样的修改结果如何,从图六中我们可以看到连续四个写事务,且地址偏移从0开始,每次偏移4。这就实现了不同地址偏移的读写操作。

图六
-
突发模式传输:
图七是官方给出的例程,使用C语言中的memcpy函数实现突发模式操作;还可以通过流水打拍的for循环实现。memcpy函数用于在使用AXI4主接口指定的顶层函数实参上执行双向数据出入传输时,才支持对其进行综合。

图七
从图八中可以看到可以看到AXI发出了四次读突发,前三次ARLEN为16,最后一次为2,加起来一共就是50次,对应这段代码memcpy(buff, (const int*)d, 50 * sizeof(int));上面提到过,不额外设置,突发长度默认为16,地址也随之偏移。

图八
从图九可以看出,axi发出了四次写突发,前三次AWLEN为16,最后一次为2,加起来一共就是50次,对应这段代码memcpy((int*)d, buff, 50 * sizeof(int));不额外设置,突发长度默认为16,地址也随之偏移。

图九
偏移和操作模式:
偏移在上面已经展示过了,如果不修改指针,地址就会从偏移地址开始,根据所给数据长度开始往后偏移;如果需要修改一开始的偏移地址,将指针加相应的数就可以了。如上面突发例子,如果基地址为0x000_0000;读取或写入地址就会从0x000_0000到0x0000_00c7。
操作模式:操作模式就是如何修改基地址,一共有三种操作模式可以选择,offset = off;
offset = direct; offset = slave;
offset = off:在 Vivado IP integrator 工具中使用 IP 时,Vitis HLS 会为 m_axi 接口设置基址。这种方法的缺点之一是在运行时间内无法更改基址。
offset = direct:
Vitis HLS 会在 IP 上生成端口用于设置地址。请注意在下图中添加的 a 端口。它支持您在运 行时间更新地址,这样即可通过同一个 m_axi 接口来读取和写入不同位置。图十是我验证代码的测试框图,在下图中可以看到我们综合出来的模块,nvme_0有一个端口a,这个端口就是用来配置基地址的。

图十
offset = slave:
在这模式下,基地地址是通过axilite接口来配置的,我的理解是跟上面一样,只是接口方式不一样。
s_axilite:仅限在除串流外的任意类型的实参上指定此协议。s_axilite模式用于指定AXI4_Lite从接口。可以将多个实参组合到单个s_axilite接口内。
axis:仅限在输入实参或输出实参上指定此协议,而不得在(输入/输出)实参上指定。axis模式用于指定AXI4-Stream接口。
更多推荐



所有评论(0)