事故现场我发现了,这个系列最难的一件事就是起标题了,要巧妙地在吸引人和标题党之间找到一个合适的名字也是非常的艰难啊。这个名字就起的非常的难以理解,但是啊一会你细品其实非常的准确。
事情是个什么事情呢?之前有这样一个功能,要检测一个接口上持续没有操作的拍数,这个接口是一个握手接口所以定的方案就是只要发生握手就将一个计数器清零,不握手就一直累加,用这个计数器来反馈接口上“闲置”了多少拍。
为什么要做这个功能呢?这个功能作为动态复位流程中的一步,大概作用就是在动态复位请求下发后,该模块需要响应请求,停止本身的对外访问通路将寄存器间接访问ram的通路接进来送出去。换句话说就是寄存器间接访问通路和模块访问通路共用了一组接口,然后模块本身停止自身的访问来给寄存器间接访问让路。本身呢,模块应该通过状态上报来告知软件通路让出来了,但是这个模块太复杂了不是很好做这个功能,所以就想了折中的办法通过接口上空拍的持续时间来判定通路已经闲置了,这个计数器本身设置的也很大几乎达到ms级了。
aqpnxfyxghe64030360459.jpg
功能就是这么个功能,RTL也是按照这个feature来实现的,测试也一直非常的正常,直到有一天计数器显示已经通路已经空置几万拍了,但是通过寄存器进行间接访问时候发现直接挂死了。
事故分析带着波形复现bug,通过波形确认发现了问题:确实几万拍没握手了,但原因是总线的ready一直为0导致不握手!所以说这个问题本质是方案直接做错了,只考虑了不握手就是空了,没有想到不握手也可能是下游不接收所以一直不能握手。
在上一篇文章中我也提过,“对于总线超时不能只检查发出去的req收到的rsp是不是超时了,还要检测req始终没有办法发出去的场景,比如说握手接口,如果总线挂死了axi_awready始终无法为1接收请求”这个点其实也是根据这个bug推出来的。
事故解决对于这种情况,判断接口是否空闲了,应该看valid为低持续的时间,修改后验证通过。 |