基于Smart ZYNQ (SP/SP2/SL 版) 的PS实验十三 PS与PL数据交互之 PS访问 PL端的reg 寄存器

PS端与PL端在硬件上是相互独立的,之前可以通过EMIO 和 AXI GPIO等方式 让ZYNQ PS 端的GPIO 口映射到PL端上,但是仅仅只能控制GPIO。 本文介绍一种新的方法,通过让PS端访问PL端寄存器的方式,来让ARM 和FPGA实现简单的数据交互(小数据量)

  • 此章节内容适用于Smart ZYNQ SP SP2和 SL 版的板子 ( 不包含Smart ZYNQ 标准版 ),如是标准版或本站其他板子请看对应板子目录
  • 本文在 vivado2018.3版本上演示

一、工程创建

工程创建的过程可以参考实验一中的内容,这里不详细描述了。基于Smart ZYNQ (SP/SP2/SL 版) 的PS实验一 GPIO之用EMIO方式点亮LED(完整图文) (芯片型号选XC7Z020CLG484-1)

二、创建一个带AXI 接口的IP

  1. 创建并封装一个带AXI 接口的IP 具体过程如下 ,TOOLS->Create and Package New IP

2.选择封装带AXI4总线的

3、next,填写名称等信息,注意IP保存路径(保存到工程目录下就可)。这里给IP取名 PS_PL_REG 即 PS和PL的REG互相访问


4、next,选择总线相关信息,这里AXI的 协议选择 LITE 轻型, 然后number of registers 根据需求选择,4即代表有四个32bit的寄存器 最小选择是4个

5.选择 下一步 EDIT IP 并点FINISH完成(这里一定要选择“Edit IP”,否则,软件只是生成了框架文件,而不会创建一个关于IP 核的工程)

6.之后系统会自动生成一个该IP的工程。 这里我们双击打开系统默认生成的IP代码

7.研究代码,可以看到 我们设置IP的时候 PL端的4个用于PS访问的寄存器分别是 slv_reg0,slv_reg1,slv_reg2,svl_reg3 ,这4个寄存器 通过AXI 接口,可供ARM PS端进行读和写的操作。

8.为了让交互的过程更为直观,我们在原有的IP代码中添加一个LED指示灯用来观察交互的结果

output reg LED;

并在代码中增加以下代码用来将灯和数据进行对应

   always@(posedge S_AXI_ACLK)begin
        if(slv_reg0==32'd0)LED<=0;
        else if(slv_reg0<=32'd1)LED<=1;
    end

代码解释 ,当slv_reg0等于32位的0时 LED 熄灭, 当slv_reg0等于32‘d1时,即十进制1时,LED点亮(slv_reg0后面可由ARM端的程序直接读写)

9.对系统生成的IP的上层模块,也相应的增加LED 接口,并与内部的模块相连接

10.编辑完后,保存修改,接下来是打包 修改完的IP(封装之前,先编译综合看看代码是否有报报错),回到Package IP页面设置IP,如下所示输入相关信息,也可以不修改

11) 在file Groups项中点击Merge changs from File Groups Wizard

12) 根据上面的操作,也将软件界面中没有打勾的 选项全部都merge了

当除了最后一项,所有的选项都勾上更新后, 在最后一栏里点重新打包封装IP,完成IP的打包

IP打包后,修改IP的工程会被系统自动关闭

三、在vivado工程中增加ZYNQ模块

1.增加ZYNQ 模块

在Block Design 中 增加ZYNQ模块,并且在设置界面 将DDR选项设置成 MT41K256M16RE-125 位宽选择16bit

2)选择 Run Block Automation 完成端口自动布线

3)手动连接 FCLK_CLK0到 M_AXI_GP0_ACLK

4)在block design 中添加我们刚才创建的PS_TO_PL_REG IP模块

5) 如下图所示 我们添加的PS_PL_REG模块已经添加到设计中,再次点选run connection automation尝试自动连线

如下图所示,系统为我们自动添加需要增加的模块,并自动连接好了各个模块

6) 因为我们的演示 是需要通过LED 来观察结果的,所以这里右键LED 将LED窗口印出来

这样我们的整个硬件系统就算布局完成了。

7) 在design Sources中 右键我们刚刚设计的ZYNQ模块,然后点选 Create HDL Wrapper

8)编译 RUN

9)为LED 分配管脚

10)综合并生成 bit文件

三、PS部分工程创建

1)File→Export→Export hardware…,在弹出的对话框中勾选“include bitstream”,点击“OK”确认,如下图所示。

2)File→Lauch SDK,在弹出的对话框中,保存默认,点击“OK”,如下图所示。

系统将自动打开SDK开发环境

3)再创建一个LED 工程,负责LED 指示灯的闪烁

a. 创建一个新的空工程,可以取名叫PS_PL_REG_TEST

b.右键工程的SRC目录,然后新建一个SOURCE FILE

c.取名 main.c

四、PS端代码编写

1.点开platform中的 system.hdf 这里所有的资源都会显示在这里, 找到我们之前创建的PS_PL_REG ,可以看到 这个外设的基地址是 0X43C00000 ,后面我们会用到这个地址

2.在main .c中添加如下代码

#include "xparameters.h"
#include "xil_io.h"

#define LED_BASE_ADDR 0x43c00000

int main()
{
	volatile int Delay;

    while(1)
    {

    	Xil_Out32(LED_BASE_ADDR, 1);
    	for (Delay = 0; Delay < 10000000; Delay++);
    	Xil_Out32(LED_BASE_ADDR, 0);
    	for (Delay = 0; Delay < 10000000; Delay++);
    }

    return 0;
}

五、下载与验证

1)新创建的工程最好先对Run as 进行配置:右键工程,并点选Run As -> Run Configurations

2) 在弹出的窗口中对Reset entire system 和 Program FPGA两个选项进行勾选操作,这样就不会出现下载程序debug的时候概率性不工作的问题了。(这样操作后系统会自动对FPGA进行配置,不需要按之前工程手动对FPGA进行编程了)

PS如果没有出现下图对话框,可以直接双击左侧的applicationo (System Debugger)。

3)设置好之后,选择Run As -> Launch on Hardware (System Debugger) 进行调试。

可以看到板子上的LED1灯在闪烁

六、代码解读

#define LED_BASE_ADDR 0x43c00000,这里的0X43C00000就是我们之前看到的 模块地址

Xil_Out32(LED_BASE_ADDR, 1); 相当于向上面的模块地址写入1

Xil_Out32(LED_BASE_ADDR,0) ; 相当于向模块的基地址写入0

因为我们在PL端创建的模块中的4个寄存器,只有寄存器0对应了LED ,所以我们只要向基地址写入信息就可以控制LED 指示灯了

如果要控制寄存器1,寄存器2 ,寄存器3 只需要在基地址的基础上+4就可以了 (+4是因为数据都是32bit的)

另外我们也可以反向用PS 去读取PL端的寄存器值,具体过程不展开描述了, 实际PS访问 可以通过指令Xil_In32(LED_BASE_ADDR); (LED_BASE_ADDR 为我们定义的基地址 )来进行读取。

通过上述方式 我们成功的实现了 PS和PL 通过寄存器方式的交互,这种方式相对比较简单 容易入手,当然交互的方式还有很多,后面 有时间再继续整理。

AXI 的通讯也是个大课题,有时间会继续整理相关内容

  • 本文的完整工程下载:13_PS_TO_PL_REG
  • VIVADO的版本:2018.3
  • 工程创建目录:E:\Smart_ZYNQ_SP_SL\SDK\13_PS_TO_PL_REG
  • 工程适用主板: Smart ZYNQ (SP / SP2 / SL) (不适用于Smart ZYNQ 标准版 

“基于Smart ZYNQ (SP/SP2/SL 版) 的PS实验十三 PS与PL数据交互之 PS访问 PL端的reg 寄存器”的2个回复

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注