Board logo

标题: ZedBoard-自定义IP核实现+PS成功调用【详细步骤+流程介绍+源码】 [打印本页]

作者: pengpengpang    时间: 2014-9-11 10:50     标题: ZedBoard-自定义IP核实现+PS成功调用【详细步骤+流程介绍+源码】

软件环境:WIN7_64 + ISE 14.4 (system_edition)
硬件:Zedboard、USB-Cable线
搭建图:


经过前几天的学习,查看数据手册、官方例程,笔者已经对Zedboard有了基本的了解,但是怎样才能充分发挥ZYNQ的优势呢?这个就不得不说下ZYNQ的基本架构了,它分为PS(Processing System)和PL(Programmable Logic)两大部分。PS集成了双核的ARM Cortex-A9,并内置有很多通用的外设,比如DDR控制器、USB控制器、各种通用总线接口。PL部分: Zedboard使用了XILINX芯片XC7Z020,而查看官方数据可知它使用了和7系列Aritex相同的架构,性能极为强悍!想要最大程度的利用ZYNQ芯片的性能,可以把PS和PL部分结合起来,而这个首先得知道怎么自定义通用IP核,并将之导入到PS中,然后编写驱动和应用程序来入门。笔者刚开始也是一头雾水,查看help,官方教程,可是大多数资料都只是讲怎么使用ISE提供的现成IP核,对于怎么定义用户自己的IP核却是要么不说要么讲的很模糊,害得笔者亲自动手折腾了十几次才最终搞明白,现将详细过程记录如下,以供后来者能够少走些弯路。
经过笔者个人亲自尝试,自定义IP核并在PS中使用大致流程如图1所示。


图1

笔者所做的这个工程是基于Zedboard开发板, IP核的功能是读取拨码开关的状态,并写数据控制LED灯。应用程序是在输出台上输出拨码开关的状态,并给LED灯写入0x24。具体方法如下:
1、打开PlanAhead创建新工程,并配置XPS(略),不清楚的可以去参考笔者所写的前一篇博文,http://xilinx.eetrend.com/blog/3987

2、当PlanAhead默认打开XPS后,如图2所示,调整参数使之如图3所示,因为我们想要定义自己的IP核来使用LED和SW,故删除自带的对应IP核,另外按钮没用到,故也可以删除。


图2



图3

3、点击Finish。此时等大约一分钟左右XPS中出现了ZYNQ的SAV图,此时,点击图4中黑色矩形部分,创建或者导入外设,后面一直按默认点击NEXT,直至图5,按图5中创建并配置自己的IP核,然后NEXT,如图6所示,选择AXI4-Lite总线,AXI全名为Advanced eXtensive Interface,是AMBA下一个很重要的总线接口,而AXI-Lite是AXI总线协议的精简版,详细信息可以参考XILINX的help文档。点击NEXT,如图7,这个是XILINX为了简化用户工作量封装的IP和AXI总线之间的功能模块IPIF,然后继续NEXT,如图8所示,此时设置用户读写的寄存器的数量为2,因为我们需要读取拨码开关SW的状态,并使用数据控制LED灯,故需要两个寄存器。NEXT,如图9所示,保持默认即可,不用修改,然后一路NEXT直至图10所示,生成ISE工程文件和驱动,第一个选项可以选也可以不选,笔者比较熟悉VHDL,故没选,熟悉Verilog的可以勾上,然后NEXT,点击Finish。此时在XPS的IP Catalog中可以看到我们创建的IP核my_gpio。如图11所示.


图4



图5



图6



图7



图8



图9



图10



图11

下一步是要修改我们的IP核让其满足我们的要求,此时,打开PlanAhead的工程目录,找到生成的my_gpio的ISE工程文件,如图12所示,继续打开project3.srcs文件夹中,按路径打开子文件夹,直至出现ISE工程文件,如图13所示, 使用ISE打开该文件,并打开文件USER_LOGIC.VHD文件如图14所示,添加两行代码如红色矩形部分所示。此为我们自己定义的IP端口。查看USER_LOGIC.VHD代码可以知道,两个寄存器分别为slv_reg0和slv_reg1,我们使用slv_reg0作为SW和AXI总线的数据寄存器,则该寄存器只读,为此,注释掉该寄存器写逻辑,具体如图15所示,下一步定义我们自己的信号sw_reg0,sw_reg1,(为了同步SW信号)如图16所示,继续添加同步逻辑,如图17所示,下一步,增加写LED和读取SW状态逻辑,具体方法如图18所示,接着更改顶层文件my_gpio.vhd,在图19所示的代码中添加端口如图20所示,然后如图21所示在USER_LOGIC_I模块中添加代码,如此之后,IP逻辑基本写完了,使用综合工具综合并查看RTL视图,如图22和23所示,从图23可以看出我们定义的端口LED和SW分别都有效定义了,下一步,回到XPS中,如图24所示进行查看MPD文件,MPD(Microprocessor Peripheral Definition),即微处理器外设定义文件,并如图24添加代码并保存,接着,如图25操作, Rescan user repositories,重新扫描用户目录,紧接着,添加设计的IP核,如图26所示 ,下面一路默认即可,最终如图27所示,可以看到我们增加的接口已经显示出来了,下一步是把我们的端口引出去,具体如图28和图29所示,最终如图30所示,下一步是为我们的外设分配映射到内存的地址,GP0和GP1是 通用的I/O端口,GP0范围为0x4000000~0x7FFFFFFF,GP1的范围是0x80000000~0xBFFFFFFF,如图31所示,可以看出系统已经为我们默认设置了地址0x75c00000~0x75c0FFFF,只需锁定即可。此时点击Graphic Design View可以看到我们设计的IP核的端口情况。如图32所示。接着,关闭XPS,回到PlanAhead,右击system为此设计增加top HDL文件,具体如图33所示,


图12



图13



图14



图15



图16



图17



图18



图19



图20



图21



图22



图23



图24



图25



图26



图27



图28



图29



图30



图31



图32



图33



图34



图35



图36



图37



图38



图39



图40



图41



图42



图43



图44



图45



图46



图47

我们修改文件memory_test.c如下所示,
#include
#include "xparameters.h"
#include "xil_types.h"
#include "xstatus.h"
#include "xil_testmem.h"
#include "platform.h"
#include "memory_config.h"
#include "my_gpio.h"
#define BASE_ADDR 0x75c00000

int main()
{
unsigned int i;
init_platform();
//读取SW的状态,这个函数是XILINX为我们编写的驱动,包含在头文件my_gpio.h中
i = MY_GPIO_mReadReg(BASE_ADDR,0);
xil_printf("sw state is %x",i);
//将0x24写入LED灯
MY_GPIO_mWriteReg(BASE_ADDR,0x00000004,0x24);
cleanup_platform();
return 0;
}

最后,编译工程,完成后打开电源,将bit流下载到FPGA开发板上,配置串口,运行,(不清楚的可以去看下我的上一篇博文http://xilinx.eetrend.com/blog/3987,里面有详细步骤),接着并按如图49配置运行环境,点击确定,接着如图50,点击红色矩形按钮,生成debug,并运行即可!串口输出结果如图51所示。而此时开关状态和LED情况如图52所示。即运行成功!是不是很有成就感啊!


图49



50



51



52

最后的最后,我想说的是这只是一个开始,没有涉及到中断、高级调用等等,但是我们已经对基本流程有个大致的了解了,剩下的就是功能完善的问题了。 另外由于笔者水平有限,有什么问题请指出(通过留言或者邮箱联系)!谢谢!




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0