作者: 碎碎思,本文转载自:OpenFPGA微信公众号
Xilinx Vivado中提供了AXI FIFO和AXI virtual FIFO类似IP,这篇文章主要通过实例来讲解这两个IP的使用方法。
AXI Virtual FIFO Controller
FIFO 是我们设计中常用的工具,因为它们使我们能够在进行信号和图像处理时缓冲数据。我们还使用异步FIFO来处理数据总线的时钟域交叉问题。
![](https://cdn.eetrend.com/files/2022-11/wen_zhang_/100565483-277767-1.png)
FIFO 的挑战之一是存储大量数据需要 FPGA 内的大量资源。当然,这在较小的 FPGA 中可能是一个问题,因为 BRAM 资源是有限的。但在许多情况下,较小的 FPGA 可能会连接外部存储器,如 DDR3 或 DDR3L。开发人员可以使用此存储器通过直接存储器访问 (DMA) 在 DDR 存储器存储外部缓冲数据。
AMD-Xilinx 提供了一个称为 AXI Virtual FIFO Controller 的 IP 内核,以简化开发人员希望使用 DDR 存储器将信号或数据样本存储在外部 DDR 中作为 FIFO 的情况。
AXI Virtual FIFO Controller为开发人员提供可连接到信号处理路径的主从 AXI 流端口。与 DDR 存储器的接口由完整的 AXI 接口提供。
![](https://cdn.eetrend.com/files/2022-11/wen_zhang_/100565483-277768-2.png)
使用这些接口,AXI Virtual FIFO Controller能够在 DDR 中创建一个 FIFO,并且能够存储比使用内部 BRAM 更大数量的数据。
AXI Virtual FIFO Controller能够将多个通道数据存储在外部 DDR 中。需要注意的一件事是内存位置与其他内存使用(例如,MicroBlaze 应用程序)可能会发生冲突。在 IP 定制时,我们能够分配的空间需要注意。
![](https://cdn.eetrend.com/files/2022-11/wen_zhang_/100565483-277769-3.png)
接下来创建一个以 Xilinx FPGA(S7-50 )为目标的小项目,项目主要演示AXI Virtual FIFO Controller的工作原理。在本设计中,XADC 是要写入 DDR 的 AXI Stream 数据的来源,DDR 可以通过 AXI Stream 输出其样本。
AXI Virtual FIFO Controller 的输出(读取通道)连接到 AXI Stream FIFO ,最后处理器通过 AXI4-Lite 接口读取数据。
下面显示了设计中的输入路径,其中包含由 XADC 生成的信号和一个subset convertor,用于将 TLast 信号添加到 AXI 流。AXI ILA 使 XADC 生成的数据能够与我们稍后在 DDR 存储器中看到的数据进行对比。然后,信号通过 AXI Virtual FIFO Controller进入 DDR。
![](https://cdn.eetrend.com/files/2022-11/wen_zhang_/100565483-277770-4.png)
输出路径类似。它从 DDR 通过 SMC 进入 AXI Virtual FIFO Controller,然后输出到 AXI Stream FIFO,MicroBlaze 就可以访问它。
![](https://cdn.eetrend.com/files/2022-11/wen_zhang_/100565483-277771-5.png)
将此下载到 FPGA 后,我们可以运行一个简单的 hello world 应用程序,暂停程序,并观察 AXI Virtual FIFO Controller缓冲数据的 DDR 内存位置。
![](https://cdn.eetrend.com/files/2022-11/wen_zhang_/100565483-277772-6.png)
该数据可以通过观察 Vivado ILA 来对比。
![](https://cdn.eetrend.com/files/2022-11/wen_zhang_/100565483-277773-7.png)
输出路径需要 AXI Stream FIFO 断言 Tready 信号。为此,我们需要使用 MicroBlaze 上运行的软件配置 AXI Stream FIFO。
![](https://cdn.eetrend.com/files/2022-11/wen_zhang_/100565483-277774-8.png)
AXI Stream FIFO
在本节中,我们将继续检查输出路径,了解如何使用AXI Stream FIFO 从 DDR 中的 AXI Virtual FIFO Controller读取样本。
![](https://cdn.eetrend.com/files/2022-11/wen_zhang_/100565483-277775-9.png)
AXI Stream FIFO 允许开发人员能够从 AXI 内存映射外设访问 AXI 流,而无需实施完整的 DMA 解决方案。为了实现这一点,AXI Stream FIFO 提供了从 AXI MM 到 AXI 流的读写能力。就像此示例一样,这可用于与AXI Virtual FIFO Controller或 IP 进行交互,例如快速傅里叶变换,它具有通过 AXIS 的配置数据。
为了与我们的设计交互,AXI Stream FIFO 提供了以下接口:
RX Stream Data – 这是要由 AXI Stream FIFO 接收的数据
TX Stream Data — 这是由 AXI Stream FIFO 传输的数据
TX Stream Control Data – 此接口支持 AXI 以太网 IP 内核的传输协议
AXI Lite – 用于访问配置寄存器和数据 Tx 和 Rx 数据的内存映射接口
AXI MM – 用于数据 Tx/Rx 的可选 AXI MM 接口
![](https://cdn.eetrend.com/files/2022-11/wen_zhang_/100565483-277777-11.png)
AXI Stream FIFO 提供了一个简单的寄存器接口,使用户能够定义以下内容:
Transmission Length——要传输的数据的长度
Transmission Vacancy – FIFO 中当前空的位置
Receive Length – 接收到的数据包的长度
Receive Occupancy – FIFO 中占用的插槽数
Receive / Transmission Destination – 边带 AXIS 信号 TIDest
Receive / Transmission ID – Side band AXIS 信号 TId
Receive / Transmission User – Side band AXIS 信号 TUser
系统/传输和接收中断
系统/传输和接收复位
通过写入 FIFO 或从 FIFO 读取的内存地址从 AXI Stream FIFO 写入或读取数据。
在此应用程序中,我们仅使用接收路径使用 MicroBlaze 从 AXI Virtual FIFO Controller读取样本。
在软件中设置非常简单。我们需要在软件中执行以下操作:
配置 AXI Stream FIFO
读取FIFO的占用情况
从 FIFO 中读出指定的字数
在应用软件中根据需要处理样品
#include
#include "platform.h"
#include "xil_printf.h"
#include "xstreamer.h"
#include "xllfifo.h"
#define FIFO_DEV_ID XPAR_AXI_FIFO_0_DEVICE_ID
#define WORD_SIZE 4
XLlFifo_Config *Config;
XLlFifo FifoInstance;
int main()
{
int Status,i;
u32 RxWord;
static u32 ReceiveLength;
init_platform();
Config = XLlFfio_LookupConfig(FIFO_DEV_ID);
XLlFifo_CfgInitialize(&FifoInstance, Config, Config->BaseAddress);
print("Hello World\n\r");
print("Successfully ran Hello World application");
/* Check for the Reset value */
Status = XLlFifo_Status(&FifoInstance);
XLlFifo_IntClear(&FifoInstance,0xffffffff);
Status = XLlFifo_Status(&FifoInstance);
if(Status != 0x0) {
xil_printf("\n ERROR : Reset value of ISR0 : 0x%x\t"
"Expected : 0x0\n\r",
XLlFifo_Status(&FifoInstance));
return XST_FAILURE;
}
while(1){
while(XLlFifo_iRxOccupancy(&FifoInstance)) {
/* Read Receive Length */
ReceiveLength = (XLlFifo_iRxGetLen(&FifoInstance))/WORD_SIZE;
for (i=0; i < ReceiveLength; i++) {
RxWord = XLlFifo_RxGetWord(&FifoInstance);
printf("%x \n\r",RxWord);
}
}
}
cleanup_platform();
return 0;
}
源程序如下:
https://github.com/ATaylorCEngFIET/MZ_439
![](https://cdn.eetrend.com/files/2022-11/wen_zhang_/100565483-277776-10.png)
查看 AXI Virtual FIFO Controlle和 AXI Stream FIFO 后,这些 IP 内核在我们希望缓冲大量数据并与 AXI 流交互而无需 DMA 开销的应用中都非常有用。