当前位置:   article > 正文

Xilinx_ZYNQ7020_自定义IP开发文档_zynq7020官方文档

zynq7020官方文档

系统设计

本文档中的示例实验的系统设计框图如下图所示。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2FaM6NWy-1582858270651)(media/aab71e0ee5f6d827823f26628900ce6d.png)]

ZYNQ芯片的PL部分也就是FPGA部分,定义了一个用户逻辑的IP,实现将两个输入的32bit的数据相加。自定义的用户逻辑IP中设计了4个寄存器,其中3个配置寄存器(可读、可写)和一个状态寄存器(只读)。

ARM处理器通过写配置寄存器slv_reg0和slv_reg1分别写入两个输入数据,用户逻辑做加法运算,计算相加的结果放入slv_reg3寄存器中。slv_reg3寄存器作为自定义IP的状态寄存器使用,不能写,只能读。ARM处理器读取slv_reg3寄存器中的数据,并将结果显示在串口调试工具窗口中。

使用自定义IP

Xilinx官方提供了许多的IP核,在Vivado中我们通过IP
Catalog可以管理、添加和查看这些IP核。然后用户在构建自己的系统时,有时候需要使用自己的用户IP核。创建自定义IP核将使系统设计层次结构和模块化结构更加的清晰;增加功能模块的设计复用性,简化系统设计和缩短设计时间;可以在IP核中加入license有偿提供给别人使用。

在ZYNQ嵌入式开发中最常用的就是使用AXI总线将PS同PL
Fabric的IP核连接起来。本实验将为大家介绍如何在Vivado中创建一个AXI总线的自定义IP,并且创建该IP的驱动函数库,并在SDK应用程序中读写该自定义IP中的寄存器。

Vivado工程建立

处理器IP的配置

ALINX AX7020的使用的是Xilinx 公司的Zynq7000系列的SOC芯片。

SOC芯片的型号为XC7Z020-2CLG400I。

芯片上的PS系统集成了两个ARM Cortex-A9处理器。

FPGA硬件工程师需要在工程中添加和配置好PS端ARM内核,以及PS端的外设。

步骤如下:

  1. 新建一个Vivado工程,工程名“custom_ip”。

  2. 创建一个Block设计,添加一个ZYNQ7 Processing
    System的IP核。根据开发板原理图和用户手册配置参数。

  3. 通过阅读原理图可以得知外设IO的MIO的BANK0的电平为3.3V,BANK1的电平为1.8V,因此将BANK0配置为LVCOMS3.3V,BANK1配置为LVCOMS1.8V。

  4. 串口的TX和RX分别连接到MIO48-MIO49,因此配置为UART1(MIO48-MIO49)。

  5. QSPI FLASH的芯片型号为W25Q256,配置QSPI FLASH,选择Single SS 4bit IO。

  6. 开发板上有两个4Gbis的DDR3 SDRAM,配置为兼容“MT41J128M16
    RE-125”,总线位宽为“32bit”。

  7. 千兆以太网的引脚接口如下:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mYIrGCL7-1582858270654)(media/ccf7a897d8ca92aac9de379d49a72cc5.png)]

    因此配置以太网接口为Ethernet 0
    (MIO16-MIO27),此外还需要配置MDIO为以太网的配置寄存器的接口(MIO52-MIO53)。

  8. SD卡槽的连接如下图所示。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xj3nPFSc-1582858270660)(media/ad3e7dd294da586ea46d1abc30f57bc1.png)]

    因此配置SD卡槽的配置为:SD 0 (MIO40-MIO45)。

  9. PS端的输入时钟配置为33.333333MHz,CPU时钟配置为767MHz。

处理器IP的配置基本完成了。

创建自定IP

创建自定义IP的步骤如下:

  1. 点击菜单栏“Tool”Create and Package New IP,弹出创建自定义IP的向导(Create
    and Package New IP Wizard)。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zjpQkYZn-1582858270662)(media/df42d107ce191cfa246b65d544756395.png)]

  2. 点击Next,在任务类型选择时,选择创建一个新的AXI4外设。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bSJC1rmy-1582858270665)(media/097139309896a2e1159b46d9a0f32ae3.png)]

  3. 点击Next,在Peripheral
    Detail的配置窗口中,设置设备IP的名称为my_app_0,点击Next。

  4. 在设备IP的AXI接口配置窗口对AXI接口进行配置,接口类型保持默认的AXI
    Lite接口,接口模式为Slave模式,数据位宽为32bits,寄存器数量设置为4个。点击Finish,完成创建IP。

  5. 在Vivado的IP Catalog中可以查看刚才创建的自定义IP。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ehYy6WQA-1582858270666)(media/00f7e469e3fbe1635531a72109c398b9.png)]

  6. 此时的自定义IP只有简单的寄存器读写功能,我们需要在其中添加用户逻辑。右键点击该IP,选择Edit
    in IP Packager。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6wGKhUXq-1582858270669)(media/1ae8bd554f9722261714aa1c5fc06457.png)]

  7. 弹出对话框要求输入工程的名称和路径,这里保持默认。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EU5o1XRu-1582858270672)(media/99b873f1b189481dd2d525c7dbf73e26.png)]

  8. 点击OK,Vivado打开了一个新的工程,编辑IP。

  9. 添加用户逻辑代码。在目录custom_ip/下新建一个my_app0.v的源代码文件,内容如下:

`timescale 1ns / 1ps

//

module my_app0

#(

// register bit width

parameter N = 32

)

(

input clk,

input[N - 1:0] input_reg0,

input[N - 1:0] input_reg1,

input[N - 1:0] input_reg2,

output[N - 1:0] output_reg0

);

reg[N - 1:0] input_reg_reg0;

reg[N - 1:0] input_reg_reg1;

reg[N - 1:0] output_reg_reg0;

always@(posedge clk)

begin

input_reg_reg0 <= input_reg0;

input_reg_reg1 <= input_reg1;

end

always@(posedge clk)

begin

output_reg_reg0 <= input_reg_reg0 + input_reg_reg1;

end

assign output_reg0 = output_reg_reg0;

endmodule

  1. 这个用户逻辑的源码还是非常简单易懂的,就是将两个输入input_reg0和input_reg1分别放入input_reg_reg0和input_reg_reg1。并将它们的值相加,放入output_reg0中输入。

  2. 点击Add Sources,打开添加源码向导,选择Add or create design sourcesAdd
    File,添加用户逻辑的源码文件,确保添加文件时选择Copy Sources into IP
    Directory。添加的源文件会复制到IP目录中,之后在IP编辑窗口中,对用户逻辑文件的所有的修改都是对IP目录中的用户逻辑文件,而与之前的custom_ip/my_app0.v无关,且不会同步。注意这里并没有使用Create
    File创建源代码文件的方式,这是因为软件源代码文件时会要求指定源代码的路径,而不是使用IP自动保存源码的路径,这可能造成后面源码修改的同步问题。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2hgG4UT3-1582858270675)(media/48deda5ed182536373c9afa610979d6b.png)]

  3. 通过源码管理器窗口中可以查看文件的属性。可以看到IP的源码位置在ip_repo/myapp_0_1.0/src。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rI8Zk3Ht-1582858270678)(media/89f608f73c0e1181424e2480b7fa60a2.png)]

  4. 自定义IP的这个工程,除了之前添加的用户逻辑源码文件以外,还有两个文件,其中一个为myapp_0_v1_0的IP顶层文件。在顶层文件中实现了一个“myapp_0_v1_0_S00_AXI_inst”模块的例化。其对应的源代码myapp_0_v1_0_S00_AXI.v文件中实现了AXI4-Lite
    Slave接口的时序逻辑。

  5. 我们需要修改该myapp_0_v1_0_S00_AXI.v文件,在其中实现用户逻辑模块的例化,并实现用户逻辑寄存器与IP配置和状态读取寄存器的绑定。

  6. 在myapp_0_v1_0_S00_AXI.v文件的最下方,注释“Add user logic
    here”的下方,添加如下的代码。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8Xnd04IF-1582858270681)(media/98f3b7f7469a30bbb0282f6c5c0c7bd7.png)]

  7. 这里实现了用户逻辑模块的例化,其中三个输入端口分别连接到配置寄存器slv_reg0,slv_reg1和slv_reg2。输出引脚不能直接连接到slv_reg3,所以我们先添加了一个wire类型的变量,其位宽与slv_reg3的数据位宽相同。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2cCshhB2-1582858270683)(media/eee06e129486377282a8afa89b73008d.png)]

  8. 修改如下的写寄存器的代码。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WQUEPerQ-1582858270685)(media/0948822ccbdb67c6d89ac40d51e6706e.png)]

    其中case语句中的写地址axi_awaddr为2’h0,2’h1和2’h2的情况下,分别写slv_reg0,slv_reg1和slv_reg2寄存器。我们要实现的是slv_reg0,slv_reg1寄存器保存并可设置输入的值,而slv_reg3寄存器保存slv_reg0和slv_reg1两个值相加的结果,因此我们将slv_reg0,slv_reg1和slv_reg2寄存器作为可读写的配置寄存器,而slv_reg3作为只读的状态寄存器。所以这里我们不允许写slv_reg3寄存器,因此删除如下的代码。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9EHHsJ2s-1582858270688)(media/48e4df97df904e097a90b5a8fd2f39ba.png)]

    这一段也删除掉,因为不管地址是什么都不应该写slv_reg3寄存器。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-agodUQNd-1582858270690)(media/a6b2755ed2e525bd2229641dbcebf5f0.png)]

    然后在if(slv_reg_wren)语句包括的begin和end所有逻辑的后面,添加下面的语句。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6ATTZZz0-1582858270693)(media/f301134204e73467dd7d10d86f084162.png)]

    这段代码的意思:除了复位和AXI写寄存器以外的其它情况(如AXI读操作,非读、非写时,等情况)进行寄存器slv_reg3内数据的同步,将my_app0用户逻辑的输出(即两个配置寄存器内的值相加的结果)同步到slv_reg3寄存器。
    保存文件。

  9. 双击Source窗口的IP-XACT下的component.xml文件。此时在Packaging Steps栏的File
    Group选项卡中弹出“Merge changers from File Groups Wizard”。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6snEVXkL-1582858270694)(media/18870b4aa4d679f7f75fe9f8aff65194.emf)]

    点击“Merge changers from File Groups Wizard”,更新合并修改的源代码。

  10. 点击“Review and Package”栏的“Re-Package IP”,完成IP的修改。

  11. Vivado自动关闭了IP的工程,此时可以在custom_ip的Block
    Design的Diagram设计窗口中点击添加自定义的IP,并点击“Run Connection
    Automation”进行自动接线。设计框图如下。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l8GySmwq-1582858270697)(media/7739752a0fb006d3eb2f2e20d5fa1d90.png)]

  12. 保存设计,右键点击Source窗口下.db文件,选择Generate Output
    Product,生成设计产品文件。

  13. 点击Generate Bitstream,运行综合和执行,并生成Bitstream文件。

  14. 点击菜单”File””Export””Export
    Hardware”,导出硬件信息,在导出硬件信息时需要选上“Include Bitstream”。

  15. 点击菜单”File””Launch SDK”打开SDK。

下面进入到软件工程的开发。

SDK软件工程开发

在Vivado中运行Launch
SDK,自动打开SDK软件,可以看到一个design_1_wrapper_hw_platform_0的硬件信息。

展开可以看到里面的目录和文件的结构如下。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LlbG2jrc-1582858270698)(media/f0cec85caaa8b4830e9ba954c55ccd13.png)]

双击system.hdf文件,可以看到里面包含了硬件的总体信息,如目标FPGA芯片的型号,地址映射,以及IP模块的组成等。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kN8iEfUU-1582858270700)(media/99a04a7fad63eeb986ede3f257a9882a.png)]

在dirvers目录下的myapp_0_v1_0目录中包含了自定义IP的驱动程序。双击myapp_0.h打开,里面的内容如下。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hpcaI9vD-1582858270701)(media/335668d01a3fa27d30bdc44cccadde26.png)]

主要定义了每个IP内部寄存器的偏移地址,也就是之前FPGA工程中定义的slv_reg0,slv_reg1,slv_reg2,slv_reg3,slv_reg4寄存器的偏移地址。

此外还定义了读写寄存器的宏定义函数,分别为:

MYAPP_0_mWriteReg和MYAPP_0_mReadReg。

最后还有一个自测试的函数:MYAPP_0_Reg_SelfTest。

双击打开myapp_0.c,可以看到里面只有一条包含头文件的代码。用户可以在这里定义自定义的驱动函数。因为示例中我们没有用到复杂的驱动函数,所有只使用头文件中定义的宏定义来实现寄存器的读写就可以了。

  1. 点击菜单FileNewApplication Project,新建一个ARM上的应用软件工程。

  2. 工程名称为“custom_ip_test”,模板为“Hello World”模板。

  3. 修改helloworld.c文件的代码如下。

    1. #include <stdio.h>

    2. #include “platform.h”

    3. #include “xil_printf.h”

    4. #include “myapp_0.h”

    5. #include “xparameters.h”

    6. #include “xil_io.h”

    7. int main()

    8. {

    9. u32 regValue;

    10. init_platform();

    11. print(“Hello World\n\r”);

    12. MYAPP_0_mWriteReg(XPAR_MYAPP_0_0_S00_AXI_BASEADDR,MYAPP_0_S00_AXI_SLV_REG0_OFFSET,2);

    13. MYAPP_0_mWriteReg(XPAR_MYAPP_0_0_S00_AXI_BASEADDR,MYAPP_0_S00_AXI_SLV_REG1_OFFSET,5);

    14. regValue =
      MYAPP_0_mReadReg(XPAR_MYAPP_0_0_S00_AXI_BASEADDR,MYAPP_0_S00_AXI_SLV_REG3_OFFSET);

    15. printf(“result is %u \n\r”, (unsigned int)regValue);

    16. cleanup_platform();

    17. return 0;

    18. }

  4. 其中第16行和第17行代码调用了自定义IP的写寄存器宏定义,分别在slv_reg0和slv_reg1中写入数值2和5。第19行代码调用自定义IP的读寄存器宏定义,读取slv_reg3中的数值,并放入regValue变量中。第20行代码,打印slv_reg0

    • slv_reg1 = slv_reg3的结果。
  5. 打开PuTTY串口调试工具,设置串口号和波特率(笔者为:COM3、115200),打开串口监视端口。

  6. 右键点击custom_ip_test工程选择Run As Run
    Configuration。弹出运行配置对话框,双击Xilinx C/C++ application (System
    Debugger)新建一个运行配置,并选上Reset entire system和Program
    FPGA选项框。点击运行。

  7. 串口调试窗口的显示结果如下。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qtt3fJTq-1582858270704)(media/3399e2ddae252ee4f9e82edd86886997.png)]

  8. 添加如下两行代码:
    inputValue1 =
    MYAPP_0_mReadReg(XPAR_MYAPP_0_0_S00_AXI_BASEADDR,MYAPP_0_S00_AXI_SLV_REG0_OFFSET);

    inputValue2 =
    MYAPP_0_mReadReg(XPAR_MYAPP_0_0_S00_AXI_BASEADDR,MYAPP_0_S00_AXI_SLV_REG1_OFFSET);

  9. 修改printf语句为:
    printf("%u + %u = ?, result is %u \n\r",(unsigned
    int)inputValue1,(unsigned int)inputValue2, (unsigned int)regValue);

  10. 重新运行代码。得到如下的结果。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L1fQylDi-1582858270707)(media/47c488e62ab7508314970af246d556c5.png)]

ReadReg(XPAR_MYAPP_0_0_S00_AXI_BASEADDR,MYAPP_0_S00_AXI_SLV_REG1_OFFSET);*

  1. 修改printf语句为:
    printf("%u + %u = ?, result is %u \n\r",(unsigned
    int)inputValue1,(unsigned int)inputValue2, (unsigned int)regValue);

  2. 重新运行代码。得到如下的结果。

    [外链图片转存中…(img-L1fQylDi-1582858270707)]

实验结束。

声明:笔者通常是将word转成.md文件,但是在csdn导入时却每次不能导入图片,不是故意没图片的。可直接去下载笔者上传的word文档,另附上工程源码一份。如果暂时下载不了可能是正在审核中。
源码链接:https://download.csdn.net/download/weixin_43354598/12197619

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/346172
推荐阅读
相关标签
  

闽ICP备14008679号