如何从Altera Cyclone V SoC直接写入FPGA外设?
针对Cyclone V SoC HPS端直接写入FPGA外设的实现方案
核心逻辑和NIOS II的IOWR一致,本质是将访问FPGA外设的地址段配置为非缓存、强序/设备内存类型,跳过缓存同步步骤直接将数据送到AXI总线发给FPGA外设,具体实现方式如下:
方法1:使用hwlib自带的非缓存写入接口
hwlib本身已经提供直接写入的专用函数,很多开发者容易忽略:
- 直接调用
alt_write_direct_word即可,不需要额外做内存配置,传入FPGA外设对应的HPS物理地址和要写入的值即可,底层默认走非缓存地址段访问。
注意:需要确认传入的物理地址和Platform Designer中给FPGA外设分配的HPS地址映射范围一致,不要传入虚拟地址。
方法2:手动配置内存属性封装自定义读写函数
如果需要适配自己的业务逻辑封装专属接口,按以下步骤操作:
- 首先确认FPGA外设的地址段在Platform Designer中分配的HPS物理地址范围,Cyclone V SoC默认给FPGA外设预留的地址段通常为
0xC0000000 ~ 0xFFFFFFFF。 - 如果运行在Linux用户态,调用
mmap映射该物理地址段时,权限设置为PROT_WRITE | PROT_READ,flags参数添加MAP_SHARED,映射完成后调用mprotect将对应虚拟地址段的内存属性设置为非缓存设备类型,ARM平台对应配置PROT_NOCACHE相关属性宏即可(宏定义以你使用的交叉编译器头文件为准)。 - 如果是裸机开发,直接在MMU配置表中将对应FPGA外设物理地址段的属性设置为强序非缓存内存,不需要做地址映射,直接访问物理地址即可。
- 封装自定义读写函数,必须加
volatile关键字防止编译器优化掉读写操作,示例代码如下:
// base为映射后的虚拟地址基址(裸机环境下直接填物理地址) #define MY_IOWR(base, offset, data) (*(volatile unsigned int *)((base) + (offset)) = (data)) #define MY_IORD(base, offset) (*(volatile unsigned int *)((base) + (offset)))
注意事项
- 仅对地址加
volatile关键字无法跳过缓存,必须先完成内存属性的非缓存配置,否则写入操作还是会先到缓存,不会实时同步到FPGA外设。 - 非缓存配置完成后不需要手动调用缓存同步接口,写入操作会直接送到FPGA侧,和NIOS II的
IOWR效果完全一致。
内容的提问来源于stack exchange,提问作者LowK
相关产品推荐
相关产品推荐

