彩票真人網(wǎng)站建設(shè)有什么功能
1)實(shí)驗(yàn)平臺(tái):正點(diǎn)原子MPSoC開發(fā)板
2)平臺(tái)購(gòu)買地址:https://detail.tmall.com/item.htm?id=692450874670
3)全套實(shí)驗(yàn)源碼+手冊(cè)+視頻下載地址: http://www.openedv.com/thread-340252-1-1.html
第二十章AXI4接口之DDR讀寫實(shí)驗(yàn)
Xilinx從Spartan-6和Virtex-6系列開始使用AXI協(xié)議來(lái)連接IP核。在ZYNQ MPSOC器件中,Xilinx在IP核中繼續(xù)使用AXI協(xié)議。本章我們對(duì)AXI協(xié)議作一個(gè)簡(jiǎn)單介紹,并在Vivado中實(shí)現(xiàn)一個(gè)AXI4接口的IP核,用于對(duì)MPSOC PS端的DDR4進(jìn)行讀寫測(cè)試。
本章包括以下幾個(gè)部分:
2020.1簡(jiǎn)介
20.2實(shí)驗(yàn)任務(wù)
20.3硬件設(shè)計(jì)
20.4軟件設(shè)計(jì)
20.5下載驗(yàn)證
20.1簡(jiǎn)介
MPSOC將高性能ARM Cotex-A系列處理器與高性能FPGA在單芯片內(nèi)緊密結(jié)合,為設(shè)計(jì)帶來(lái)了如減小體積和功耗、降低設(shè)計(jì)風(fēng)險(xiǎn),增加設(shè)計(jì)靈活性等諸多優(yōu)點(diǎn)。在將不同工藝特征的處理器與FPGA融合在一個(gè)芯片上之后,片內(nèi)處理器與FPGA之間的互聯(lián)通路就成了MPSOC芯片設(shè)計(jì)的重中之重。如果Cotex-A53與FPGA之間的數(shù)據(jù)交互成為瓶頸,那么處理器與FPGA結(jié)合的性能優(yōu)勢(shì)就不能發(fā)揮出來(lái)。
我們?cè)谇懊娴膶?shí)驗(yàn)中介紹了一些MPSOC PS與PL交互所使用的接口,比如《EMIO按鍵控制LED實(shí)驗(yàn)》中的EMIO,以及《AXI GPIO按鍵控制LED實(shí)驗(yàn)》中的AXI4-Lite接口等。其中AXI4-Lite接口屬于AXI4總線協(xié)議,接下來(lái)我們將對(duì)該協(xié)議作一個(gè)更具體的介紹。
AXI的英文全稱是Advanced eXtensible Interface,即高級(jí)可擴(kuò)展接口,它是ARM公司所提出的AMBA(Advanced Microcontroller Bus Architecture)協(xié)議的一部分。在介紹AXI協(xié)議之前,我們首先要對(duì)通信協(xié)議有一個(gè)基本的概念。
簡(jiǎn)單來(lái)說(shuō),通信協(xié)議就是指雙方進(jìn)行信息傳遞所遵循的規(guī)則和約定。其實(shí)在我們的生活當(dāng)中,比如在打電話的時(shí)候,就遵循著一些基本的“通信協(xié)議”。為了更形象的說(shuō)明這一概念,我們首先來(lái)看一個(gè)通話記錄:
《少林寺的通話記錄》
老方丈:下午張三豐和滅絕師太要來(lái)參觀,你去機(jī)場(chǎng)接一下,我把他倆手機(jī)號(hào)給你 //主機(jī)發(fā)送控制信號(hào)
小和尚:好的,稍等,我找張紙記一下。
老方丈:嗯。 //主機(jī)等待
小和尚:我準(zhǔn)備好了,您說(shuō)吧。 //從機(jī)返回Ready信號(hào)
老方丈:張三豐的是“123-321-34567”,滅絕師太的是“123-456-56789”。 //主機(jī)突發(fā)傳輸數(shù)據(jù)
小和尚:記下來(lái)了。 //從機(jī)返回響應(yīng)信號(hào)
上面的通話記錄是一次完整的通信過(guò)程,傳輸?shù)男畔⑹莾蓚€(gè)手機(jī)號(hào)。我們把“老方丈”當(dāng)成主機(jī),“小和尚”當(dāng)成從機(jī),那么這一通信過(guò)程由主機(jī)發(fā)起,最終向從機(jī)寫入兩組數(shù)據(jù)(手機(jī)號(hào))。我們需要注意的是整個(gè)過(guò)程中二者的協(xié)調(diào)配合:為了確保數(shù)據(jù)傳輸無(wú)誤,主機(jī)需要等從機(jī)準(zhǔn)備好之后才能發(fā)送數(shù)據(jù);另外從機(jī)在接收數(shù)據(jù)完成后,會(huì)發(fā)送響應(yīng)信號(hào),表示傳輸完成。
然后再來(lái)看另外一個(gè)通話記錄:
《武當(dāng)山的通話記錄》
張三豐:下午我要去趟少林寺,你把方丈的手機(jī)號(hào)找給我 //主機(jī)發(fā)送控制信號(hào)
小道士:找到了,188-666…… //從機(jī)返回有效數(shù)據(jù)
張三豐:等一下,我找支筆。好了,你說(shuō)吧 //主機(jī)發(fā)送Ready信號(hào)
小道士:188-666-66666,念完了 //從機(jī)返回有效數(shù)據(jù),以及響應(yīng)信號(hào)
張三豐:好的。
在武當(dāng)山的通話記錄中,張三豐是主機(jī),小道士是從機(jī)。通信過(guò)程同樣是由主機(jī)發(fā)起,向從機(jī)請(qǐng)求數(shù)據(jù)。主機(jī)準(zhǔn)備好之后發(fā)送Ready信號(hào),接下來(lái)從機(jī)開始發(fā)送數(shù)據(jù)。從機(jī)在數(shù)據(jù)發(fā)送完成后給出響應(yīng)信號(hào),表明本次傳輸結(jié)束。
對(duì)比上述兩個(gè)通話記錄可以發(fā)現(xiàn),少林寺的通話是一次主機(jī)向從機(jī)寫數(shù)據(jù)的過(guò)程,而武當(dāng)山的通話則是主機(jī)向從機(jī)讀數(shù)據(jù)的過(guò)程。在通信過(guò)程中,主從之間會(huì)進(jìn)行協(xié)調(diào),只有等接收方準(zhǔn)備好之后,才能開始數(shù)據(jù)傳輸,這種機(jī)制我們稱之為“握手”。
在打電話的時(shí)候,通話雙方能夠理解彼此的語(yǔ)言,進(jìn)而從中篩選有效信息。而在數(shù)字電路中,通信雙方就沒有那么智能了,主設(shè)備和從設(shè)備需要按照約定好的數(shù)據(jù)傳輸方式來(lái)發(fā)送和接收數(shù)據(jù)。AXI協(xié)議就是描述了主設(shè)備和從設(shè)備之間的數(shù)據(jù)傳輸方式,在該協(xié)議中,主設(shè)備和從設(shè)備之間通過(guò)握手信號(hào)建立連接。
AXI協(xié)議是一種高性能、高帶寬、低延遲的片內(nèi)總線,具有如下特點(diǎn):
1、總線的地址/控制和數(shù)據(jù)通道是分離的;
2、支持不對(duì)齊的數(shù)據(jù)傳輸;
3、支持突發(fā)傳輸,突發(fā)傳輸過(guò)程中只需要首地址;
4、具有分離的讀/寫數(shù)據(jù)通道;
5、支持顯著傳輸訪問(wèn)和亂序訪問(wèn);
6、更加容易進(jìn)行時(shí)序收斂。
在數(shù)字電路中只能傳輸二進(jìn)制數(shù)0和1,因此可能需要一組信號(hào)才能高效地傳輸信息,這一組信號(hào)就組成了接口。AXI4協(xié)議支持以下三種類型的接口:
1、AXI4:高性能存儲(chǔ)映射接口。
2、AXI4-Lite:簡(jiǎn)化版的AXI4接口,用于較少數(shù)據(jù)量的存儲(chǔ)映射通信。
3、AXI4-Stream:用于高速數(shù)據(jù)流傳輸,非存儲(chǔ)映射接口。
在這里我們首先解釋一下存儲(chǔ)映射(Meamory Map)這一概念。如果一個(gè)協(xié)議是存儲(chǔ)映射的,那么主機(jī)所發(fā)出的會(huì)話(無(wú)論讀或?qū)?#xff09;就會(huì)標(biāo)明一個(gè)地址。這個(gè)地址對(duì)應(yīng)于系統(tǒng)存儲(chǔ)空間中的一個(gè)地址,表明是針對(duì)該存儲(chǔ)空間的讀寫操作。
AXI4協(xié)議支持突發(fā)傳輸,主要用于處理器訪問(wèn)存儲(chǔ)器等需要指定地址的高速數(shù)據(jù)傳輸場(chǎng)景。AXI-Lite為外設(shè)提供單個(gè)數(shù)據(jù)傳輸,主要用于訪問(wèn)一些低速外設(shè)中的寄存器。而AXI-Stream接口則像FIFO一樣,數(shù)據(jù)傳輸時(shí)不需要地址,在主從設(shè)備之間直接連續(xù)讀寫數(shù)據(jù),主要用于如視頻、高速AD、PCIe、DMA接口等需要高速數(shù)據(jù)傳輸?shù)膱?chǎng)合。
在本章我們重點(diǎn)介紹AXI4接口,它由五個(gè)獨(dú)立的通道構(gòu)成:
1、讀地址
2、讀數(shù)據(jù)
3、寫地址
4、寫數(shù)據(jù)
5、寫響應(yīng)
下面是使用讀地址和讀數(shù)據(jù)通道實(shí)現(xiàn)讀傳輸過(guò)程的示意圖:
圖 20.1.1 讀傳輸過(guò)程示意圖
從圖 20.1.1中可以看到,在一個(gè)讀傳輸過(guò)程中,主機(jī)首先在讀地址通道給出讀地址和控制信號(hào),然后從機(jī)由讀數(shù)據(jù)通道返回讀出的數(shù)據(jù)。另外我們需要注意的是,這是一次突發(fā)讀操作,主機(jī)只給出一個(gè)地址,從該地址連續(xù)突發(fā)讀出四個(gè)數(shù)據(jù)。
寫傳輸過(guò)程如圖 20.1.2所示,它用到了寫地址、寫數(shù)據(jù)和寫響應(yīng)三個(gè)通道。主機(jī)在寫地址通道給出寫地址和控制信號(hào),然后在寫數(shù)據(jù)通道連續(xù)突發(fā)寫四個(gè)數(shù)據(jù)。從機(jī)在接收數(shù)據(jù)之后,在寫響應(yīng)通道給出響應(yīng)信號(hào)。
圖 20.1.2 寫傳輸過(guò)程示意圖
AXI總線中的每個(gè)通道都包含了一組信息信號(hào),還有一個(gè)VALID和一個(gè)READY信號(hào)。VALID信號(hào)由源端(source)產(chǎn)生,表示當(dāng)前地址或者數(shù)據(jù)線上的信息是有效的;而READY信號(hào)由目的端(destination)產(chǎn)生,則表示已經(jīng)準(zhǔn)備好接收地址、數(shù)據(jù)以及控制信息。VALID和READY信號(hào)提供了AXI總線中的握手機(jī)制,如下圖所示:
圖 20.1.3 VALID和READY握手機(jī)制
在圖 20.1.3中,ACLK為時(shí)鐘信號(hào),在AXI協(xié)議中,所有的輸入信號(hào)都是在ACLK的上升沿采樣,所有的輸出信號(hào)必須在ACLK的上升沿之后才能改變。在T1之后,源端將VALID拉高,表明INFORMATION信號(hào)線上傳輸?shù)氖怯行У牡刂?、?shù)據(jù)或者控制信息。目的端在T2之后將READY拉高,表明它已經(jīng)準(zhǔn)備好接收數(shù)據(jù),此時(shí)源端必須保持INFORMATION數(shù)據(jù)穩(wěn)定不變,直到T3時(shí)刻進(jìn)行數(shù)據(jù)傳輸。
需要注意的是,源端不允許等目的端的READY信號(hào)拉高之后,才將VALID信號(hào)置為有效狀態(tài)。而且,一旦VALID拉高,源端必須保持其處于有效狀態(tài),直至成功握手(在時(shí)鐘上升沿檢測(cè)到VALID和READY同時(shí)為有效狀態(tài))。
AXI協(xié)議的五個(gè)通道都有各自的VALID/READY握手信號(hào)對(duì),每個(gè)通道握手信號(hào)對(duì)的名稱如下圖所示:
圖 20.1.4 各通道握手信號(hào)名稱
到這里,我們已經(jīng)簡(jiǎn)單介紹了AXI4協(xié)議的讀寫過(guò)程,以及握手協(xié)議。關(guān)于如何實(shí)現(xiàn)AXI4通信協(xié)議,以及如何在設(shè)計(jì)中使用該協(xié)議進(jìn)行通信,我們將在硬件設(shè)計(jì)部分進(jìn)行講解。
20.2實(shí)驗(yàn)任務(wù)
本章的實(shí)驗(yàn)任務(wù)是通過(guò)自定義一個(gè)AXI4接口的IP核,通過(guò)AXI_HP接口對(duì)PS端DDR4進(jìn)行讀寫測(cè)試。
20.3硬件設(shè)計(jì)
根據(jù)實(shí)驗(yàn)任務(wù)我們可以畫出本次實(shí)驗(yàn)的系統(tǒng)框圖,如下圖所示:
圖 20.3.1 系統(tǒng)框圖
在圖 20.3.1中,DDR Test是我們自定義的IP核,具有AXI4 Master端口,該端口通過(guò)AXI Smartconnect模塊,最終連接到PS端的Slave AXI_HP端口。輸入的按鍵控制DDR Test模塊對(duì)PS的DDR4進(jìn)行讀寫測(cè)試,并在讀寫測(cè)試結(jié)束后,通過(guò)兩個(gè)PL LED燈分別指示讀寫完成和讀寫錯(cuò)誤。需要說(shuō)明的是,DDR Test模塊通過(guò)輸入信號(hào)的上升沿作為對(duì)DDR4讀寫測(cè)試的觸發(fā)信號(hào),需要對(duì)輸入的按鍵信號(hào)進(jìn)行消抖,否則會(huì)導(dǎo)致讀寫錯(cuò)誤。
首先創(chuàng)建Vivado工程,工程名為“axi4_ddr_rw”,然后創(chuàng)建Block Design設(shè)計(jì)(design_1.bd)并添加Zynq UltraScale+ MPSOC模塊。接下來(lái)按照《“Hello World”實(shí)驗(yàn)》中的步驟2-7、2-8分別配置PS的UART和DDR控制器。需要特別注意的是,我們?cè)凇丁癏ello World”實(shí)驗(yàn)》的步驟2-10中,移除了PS中與PL端交互的接口信號(hào),在我們本次實(shí)驗(yàn)中要保留時(shí)鐘“PL Fabric Clocks”和復(fù)位“Fabric Reset Enable”信號(hào)。
由于本次實(shí)驗(yàn)用到了PS端的HP接口,因此在Zynq UltraScale+ MPSOC模塊的配置界面左側(cè)點(diǎn)擊“PS-PL Configuration”標(biāo)簽,然后依次展開右側(cè)界面中PS-PL Interfaces-> Slave Interface->AXI HP,勾選“AXI HP0 FPD”,如下圖所示:
圖 20.3.2 PS-PL接口配置
最后點(diǎn)擊右下角的“OK”,本次實(shí)驗(yàn)Zynq UltraScale+ MPSOC模塊就配置完成了。
Zynq UltraScale+ MPSOC模塊配置完成后其接口如下圖所示:
圖 20.3.3 Zynq UltraScale+ MPSOC模塊接口
在圖 20.3.3中,S_AXI_HP0_FPD是PS端的AXI高性能接口,它是一個(gè)從接口,連接到PS內(nèi)的存儲(chǔ)器互聯(lián),用于PL訪問(wèn)PS內(nèi)的存儲(chǔ)設(shè)備,包括OCM和DDR。
在本次實(shí)驗(yàn)中,PS內(nèi)的數(shù)據(jù)通路如圖 20.3.4所示。我們?cè)赑L內(nèi)自定義的DDR Test IP核作為主設(shè)備,通過(guò)PS Slave AXI_HP0接口,與DDR控制器進(jìn)行通信,最終對(duì)DDR4存儲(chǔ)器進(jìn)行讀寫操作。
圖 20.3.4 PS內(nèi)的數(shù)據(jù)通路
接下來(lái)我們要在Block Design中添加PL端的自定義IP核。
在添加該IP之前,我們需要先自定義一個(gè)帶有AXI4 Master端口的IP核,并將其添加到工程的IP庫(kù)中。我們?cè)凇蹲远xIP核-呼吸燈實(shí)驗(yàn)》中介紹了如何定義一個(gè)帶有AXI-Lite Slave接口的IP核,在本次實(shí)驗(yàn)中定義IP的方法與之相同,只是這次我們要選擇AXI4 Master接口。
在菜單欄中點(diǎn)擊“Tools”,然后在下拉列表中選擇“Create and Package New IP”,如下圖所示:
圖 20.3.5 創(chuàng)建IP
在彈出的對(duì)話框中直接點(diǎn)擊“Next”,如下圖所示:
圖 20.3.6 創(chuàng)建和封裝IP
在下圖所示的界面中選擇“Create a new AXI4 peripheral”,點(diǎn)擊“Next”:
接下來(lái)設(shè)置IP核的名稱為“axi4_rw_test”,并將IP的路徑修改為當(dāng)前工程路徑下的“ip_repo”文件夾,最后點(diǎn)擊“Next”,如下圖所示:
圖 20.3.7 設(shè)置IP名稱和路徑
在“Add Interfaces”界面中修改接口名稱為“M_AXI”,選擇接口類型為“Full”,接口模式為“Master”,數(shù)據(jù)位寬為“32”。如下圖所示:
圖 20.3.8 自定義IP核接口配置
圖 20.3.8中對(duì)IP核接口的配置與《自定義IP核——呼吸燈實(shí)驗(yàn)》不同,在這里我們新建的IP核作為主機(jī)(Master),除此之外我們使用的接口類型變成了AXI-Full,而不再是AXI-Lite。
設(shè)置完成后點(diǎn)擊上圖中右下角的“Next”。
接下來(lái)在圖 20.3.9中選擇“Edit IP”,最后點(diǎn)擊“Finish”,如下圖所示:
圖 20.3.9 創(chuàng)建外設(shè)
在上圖中點(diǎn)擊“Finish”后會(huì)自動(dòng)打開一個(gè)新的Vivado工程,工程名為“edit_ axi4_rw_test_v1_0”,如圖 20.3.10所示。我們可以在這個(gè)工程中對(duì)創(chuàng)建的IP核——AXI4_RW_TEST進(jìn)行編輯。
圖 20.3.10 Edit IP工程
AXI4接口共有五個(gè)獨(dú)立的通道,每個(gè)通道又有少則幾個(gè),多則十幾個(gè)信號(hào),如果讓我們自己來(lái)實(shí)現(xiàn)這樣一個(gè)接口還是比較復(fù)雜的。不過(guò)大家不用擔(dān)心,我們?cè)趫D 20.3.8中創(chuàng)建AXI4接口的IP時(shí),Vivado提供的IP封裝工具已經(jīng)自動(dòng)幫我們實(shí)現(xiàn)了這樣一個(gè)接口,并提供了一個(gè)示例程序。
在圖 20.3.10中,箭頭所指示的文件實(shí)現(xiàn)了AXI4協(xié)議下的讀寫測(cè)試模塊,我們甚至都不用對(duì)代碼作任何修改,即可實(shí)現(xiàn)對(duì)DDR的讀寫測(cè)試功能。雖然該模塊的代碼看上去比較長(zhǎng)(900多行),但是大多是一些注釋,非常詳盡。大家可以通過(guò)閱讀代碼及注釋,來(lái)學(xué)習(xí)AXI4協(xié)議主機(jī)的實(shí)現(xiàn)方式。
在這里我們只貼出部分代碼:
735 //implement master command interface state machine
736
737 always @ ( posedge M_AXI_ACLK)
738 begin
739 if (M_AXI_ARESETN == 1'b0 )
740 begin
741 // reset condition
742 // All the signals are assigned default values under reset condition
743 mst_exec_state <= IDLE;
744 start_single_burst_write <= 1'b0;
745 start_single_burst_read <= 1'b0;
746 compare_done <= 1'b0;
747 ERROR <= 1'b0;
748 end
749 else
750 begin
751
752 // state transition
753 case (mst_exec_state)
754
755 IDLE:
756 // This state is responsible to wait for user defined C_M_START_COUNT
757 // number of clock cycles.
758 if ( init_txn_pulse == 1'b1)
759 begin
760 mst_exec_state <= INIT_WRITE;
761 ERROR <= 1'b0;
762 compare_done <= 1'b0;
763 end
764 else
765 begin
766 mst_exec_state <= IDLE;
767 end
768
769 INIT_WRITE:
770 // This state is responsible to issue start_single_write pulse to
771 // initiate a write transaction. Write transactions will be
772 // issued until burst_write_active signal is asserted.
773 // write controller
774 if (writes_done)
775 begin
776 mst_exec_state <= INIT_READ;
777 end
778 else
779 begin
780 mst_exec_state <= INIT_WRITE;
781
782 if (~axi_awvalid && ~start_single_burst_write && ~burst_write_active)
783 begin
784 start_single_burst_write <= 1'b1;
785 end
786 else
787 begin
788 start_single_burst_write <= 1'b0; //Negate to generate a pulse
789 end
790 end
791
792 INIT_READ:
793 // This state is responsible to issue start_single_read pulse to
794 // initiate a read transaction. Read transactions will be
795 // issued until burst_read_active signal is asserted.
796 // read controller
797 if (reads_done)
798 begin
799 mst_exec_state <= INIT_COMPARE;
800 end
801 else
802 begin
803 mst_exec_state <= INIT_READ;
804
805 if (~axi_arvalid && ~burst_read_active && ~start_single_burst_read)
806 begin
807 start_single_burst_read <= 1'b1;
808 end
809 else
810 begin
811 start_single_burst_read <= 1'b0; //Negate to generate a pulse
812 end
813 end
814
815 INIT_COMPARE:
816 // This state is responsible to issue the state of comparison
817 // of written data with the read data. If no error flags are set,
818 // compare_done signal will be asseted to indicate success.
819 //if (~error_reg)
820 begin
821 ERROR <= error_reg;
822 mst_exec_state <= IDLE;
823 compare_done <= 1'b1;
824 end
825 default :
826 begin
827 mst_exec_state <= IDLE;
828 end
829 endcase
830 end
831 end //MASTER_EXECUTION_PROC
上面的代碼實(shí)現(xiàn)了一個(gè)狀態(tài)機(jī),其狀態(tài)轉(zhuǎn)換圖如下所示:
圖 20.3.11 狀態(tài)轉(zhuǎn)換圖
系統(tǒng)復(fù)位后,狀態(tài)機(jī)處于初始狀態(tài),在該狀態(tài)下等待外部輸入的啟動(dòng)傳輸脈沖init_txn_pulse。一旦檢測(cè)到init_txn_pulse為高電平,狀態(tài)機(jī)跳轉(zhuǎn)到INIT_WRITE狀態(tài)。
在INIT_WRITE狀態(tài)下,狀態(tài)機(jī)拉高start_single_burst_write信號(hào),來(lái)不斷地啟動(dòng)AXI4 Master接口對(duì)Slave端大小為4KB的存儲(chǔ)空間進(jìn)行突發(fā)寫操作。寫操作完成后,write_done信號(hào)會(huì)拉高,狀態(tài)機(jī)進(jìn)入INIT_READ狀態(tài)。
在INIT_READ狀態(tài)下,狀態(tài)機(jī)拉高start_single_burst_read信號(hào),不斷地啟動(dòng)AXI4 Master接口對(duì)Slave端同一存儲(chǔ)空間進(jìn)行突發(fā)讀操作,同時(shí)將讀出的數(shù)據(jù)與寫入的數(shù)據(jù)進(jìn)行對(duì)比。讀操作完成后,read_done信號(hào)拉高,狀態(tài)機(jī)進(jìn)入INIT_COMPARE狀態(tài)。
在INIT_COMPARE狀態(tài)下,判斷AXI4接口在讀寫過(guò)程中的是否發(fā)生錯(cuò)誤,并將錯(cuò)誤狀態(tài)賦值給ERROR信號(hào),然后將compare_done信號(hào)拉高,表示一次讀寫測(cè)試完成。最后跳轉(zhuǎn)到IDLE狀態(tài),等待下一次讀寫操作的啟動(dòng)信號(hào)。
我們?cè)诓榭戳藞D 20.3.10中箭頭所指示的IP核源碼后,不需要再對(duì)IP作任何修改,直接關(guān)閉名為edit_AXI4_RW_TEST_v1_0的工程。最終我們創(chuàng)建的IP核將通過(guò)AXI4 Master端口向Slave端指定的4K存儲(chǔ)空間中連續(xù)寫入1024個(gè)數(shù)據(jù),寫入的數(shù)值從1累加到1024,每個(gè)數(shù)據(jù)占32bit。
IP核創(chuàng)建完成后,我們?cè)诠こ棠夸浵碌膇p_repo文件夾中可以找到IP相關(guān)的文件,如下圖所示:
圖 20.3.12 IP核相關(guān)的文件
需要注意的是,在圖 20.3.12中我們只需要保留紅色方框中的文件夾即可,其余文件及文件夾是用于對(duì)IP進(jìn)行編輯的工程文件,我們可以直接刪除。
回到axi4_ddr_rw工程界面,在左側(cè)“Flow Navigator”一欄點(diǎn)擊“IP Catalog”,然后在右側(cè)的IP目錄中可以看到我們前面所創(chuàng)建的IP核——AXI4_RW_TEST,該IP已經(jīng)自動(dòng)添加到了當(dāng)前工程的IP庫(kù)中。
圖 20.3.13 IP目錄
接下來(lái)在Diagram窗口中給設(shè)計(jì)添加自定義的IP核AXI4_RW_TEST,添加完成后如下圖所示:
圖 20.3.14 添加AXI4_RW_TEST IP核
在圖 20.3.14中,M_AXI是AXI-Full類型的主機(jī)接口,我們將通過(guò)這個(gè)接口對(duì)PS端的DDR4進(jìn)行讀寫操作。AXI4_RW_TEST IP核在檢測(cè)到m_axi_init_axi_txn端口的上升沿后會(huì)啟動(dòng)讀寫過(guò)程,并將讀出的數(shù)據(jù)與寫入的數(shù)據(jù)作比較,比較完成后m_axi_txn_done輸出高電平。另外,在比較完成后,m_axi_error信號(hào)會(huì)指示整個(gè)過(guò)程是否出錯(cuò)。如果在讀寫過(guò)程中出錯(cuò),或者在比較的過(guò)程中發(fā)現(xiàn)讀出的數(shù)據(jù)與寫入的數(shù)據(jù)不一致,那么m_axi_error將會(huì)拉高。
添加完自定義IP核之后,雙擊該IP核對(duì)其進(jìn)行配置,如下圖所示:
圖 20.3.15 配置AXI4_RW_TEST IP核
在圖 20.3.15中,我們將變量C M AXI TARGET SLAVE BASE ADDR的值修改為0x1000_0000,它位于DDR4存儲(chǔ)器的地址空間,是AXI4_RW_TEST IP核進(jìn)行讀寫操作的起始地址。我們將該地址之前的存儲(chǔ)空間預(yù)留下來(lái),用于運(yùn)行PS中的軟件程序。
接下來(lái),我們還要添加Utility Vector Logic IP核。然后將其配置成非門,位寬為1,作為反向器使用,如下圖所示:
圖 20.3.16 Utility Vector Logic IP核設(shè)置
這是因?yàn)槲覀冃枰褂肞L端的按鍵來(lái)作為AXI4_RW_TEST IP核的啟動(dòng)信號(hào),MPSOC開發(fā)板上的按鍵在按下的時(shí)候?yàn)榈碗娖?#xff0c;因此我們通過(guò)添加一個(gè)反向器,將其修改為按下時(shí)輸出高電平。
接下來(lái)為按鍵添加消抖模塊,用于消除按鍵的抖動(dòng)。添加的方法是先將《MPSOC之FPGA開發(fā)指南》中“按鍵控制蜂鳴器”里的按鍵消抖模塊(key_debounce.v)添加至工程,然后再添加至框圖設(shè)計(jì)中即可。下面開始具體操作,我們?cè)诠こ棠夸?\axi4_ddr_rw\axi4_ddr_rw.srcs\sources_1下創(chuàng)建一個(gè)文件夾new,將key_debounce.v拷貝至new文件夾下,如下圖所示:
圖 20.3.17 key_debounce路徑
接下來(lái)將key_debounce.v模塊添加至工程中,右擊Design Sources下的design_1(design_1.bd),選擇“Add Sources…”,如下圖所示。
圖 20.3.18 添加源文件
在彈出的頁(yè)面中選擇第二個(gè)“Add or create design sources”,點(diǎn)擊“NEXT”。
然后點(diǎn)擊頁(yè)面中的“Add Files”,在彈出的頁(yè)面中選擇“key_debounce.v”,如下圖所示。
圖 20.3.19 添加“key_debounce.v”
最后點(diǎn)擊“Finish”完成代碼的添加,如下圖所示。
圖 20.3.20 點(diǎn)擊“Finish”
此時(shí)在Design Sources界面下,可以看到剛剛添加的文件,如下圖所示。
圖 20.3.21 添加完成界面
接下來(lái)在Diagram界面空白處右擊,選擇“Add Module…”,如下圖所示。
圖 20.3.22 點(diǎn)擊“Add Module”
此時(shí)會(huì)彈出工程中添加的.v文件,將key_debounce.v添加進(jìn)來(lái),如下圖所示。
圖 20.3.23 添加“key_debounce.v”至BD中
需要說(shuō)明的是,如果上圖的界面中,沒有出現(xiàn)按鍵消抖模塊,可能是軟件界面還沒有更新剛剛添加的設(shè)計(jì)文件,可以稍作等待后再添加,添加完成后如下圖所示。
圖 20.3.24 消抖模塊成功添加至BD界面中
IP核添加完成后,使用工具的自動(dòng)連接功能,對(duì)設(shè)計(jì)進(jìn)行連線,連線后如下圖所示:
圖 20.3.25 自動(dòng)連接
以上是使用Vivado軟件的自動(dòng)連線,接下來(lái)還需要手動(dòng)進(jìn)行消抖模塊、反向器、AXI4_RW_TEST IP核之間的連接。連接完成后,在Diagram窗口空白處右擊,然后選擇“Regenerate Layout”對(duì)設(shè)計(jì)進(jìn)行重新布局,布局后的界面如下圖所示:
圖 20.3.26 重新布局后的設(shè)計(jì)界面
從上圖中可以看到,在執(zhí)行了自動(dòng)連接之后,工具自動(dòng)添加了兩個(gè)IP核,分別是AXI智能互聯(lián)(AXI Smartconnect)和處理器系統(tǒng)復(fù)位(Processor System Reseet)。接下來(lái)需要將消抖模塊key端口引出,用于連接開發(fā)板PL端按鍵,并重命名為key_int,命名方法參考AXI GPIO按鍵LED實(shí)驗(yàn);還需要將AXI4讀寫測(cè)試模塊的m_axi_txn_done和m_axi_error兩個(gè)端口引出,用于連接PL端LED燈,并分別重命名為compare_done和error_flag,如下圖所示:
圖20.3.27 引出管腳
圖20.3.27中橙色的連線標(biāo)注出了本設(shè)計(jì)中AXI4總線的連接,其中AXI4_RW_TEST IP核的M_AXI作為主機(jī)接口,Zynq UltraScale+ MPSOC的S_AXI_HP0_FPD為從機(jī)接口,中間經(jīng)過(guò)了AXI Smartconnect。AXI Smartconnect的功能與AXI Interconnect IP核類似,都是用于將AXI存儲(chǔ)器映射的主器件連接到存儲(chǔ)器映射的從器件。
到這里我們的Block Design就設(shè)計(jì)完成了,在Diagram窗口空白處右擊,然后選擇“Validate Design”驗(yàn)證設(shè)計(jì)。驗(yàn)證完成后彈出對(duì)話框提示“Validation Successful”表明設(shè)計(jì)無(wú)誤,點(diǎn)擊“OK”確認(rèn)。最后按快捷鍵“Ctrl + S”保存設(shè)計(jì)。
接下來(lái)在Source窗口中右鍵點(diǎn)擊Block Design設(shè)計(jì)文件“design_1.bd”,然后依次執(zhí)行“Generate Output Products”和“Create HDL Wrapper”。
在左側(cè)Flow Navigator導(dǎo)航欄中找到RTL ANALYSIS,點(diǎn)擊該選項(xiàng)中的“Open Elaborated Design”,在彈出的窗口中點(diǎn)擊“OK”?;蛘咴诓藛螜谥悬c(diǎn)擊 Layout,在下拉列表中選擇I/O Planning以打開I/O Ports窗口。我們將在 I/O Ports 窗口中對(duì)key_init等接口進(jìn)行管腳分配,如下圖所示:
圖20.3.28 管腳分配
在圖20.3.28中,我們將key_init分配到了AD11引腳上,該引腳最終與MPSOC開發(fā)板上的按鍵PL_KEY0相連接;compare_done和error_flag分別連接到開發(fā)板上的LED:PL_LED0和PL_LED1。管腳分配完成后按快捷鍵Ctrl+S保存管腳約束,并在彈出的保存約束窗口中輸入文件名“axi4_ddr_rw”。
最后在左側(cè)Flow Navigator導(dǎo)航欄中找到PROGRAM AND DEBUG,點(diǎn)擊該選項(xiàng)中的“Generate Bitstream”,對(duì)設(shè)計(jì)進(jìn)行綜合、實(shí)現(xiàn)、并生成Bitstream文件。
在生成Bitstream之后,在菜單欄中選擇 File > Export > Export hardware導(dǎo)出硬件,并在彈出的對(duì)話框中,勾選“Include bitstream”。將導(dǎo)出的“design_1_wrapper.xsa”文件放到vitis文件夾,然后在菜單欄選擇File > Launch Vitis,啟動(dòng)VITIS軟件。
20.4軟件設(shè)計(jì)
在VITIS軟件中新建一個(gè)空的應(yīng)用工程,應(yīng)用工程名為“axi4_ddr_rw”。然后為應(yīng)用工程新建一個(gè)源文件“main.c”,我們?cè)谛陆ǖ膍ain.c文件中輸入本次實(shí)驗(yàn)的代碼:
1 #include "stdio.h"
2 #include "xil_cache.h"
3 #include "xil_printf.h"
4 #include "xil_io.h"
5
6 int main()
7 {
8 int i;
9 char c;
10
11 Xil_DCacheDisable();
12 printf("AXI4 PL DDR TEST!\n\r");
13
14 while(1)
15 {
16 scanf("%c",&c);
17 if(c == 'c'){
18 printf("start\r\n");
19 for(i=0;i<4096;i=i+4)
20 {
21 printf("%d is %d\n",i,(int)(Xil_In32(0x10000000+i)));
22 }
23 }
24 }
25 return 0;
26 }
可以看出,我們的軟件程序特別簡(jiǎn)單。在代碼的第14行至24行,通過(guò)一個(gè)while(1)死循環(huán),連續(xù)判斷用戶輸入的字符。當(dāng)輸入字符“c”時(shí),程序通過(guò)一個(gè)for循環(huán)開始從地址0x1000_0000讀取DDR存儲(chǔ)器中的數(shù)據(jù),讀取的存儲(chǔ)空間大小為4KB。需要注意的是,變量i每次累加4,這是因?yàn)槲覀冋{(diào)用了函數(shù)Xil_In32( )來(lái)讀取內(nèi)存數(shù)據(jù),每次讀取32bit。而內(nèi)存地址是以字節(jié)(1字節(jié)==8bit)為單位的,那么操作完成后地址應(yīng)該累加4。
可以看出,我們?cè)谲浖凶x取的內(nèi)存地址與硬件設(shè)計(jì)過(guò)程中DDR Test IP核所寫入的地址是一致的。我們將軟件讀出的數(shù)據(jù)通過(guò)串口打印出來(lái),與DDR Test IP核寫入的數(shù)據(jù)進(jìn)行對(duì)比,即可驗(yàn)證我們通過(guò)AXI4接口對(duì)DDR進(jìn)行的讀寫操作是否成功。
另外,在代碼的第11行,我們通過(guò)調(diào)用函數(shù)Xil_DCacheDisable( )來(lái)關(guān)閉數(shù)據(jù)緩存(Data Cache),以避免從緩存中讀取數(shù)據(jù)。這是因?yàn)樵趯?duì)同一地址進(jìn)行讀操作時(shí),讀出的有可能是Data Cache中緩存的數(shù)據(jù),而不是DDR中真正的數(shù)據(jù)。
20.5下載驗(yàn)證
首先我們將下載器與開發(fā)板上的JTAG接口連接,下載器另外一端與電腦連接。然后使用USB連接線將USB_UART(開發(fā)板PS PORT)接口與電腦連接,用于串口通信。最后連接開發(fā)板的電源,給開發(fā)板上電。
打開Vitis Terminal終端,設(shè)置并連接串口。然后下載本次實(shí)驗(yàn)的程序,下載完成后,在下方的Vitis Terminal中可以看到應(yīng)用程序打印的信息“AXI4 PL DDR TEST!”。
然后在Vitis Terminal窗口中輸入字符“c”,然后按回車鍵發(fā)送。程序會(huì)打印從DDR中讀出的數(shù)據(jù),如下圖所示:
圖 20.5.1 第一次從DDR4中讀出的數(shù)據(jù)
如圖 20.5.1所示,串口打印出了DDR存儲(chǔ)空間中從地址0x1000_0000開始的1024個(gè)數(shù)據(jù),每個(gè)數(shù)據(jù)占4個(gè)字節(jié)。從圖中可以看出,開發(fā)板上電后,在沒對(duì)該地址空間進(jìn)行寫操作之前,DDR中的數(shù)據(jù)是隨機(jī)的。
我們按下開發(fā)板上的按鍵PL_KEY1然后釋放,該動(dòng)作會(huì)啟動(dòng)AXI4_RW_TEST IP核對(duì)DDR的讀寫操作。然后開發(fā)板上的PL_LED1會(huì)點(diǎn)亮,表示讀寫操作完成。如下圖所示:
圖 20.5.2 MPSOC開發(fā)板實(shí)物圖
在圖 20.5.2中,如果旁邊的PL_LED2也點(diǎn)亮了,這表明在對(duì)DDR進(jìn)行讀寫操作過(guò)程中出現(xiàn)了錯(cuò)誤。但是這個(gè)錯(cuò)誤指示燈點(diǎn)亮的原因并不唯一,通過(guò)分析AXI4_RW_TEST IP核的源碼可以看出,在AXI4通信過(guò)程中寫響應(yīng)出錯(cuò)、讀響應(yīng)出錯(cuò)、以及讀出與寫入的數(shù)據(jù)不一致均會(huì)導(dǎo)致錯(cuò)誤指示燈點(diǎn)亮。
筆者最早在實(shí)現(xiàn)本次實(shí)驗(yàn)功能的時(shí)候,旁邊的PL_LED2偶爾也會(huì)亮,是由于沒有對(duì)按鍵進(jìn)行消抖處理所致,添加按鍵消抖模塊后,沒有再出現(xiàn)讀寫錯(cuò)誤的情況。
在Vitis Terminal窗口中重新輸入字符“c”并發(fā)送,程序會(huì)再次打印從DDR中讀出的數(shù)據(jù),如下圖所示:
圖 20.5.3 第二次從DDR4中讀出的數(shù)據(jù)
從圖 20.5.3中可以看出,PS端軟件從DDR中指定的4KB存儲(chǔ)空間中讀出的數(shù)據(jù)依次為1到1024,與AXI4_RW_TEST IP核寫入的數(shù)據(jù)一致,說(shuō)明本次實(shí)驗(yàn)在MPSOC開發(fā)板上面下載驗(yàn)證成功。