1. 问题现象与背景分析
最近在调试ZYNQ平台的软硬件协同项目时,遇到了一个诡异的现象:当PS端通过AXI总线向BRAM写入数据后,PL端读取时连续4个地址返回了完全相同的数据。这个问题直接影响了我们的数据交互可靠性,经过一周的排查和验证,终于找到了根本原因和解决方案。
ZYNQ芯片的PS与PL协同工作中,BRAM作为共享存储介质是常见的设计选择。在标准设计中,我们通常会:
- 在Vivado中配置一个双端口BRAM IP核
- 一个端口连接AXI BRAM Controller供PS访问
- 另一个端口直接引出到PL逻辑
理论上,这种设计应该能实现PS和PL的无缝数据交互。但实际测试中发现,当PS写入一组递增测试数据(如0x11,0x22,0x33,0x44)后,PL端读取时却得到了0x11,0x11,0x11,0x11这样的重复数据。
2. 根本原因深度解析
2.1 总线位宽不匹配导致的地址对齐问题
经过信号抓取和波形分析,发现问题出在AXI总线与本地总线(Local Bus)的位宽转换上。在我们的案例中:
- PS端AXI控制器配置为32位数据总线
- PL端的BRAM接口却是8位数据总线
- Vivado自动插入的位宽转换逻辑没有正确处理地址递增
关键问题在于:当32位AXI总线向8位BRAM写入时,一个AXI写事务实际上会占用4个BRAM物理地址。但地址生成逻辑没有正确左移2位,导致所有写入都集中在BRAM的同一个物理存储位置。
2.2 BRAM的字节使能信号异常
进一步分析发现,AXI的STRB(Strobe)信号在转换过程中出现了异常:
- 正常情况:每个STRB位应对应一个字节通道
- 实际现象:所有STRB位始终保持全高
- 结果:每次32位写入都会重复更新同一组8位存储单元
这解释了为什么PL端读取时,相邻地址会返回相同数据——它们实际上指向的是BRAM中的同一个物理存储单元。
3. 解决方案与实现步骤
3.1 硬件设计修正方案
方案一:统一总线位宽(推荐)
-
在Vivado Block Design中:
- 将BRAM配置为32位数据宽度
- 确保AXI BRAM Controller数据宽度匹配
- 更新PL端接口定义
-
关键参数设置:
