Cyclone V板FPGA通过H2F AXI总线向HPS传输数据的实现问询
Cyclone V H2F AXI 实现FPGA到HPS的ASCII数据传输步骤
一、先验证FIFO与H2F AXI总线的连接正确性
这是核心前提,避免后续无效调试:
- 匹配AXI接口类型:Cyclone V的H2F AXI支持AXI Lite(地址映射型)和AXI Stream(流数据型),连续ASCII传输优先选AXI Stream。
- 关键信号核对:
- 若用AXI Lite:确保FIFO的AXI slave信号(AWVALID/WVALID/BREADY/ARVALID/RREADY等)与H2F的AXI Lite master接口正确对接,地址、数据位宽匹配(你的场景是32位)。
- 若用AXI Stream:FIFO的TREADY/TVALID/TDATA信号要和H2F的AXI Stream slave接口一一对应,TDATA设为32位。
- FPGA端仿真验证:给FIFO写入固定ASCII测试数据,模拟HPS的AXI读操作,确认数据能正确读出,验证接口逻辑合法性。
二、设备树配置(让Linux识别自定义外设)
你已烧录设备树,需确认是否添加了AXI外设节点:
- 打开设备树源文件(如
soc_cv_av.dtsi或自定义.dts),添加对应节点:- AXI Lite slave示例:
fpga_ascii_fifo: fpga-ascii-fifo@0xff200000 { compatible = "altr,axi-lite-fifo,1.0"; reg = <0xff200000 0x1000>; // 地址范围需与Qsys中H2F Bridge的外设分配地址一致 status = "okay"; };
- AXI Lite slave示例:
- 重新编译设备树:用
dtc工具将源文件编译为.dtb,替换SD卡中的设备树文件后重启开发板。
三、HPS端程序编写(Linux用户态)
无需编写内核驱动,直接用内存映射或字符设备访问:
方案1:AXI Lite + 内存映射
适用于地址型外设,通过/dev/mem映射AXI地址空间:
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/mman.h> #include <unistd.h> #include <stdint.h> #define FIFO_BASE 0xff200000 // 与设备树reg字段一致 #define FIFO_MAP_SIZE 0x1000 int main() { int fd = open("/dev/mem", O_RDWR | O_SYNC); if (fd == -1) { perror("/dev/mem open failed"); return -1; } void *fifo_ptr = mmap(NULL, FIFO_MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, FIFO_BASE); if (fifo_ptr == MAP_FAILED) { perror("mmap failed"); close(fd); return -1; } // 循环读取FIFO中的32位ASCII数据(拆分为4个8位字符) while (1) { uint32_t raw_data = *(volatile uint32_t*)fifo_ptr; char c1 = (raw_data >> 24) & 0xff; char c2 = (raw_data >> 16) & 0xff; char c3 = (raw_data >> 8) & 0xff; char c4 = raw_data & 0xff; printf("Read ASCII: %c%c%c%c\n", c1, c2, c3, c4); usleep(100000); // 根据FPGA数据生成速度调整延时 } munmap(fifo_ptr, FIFO_MAP_SIZE); close(fd); return 0; }
- 编译:用交叉编译器(如
arm-linux-gnueabihf-gcc)编译,通过SSH或SD卡传到开发板运行。
方案2:AXI Stream + 字符设备
若用AXI Stream接口,Qsys中添加AXI Stream to FIFO和AXI Stream Bridge for HPS,Linux会生成/dev/axistream*设备文件,直接读取:
#include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <stdint.h> int main() { int fd = open("/dev/axistream0", O_RDONLY); if (fd == -1) { perror("axistream device open failed"); return -1; } uint32_t buf; while (1) { read(fd, &buf, sizeof(buf)); char c1 = (buf >> 24) & 0xff; char c2 = (buf >> 16) & 0xff; char c3 = (buf >> 8) & 0xff; char c4 = buf & 0xff; printf("Received: %c%c%c%c\n", c1, c2, c3, c4); } close(fd); return 0; }
四、调试验证步骤
- 确认FPGA程序加载:查看
/sys/class/fpga_manager/fpga0/state,显示operating即为加载成功。 - 先通过
devmem命令快速测试:比如devmem 0xff200000 32,若能读出预期ASCII数据,说明地址映射和FPGA逻辑正常。 - 若读不到数据,排查方向:
- FPGA端AXI接口是否正确响应HPS读请求;
- 设备树地址与Qsys配置是否完全一致;
- FIFO是否有数据输出(可在FPGA端加LED指示FIFO非空状态)。
内容的提问来源于stack exchange,提问作者2258432
相关产品推荐
相关产品推荐

