赞
踩
上一节zynq linux调用HLS IP核
中讲了如何通过UIO在zynq linux开发中调用HLS IP核,但是那个例子中只涉及到了AXI Lite接口,没有内存中虚拟地址和物理地址的问题,本节讲述如何在linux上解决该问题。
我们知道,在PL端访问ARM的DDR时,采用的是物理地址,然而在Linux上的应用程序,一般采用虚拟地址,因此zynq上linux的开发就必须解决这一问题。
本次实验,在HLS中实现了一个采用m_axi接口的向量加法IP核:
该m_axi接口与AXI HP口相连,直接读取PS端的DDR,具体功能为
读取100个a数组元素,读取100个b数组元素,然后对应元素相加,得到的100个和再写回DDR中指定的位置。
整个开发过程与上一节类似,唯一的不同就是最后的应用程序,代码如下:
/* * Copyright (c) 2012 Xilinx, Inc. All rights reserved. * * Xilinx, Inc. * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE. * */ #include<stdio.h> #include<unistd.h> #include<sys/mman.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include"xadder.h" #define A_BASE_ADDR 0x05000000 #define B_BASE_ADDR 0x06000000 #define C_BASE_ADDR 0X07000000 #define SIZE 4096 int main() { XAdder add_inst; int i; int devmem; int *a_addr; int *b_addr; int *c_addr; devmem = open("/dev/mem", O_RDWR | O_SYNC); if(devmem==-1) printf("open /dev/mem failed\n"); a_addr=(int*)mmap(0,SIZE*sizeof(int),PROT_READ|PROT_WRITE,MAP_SHARED,devmem,A_BASE_ADDR); if(a_addr == MAP_FAILED) printf("a_addr map failed\n"); b_addr=(int*)mmap(0,SIZE*sizeof(int),PROT_READ|PROT_WRITE,MAP_SHARED,devmem,B_BASE_ADDR); if(b_addr == MAP_FAILED) printf("b_addr map failed\n"); c_addr=(int*)mmap(0,SIZE*sizeof(int),PROT_READ|PROT_WRITE,MAP_SHARED,devmem,C_BASE_ADDR); if(c_addr == MAP_FAILED) printf("c_addr map failed\n"); for(i=0;i<100;i++) { *(a_addr+i)=2*i; *(b_addr+i)=100-i; *(c_addr+i)=0; } printf("test start\n"); if(XST_SUCCESS!=XAdder_Initialize(&add_inst,"adder")){ printf("adder init error\n"); return -1; } XAdder_Set_a_r(&add_inst,(u32)A_BASE_ADDR); XAdder_Set_b_r(&add_inst,(u32)B_BASE_ADDR); XAdder_Set_c_r(&add_inst,(u32)C_BASE_ADDR); XAdder_Start(&add_inst); while(!XAdder_IsDone(&add_inst)); XAdder_Release(&add_inst); printf("PL compute finished\n"); for(i=0;i<100;i++) printf("%d+%d=%d\n",*(a_addr+i),*(b_addr+i),*(c_addr+i)); printf("end\n"); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。