您好,现在是 2024年11月15日 06点09分 星期五

【OpenHW12参赛手记】ZedBoard-自定义IP核实现+PS成功调用【详细步骤+流程介绍+源码】 转载

文章来源

图片无法复制,请看原文

http://www.eefocus.com/jefby1990/blog/13-03/291975_490bc.html

 

【OpenHW12参赛手记】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://www.eefocus.com/jefby1990/blog/13-03/291863_e5055.html

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进行选择,接着NEXT,如图36进行操作,并确定,生成约束文件,接着,打开生成的system.ucf文件,编辑如图37所示,最后保存,并如图38所示,点击红色矩形所示区域,生成bit流文件,完成后如图39所示。接着,如图40所示,导出硬件到SDK,

 

                                  图34

 

                                图35

 

                                图36

 

                                图37

                              

                                                              图38

 

                                                               图39

 

                                                       图40

如图41所示,设置,点击OK,即可。在SDK里面,my_gpio的地址映射如图42所示,我们新建项目,如图43所示,并如图44所示设置项目,点击NEXT,选择memory test,Finish。接着如图45所示,点击所示阴影区域,去掉自动编译选项。接着去目录E:\Project\openhw\project_3\project_3.srcs\sources_1\edk\system\drivers\my_gpio_v1_00_a\src下找到文件my_gpio.c和my_gpio.h,并且将其拷贝到目录E:\Project\openhw\project_3\project_3.sdk\SDK\SDK_Export\my_gpio\src下,接着,我们打开my_gpio.h和my_gpio.c可以看到,这里面是对函数Xil_Out32和Xil_In32的封装,具体如图47所示,

                   

                                                          图41

 

                                       图42

 

                                   图43

                              

                                                                       图44

                             

                                                              图45

 

                                 图46

 

                                  图47

我们修改文件memory_test.c如下所示,

 

#include <stdio.h>

#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;

}

 

                              图48

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

 

                                    图49

 

                             图50

 

                             图51

 

                             图52

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

 

这里是原工程下载地址以及本博文的PDF版(个人推荐下载)。需要的可以下载!pan.baidu.com/share/link

 

jefby.

[email protected]

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。