ZYNQ基础系列(一) AXI总线通信

PS-PL通信之AXI总线

在ZYNQ开发过程中,PS与PL之间的通信是不可避免的,除了MIO与EMIO通信外,还有一种更高速的接口与ARM核通信。本章将创建并测试一个基于高速AXI总线的IP核,以及调用并测试vivado自带的IP核。

一、创建IP

1. 新建工程

2. 单击 Tools 菜单下的 Create and package IP

3. 单击 Next,选择 Create a new AXI4 peripheral,单击 Next。


4. 输入名字和一些信息


5. 配置接口类型、数据位宽和地址线位宽等


6. 选择 Edit IP,然后选择 Finish 按钮将打开一个新的编辑 IP 的工程

7. 打开如图.v文件,并添加输出端口和赋值语句


8. 修改此.v文件的上层.v,并添加输出端口


9.单击 Tools 菜单下的 Create and package IP 命令,重新封装 IP,如图选择,点next


10. 选择路径后保存IP,若按默认路径,则继续点击overwrite 该IP

11. 在弹出的新窗口中选择 Review and package IP,package IP核


至此已完成IP核的创建

二、创建工程

1. 新建另一个vivado工程

2. 在setting中添加IP路径


3. 新建一个 BD 文件,并添加一个ZYNQ Processing system和刚刚创建的IP,并设置好ZYNQ Processing system的与硬件相符合的PS和PL时钟以及DDR型号(防止SDK的程序崩溃)


4. 点击自动布线,并把LED_AXI的线按CTR+T引出来


5. 右键单击 Block 文件,文件选择 Generate the Output Products

6. 右键单击 Block 文件,选择 Create a HDL wrapper,根据 Block 文件内容产生一个 HDL 的顶层文件,并选择让 vivado 自动完成

7. 添加引脚约束文件,并综合实现、生产.bit文件

三、加载到SDK

1. 导出硬件

2. 新建一个空 SDK 工程,并添加一个 main.c 的文件

    #include <stdio.h>
    #include "xparameters.h"
    #include "xil_io.h"
    #include "sleep.h"
    #include "xil_types.h"
    #define XGpio_axi_WriteReg(BaseAddr, RegOffset, Data) \
    Xil_Out32((BaseAddr) + (u32)(RegOffset), (u32)(Data))
    #define AXI_LED XPAR_AXI_LED_SW_V1_0_0_BASEADDR

    #define GPIO_LITE_ML_REG0 0
int main()
{
    u8 i=0;
    XGpio_axi_WriteReg(AXI_LED,GPIO_LITE_ML_REG0,0X00);
  while(1)
  {
    for(i=0;i < =3;i++)
    {
    XGpio_axi_WriteReg(AXI_LED,GPIO_LITE_ML_REG0,1<<i);
    usleep(500000);
    }
    i=0;
  }
}

3. 设置好相关参数,点击RUN按钮


最后可以看到LED轮流闪烁。

四、调用系统AXI的IP增加按键输入

1. 搜索并添加AXI GPIO的IP核

2. 配置IP核


3. 自动布线

4. 将GPIO展开,并将下面的输入引脚Ctr+T引出,并改名为SW


5. 修改后的原理图


6. 按照之前(二、创建工程)类似的一些操作生成.bit文件,并导出硬件到SDK

7. 更改程序

    #include <stdio.h>
    #include "xparameters.h"
    #include "xil_io.h"
    #include "sleep.h"
    #include "xil_types.h"
    #define XGpio_axi_WriteReg(BaseAddr, RegOffset, Data) \
      Xil_Out32((BaseAddr) + (u32)(RegOffset), (u32)(Data))
    #define XGpio_axi_ReadReg(BaseAddr, RegOffset) \
      Xil_In32((BaseAddr) + (u32)(RegOffset))

    #define AXI_LED XPAR_AXI_LED_SW_V1_0_0_BASEADDR
    #define AXI_SW XPAR_AXI_GPIO_0_BASEADDR

int main()
{
  u32 i=0;
  while(1)
  {
    i=XGpio_axi_ReadReg(AXI_SW,0);
    XGpio_axi_WriteReg(AXI_LED,0,i);
    usleep(5000);
  }
}

8. 最后下入程序,就可以看到LED随按键按下而变化啦

版权声明:本文为CSDN博主「long_fly」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/long_fly/article/details/78619451

最新文章

最新文章