本文讲解host如何通过AXI4接口读写DDR(或者BRAM)和通过AXI-LITE接口读写控制信号,BD图如下图所示: 可以看到M_AXI通过interconnecte IP连接到DDR4,M_AXI_LITE通过interconnecte IP连接到bram_ctrl,将BRAM_PORTA引出,在FPGA侧进行控制信号的读写。 开发环境:FPGA:赛灵思KU115 HOST:ubuntu 18.04 Driver:XDMA,具体安装方法参考: [color=inherit !important]仰望星空:HiFive Unmatched开发板安装XDMA(linux安装XDMA)13 赞同 · 7 评论文章
HOST主要代码:# include "stdio.h"#include <assert.h>#include <fcntl.h>#include <getopt.h>#include <stdint.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <time.h>#include <pthread.h>#include <semaphore.h>#include <stdarg.h>#include <syslog.h>#include <sys/mman.h>#include <sys/stat.h>#include <sys/time.h>#include <sys/types.h>#include <sys/sysinfo.h>#include <unistd.h>#include <dirent.h>#include <string.h>/* ltoh: little to host *//* htol: little to host */#if __BYTE_ORDER == __LITTLE_ENDIAN# define ltohl(x) (x)# define ltohs(x) (x)# define htoll(x) (x)# define htols(x) (x)#elif __BYTE_ORDER == __BIG_ENDIAN# define ltohl(x) __bswap_32(x)# define ltohs(x) __bswap_16(x)# define htoll(x) __bswap_32(x)# define htols(x) __bswap_16(x)#endif#define MAP_SIZE (1024*1024UL)#define MAP_MASK (MAP_SIZE - 1)#define FPGA_AXI_START_ADDR (0)void *control_base;int control_fd;int c2h_dma_fd;int h2c_dma_fd;static unsigned int h2c_fpga_ddr_addr;static unsigned int c2h_fpga_ddr_addr;static int open_control(char *filename){ int fd; fd = open(filename, O_RDWR | O_SYNC); if(fd == -1) { printf("open control error\n"); return -1; } return fd;}static void *mmap_control(int fd,long mapsize){ void *vir_addr; vir_addr = mmap(0, mapsize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); return vir_addr;}void write_control(int offset,uint32_t val){ uint32_t writeval = htoll(val); *((uint32_t *)(control_base+offset)) = writeval;}uint32_t read_control(int offset){ uint32_t read_result = *((uint32_t *)(control_base+offset)); read_result = ltohl(read_result); return read_result;}void put_data_to_fpga_ddr(unsigned int fpga_ddr_addr,short int *buffer,unsigned int len){ lseek(h2c_dma_fd,fpga_ddr_addr,SEEK_SET); write(h2c_dma_fd,buffer,len*2);}void get_data_from_fpga_ddr(unsigned int fpga_ddr_addr,short int *buffer,unsigned int len){ lseek(c2h_dma_fd,fpga_ddr_addr,SEEK_SET); read(c2h_dma_fd,buffer,len*2);}int pcie_init(){ c2h_dma_fd = open("/dev/xdma0_c2h_0",O_RDWR | O_NONBLOCK); if(c2h_dma_fd < 0) return -1; h2c_dma_fd = open("/dev/xdma0_h2c_0",O_RDWR ); if(h2c_dma_fd < 0) return -2; control_fd = open_control("/dev/xdma0_user"); if(control_fd < 0) return -5; control_base = mmap_control(control_fd,MAP_SIZE); return 1;}void pcie_deinit(){ close(c2h_dma_fd); close(h2c_dma_fd); close(control_fd);}unsigned int len = 4096;int read_fftdata(short int *buf1){ FILE *fpread=fopen("fft_linux.txt","r"); if(fpread == NULL) return 1; for(int i=0;i<len;i++) fscanf(fpread, "%hd", &buf1); return 0;}
在主函数中,通过调用pcie初始化,写控制,读控制,写数据、读数据。 具体设计方案可加wx:Jx_G_zhihu获取
|