ediweizhang

vivado环境下开发ZYNQ7000(摘自网易资料)

0
阅读(3691)

vivado环境下开发ZYNQ7000

2014-02-20 14:29:56| 分类:ZYNQ相关|举报|字号订阅

ARM已经在国内流行得一塌糊涂,各类教程、开发板(S3C2440,6410)层出不穷,归结下来,传统ARM开发包括以下几个步骤:

(1)硬件电路板设计(对于Zedboard,相当于设计逻辑电路,PL工程师负责);

(2)基本模块裸机代码测试(UART,DDR2,其他外设);

(3)移植操作系统(如Linux,uCLinux,uCOS等);

(4)编写相应操作系统的驱动程序(可从(2)中移植过来);

(5)编写应用程序(或移植已有的应用程序)、界面设计(Qt);

一个有ARM开发经验的工程师,接触Zynq时很容易陷入误区:到底哪一部分需要由逻辑完成,哪一部分由ARM完成?Zynq资料庞杂,怎样进行有效的学习?

从前面基本介绍我们知道,Zynq内部PS就是ARM工程师的战场,调试代码都是基于PS进行,如果出现问题(硬件问题、驱动问题、软件版本问题)如何定位是一项非常耗时的任务,尤其加入了逻辑设计之后,调试难度大大增加了。所以在一颗芯片中集成了ARM和FPGA虽然提高了性能,但也带来任务划分不明确,调试复杂等新问题。Zynq官方例程的网址为http://www.xilinx.com/support/documentation/sw_manuals/xilinx14_2/ug873-zynq-ctt.pdf,步骤较多,让人分不清到底是在做软件设计还是硬件开发。

本节在参考了上面例程的基础上,进一步做了几个小例子来说明Zynq其实可以和普通ARM开发一样简单易学。将ARM设计与逻辑设计完全解耦,有利于我们加深对zynq内部结构的理解。

ARM工程师开发Zynq用到的软件环境主要有:

PlanAhead+XPS:建立硬件工程,相当于在一个万用板上自己搭建一个单片机最小系统,我们需要将单片机的IO口连接不同的外设(LED,按键,液晶屏,串口等);

SDK:建立软件工程,编写基本模块程序;建立Bootloader工程;

arm-xilinx-linux-gnueabi-gcc:交叉编译工具,编写基于Linux的应用程序和驱动程序;

几乎所有ARM工程师都是从单片机开始学习,而且第一个实验一般都是流水灯实验。ZedBoard上既然有一个ARM芯片,有8个LED,能不能用ARM点亮它们,并实现流水灯效果呢?我们来试试吧!

笔者安装软件为ISE14.5,其他版本操作类似。

(1)硬件电路板设计

首先,运行PlanAhead软件(安装完成后,一般在桌面上会有快捷方式)。

单击“Create New Project ”,新建工程,为了方便叙述,连续点6次“Next”,直到出现下图:

左上框中选择“board”,在下面框中找到ZedBoard并选中,点Next,一直到Finish,结束。

在主面板左侧,点“Add Source”,添加一个嵌入式模块(这就是ARM核),选择如图所示。

Next,点“Create Sub-Design”

随便起个名吧,保留默认,OK,Finish。这个步骤主要功能是添加我们的ARM核心到万用板上,但是还没有连线。

这时PlanAhead会自动调用XPS,在XPS中,当有提问是否用BSB建立基本系统时,选“是”。OK,Next,出现下图:

把原先右侧的所有硬件都Remove掉,因为我们需要自己连线。点Finish。

看到了一个彩色的庞大系统,如下图所示。

主窗口显示的就是Zynq内部结构图,主窗口上面有四个标签,“Zynq”表示图形化显示,“Bus Interface”表示总线连接,“Ports”表示芯片外部IO连接,“Address”表示Zynq系统的地址映射。主窗口下有3个标签,有设计总结报告、系统组成显示、图形设计显示。默认用系统组成显示,另外两种可以在设计完成后观察。

我们点击Zynq系统组成框图中左上侧绿色的"I/O Peripherals“框,弹出IO口外设配置选项,展开最下侧的GPIO(点加号),勾上EMIO,并设置IO数目为8,如下图所示:

点关闭,然后从主窗口上面标签的Zynq标签切换到Ports标签,展开processing_system7_0(点加号),找到GPIO_0,将它设置为连接到外部引脚,如图所示。

什么是EMIO?什么是MIO?这是Zynq里面比较独特的特性。MIO就是ARM自己的手脚,完全由自己支配;而EMIO,则是FPGA的手脚,如果不做任何处理,ARM说什么对它们根本不起作用。Zynq有一种机制,可以通过布线,将一部分FPGA手脚连接到ARM上,接受ARM指挥,这样就可以方便地扩展ARM的IO口,使ARM也像FPGA那样,任意设置外部引脚,非常灵活。这个实验中,我们用了8个FPGA引脚接受ARM控制,上面操作已经设置完毕了。

接下来,需要检查硬件是否有错误。点击菜单Project->Design Rule Check,如果在XPS Console窗口中输出如下内容,表示没有错误:


[cpp] view plain copy print ?
Running system level update procedures...
Running UPDATE Tcl procedures for OPTION SYSLEVEL_UPDATE_PROC...
Running system level DRCs...
Performing System level DRCs on properties...
Running DRC Tcl procedures for OPTION SYSLEVEL_DRC_PROC...
Done!
Running system level update procedures... Running UPDATE Tcl procedures for OPTION SYSLEVEL_UPDATE_PROC... Running system level DRCs... Performing System level DRCs on properties... Running DRC Tcl procedures for OPTION SYSLEVEL_DRC_PROC... Done!


这时彻底关闭XPS,回到PlanAhead中。在Project Manager的Source窗口中,找到module_1.xmp,单击右键,选择Create Top HDL,如下图所示:

这时生成了顶层HDL模块,名称为module_1_stub.v,打开这个文件,内容如下:


[cpp] view plain copy print ?
//-----------------------------------------------------------------------------
// module_1_stub.v
//-----------------------------------------------------------------------------

module module_1_stub
(
processing_system7_0_MIO,
processing_system7_0_PS_SRSTB,
processing_system7_0_PS_CLK,
processing_system7_0_PS_PORB,
processing_system7_0_DDR_Clk,
processing_system7_0_DDR_Clk_n,
processing_system7_0_DDR_CKE,
processing_system7_0_DDR_CS_n,
processing_system7_0_DDR_RAS_n,
processing_system7_0_DDR_CAS_n,
processing_system7_0_DDR_WEB_pin,
processing_system7_0_DDR_BankAddr,
processing_system7_0_DDR_Addr,
processing_system7_0_DDR_ODT,
processing_system7_0_DDR_DRSTB,
processing_system7_0_DDR_DQ,
processing_system7_0_DDR_DM,
processing_system7_0_DDR_DQS,
processing_system7_0_DDR_DQS_n,
processing_system7_0_DDR_VRN,
processing_system7_0_DDR_VRP,
processing_system7_0_GPIO_pin
);
inout [53:0] processing_system7_0_MIO;
input processing_system7_0_PS_SRSTB;
input processing_system7_0_PS_CLK;
input processing_system7_0_PS_PORB;
inout processing_system7_0_DDR_Clk;
inout processing_system7_0_DDR_Clk_n;
inout processing_system7_0_DDR_CKE;
inout processing_system7_0_DDR_CS_n;
inout processing_system7_0_DDR_RAS_n;
inout processing_system7_0_DDR_CAS_n;
output processing_system7_0_DDR_WEB_pin;
inout [2:0] processing_system7_0_DDR_BankAddr;
inout [14:0] processing_system7_0_DDR_Addr;
inout processing_system7_0_DDR_ODT;
inout processing_system7_0_DDR_DRSTB;
inout [31:0] processing_system7_0_DDR_DQ;
inout [3:0] processing_system7_0_DDR_DM;
inout [3:0] processing_system7_0_DDR_DQS;
inout [3:0] processing_system7_0_DDR_DQS_n;
inout processing_system7_0_DDR_VRN;
inout processing_system7_0_DDR_VRP;
inout [7:0] processing_system7_0_GPIO_pin;

(* BOX_TYPE = "user_black_box" *)
module_1
module_1_i (
.processing_system7_0_MIO ( processing_system7_0_MIO ),
.processing_system7_0_PS_SRSTB ( processing_system7_0_PS_SRSTB ),
.processing_system7_0_PS_CLK ( processing_system7_0_PS_CLK ),
.processing_system7_0_PS_PORB ( processing_system7_0_PS_PORB ),
.processing_system7_0_DDR_Clk ( processing_system7_0_DDR_Clk ),
.processing_system7_0_DDR_Clk_n ( processing_system7_0_DDR_Clk_n ),
.processing_system7_0_DDR_CKE ( processing_system7_0_DDR_CKE ),
.processing_system7_0_DDR_CS_n ( processing_system7_0_DDR_CS_n ),
.processing_system7_0_DDR_RAS_n ( processing_system7_0_DDR_RAS_n ),
.processing_system7_0_DDR_CAS_n ( processing_system7_0_DDR_CAS_n ),
.processing_system7_0_DDR_WEB_pin ( processing_system7_0_DDR_WEB_pin ),
.processing_system7_0_DDR_BankAddr ( processing_system7_0_DDR_BankAddr ),
.processing_system7_0_DDR_Addr ( processing_system7_0_DDR_Addr ),
.processing_system7_0_DDR_ODT ( processing_system7_0_DDR_ODT ),
.processing_system7_0_DDR_DRSTB ( processing_system7_0_DDR_DRSTB ),
.processing_system7_0_DDR_DQ ( processing_system7_0_DDR_DQ ),
.processing_system7_0_DDR_DM ( processing_system7_0_DDR_DM ),
.processing_system7_0_DDR_DQS ( processing_system7_0_DDR_DQS ),
.processing_system7_0_DDR_DQS_n ( processing_system7_0_DDR_DQS_n ),
.processing_system7_0_DDR_VRN ( processing_system7_0_DDR_VRN ),
.processing_system7_0_DDR_VRP ( processing_system7_0_DDR_VRP ),
.processing_system7_0_GPIO_pin ( processing_system7_0_GPIO_pin )
);

endmodule
//----------------------------------------------------------------------------- // module_1_stub.v //----------------------------------------------------------------------------- module module_1_stub ( processing_system7_0_MIO, processing_system7_0_PS_SRSTB, processing_system7_0_PS_CLK, processing_system7_0_PS_PORB, processing_system7_0_DDR_Clk, processing_system7_0_DDR_Clk_n, processing_system7_0_DDR_CKE, processing_system7_0_DDR_CS_n, processing_system7_0_DDR_RAS_n, processing_system7_0_DDR_CAS_n, processing_system7_0_DDR_WEB_pin, processing_system7_0_DDR_BankAddr, processing_system7_0_DDR_Addr, processing_system7_0_DDR_ODT, processing_system7_0_DDR_DRSTB, processing_system7_0_DDR_DQ, processing_system7_0_DDR_DM, processing_system7_0_DDR_DQS, processing_system7_0_DDR_DQS_n, processing_system7_0_DDR_VRN, processing_system7_0_DDR_VRP, processing_system7_0_GPIO_pin ); inout [53:0] processing_system7_0_MIO; input processing_system7_0_PS_SRSTB; input processing_system7_0_PS_CLK; input processing_system7_0_PS_PORB; inout processing_system7_0_DDR_Clk; inout processing_system7_0_DDR_Clk_n; inout processing_system7_0_DDR_CKE; inout processing_system7_0_DDR_CS_n; inout processing_system7_0_DDR_RAS_n; inout processing_system7_0_DDR_CAS_n; output processing_system7_0_DDR_WEB_pin; inout [2:0] processing_system7_0_DDR_BankAddr; inout [14:0] processing_system7_0_DDR_Addr; inout processing_system7_0_DDR_ODT; inout processing_system7_0_DDR_DRSTB; inout [31:0] processing_system7_0_DDR_DQ; inout [3:0] processing_system7_0_DDR_DM; inout [3:0] processing_system7_0_DDR_DQS; inout [3:0] processing_system7_0_DDR_DQS_n; inout processing_system7_0_DDR_VRN; inout processing_system7_0_DDR_VRP; inout [7:0] processing_system7_0_GPIO_pin; (* BOX_TYPE = "user_black_box" *) module_1 module_1_i ( .processing_system7_0_MIO ( processing_system7_0_MIO ), .processing_system7_0_PS_SRSTB ( processing_system7_0_PS_SRSTB ), .processing_system7_0_PS_CLK ( processing_system7_0_PS_CLK ), .processing_system7_0_PS_PORB ( processing_system7_0_PS_PORB ), .processing_system7_0_DDR_Clk ( processing_system7_0_DDR_Clk ), .processing_system7_0_DDR_Clk_n ( processing_system7_0_DDR_Clk_n ), .processing_system7_0_DDR_CKE ( processing_system7_0_DDR_CKE ), .processing_system7_0_DDR_CS_n ( processing_system7_0_DDR_CS_n ), .processing_system7_0_DDR_RAS_n ( processing_system7_0_DDR_RAS_n ), .processing_system7_0_DDR_CAS_n ( processing_system7_0_DDR_CAS_n ), .processing_system7_0_DDR_WEB_pin ( processing_system7_0_DDR_WEB_pin ), .processing_system7_0_DDR_BankAddr ( processing_system7_0_DDR_BankAddr ), .processing_system7_0_DDR_Addr ( processing_system7_0_DDR_Addr ), .processing_system7_0_DDR_ODT ( processing_system7_0_DDR_ODT ), .processing_system7_0_DDR_DRSTB ( processing_system7_0_DDR_DRSTB ), .processing_system7_0_DDR_DQ ( processing_system7_0_DDR_DQ ), .processing_system7_0_DDR_DM ( processing_system7_0_DDR_DM ), .processing_system7_0_DDR_DQS ( processing_system7_0_DDR_DQS ), .processing_system7_0_DDR_DQS_n ( processing_system7_0_DDR_DQS_n ), .processing_system7_0_DDR_VRN ( processing_system7_0_DDR_VRN ), .processing_system7_0_DDR_VRP ( processing_system7_0_DDR_VRP ), .processing_system7_0_GPIO_pin ( processing_system7_0_GPIO_pin ) ); endmodule


可以看到,module_1_stub只是对我们用XPS创建的嵌入式模块module_1用verilog语言进行一层包装,相当于芯片制造业中将晶圆向外引线,做最后的邦定。我们后面会讲,在这一步也可以进行用户逻辑开发。

接着需要添加约束文件(UCF),还是在Project Manager中Add Source,这次类型选第一个“Constraints”,如图所示

仍然点Create File,名称随便起,我们输入system,最后确认,回到主窗口。这时看到Project Manager中添加了system.ucf

双击该文件,添加内容如下:


[cpp] view plain copy print ?
NET "processing_system7_0_DDR_Addr[0]" LOC = M4;
NET "processing_system7_0_DDR_Addr[1]" LOC = M5;
NET "processing_system7_0_DDR_Addr[2]" LOC = K4;
NET "processing_system7_0_DDR_Addr[3]" LOC = L4;
NET "processing_system7_0_DDR_Addr[4]" LOC = K6;
NET "processing_system7_0_DDR_Addr[5]" LOC = K5;
NET "processing_system7_0_DDR_Addr[6]" LOC = J7;
NET "processing_system7_0_DDR_Addr[7]" LOC = J6;
NET "processing_system7_0_DDR_Addr[8]" LOC = J5;
NET "processing_system7_0_DDR_Addr[9]" LOC = H5;
NET "processing_system7_0_DDR_Addr[10]" LOC = J3;
NET "processing_system7_0_DDR_Addr[11]" LOC = G5;
NET "processing_system7_0_DDR_Addr[12]" LOC = H4;
NET "processing_system7_0_DDR_Addr[13]" LOC = F4;
NET "processing_system7_0_DDR_Addr[14]" LOC = G4;
NET "processing_system7_0_DDR_BankAddr[0]" LOC = L7;
NET "processing_system7_0_DDR_BankAddr[1]" LOC = L6;
NET "processing_system7_0_DDR_BankAddr[2]" LOC = M6;
NET "processing_system7_0_DDR_CAS_n" LOC = P3;
NET "processing_system7_0_DDR_CKE" LOC = V3;
NET "processing_system7_0_DDR_CS_n" LOC = P6;
NET "processing_system7_0_DDR_Clk" LOC = N4;
NET "processing_system7_0_DDR_Clk_n" LOC = N5;
NET "processing_system7_0_DDR_DM[0]" LOC = B1;
NET "processing_system7_0_DDR_DM[1]" LOC = H3;
NET "processing_system7_0_DDR_DM[2]" LOC = P1;
NET "processing_system7_0_DDR_DM[3]" LOC = AA2;
NET "processing_system7_0_DDR_DQ[0]" LOC = D1;
NET "processing_system7_0_DDR_DQ[1]" LOC = C3;
NET "processing_system7_0_DDR_DQ[2]" LOC = B2;
NET "processing_system7_0_DDR_DQ[3]" LOC = D3;
NET "processing_system7_0_DDR_DQ[4]" LOC = E3;
NET "processing_system7_0_DDR_DQ[5]" LOC = E1;
NET "processing_system7_0_DDR_DQ[6]" LOC = F2;
NET "processing_system7_0_DDR_DQ[7]" LOC = F1;
NET "processing_system7_0_DDR_DQ[8]" LOC = G2;
NET "processing_system7_0_DDR_DQ[9]" LOC = G1;
NET "processing_system7_0_DDR_DQ[10]" LOC = L1;
NET "processing_system7_0_DDR_DQ[11]" LOC = L2;
NET "processing_system7_0_DDR_DQ[12]" LOC = L3;
NET "processing_system7_0_DDR_DQ[13]" LOC = K1;
NET "processing_system7_0_DDR_DQ[14]" LOC = J1;
NET "processing_system7_0_DDR_DQ[15]" LOC = K3;
NET "processing_system7_0_DDR_DQ[16]" LOC = M1;
NET "processing_system7_0_DDR_DQ[17]" LOC = T3;
NET "processing_system7_0_DDR_DQ[18]" LOC = N3;
NET "processing_system7_0_DDR_DQ[19]" LOC = T1;
NET "processing_system7_0_DDR_DQ[20]" LOC = R3;
NET "processing_system7_0_DDR_DQ[21]" LOC = T2;
NET "processing_system7_0_DDR_DQ[22]" LOC = M2;
NET "processing_system7_0_DDR_DQ[23]" LOC = R1;
NET "processing_system7_0_DDR_DQ[24]" LOC = AA3;
NET "processing_system7_0_DDR_DQ[25]" LOC = U1;
NET "processing_system7_0_DDR_DQ[26]" LOC = AA1;
NET "processing_system7_0_DDR_DQ[27]" LOC = U2;
NET "processing_system7_0_DDR_DQ[28]" LOC = W1;
NET "processing_system7_0_DDR_DQ[29]" LOC = Y3;
NET "processing_system7_0_DDR_DQ[30]" LOC = W3;
NET "processing_system7_0_DDR_DQ[31]" LOC = Y1;
NET "processing_system7_0_DDR_DQS[0]" LOC = C2;
NET "processing_system7_0_DDR_DQS[1]" LOC = H2;
NET "processing_system7_0_DDR_DQS[2]" LOC = N2;
NET "processing_system7_0_DDR_DQS[3]" LOC = V2;
NET "processing_system7_0_DDR_DQS_n[0]" LOC = D2;
NET "processing_system7_0_DDR_DQS_n[1]" LOC = J2;
NET "processing_system7_0_DDR_DQS_n[2]" LOC = P2;
NET "processing_system7_0_DDR_DQS_n[3]" LOC = W2;
NET "processing_system7_0_DDR_DRSTB" LOC = F3;
NET "processing_system7_0_DDR_ODT" LOC = P5;
NET "processing_system7_0_DDR_RAS_n" LOC = R5;
NET "processing_system7_0_DDR_VRN" LOC = M7;
NET "processing_system7_0_DDR_VRP" LOC = N7;
NET "processing_system7_0_DDR_WEB_pin" LOC = R4;
NET "processing_system7_0_MIO[0]" LOC = G6;
NET "processing_system7_0_MIO[1]" LOC = A1;
NET "processing_system7_0_MIO[2]" LOC = A2;
NET "processing_system7_0_MIO[3]" LOC = F6;
NET "processing_system7_0_MIO[4]" LOC = E4;
NET "processing_system7_0_MIO[5]" LOC = A3;
NET "processing_system7_0_MIO[6]" LOC = A4;
NET "processing_system7_0_MIO[7]" LOC = D5;
NET "processing_system7_0_MIO[8]" LOC = E5;
NET "processing_system7_0_MIO[9]" LOC = C4;
NET "processing_system7_0_MIO[10]" LOC = G7;
NET "processing_system7_0_MIO[11]" LOC = B4;
NET "processing_system7_0_MIO[12]" LOC = C5;
NET "processing_system7_0_MIO[13]" LOC = A6;
NET "processing_system7_0_MIO[14]" LOC = B6;
NET "processing_system7_0_MIO[15]" LOC = E6;
NET "processing_system7_0_MIO[16]" LOC = D6;
NET "processing_system7_0_MIO[17]" LOC = E9;
NET "processing_system7_0_MIO[18]" LOC = A7;
NET "processing_system7_0_MIO[19]" LOC = E10;
NET "processing_system7_0_MIO[20]" LOC = A8;
NET "processing_system7_0_MIO[21]" LOC = F11;
NET "processing_system7_0_MIO[22]" LOC = A14;
NET "processing_system7_0_MIO[23]" LOC = E11;
NET "processing_system7_0_MIO[24]" LOC = B7;
NET "processing_system7_0_MIO[25]" LOC = F12;
NET "processing_system7_0_MIO[26]" LOC = A13;
NET "processing_system7_0_MIO[27]" LOC = D7;
NET "processing_system7_0_MIO[28]" LOC = A12;
NET "processing_system7_0_MIO[29]" LOC = E8;
NET "processing_system7_0_MIO[30]" LOC = A11;
NET "processing_system7_0_MIO[31]" LOC = F9;
NET "processing_system7_0_MIO[32]" LOC = C7;
NET "processing_system7_0_MIO[33]" LOC = G13;
NET "processing_system7_0_MIO[34]" LOC = B12;
NET "processing_system7_0_MIO[35]" LOC = F14;
NET "processing_system7_0_MIO[36]" LOC = A9;
NET "processing_system7_0_MIO[37]" LOC = B14;
NET "processing_system7_0_MIO[38]" LOC = F13;
NET "processing_system7_0_MIO[39]" LOC = C13;
NET "processing_system7_0_MIO[40]" LOC = E14;
NET "processing_system7_0_MIO[41]" LOC = C8;
NET "processing_system7_0_MIO[42]" LOC = D8;
NET "processing_system7_0_MIO[43]" LOC = B11;
NET "processing_system7_0_MIO[44]" LOC = E13;
NET "processing_system7_0_MIO[45]" LOC = B9;
NET "processing_system7_0_MIO[46]" LOC = D12;
NET "processing_system7_0_MIO[47]" LOC = B10;
NET "processing_system7_0_MIO[48]" LOC = D11;
NET "processing_system7_0_MIO[49]" LOC = C14;
NET "processing_system7_0_MIO[50]" LOC = D13;
NET "processing_system7_0_MIO[51]" LOC = C10;
NET "processing_system7_0_MIO[52]" LOC = D10;
NET "processing_system7_0_MIO[53]" LOC = C12;
NET "processing_system7_0_GPIO_pin[0]" LOC = T22;
NET "processing_system7_0_GPIO_pin[1]" LOC = T21;
NET "processing_system7_0_GPIO_pin[2]" LOC = U22;
NET "processing_system7_0_GPIO_pin[3]" LOC = U21;
NET "processing_system7_0_GPIO_pin[4]" LOC = V22;
NET "processing_system7_0_GPIO_pin[5]" LOC = W22;
NET "processing_system7_0_GPIO_pin[6]" LOC = U19;
NET "processing_system7_0_GPIO_pin[7]" LOC = U14;
NET "processing_system7_0_GPIO_pin[7]" IOSTANDARD = LVCMOS33;
NET "processing_system7_0_GPIO_pin[6]" IOSTANDARD = LVCMOS33;
NET "processing_system7_0_GPIO_pin[5]" IOSTANDARD = LVCMOS33;
NET "processing_system7_0_GPIO_pin[4]" IOSTANDARD = LVCMOS33;
NET "processing_system7_0_GPIO_pin[3]" IOSTANDARD = LVCMOS33;
NET "processing_system7_0_GPIO_pin[2]" IOSTANDARD = LVCMOS33;
NET "processing_system7_0_GPIO_pin[1]" IOSTANDARD = LVCMOS33;
NET "processing_system7_0_GPIO_pin[0]" IOSTANDARD = LVCMOS33;
NET "processing_system7_0_DDR_Addr[0]" LOC = M4; NET "processing_system7_0_DDR_Addr[1]" LOC = M5; NET "processing_system7_0_DDR_Addr[2]" LOC = K4; NET "processing_system7_0_DDR_Addr[3]" LOC = L4; NET "processing_system7_0_DDR_Addr[4]" LOC = K6; NET "processing_system7_0_DDR_Addr[5]" LOC = K5; NET "processing_system7_0_DDR_Addr[6]" LOC = J7; NET "processing_system7_0_DDR_Addr[7]" LOC = J6; NET "processing_system7_0_DDR_Addr[8]" LOC = J5; NET "processing_system7_0_DDR_Addr[9]" LOC = H5; NET "processing_system7_0_DDR_Addr[10]" LOC = J3; NET "processing_system7_0_DDR_Addr[11]" LOC = G5; NET "processing_system7_0_DDR_Addr[12]" LOC = H4; NET "processing_system7_0_DDR_Addr[13]" LOC = F4; NET "processing_system7_0_DDR_Addr[14]" LOC = G4; NET "processing_system7_0_DDR_BankAddr[0]" LOC = L7; NET "processing_system7_0_DDR_BankAddr[1]" LOC = L6; NET "processing_system7_0_DDR_BankAddr[2]" LOC = M6; NET "processing_system7_0_DDR_CAS_n" LOC = P3; NET "processing_system7_0_DDR_CKE" LOC = V3; NET "processing_system7_0_DDR_CS_n" LOC = P6; NET "processing_system7_0_DDR_Clk" LOC = N4; NET "processing_system7_0_DDR_Clk_n" LOC = N5; NET "processing_system7_0_DDR_DM[0]" LOC = B1; NET "processing_system7_0_DDR_DM[1]" LOC = H3; NET "processing_system7_0_DDR_DM[2]" LOC = P1; NET "processing_system7_0_DDR_DM[3]" LOC = AA2; NET "processing_system7_0_DDR_DQ[0]" LOC = D1; NET "processing_system7_0_DDR_DQ[1]" LOC = C3; NET "processing_system7_0_DDR_DQ[2]" LOC = B2; NET "processing_system7_0_DDR_DQ[3]" LOC = D3; NET "processing_system7_0_DDR_DQ[4]" LOC = E3; NET "processing_system7_0_DDR_DQ[5]" LOC = E1; NET "processing_system7_0_DDR_DQ[6]" LOC = F2; NET "processing_system7_0_DDR_DQ[7]" LOC = F1; NET "processing_system7_0_DDR_DQ[8]" LOC = G2; NET "processing_system7_0_DDR_DQ[9]" LOC = G1; NET "processing_system7_0_DDR_DQ[10]" LOC = L1; NET "processing_system7_0_DDR_DQ[11]" LOC = L2; NET "processing_system7_0_DDR_DQ[12]" LOC = L3; NET "processing_system7_0_DDR_DQ[13]" LOC = K1; NET "processing_system7_0_DDR_DQ[14]" LOC = J1; NET "processing_system7_0_DDR_DQ[15]" LOC = K3; NET "processing_system7_0_DDR_DQ[16]" LOC = M1; NET "processing_system7_0_DDR_DQ[17]" LOC = T3; NET "processing_system7_0_DDR_DQ[18]" LOC = N3; NET "processing_system7_0_DDR_DQ[19]" LOC = T1; NET "processing_system7_0_DDR_DQ[20]" LOC = R3; NET "processing_system7_0_DDR_DQ[21]" LOC = T2; NET "processing_system7_0_DDR_DQ[22]" LOC = M2; NET "processing_system7_0_DDR_DQ[23]" LOC = R1; NET "processing_system7_0_DDR_DQ[24]" LOC = AA3; NET "processing_system7_0_DDR_DQ[25]" LOC = U1; NET "processing_system7_0_DDR_DQ[26]" LOC = AA1; NET "processing_system7_0_DDR_DQ[27]" LOC = U2; NET "processing_system7_0_DDR_DQ[28]" LOC = W1; NET "processing_system7_0_DDR_DQ[29]" LOC = Y3; NET "processing_system7_0_DDR_DQ[30]" LOC = W3; NET "processing_system7_0_DDR_DQ[31]" LOC = Y1; NET "processing_system7_0_DDR_DQS[0]" LOC = C2; NET "processing_system7_0_DDR_DQS[1]" LOC = H2; NET "processing_system7_0_DDR_DQS[2]" LOC = N2; NET "processing_system7_0_DDR_DQS[3]" LOC = V2; NET "processing_system7_0_DDR_DQS_n[0]" LOC = D2; NET "processing_system7_0_DDR_DQS_n[1]" LOC = J2; NET "processing_system7_0_DDR_DQS_n[2]" LOC = P2; NET "processing_system7_0_DDR_DQS_n[3]" LOC = W2; NET "processing_system7_0_DDR_DRSTB" LOC = F3; NET "processing_system7_0_DDR_ODT" LOC = P5; NET "processing_system7_0_DDR_RAS_n" LOC = R5; NET "processing_system7_0_DDR_VRN" LOC = M7; NET "processing_system7_0_DDR_VRP" LOC = N7; NET "processing_system7_0_DDR_WEB_pin" LOC = R4; NET "processing_system7_0_MIO[0]" LOC = G6; NET "processing_system7_0_MIO[1]" LOC = A1; NET "processing_system7_0_MIO[2]" LOC = A2; NET "processing_system7_0_MIO[3]" LOC = F6; NET "processing_system7_0_MIO[4]" LOC = E4; NET "processing_system7_0_MIO[5]" LOC = A3; NET "processing_system7_0_MIO[6]" LOC = A4; NET "processing_system7_0_MIO[7]" LOC = D5; NET "processing_system7_0_MIO[8]" LOC = E5; NET "processing_system7_0_MIO[9]" LOC = C4; NET "processing_system7_0_MIO[10]" LOC = G7; NET "processing_system7_0_MIO[11]" LOC = B4; NET "processing_system7_0_MIO[12]" LOC = C5; NET "processing_system7_0_MIO[13]" LOC = A6; NET "processing_system7_0_MIO[14]" LOC = B6; NET "processing_system7_0_MIO[15]" LOC = E6; NET "processing_system7_0_MIO[16]" LOC = D6; NET "processing_system7_0_MIO[17]" LOC = E9; NET "processing_system7_0_MIO[18]" LOC = A7; NET "processing_system7_0_MIO[19]" LOC = E10; NET "processing_system7_0_MIO[20]" LOC = A8; NET "processing_system7_0_MIO[21]" LOC = F11; NET "processing_system7_0_MIO[22]" LOC = A14; NET "processing_system7_0_MIO[23]" LOC = E11; NET "processing_system7_0_MIO[24]" LOC = B7; NET "processing_system7_0_MIO[25]" LOC = F12; NET "processing_system7_0_MIO[26]" LOC = A13; NET "processing_system7_0_MIO[27]" LOC = D7; NET "processing_system7_0_MIO[28]" LOC = A12; NET "processing_system7_0_MIO[29]" LOC = E8; NET "processing_system7_0_MIO[30]" LOC = A11; NET "processing_system7_0_MIO[31]" LOC = F9; NET "processing_system7_0_MIO[32]" LOC = C7; NET "processing_system7_0_MIO[33]" LOC = G13; NET "processing_system7_0_MIO[34]" LOC = B12; NET "processing_system7_0_MIO[35]" LOC = F14; NET "processing_system7_0_MIO[36]" LOC = A9; NET "processing_system7_0_MIO[37]" LOC = B14; NET "processing_system7_0_MIO[38]" LOC = F13; NET "processing_system7_0_MIO[39]" LOC = C13; NET "processing_system7_0_MIO[40]" LOC = E14; NET "processing_system7_0_MIO[41]" LOC = C8; NET "processing_system7_0_MIO[42]" LOC = D8; NET "processing_system7_0_MIO[43]" LOC = B11; NET "processing_system7_0_MIO[44]" LOC = E13; NET "processing_system7_0_MIO[45]" LOC = B9; NET "processing_system7_0_MIO[46]" LOC = D12; NET "processing_system7_0_MIO[47]" LOC = B10; NET "processing_system7_0_MIO[48]" LOC = D11; NET "processing_system7_0_MIO[49]" LOC = C14; NET "processing_system7_0_MIO[50]" LOC = D13; NET "processing_system7_0_MIO[51]" LOC = C10; NET "processing_system7_0_MIO[52]" LOC = D10; NET "processing_system7_0_MIO[53]" LOC = C12; NET "processing_system7_0_GPIO_pin[0]" LOC = T22; NET "processing_system7_0_GPIO_pin[1]" LOC = T21; NET "processing_system7_0_GPIO_pin[2]" LOC = U22; NET "processing_system7_0_GPIO_pin[3]" LOC = U21; NET "processing_system7_0_GPIO_pin[4]" LOC = V22; NET "processing_system7_0_GPIO_pin[5]" LOC = W22; NET "processing_system7_0_GPIO_pin[6]" LOC = U19; NET "processing_system7_0_GPIO_pin[7]" LOC = U14; NET "processing_system7_0_GPIO_pin[7]" IOSTANDARD = LVCMOS33; NET "processing_system7_0_GPIO_pin[6]" IOSTANDARD = LVCMOS33; NET "processing_system7_0_GPIO_pin[5]" IOSTANDARD = LVCMOS33; NET "processing_system7_0_GPIO_pin[4]" IOSTANDARD = LVCMOS33; NET "processing_system7_0_GPIO_pin[3]" IOSTANDARD = LVCMOS33; NET "processing_system7_0_GPIO_pin[2]" IOSTANDARD = LVCMOS33; NET "processing_system7_0_GPIO_pin[1]" IOSTANDARD = LVCMOS33; NET "processing_system7_0_GPIO_pin[0]" IOSTANDARD = LVCMOS33;


如果对引脚的位置不太确定,可以参考我上传的资源:http://download.csdn.net/detail/kkk584520/5901617里面有ZEDBoard原理图,其中有关LED的引脚如下图所示:

为了防止生成FPGA比特文件时报错,需要设置一下属性:

点菜单Flow->Bitstream Settings,设置More Options的值为-g UnconstrainedPins:Allow,点OK。

做完上面的内容,接着点击菜单Flow->Generate Bitstream。等大约5分钟(PC配置不同,时间有长有短),直到生成bitstream成功。这样就把FPGA逻辑设计部分工作做完了。

其实实际项目中,上述工作一般都是由逻辑开发工程师完成的,我们这个例子讲得如此详细是为了让ARM工程师对硬件有个较为深入的了解,这样后期调试时会更加得心应手。况且Xilinx把所有软件都集成在了PlanAhead中,ARM工程师不再像以前那样,直接用RealView MDK写代码,而是必须基于刚刚搭建的硬件环境用Xilinx的SDK开发工具完成软件设计。

下面将前面的硬件工程导出到SDK。

点击菜单File->Export->Export Hardware for SDK,弹出对话框,勾上Launch SDK,确认:

经过一段时间的导出,进入了SDK开发界面,点击菜单File->New->Application Project,如下所示:

名称随便起一个吧,我们取为led8,下一步,模板选择Hello World,这也是最基础的模板,后面我们大部分应用程序都基于这个模板。

打开helloworld.c,代码修改为:


[cpp] view plain copy print ?
/*
* 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
#include "platform.h"
#define MIO_BASE 0xE000A000

#define DATA1_RO 0x64
#define DATA2 0x48
#define DATA2_RO 0x68
#define DIRM_2 0x284
#define OEN_2 0x288


void print(char *str);
void delay_1s(int i)
{
int j;
while(i--)
{
j=10000;
while(j--)
{
__asm("NOP");
}
}
}
int main()
{
int i;
init_platform();
*((volatile int*)(MIO_BASE+OEN_2)) = 0xff;
*((volatile int*)(MIO_BASE+DIRM_2)) = 0xff;
print("Hello world!\r\nThe Leds are flowing...\r\n");
while(1)
{
for(i = 0;i < 8; i++)
{
*((volatile int*)(MIO_BASE+DATA2)) = 0x01<delay_1s(1000);
}
}
cleanup_platform();

return 0;
}
/* * 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  #include "platform.h" #define MIO_BASE 0xE000A000 #define DATA1_RO 0x64 #define DATA2 0x48 #define DATA2_RO 0x68 #define DIRM_2 0x284 #define OEN_2 0x288 void print(char *str); void delay_1s(int i) { int j; while(i--) { j=10000; while(j--) { __asm("NOP"); } } } int main() { int i; init_platform(); *((volatile int*)(MIO_BASE+OEN_2)) = 0xff; *((volatile int*)(MIO_BASE+DIRM_2)) = 0xff; print("Hello world!\r\nThe Leds are flowing...\r\n"); while(1) { for(i = 0;i < 8; i++) { *((volatile int*)(MIO_BASE+DATA2)) = 0x01<
        


保存,程序会自动编译。如果控制台输出如下表示编译无错误出现。


[cpp] view plain copy print ?
arm-xilinx-eabi-size led8.elf |tee "led8.elf.size"
text data bss dec hex filename
22304 1096 29780 53180 cfbc led8.elf
'Finished building: led8.elf.size'
' '

19:38:31 Build Finished (took 7s.342ms)
arm-xilinx-eabi-size led8.elf |tee "led8.elf.size" text data bss dec hex filename 22304 1096 29780 53180 cfbc led8.elf 'Finished building: led8.elf.size' ' ' 19:38:31 Build Finished (took 7s.342ms)


我们的LED流水灯程序马上就能跑了!别急,先做好运行准备。确保你的板子电源接好,MIO2~MIO6的短路帽都接地,USB-UART和USB-JTAG都连接到了电脑上,而且都已经安装相应驱动程序。打开电源开关,先下载bit流文件到FPGA,点击菜单Xilinx Tools->Launch Hardware Server,弹出一个黑框,不用管它(ISE14.2不需要这一步)。然后点击菜单Xilinx Tools->Program FPGA,确保bit文件位置正确(你可以亲自到相应目录下找到这个文件,看更新时间戳是不是正确),点Program,等待FPGA编程结束。成功编程后,板子上的LD12蓝灯会亮起。

接下来运行ARM端软件,右键点击工程浏览器中的led8,选择Run As->Launch on Hardware。打开电脑上的超级终端(Win7没有这个工具,我这里用的是SecureCRT),连接好,等待程序加载完成后,就能看到实验结果了,串口打印内容为:

板子上的8个LED则会呈现出流水灯的效果。

最终效果视频地址为:http://v.youku.com/v_show/id_XNTk2ODg1ODU2.html

工程文件:http://download.csdn.net/detail/kkk584520/5961635

总结:通过一个流水灯实验,我们基本上熟悉了Zynq开发需要的几个工具软件。步骤虽然很多,但有了一个清晰的方向,就不会迷失在各个软件的繁琐操作中。本博文不希望成为一个详细的傻瓜级教程(由于是第一个实验,步骤比较详细,后面的实验会非常简洁,所以不熟悉软件操作的童鞋要多加练习),也不想成为官方文档的简单堆砌和翻译,而是希望成为一个指路牌,告诉你在茫茫软件中何去何从。

ARM工程师关注的细节,应该是各类硬件寄存器,如GPIO,PLL,Timer,WDT,UART,SPI等等,这些寄存器可以从官方文档Zynq-7000-TRM中得到。经常查阅TRM是开发驱动、硬件接口必不可少的环节,如果需要移植操作系统,还需要查看ARM内核相应文档,如cortex_a9_mpcore_r4p1_trm,cortex_a9_neon_mpe_r4p1_trm等。一般来说,应用工程师需要熟悉相应的API,操作系统驱动工程师需要熟悉内核调用,裸机驱动工程师需要熟悉硬件协议。在一个项目中,需要所有工程师分工协作,这样才能高效地完成设计。

ARM工程师很多软件模块可以参考官方设计,在{ISE安装路径}\14.5\ISE_DS\EDK\sw\XilinxProcessorIPLib\drivers中有很多外设操作的例程,不需要从头开发。

在ARM之外,Zynq开发的另一个难点就是逻辑开发。下一节我们介绍如何利用ISE工具开发PL逻辑。

Baidu
map