Zedboard--AXI三部曲(一)---流程+调试
Zedboard的體系中,ZYQN的外設資源已經很豐富,Xilinx提供大量的基于AXI總線和PLB總線的外設,推薦大家優先Xilinx官方IP,不僅經歷過測試和驗證,還有完善的文檔和驅動。
為了進一步豐富ZYQN的生態系統,Xilinx的ZYQN系列的PS部分,開放內部互連,提供一系列接口,便于掛接各類符合總線要求的外設;
也為了進一步搭建異構系統,實現三分天下。
此外,ALTERA也推出了颶風V的SOPC系列,配置類似ZYQN
三部曲大致如下:
AXI-LITE基本建立流程和XMD測試方法(協處理加法器的實現)
AXI-LITE實用外設開發---AXI-LITE串口開發 (待定)
AXI 互連多主機開發---讀寫DDR3
注:才疏學淺,不擅于繪圖,更加不擅于貼圖教程。操作貼圖步驟有很多很不錯的帖子,如“Zedboard 一步一步系列,Zedboard學習手記,玩轉Zedboard開發板”等,望大家參考!
感謝老部長BW的支持,提供珍貴的Zedboard!
AXI-LITE外設基本建立流程和XMD測試方法
基本建立流程
注:很多例程從Planahead開始,因為參考ug873-zynq-ctt.pdf。本文為了簡便,直接從XPS啟動(XPS是建立以軟MCU或者硬MCU為主體的SOPC硬件開發平臺)
1.直接從XPS啟動,建立基于BSB的系統
Step1:選擇AXI系統,ARM-A9的使用AXI接口與內部互連相接,而且開發的外設也基本基于AXI。
若大家建立基于Microblaze的系統,可以選擇PLB。
AXI是ARM的總線,越來越成為主流。不僅僅在Xilinx上有用,在ALTERA同樣行的通。
Step2:選擇基于基于開發板的配置,選擇avent的zedboard配置
建議大家如此操作,省略設置DDR控制器時序參數的操作;而且UCF文件自動生成,免去配置錯誤的情況發生(引腳配錯,導致無法生成bitsteam)
如果大家以后自己繪制PCB,那么建議采用custom的選擇,滿足自主化的要求
思 考:如果大家從ISE開始,啟動XPS后,有可能會發現沒有avent的選項,
此時,可以先建立個同類型芯片的自主的配置,然后進入XPS主界面后,選擇import,導入zedboard的xml格式的配置信息
此處,反過來看,如果作為項目開發,可以建立自己的XML文件,便于項目間傳遞,通過export導出。如下圖
2.通過向導建立AXI-Lite的外設
step1: 從hardware選項里的create or import 建立,具體參考edk_ctt.pdf(來自官網)
選擇相應的接口
選擇合適的寄存器數量
如果是verilog HDL使用者,建議勾選用verilog hdl 實現user logic的temple
思 考: 如何Import 外設?如何從.hdl全自主書寫開發?如何開發內部包含xilinx ip的外設?
在導入的過程中,有此3個復選框
至少要選擇第一個選項,作為頂層TOP使用
關于第二個和第三個,根據個人需要選擇。
關于.ngc.edif格式的文件,基本是綜合后的文件,意味著可以直接綜合完成,然后采用black box的方式調用,確保IP的安全性
關于pfd,doc等文檔,建議大家參考官方的IP文檔書寫,至少畫個框架圖,功能摘要,寄存器列表及簡單的驅動演示
step2: 互連AXI-LITE外設
如果外設只有AXI-LITE從機接口,直接選擇連接processor7即可
如果外設包含主機口等其他接口,建議選擇手動連接
添加axi interconnect IP
設定相應的參數值
插入自己寫的DEMO,基于AXI lite 的32bit加法器
|
0x0 寫讀 |
加數1 寄存器1 |
|
0x4 寫讀 |
加數2 寄存器2 |
|
0x8 只讀 |
和 寄存器3 |
只需要修改user logic
user loigc片段 // implement slave model register(s)
always @( posedge Bus2IP_Clk )
begin
if ( Bus2IP_Resetn == 1'b0 )
begin
slv_reg0 <= 0;
slv_reg1 <= 0;
// slv_reg2 <= 0;
end
else
case ( slv_reg_write_sel )
3'b100 :
for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
if ( Bus2IP_BE[byte_index] == 1 )
slv_reg0[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
3'b010 :
for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
if ( Bus2IP_BE[byte_index] == 1 )
slv_reg1[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
/* 3'b001 :
for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
if ( Bus2IP_BE[byte_index] == 1 )
slv_reg2[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];*/
default : begin
slv_reg0 <= slv_reg0;
slv_reg1 <= slv_reg1;
// slv_reg2 <= slv_reg2;
end
endcase
end // SLAVE_REG_WRITE_PROC
// implement slave model register read mux
always @( slv_reg_read_sel or slv_reg0 or slv_reg1 or slv_reg2 )
begin
case ( slv_reg_read_sel )
3'b100 : slv_ip2bus_data <= slv_reg0;
3'b010 : slv_ip2bus_data <= slv_reg1;
3'b001 : slv_ip2bus_data <= slv_reg2;
default : slv_ip2bus_data <= 0;
endcase
end // SLAVE_REG_READ_PROC
// ------------------------------------------------------------
// User Logic adder:
// ------------------------------------------------------------
always @ (slv_reg0 or slv_reg1 )
slv_reg2 = slv_reg0 + slv_reg1;
軟件文件如下
hello world.c
helloworld.c/*
* Copyright (c) 2009 Xilinx, Inc. All rights reserved.
*
* Xilinx, Inc.
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
* STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
* IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
* FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
* ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
* FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE.
*
*/
/*
* helloworld.c: simple test application
*/
#include <stdio.h>
#include "summator.h"
//void print(char *str);
int main()
{
unsigned int sum;
int op1,op2;
init_platform();
printf("======summator design======
");
printf("Please input the first operand ADD1:
");
scanf("%d", &op1);
printf("Please input the second operand ADD2:
");
scanf("%d", &op2);
sum = add(op1, op2);
printf("Output the result ADD1 + ADD2:
");
printf("SUM = ADD1 + ADD2 = %d
",sum);
cleanup_platform();
return 0;
}
summator.h
summator.c/*
* summator.h
*
* Created on: 2013-7-9
* Author: szy
*/
#ifndef SUMMATOR_H_
#define SUMMATOR_H_
#include "platform.h"
#define ADD1 (* (volatile unsigned int *) 0x7aa00000) // 第一個寄存器地址---加數一
#define ADD2 (* (volatile unsigned int *) 0x7aa00004) // 第二個寄存器地址---加數二
#define SUM (* (volatile unsigned int *) 0x7aa00008) // 第三個寄存器地址---和
int add(int a, int b)
{
int sum;
ADD1 = a;
ADD2 = b;
sum = SUM;
return sum;
}
#endif /* SUMMATOR_H_ */
XMD流程簡介
XMD是Xilinx? Microprocessor Debugger 的含義,采用命令行的形式,使用TCL語言及Xilinx擴展的一些TCL命令。
作為調試PS系統的調試工具,
作為GNU Debug 和目標板的連接(軟件開發時,即可作為后臺任務的執行者,也可可以調出命令行界面)
思 考: XMD如何工作?如何充分利用XMD
XMD通過JTAG接口連接到PS的互連結構上
連接MCU的調試口來控制MCU(復位,停止,讀取寄存器等)
XMD作為互連結構的主機,可以控制外設即訪問外設的寄存器(采用地址方式)
參考EDK的文檔,充分學習使用XMD。
基本使用,建議在命令行輸入help running,會列出一些常見命令
XMD簡單演示
從XPS里啟動SDK (復選框:Include .bitstream .bmm 選上)
在SDK—xilinx tool—launch XMD
在SDK—xilinx tool—programme FPGA
此處,可以看到XMD打印出SDK軟件的一些操作語句------精彩馬上到來!!
在XMD下,依次輸入一下指令:
connect arm hw ----連接ARM硬件
stop ----
mwr 0x7aa00000 0x1 ---向 0x7aa00000 寫入0x1
mwr 0x7aa00004 0x5 ---向 0x7aa00004 寫入0x5
mrd 0x7aa00000 --- 從 0x7aa00000 讀出數
注: 此流程配合著上一段寫的加法器的demo,請大家對比以前用軟件操作外設的方法,類比理解
針對大家通常看的DEMO,zedboard的Helloworld DEMO,可以嘗試做一下小測試
connect arm hw ----連接ARM硬件
stop ----
mwr 0x41220000 0x3 ---此時,對應的 LD0和LD1亮了 (0x后面的值,對應著二進制0000_0011,所以低位兩個led亮)
mrd 0x41200000 ---此時,讀出數據為8個撥碼開關的二進制組合數,望大家驗證
總結
以上是生活随笔為你收集整理的Zedboard--AXI三部曲(一)---流程+调试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电脑内存条的作用是什么
- 下一篇: java rsa内容超长_RSA 非对称