使用axi_datamover完成ZYNQ片内PS与PL间的数据传输
2016-03-14 14:46
267 查看
分享下PS与PL之间数据传输比较另类的实现方式,实现目标是:
1、传输时数据不能滞留在一端,无论是1个字节还是1K字节都能立即发送;
2、PL端接口为FIFO接口;
PS到PL的数据传输流程:
PS到PL的数据传输相对简单,使用vivado自带的axi_datamover即可完成,详细如下:
A、向PL端查询剩余数据存储长度(以byte为单位);
B、通过写寄存器设置PL端DMA数据传输开始地址;
C、通过写寄存器设置PL端DMA数据传输长度(以byte为单位);
D、通过写寄存器启动PL端DMA传输;
E、通过读寄存器查询PL端DMA是否完成数据传输;
PS(ARM)端驱动代码如下:
#define WRITE_SPACE_REG 0x84000004
#define ps2pl_SA 0x84000008
#define ps2pl_LENGTH 0x8400000C
#define ps2pl_START 0x84000010
#define ps2pl_FINISHED 0x84000014
data_space = Xil_In32(WRITE_SPACE_REG);
void init_axi_dma_simple_write(u32 num)
{
Xil_Out32(ps2pl_SA,(unsigned int )recvram);
Xil_Out32(ps2pl_LENGTH,(0x80000000+num));
Xil_Out32(ps2pl_START,0x00000001);
while(!(Xil_In32(ps2pl_FINISHED)&0x00000001));
}
PL到PS的数据传输流程:
PL到PS的数据传输相对复杂点,vivado自带axi_datamover测试发现有时不太正常,所以按照vivado自带axi_datamover接口协议重新写了模块,详细如下:
A、通过读寄存器查询待传输数据长度(以byte为单位);
B、通过写寄存器设置PL端DMA数据传输开始地址;
C、通过写寄存器设置数据传输长度(以byte为单位);
D、通过写寄存器启动数据传输;
E、通过读寄存器查询PL端DMA是否完成数据传输;
注:数据传输长度有数值限制,假如待传输数据长度为8byte的整数倍,则每次的数据传输长度也必须为8byte的整数倍。假如待传输数据长度不是8byte的整数倍,以15byte为例,只能以下面两种方式读取:1、第一次读取8byte,第二次读取7byte;2、一次读取15byte。为了简化这种限制,可以使每次的待传输数据长度小于PS端的缓存,这样可以一次读取所有待传输的数据,也就是第二种读取方式。
PS(ARM)端代码如下:
#define READ_NUM_REG 0x84000044
#define pl2ps_DA 0x84000048
#define pl2ps_LENGTH 0x8400004C
#define pl2ps_START 0x84000050
#define pl2ps_FINISHED 0x84000054
data_return = Xil_In32(READ_NUM_REG);
void init_axi_dma_simple_read(u32 num)
{
Xil_Out32(pl2ps_DA,(unsigned int )recvram);
Xil_Out32(pl2ps_LENGTH,(0x80000000+num));
Xil_Out32(pl2ps_START,0x00000001);
while(!(Xil_In32(pl2ps_FINISHED)&0x00000001));
}
附件为在vivado中打包好的用于pl2ps传输的ip。
1、传输时数据不能滞留在一端,无论是1个字节还是1K字节都能立即发送;
2、PL端接口为FIFO接口;
PS到PL的数据传输流程:
PS到PL的数据传输相对简单,使用vivado自带的axi_datamover即可完成,详细如下:
A、向PL端查询剩余数据存储长度(以byte为单位);
B、通过写寄存器设置PL端DMA数据传输开始地址;
C、通过写寄存器设置PL端DMA数据传输长度(以byte为单位);
D、通过写寄存器启动PL端DMA传输;
E、通过读寄存器查询PL端DMA是否完成数据传输;
PS(ARM)端驱动代码如下:
#define WRITE_SPACE_REG 0x84000004
#define ps2pl_SA 0x84000008
#define ps2pl_LENGTH 0x8400000C
#define ps2pl_START 0x84000010
#define ps2pl_FINISHED 0x84000014
data_space = Xil_In32(WRITE_SPACE_REG);
void init_axi_dma_simple_write(u32 num)
{
Xil_Out32(ps2pl_SA,(unsigned int )recvram);
Xil_Out32(ps2pl_LENGTH,(0x80000000+num));
Xil_Out32(ps2pl_START,0x00000001);
while(!(Xil_In32(ps2pl_FINISHED)&0x00000001));
}
PL到PS的数据传输流程:
PL到PS的数据传输相对复杂点,vivado自带axi_datamover测试发现有时不太正常,所以按照vivado自带axi_datamover接口协议重新写了模块,详细如下:
A、通过读寄存器查询待传输数据长度(以byte为单位);
B、通过写寄存器设置PL端DMA数据传输开始地址;
C、通过写寄存器设置数据传输长度(以byte为单位);
D、通过写寄存器启动数据传输;
E、通过读寄存器查询PL端DMA是否完成数据传输;
注:数据传输长度有数值限制,假如待传输数据长度为8byte的整数倍,则每次的数据传输长度也必须为8byte的整数倍。假如待传输数据长度不是8byte的整数倍,以15byte为例,只能以下面两种方式读取:1、第一次读取8byte,第二次读取7byte;2、一次读取15byte。为了简化这种限制,可以使每次的待传输数据长度小于PS端的缓存,这样可以一次读取所有待传输的数据,也就是第二种读取方式。
PS(ARM)端代码如下:
#define READ_NUM_REG 0x84000044
#define pl2ps_DA 0x84000048
#define pl2ps_LENGTH 0x8400004C
#define pl2ps_START 0x84000050
#define pl2ps_FINISHED 0x84000054
data_return = Xil_In32(READ_NUM_REG);
void init_axi_dma_simple_read(u32 num)
{
Xil_Out32(pl2ps_DA,(unsigned int )recvram);
Xil_Out32(pl2ps_LENGTH,(0x80000000+num));
Xil_Out32(pl2ps_START,0x00000001);
while(!(Xil_In32(pl2ps_FINISHED)&0x00000001));
}
附件为在vivado中打包好的用于pl2ps传输的ip。
相关文章推荐
- ubuntu如何访问windows共享文件夹
- VMware Workstation 系统备份-虚拟机克隆方法
- AWK分割的用法
- 20来行的Python拼写检查器
- 什么是浅复制与深复制
- 第53课:Hive 第一课:Hive的价值、Hive的架构设计简介
- iOS 基础知识大全之网络篇(可供零基础学习)
- 简单实用Python程序
- [转] What is the point of redux when using react?
- WEKA使用教程(经典教程转载)
- mac如何使用本地数据库
- TCP的三次握手,四次断开
- strStr
- TortoiseSVN文件夹及文件图标不显示解决方法
- 前端展示时间戳问题
- 很像动态规划的贪心
- Latex.exe 已停止工作 underfull \hobx (badness 10000) has occurred while \output is activeBuffer size exc
- 告诉你Hadoop是什么
- Caffe + Ubuntu 14.04 64bit + CUDA 6.5 配置说明
- React + ES6 实践中遇到的问题