學習內(nèi)容
本文首先進行自定義IP的AXI總線IP的設(shè)計,然后在SDK下編寫代碼進行DDR的讀寫數(shù)據(jù)的測試。
開發(fā)環(huán)境
vivado 18.3&SDKPYNQ-Z2開發(fā)板
系統(tǒng)框圖
首先對本次工程進行簡要說明:本次工程使用AXI-Full接口的IP進行DDR的讀寫測試。在我們的DDR讀寫IP中,我們把讀寫完成和讀寫錯誤信號關(guān)聯(lián)到PL端的LED上,用于指示DDR讀寫IP的讀寫運行狀態(tài)。然后使用PL部分消抖處理后的按鍵進行啟動AXI總線工作,控制數(shù)據(jù)寫入。通過AXI互聯(lián)模塊連接到AXI_HP0端口,由PS端口進行數(shù)據(jù)的讀取操作,并通過串口進行讀寫數(shù)據(jù)的監(jiān)控。
自定義IP設(shè)計
首先打開Vivado軟件,在Tasks這里選擇New IP lacation
點擊next,對IP的信息進行設(shè)置,這里我們使用默認配置即可。設(shè)置好我們IP要保存的位置。
點擊Tools中的創(chuàng)建和封裝新的IP選項,
點擊NEXT ,選擇我們的封裝類型。因為這里我們是直接進行打開IP設(shè)計的界面,前兩個選項是可以在我們的vivado當前工程下面進行封裝設(shè)計,這里我們只進行了IP設(shè)計沒有建立工程,所以前兩個選項是無法選中的。我們也可以通過工程界面,進入點擊Tools中的創(chuàng)建和封裝新的IP選項。
這里是用DDR讀寫IP來做主機,控制數(shù)據(jù)寫入,PS作為從機進行讀取IP中寫入的數(shù)據(jù)。
可以直接選中進行編輯IP,用戶可以根據(jù)自己的設(shè)計進行修改編輯IP的功能,這里沒有對IP進行修改處理,所以可以直接保存選擇第一個添加到IP庫中即可。
若修改相應的邏輯功能打開IP,在對應位置編輯添加代碼即可。
添加完成綜合后對IP進行重新打包。DDR讀寫IP設(shè)計完成,創(chuàng)建的 IP 核將通過 AXI4 Master 端口向 Slave 端指定的 4K 存儲空間中連續(xù)寫入 1024 個數(shù)據(jù), 寫入的數(shù)值從 1 累加到 1024, 每個數(shù)據(jù)占 32bit。然后進行硬件平臺的構(gòu)建。
硬件平臺構(gòu)建
首先,添加ZYNQ7 IP核,以及添加已經(jīng)完成設(shè)計的ddr讀寫IP核。
添加用戶自定義IP
用戶自定義的IP可通過以下步驟完成添加。點擊Settings,
在project settings選擇IP,依次點擊,在IP庫那里點擊加號,把對應的IP目錄文件夾添加后,點擊OK或者Apply即可完成添加,在IP庫中就可以找到用戶設(shè)計的IP。
完成IP和ZYNQ7 IP的導入后,如下圖:
雙擊打開zynq刪除多余的接口,這里只需要保留uart,并打開Slave HP0端口、時鐘、復位端口。
配置完,選擇自動連接接口,完成部分連接設(shè)計。
整體設(shè)計圖如下,
添加按鍵消抖IP
由于ddr讀寫IP的axi_init_axi_txn接入的是按鍵,這里按鍵按下會產(chǎn)生抖動,axi_init_axi_txn與好多讀寫信號關(guān)聯(lián),如果不添加消抖IP,在按鍵按下的時,產(chǎn)生的毛刺會進行影響后續(xù)的操作,從而導致讀寫操作的錯誤,也就是讀寫操作的指示燈會亮起。
系統(tǒng)復位后, 狀態(tài)機處于初始狀態(tài),在該狀態(tài)下等待外部輸入的啟動傳輸脈沖 init_txn_pulse。一旦檢測到 init_txn_pulse 為高電平,狀態(tài)機跳轉(zhuǎn)到 INIT_WRITE 狀態(tài)。在 INIT_WRITE 狀態(tài)下, 狀態(tài)機拉高 start_single_burst_write 信號, 來不斷地啟動 AXI4 Master 接口對Slave 端大小為 4KB 的存儲空間進行突發(fā)寫操作。寫操作完成后, write_done 信號會拉高,狀態(tài)機進入INIT_READ 狀態(tài)。在 INIT_READ 狀態(tài)下, 狀態(tài)機拉高 start_single_burst_read 信號, 不斷地啟動 AXI4 Master 接口對 Slave端同一存儲空間進行突發(fā)讀操作, 同時將讀出的數(shù)據(jù)與寫入的數(shù)據(jù)進行對比。讀操作完成后, read_done 信號拉高,狀態(tài)機進入 INIT_COMPARE 狀態(tài)。在 INIT_COMPARE 狀態(tài)下, 判斷 AXI4 接口在讀寫過程中的是否發(fā)生錯誤, 并將錯誤狀態(tài)賦值給ERROR 信號, 然后將 compare_done 信號拉高,表示一次讀寫測試完成。最后跳轉(zhuǎn)到 IDLE 狀態(tài),等待下一次讀寫操作的啟動信號。這里的消抖模塊直接添加之前寫過的按鍵消抖模塊即可,這里給出我的設(shè)計:
module key_filter( Clk, //50M時鐘輸入 Rst_n, //模塊復位 key_in, //按鍵輸入 key_flag, //按鍵標志信號 key_state //按鍵狀態(tài)信號 ); input Clk; input Rst_n; input key_in; output reg key_flag; output reg key_state; localparam IDEL= 4'b0001, FILTER0= 4'b0010, DOWN= 4'b0100, FILTER1 = 4'b1000; reg [3:0]state; reg [19:0]cnt; reg en_cnt;//使能計數(shù)寄存器 //對外部輸入的異步信號進行同步處理 reg key_in_sa,key_in_sb; always@(posedge Clk or negedge Rst_n) if(!Rst_n)begin key_in_sa <= 1'b0; key_in_sb <= 1'b0; end else begin key_in_sa <= key_in; key_in_sb <= key_in_sa; end reg key_tmpa,key_tmpb; wire pedge,nedge; reg cnt_full;//計數(shù)滿標志信號 //使用D觸發(fā)器存儲兩個相鄰時鐘上升沿時外部輸入信號(已經(jīng)同步到系統(tǒng)時鐘域中)的電平狀態(tài) always@(posedge Clk or negedge Rst_n) if(!Rst_n)begin key_tmpa <= 1'b0; key_tmpb <= 1'b0; end else begin key_tmpa <= key_in_sb; key_tmpb <= key_tmpa; end //產(chǎn)生跳變沿信號 assign nedge = !key_tmpa & key_tmpb; assign pedge = key_tmpa & (!key_tmpb); always@(posedge Clk or negedge Rst_n) if(!Rst_n)begin en_cnt <= 1'b0; state <= IDEL; key_flag <= 1'b0; key_state <= 1'b1; end else begin case(state) IDEL : begin key_flag <= 1'b0; if(nedge)begin state <= FILTER0; en_cnt <= 1'b1; end else state <= IDEL; end FILTER0: if(cnt_full)begin key_flag <= 1'b1; key_state <= 1'b0; en_cnt <= 1'b0; state <= DOWN; end else if(pedge)begin state <= IDEL; en_cnt <= 1'b0; end else state <= FILTER0; DOWN: begin key_flag <= 1'b0; if(pedge)begin state <= FILTER1; en_cnt <= 1'b1; end else state <= DOWN; end FILTER1: if(cnt_full)begin key_flag <= 1'b1; key_state <= 1'b1; state <= IDEL; en_cnt <= 1'b0; end else if(nedge)begin en_cnt <= 1'b0; state <= DOWN; end else state <= FILTER1; default: begin state <= IDEL; en_cnt <= 1'b0; key_flag <= 1'b0; key_state <= 1'b1; end endcase end always@(posedge Clk or negedge Rst_n) if(!Rst_n) cnt <= 20'd0; else if(en_cnt) cnt <= cnt + 1'b1; else cnt <= 20'd0; always@(posedge Clk or negedge Rst_n) if(!Rst_n) cnt_full <= 1'b0; else if(cnt == 20'd999_999) cnt_full <= 1'b1; else cnt_full <= 1'b0; endmodule
添加完模塊后系統(tǒng)設(shè)計如下:注:axi_init_axi_txn是上升沿有效,這里為了保證系統(tǒng)上電后是初始默認隨機狀態(tài),要確保按鍵未按下給啟動脈沖時,是低電平。因為PYNQZ2開發(fā)板按鍵默認電位是低,按下為高,這里不用進行處理,若按鍵按下后為低,默認拉高,這里可以對按鍵進行添加非邏輯的IP進行取反。(使用 utility vector logic IP完成配置)
雙擊DDR讀寫的IP核進行配置,這里沒有用到user的接口所以都設(shè)置為0,如圖:
對于Base address,我們可以查看下接口的地址范圍,避免數(shù)據(jù)操作超過可操作范圍,這里我們就取中間值0X10000000。
然后我們進行g(shù)enerate output product 然后生成HDL封裝。接著就對應引腳進行引腳約束即可(PYNQ的粉色開發(fā)板可以直接引用這個約束):
##LEDs set_property -dict { PACKAGE_PIN R14 IOSTANDARD LVCMOS33 } [get_ports { m0_axi_error_0 }]; #IO_L6N_T0_VREF_34 Sch=led[0] set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { m0_axi_txn_done_0}]; #IO_L6P_T0_34 Sch=led[1] ##Buttons set_property -dict { PACKAGE_PIN D19 IOSTANDARD LVCMOS33 } [get_ports { key }]; #IO_L4P_T0_35 Sch=btn[0]
完成約束后進行綜合布局布線,等待生成bit流文件。
bit文件生成后在FILE處,點擊導出硬件資源(包含bit流文件),接著launch SDK。
SDK軟件部分
打開SDK后,新建application project。在main.c中輸入以下代碼:
#include "stdio.h" #include "xil_cache.h" #include "xil_printf.h" #include "xil_io.h" int main(){ int i; char chardata; Xil_DCacheDisable(); printf("AXI4-FULL RW TEST~ "); while(1){ scanf("%c",chardata); if(chardata="y"){ printf("start "); for(i=0;i<4096;i=i+4){ printf("%d is %d ",i,(int)(Xil_In32(0x10000000+i))); } } } return 0; }
代碼簡要說明
這里使用的IP我們設(shè)定成不需要進行緩存的,所以在main函數(shù)中調(diào)用Xil_DCacheDisable();。使用Xil_In32(),對DDR對應位置的數(shù)據(jù)進行讀取。參數(shù)只需要傳遞所要讀取的地址即可。因為一次寫入的數(shù)據(jù)是32位的,每個地址的數(shù)據(jù)位寬是8位,所以在for循環(huán)中使用了i=i+4。
在串口中使用printf("%d is %d ",i,(int)(Xil_In32(0x10000000+i)));對相應地址的數(shù)據(jù)進行讀取顯示。
運行效果
當按鍵未按下時,也就是未進行寫入操作直接讀取數(shù)據(jù),DDR中的數(shù)據(jù)是默認的隨機狀態(tài),如下所示:
當按鍵按下后,IP完成數(shù)據(jù)寫入操作,數(shù)據(jù)是從1-1024自增的
如何波形進行debug?
這里我們選中要進行DEBUG的數(shù)據(jù)信號右擊選中debug
然后點擊自動連接,完成debug功能搭建
綜合后會多出ILA的IP進行波形分析幫助DEBUG。
然后打開硬件設(shè)備,如下圖在ila界面即可看到我們debug的波形數(shù)據(jù)了。
添加觸發(fā)條件,標號2是單次觸發(fā),標號1是一直運行debug抓取波形。
審核編輯:劉清
-
DDR
+關(guān)注
關(guān)注
11文章
717瀏覽量
65764 -
AXI總線
+關(guān)注
關(guān)注
0文章
66瀏覽量
14372 -
SDK
+關(guān)注
關(guān)注
3文章
1050瀏覽量
46656 -
AXI
+關(guān)注
關(guān)注
1文章
130瀏覽量
16831
原文標題:如何波形進行debug?
文章出處:【微信號:zhuyandz,微信公眾號:FPGA之家】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
如何使用AXI VIP在AXI4(Full)主接口中執(zhí)行驗證和查找錯誤
XILINX FPGA IP之AXI Traffic Generator

例說FPGA連載41:DDR控制器集成與讀寫測試之DDR2 IP核接口描述
ZYNQ調(diào)用XDMA PCIE IP同時讀寫PS DDR,導致藍屏問題。
如何用zedboard創(chuàng)建一個AXI接口應用程序?
【正點原子FPGA連載】第九章AXI4接口之DDR讀寫實驗--摘自【正點原子】達芬奇之Microblaze 開發(fā)指南
XILINX MIG(DDR3) IP的AXI接口與APP接口的區(qū)別以及優(yōu)缺點對比
簡單講解AXI Interconnect IP核的使用方法

AXI通道讀寫DDR的阻塞問題?

評論