本原创教程由芯驿电子科技(上海)有限公司(ALINX)创作,版权归本公司所有,如需转载,需授权并注明出处。
AXU2CGA/AXU2CGB/AXU3EG/AXU4EV-E/AXU4EV-P/AXU5EV-E/AXU5EV-P /AXU9EG/AXU15EG
实验Vivado工程目录为“pl_read_write_ps_ddr/vivado”。
实验vitis工程目录为“pl_read_write_ps_ddr /vitis”。
PL和PS的高效交互是zynq soc开发的重中之重,我们常常需要将PL端的大量数据实时送到PS端处理,或者将PS端处理结果实时送到PL端处理,常规我们会想到使用DMA的方式来进行,但是各种协议非常麻烦,灵活性也比较差,本节课程讲解如何直接通过AXI总线来读写PS端ddr的数据,这里面涉及到AXI4协议,vivado的FPGA调试等。
以下为FPGA工程师负责内容。
zynq 7000 SOC的HP口是 High-Performance Ports的缩写,如下图所示,一共有4个HP口,HP口是AXI Slave设备,我们可以通过这4个HP接口实现高带宽的数据交互。
1)基于“ps_hello”工程,在vivado的界面中HP的配置如下图(HP0~HP3),这里面有使能控制,数据位宽选择,可选择32bit、64bit或128bit的位宽。我们的实验启用HP0配置为64bit位宽,使用的时钟是150Mhz,HP的带宽是150Mhz * 64bit,对于视频处理,ADC数据采集等应用都有足够的带宽。不需要AXI HPM0 LPD,取消选择。
2)添加复位模块,用于复位
3)在空白处右键选择”Creat Port”
配置如图
4)连接时钟和复位
5)选中引脚,点击Make External,将信号导出
并修改引脚名称如下图
并选择总线同步时钟为axi_hp_clk
6)点开Address Editor,如果发现地址没有分配,点击自动分配地址按钮
分配后的结果,可以看到访问DDR, QSPI, OCM的地址空间
保存设计,重新Generate Ouput Product
7)添加hdl文件
点击Finish
HDL层级关系更新结果
AXI4相对复杂,但SOC开发者必须掌握,对于zynq的开发者,笔者建议能够在一些已有的模板代码基础上修改。AXI协议的具体内容可参考Xilinx UG761 AXI Reference Guide。在这里我们简单了解一下。
AXI4所采用的是一种READY,VALID握手通信机制,即主从模块进行数据通信前,先根据操作对各所用到的数据、地址通道进行握手。主要操作包括传输发送者A等到传输接受者B的READY信号后,A将数据与VALID信号同时发送给B,这是一种典型的握手机制。
AXI总线分为五个通道:
读地址通道,包含ARVALID, ARADDR, ARREADY信号;
写地址通道,包含AWVALID,AWADDR, AWREADY信号;
读数据通道,包含RVALID, RDATA, RREADY, RRESP信号;
写数据通道,包含WVALID, WDATA,WSTRB, WREADY信号;
写应答通道,包含BVALID, BRESP, BREADY信号;
系统通道,包含:ACLK,ARESETN信号;
其中ACLK为axi总线时钟,ARESETN是axi总线复位信号,低电平有效;读写数据与读写地址类信号宽度都为32bit;READY与VALID是对应的通道握手信号;WSTRB信号为1的bit对应WDATA有效数据字节,WSTRB宽度是32bit/8=4bit;BRESP与RRESP分别为写回应信号,读回应信号,宽度都为2bit,‘h0代表成功,其他为错误。
读操作顺序为主与从进行读地址通道握手并传输地址内容,然后在读数据通道握手并传输所读内容以及读取操作的回应,时钟上升沿有效。如图所示:
写操作顺序为主与从进行写地址通道握手并传输地址内容,然后在写数据通道握手并传输所读内容,最后再写回应通道握手,并传输写回应数据,时钟上升沿有效。如图所示:
在我们不擅长写FPGA的一些代码时我们往往要借鉴别人的代码或者使用IP core。在这里笔者从github上找到一个AXI master的代码,地址是https://github.com/aquaxis/IPCORE/tree/master/aq_axi_vdma。这个工程是一个自己写的VDMA,里面包含了大量可参考的代码。笔者这里主要使用了aq_axi_master.v这个代码用于AXI master读写操作。借鉴别人代码有时会节省很多时间,但如果不能理解的去借鉴,出现问题了很难解决。具体可以参考aq_axi_master.v代码,有部分修改。
有了AXI Master读写接口以后比较编写了一个简单的验证模块,这个验证模块是用来验证ddr ip的,通过写入数据,然后读取出来比较。这里要注意的是PS端DDR的起始地址和大小,还有地址的单位是byte还是word,AXI总线的地址单位是byte,测试模块的地址单位是word(这里的word不一定是4byte)。文件名mem_test.v。
AXI读写验证模块只有一个error信号用于指示错误,如果有数据错误我们希望能更精确的信息,altera的quartus II软件中有signal tap工具,xilinx 的ISE中有chipscope工具,这些都是嵌入式逻辑分析仪,对我们调试有很大帮助,在vivado软件中调试更加方便。在插入调试信号时有些信息可能会被优化掉,或者信号名称改变了就不容易识别,这个时候我们可以在程序代码里加入*mark_debug="true"*这样的属性,如下图的信号:
具体的添加方法在”PL的“Hello World”LED实验”中已经讲过,可参考。
并在XDC文件里绑定error信号到PL端LED灯上。
以hello world为模板新建vitis工程如下
通过vitis下载程序后,系统会复位并且下载FPGA的bit文件。然后回到vivado界面点击Program and Debug栏自动连接目标如下图所示:
自动连接硬件后可发现JTAG连上的设备,其中有一个hw_ila_1的设备,这个设备就是我们debug设备,选中后可点击上方黄色三角按钮捕捉波形。如果有些信号没有显示完整,可点击波形旁边的“+”按钮添加。
点击捕获波形以后如下图所示,如果error一直为低,并且读写状态有变化,说明读写DDR数据正常,用户在这里可以自己查看其它的信号来观察写入DDR的数据和从DDR读出的数据。
zynq系统相对于单个FPGA或单个ARM要复杂很大,对开发者的基础知识要求较高,本章内容涉及到AXI协议、zynq的互联资源、vivado的和Vitis的调试技巧。这些都仅仅是基础知识,笔者在这里也仅仅是抛砖引玉,大家还是要多多练习,在不断练习中掌握技巧.
全部0条评论
快来发表一下你的评论吧 !