第三章 基于规则的故障诊断:专家系统构建、规则库设计、推理机实现、规则冲突解决

各位同学,咱们今天聊点实在的。

基于规则的故障诊断,说白了就是让芯片自己学会“看病”。你想想看,一个SoC里几百个模块,出了问题靠人工翻波形,那得翻到猴年马月去?我早年做验证的时候,就吃过这个亏。有一次一个DMA的地址对齐错误,我愣是盯了三天波形才找到根因。后来我就琢磨,能不能把这些排查经验固化下来,让工具替我们干这活?

嗯,这就是专家系统的由来。

3.1 专家系统的基本架构

一个典型的专家系统,核心就三块:知识库、推理机、工作存储器。我个人习惯把知识库比作“老中医的方子”,推理机就是“抓药的过程”,工作存储器则是“当前的病人状态”。

在SoC故障诊断场景下,架构是这样的:

  • 知识库:存放所有故障模式与处理规则。比如“如果AXI总线超时,且重试次数超过3次,则判定为从设备无响应”。
  • 推理机:根据当前观测到的信号状态,匹配知识库中的规则,得出结论。
  • 工作存储器:存放当前SoC的运行状态、寄存器值、中断标志等动态数据。

我在项目中遇到过一种情况:知识库建得特别大,但推理机跑起来慢得像蜗牛。后来发现是规则索引没做好。所以这里要提醒大家,知识库的组织方式直接影响诊断效率。

3.2 规则库设计:从经验到代码

规则库设计是整个系统的灵魂。你想想看,一个资深工程师脑子里有多少条“潜规则”?比如“当FIFO的almost_full信号拉高后,如果写使能还在持续,大概率是背压机制失效了”。这些经验,得一条条写成机器能理解的规则。

我常用的规则表示方法是产生式规则:

IF (条件1 AND 条件2) OR 条件3 THEN 结论 (置信度)

举个例子,一个实际的SoC总线故障规则:

RULE bus_timeout_001:
  IF (axi_awready == 0) 
     AND (axi_awvalid == 1) 
     AND (timeout_counter > 1000)
  THEN 
     slave_no_response = TRUE (置信度: 0.95)
     action: 触发总线错误中断,记录从设备地址

这里要注意置信度的设置。我刚开始做的时候,所有规则都设成1.0,结果发现有些误报。后来改成0.95、0.8这样的分级,诊断准确率反而上去了。

我的小技巧:规则库设计时,建议按模块分类。比如DMA相关的规则放在一组,中断控制器相关的放在另一组。这样维护起来方便,也便于后续的规则冲突排查。

3.3 推理机实现:正向与反向

推理机有两种主流方式:正向推理和反向推理。我个人更偏爱正向推理,因为SoC故障诊断通常是“看到现象找原因”,正好匹配正向推理的思路。

正向推理的伪代码大致是这样的:

while (有未匹配的规则) {
  从工作存储器获取当前事实集F;
  遍历规则库,找到所有条件能被F满足的规则R;
  if (R不为空) {
    选择一条规则执行(这里涉及冲突解决);
    将结论加入工作存储器;
    标记该规则为已使用;
  } else {
    退出循环,报告无法诊断;
  }
}

反向推理呢?适合那种“假设某个故障,然后验证”的场景。比如你怀疑是时钟域同步出了问题,那就反向去找有没有跨时钟域的路径没加同步器。

我记得有一次,一个同事用反向推理查一个DDR训练失败的问题。他先假设是ODT配置错误,然后反向推导出需要检查哪些寄存器。结果还真让他找到了——一个PHY的阻抗校准值写反了。

3.4 规则冲突解决:最头疼的部分

规则冲突,说白了就是多条规则同时满足条件,但结论互相矛盾。比如规则A说“复位后应该检查PLL锁定状态”,规则B说“复位后应该先检查时钟是否稳定”。两条都对,但执行顺序错了,诊断结果就乱了。

我常用的冲突解决策略有几种:

策略名称 做法 适用场景
优先级法 给每条规则分配优先级,高优先级的先执行 故障严重程度不同时
最近使用优先 最近被触发过的规则优先 时序相关的故障
特异性优先 条件更具体的规则优先于条件宽泛的 通用规则与特殊规则并存时
数据新鲜度 基于最新观测数据的规则优先 实时诊断场景
避坑指南:我曾经在一个项目中,因为没处理好规则冲突,导致同一个故障被诊断出三个不同的根因。后来我加了一个“规则依赖图”,把规则之间的先后关系画出来,冲突就少多了。记住,规则冲突不是bug,是设计时就要考虑的问题。

3.5 实战案例:一个总线死锁的诊断

说个我亲身经历的例子。某次芯片回片测试,发现系统跑着跑着就卡死了。波形上看,AXI总线上的所有master都在等ready信号,但没有任何一个slave响应。

我建了这么几条规则:

RULE deadlock_001:
  IF (所有master的awvalid == 1) 
     AND (所有slave的awready == 0)
  THEN 总线死锁 (置信度: 0.9)

RULE deadlock_002:
  IF (总线死锁) 
     AND (中断控制器状态寄存器 == 0xFF)
  THEN 中断风暴导致死锁 (置信度: 0.85)

RULE deadlock_003:
  IF (总线死锁) 
     AND (某个slave的bvalid持续为高)
  THEN 写响应未处理导致死锁 (置信度: 0.95)

推理机跑起来后,先匹配到deadlock_001,确认了死锁状态。然后继续匹配,发现deadlock_003的条件也满足——某个DMA的写响应通道卡住了。最终定位到是DMA的中断服务程序里少了一个写响应清空操作。

你看,如果没有这套规则系统,光靠人工翻波形,这个bug至少要多花两天时间。

3.6 规则库的维护与迭代

规则库不是建完就完事的。我见过太多团队,一开始建了上百条规则,用着用着就没人维护了。新发现的故障模式加不进去,旧的规则又过时了。

我的建议是:

  • 每个新bug修复后,评估是否能抽象成一条规则
  • 定期清理置信度低于0.5的规则
  • 规则库版本要和芯片版本对应,不同工艺的芯片规则可能不同

嗯,说到这我想起来,有一次一个实习生把28nm工艺的规则直接套到7nm的芯片上,结果误报率飙升到40%。所以啊,规则库也是要“与时俱进”的。

核心要点回顾

  • 专家系统三要素:知识库、推理机、工作存储器
  • 规则设计要分模块、设置信度
  • 正向推理适合“现象找原因”,反向推理适合“假设验证”
  • 冲突解决用优先级、特异性、数据新鲜度等策略
  • 规则库需要持续维护,与芯片版本同步

下一章咱们聊聊基于模型的故障诊断,那又是另一套思路了。不过先把今天这些消化掉,规则系统玩明白了,后面就好办了。