1 概述 Zynq将ARM和FPGA整合到了一个芯片上,它的过人之处不仅是功耗、面积、成本的优化,更多的是将二者之间原本极为受限的数据交互方式转移到芯片内部完成,4条AXI GP通道(2个从机、2个主机)和4条AXI HP通道(均为从机)能够大大提升系统数据交互带宽,使得软硬协同设计变得更为灵活。AXI HP总线是专为大吞吐量数据传输设定的,AXI GP则更多的是为了方便ARM侧对PL(FPGA逻辑)进行常规的数据寄存器读写控制或状态监控。在实际项目中,AXI GP常常不可或缺,本实例我们就要设计一个PL端的AXI GP从机,实现PS端可读写访问的AXI GP寄存器外设。 2 AXI总线协议介绍 参考文档《玩转Zynq-基础篇:AXI总线协议介绍.pdf》。 3 AXI GP外设配置 在zstar_ex53实例的基础上,需要对ZYNQ7Processing System(PS)配置页面做更改。选择PageNavigator的PS-PLConfiguration项。然后如图所示,展开AXINon Secure Enablement --> GP Master AXI Interface,勾选M AXI GP0 interface,相当于开启PS系统的AXI GP0的主机功能。注意下面还有一个M AXI GP1 interface,也就是说Zynq最多可以有2个AXI GP主机外设。 接着,在Clock Configuration项,展开PL Fabric Clocks,勾选FCLK_CLK0,设定时钟频率为100(MHz)。这个由PS引出的时钟将要作为AXI GP的工作时钟。 完成ZYNQ7 Processing System的配置更改后,回到Diagram界面中,可以看到新出现了名为M_AXI_GP0_ACLK、M_AXI_GP0和FCLK_CLK0的接口,下面我们要对这些接口进行连接或引出。先点击选中processing_system7_0的M_AXI_GP0接口,颜色呈现灰色,然后单击右键,弹出菜单中选择CreateInterface Port...。 弹出Create Interface Port选项卡,输入Interfacename为AXI_GP0,VLNV和Mode使用默认设定,点击OK。 选中FCLK_CLK0,右键菜单中选择CreateInterface Port...,配置名称为FCLK_CLK_100M,如图所示。 选中FCLK_RESET0_N,右键菜单中选择CreateInterface Port...,配置名称为FCLK_RESET_N,如图所示。 完成这3个接口引出后,如图所示。 将鼠标靠近FCLK_CLK_100M的连线处,出现一只小笔的图标,点击它并且保持鼠标按下,将鼠标拖动到左侧M_AXI_GP0_ACLK接口出,出现一条预连线,松开鼠标,则连接好FCLK_CLK_100M和M_AXI_GP0_ACLK信号如图所示。也就意味着,FCLK_CLK_100M将作为AXI_GP0的时钟源。 此时,切换到AddressEditor窗口,展开Data项出现了AXI_GP0的外设,当前的Offset Address、Range和High Address都未分配。可以如图点击左侧的Auto Assign Address图标自动分配地址。 分配完成后,如图所示。OffsetAddress是0x43c00000,Range是64K。也就是说,这个AXI_GP0外设定义的寄存器必须在这个0x43c00000地址开始的64K地址空间内。 回到Diagram中,空白处右键单击,弹出菜单点击Validate Design,确认框图连接配置没有错误。 如图所示,提示Validationsuccessful表示系统连接符合规则,点击OK。 Sources窗口中,展开顶层模块zstar.v,看到zstar_zynq_ps_i就是我们的框图连接的Zynq系统,右键单击它,选择GenerateOutput Products...。 弹出如图所示的GenerateOutput Products页面,点击Generate。 完成Generate后弹出如图所示的completed successfully提示信息,点击OK。 此时,打开Zynq系统的例化模板文件zstar_zynq_ps_wrapper.v,可以看到有很多AXI_GP0打头的信号增加到了系统中,这些信号就是Zynq系统作为主机连接到PL的AXI GP总线接口。接下来我们要做的事就是设计一个AXI GP从机接口和AXI_GP0_*接口连接起来,实现Zynq PS端可以读写的寄存器接口。 编辑顶层源码,将我们的AXI GP从机模块和PS生成的AXI GP主机模块的接口连接起来。 4 AXI GP从机设计 该工程的模块层次如图所示,zstar.v是顶层模块,其下例化PS模块zstar_zynq_ps.v以及AXI GP总线从机模块axi_gp_top.v模块。PS模块zstar_zynq_ps.v是通过配置ZYNQ系统自动生成的;axi_gp_top.v模块以及其下的两个子模块,是这个实例我们自己动手编写的逻辑。axi_gp_ctrl.v模块对AXI GP总线的控制、地址时序进行译码,axi_gp_data.v模块则是AXI GP总线对该从机进行实际读写数据操作时产生必要的数据在读或写总线上。 下面我们看看各个模块中涉及AXI GP总线的逻辑是如何设计的。 在zstar.v模块中,将axi_gp_top.v模块和zstar_zynq_ps.v模块的AXI GP总线信号接口进行连接。在Schematic视图中,可以看到这些高亮的连续就是它们之间的AXI GP总线信号接口。 在axi_gp_top.v模块中,主要也是起到一个例化模块和连接信号的作用,这个模块中也没有什么具体的设计逻辑。 axi_gp_ctrl.v模块中,则是对AXI GP总线的读、写使能信号,读、写地址信号进行译码,产生一组新的控制信号。axi_gp_data.v模块则通过这些控制信号送出AXI GP总线需要读取的数据,或者从AXI GP总线上接收写入的数据。axi_gp_ctrl.v模块对AXI GP总线的控制和地址信号译码后的这组新的控制信号如下。 //AXI GP总线译码控制接口 outputaxi_slaver_wr_en, //AXI写使能 outputreg[15:0] axi_slaver_wr_addr, //AXI写地址 output[31:0]axi_slaver_wr_data, //AXI写数据 outputaxi_slaver_rd_en, //AXI读使能 output[15:0] axi_slaver_rd_addr, //AXI读地址 input[31:0]axi_slaver_rd_data //AXI读数据 可以这样说,AXI GP总线需要遵循一定的总线协议,相对比较复杂,而我们译码后的控制信号,则简化了总线本身的复杂性,后续模块可以根据这组信号的状态对相应地址的数据实现主机的读写操作。 axi_gp_data.v模块则使用axi_gp_ctrl.v模块的控制和地址信号,在AXI GP主机要读数据时,将相应地址的数据送到AXI GP读数据总线上;在AXI GP主机要写数据时,对相应地址的数据进行更新。 5 工程编译 对工程进行全编译,生成Bitstream。由于该工程需要将AXI GP总线的信号引出使用FPGA的在线逻辑分析仪观察时序,所以需要先RunSynthesis,然后SetUp Debug设置需要观察的信号,最后再做全编译。具体可以参考文档《玩转Zynq-工具篇:基于Vivado的在线逻辑分析仪板级调试》。 6 嵌入式软件开发 参考文档《玩转Zynq-工具篇:导出PS硬件配置和新建SDK工程.pdf》导出PS硬件工程,并打开EDK新建一个HelloWorld的模板工程。 修改HelloWorld工程中的HelloWorld.c源码如下。每隔2s对0x43c00000基址(AXI_GP0总线外设的地址空间)的0、4和8偏移地址执行读写操作,并且打印读出数据。 7 板级调试 在Zstar板子上,设置跳线帽P3为JTAG模式,即PIN2-3短接。 连接好串口线(USB线连接PC的USB端口和Zstar板的UART接口)和Xilinx下载线(下载器连接PC的USB端口和Zstar板的JTAG插座)。使用5V电源给板子供电。 参考文档《玩转Zynq-工具篇:SDK在线运行裸跑程序.pdf》将当前工程产生的.bit文件和.elf文件在Zstar板上运行起来。 打开PuTTY,设定好串口号和波特率115200,可以看到不断的打印如下的信息。 若希望使用在线逻辑分析仪对AXI GP总线接口波形进行观察,可以参考文档《玩转Zynq-工具篇:基于Vivado的在线逻辑分析仪板级调试》。
|