建立工程

这里参照上一篇文章ZYBO学习笔记(一)- PL端实现流水灯建立工程ps_led

clipboard.png

建立 Block Design

当我们的设计需要用到 Zynq 的处理器系统(Processing System, PS)时候,就需要透过 Block Design 来建立我们的电路设计,点击IP Integrator -> Create Block Design
clipboard.png

保持默认设置点击OK
clipboard.png

点选 Add IP 按钮去增加我们需要的 IP 核
clipboard.png

我们首先寻找 Zynq 并将ZYNQ7 Processing System加入到我们的Block Design

clipboard.png

双击添加后的PS核,然后点击上方的Import xps settings,导入zybo的板卡网表文件zybo_zynq_def.xml,然后点击ok。如下图红框所示

clipboard.png

进入到Run Block Automation的设定页面后,确认processing_system7_0有被勾选到,并且Cross Trigger In以及 Cross Trigger Out都是Disable的状态,点选 Ok 结束设定。
clipboard.png

上面的设定好了后,就会看到ZYNQ7 Processing System的 DDR 以及 FIXED_IO 都有接线出来

clipboard.png

点选 Add IP 按钮去增加我们需要的 IP 核,这次我们要增加 AXI_GPIO ,用来对可程式逻辑(Programmable Logic, PL)区域的 LED 进行控制

clipboard.png

双击GPIO IP,按如图配置,包含4bit的输入和4bit的输出,然后点击ok:

clipboard.png

此时diagram界面如下所示。我们需要建立IP与PS之间的通道。点击Run connection automation,如下图所示

clipboard.png

勾选“all automation“,点击ok

clipboard.png

系统自动生成连接

clipboard.png

此处详解:PS核与PL的IP之间通信方式只有一种,那就是通过AXI总线。AXI interconnect IP是一个功能强大的IP,它能管理多个AXI接口的IP。用户如果用到多个AXI IP,那么只需PS将M_AXI_GP0引脚连接到AXI interconnect Ip的SO0_AXI引脚,再将AXI interconnect ip的输出分别连接到每个AXI IP的S_AXI引脚即可,省去了多个AXI互联的管理问题。Processor System Reset IP为其他IP提供复位信号。

连接完毕axi ip后,还需进行ip的地址分配,以便ps部分对IP的调用。在Address Editor一栏,直接点击左侧的auto assign address按钮。如下图所示:

clipboard.png

接下来将GPIO引脚重新命名

clipboard.png

接下来点选 Validate Design 按钮,我们要确认我们的 Block Design 没问题才能够继续往下走。
clipboard.png

添加引脚约束

参考前文ZYBO学习笔记(一)- PL端实现流水灯添加Zybo-Master.xdc引脚约束文件,取消注释LED部分

产生HDL Wrapper

clipboard.png

然后选择
clipboard.png

生成相应的HDL Wrapper文件
clipboard.png

修改Constraints文件让Wrapper和Constraints文件里面的引脚对应起来

  output [3:0]led_tri_o;
  input [3:0]sw_tri_i;

改好后,点选上方的 Run Implementation 来确认我们这样的修改是否能编译/验证成功。
clipboard.png

产生位元流 (bitstream)

前面的处理都好了后,接下来点选 Program and Debug -> Generate Bitstream 去让 Vivado 将这个专案产生出位元流 (bitstream),ZYNQ 会根据 bitstream 的资讯对 FPGA 进行设定。
clipboard.png

当 bitstream 产生完成后,由于我们这次的实作,是要透过写 C 语言程式来控制 Zynq 进行 LED 的亮暗,因此要先将刚刚产生的硬体资讯输出给 Xilinx SDK 去。

点击File -> Export -> Export Hardware

clipboard.png

完成后,启动 Xilinx SDK

clipboard.png

Xilinx SDK

选择File -> New -> Application Project建立工程

clipboard.png

我这里命名为LED

clipboard.png

clipboard.png
当专案建立完成后,会自动打开 LED_bsp 裡面的 system.mss ,裡面会显示我们所用的週边范例程式码以及使用手册的连结,我们可以点选这些连结来了解这些週边要怎样使用。
clipboard.png

建立 main.c

在LED的src下右键新建文件
clipboard.png

clipboard.png

代码

#include <stdio.h>
#include "platform.h"
#include "xgpio.h"

//void print(char *str);
XGpio SW_LED;

#define SW_CHANNEL 1

#define LED_CHANNEL 2

#define SW_IN XGpio_SetDataDirection(&SW_LED, SW_CHANNEL, 0x0f)

#define LED_OUT XGpio_SetDataDirection(&SW_LED, LED_CHANNEL, 0x00)

#define SW_VALUE XGpio_DiscreteRead(&SW_LED, SW_CHANNEL)

int init_gpio(){
    int Status;

    Status = XGpio_Initialize(&SW_LED, XPAR_AXI_GPIO_0_DEVICE_ID);

    if (Status != XST_SUCCESS){

        return XST_FAILURE;

    }
    SW_IN;

    LED_OUT;

    return XST_SUCCESS;
}

int main(){
    int value;

    init_platform();

    print("Hello World\n\r");

    init_gpio();

    while(1){
        value = SW_VALUE;
        XGpio_DiscreteWrite(&SW_LED, LED_CHANNEL,value);
    }


    cleanup_platform();

    return 0;
}

LED闪烁USB串口循环打印测试

int main(){
    int value;

    init_platform();

    print("Hello World\n\r");

    init_gpio();

    value = SW_VALUE;

    while(1){

        XGpio_DiscreteWrite(&SW_LED, LED_CHANNEL, value);

        value = ~value;

        print("Hello World\n\r");

        simple_delay(10000000);
    }


    cleanup_platform();

    return 0;
}

程序分析

在 main.c 的开头,我们载入了需要使用的几个标头档,在 Xilinx SDK 中,已经包含了一些预设好的函式库等功能,具体资讯请查阅Xilinx OS and Libraries Document Collection (UG643)手册。

xparameters.h这个标头档则是 Xilinx SDK 自己产生的,里面会包含一些关于你使用的 IP Core 的资讯,比如标准输出的基底位址 (base address) 或是其他和你这份硬体相关的设定。而xgpio.h则提供了一些高阶的抽象函式,让你开发 GPIO 相关的功能可以更加轻松。

参考文档在vivado安装目录下可以找到,我的电脑在file:///D:/Xilinx/SDK/2015.4/data/embeddedsw/XilinxProcessorIPLib/drivers/gpio_v4_0/doc/html/api/group__gpio__v4__0.html直接浏览器打开

int XGpio_Initialize(XGpio * InstancePtr, u16 DeviceId)根据DeviceId例化XGpio,DeviceIdxparameters.h里定义,初始化成功返回XST_SUCCESS

clipboard.png

void XGpio_SetDataDirection(XGpio * InstancePtr,unsigned Channel,u32 DirectionMask)Channel控制当前操作IP核里哪一个通道的GPIO,这里1组是开关输入,2组是输出到LED。DirectionMask参数决定了输入输出,0输出,1输入每位对应1个IO

clipboard.png

u32 XGpio_DiscreteRead(XGpio * InstancePtr,unsigned Channel)这个很好理解就是读GPIO上的值

void XGpio_DiscreteWrite(XGpio * InstancePtr, unsigned Channel, u32 Data)设置GPIO输出的值

下载到Zybo board

确定此时你有将 Zybo board 接到电脑,并且你 JP5 设定在 QSPI 模式下,就像这样

clipboard.png

选择 Xilinx Tools -> Program FPGA 进行 FPGA 的烧录。

clipboard.png

确认要烧录的资料无误后,点选Program将位元流 (bitstream) 烧录到 FPGA 去

clipboard.png

clipboard.png

下载bit完毕,接着就是运行PS了。在工程左侧Procject Explorer栏,右击hello->RunAs->Launch on Hardware,如下图:

clipboard.png

稍等几秒,就可以操作SW了。LED的状态随着SW的改变而改变。

参考

https://reference.digilentinc...
https://coldnew.github.io/dec...
https://blog.csdn.net/lzy2729...


Kyseng
1 声望3 粉丝

电子爱好者一枚,利用工作空余时间记录一下学习过程