ZYNQ概述
ZYNQ內部包含PS和PL兩部分,PS中包含以下4個主要功能模塊:
- Application processor unit (APU)
- Memory interfaces
- I/O peripherals (IOP)
- Interconnect
ZYNQ內部的總體框架如所示,PS中包含2個ARM Cortex-9的內核,一些基本的外設擴展口以及Memory接口。PS和PL的相互通信通過兩個通路完成,分別是GP(General Purpose)Ports和HP(High Performance)Ports。
GP Ports包含2個Master接口和2個Slave接口,符合標準的AXI協議數據位寬是32bit。HP Ports包含4個接口,全部是PL作為Master;有兩個專用的連接到DDR Controller的接口和一個連接到OCM的接口。HP與GP相比,最大的特點在于有額外的FIFO作為Buffer,可以提高傳輸效率和數據吞吐量。
所以從功能角度,GP Ports主要用于寄存器的讀寫以及小數據量的傳輸;HP Ports用于大量數據的傳輸,主要是Memory數據的讀寫。
ZYNQ中最常用的設計思路是將主程序放在PS中完成,在PL中設計相應的邏輯功能作為PS的外設使用,將邏輯設計封裝成IP,且每個IP都包含一個標準的AXI-Lite接口。PS對于邏輯設計的控制是通過控制邏輯設計的功能寄存器,進而控制邏輯設計進行相應的操作,同時將工作情況通過狀態寄存器返回給PS端。如果邏輯設計與PS端需要進行大量數據的交互,則會在邏輯設計中增加AXI-Full接口,與PS的HP Port相連。
綜上,ZYNQ設計的基本流程包含以下步驟:
1. Vivado中搭建ZYNQ平臺,完成基本外設控制。
2. 創建邏輯設計,并封裝成IP。
3. ZYNQ設計中調用封裝的IP。
4. 對設計的IP進行仿真。
ZYBO開發板簡介
ZYBO是Digilent開發的以XC7Z010-1CLG400C為核心處理器的開發板,其主要功能包括有:
- 1片32bit位寬,512MB容量的 DDR3
- 1個 HDMI port
- 1個VGA source port
- 1個(1Gbit/100Mbit/10Mbit) Ethernet PHY 與RJ45接口
- 1個MicroSD slot
- 1個OTG USB 2.0 PHY
- 1個外部 EEPROM
- 1個耳機輸出接口和1個麥克風輸入接口
- 1片128Mb QSPI Flash作為加載Flash
- 1個JTAG接口和1個USB-Converter下載接口
- GPIO: 6 pushbuttons, 4 slide switches, 5 LEDs
- 6個 Pmod ports
其板上器件分布情況如圖 2和圖 3所示。
Vivado中進行ZYNQ硬件部分設計
Step1: Viavdo中選擇XC7Z010-1CLG400器件,建立工程。
Step2: 建立Block Design。
Step3: 加入ZYNQ7 Processing System和其他所需要的外設IP。
點擊“Add IP”,加入ZYNQ7 Processing System和AXI GPIO,雙擊IP可以對其進行配置。該實驗中ZYNQ7配置使能UART,引腳為MIO48和49,其ZYBO相關電路圖如圖 5所示。(注:如果需要在Step11中選擇Hello World工程,則需要使能UART)。AXI GPIO的位寬設置為4,其余為默認配置。
注意:這里有個地方非常容易出錯。在Vivado建立工程選擇器件的過程中沒有選擇ZYBO開發板的配置,而是直接選擇的XC7Z010-1CLG400C器件的配置。系統默認的ZYNQ7 Processing System配置中Input Clock Frequency是33.3333MHz,而ZYBO板上為50MHz。此處必須修改過來,否則后面的系統時鐘會完全錯亂,導致軟件工程無法運行。
Step4: 點擊“Run Block Automation”,其作用是完成ZYNQ7 Processing System專用引腳的連接,包括FIXED_IO和DDR引腳的連接。
Step5: 點擊“Run Connection Automation”,其作用是自動完成ZYNQ與外設的連接,連接是按照工具對于用戶所設計系統的理解,如果需要進行修改,可以手動更改Block中的連線。該操作工具會默認增加:
1. AXI interconnect
2. Processor System Reset
3. 自動完成了外設IP的AXI-Lite端口與ZYNQ7 Processing System的連接,默認接法是ZYNQ的FCLK_CLK0作為外設AXI時鐘,Processor System Reset產生外設復位信號連接到所有外設的復位端口。
4. 將AXI GPIO的引腳引出。
可以使用“Regenerate Layout”,重新布局Block Design。
Step6: 在“Address Editor”中查看、修改外設在總線上的地址。
Step7: 首先在Block design界面右擊彈出的菜單中點擊Validate Design,以驗證Block Design的設計和連接是否有錯誤。至此Block Design完成了,但是還需要根據Block Design的配置生成相應的源代碼。右擊.bd設計,并選擇“Create HDL Wrapper”。隨后即生成了相應的HDL代碼。
Step8: 對于PL端的外接引腳,需要設置相應的Constraints。
Step9: 與普通FPGA設計一樣,完成Synthesis、Implementation和Generate Bitstream。
Step10: 將Step9中完成的硬件設計導入到SDK開發平臺下。
Step11: 從這一步開始,開發平臺轉移到SDK平臺。此時硬件平臺已經確定,接下來是軟件的開發。首先在SDK中建立軟件工程。
Step12: 在新建工程中完成C代碼的設計。
#include
#include
#include "xparameters.h"
#include "sleep.h"
#include "platform.h"
int main()
{
XGpio output;
int Status;
/*
* Initialize the GPIO driver so that it's ready to use,
* specify the device ID that is generated in xparameters.h
*/
Status = XGpio_Initialize(&output, XPAR_GPIO_0_DEVICE_ID);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* Set the direction for all signals to be outputs */
XGpio_SetDataDirection(&output, 1, 0x0);
init_platform();
while(1){
usleep(200000); //delay
XGpio_DiscreteWrite(&output, 1, 0x0);
usleep(200000); //delay
XGpio_DiscreteWrite(&output, 1, 0xF);
};
cleanup_platform();
return 0;
}
Step13: 首先點擊“Program FPGA”,將硬件平臺下載到ZYNQ中。
Step14: 運行軟件工程進行調試。
在ZYBO板上也能看到LED燈閃爍,至此完成了ZYNQ的一個基本設計的所有開發流程。
DK中進行ZYNQ軟件部分設計
首先對“Vivado中進行ZYNQ硬件部分設計”中讓LED閃爍的C代碼做詳細的注釋。
int main()
{
/*定義外設對于的類型指針,用于綁定外設,便于后面程序調用時選擇
* 外設
*/
XGpio output;
int Status;
/* XGpio_Initialize()函數是xgpio.c中的函數,在BSP Documentation可以
* 查到該函數的描述。
* int XGpio_Initialize(XGpio * InstancePtr, u16 DeviceId)
* InstancePtr為GPIO類型的指針
* DeviceId是在板級配置中已經定義好的外設的ID,該定義包含在BSP的xparameters.h中
* 即在xparameters.h已經為該硬件設計中的每一種類型的多個外設設置了唯一的ID
* 例如設計中如果有2個GPIO外設,則ID分別為0和1.
* 該語句完成之后將ID對應的外設對象與該指針進行了綁定,后面可以通過調用該指針指
* 定到該外設
*/
Status = XGpio_Initialize(&output, XPAR_GPIO_0_DEVICE_ID);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* void XGpio_SetDataDirection (XGpio * InstancePtr,
* unsigned Channel,u32 DirectionMask )
* InstancePtr:外設指針,用于指定到對應的外設設備,已經與外設綁定
* Channel: 每個AXI_GPIO中可以有兩個32bit的GPIO端口,該參數用來
* 選擇是該外設中的哪一個端口
* DirectionMask:選擇GPIO的方向,0為output,1為input
* 該函數的作用是設置GPIO的方向,如前所述,可以通過output指定到
* 該GPIO外設,
*/
XGpio_SetDataDirection(&output, 1, 0x0);
//初始化ARM內核
init_platform();
while(1){
usleep(200000); //delay
XGpio_DiscreteWrite(&output, 1, 0x0);
usleep(200000); //delay
XGpio_DiscreteWrite(&output, 1, 0xF);
};
cleanup_platform();
return 0;
}
以上調用的這些函數,其定義及使用方法全部可以在BSP(Board Support Package)板級支持包中找到。當在Vivado平臺中設計完成硬件,將其導入到SDK平臺時,工具會根據硬件設計中使用到的外設,自動生成相應的板級支持包。在SDK的“Project Explorer”界面中可以查看,并且可以在其中打開相應的BSP說明文檔,如圖 18所示。
但是雖然BSP中提供了所有相關的API函數,但是對于初學者來說,想搭建一個可以實現基本功能的平臺還是有些困難。于是另一個方法是利用SDK生成新的Application時提供的Peripheral Test模板。
該模板生成的代碼中,在主函數中找到相應外設的測試函數,例如本例中GPIO的測試函數“GpioOutputExample()”,再通過追述該函數的具體實現,可以一定程度上作為最基本的范例代碼。
如果再進一步深入到ARM編程的本質,其實與硬件的所有控制和通信都是依靠讀寫底層的寄存器來完成的。例如如果查看一下“XGpio_SetDataDirection()”函數的底層實現,可以發現逐級調用的分別是“XGpio_WriteReg()”函數和“XGpio_Out32()”函數,而“XGpio_Out32()”調用的是“Xil_Out32()”。 其實“Xil_Out32()”和“Xil_In32()”這兩個函數分別是寫讀底層硬件寄存器的兩個函數,所有的上層與底層的寄存器級別的通信,也就是絕大多數的外設控制,都是依靠這兩個函數完成的。
-
FPGA
+關注
關注
1643文章
21969瀏覽量
614279 -
寄存器
+關注
關注
31文章
5422瀏覽量
123403 -
Zynq
+關注
關注
10文章
614瀏覽量
48033 -
Vivado
+關注
關注
19文章
830瀏覽量
68246
發布評論請先 登錄
如何將CCG3上的“啟用固件更新”部分設置為“是”?
e203在vivado硬件里自定義指令識別為非法指令怎么解決?
ZYNQ基礎---AXI DMA使用

硬件電路的設計思路

LM4890采用差分設計方案,為什么沒有聲音?怎么解決?
Vivado使用小技巧

評論