ZYNQ学习之路4.ZYNQ通过GP口读取PL内部RAM数据
實驗環境:window 7 64 bit, vivado 2017.1, ZTURN board.
參考手冊:Xilinx Distributed Memory Generator
? ? ? ? 在ZYNQ開發中,經常需要PS與PL進行數據交互。當數據量比較大時往往需要先緩存一部分然后批量傳輸到Linux系統,否則中斷響應時間無法滿足要求,使用雙端口RAM或許是一種不錯的方法。本文詳細描述PS端讀寫PL端片的雙端口RAM數據的實驗過程。本次實驗使用FPGA內部的Block Memory,PS端通過Master GP0端口向RAM寫數據,通過Master GP1端口讀出數據,本次實驗涉及到AXI BRAM Controller和Block Memory Generator等IP核。
一. SRAM介紹
1.1 雙端口RAM結構
? ? ? ? Xilinx的ZYNQ7Z010內部FPGA是virtex7系列,內部有32KB的Block Memory,可以用它作為ROM,Single-Port RAM, Dual-Port RAM或Simple Dual-Port RAM, RAM的區別在于讀寫數據線與地址總線的數量的區別,根據自己的需求進行選擇。
| RAM類型 | 功能 | 數據總線數量 | 地址總線數量 |
| Single-Port | 通過一個端口進行數據的讀寫操作 | 1 | 1 |
| Dual-Port | 通過兩個端口讀寫數據 | 2 | 2 |
| Simple Dual-Port | 一個端口進行寫操作,另一個端口進行讀操作 | 1 | 2 |
? ? ? ? 雙端口RAM示意圖如下:
圖1-1.雙端口RAM示意圖題? ? ? ? 雙端口RAM相比其他幾種RAM更復雜,所以本文只介紹雙端口RAM的使用。
1.2 雙端口RAM控制信號
? ? ? ? 上文中的示意圖中只列出了基本且常用的信號,其他特殊信號在次不做介紹。常用控制信號功能定義如下:
| 信號 | 方向 | 描述 |
| din[31:0] | Input | 數據總線輸入,32位寬 |
| addr[31:0] | Input | 地址總線輸入,32位寬,地址從0開始,有效至容量大小 |
| clk | Input | 時鐘信號輸入,1位,寫同步時鐘 |
| en | Input | 使能讀,寫,復位選項 |
| rst | Input | 復位或置位讀出鎖存寄存器,如果要讀出需要置置 |
| wea[3:0] | Input | 寫使能 |
| dout[31:0] | Output | 數據輸出,32位寬 |
? ? ? ? 雙端口RAM的工作模式有三種,寫優先、讀優先和無變化模式。
寫優先模式:數據同時寫入到內存并輸出到數據端口,時序如圖1-2所示:
圖1-2: Write First Mode Example讀優先模式:當要寫入內存數據時,先前存儲的數據在寫地址有效前存儲到數據輸出總線上。時序圖如圖1-3所示:
圖1-3:Read First Mode Example無變化模式: 輸出鎖存器在寫入內存期間不改變值。時序圖如圖1-4所示:
圖1-4:No Change Mode Example1.3 字節寫操作
在使用32為數據總線時,數據按32位同時變化,如果只寫入8,16,24位的數據或者間隔一個字節寫入兩個不連續的字節,這是可以使用WE信號,首先看看圖1-5時序圖。
圖1-5: Byte-write Example標題圖中第一個上升沿到來之時,數據輸入0xFFEEDD,WEA=0x011,寫入內容變為0x00FFDD,只有后面兩個字節寫入成功,可以發現WEA的某個bit位置1時對應數據輸入的字節將被寫入,其他字節屏蔽寫操作,32為數據總線時WEA為4位,從低到高依次對應數據總線低到高的四個字節的掩碼,置位可寫,復位屏蔽,也就是說寫32位數據時WEA[3:0]=b1111.
二. PL端硬件設計
2.1 新建一個vivado工程,選擇開發板所對應的芯片型號。
2.2 Add IP, 添加ZYNQ,雙擊設置屬性,保留uart1,選擇M AXI GP0 interface和M AXI GP1 interface
圖2-1: ZYNQ IP核GP端口設置2.3 Add IP, 添加一個Block memory Generator,選擇true dual Port RAM類型。
圖2-2: Block Ram設置2.4 Add IP,添加兩個AXI BRAM Controller,把number of BRAM interfaces改成1。
圖2-3: AXI BRAM Controler設置2.5 點擊run connection automation,把axi_bram_ctl_0的Master選擇為GP0, axi_bram_ctl_1的Master選擇為GP1,interconnect ip都選擇為 new AXI Interconnect。
圖2-4: 設置AXI連接2.6 點擊重新布局,最后得到如下結構。
圖2-5: 雙端口RAM系統結構2.7 點擊Address Editor,可以看到GP0和GP1的地址已經自動分配好。
圖2-6: RAM地址分配2.8 在sources下選擇block design右擊,點擊Create HDL wrapper,生成系統的頂層模塊,在system_wrapper上右擊,選擇generate output products...。
2.9 編譯綜合工程,最后generate bitstream,導出硬件(包含bitstream),launch SDK。
?
三. PS端軟件的編寫與測試
3.1 新建一個以helloworld為模板的工程,SDK自動創建了硬件的bsp,設置終端串口為uart1。
?
3.2 在main函數中編寫代碼如下:
#include <stdio.h> #include "platform.h" #include "xil_printf.h" #include <sleep.h> #include "xil_io.h" #include "xparameters.h"int main() {int a[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};int b[16] = {0};init_platform();print("------The test is start...------\n\r");xil_printf( "Write data:\n\r");memcpy((void *)0x40000000, a, 16*4);for(int i = 0;i<16;i++){xil_printf( "%x ",a[i]);}xil_printf( "\n\r");sleep(1);xil_printf( "Read data:\n\r");memcpy(b, (void*)0x80000000, 4*16);for(int i = 0;i<16;i++){xil_printf( "%x ",b[i]);}xil_printf( "\n\r");xil_printf("------The test is end!------\n\r");cleanup_platform();return 0; }程序開始向地址0x40000000處復制數組a的內容,并打印數組a,然后將地址0x80000000開始的64字節(數組a大小)內容復制到數組b中,然后打印數組b。如果不復制到數組b,顯然數組b是全零數組,上電啟動初始狀態內存中全部為為0。0x40000000和0x80000000分別是雙端口RAM的兩個端口的起始地址,如果寫入與讀取的內容一致,則說明雙端口RAM的兩套讀寫地址操作的是同一個存儲空間,說明實驗是成功的。
3.3 連接好仿真器和串口終端,先下載FPGA程序,然后運行PS的軟件,在終端顯示如下:
可以看出讀取的與寫入的數據完全一樣,然而讀取的地址不一樣,說明實驗是成功的。
說明:由于BRAM是連接在GP0和GP1接口上通過AXI總線進行讀寫操作,在地址空間上尋址可以直接使用指針操作,因此memcpy這樣的C基本庫函數可以直接對GP0和GP1地址空間進行操作,在訪問速度上比使用循環指針操作要快很多。
歡迎關注亦夢云煙的微信公眾號: 亦夢智能計算
?
總結
以上是生活随笔為你收集整理的ZYNQ学习之路4.ZYNQ通过GP口读取PL内部RAM数据的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 正则表达式 '^[a-zA-Z0-9''
- 下一篇: 中专在学校里考的计算机四级证属于中级职业