0%

ZYNQ嵌入式之IP核(基于PYNQ-Z2开发板)

本节主要介绍了Vivado中自定义IP核的创建,以及IP核如何与PS建立联系,并以一个呼吸灯实验为例作为演示

自定义IP核的创建与编辑

1.IP核的创建

  • 创建管理IP核的工程

    image-20230923105815914

  • 创建并封装一个新的ip

    image-20230923105917271

  • 创建AXI4外设:当verilog代码需要跟PS做一些数据交互的时候选这个

    image-20230923110134425

    image-20230923110245443

    image-20230923110453477

2.IP核的编辑

  • 在IP的封装包内对其进行编辑

    image-20230923110841775

  • 创建breath_LED的verilog设计文件并将其保存在对应目录下

    image-20230923111939491

  • 编写呼吸灯模块代码并在ip核中例化

    • 模块添加:

      image-20230923135247006

    • 添加参数和自定义的输入或输出端口

      image-20230923135433196

    • 端口连线

      image-20230923135833161

    • 在IP的顶层文件中添加参数和端口的例化

      image-20230923140115533

    • 同样也需要在顶层文件中添加自定义的输入或输出端口和相关参数

      image-20230923140423292

3.IP核的封装

  • Identification:

    image-20230923140851598

  • Compatibility:

    image-20230923140956297

  • File Groups:可以预览 IP 核包含的相关源码文件,在源码工程中包含的所有Verilog源码或者仿真测试脚本,也都会出现在这里,被集成到IP核中

    image-20230923141550784

  • Customization Parameters:配置相关参数

    image-20230923141502191

4.IP核的添加

image-20230923142522060


自定义IP核的应用-呼吸灯

  • 实验任务:通过自定义一个LED ip核,来控制PL LED呈呼吸灯效果,并且PS可以通过AXI接口来控制呼吸灯的开关和呼吸的频率

    image-20230923105200759

1.Vivado中的block design

  • 直接加载zynq芯片与breath_led的IP核,点击自动配置与自动连线,最终block design的设计图如下:

    image-20230923144504423

  • led的管脚分配

    image-20230923145121578

2.Vitis中代码编写

  • LED灯先快闪5s之后,休息1s,开始慢闪
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include<iostream>
#include<xparameters.h>
#include<breath_led_ip.h>
#include<xil_io.h>
#include<sleep.h>
using namespace std;

#define LED_IP_BASEADDR XPAR_BREATH_LED_IP_0_S01_AXI_BASEADDR //呼吸灯IP核的基地址
#define SLV_REG0_OFFSET BREATH_LED_IP_S01_AXI_SLV_REG0_OFFSET //寄存器地址0的偏移量
#define SLV_REG1_OFFSET BREATH_LED_IP_S01_AXI_SLV_REG1_OFFSET //寄存器地址1的偏移量

int main(void)
{
int freq_flag = 0;
while(1)
{
if(freq_flag == 0)
{
BREATH_LED_IP_mWriteReg(LED_IP_BASEADDR, SLV_REG1_OFFSET, 0x800000ef);
freq_flag = 1;
}
else
{
BREATH_LED_IP_mWriteReg(LED_IP_BASEADDR, SLV_REG1_OFFSET, 0x8000001f);
freq_flag = 0;
}
BREATH_LED_IP_mWriteReg(LED_IP_BASEADDR, SLV_REG0_OFFSET, 0x00000001); //打开呼吸灯开关
sleep(5);
BREATH_LED_IP_mWriteReg(LED_IP_BASEADDR, SLV_REG0_OFFSET, 0x00000000); //关闭呼吸灯开关
sleep(1);
}
return 0;
}

由于自定义IP导入Vitis,会出现一个bug

  • 解决办法参考:

  • 我的makefile文件如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    COMPILER=
    ARCHIVER=
    CP=cp
    COMPILER_FLAGS=
    EXTRA_COMPILER_FLAGS=
    LIB=libxil.a

    RELEASEDIR=../../../lib
    INCLUDEDIR=../../../include
    INCLUDES=-I./. -I${INCLUDEDIR}

    INCLUDEFILES=$(wildcard *.h)
    LIBSOURCES=$(wildcard *.c *.cpp)
    OUTS = $(addsuffix .o, $(basename $(wildcard *.c)))

    OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c *.cpp)))
    ASSEMBLY_OBJECTS = $(addsuffix .o, $(basename $(wildcard *.S)))

    libs:
    echo "Compiling breath_led_ip..."
    $(COMPILER) $(COMPILER_FLAGS) $(EXTRA_COMPILER_FLAGS) $(INCLUDES) $(LIBSOURCES)
    $(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OUTS}
    make clean

    include:
    ${CP} $(INCLUDEFILES) $(INCLUDEDIR)

    clean:
    rm -rf ${OUTS}
欢迎来到ssy的世界