ZYNQ7000 FPGA运行Verilog BoolLogger时偶发无效数据问题
ZYNQ 7000布尔数据记录器偶发无效日志问题
项目基本情况
- 开发平台:ZYNQ 7000 SoC
- 实现功能:布尔数据记录器,从GPIO接口采集布尔输入信号,记录输入电平值以及相邻两次电平翻转的时间间隔
- 单条日志格式:采用32位寄存器存储,最高位(MSB)存储当前布尔电平值,低31位(30:0位)为无符号整数,记录相邻两次电平翻转的间隔计数值
- 预期工作逻辑:

现有实现方案
为方便处理器读取记录的日志数据,使用Vivado生成的AXI从机接口,将记录器逻辑内联到AXI模块中,核心代码如下:
module BoolLogger_AXI #( parameter BufferDepth = 512 )( input wire data_in, // 布尔输入信号 input wire S_AXI_ACLK, // 逻辑时钟 input wire S_AXI_ARESETN, // 低有效复位信号 // 其余AXI接口信号 ); wire slv_reg_wren; // AXI接口写使能信号 reg[31:0] buff[0:BufferDepth-1]; reg[15:0] idx; reg[31:0] count; reg last_data; always @(posedge S_AXI_ACLK) begin if((!S_AXI_ARESETN) || slv_reg_wren) begin idx <= 0; count <= 1; last_data <= data_in; end else begin if(last_data!=data_in) begin // 仅当输入发生翻转时新增日志条目 last_data <= data_in; if(idx < BufferDepth) begin // 缓冲区写满后停止记录 buff[idx] <= count | (data_in << 31); idx <= idx + 1; end count <= 1; end else begin count <= count + 1; end end end // 其余AXI接口逻辑 endmodule
- 工程块设计:

- 地址映射:总容量为512*32bit的日志缓冲区被映射到
0x43c20000至0x43c20800的地址区间 - 运行参数:FPGA逻辑时钟为10MHz,输入信号频率为10Hz,正常情况下相邻翻转的间隔计数值典型值为
10e6/10/2 = 0x7A120,除无效数据外,其余日志的计数值均接近该数值。
故障现象与已排查内容
- 仿真验证结果:模块在仿真环境下运行完全符合预期
- 硬件实际运行故障:烧录到FPGA运行时随机偶现无效日志数据,存在连续两条日志的MSB位完全相同的情况,意味着输入电平未发生翻转时,逻辑错误地新增了日志条目
- 无效日志样例:

- 已完成排查:
- 直接通过代码
*(u32*)(0x43c20000+4*idx)读取对应物理地址,仍然可以读到无效数据,排除上层软件读取逻辑错误 - 通过ILA(集成逻辑分析仪)观测
idx信号,确认读取数据时idx值为512,此时日志记录已经完成,排除读取过程中日志仍在写入的并发问题
- 直接通过代码
- 核心疑问:代码逻辑层面仅在电平翻转时才会写入新日志,理论上不应出现这类无效数据,该故障可能是什么原因导致的?是否属于时序违例问题?
- 完整工程代码仓库:BoolLogger项目代码
内容的提问来源于stack exchange,提问作者Jackoo
相关产品推荐
相关产品推荐

