Xilinx Vivado中提供了AXI FIFO和AXI virtual FIFO類似IP,這篇文章主要通過實例來講解這兩個IP的使用方法。
FIFO 是我們設計中常用的工具,因為它們使我們能夠在進行信號和圖像處理時緩沖數據。我們還使用異步FIFO來處理數據總線的時鐘域交叉問題。

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 接口提供。

使用這些接口,AXI Virtual FIFO Controller能夠在 DDR 中創建一個 FIFO,并且能夠存儲比使用內部 BRAM 更大數量的數據。
AXI Virtual FIFO Controller能夠將多個通道數據存儲在外部 DDR 中。需要注意的一件事是內存位置與其他內存使用(例如,MicroBlaze 應用程序)可能會發生沖突。在 IP 定制時,我們能夠分配的空間需要注意。

接下來創建一個以 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。

輸出路徑類似。它從 DDR 通過 SMC 進入 AXI Virtual FIFO Controller,然后輸出到 AXI Stream FIFO,MicroBlaze 就可以訪問它。

將此下載到 FPGA 后,我們可以運行一個簡單的 hello world 應用程序,暫停程序,并觀察 AXI Virtual FIFO Controller緩沖數據的 DDR 內存位置。

該數據可以通過觀察 Vivado ?ILA 來對比。

輸出路徑需要 AXI Stream FIFO 斷言 Tready 信號。為此,我們需要使用 MicroBlaze 上運行的軟件配置 AXI Stream FIFO。
在本節中,我們將繼續檢查輸出路徑,了解如何使用AXI Stream FIFO 從 DDR 中的 AXI Virtual FIFO Controller讀取樣本。

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 接口

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?
???RxWord?=?XLlFifo_RxGetWord(&FifoInstance);
???printf("%x?\n\r",RxWord);
??}
?}
}
????cleanup_platform();
????return?0;
}
源程序如下:
https://github.com/ATaylorCEngFIET/MZ_439

查看 AXI Virtual FIFO Controlle和 AXI Stream FIFO 后,這些 IP 內核在我們希望緩沖大量數據并與 AXI 流交互而無需 DMA 開銷的應用中都非常有用。
END
往期精選?
?
?

FPGA技術江湖廣發江湖帖
無廣告純凈模式,給技術交流一片凈土,從初學小白到行業精英業界大佬等,從軍工領域到民用企業等,從通信、圖像處理到人工智能等各個方向應有盡有,QQ微信雙選,FPGA技術江湖打造最純凈最專業的技術交流學習平臺。
FPGA技術江湖微信交流群

加群主微信,備注姓名+公司/學校+崗位/專業進群
FPGA技術江湖QQ交流群

備注姓名+公司/學校+崗位/專業進群
