
摘要
在安全关键型应用(如汽车领域)中,复杂且技术先进的集成电路(IC)的应用,促使人们引入新的解决方案,以确保达到所需的可靠性目标。其中一种解决方案是执行现场测试(即设备部署到任务环境后进行的测试),以检测电子电路在该生命周期阶段可能出现的故障。在这种情况下,一种日益得到广泛应用的方法基于软件测试库(STL),即由系统中包含的中央处理器(CPU)运行的适当代码,该代码能够检测 CPU 本身以及系统其他部分可能存在的永久性故障。为了评估软件测试库的有效性,需要进行故障仿真,从而计算所实现的故障覆盖率(例如,针对固定型故障)。本文阐述了为何软件测试库的故障仿真与传统测试激励的故障仿真(目前已有非常有效的算法和工具)相比是一个不同的问题,说明了为何软件测试库的故障仿真计算成本可能极高,并概述了一些降低计算成本的解决方案,这些方案可能需要在结果准确性和成本之间进行权衡。
一、引言
数十年来,电子系统的可靠性一直是人们关注的重点,这催生出了被广泛应用的技术解决方案,例如在航天、航空、军事、核电站控制等领域。近年来,汽车、生物医学或电信等新的应用领域极大地改变了需要考虑的场景(例如,更强调成本和产品上市时间等参数),并促使人们采用新的解决方案来开发高可靠性电子系统。然而,目标应用和所采用的半导体技术的持续发展,进一步加速了对新的技术手段的需求,这些技术手段需能够为这类电子系统的设计者提供支持。特别是在最近一段时间,由于电子系统在安全要求极高的应用中被大量采用,而这些应用对高性能的需求又催生了先进(但可靠性相对较低)的半导体技术和架构(如多核架构),该领域正经历着进一步的变革。因此,在过去十年中,所谓的功能安全标准(如针对汽车领域的 ISO 26262 标准,或更通用的针对安全关键型应用的 IEC 61508 标准)应运而生,以规范这些领域中电子设备的使用。此类标准规定了可靠性指标,而这些指标通常需要借助各种安全机制来实现。
根据 ISO 26262 标准(下文以此为参考标准,但在其他任何功能安全标准中也能找到类似概念),安全机制是系统的一部分,其目的是检测故障、控制系统失效,从而实现和 / 或维持安全状态。最常采用的安全机制如下:
· 逻辑内建自测试(LBIST)和存储器内建自测试(MBIST):它们主要用于现场测试,但也可用于制造末期测试;
· 端到端纠错码(ECC):用于保护存储器免受辐射引起的位翻转影响;
· 双核锁步(DCLS):两个处理器内核(分别为主内核和校验内核)配对使用,且始终接收完全相同的输入。它们的输出由一组比较器持续监控,这样一来,两个处理器中任意一个出现故障都能被立即检测到;
· 软件测试库(STL):一组基于软件的自测试(SBST)程序,通常用于现场测试。
对于可靠性要求最高的应用(根据 ISO 26262 标准,为 ASIL C 级和 ASIL D 级),端到端纠错码(ECC)和双核锁步(DCLS)是应对单点故障的实际标准解决方案。若没有合适的安全机制对这类故障进行防护,它们会直接导致严重的失效。然而,潜在故障(即不会直接导致失效,但与第二个故障同时出现时可能产生危害的故障)可能会使这些安全机制的功能失效。
基于内建自测试(BIST)的解决方案适用于上电自测试(POST),即设备上电时执行的现场测试。尽管这类解决方案效果显著,但它们的应用仅限于上电自测试,因为它们通常属于侵入性解决方案,会破坏系统状态,而且测试执行时间可能相当长。如果两次连续上电之间的时间间隔较长,这就可能成为一个问题。
出于这些原因,软件测试库(STL)成为在线测试的更优解决方案。在线测试是在用户应用程序(如操作系统)运行的同时执行的现场测试。进行在线测试时,测试阶段必须在相对较短的时间内完成(通常为几十毫秒甚至更短),同时侵入性应尽可能小。
构成软件测试库(STL)的程序,其设计思路相对简单,且数十年前就已为人所知:如果目标设备本身是处理器或包含处理器,我们可以强制处理器执行一段适当的代码,这段代码可能会读取一些输入数据,并以精心选择的方式对这些数据进行处理。通过观察生成的输出数据,就能检测出处理器模块(及其周边)可能存在的若干故障。采用适当的技术,可使获得的故障覆盖率达到足够高的水平。
该解决方案在现场测试中所具备的优势,促使用于安全关键型应用(如汽车领域)的设备制造商提供此类自测试程序库(有时被称为软件测试库,即 STL)。这些程序由半导体公司开发,该公司掌握着设备的所有结构信息,能够保证这些程序的执行可实现特定的故障覆盖率指标。自测试程序开发完成后,系统公司(在汽车领域通常相当于一级供应商)会将其集成到应用软件中,并在需要时(如定期调用或在应用程序空闲时调用)执行这些程序。通过这种方式,无需从半导体公司向系统公司传输任何敏感信息,就能达到所需的安全级别。
因此,软件测试库(STL)在实际工业应用中的范围十分广泛,既包括针对 ASIL A 级或 ASIL B 级应用(根据 ISO 26262 标准,为最低安全级别)的处理器内核在线测试,也包括针对 ASIL C 级或 ASIL D 级应用中双核锁步(DCLS)和端到端纠错码(ECC)等安全机制的潜在故障测试。对于双核锁步(DCLS)而言,软件测试库(STL)特别适用于避免校验内核和主内核中潜在故障的累积,因为故障累积可能会导致故障被掩盖而无法检测。如今,许多半导体公司和知识产权(IP)公司都广泛支持这种方法,如英飞凌、意法半导体、赛普拉斯、瑞萨电子、微芯科技、ARM等。
为特定设备开发软件测试库(STL)时,测试工程师必须面对两个主要问题:
1.如何高效地编写代码,最大限度地减少相关工作量(例如,遵循一定的指导原则,同时在可能的情况下,明确复用为同一设备的先前版本或类似设备开发的代码);
2.如何以高效且精确的方式计算这些程序所实现的故障覆盖率。
目前已有不少文献关注第一个问题,提出了为系统中不同模块编写自测试程序的技术以及优化这些程序的技术,而本文则聚焦于第二个问题。
计算特定测试序列所实现的故障覆盖率,通常需要借助故障仿真。在 20 世纪 90 年代,大量的研究工作推动了高效且高度优化的故障仿真算法的发展。此类算法已被广泛应用于商业工具(如故障仿真器和自动测试图形生成(ATPG)工具)中,如今这些工具在不同的商业环境中被用于为特定数字电路生成测试图形并进行故障分级。然而,这些工具和方法所针对的问题与本文所探讨的问题有很大不同。
实际上,传统的故障仿真方法旨在计算将一系列输入向量应用于通用时序电路时所实现的故障覆盖率(通常针对固定型故障),其前提是所有输出信号都能被持续观测。这种场景与制造末期测试的场景非常相似,但与现场测试的场景截然不同。
当考虑执行自测试程序所产生的效果时,我们关注的是处理器执行存储在存储器中的程序,并生成一些输出结果,这些输出结果同样存储在存储器中,且要在程序执行结束时进行观测。这种场景与传统故障仿真的场景有很大差异。例如,处理器的输入序列(如所执行的指令序列)常常会因故障影响而发生变化,比如当故障影响到实现指令取指机制的逻辑时,就经常会出现这种情况。此外,可观测性机制也完全不同:只有当自测试程序执行结束后,存储器中产生错误结果时,才能将故障标记为已检测到。
这种分析通常是功能安全验证流程的一部分。具体而言,在故障模式影响及诊断分析(FMEDA)过程中,软件测试库(STL)的故障分级变得至关重要。故障模式影响及诊断分析(FMEDA)是一种结构化方法,旨在确定故障模式、计算故障率、为已识别的故障设计适当的安全机制,并衡量这些安全机制的有效性。
为了更好地适应这种场景,市场上最近出现了所谓的功能故障仿真器(例如,新思科技(Synopsys)的 Z01X 工具,或楷登电子(Cadence)的 Incisive 平台中的新增功能)。这类工具能够在不同的抽象层级(即从寄存器传输级(RTL)到门级)对电路进行故障仿真,这在功能安全分析过程中是很常见的做法。
本文的目的有多个方面。首先,也是最重要的一点,我们要强调传统故障仿真方法无法有效计算自测试程序库所实现的故障覆盖率,同时阐明时序电路故障仿真(SC-FSIM)与自测试程序故障仿真(STP-FSIM)之间的差异。其次,我们将解释进行自测试程序故障仿真(STP-FSIM)需要极高计算成本的原因(并提供实验证据)。最后,我们将概述一些能够显著加快自测试程序故障仿真(STP-FSIM)速度的解决方案,这些方案有时可能会导致准确性出现少量损失。所有提出的解决方案都基于商用电子设计自动化(EDA)工具,因此该领域的专业人员可轻松采用。
据我们所知,与类似研究相比,本文首次尝试全面且带有解读地概述可用于有效执行软件测试库(STL)故障分级的技术。
本文其余部分的结构如下:第二节提供必要的术语和背景信息;第三节和第四节详细介绍可能的故障仿真技术;第五节呈现所获得的实验结果;最后,第六节对本文的研究结论进行讨论。
二、背景知识
在本节中,我们旨在明确传统故障仿真技术所面临的问题与计算软件测试库(STL)中自测试程序(用于现场测试)所实现的故障覆盖率问题之间的差异。传统故障仿真技术是过去为支持时序电路故障仿真(通常用于评估制造末期测试解决方案的有效性)而开发的。为了使解释更清晰,下文将假设采用常见的固定型故障模型,但下述概念也可扩展到其他多种故障模型(如跳变延迟故障模型)。
(一)时序电路故障仿真(SC-FSIM)
在这种情况下,目标是计算将特定测试序列应用于被测电路(CUT)时所实现的故障覆盖率,其中被测电路(CUT)是组合数字电路或时序数字电路(图 1)。通常,我们进行此类计算时所指的测试,是设备制造完成后执行的最终测试。在这种场景中,被测电路(CUT)安装在自动测试设备(ATE)上,并施加测试序列。在大多数情况下,对被测电路(CUT)的测试会借助可测试性设计(DfT)结构。

图1. 基于测试向量的通用顺序CUT制造结束测试场景
施加到被测电路(CUT)的一系列数值(即测试图形)是固定的,它既不依赖于测试过程中被测电路(CUT)自身产生的输出值序列,也不依赖于故障的影响。此外,会持续监控输出信号,以检测可能的故障影响。一旦故障导致任何输出信号出现差异,该故障就能被标记为已检测到。
故障仿真应准确地再现这种场景。然而,故障仿真的目的仅仅是计算已检测到的故障数量。由于故障仿真计算量很大,一旦检测到故障,就可以将其剔除,后续无需再仿真其影响。这种机制(称为故障剔除)能显著降低故障仿真的计算成本,因为大多数故障只需进行有限时间的仿真。
(二)自测试程序故障仿真(STP-FSIM)
当目标是计算在中央处理器(CPU)上运行一个或多个自测试程序所实现的故障覆盖率时,场景会大不相同。这个过程也被称为自测试程序的故障分级。
具体而言,在这种情况下,需要考虑的场景更为复杂,因为软件测试库(STL)的典型应用场景是现场测试,即在设备已处于运行阶段且没有任何自动测试设备(ATE)支持的情况下进行测试。实际上,在这种场景中,中央处理器(CPU)接收的不是测试图形,而是从存储器读取的或来自输入外设(若有)的处理器指令和数据。
事实上,在测试过程中,中央处理器(CPU)会执行一段代码,因此会为了取指以及数据读写操作而持续与存储器模块进行交互。中央处理器(CPU)也可能与外设模块进行交互。因此,需要进行故障仿真的被测电路(CUT)不能仅仅是中央处理器(CPU),还应包括所有与它进行交互的模块(图 2)。为简便起见,且由于输入 / 输出(I/O)操作在概念上与存储器操作类似,下文将忽略输入 / 输出(I/O)操作。

图2.基于STL的CPU系统现场测试场景
实际上,自测试程序通常会将生成的结果累积到一个寄存器中,以生成测试特征码。然后,自测试代码会将该特征码与标准特征码进行比对:如果测试代码的执行导致生成错误的特征码,那么该故障就会被认定为已检测到。测试结束时,自测试代码会对特征码进行检查,并通过在存储器中存储一个标志位来返回结果,该标志位表明是否检测到故障以及计算得到的特征码是什么。
因此,以下几点表述是成立的:
1.中央处理器(CPU)接收的输入序列包括:
· 来自代码存储器的值,对应中央处理器(CPU)应执行的指令代码;
· 来自数据存储器的值,对应中央处理器(CPU)每次进行存储器读操作时所访问的存储单元的值。
在这两种情况下,输入序列都与中央处理器(CPU)通过输出地址所访问的存储单元的内容相对应。因此,如果故障导致中央处理器(CPU)生成的任何地址发生改变,输入序列都可能随之变化。时序电路故障仿真(SC-FSIM)技术(及工具)很难处理这种场景。
2.只有当测试代码执行结束时满足特定条件(例如,某个存储单元存储了特定值,或自测试程序返回了特定值),才能将故障标记为已检测到。同样,时序电路故障仿真(SC-FSIM)技术(及工具)很难处理这种场景。
3.由于只有在测试代码执行结束时才能将故障标记为已检测到,因此无法执行故障剔除操作。所有故障都必须仿真到测试代码执行结束,这会导致计算成本显著增加。
综上所述,自测试程序的故障仿真与时序电路故障仿真(SC-FSIM)是截然不同的任务,它需要具备以下能力的方法和工具:
1.能高效地对执行一段代码(即与存储器进行交互)的中央处理器(CPU)进行故障仿真;
2.支持比单纯检测输出信号差异更复杂的故障检测策略;
3.通过控制因缺少故障剔除机制而额外增加的工作量,来限制计算成本。
值得注意的是,自测试程序故障仿真(STP-FSIM)的规范可能比本节概述的更为复杂。例如,故障可能会产生除测试程序执行结束时存储器中出现错误值之外的其他影响:引发异常或迫使处理器进入无限循环的故障可能很容易被发现。在这两种情况下,该故障通常会被归类为已检测到,这就要求故障仿真工具支持时序电路故障仿真(SC-FSIM)技术难以实现的故障检测机制。
三、基本的自测试程序故障仿真技术
本文的目标之一是概述旨在有效执行一组自测试程序故障分级的不同故障仿真技术。下文将介绍自测试程序故障仿真(STP-FSIM)的可能方法。这些不同方法的区别首先体现在以下两个方面:a)故障检测机制;b)输入激励。前者定义了要观测设计的哪些输出信号(即可观测点)以及何时观测这些信号,以确定故障是否可标记为已检测到;后者则指如何向中央处理器(CPU)提供指令和数据。
下文假设每个自测试程序在执行结束时,会将计算得到的特征码存储到数据存储器中(实际情况通常如此)。首先,我们将考虑单个自测试程序的故障分级,然后将分析扩展到整个软件测试库(STL)的故障分级。对于每种方法,我们都会介绍其优缺点,并在本文的实验部分对这些优缺点进行验证。
(一)单个自测试程序的故障分级
要对单个自测试程序进行故障分级,可以采用不同的方法,我们将这些方法分为以下三种主要类型:
1.STP-FSIM0:基于传统时序电路故障仿真(SC-FSIM)的方法
这种方法以传统的时序电路故障仿真(SC-FSIM)为基础。尽管传统故障仿真技术和工具的设计初衷与自测试程序的故障分级大相径庭,但在这种情况下仍可采用它们。然而,如下文所述,这种方法可能很不适用,且可能无法得出正确的结果。
进行这类故障仿真时,被测电路(CUT)仅为中央处理器(CPU),其输入会施加测试图形。在这种情况下,测试图形一方面对应构成自测试程序的一系列编码指令,中央处理器(CPU)每次执行取指操作时,这些指令会被依次输入;另一方面对应中央处理器(CPU)每次执行存储器读操作时从存储器读取的数据值。
由于我们采用的是传统的时序电路故障仿真(SC-FSIM)方法,输入序列是固定的。因此,无论是否有故障导致中央处理器(CPU)生成的指令 / 数据地址序列发生改变或延迟,在整个故障仿真过程中,所取指和执行的指令 / 数据序列始终保持不变。
此外,在故障仿真实验过程中,会每个时钟周期都观测中央处理器(CPU)的所有输出,一旦检测到差异,就会将相应的故障标记为已检测到。
这种方法可能会导致故障覆盖率数据出现偏差(即高于实际值),因为故障可能会导致一个或多个输出信号出现差异,但这种差异随后可能会被掩盖,从而不会反映在最终的自测试程序特征码中。
2.STP-FSIM1:改进的故障仿真方法
可以对上述方法进行改进,以提高故障仿真结果的准确性。为了模拟实际场景(即现场测试场景),可观测性仅限于指向数据存储器的信号(特征码存储时应通过这些信号传输)。此外,应设置故障仿真器,使其仅在结果即将写入存储器时观测这些信号。
图 3 展示了这种情况,其中 “偏移时间” 指的是测试程序执行指令但尚未将结果写入存储器的初始时间段。这种方法的主要局限性在于,仍然无法模拟导致测试代码执行流程发生改变的故障所产生的影响。此外,该方法不采用故障剔除机制:仅在自测试程序执行结束时才观测输出。因此,所有故障都必须在整个实验过程中进行仿真,这会导致计算成本显著增加。

图3.STP-FSIM1故障检测机制的图形表示
3.STP-FSIM2:基于全系统仿真的方法
上述方法的局限性部分源于被测电路(CUT)仅为中央处理器(CPU),无法妥善地对其与存储器的交互进行建模,尤其是在电路存在故障的情况下。然而,若采用功能故障仿真器,通过对中央处理器(CPU)所在的整个系统(包括数据存储器、代码存储器,甚至外设)进行仿真,就能克服这些局限性,从而计算出自测试程序所实现的准确故障覆盖率。
通常,中央处理器(CPU)会以门级网表的形式进行描述(与 STP-FSIM0 和 STP-FSIM1 方法相同),而其他组件则采用行为级描述。中央处理器(CPU)的输入激励(即指令)直接从指令存储器(现已成为仿真模型的一部分)中获取,这样就能对故障导致执行流程发生改变的影响进行建模。此外,还能对数据存储器读写不同数据的场景进行建模。
在可观测性方面,自测试程序执行结束后,会直接观测存储器的最终内容。显然,只需检查测试程序应写入的那些地址即可;否则,对于大型设计而言,检查整个存储器是不现实的。
然而,由于现在仿真的模型规模大得多,与前两种方法相比,所需的计算成本会显著增加。存储器仿真的计算成本很高,而且由于不采用故障剔除机制,故障仿真往往速度较慢且占用大量内存。
(二)软件测试库(STL)的故障分级
通常,自测试程序的开发会采用分而治之的策略。如果目标模块是中央处理器(CPU),会将其划分为多个子模块,并为每个子模块开发专门的自测试程序 [9]。
上一小节介绍的方法是对单个测试程序进行故障分级的有效解决方案。在为目标模块开发自测试程序的过程中,只需考虑该模块自身的故障。然而,在整个开发流程中,通常需要对整个中央处理器(CPU)的故障列表执行一组自测试程序的故障仿真。这一步骤对于评估所实现的整体故障覆盖率以及(在软件测试库(STL)开发过程中)更好地指导开发工作、达到目标故障覆盖率至关重要。
其根本原因在于,为某个子模块开发的测试程序,有可能也能检测到其他子模块中存在的故障。
最高效的策略是所谓的增量式故障分级法。软件测试库(STL)的故障仿真分为多个阶段,每个阶段对不同的自测试程序进行故障仿真。初始时,故障列表中的所有故障都被标记为未检测到。完成第一个阶段的仿真后,对下一个测试程序进行故障仿真,此时仅需考虑上一阶段标记为未检测到的故障。这一过程会持续进行,直到所有自测试程序都完成故障仿真。
这种方法的主要优势在于,仅第一个自测试程序需要针对完整的故障列表进行故障仿真。随着仿真阶段的推进,需要仿真的故障数量会逐渐减少,故障仿真的工作量也会相应降低。
值得注意的是,上述策略可应用于任何故障仿真方法,且不会导致故障覆盖率的准确性有所损失。此外,这种方法对计算成本较高的故障仿真方法(如 STP-FSIM2)的提升效果最为显著。
四、优化的故障仿真技术
本节旨在进一步扩展现有的技术体系,介绍另外两种优化策略。这些策略以 STP-FSIM2 方法为基础,能够在略微牺牲故障覆盖率准确性的前提下,显著加快故障仿真的速度。这两种技术的共同出发点是:在 STP-FSIM2 方法中,完全没有利用故障剔除机制。因此,下文将探讨一种仍能采用该机制的可行方式。
(一)STP-FSIM3:基于指令地址监控的优化方法
这种方法(图 4)与基本的 STP-FSIM2 方法的主要区别在于可观测性的设置。该方法不再仅在测试程序执行结束时观测数据存储器,而是每个时钟周期都监控指向代码存储器的地址信号。

图4.STP-FSIM3场景:可观测性位置标记为红色
采用这种设置的原因是,某些故障可能会导致从代码存储器中读取的指令序列发生改变,这通常会使测试程序的执行流程发生改变,进而导致测试程序生成不同的特征码。
为了节省故障仿真时间,我们的思路是识别出那些会导致执行流程发生改变的故障,并尽快将其从故障仿真中剔除(从而实现故障剔除)。
显然,并非所有导致执行流程改变的故障最终都会使存储器内容发生变化。因此,预计该方法得出的故障覆盖率会略高于 STP-FSIM2 方法。但实验结果表明,这种差异通常很小,而计算成本的节省则可能非常显著。
(二)STP-FSIM4:基于存储器操作监控的优化方法
另一种优化方法(图 5)能在 STP-FSIM2 方法的基础上进一步加快仿真速度,具体做法是:当中央处理器(CPU)执行存储器写操作时,观测其与数据存储器相连的信号(即数据信号和地址信号)。如果中央处理器(CPU)执行存储器写操作时生成的地址值与预期值不同,或者同时写入存储器的数据值与预期值不同,就会将该故障标记为已检测到,并立即将其剔除。

图5.STP-FSIM4场景:可观测性位置标记为红色
这种策略的故障剔除力度最大,因此能进一步减少故障仿真时间,但同时也会牺牲一定的故障覆盖率准确性。
从理论上讲,这种方法可能会得出过于乐观的结果,因为影响存储器操作的故障可能不会反映在特征码中。但实际上,自测试程序执行过程中通常只会执行少量存储器操作。这些操作包括:在调用自测试程序之前保存 / 恢复先前的上下文,以及对特定地址执行存储 / 加载操作以测试特定单元。
对于前者,故障导致的栈帧损坏会不可逆转地导致测试失败;对于后者,由于测试通常完全依赖这些存储器操作,任何异常都会反映在最终的特征码中。
表 1 总结了本文介绍的各种故障仿真方法,并列出了每种方法的所有关键特征。值得注意的是,基于 STP-FSIM2 的方法不需要预先设定输入序列,因为中央处理器(CPU)所需的激励直接从存储器中获取,且可能会因故障的影响而发生变化。

表 1. 故障仿真技术对比
五、实验结果
本节首先简要介绍评估软件测试库(STL)故障覆盖率所采用的流程,然后介绍用于定量评估不同技术有效性的自测试程序的相关特征和故障仿真环境,最后呈现并讨论所获得的实验结果。
(一)实验平台与设计
实验基于开源的 OpenRISC 1200(OR1200)软核处理器展开。该处理器是一款 32 位标量精简指令集计算机(RISC),采用哈佛架构,具备内存管理单元(MMU)和基本的数字信号处理(DSP)功能。OR1200 包括一个中央处理器(CPU)和基本的外设(如定时器、中断控制器),如图 6 所示。

图6.OR1200架构
我们将 OR1200 集成到一个片上系统(SoC)中,该系统包含 WishBone 接口、一个闪存(Flash)和一个随机存取存储器(RAM)。闪存和随机存取存储器的容量均为 2MB。
采用新思科技(Synopsys)的 Design Compiler 作为逻辑综合工具,将 OR1200 综合并映射到 65 纳米互补金属氧化物半导体(CMOS)工艺库。
需要强调的是,OR1200 代表了一类在安全关键型应用中广泛使用的中央处理器(CPU)。尽管其规模相对较小,但在本文中将其用作测试案例并不会影响实验结果的通用性。事实上,对于更大规模的处理器,故障分级所需的计算工作量和内存占用只会增加,而前文介绍的不同故障分级技术的相对性能表现则保持不变。
(二)自测试程序与故障仿真环境
实验中使用的自测试程序是通过不同的开发策略(随机策略、确定性策略、基于自动测试图形生成(ATPG)的策略)开发的。这些自测试程序会在内部计算测试结果,并将其写入系统随机存取存储器(RAM)中一个已知的存储单元。
每个测试程序针对中央处理器(CPU)特定部分的固定型故障:寄存器堆(RF)、控制单元、操作数多路复用器、算术逻辑单元(ALU)、乘累加器(MAC)单元、加载存储单元(LSU)、取指译码单元、写回多路复用器。
最终的软件测试库(STL)包含 8 个自测试程序,其主要特征如表 2 所示。

表2.STL特性
在故障仿真过程中,使用了新思科技(Synopsys)的 Z01X 工具。Z01X 是一款功能故障仿真器,广泛应用于功能安全分析。其故障仿真算法基于编译型事件驱动并发引擎,同时支持时序电路故障仿真(SC-FSIM)和自测试程序故障仿真(STP-FSIM)技术。
为了实现 STP-FSIM0 和 STP-FSIM1,我们通过对门级网表上的自测试程序进行逻辑仿真(在这些实验中,使用新思科技(Synopsys)的 VCS 工具),预先生成了一个值变化转储(VCD)文件,并通过该文件向被测电路(CUT,即 OR1200)提供测试图形(即指令)。
在 STP-FSIM0 故障仿真过程中,观测点设置在 OR1200 的所有顶层端口(即图 6 中的绿色方框)。对于 STP-FSIM1,观测点仅限于数据 WishBone 接口(即图 6 中的 WB_D)。
在 STP-FSIM2、STP-FSIM3 和 STP-FSIM4 实验中,仿真模型是一个包含 OR1200 内核和两个 2MB 存储器模块的系统。在 STP-FSIM3 中,仅观测随机存取存储器(RAM)的内容和指令 WishBone 接口(即图 6 中的 WB_I);而在 STP-FSIM4 中,会观测数据 WishBone 接口和指令 WishBone 接口。
该工具还提供了其他功能,如超级故障检测。然而,并非所有故障仿真器都支持这一特定机制。因此,为了确保实验的可重复性,在故障仿真过程中禁用了该功能。
所有实验均在一台工作站上进行,该工作站配备了 2.5 吉赫兹(GHz)的英特尔至强(Intel Xeon)处理器、12 个内核和 256 吉字节(GB)的内存。故障仿真仅使用其中一个内核。
为了保证通用性,实验针对中央处理器(CPU)的固定型故障列表进行,未剔除安全故障(即在应用环境中不会导致任何失效的故障)。若剔除安全故障,所实现的故障覆盖率会显著提高。最后,故障仿真采用零延迟模式(即忽略所有组合延迟和时序延迟)。
(三)实验结果与分析
表 3 展示了针对第三节和第四节介绍的方法所获得的实验结果。故障覆盖率数据是采用增量式故障分级策略,针对整个软件测试库(STL)和完整的中央处理器(CPU)故障列表(约含 98000 个固定型故障)计算得出的。

表3.故障模拟结果
可以看出,STP-FSIM0 和 STP-FSIM1 方法无疑是速度最快的,但与 STP-FSIM2 方法(以粗体标注,因其能得出正确的故障覆盖率结果)相比,它们得出的故障覆盖率数据偏差最大。STP-FSIM1 比 STP-FSIM0 慢,原因是其可观测性降低,无法采用故障剔除机制。
对于基于 STP-FSIM2 的技术,STP-FSIM2 能得出精确的故障覆盖率数值,因为它模拟了片上系统(SoC)部署到现场后的实际运行条件。自测试程序在设计时会将结果写入单个存储单元,因此测试程序执行结束后,只需检查该存储单元即可。
两种优化技术(STP-FSIM3 和 STP-FSIM4)与基础的 STP-FSIM2 方法相比,能实现显著的加速。STP-FSIM3 可使故障仿真时间减少近 56%,而 STP-FSIM4 的加速效果更显著,约为 68%。这一加速效果意义重大,因为故障覆盖率的准确性损失非常小(STP-FSIM3 与 STP-FSIM2 相比损失 0.3%,STP-FSIM4 与 STP-FSIM2 相比损失 0.4%)。
STP-FSIM3 和 STP-FSIM4 之间的差异较小,主要原因是在 STP-FSIM4 中,故障仿真器标记为可能已检测到的故障数量更多。如果将这些故障都计为已检测到,两种方法得出的故障覆盖率数据会几乎相同。
有趣的是,使用故障列表分析工具(FLAT)对 STP-FSIM2、STP-FSIM3 和 STP-FSIM4 的故障列表进行处理后发现,这三种方法检测到的故障集合略有不同。我们用 A、B、C、D、E、F 和 G 表示比较这三种故障仿真方法所检测到的故障集合时需要考虑的故障集合(图 7)。表 4 详细列出了每个集合中的故障数量。

图7.STP-FSIM2、STP-FSIMO3、STP-FSI M4检测到的故障及其可能的交叉点。在这种情况下,E=F=G=0

表4.故障集的大小
如图 7 所示,每种故障仿真方法检测到的故障集合都可以表示为这些集合的组合(为简洁起见,由于在考虑的案例中 E、F 和 G 为空集,下文将省略这些集合)。
从表 4 可以看出,集合 A 的规模最大,实际上它包含了三种技术都能检测到的故障。集合 B 是 STP-FSIM2 和 STP-FSIM3 共同检测到但 STP-FSIM4 未检测到的故障集合。需要注意的是,STP-FSIM2 检测到的所有故障都包含在 STP-FSIM3 检测到的故障中。
集合 C 中的故障仅能被 STP-FSIM4 和 STP-FSIM3 检测到(在 STP-FSIM2 中被标记为未检测到),这些故障主要属于 genpc、if 和 ctrl 模块。这是合理的,因为 STP-FSIM3 和 STP-FSIM4 与 STP-FSIM2 的区别在于对指令总线的观测,而 genpc、if 和 ctrl 模块直接与该接口相连。
对于仅包含在 STP-FSIM4 中的集合 D,其故障主要与 lsu 和 except 单元相关,这些单元与数据总线相连,而 STP-FSIM4 是唯一观测这些信号的技术。
图 8 总结了上述方法产生的结果。可以看出,STP-FSIM0 和 STP-FSIM1 方法的故障仿真速度最快,但与精确值(用红线表示)相比,它们提供的故障覆盖率指标准确性很低。另一方面,基于 STP-FSIM2 的方法计算成本更高,但能得出最准确的结果。

图8.故障模拟方法:故障覆盖精度与故障模拟时间。红线代表确切的FC数字
具体而言,由于 STP-FSIM2 能得出精确结果,因此 STP-FSIM0 得出的故障覆盖率数值通常会更高,因为它会持续观测所有输出。相反,STP-FSIM1 得出的故障覆盖率数值较低,因为它没有考虑故障导致执行流程发生改变的影响。
对于 STP-FSIM3 和 STP-FSIM4,实验证实它们的故障覆盖率指标是实际覆盖率的合理近似值。
读者还应注意,通过精心开发自测试程序,可以最大限度地缩小精确故障覆盖率数值与任何近似方法得出的数值之间的差异。

表5. STP-FSIM2与STP-FSIMO故障分级
例如,表 5 展示了使用 STP-FSIM0 和 STP-FSIM2 方法时,针对每个特定自测试程序所目标模块的故障覆盖率数值。对于 rf_test、alu_test 和 lsu_test 等测试程序,两种技术得出的结果差异可能很大(例如,rf_test 的差异为 24.62%)。这主要是因为像加载存储单元(LSU)这样的模块直接与 OR1200 的顶层输出(即系统总线接口)相连,因此使用 STP-FSIM0 方法(观测所有输出)比使用 STP-FSIM2 方法(仅利用生成的特征码)更容易检测到故障影响。
对于寄存器堆(RF)和算术逻辑单元(ALU),结果存在差异的原因是算术逻辑单元(ALU)用于计算加载和存储操作的有效地址。因此,算术逻辑单元(ALU)的输出也与系统总线接口相连,在寄存器堆(RF)测试(采用介绍的测试算法)和算术逻辑单元(ALU)测试过程中,该信号上可能会传输一些错误数据,但这些错误数据不会反映在最终的特征码中。
另一方面,对于那些深埋在处理器内核中的模块,两种方法得出的结果不会存在这种差异。实际上,乘累加器(MAC)和操作数多路复用器不与顶层信号直接相连,因此两种方法得出的结果非常相似。

表6.单片与增量故障分级
为了全面起见,表 6 计算了采用整体式故障分级(即不采用增量式故障分级)方法时,STP-FSIM0、STP-FSIM1 和 STP-FSIM2 方法对软件测试库(STL)进行故障分级所需的时间。可以看出,尽管 STP-FSIM0 仍可行,但对于其他两种方法,故障仿真时间会急剧增加,对于大型设计而言,这种方法是不现实的。
从目前描述的实验可以明确,STP-FSIM0 和 STP-FSIM1 方法不适合用于提供能反映实际运行环境情况的最终故障覆盖率数值。然而,在为基于双核锁步(DCLS)的片上系统(SoC)中的内核生成软件测试库(STL)时,采用 STP-FSIM0 方法可以显著缩短开发时间,同时仍能得出正确的结果。
实际上,双核锁步(DCLS)通常用于满足复杂设备(如多核设备)的可靠性要求。在这种情况下,软件测试库(STL)用于检测影响校验内核或主内核的潜在故障。显然,对于如此庞大的设计,采用 STP-FSIM2 方法可能会面临挑战。
但让我们思考一下锁步原理的工作方式。其核心思想是添加一个与主内核在功能上完全相同的副本,这样一来,任何传播到某个输出信号的故障影响都能被一组比较器立即检测到。只要两个副本中只有一个受到故障影响,这一原理就成立。
因此,软件测试库(STL)用于检测潜在故障,从而迫使故障的可能出现表现为处理器输出端的失效。由于这些输出端会被比较器持续监控,一旦出现失效,就会触发警报,片上系统(SoC)也会相应地做出反应。
上述场景在概念上与故障仿真(尤其是 STP-FSIM0)的场景类似,在 STP-FSIM0 中,会对输出信号进行监控,并将其与无故障机器的标准值进行比较。因此,在为基于双核锁步(DCLS)的片上系统(SoC)开发和分级软件测试库(STL)时,可以直接采用 STP-FSIM0 方法(并利用其优势)。
当然,这两种场景并非完全等同,我们基于 OR1200 的内部双核锁步(DCLS)版本所进行的实验也证实了这一点。我们在尽可能低的层级(即中央处理器(CPU)层级)应用了锁步机制。表 7 总结了实验结果。

表7.STP-FSIM0用于面向DCLS的STL分级
观察第二列可以发现,自测试程序的故障覆盖率指标略高于表 5 中的数值。这是因为在表 5 中,观测点设置在 OR1200(包含中央处理器(CPU))的输出信号上,这一层级比表 7 中的观测层级高一级。这样做是为了能与仅利用锁步机制时的结果进行公平比较。
第三列报告了观测锁步比较器输出信号时的故障覆盖率。可以看出,虽然存在差异,但差异非常小(最坏情况下仅为 0.03%)。
六、结论
本文的主要目的是概述用于执行软件测试库(STL)故障仿真的不同方法。通过实验,我们表明传统故障仿真方法在处理这类任务时存在不足,因为问题的性质已从制造末期测试转变为现场测试,因此故障仿真方法也应相应地发展。
在软件测试库(STL)的开发过程中,故障仿真是至关重要的一步,通常需要大量的计算工作。为了实现最高效率,应综合运用所有这些技术。在开发初期,为了完善程序,可能更倾向于采用快速故障仿真方法(如 STP-FSIM0 和 STP-FSIM1)。当自测试程序足够成熟后,测试工程师应转而采用更精确的故障仿真方法(如 STP-FSIM3 或 STP-FSIM4)。最后,在计算整个软件测试库(STL)的最终故障覆盖率时,应采用 STP-FSIM2 方法。
然而,实验还表明,在为基于双核锁步(DCLS)的片上系统(SoC)开发软件测试库(STL)时,整个开发过程都可以采用 STP-FSIM0 方法,从而避免耗时且成本高昂的故障仿真。
本文由豆包软件翻译,如有不当之处请参照原文
下载请扫二维码:



