Zynq-7000系列器件PS端的DMA控制器采用ARM的IP核DMA-330(PL-330)实现。有关DMA控制器的硬件细节及相关指令集、编程实例内容参考ARM官方文档:
DDI0424D:dma330_r1p2_trm.pdf
DAI0239A:dma330_example_programs.pdf
本文开发环境为Xilinx SDK2015.2,DMA库版本为dmaps_v2_1。
DMA控制器具有以下的特点:
n 8个独立的通道,4个可用于PL—PS间数据管理,每个通道有1024Byte的MFIFO;
n 使用CPU_2x 时钟搬运数据,CPU_2x = (CPU frq/6)*2;
n 执行自定义内存区域内的DMA指令运行DMA;
n AHB控制寄存器支持安全和非安全模式;
n 每个通道内置4字Cache;
n 可以访问SoC的以下映射物理地址:
DDR、OCM、PL、Linear QSPI Read、SMC和M_AXI_GP设备,访问设备的互联结构如图1所示。
从图1可以看出DMA控制器可以访问连接到Central Interconnect上的所有设备,并提供了四个通道的外设管理接口可用于控制PL的数据搬运。
Zynq系列器件中DMA控制器采用ARM PL-330 IP和r1p1版,结构框图如图2所示。
图2 Zynq DMA控制器结构框图
如图2所示,DMA控制器由指令加速引擎,AXI Master数据接口,AXI APB寄存器访问接口以及可以连接到PL的外设请求接口,数据缓冲FIFO和控制及状态产生单元组成。
从图2可以看到,DMA PL330的设计思想是:DMA控制器通过DMA指令执行引擎执行自己的指令,并将执行状态通过APB总线和中断等形式反馈给CPU,达到数据搬运不占用CPU的目的。
DMA控制器共有八个通道,其中四个通道负责互联到Central Interconnectcun存储单元上的数据搬运;四个数据通道为外设请求接口,可用于PL AXI互联接口的数据访问管理。
每个DMA通道都执行自己的指令,拥有自己的独立线程,通道间互不影响。指令执行引擎有自己独立的Cache线。
本文不考虑外设请求接口,DMA控制器编程分为以下几个部分:
u DMA控制器初始化;
u 组织DMA引擎执行代码;
u 启动或停止DMA传输;
u 异常处理。
DMA控制器初始化,DMA初始化包括配置时钟、复位,安全状态,中断服务等,如下表1所示。
表1 DMAC初始化配置
步骤 |
配置项 |
相关寄存器 |
描述 |
1 |
配置时钟 |
|
使能APB时钟,一般已经使能 |
slcr.AER_CLK_CTRL [DMA_CPU_2XCLKACT]=1’b1 |
使能CPU_2x时钟给AXI |
||
2 |
配置安全状态 |
SLCR. TZ_DMA_NS = 1 |
非安全 |
SLCR. TZ_DMA_IRQ_NS=1 |
非安全 |
||
SLCR. TZ_DMA_PERIPH_NS=1 |
非安全 |
||
3 |
复位 |
slcr.DMAC_RST_CLTR[DMAC_RST] |
复位DMAC |
4 |
中断 |
|
设置中断服务函数 |
一般的时钟和复位都在FSBL里面完成,用户只需要设置DMA的APB总线安全模式和中断服务函数即可。特别要注意对安全模式的设置,否则在非安全模式下访问安全模式寄存器无任何有效应答。
Xilinx SDK(gcc)不支持编译DMA引擎指令,因此需要自己对照ARM官方文档”DDI0424D_dma330_r1p2_trm.pdf”对指令集的描述一条一条的组织指令,特别注意执行指令的长度应为Cache线的整数倍,不足的用NOP补齐。
下面以DMAMOV指令为例,说明如何编写指令引擎执行的机器码,图3是DMAMOV指令的编码。
图3 DMAMOV指令的编码
本条指令编码由48位(6字节)构成,如图3中的编码:
① rd[2:0]:表示寄存器地址,000为源地址寄存器SAR,001为通道控制寄存器CCR,DAR为目的地址寄存器。
② imm[31:0],为以上三个寄存器的配置值。
CCR为AXI总线配置寄存器,参见文档DDI0424D中 3.3.15 Channel Control Registers章节的描述;有关AXI总线协议接口描述自行参照ARM官方文档IHI 0022D:AMBA AXI andACE Protocol Specification。
那么生成DMAMOV机器码的函数如下所示:
INLINE int XDmaPs_Instr_DMAMOV(char *DmaProg, unsigned Rd, u32 Imm)
{
/*
* DMAMOV encoding
* 15 4 3 2 1 10 ... 8 7 6 5 4 3 2 1 0
* 0 0 00 0 |rd[2:0]|1 0 1 1 1 1 0 0
*
* 47 ... 16
* imm[32:0]
*
* rd: b000 for SAR, b001 CCR, b010 DAR
*/
*DmaProg= 0xBC;
*(DmaProg+ 1) = Rd & 0x7;
XDmaPs_Memcpy4(DmaProg+ 2, (char *)&Imm);
return 6;
}
那么,看下面一段汇编代码,代码完成160K数据搬运,数据源和目的都是DDR:
DMAMOV SAR #SrcAddr
DMAMOV DAR #DstAddr
DMAMOV CCR #CCRn
DMALP lc1 outerloop
DMALP lc0 innerloop
DMALD
DMAST
DMALPEND lc0
DMALD
DMAST
DMALPEND lc1
DMASEV
DMAEND
DMAC提供了两个计数器lc0和lc1,都是8bit的,因此每层循环的次数都不能超过256次。指令执行到DMASEV时控制器发出完成中断,执行过程中遇到任何错误或异常均发出Abrot中断。
在本例中SrcAddr=0x10000000,DstAddr = 0x11000000,数据长度为160KB,CCRn的参数如下:
CCRn.EndianSwapSize = 0x00;
CCRn.DstCacheCtrl =0x00;
CCRn.DstProtCtrl = 0x00;
CCRn.DstBurstLen = 0x07;
CCRn.DstBurstSize = 0x03;
CCRn.DstInc =0x01;
CCRn.SrcCacheCtrl = 0x00;
CCRn.SrcProtCtrl = 0x00;
CCRn.SrcBurstLen = 0x07;
CCRn.SrcBurstSize = 0x03;
CCRn.SrcInc =0x01;
那么通过库函数XDmaPs_BuildDmaProg生成的可执行机器码就是:
[Addr]Code
[0] BC
[1] 0
[2] 0
[3] 0
[4] 0
[5] 10
[6] BC
[7] 2
[8] 0
[9] 0
[A] 0
[B] 11
[C] BC
[D] 1
[E] 77
[F] C0
[10] 1D
[11] 0
[12] 22
[13] 9
[14] 20
[15] FF
[16] 4
[17] 8
[18] 38
[19] 2
[1A] 3C
[1B] 6
[1C] 34
[1D] 0
[1E] 0
代码正常执行完成后产生SEV中断,需在中断服务程序中清除当前的中断状态。
在DMA控制器的诸多寄存器中,绝大部分仅是反映DMA引擎的当前执行情况,用于实施跟踪执行状态。至关重要的寄存器DBGSTATUS、 DBGCMD、DBGINST0、DBGINST1用于控制DMA的开始、中断和终止。也就是DMA指令中的DMAGO、DMASEV和DMAKILL, 由于APB接口和DMA引擎间的异步关系,指令执行存在一定的延时,在下发下条指令前一定要通过读取DBGSTATUS的值轮询上次指令是否执行完毕。
遇到DMA Abrot中断事件,都必须下发DMAKILL指令终止当前线程。
ARM PL330 DMA控制器乍看来似乎难以理解,实际上它是把DMAC当成一个协处理来看待,有自己的指令执行引擎。用户组织好执行机器码后存到内存,用户通过APB接 口发出DMAGO指令告诉DMAC的指令执行引擎执行代码的首地址并启动DMA指令引擎直到指令执行到DMAEND停止。
备注:比如将SDK安装到了D:\Vivado\SDK目录下,版本为2015.2,那么DMAC参考示例代码就存放在“D:\Vivado\SDK\2015.2\data\embeddedsw\
XilinxProcessorIPLib\drivers\dmaps_v2_1\examples”路径下。
来源:http://blog.csdn.net/haoxingheng/article/details/47131373
本视频基于Xilinx公司的Artix-7FPGA器件以及各种丰富的入门和进阶外设,提供了一些典型的工程实例,帮助读者从FPGA基础知识、逻辑设计概念
本课程为“从零开始大战FPGA”系列课程的基础篇。课程通俗易懂、逻辑性强、示例丰富,课程中尤其强调在设计过程中对“时序”和“逻辑”的把控,以及硬件描述语言与硬件电路相对应的“
课程中首先会给大家讲解在企业中一般数字电路从算法到流片这整个过程中会涉及到哪些流程,都分别使用什么工具,以及其中每个流程都分别做了
@2003-2020 中国电子顶级开发网