本文通过一个简单例子介绍zynq 7000中自定义ip 的设计过程。 此例子就是控制4个led 。 在ps-pl 试验中,一般用的就是Vivado 自带的GPIO ip。 所以如果你熟悉了PS端和PL端协同设计流水灯试验,对于本例子就只需关注自定义ip 的设计了。如果你还不熟悉这种协同设计,那你就得先学习好了,再来看本文试验。

本文就是用自定义的ip 替代自带的gpio ip来控制流水灯。其主要意义是掌握自定义ip 的设计过程。
本文测试环境是Vivado 2015.4, 测试硬件是黑金的AC7010, AX7010。

本文的工程和源代码下载地址:

链接:https://pan.baidu.com/s/1b9tTFK 密码:vn92

1:新建一个试验工程

打开Vivado, 点击新建工程,工程取名custom_ip。

zynq 7000 自定义IP 实验


一路Next , 在这个界面设置好你所用的硬件,我的是这样的。

zynq 7000 自定义IP 实验


工程建立好是这样的,点击Create Block Design。

zynq 7000 自定义IP 实验


取名system。

zynq 7000 自定义IP 实验


在原理图里右键添加ip , 添加ZYNQ Processing System. 添加完成后点击 Run Block Automation。

zynq 7000 自定义IP 实验


然后 点击图标, recustom ip, 设置处理器。首先设置好DDR, 我的是这样选择的。

zynq 7000 自定义IP 实验


设置信息监控端口, UART1, 其实也不是很重要。

zynq 7000 自定义IP 实验


时钟设置比较重要,选择Clock Configuration,点开 IO Peripheral Clocks, PL Fabric Clocks, 检查FCLK_CLK0 是否已勾上,并且频率设置为100 MHZ。

zynq 7000 自定义IP 实验


PS-PL Configuration 这里也要选择好。

zynq 7000 自定义IP 实验


2: 建立自定义IP 。 菜单选择 Tools -> Create and Package IP… 。

zynq 7000 自定义IP 实验


Next 到这个界面, 做如下选择: 选择 Create a new AXI peripheral

zynq 7000 自定义IP 实验


在这个界面做好设置和选择;

zynq 7000 自定义IP 实验


这个接口设置很重要,按如下设置好。

zynq 7000 自定义IP 实验


到这个界面,选择 Edit IP, 然后点击Finish。

zynq 7000 自定义IP 实验


Finish 后界面是这样的。

zynq 7000 自定义IP 实验


3: 自定义ip 的设计


我们先来看看主界面。在 Design Source 下面有2个.v 文件。上面的myip_led_v1_0.v 是顶层文件, top level,但他只是实现接口界面,并调用实例函数。所以真正实现是在 下面的文件, myip_led_v1_0_S00_AXI.v, 当然这个文件主要是实现AXI接口。重要的逻辑实现需要我们另外添加自己的函数。但在这个例子,我们把这部分最简单化,只是实现一个很简单的功能。

zynq 7000 自定义IP 实验


这个实现文件很长,有400行多,但层次很清楚,每段实现一个逻辑点,并且有注释。这里不分析那么多了。

上图里是添加参数的位置,简化一点,不改参数了,所以这段后来取消了,就是取消了参数添加段,但保持注释。


寻找到下面注释段(line 16-20):

        // Users to add ports here
       
        // User ports ends
        // Do not modify the ports beyond this line


这里是添加ports 的地方,我们添加ports, 结果如下

        // Users to add ports here
        output wire [3:0]LED,
        // User ports ends
        // Do not modify the ports beyond this line


寻找到下面注释段(line 392-394):

    // Add user logic here
   
    // User logic ends


这里是添加逻辑的地方,可能有很多逻辑设计,或者调用自己定义的很多函数实现

但这里我们简单化, 只是添加一点点assign LED[3:0]=slv_reg0[3:0];

结果如下:

    // Add user logic here
    assign LED[3:0]=slv_reg0[3:0];
    // User logic ends

以上是我们对AXI接口实现函数的修改。很简单,找到地方添加2行。

下面我们对顶层文件做一点修改,点击并打开 myip_led_v1_0.v,找到如下地方(line 16-20)

    (
        // Users to add ports here
       
        // User ports ends
        // Do not modify the ports beyond this line


这是添加ports 的地方,添加后结果如下:

    (
        // Users to add ports here
        output wire [3:0]LED,
        // User ports ends
        // Do not modify the ports beyond this line


找到如下位置(line 46-51), 就是AXI实例化开始的地方,上面部分是参数设置的地方。

// Instantiation of Axi Bus Interface S00_AXI
    myip_led_v1_0_S00_AXI # (
        .C_S_AXI_DATA_WIDTH(C_S00_AXI_DATA_WIDTH),
        .C_S_AXI_ADDR_WIDTH(C_S00_AXI_ADDR_WIDTH)
    ) myip_led_v1_0_S00_AXI_inst (
        .S_AXI_ACLK(s00_axi_aclk),

我们需要让2部分是端口对应起来,所以添加了 .LED(LED), 结果如下:

// Instantiation of Axi Bus Interface S00_AXI
    myip_led_v1_0_S00_AXI # (
        .C_S_AXI_DATA_WIDTH(C_S00_AXI_DATA_WIDTH),
        .C_S_AXI_ADDR_WIDTH(C_S00_AXI_ADDR_WIDTH)
    ) myip_led_v1_0_S00_AXI_inst (
       .LED(LED),
        .S_AXI_ACLK(s00_axi_aclk),


好的,代码修改的任务完成了。保存此2个文件,特别是检查是否有错误。 有错误会告诉你错误了,但具体是哪里,我不知道,我一般综合一下,容易定位错误的具体地方。


双击IP-XACT下的component.xml ,返回到Package IP 窗口。下面是各种对应关系。

zynq 7000 自定义IP 实验


在左边没有绿勾的地方点一下,应该最开始是 Ports and Interface, 但我没截图,这里是 File Groups, 看看蓝色的提示条: Merge changes from File Group Wizard ,点击它。

zynq 7000 自定义IP 实验


点击后就全变绿勾了。右边的东西点开看看:

zynq 7000 自定义IP 实验


选择 Reviews and Package。 可以看到一些信息, 红框里说 inarchive will not be generate. Use the setting link before to change。

你想改变的话,可以点击试试看。 点击Re-Package IP。这样就完成了IP的设计了。


zynq 7000 自定义IP 实验


4:添加自定义ip 到原理图中验证

re-package ip 后,如下提示,我选择Add IP to Block Design,添加到原理图中。 如果不是这样, 你可能需要一个添加自定义ip 的程序。 自定义ip 路径设置,然后添加ip。

zynq 7000 自定义IP 实验


ip 添加到原理图中如下,点击Run Connection Automation。

zynq 7000 自定义IP 实验


所有线都连接好了, 但Led 还没有输出。 选择ip 的LED,

zynq 7000 自定义IP 实验


选择ip 的 LED,并右键选择 Make External

zynq 7000 自定义IP 实验


这样LED有了输出。

zynq 7000 自定义IP 实验


添加约束文件

zynq 7000 自定义IP 实验

此后就是常规操作了,在Source 中选中system.v,右键并先后选择 Generate Output Products 和 Create HDL Wrapper。 然后产生流文件。


硬件输出,菜单File -> Export -> Export Hardware , 这里要选择包含流文件。

zynq 7000 自定义IP 实验


菜单选择File -> Launch SDK 启动SDK开发环境。

zynq 7000 自定义IP 实验


5: SDK软件编程


新建工程:
菜单 File -> New -> Application Project

zynq 7000 自定义IP 实验


工程取名为test_led。

zynq 7000 自定义IP 实验


选择hello world 工程样本。

然后修改helloworld.cpp 如下:

#include <stdio.h>
#include “platform.h”
#include “xparameters.h”
#include “xil_io.h”

#define MY_IP    0x43c00000

int main()
{
    init_platform();

    print(“Hello World\n\r”);
    u32 Delay;
    u32 Ledwidth;

      while (1)
      {
          for (Ledwidth = 0x0; Ledwidth < 4; Ledwidth++)
          {
              Xil_Out32(MY_IP,1 << Ledwidth);
              //printf(“led=%x\n\r”,1<<Ledwidth);
              for (Delay = 0; Delay < 18000000; Delay++);
          }
      }
    cleanup_platform();
    return 0;
}


文件中有

#define MY_IP    0x43c00000 ,其来由在Vivado 的地址中得到。
zynq 7000 自定义IP 实验

保存文件并编译链接,Run AS-> 或者 Debug As ->  Launch on Hardware(System Debugger

就看到流水灯的运行了。


原文链接:https://blog.csdn.net/leon_zeng0/article/details/78674832

相关文章: