FPGA+ARM是ZYNQ的特點,那么PL部分怎么和ARM通信呢,依靠的就是AXI總線。這個實驗是創建一個基于AXI總線的GPIO IP,利用PL的資源來擴充GPIO資源。通過這個實驗迅速入門開發基于總線的系統。
使用的板子是zc702。
AXI總線初識:
AXI (Advanced eXtensible Interface),由ARM公司提出的一種總線協議。總線是一組傳輸通道, 是各種邏輯器件構成的傳輸數據的通道, 一般由數據線、地址線、 控制線構成。Xilinx從6系列的 FPGA 開始對 AXI 總線提供支持, 此時 AXI 已經發展到了 AXI4 這個版本, Vivado里都是基于AIX4的 IP。
ZYNQ支持三種AXI總線,擁有三種AXI接口,用的都是AXI協議:
AXI4:(For high-performance memory-mapped requirements)主要面向高性能地址映射通信的需求,是面向地址映射的接口,允許最大256輪的數據突發傳輸。
AXI4-Lite:(For simple, low-throughput memory-mapped communication)是一個輕量級的地址映射單次傳輸接口, 占用很少的邏輯單元。
AXI4-Stream:(For high-speed streaming data)面向高速流數據傳輸,去掉了地址項,允許無限制的數據突發傳輸。
數據在總線上是遵守協議定的規則來傳輸的,AXI信號傳輸先是傳地址,然后檢測READY+VALID,都為高電平時開始傳數據,當主機發送最后一個數據時LAST信號拉高,通知從機傳輸結束。
在介紹讀寫如何進行前先介紹握手協議:
READY,VALID握手通信機制,主機產生 VLAID 信號來指明何時數據或控制信息有效。從機產生 READY 信號來指明已經準備好接受數據或控制信息。傳輸發生在 VALID和 READY 信號同時為高的時候。(還有一個LAST信號表示什么時候傳到最后一個數據了)
讀時序:地址線上發來地址,地址準備和地址有效都高時,開始發送要讀的數據,讀準備和讀有效都高時數據被讀取到,發最后一個數據時讀LAST信號拉高。
寫時序:地址線上發來地址,地址準備和地址有效都高時,開始發送要寫的數據,寫準備和寫有效都高時數據寫入,發最后一個數據時寫LAST信號拉高。寫數據多了一個反饋信號,反饋給主機,主機接收到這個信號,就知道寫成功了。
這個協議可以暫時不去理清,知道大致信號關系,后面會通過觀察波形進一步加深印象,這次實驗的重點是學習通過編程操作寄存器完成讀寫!
第一步,創建AXI總線IP
新建一個工程,Tools-->Create and Pacakge IP-->選擇Create AXI4 Peripheral
創建完以后(起個易理解的名字,放到能找到的路徑下),有三項需要設置:接口類型,數據類型和寄存器數量
我們按默認這是就好,記住這里的設置:選擇AXI_Lite總線,數據位寬是32位,也就是4字節,寄存器4個,實際我們用到的只有一個,但這里最低要求4個,沒關系,多出的不用就是,待會我們就要通過操作寄存器完成對數據的讀寫。
然后選擇Edit IP,
打開ip的工程后,先打開這個文件:
這個就是基于AXI_Lite總線協議的模塊,可以看到我們設置的數據位寬和寄存器數量:
AXI總線向寄存器寫數據:
AXI總線下讀寄存器的數據:
然后打開頂層文件:
將添加的信號加上去:
保存,Tools-->Create and Package IP:
overwrite原來的文件。
在IP自己創建的工程文件夾里,打包好的IP就是這個文件夾,可以將其拷貝放到任意地方:
至此,基于AXI_Lite總線的IP就完成了。可以將這個文件夾拷到你之前建的工程目錄下,我是放在myip文件夾下。
第二步,使用基于AXI總線的IP
將我們自定義的IP添加到庫里:
添加我們自己創建的IP,然后點擊自動連接:
會自動出現互聯模塊和復位模塊,互聯模塊主要是起管理主從設備的作用:
本來我們還應該添加邏輯分析儀觀察AXI總線的各信號波形,但是為了先上手體驗怎么開發基于AXI的系統,我們先略過,放在下一個實驗中。
再點擊Run Block Automatiom:
將LED信號也輸出出來,右擊GPIO_LED,Make External。
右擊空白處,選擇Regenerate layout,美化一下排版:
這樣我們的系統就搭建成功了,下面就是一些例行操作:
檢驗一下我們的設計:
保存一下我們的設計:
右鍵bd文件,復位一下系統,Reset Output Products:
右鍵bd文件,Geberate Output Products,
右鍵bd文件,Create HDL Wrapper。
然后就是添加管腳約束,把GPIO_LED信號連接到LED燈上:
zc702的管教約束如下:
#GPIO PMOD1
set_property PACKAGE_PIN E15 [get_ports {GPIO_LED[7]}]
set_property IOSTANDARD LVCMOS25 [get_ports {GPIO_LED[7]}]
set_property PACKAGE_PIN D15 [get_ports {GPIO_LED[6]}]
set_property IOSTANDARD LVCMOS25 [get_ports {GPIO_LED[6]}]
set_property PACKAGE_PIN W17 [get_ports {GPIO_LED[5]}]
set_property IOSTANDARD LVCMOS25 [get_ports {GPIO_LED[5]}]
set_property PACKAGE_PIN W5 [get_ports {GPIO_LED[4]}]
set_property IOSTANDARD LVCMOS25 [get_ports {GPIO_LED[4]}]
#GPIO PMOD2
set_property PACKAGE_PIN V7 [get_ports {GPIO_LED[3]}]
set_property IOSTANDARD LVCMOS25 [get_ports {GPIO_LED[3]}]
set_property PACKAGE_PIN W10 [get_ports {GPIO_LED[2]}]
set_property IOSTANDARD LVCMOS25 [get_ports {GPIO_LED[2]}]
set_property PACKAGE_PIN P18 [get_ports {GPIO_LED[1]}]
set_property IOSTANDARD LVCMOS25 [get_ports {GPIO_LED[1]}]
set_property PACKAGE_PIN P17 [get_ports {GPIO_LED[0]}]
set_property IOSTANDARD LVCMOS25 [get_ports {GPIO_LED[0]}]
添加完先綜合一下,看看連線有沒有錯誤。綜合完成生成比特流文件。
至此,大功告成,下面就到了本實現的重點,進入SDK寫代碼來讀寫寄存器!
將硬件系統信息和bit文件導入SDK:
然后Lanch SDK,新建一個空的工程:
在src文件下建一個c文件:
c大家都知道,用到什么函數要將這個函數所在的文件添加到頭文件,這類先把頭文件添加進去:
#include
#include "xparameters.h"
#include "xil_io.h"
#include "sleep.h"
#include "xil_types.h"
Xinlin提供的讀函數是Xil_Out32((BaseAddr) + (u32)(RegOffset)),寫函數是Xil_Out32((BaseAddr) + (u32)(RegOffset), (u32)(Data)),讀寫都是相對于Master而言的,讀當然是In,寫當然是Out了。
前面我們提到了,讀寫是對我們定義的寄存器操作,我們這里8個led燈,只要用到寄存器0的低8位就可以了。既然要操作寄存器,肯定要知道寄存器的地址,所有設備的地址都放在bsp文件下的include文件里的xparameters.h文件里,并且以宏定義,方便調用:
例如我們的自定義IP在這里,GPIO_Zhu,第一個是基地址,第二個是最高地址,:
寄存器0所在地址就是基地址,偏移量為0,因為我們定義的位寬是32位,4個字節,寄存器1所在地址就是基地址+4,依次類推。
這里我們讓8個Led燈依次閃爍,1秒移動一次,并讀取寄存器的數據打印到串口:
#include
#include "xparameters.h"
#include "xil_io.h"
#include "sleep.h"
#include "xil_types.h"
int main(){
u8 i=0;
u8 ledValue=0;
Xil_Out32(XPAR_GPIO_ZHU_V1_0_0_BASEADDR+0*4,0X00);
while(1){
for(i=0;i Xil_Out32(XPAR_GPIO_ZHU_V1_0_0_BASEADDR+0*4,1 ledValue=Xil_In32(XPAR_GPIO_ZHU_V1_0_0_BASEADDR+0*4);
xil_printf("ledValue=%x/r/n",ledValue); //打印到串口
sleep(1); //1s移動一次
}
i=0;
}
}
板子上電,連接好,以Debug方式運行:
下載好后,打開串口:
點擊開始運行:
Led開始依次閃爍了!,并且在串口看到打印出的數據:
至此,實驗成功,開啟了我們ARM+FPGA開發之路!以后可以嘗試開發更復雜的系統。
編輯:hfy
-
Xilinx
+關注
關注
73文章
2177瀏覽量
123723 -
AXI
+關注
關注
1文章
132瀏覽量
16997
發布評論請先 登錄
相關推薦
基于小凌派RK2206開發板:OpenHarmony如何使用IoT接口控制GPIO外設

一文詳解Video In to AXI4-Stream IP核

16通道AD采集方案,基于復旦微ARM + FPGA國產SoC處理器平臺

ARM開發板與FPGA的結合應用
AMBA AXI4接口協議概述

實測52.4MB/s!全國產ARM+FPGA的CSI通信案例分享!
國產RK3568J基于FSPI的ARM+FPGA通信方案分享
FPGA的IP軟核使用技巧
SoC設計中總線協議AXI4與AXI3的主要區別詳解

評論