CN1981200A - 开发用于半导体集成电路的测试程序的方法和结构 - Google Patents

开发用于半导体集成电路的测试程序的方法和结构 Download PDF

Info

Publication number
CN1981200A
CN1981200A CN 200580016437 CN200580016437A CN1981200A CN 1981200 A CN1981200 A CN 1981200A CN 200580016437 CN200580016437 CN 200580016437 CN 200580016437 A CN200580016437 A CN 200580016437A CN 1981200 A CN1981200 A CN 1981200A
Authority
CN
China
Prior art keywords
test
file
name
class
header
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Granted
Application number
CN 200580016437
Other languages
English (en)
Other versions
CN100541218C (zh
Inventor
安康·普拉马尼克
马克·埃尔斯顿
拉马钱德兰·克里希纳斯瓦米
足立敏明
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Advantest Corp
Original Assignee
Advantest Corp
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Advantest Corp filed Critical Advantest Corp
Publication of CN1981200A publication Critical patent/CN1981200A/zh
Application granted granted Critical
Publication of CN100541218C publication Critical patent/CN100541218C/zh
Expired - Fee Related legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Images

Landscapes

  • Tests Of Electronic Circuits (AREA)
  • Test And Diagnosis Of Digital Computers (AREA)
  • Debugging And Monitoring (AREA)
  • Management, Administration, Business Operations System, And Electronic Commerce (AREA)

Abstract

公开了开发用于半导体测试***的测试程序的方法。该方法包括以测试程序语言(TPL)描述测试计划文件,其中该测试计划文件描述测试程序的至少一个测试;以***程序语言(SPL)描述测试类文件并以TPL描述该测试类文件的相应的预编译头文件,其中该测试类文件描述测试程序的至少一个测试的实施;以及使用测试计划文件、测试类文件和预编译头文件来生成测试程序。

Description

开发用于半导体集成电路的测试程序的方法和结构
相关申请的交叉参考
[1]本申请是部分延续申请,且要求于2004年2月6日提交的名称为“Method and Structure to Develop a Test Program for Semiconductor IntegratedCircuits”的共同未决美国申请No.10/772,434的权益,后者又要求了于2003年2月14日提交的、名称为“Method and Structure to Develop a Test Programfor Semiconductor Integrated Circuits”的申请No.60/447,839的权益;本申请还要求于2004年5月22日提交的名称为“Software Development in an OpenArchitecture Test System”的美国临时申请No.60/573,577的权益;所有这些申请都已转让给Advantest公司,且上述申请的全部内容通过参考结合于此。
技术领域
[2]本发明涉及用于半导体测试的自动测试设备领域。具体地,本发明涉及开发用于半导体测试***的测试程序的方法。
背景技术
[3]半导体测试***具有多个设备一起工作的复杂的***环境。测试***可包括多个控制器,这些控制器控制多个厂商模块及它们相应的被测设备(DUT)的操作。用于半导体测试***的测试程序需要在复杂的***环境中运行。开发这种测试程序的一种方法是以***程序语言(SPL)(诸如C++)直接编写测试代码。然而,利用这种方法,测试工程师要受复杂的测试***环境所累。具体而言,为了开发测试程序,测试工程师必须遵循许多复杂的***编程规则,并且必须符合***程序语言的要求。
[4]现有方法的另一问题是可能直到以SPL对测试程序进行编译时或直到在DUT测试期间运行测试程序后,才能发现测试程序中的错误。此外,在复杂的测试***环境中识别测试计划错误往往是困难和耗时的。这种限制可能会延迟DUT的生产,这将推迟产品发布甚至丢失市场的机会。
[5]因此,需要消除测试计划的开发中***编程的复杂性。具体而言,需要以这样一种语言来开发测试计划,与引入测试***复杂性的语言不同,该语言更接近测试工程师熟悉的问题领域。另外,需要在***编译之前识别测试计划中的错误。测试计划错误的早期检测可使得测试程序开发时间以及被测试的DUT的减少。
发明内容
[6]本申请描述使用面向对象的构造(如C++对象和类)的测试程序开发。更具体地,该方法适合开发用于开放体系测试器的程序,如转让给本发明受让人的美国申请No.60/449,622、No.10/404,002以及No.10/403,817中描述的测试器。
[7]本发明的一个实施例提供一种方法,用于通过以通用的面向对象的构造(如C/C++)描述测试***资源、测试***配置、模块配置、测试顺序、测试计划、测试条件、测试模式、以及定时信息来在半导体测试***(如自动测试装置(ATE))上开发测试被测试设备(如IC)的测试程序。包含这些描述的文件存储在测试***或使用这些文件的有关设备可访问的存储器,即计算机可读介质中。
[8]描述测试***资源可以包括指定资源类型,其中资源类型与对IC施加测试的至少一个测试模块关联,指定与资源类型关联的参数类型及指定参数类型的参数。
[9]描述测试***配置可以包括指定用于控制至少一个测试模块的站点控制器,其中每个测试模块对IC施加测试,及指定模块连接使能器的输入端口。测试***将站点控制器耦合到模块连接使能器的该指定的输入端口处,而模块连接使能器将站点控制器耦合到测试模块。模块连接使能器可以实现为开关阵列。
[10]描述模块配置可以包括指定用于指定模块类型的模块标识符,指定用于控制由模块标识符所指定模块类型的测试模块的可执行代码及指定与测试模块关联的资源类型。可执行代码可以采取动态链接库的形式。
[11]描述模块配置还可以涉及用户指定用于指定模块连接使能器输出端口的槽标识符,其中测试***在输出端口将测试模块耦合到模块连接使能器,而模块连接使能器将测试模块耦合到对应的站点控制器。用户还可以指定用于识别测试模块提供商的厂商标识符及结合资源类型可用的最大数量资源单元的标识符。资源类型可以是例如数字测试器引脚和资源单元测试器通道。可选地,测试器通道资源单元还可以对应于资源类型,例如模拟测试器引脚、RF测试器引脚、电源引脚、数字转换器引脚和任意波形生成引脚。还可以提供关于禁用哪个资源单元的指示符。指示为禁用的资源单元可以表示测试模块不完善的资源单元。
[12]描述测试条件可以包括指定至少一个测试条件组、指定包括至少一个变量的规范集合;及指定用于选择要绑定到变量的表达式的选择器。测试条件组与用于规范集合的选择器的结合定义了测试条件。
[13]描述测试序列可以包括指定其中各种测试可以施加的次序(或流)。
[14]描述测试模式可以包括指定测试模式、相关联的电压与电流电平、信号值的过渡、对应的上升与下降时间以及相关联的定时。
[15]本发明实施例的模式编译器包括至少一个特定于模块的模式编译器,以及目标文件管理器,该目标文件管理器用于指令每个特定模块的编译器编译模式资源文件的相应的特定于模块的部分和模式资源文件的公共部分。该公共部分包括所有特定于模块的编译器都可以访问的信息。编译器的输出包括至少一个特定于模块的模式数据部分。特定于模块的模式加载器将特定于模块的模式数据从相应的特定于模块的模式数据部分加载到测试模块中用于执行。
[16]通过以更接近测试计划旨在针对的问题领域的语言来描述测试计划,所公开的用于开发测试程序的方法使测试计划开发者脱离***编程的复杂性。该方法还使得测试工程师能够在测试程序开发的较早阶段识别测试计划中的错误,这可以减少测试程序的开发时间和对应的被测试的DUT。
[17]在一个实施例中,开发用于半导体测试***的测试程序的方法包括:以测试程序语言(TPL)描述测试计划文件,这里,该测试计划文件描述测试程序的至少一个测试;以***程序语言(SPL)描述测试类文件并以TPL描述测试类文件的相应的预编译头文件(pre-header file),这里,测试类文件描述测试程序的至少一个测试的实施,并使用测试计划文件、测试类文件和预编译头文件产生测试程序。
[18]在另一个实施例中,产生用于半导体测试***的测试程序的预编译头包括:用于指定测试程序的至少一个属性的参数部分,以及用于将源代码***到测试程序的头文件中的模板部分,其中测试程序的至少一个属性与模式列表和测试条件相关。
[19]在又一实施例中,一种验证用于半导体测试***的测试程序的方法包括:以测试程序语言(TPL)描述测试计划文件,其中所述测试计划文件描述测试程序的至少一个测试;以TPL描述预编译头文件;以及使用所述预编译头文件验证所述测试计划文件。
[20]在又一实施例中,一种半导体测试***包括:用于将至少一个测试施加于被测设备的至少一个测试模块,以及用于接收测试计划文件、测试类文件和该测试类文件的相应的预编译头文件的控制器,其中所述测试计划文件以测试程序语言(TPL)描述该至少一个测试,且所述测试类文件以***程序语言(SPL)描述该至少一个测试的实施。该半导体测试***还包括用于编译测试计划文件和预编译头文件以分别形成得出的测试计划文件和头文件的装置,以及使用测试类文件、得出的测试计划文件和头文件产生测试程序的装置。
附图说明
[21]当联系附图参考本发明实施方式的具体描述时,以上提到的本发明特征与优点及其另外的特征与优点将在下文中更清楚地理解。
[22]图1说明了传统的测试器体系。
[23]图2说明了根据本发明实施方式的测试器体系。
[24]图3说明了根据本发明实施方式的测试器软件体系。
[25]图4说明了根据本发明实施方式的测试程序编译器。
[26]图5说明了根据本发明实施方式有多少不同的测试实例可以从单个测试类导出。
[27]图6说明了根据本发明实施方式的模式编译器。
[28]图7说明了根据本发明实施方式有序的模式树例子。
[29]图8说明了根据本发明实施方式的另一有序的模式树例子。
[30]图9说明了根据本发明实施方式测试程序所需的文件之间的关系。
[31]图10说明了根据本发明实施方式的波形生成。
[32]图11说明了根据本发明实施方式用于定时的映射。
[33]图12说明了根据本发明实施方式用于定时的另一映射。
[34]图13说明了根据本发明实施方式的用于开发测试程序的方法。
具体实施方式
[35]提供开发用于半导体测试***的测试程序的方法和***。以下描述的提出是为了使本领域任何技术人员能够制造并使用本发明。特定实施方式与应用的描述仅仅是作为例子提供的。在此所描述的例子的各种修改与组合对本领域技术人员是显而易见的,而且在不背离本发明主旨与范围的情况下在此所定义的通用原理适用于其它例子与应用。因此,本发明不是要限定到所描述和示出的例子,而是要符合与在此所公开的原理与特征一致的最广泛范围。
[36]本发明总的来说是根据如本受让人的美国申请No.60/449,622、10/404,002和10/403,817中所描述的开放体系来描述的。但是,本领域技术人员将认识到本发明不仅适用于开放测试器体系,而且也适用于固定测试器体系。
[37]开放体系测试***的描述可以在要求本受让人的美国申请No.60/449,622的权益的美国申请No.10/772,372“Method and Apparatus for Testing IntegratedCircuits”中找到。
[38]图1说明了显示信号如何生成并施加到进行测试的设备(DUT)的传统测试器的通用结构。每个DUT输入引脚都连接到施加测试数据的驱动器2,而每个DUT输出引脚都连接到比较器4。在大多数情况下,使用三态驱动器比较器,使得每个测试器引脚(通道)都可以既充当输入引脚,又充当输出引脚。专用于单个DUT的测试器引脚共同形成与相关定时发生器6、波形发生器8、模式存储器10、定时数据存储器12、波形存储器数据14及定义数据率的块16一起工作的测试站点。
[39]图2说明了根据本发明实施方式的***体系100。***控制器(SysC)102耦合到多个站点控制器(SiteC)104。***控制器还可以耦合到网络,以便访问文件。通过模块连接使能器106,每个站点控制器都耦合成控制位于测试站点110的一个或多个测试模块108。模块连接使能器106允许所连接硬件模块108的重新配置,还充当数据传输的总线(用于加载模式数据、收集响应数据、提供控制,等等)。可能的硬件实现包括专用连接、开关连接、总线连接、环形连接及星形连接。模块连接使能器106可以由例如开关阵列实现。每个测试站点110都与一个DUT 112关联,DUT 112通过加载板114连接到对应站点的模块。在一种实施方式中,单个站点控制器可以连接到多个DUT站点。
[40]***控制器102充当全局***管理器。它协调站点控制器的动作、管理***级的并行测试策略并附加地提供操纵器/探测器控制及***级数据登录与错误处理支持。依赖于操作设置,***控制器102可以部署到独立于站点控制器104运行的CPU上。可选地,***控制器102和站点控制器104可共享一个CPU。类似地,每个站点控制器104可以部署到其自己的专用CPU(中央处理单元),或者作为相同CPU中的独立处理器或线程。
[41]上述***体系可以从概念上设想为图2所示的分布式***,应当理解,单独的***部件也可以看作集成、单块***的逻辑组件而不一定是分布式***的物理组件。
[42]图3说明了根据本发明实施方式的软件体系200。软件体系200代表了分布式操作***,具有对应于相关硬件***元素102、104、108的***控制器220、至少一个站点控制器240和至少一个模块260元素。除了模块260,体系200还包括用于软件模块仿真280的对应元件。
[43]作为示例选择,用于这种平台的开发环境可以基于微软的Windows。这种体系的使用在还有程序与支持的便携性方面的好处(例如,站点服务引擎可以连接运行测试器操作***的膝上型电脑,以便执行事先的诊断)。但是,对于大的计算密集操作(例如测试模式编译),可以使相关软件作为能够独立运行以便允许在整个分布式平台上进行任务调度的独立实体。因此,用于批任务的相关软件工具能够运行在多个平台类型上。
[44]作为示例选择,ANSI/ISO标准C++可以作为软件的本机语言使用。当然,有多种允许带其自己的可选语言的第三方集成到***中的选择(提供标准C++接口上的层)。
[45]图3说明了通过标准的源,根据各个元件的组织对其进行阴影表示(或者作为子***集中开发),包括测试操作***、用户部件292(例如,由用户为测试目的提供的)、***部件294(例如,为基本连接性和通信作为软件基础结构提供的)、模块开发部件296(例如,由模块开发器提供的)及外部部件298(例如,由除模块开发器之外的外部源提供的)。
[46]从基于源的组织的观点看,测试操作***(TOS)接口290包括:用于站点控制器接口的***控制器222、框架类224、用于模块接口的站点控制器245、框架类246、预定义的模块级接口、背板通信库249、底盘槽IF(接口)262、加载板硬件IF264、背板模拟IF 293、加载板模拟IF 285、DUT模拟IF 287、用于DUT的Verilog模型的Verilog PLI(编程语言接口)288及用于DUT的C/C++模型的C/C++语言支持289。
[47]用户部件292包括:用户测试计划242、用户测试类243、硬件加载板265及DUT 266、DUT Verilog模型293和DUT C/C++模型291。
[48]***部件294包括:***工具226、通信库230、测试类244、加载板驱动器250、HW背板261、模拟框架281、背板仿真282及加载板模拟286。
[49]模块开发部件296包括:模块命令实现248、模块硬件263及模块仿真284。
[50]外部部件298包括外部工具225。
[51]***控制器220包括用于站点控制器的接口222、框架类224、***工具226、外部工具225及通信库230。***控制器软件是用户的主要交互点。它提供到本发明的站点控制器的网关及多站点/DUT环境中站点控制器的同步,如在本受让人的美国申请No.60/449,622中所描述的。基于图形用户接口(GUI)或其它的用户应用与工具运行在***控制器上。***控制器还可充当用于所有测试计划相关信息的仓库,包括测试计划、测试模式和测试参数文件。存储这些文件的存储器可以对***控制器是本地的或者离线的,例如通过网络连接到***控制器。测试参数文件包含在本发明实施方式中面向对象的环境中用于测试类的参数化数据。
[52]除标准***工具226之外(或者代替之),第三方开发人员也可提供工具。***控制器220上的标准接口222包括工具用来访问测试器和测试对象的接口。工具(应用)225/226允许测试和测试器对象的交互性与批控制。工具包括用于(通过例如SECS/TSEM等的使用)提供自动化能力的应用。
[53]驻留在***控制器220上的通信库230提供以对用户应用和测试程序透明的方式与站点控制器240通信的机制。
[54]驻留在与***控制器220关联的存储器中的接口222提供与在***控制器上执行的框架对象的开放式接口。包括允许基于站点控制器的模块软件访问并检索模式数据的接口。还包括应用与工具用于访问测试器和测试对象的接口及提供通过脚本引擎访问并控制测试器与测试组件的能力的脚本接口。这使得用于交互的机制、批与远程应用能够执行它们的功能。
[55]与***控制器220关联的框架类224提供与上面提到的这些对象交互的机制,提供标准接口的引用实现。例如,本发明的站点控制器240提供功能性测试对象。***控制器框架类可提供对应的功能性测试代理作为功能性测试对象基于远程***控制器的代理。因此,使***控制器220上的工具可具有标准功能性测试接口。框架类有效地提供与主***控制器关联的操作***。它们还构成提供到站点控制器的网关并在多站点/DUT环境中提供站点控制器同步的软件元素。因此,这一层在本发明的实施方式中提供了适于控制和访问站点控制器而不需要直接处理通信层的对象模型。
[56]站点控制器240是用户测试计划242、用户测试类243、标准测试类244、标准接口245、站点控制器框架类246、模块高级命令接口(即,预定义的模块级接口247)、模块命令实现248、背板通信库249和背板驱动器250的主机。优选地,大部分测试功能是由站点控制器104/204处理的,从而允许测试站点110的独立运行。
[57]测试计划242是用户写的。计划可以直接由采用面向对象结构的标准计算机语言,如C++,来写,或者在高级测试程序语言中描述,来产生C++代码,然后C++代码可以编译成可执行测试程序。对于测试程序开发,本发明的一种实施方式采用受让人的创造性测试程序语言(TPL)编译器。参考图4,测试程序编译器400部分地充当代码生成器,包括将描述测试与相关参数的测试程序开发人员的源文件404翻译成例如C++代码的面向对象结构的翻译器部分402。编译器部分406又将代码编译并链接成可执行文件,例如DLL,以便创建可以由测试器***执行的测试程序。尽管将TPL代码生成器/翻译器的应用于测试***是新颖的,但请注意,代码生成器是本领域已知的。而且,编译器部分可以是本领域已知的标准C++编译器。
[58]测试计划通过使用框架类246和/或标准或与站点控制器关联的用户提供的测试类244创建测试对象、利用标准接口245配置硬件并定义测试计划流。它还提供测试计划执行过程中所需的任何附加逻辑。测试计划支持一些基本服务并提供与例如调试服务(例如,断点)的底层对象的服务的接口,及对底层框架与标准类的访问。
[59]输入到测试程序编译器400的源代码包括指定测试计划中所使用对象及其彼此关系的测试计划描述文件。这个文件被翻译成在站点控制器上执行的形式为标准接口实现的C++代码,这可以指示为ItestPlan。这个代码被打包成可以加载到站点控制器上的Windows动态链接库(DLL)。生成具有标准已知输入点的测试程序DLL,使得站点控制器软件可以使用该输入点生成并返回它所包含的TestPlan对象。站点控制器软件将测试程序DLL加载到其处理空间中并使用一个输入点来创建测试计划对象的实例。一旦测试计划对象已经创建,站点控制器软件就可以执行测试计划。
[60]与站点控制器关联的框架类246是实现公共的测试相关操作的一组类与方法。站点控制器级框架包括例如用于电源和引脚电子排序、设置电平与定时条件的类、获得测量值的类及控制测试流的类。框架还提供用于运行时间服务与调试的方法。框架对象可以通过实现标准接口工作。例如,TesterPin框架类的实现标准化成实现测试类可以与硬件模块引脚交互的通用测试器引脚接口。
[61]特定的框架对象可以实现成利用模块级接口247的帮助工作,与模块通信。站点控制器框架类实际上充当支持每个站点控制器的本地操作***。
[62]大体上,多于90%的程序代码是用于设备测试的数据,而剩余的10%代码实现测试方法。设备测试数据是依赖于DUT的(例如,电源条件、信号电压条件、定时条件等)。测试代码包括将特定的设备条件加载到ATE硬件上的方法,还有那些实现特定于用户的目标(例如,数据登录)所需的方法。本发明一种实施方式的框架提供独立于硬件的允许用户执行DUT测试编程任务的测试与测试器对象模型。
[63]为了增加测试代码的可重用性,可以使这种代码独立于任何特定于设备的数据(例如,引脚名、模拟数据,等等)或特定于设备测试的数据(例如,用于DC单元的条件、测试引脚、目标引脚数、模式文件名、模式程序地址)。如果测试代码利用这些类型的数据编译,则测试代码的可重用性降低。因此,根据本发明的实施方式,可以使任何特定于设备的数据或者特定于设备测试的数据在外部对测试代码可用,作为代码执行时的输入。
[64]在本发明的实施方式中,在此表示为Itest的一个测试类(它是标准测试接口的实现)实现测试数据的与用于特定类型测试的代码(及因此代码的可重用性)的分离。这种测试类可以看作是用于其自己的独立实例的“模板”,彼此只根据特定于设备和/或特定于设备测试的数据不同。测试类在测试计划文件中指定。每个测试类一般实现特定类型的设备测试或用于设备测试的设置。例如,本发明的实施方式可以提供Itest接口的特定实现,例如FunctionalTest,作为所有DUT功能性测试的基础。它提供设置测试条件、执行模式和基于失败的选通脉冲的存在确定测试状态的基本功能性。其它类型的实现可以包括AC和DC测试类,在此表示为ACParametricTests和DCParametricTests。
[65]所有的测试类型都可以提供某些虚拟方法(例如,init()、preExec()和postExec())的缺省实现。这些方法变成测试工程师覆盖缺省特征并设置任何特定于测试的进入点。但是,定制的测试类也可以在测试计划中实现。
[66]测试类允许用户通过提供用于指定该测试特定实例的选项的参数来配置类特征。例如,Functional Test可以取参数Plist和TestConditionS,来分别指定要执行的模式列表和测试的电平与定时条件。指定这些参数的不同值(通过使用测试计划描述文件中不同的“测试”块)允许用户创建函数Test的不同实例。图5说明了不同的测试实例可以如何从单个测试类中导出。这些类可以直接以面向对象的结构,例如C++代码,编程,或者设计成允许测试程序编译器从测试计划文件取该测试及其参数的描述并生成对应的C++代码,C++代码可以编译并链接以便生成测试程序。可以采用模板库作为一般算法与数据结构的通用库。这个库可以对测试器用户是可见的,使得用户可以例如修改测试类的实现,以便创建用户定义的测试类。
[67]关于用户开发的测试类,***的实施方式支持这种测试类集成到框架中,因为所有测试类都从例如ITest的单个测试接口导出,因此框架可以与标准***测试类集合相同的方式控制它们。在理解它们必须在其测试程序中使用定制代码以便利用这些附加功能的情况下,用户可以自由地将附加功能结合到它们的测试类中。
[68]每个测试站点110都专用于测试一个或多个DUT 106,并通过可配置的测试模块集合112起作用。每个测试模块112都是执行特定测试任务的实体。例如,测试模块112可以是DUT电源、引脚卡、模拟卡,等等。这种模块方法提供了高度的灵活性和可配置性。
[69]模块命令实现类248可以由模块硬件厂商提供,并依赖于厂商所选的命令实现方法,实现用于硬件模块的模块级接口或者提供标准接口的特定于模块的实现。这些类的外部接口是由预定义的模块级接口需求和背板通信库需求定义的。这一层还提供标准测试命令集合的扩展,以便允许方法(函数)与数据元素的添加。
[70]背板通信库249提供跨背板的标准通信的接口,从而提供与连接到测试站点的模块通信所必需的功能。这使得特定于厂商的模块软件可以使用背板驱动器250与对应的硬件模块通信。背板通信协议可以使用基于包的格式。
[71]测试引脚对象表示物理测试器通道,并从测试器引脚接口导出,在此表示为ITesterPin。本发明实施方式的软件开发包(SDK)提供也可以称为TesterPin的ItesterPin的缺省实现,这是根据预定义的模块级接口IChannel实现的。如果他们可以根据Ichannel实现他们的模块功能性,则厂商可以自由地使用TesterPin,否则,他们必须提供与他们的模块一起工作的ItesterPin的实现。
[72]在此表示为Imodule的由本发明测试器***提供的标准模块接口一般地表示厂商的硬件模块。厂商支持的特定于模块的***软件可以例如动态链接库(DLL)的可执行代码的形式提供。用于来自一个厂商的每种模块类型的软件可以封装到单个DLL中。每个这种软件模块都负责提供用于模块接口命令的特定于厂商的实现,这包括用于模块软件开发的API。
[73]有两方面的模块接口命令:第一,它们充当用户与***中特定硬件模块(间接)通信的接口,第二,它们提供第三方开发人员可以用于将他们自己的模块集成到站点控制器级框架中的接口。因此,由框架提供的模块接口模块分成两种类型:
[74]第一种且最显著的类型是通过框架接口暴露给用户的那些“命令”。因此,例如,测试器引脚接口(ITesterPin)提供获得和设置电平与定时值的方法,而电源接口(IPowerSupply)提供用于上电和下电的方法。
[75]此外,框架提供预定义模块级接口的特定类,这可以用于与模块通信。这些是由框架类(即,框架接口的“标准”实现)用于与厂商模块通信的接口。
[76]但是,第二方面的使用,模块级接口,是可选的。这样做的好处是厂商可以利用如ITesterPin和IPowerSupply等的类的实现,同时集中到通过实现模块级接口发送到其硬件的特定消息的内容。但是,如果这些接口对厂商不合适,则他们可以选择提供他们框架接口的定制实现(例如,ITesterPin、IpowerSupply等的厂商实现)。然后这些将提供对他们硬件合适的定制功能。
[77]以这种开放体系作为背景,以下进一步描述本发明的测试程序开发***。以下的部分A描述用于描述其中测试程序将使用的测试环境的规则;部分B描述用于测试程序开发的方法与规则;部分C指定开发测试计划及如何定义测试程序主结构的方法与规则;部分D描述如何在开放体系的测试***上运行测试程序;部分E描述用于测试模式的方法;部分F描述用于描述测试模式定时的规则;而部分G描述用于整体测试器操作的规则。
A.部件
[78]测试环境包括指定提供测试器并用于使之准备运行一组测试所必需条件的一组文件。测试环境优选地包括用于以下功能的文件:
1.测试器资源定义:用于在开放体系测试***中可用的测试器资源类型及这种资源支持的参数的说明。
2.测试器配置:用于站点控制器、站点及对应映射的说明。
3.模块配置:用于每个站点中硬件模块的说明。
4.引脚描述:用于DUT引脚的命名,例如信号引脚、电源,并描述引脚组,
5.套接字:用于DUT引脚到测试器引脚分配的说明。
6.引脚选项:用于引脚特定选项或模式的说明。
7.模式列表:用于测试模式及其序列的说明。
8.模式:用于测试向量的说明。
[79]以上所述1-3项是由ICF(安装与配置文件)利用来自CMD(配置管理数据库)的信息创建,并使得可以在众所周知的位置获得,而4-8项是特定于用户的。这部分提供了以上1-6项的描述;7-8项在部分E中更具体地描述。这些组件中的每一个优选地使用特定的方法与规则开发;这些方法与规则将在这部分中通过例子描述。
A1.资源定义
[80]每个硬件模块提供测试***所使用的一种或多种类型的硬件资源(简单地说是资源)。测试器资源定义优选地用于声明一组用于可用资源类型的资源名及一组参数名和与每种特定资源类型关联的类型。例如,资源名dpin用于指数字测试器引脚。这些资源具有例如VIL(用于输入低电压)、VIH(用于输入高电压)、VOL(用于输出低电压)、VOH(用于输出高电压)等的参数。资源定义文件将具有“.rsc”的后缀。以下所示是例子资源定义,包含一些测试器资源:
           #
           # File Resources.rsc
           #
           Version 0.1.2;
           ResourceDefs
           {
           # digital pins
           dpin
           {
              # Low and High voltages for input pins
              Voltage VIL,VIH;
              # Low and High voltages for output pins
              Voltage VOL,VOH;
          }
          # power supplies
          dps
          {
            #
            # PRE_WAIT specifies the time to wait after voltage
            #     reached its final value to start pattern
            #     generation.The actual time that the system
            #     will wait is a small system specified range:
            #     PRE_WAIT-delta<=actual<=PRE_WAIT+delta
            #
            # PRE_WAIT_MIN is a minimum amount to wait after voltage
            #     reached its final value to start pattern generation.
            #     It is a system specified range:
            #      PRE_WAIT_MIN<=actual<=
       PRE WAIT_MIN+delta
           #
           # POST_WAIT specifies the time to wait after pattern
           #     generation ends to shut down the power.The actual
           #     time that the system will wait is a small systern
           #     defined range:
           #     POST_WAIT-delta<=actual<=POST_WAIT+delta
           #
           # POST_WAIT_MIN specifies the time to wait after pattern
           #     generation ends to shut down the power.The actual
           #     time that the system will wait is a small system
           #     defined range:
           #     POST_WAIT MIN<=actual<=
      POST_WAIT_MIN+delta
           #
           Time PRE_WAIT;
           Time PRE_WAIT_MIN;
           Time POST_WAIT;
           Time POST_WAIT_MIN;
           # The voltage.
           Voltage VCC;
        }
    }
[81]应当指出,资源参数的类型(例如,电压或时间)优选地是标准工程单位。厂商提供的推荐不同参数说明的特定用途资源应当提供他们自己的资源定义文件。
资源定义的结构
[82]以下给出根据本发明优选实施方式的资源定义的结构:
          resource-file:
              version-info resource-defs
          version-info:
              V ersion version-identifer;
          resource-defs:
               ResourceDefs{resource-def-list}
          resource-def-list:
              resource-def
              resource-def-list resource-def
          resource-def:
              resource-name{resource-params-decl-list}
          resource-params-decl-list:
              resource-params-decl
              resource-params-decl-list resource-params-decl
          resource-params-decl:
              elementary-type-name resource-param-name-list;
          resource-param-name-list:
              resource-param-name
              resource-param-name-list,resource-param-name
[83]以下指定以上未定义的非终结符号:
1.version-identifier:从[0-9a-zA-Z]的一个或多个字符的序列。它表示版本号。
2.resource-name:从[a-zA-Z0-9]的一个或多个字符的序列,不能以数字开头。它表示资源名,例如dpin或dps。
3.elementary-type-name:从[a-zA-Z0-9]的一个或多个字符的序列,不能以数字开头。它表示基本类型名,例如Voltage(cf.)。
4.resource-param-name:从[a-zA-Z0-9]的一个或多个字符的序列,不能以数字开头。它表示资源参数名,例如VIL。
A2.测试器配置
[84]测试器配置是一组优选地用于列出特定***配置中站点控制器及站点控制器与开关阵列输入端口连接的规则。在本发明一个实施方式的体系中,单个站点控制器可以连接到单个开关阵列输入端口。因此,在这种环境下,开关阵列连接充当***中站点控制器的隐含标识符(其它配置也是可能的)。以下是典型测试器配置的例子:
      #
      # Tester Configuration,Sys.cfg
      #
      Version 1.2.5;
      SysConfig
      {
         #
         # The first field is the hostname of the Site Controller machine;
         # it can be specified as either a dotted-decimal IP address or a
         # domain-qualified hostname.
         #
         # The second field is the switch matrix input port number,which
         # implicitly serves as the identifier for the Site Controller
         # connected to it.
         #
         zeus.olympus.deities.org  2;
         127.0.0.2                     4;...
         127.0.0.0                     1;# SITEC-1
         127.0.0.3                     3;
      }
[85]用于特定测试层***的***配置是***简介的一部分,而且使得可以作为***配置文件Sys.cfg访问。应当指出,在一种实施方式中,连接到端口1(在以上例子中是“127.0.0.0”)的站点控制器可以享受特定状态,其中它独自配置开关阵列。该“特定”站点控制器将称为SITEC-1。还应当指出,因为站点控制器可以通过内部网连接到***控制器,所以在这个例子中指出的站点控制器是IP地址。相反,***控制器可以连接到外部网,以访问文件,如模式数据。
测试器配置的结构
[86]以下给出根据本发明实施方式***配置文件的结构:
        system-config-file:
            version-info system-config
        version-info:
            Version version-identifer;
       system-config:
           SysConfig{site-controller-connection-list}
       site-controller-connection-list:
           site-controller-connection
           site-controller-connection-list site-controller-connection
       site-controller-connection:
           site-controller-hostname input-port;
       site-controller-hostname:
           ip-address
           domain-qualified-hostname
       ip-address:
          octet.octet.octet.octet
       domain-qualified-hostname:
          name
          domain-qualified-hostname.name
[87]以下指定以上未定义的非终结符号:
1.version-identifier:从[0-9a-zA-Z]的一个或多个字符的序列。它表示版本号。
2.octet:从0到255的非负整数(十进制标记)。
3.name:从[a-zA-Z0-9]的一个或多个字符的序列,不能以数字开头。它表示有域名资格的主机名中的名字片断。
4.input-port:非负整数,十进制标记
A3.模块配置
[88]模块配置允许测试器物理配置的说明,例如***底盘中每个模块的物理位置与类型。测试器总线配置的动态属性使之成为必需,其中测试器总线配置的动态属性允许测试器总线地址到物理槽位置的映射。这种信息允许在***引导时发生的硬件发现处理使***配置有效。开关阵列的每个输出端口定义优选地由单个硬件模块占有的物理槽。以下所示是在根据本发明实施方式的文件Modules.cfg中指定的模块配置的例子:
       #
       # Module Configuration File,Modules.cfg
       #
       Versiou 0.0.1;
       ModuleConfig
       {
         #
         # A configuration definition which provides information about
         # the module type that is attached to slots 1-12 and 32-48.
         # Note that a module might provide more than
         # a single type of resource.
         #
         Slot 1-12,32-48                # Switch matrix output ports
                                         # which use the configuration
                                         # defined below.
         {
            VendorID 1;                 # defined vendor code.
            ModuleID 1;                 # Vendor-defined id code.
            ModuleDriver mod1.dll;      # Module software.
            #
            # Resource named dpin specifies channels
            # for digital data.The name dpin is not
            # a keyword.It is simply the name of a hardware
            # resource,and is obtained from the resource
            # definition file.
            #
            Resource dpin
               {
                  MaxAvailable32;     # Resource units 1..32.
               }
               Resource analog
               {
                  MaxAvailable16;     # Resource units 1..16.
                  Disabled    1-8;    # Disabled resources 1..8.
                                       # So,enabled ones are 9..16.
               }
            }
            #
            # A configuration definition which provides information about
            # the module type that is attached to slots 16-30,50,and 61-64.
            #
            Slot 16-30,50,61-64
            {
               Resource dpin
               {
                  MaxAvailable32;                  # Max available resource
        units.
                  Disabled   3,30-32;             # Disabled resources.
                }
                ModuleDriver″module two.dll″;
                VendorID     2;
                ModuleID     2;
            }
            #
            # A configuration definition,which provides information about
            # the module type that is attached to slots 65-66.
            #
            Slot 65-66
            {
               ModuleID      4;            # DPS module with 8 supplies.
               ModuleDriver      mod4.dll;
               VendorID      1;
               #
               # Resource type dps specifying resource units for a
               # Device Power Supply
               #
               Resource dps
               {
                  MaxAvailable4;
                  Disabled    1;
               }
            }
        }
[89]如前面所提到的,在一种实施方式中,槽指硬件模块可以通过其连接的连接器,如开关阵列的输出端口。每种配置定义提供关于可以连接到一个或多个槽的模块的信息。在配置定义中指定的VendorID是与厂商关联的唯一ID。ModuleID指由该厂商提供的模块的类型。在测试器配置中,可以有相同ModuleID的几个实例。ModuleDriver指为模块提供服务的厂商提供的DLL。最后,Resource指由这个模块提供服务的单元,并提供资源类型的名字;资源名是从资源定义文件获得的。
[90]以上例子描述了模块配置文件中的三个配置模块。在一种实现中,第一个配置块,槽1-12和32-48,是由厂商1生产的模块提供服务的。该厂商提供模块,标识符“1”指这个模块的类型,还提供控制模块的模块驱动器库。这个模块可以提供两种类型的资源单元,一种由资源名“dpin”指示,优选地是总共32个资源单元(即,“通道”),所有这些通道都是可用的,而另一种由资源名“analog”指示,总共16个资源单元,其中只有9至16是可用的。第二和第三个配置块以与第一个配置类似的方式指定。
[91]应当指出,允许通道标记为“disabled”使得可以识别仍然工作的模块上损坏的资源单元。还应当指出,配置块可以具有一个或多个槽标识符。当一个块具有多于一个槽标识符时,所标识的槽被称为是克隆的。
[92]模块配置文件,Modules.cfg,是作为***简介的一部分由ICM(安装配置管理***)(具有用户提供的特定于测试层的信息)创建的,而且使得在众所周知的位置可用。ICM可以是测试***本地的实体,例如在***控制器上,或者也可以驻留在***控制器连接的网络上的某个其它位置。ICM管理CMD(配置管理数据库),并且一般随着***配置的硬件变化而更新。ICM允许用户配置***,例如站点控制器和模块。CMD是存储配置的数据库。对于实际的测试器配置/操作,ICM生成例如模块配置的配置文件和其它文件,并将它们和例如特定模块DLL的相关文件拷贝到测试器上。
模块配置的结构
[93]以下是根据以上优选实施方式的模块配置结构:
            file-contents:
                 version-info module-config-def
             version-info:
                 Version version-identifier;
              module-config-def:
                 ModuleConfig{slot-entry-list}
            slot-entry-list:
                slot-entry
                slot-entry-list slot-entry
            slot-entry:
                Slot positive-integer-list{slot-info}
            slot-info:
                required-config-list
            required-config-list:
               required-config
               required-config-list required-config
            required-config:
               VendorID id-code;
               ModuleID id-code;
               ModuleDriver file-name;
               Resource resource-name{max-spec disabled-specopt}
            max-spec:
               MaxAvailable positive-integer;
            disabled-spec:
               Disabled positive-integer-list;
            positive-integer-list:
               positive-integer-list-entry
               positive-integer-list,positive-integer-list-entry
            positive-integer-list-entry:
               positive-integer
               positive-integer-number-range
            positive-integer-number-range:
               positive-integer-pos-integer
[94]以下指定以上未定义的非终结符号:
1.version-identifier:从[0-9a-zA-Z]的一个或多个字符的序列,其中第一个字符必须是从[0-9]。
2.positive-integer:从[0-9]的一个或多个字符的序列,不能以0开头。
3.id-code:从[a-zA-Z0-9]的一个或多个字符的序列。
4.resource-name:从[a-zA-Z0-9]的一个或多个字符的序列,其中第一个字符必须是从[a-zA-Z]。
[95] 支持注释;注释以“#”字符开头,而且可以延伸到一行的结束。
A4.引脚描述
[96]DUT引脚描述利用引脚描述文件描述。用户使得DUT的描述在引脚描述文件中可用,该文件具有后缀.pin。这个纯文本文件至少包含以下内容:DUT引脚名的列表;及命名引脚组的初始定义,该定义使用所定义DUT引脚名(说“初始”是因为它们以后可以编程性地修改或添加等)。
[97]数据说明与测试计划描述的分离允许DUT引脚定义一般的重用,并允许描述编译器从引脚描述文件导出(分解在向量说明中所使用的引脚名引用所需的)引脚名,而不需要将处理绑定到特定的测试计划。
[98]以下示出的是引脚描述文件的例子:
            #
            # Pin description file,myDUT.pin.
            #
            # Note that this implicitly imports the resource
            # configuration file,Resources.rsc.
            #
            Version 1.1.3a;
            PinDescription
            {
               Resource dpin
               {
                  A0;
                  A1;
                  A2;
                  A3;
                  A4;
                  # This syntax expands to the names″ABUS[1]″
            and″ABUS[2]″
                 ABUS[1:2];
                  A5;
                  BBUS[1:8];
                  DIR;
                  CLK;
                  Group Grp1
                  {
                     DIR,CLK,A0,A1,A2,A3,A4,BBUS[1:4]
                  }
                  Group Grp2
                  {
                     A5,
                     #
                     # The following line will expand to
                     # ″DIR,A1,A2,A4,A5,BBUS[2]″:
                     #
                     Grp1-CLK-A0-A3-BBUS[1]-BBUS[3:4]+A5,
                     BBUS[5:8]
                   }
                }
                Resource dps
                {
                   vcc1;
                   vcc2;
                   vcc3;
                   Group PSG
                   {
                     vcc1,vcc2
                   }
                }
             }
[99]应当指出,DUT引脚与引脚组定义封装在资源类型块中,以便允许编译器关联引脚和引脚组与电平所允许的参数设置等。
[100]应当指出以下关于引脚描述的点:
1.引脚组与引脚共享相同的命名空间并具有全局(即,测试计划)范围。这些名字的全局范围的一个结果是即使当在不同的资源块中声明时,引脚和引脚组也不能使用复制的名字。
2.在引脚描述文件中需要至少一个资源定义。
3.在每个资源中至少应当定义一个引脚名。
4.在资源边界中引脚和组名需要唯一。
5.相同的引脚或组名可以对两个或更多资源定义。但是,相同资源中的复制被忽略。
6.出现在组定义中的所有引脚名与组名应当已经在该资源中定义。
7.如果给出了,则组定义应当具有至少一个引脚名或组名(即,组定义不能为空)。
8.引脚组定义可以包括对已经定义的引脚组的引用。
9.引脚组定义可以包括例如已经定义的引脚和/或引脚组的加减的集合运算。
引脚描述的结构
[101]以下给出的是根据本发明优选实施方式的引脚描述的结构:
           pin-description-file:
               version-info pin-description
           version-info:
               Version version-identifer;
           pin-description:
              PinDescription{resource-pins-def-list}
           resource-pins-def-list:
               resource-pins-def
               resource-pins-def-list resource-pins-def
           resource-pins-def:
               Resource resource-name{pin-or-pin-group-def-list}
           pin-or-pin-group-def-list:
               pin-or-pin-group-def
               pin-or-pin-group-def-list pin-or-pin-group-def
           pindef-or-pin-groupdef:
               pin-def;
               pin-group-def
           pin-def:
               pin-name
               pin-name[index:index]
           pin-group-def:
               Group pin-group-name{pin-group-def-item-list}
           pin-group-def-item-list:
               pin-def
               pin-group-def-item-list,pin-def
[102]以下指定以上未定义的非终结符号:
1.version-identifier:从[0-9a-zA-Z]的一个或多个字符的序列。它表示版本号。
2.resource-name:从[a-zA-Z0-9]的一个或多个字符的序列,不能以数字开头。它表示资源名,如dpin或dps。
3.pin-name:从[a-zA-Z0-9]的一个或多个字符的序列,不能以数字开头。它表示引脚A0的名字。
4.pin-group-name:从[a-zA-Z0-9]的一个或多个字符的序列,不能以数字开头。它表示引脚组ABUS的名字。
5.index:非负整数。它表示相关引脚组的下界或上界。
A5.套接字
[103]套接字指定DUT引脚名与物理测试器引脚(通道)指定(物理测试器通道号在模块配置文件中定义)之间的映射。应当指出,套接字可以用于支持不同的DUT包和不同的加载板配置等。对于多DUT***,用于DUT/通道指定的套接字定义可以支持基本套接字到多个站点的“克隆”。但是,不同的套接字(即,用于相同逻辑引脚的不同物理映射)应当考虑站点模块分区。因此,除了提供DUT引脚到测试器通道指定,套接字还可以有效地定义站点分区。因此,套接字文件可以包含用于几个独立站点套接字的定义。以下所示是定义三个DUT站点的样本套接字文件:
        Version 1.1.3
        SocketDef
        {
           DUTType CHIP3
           {
    PinDescription dutP3.pin;# The pin description file for CHIP3
    DUT 2 # Uses the full-specification syntax
    {
       SiteController 1;# Switch Matrix input port
       Resource dpin
       {
          #
          # The CLK pin is assigned to resource dpin,
          # slot 2,resource unit(channel)13.
          #
          CLK          2.13;
          #
          # The DIR pin is assigned to resource dpin,
          # slot 5,resource unit 15.
          DIR          5.15;
          #
          # The following statement will be expanded to
          #      BBUS[7]    5.4
          #      BBUS[6]    5.5
          #      BBUS[5]    5.6
          #
          # So for example,the pin sequence BBUS[7],BBUS[6],
          # BBUS[5]is assigned to the same slot 5,and to
          # resource units 4,5 and 6 respectively.
          #
          BBUS[7:5]           5.[4:6];
          BBUS[1:4]           7.[21:18];
          BBUS[8]          9.16;
       }
       Resource dps
       {
          #
          # The V1 pin is assigned to resource dps,
          # slot 1,resource unit(channel)1.
          #
          VCC1 1.1;
          #
          # The VCC2 pin is assigned to resource dps,
          # slot 1,resource unit(channel)2.
          #
          VCC2 1.2;
       }
   } # End DUT 2
   DUT 1 # This is″cloned″from DUT 2 above
   {
             SiteController 1; # Same Site Controller as for DUT 2
             Resource dpin
             {
                SlotOffset 1;      # Offset value for slots
              }
              Resource dps
                 SlotOffset 10;# Offset value for slots
              }
              #
              # The offset syntax above indicates that the slot/resource
              # unit assignments are″cloned″from the first DUT defined
              # for this DUTType,i.e.,DUT 2,with the slots offset by
              # the SlotOffset values.
              # Looking at the definition of dpin resource units for
              # DUT 2,CLK is bound to slot 2. Hence,for the present
              # DUT,CLK is bound to slot 2+1=3.
              # Some of the new bindings in effect due to the offset
              # assignments are shown in the table below;
              # ----------------------------------------------------------
              #      Pin         Resource       RUnit       Slot
              # ----------------------------------------------------------
              #      CLK             dpin         13               2+1=
  3
              #      DIR             dpin         15               5+1=
  6
              #      BBUS[8]     dpin          16           9+1=10
              #      VCC1        dps           1            1+10=11
              #      VCC2        dps           2            1+10=11
          } # End DUT1
      } # End DUTType CHIP3
      DUTType 74LS245
      {
         PinDescription dutLS.pin;
         DUT 3 disabled # This DUT site is disabled,and will be
  ignored
          {
             ...
          }
      } # End DUTType 74LS245
  } # End SocketDef
[104]以下关于套接字的点应当注意:
1.套接字文件使用来自模块配置文件和用于给定DUT类型的用户引脚描述文件(见上例中PinDescription的说明)。使模块配置信息对套接字文件编译器隐含可用。套接字文件编译器是模式编译器的子部分,它读取并分析套接字DUT名到测试器通道映射,读取并分析模块配置与引脚描述文件来设置模式编译器所使用的测试器引脚到DUT引脚的映射。
2.每种DUT类型至少需要一个DUT站点定义,而且与SlotOffset语法相反,它必须使用完全说明语法。如果对同一DUT类型提供多于一个DUT站点定义,则第一个必须使用完全说明语法。
3.每个后续的DUT站点定义(对于同一DUT类型)可用使用完全说明语法或者SlotOffset语法,但不能两者都使用。这使得单个站点可能(由于,例如,不起作用的通道)偏离标准模式。
4.偏离SlotOffset语法的绑定是关于为该DUT类型定义的第一个站点(该站点使用完全说明语法)定义的。
5.DUT站点不需要以实际的物理次序声明。这允许第一(物理)站点偏离模式的情况。
6.DUT站点ID需要在整个套接字(即,所有在其中定义的DUT类型)上是唯一的。
7.对每个DUT站点定义需要至少一个资源定义。
8.站点定义必须与模块配置一起使用,以确定测试配置是单站点/单DUT还是单站点/多DUT。
9.在所有情况下,套接字文件都应当指定一组与引脚模式文件和模块配置文件一致的DUT通道映射。
10.在有些情况下,期望允许套接字定义指定一个或多个DUT通道从测试器断开(例如,通过指定所分配物理通道为具有特定ID“0.0”的通道)。在这种情况下,这些DUT通道可在测试环境下使用和参考。这种通道上的操作将导致***警告(但不是错误)。在加载时,将丢弃断开通道的模式数据。
套接字的结构
[105]以下是根据本发明优选实施方式的模块配置的结构:
      socket-file:
          version-info socket-def
      version-info:
          Version version-identifer;
      socket-def:
         SocketDef{device-specific-socket-def-list}
      device-specific-socket-def-list:
          device-specific-socket-def
          device-specific-socket-def-list device-speciftc-socket-def
      device-specific-socket-def:
          DUTType DUT-type-name{pin-description-file dut-info-list}
      pin-description-file:
          PinDesc pin-description-file-name;
      dut-info-list:
          dut-info
          dut-info-list dut-info
      dut-info:
          DUT dut-id{site-controller-input-port resource-info-list}
      site-controller-input-port:
          SiteController switch-matrix-input-port-number;
      resource-info-list:
          resource-info
          resource-info-list resource-info
      resource-info:
          Resource resource-name{resource-item-unit-assignment-list}
      resource-item-unit-assignment-list:
          resource-item-unit-assignment
          resource-item-unit-assignment-list resource-item-unit-assignment
      resource-item-unit-assignment:
         resource-item-name slot-number.resource-unit;
         resource-item-name[resource-item-index]slot-number.resource-
      unit-index;
         resource-item-name[resource-item-index-range]
            slot-number.[resource-unit-index-range];
         resource-item-index-range:
            resource-item-index:resource-item-index
         resource-unit-index-range:
            resource-unit-index:resource-unit-index
[106]以下指定以上未定义的非终结符号:
1.version-identifier:选自集合[0-9a-zA-Z]的一个或多个字符的序列。它不是版本号
2.DUT-type-name:选自集合[0-9a-zA-Z]的一个或多个字符的序列,其中第一个字符不能是选自集合[0-9]。它不是DUT的类型,如CHIP3。
3.pin-description-file-name:简单的文件名,不包括其目录名,但包括所有后缀。文件名具有由主机操作***识别的语法,并且如果包含在引号中,则允许空格和其它字符。
4.switch-matrix-input-port-number:十进制标记的非负整数,表示连接到站点控制器的输入端口的端口号。
5.dut-id:十进制标记的非负整数,识别DUT的实例。
6.resource-name:选自集合[0-9a-zA-Z]的一个或多个字符的序列,其中第一个字符不能选自集合[0-9]。它表示资源文件中所定义的资源的名字。
7.resource-item-name:选自集合[0-9a-zA-Z]的一个或多个字符的序列,其中第一个字符不能选自集合[0-9]。它表示资源单元的名字,例如pin或pin组。
8.resource-item-index:十进制标记的非负整数,表示一组资源项的特定成员。当在resource-item-index-range的环境下时,它表示连续资源项组序列的下或上界。
9.resource-unit-index:十进制标记的非负整数,表示一组资源单元(通道)的特定成员。当在resource-unit-index-range的环境下时,它表示连续资源单元组序列的下或上界。
A6.引脚
[107]应当指出,除了物理通道映射的逻辑引脚名(如由套接字所提供的),几种属性可以用于指定测试器资源。例如,选项可以用于定义通道的特定硬件配置,这可以是特定于测试的、特定于厂商的和/或特定于测试***的。这些将利用引脚模式选项进行描述,并使得可以通过引脚模式选项文件获得。
[108]引脚模式选项定义将支持测试通道的特定选项或模式的配置。例如,这可以用于选择并配置通道复用。由于它可能需要重要的通道配置,因此优选地引脚模式选项只用作测试集合初始化流的一部分。引脚选项语法支持厂商定义的选项。一个例子在下面示出:
            PinModeOptions
            {
               clock    IN       double;
               a0       OUT         single;
               ...
             };
测试环境配置
[109]如前面所指出的资源定义文件(Resources.rsc)、***配置文件(Sys.cfg)与模块配置文件(Modules.cfg)都优选地在“众所周知的”位置可以获得。这种“众所周知的”位置是由***环境变量Tester_ACTIVE_CONFIGS的值指定的目录。例如,如果Tester_ACTIVE_CONFIGS的值是目录F:\Tester_SYS\configs,则***将期望以下文件存在:
F:\Tester_SYS\configs\Resources.rs
F:\Tester_SYS\configs\Sys.cfg
F:\Tester_SYS\configs\Modules.cfg
[110]在安装过程中,驻留在主计算机上的安装与配置管理***(ICM)将优选地设置Tester_ACTIVE_CONFIGS的值。每次当ICM创建以上文件之一的新版本时,它就将新版本放置到由Tester_ACTIVE_CONFIGS指向的位置。应当指出,除了以上三个文件,例如模拟配置文件的其它***配置文件也放置在由Tester_ACTIVE_CONFIGS指向的位置。
B.用于测试程序开发的规则
[111]测试器***的两个主要面向终端用户的组件中的一个是测试环境。另一组件是测试器使之对终端用户(即,测试工程师和测试类开发人员)可用的编程工具。
[112]编程环境的主要组件是测试计划。测试计划使用测试类(这是由Test标记的测试接口的不同实现),该类实现用于特定类型测试的测试数据与代码的分离。
[113]计划可以直接写为C++测试程序,或者在测试计划描述文件中描述,该文件可以由测试程序生成器(翻译器402)处理,以便产生例如C++代码的面向对象代码。然后,所生成的C++代码可以编译成可执行测试程序。构成测试类实例所需的数据,例如电平、定时等,由用户在测试计划描述文件中指定。
[114]测试程序包括一组指定在设备上运行测试的细节的用户书写文件。本发明的实施方式包括允许用户利用C++结构写这些文件的规则集合。
[115]根据本发明实施方式的一个需求是遵循开发体系结构测试***的模块化。模块化开发允许用户写处理测试不同方面的独立组件,然后允许这些组件以多种方式混合与匹配,以输出完整的测试程序。根据本发明优选实施方式的测试程序包括如下一组文件:
用于用户变量和常量的文件*.usrv;
用于说明组的文件*.spec;
用于电平的文件*.lvl;
用于定时的文件*.tim;
用于测试条件组的文件*.tcg;
用于bin定义的文件*.bdefs;
用于定制功能和测试类的文件,用于pre-header的文件*.ph;
用于定制类型的文件*.ctyp;
用于定制变量的文件*.cvar;及
用于测试计划的文件*.tpl。
[116]以上的文件后缀是传统推荐的方便的文件分类。单个测试程序将优选地包括单个测试计划文件及其导入的文件。“导入”指具有或者直接由导入者引用的数据(指定导入的文件)或者由导入者直接引用的某个其它文件导入的数据的其它文件。测试计划文件可以在其中定义全局符、流及其它这种对象,或者它可以从其它文件导入这种信息。这些规则允许任何以上组件或者在其自己的独立文件中,或者直接内联到测试计划文件。应当指出,测试计划在概念上与C语言的main()函数类似。
测试程序特征
用户变量与常量,
说明组,
电平,
定时,
测试条件,
bin定义,
pre-header,
定制类型,
定制变量,
测试计划,
[117]测试程序标识符优选地以大写或小写字母字符开始,后面可以是任何数量的字母、数字或下划线()字符。它具有在以下给出的描述中提供的几个关键词。这些关键字在该文档中利用如Version的粗体可视识别。关键字是保留的,而且优选地不用作标识符。有几个以下描述的特定符合,例如{,}、(,),:及其它。
测试对象的确立
[118]测试描述文件的导入使导入文件能够引用由被导入文件使其可用的对象的名字。这允许导入文件引用被导入文件命名的对象。考虑导入引脚描述文件xxx.pin的套接字文件aaa.soc。可以有也导入xxx.pin的另一bbb.soc文件。但是,这些文件中任何一个都不会使由xxx.pin所描述的对象形成。它们仅仅是引用已经假设存在的对象。
[119]问题就提出来了:这些对象什么时候形成?这就是测试计划文件根本不同的地方。与C类似,它是其中具有main()例程的文件。测试计划文件中的“Import”语句将形成这些对象,即,使这些对象形成。以下所示的测试计划mickey.tpl使得xxx.pin和aaa.soc中的对象形成:
       # File for Mickey’s TestPlan
       Version 3.4.5;
       #
       # These import statements will actually cause the
       # objects to come into existence:
       #
       Import xxx.pin;# Elaborates pin and pin-group objects
       Import aaa.soc;# Elaborates site socket map objects
       # Other imports as necessary
       ...
       Flow Flowl
       {
          ...
       }
[120]测试计划中xxx.pin的导入使得所有在xxx.pin中声明的引脚和引脚组对象形成。这如下描述:“文件xxx.pin形成”。对于测试计划来说,直接导入需要形成的所有文件不是必需的。如果以下两个语句中的任何一个为真,则文件x由文件y导入:
1.y有命名x的导入语句;或
2.x由z导入,而y有命名z的导入语句。
[121]当编译测试计划时,它将在文件中形成由测试计划导入的所有对象。由测试计划导入的文件集合按拓扑结构排序,以便产生文件形成的次序。由测试计划导入的文件集合称为测试计划的导入闭包。如果测试计划的导入闭包不能按拓扑结构排序,则必须有导入循环。这种状态是不正确的,而且将被编译器拒绝。
用户变量与常量
[122]全局变量与常量将利用用户变量与常量定义。常量是其值在编译时绑定而且不能改变的对象。例如,最大整数值将是常量。另一方面,绑定到变量的表达式可以通过API在运行时改变。
整数,
无符号整数,
双精度型,
字符串,
单位为伏特的电压(V),
单位为伏特每秒的电压回转(VoltageSlew)(VPS),
单位为安培的电流(A),
单位为瓦特的功率(W),
单位为秒的时间(S),
单位为米的长度(M),
单位为赫兹的频率(Hz),
单位为欧姆的电阻(欧姆),及
单位为法拉的电容(F)。
[123]类型整数、无符号整数、浮点数与字符串称为基本类型。基本类型没有测试单位。不是基本类型的基础类型是双精度型,它具有相关联的测试单位与比例。比例符号是通用的工程比例符号:
p(pico)是10-12,例如以pF(皮法)为单位
n(nano)是10-9,例如以nS(纳秒)为单位
u(micro)是10-6,例如以uS(微秒)为单位
m(milli)是10-3,例如以mV(毫伏)为单位
k(kilo)是10+3,例如以kOhm(千欧)为单位
M(mega)是10+6,例如以MHz(兆赫)为单位
G(giga)是10+9,例如以GHz(千兆赫)为单位
[124]具有用户变量与常量的独立文件具有后缀.usrv。以下是具有一些全局常量的文件的例子。具有一些变量的文件的例子稍后给出。
      # ----------------------------------------------------------
      # File limits.usrv
      # ----------------------------------------------------------
      Version 1.0.0;
      #
      # This UserVars collection declaration declares a set of
      # globally available variables and constants.
      #
      UserVars
      {
      # Some constant Integer globals used in various places.
      Const Integer    MaxInteger=2147483647;
      Const Integer    MinInteger=-2147483648;
      # Smallest value such that 1.0+Epsilon!=1.0
      Const Double Epsilon=2.2204460492503131e-016;
             # Some important constants related to Double
             Const Double MaxDouble=1.7976931348623158e+308;
             Const Double MinDouble=-MaxDouble;
             Const Double ZeroPlus=2.2250738585072014e-308;
             Const Double ZeroMinus=-ZeroPlus;
           }
[125]以上声明的UserVars的集合被看作是‘=’左边变量的定义。因此,最好是变量或常量的定义仅出现一次,而且应当初始化。
[126]如前面所提到的,常量一旦定义就不应当改变。绑定到常量的表达式可以涉及前面定义的常量和文字值。另一方面,变量可以通过API改变。绑定到变量的表达式可以涉及前面定义的变量、常量和文字值。
[127]每个变量都绑定到在运行时维护的表达式对象。这提供了在运行时改变与变量关联的表达式然后重新求所有变量的值的能力。表达式对象是变量或常量定义右侧的解析形式。在一种实施方式中,没有提供在运行时改变常量的工具。它们的值优选地是在编译时固定的。
[128]具有全局符的任何数量的这种文件可以存在于测试计划的导入闭包中。以上全局文件是一组数字限制,而这里是一组利用工程测量单位的工程全局符及一些随机用户变量:
     # ----------------------------------------------------------
     # File myvars.usrv
     # ----------------------------------------------------------
     Version 0.1;
     #
     # This declares a UserVars collection of some engineering
     # globals.
     #
     UserVars MyVars
     {
        # Enginecring quantities.
        Const Voltage VInLow=0.0;              # 0 Volts
        Const Voltage VInHigh=5.0;             # 5 Volts
        Const Voltage VOutLow=400.0mV;             # 400milliVolts
             Const Voltage VOutHigh=5.1;         # 5.1 Volts
             Const Time DeltaT=2.0E-9;           # 2 nanoseconds
             Const Time ClkTick=1.0ns;       # 1 nanosecond
             Const Resistance R10=10.0 kOhms;    # 10 kilo Ohms
             # Some variables are declared below.
             Current ILow=1.0mA;                    # 1 milliAmp
             Current IHigh=2.0mA;                 # 2 milliAmp
             Power PLow=ILow*VInLow;              # Low power value
             Power PHigh=IHigh*VInHigh;           # High power value
             #
             # An array of low values for all A bus pins.
             # The vil for A0 will be in ABusVil[0],for A1
             # in ABusVil[1],and so on.
             #
             Voltage ABusVil[8]={1.0,1.2,Others=1.5};
           }
[129]编译器优选地检查单位与类型匹配。应当指出,由于电压乘以电流得出功率,因此以上用于PLow和PHigh的等式将编译。但是,如以下的语句一般不编译:
      #
      # Does not compile because a Current and a Voltage cannot be added to
      # yield apower
      #
      Power Pxxx=IHigh+VInHigh
[130]编译器将允许特定的自动类型转换:
           Power Pxxx=2;# Set the power to 2.0watts
           Integer Y=3.6;# Y get assigned 3
           Power Pyyy=Y;# Pyyy get assigned 3.0watts
           Double Z=Pyyy;#Pyyy gets converted to unitless Double
[131]到双精度型、无符号整数和整数的显式类型转换也是允许的:
           Power Pxxx=3.5;
           # Explicit type conversion is allowed,but not required.
           # X becomes 3.5
           Double X=Double(Pxxx);# X becomes 3.5
           Integer Y=Integer(Pxxx);# Y becomes 3
[132]通过转换成中间基本类型,不相关类型之间的转换也是可能的:
           Power Pxxx=3.5;
           # Explicit type conversion is required.
           Length L=Double(Pxxx);# L becomes 3.5 meters
           Voltage V=Integer(Pxxx);# V becomes 3.0 Volts
[133]TestPlan对象提供了UserVars类,该类是包含名字及其关联的表达式、值与类型的集合。用户变量可以进入缺省用户变量集合,或者进入命名用户变量集合。以上例子中没有指定名字的UserVars声明进入缺省集合。但是,有可能显式地如下命名集合:
    # Declare X and Y in the MyVars UserVars collection.
    UserVars MyVars
    {
      Integer X=2.0;
      #
      # Refers to the above X,and to the globally
      # available MaxInteger from the default
      # UserVars collection.
      #
      Integer Y=MaxInteger-X;
   }
   # Declare X,Y1 and Y2 in the YourVars UserVars collection.
   UserVars YourVars
   {
      Integer X=3.0;
      # Refers to the X from MyVars.
      Integer Y1=MaxInteger-MyVars.X;
      #Refers to the X declared above.
      Integer Y2=MaxInteger-X;
   }
   # More variables being added to the MyVars collection
   UserVars MyVars
   {
      #
      # Refers to X and Y from the earlier declaration
      # of MyVars.
      #
      Integer Z=X+Y;
   }
[134]UserVars集合中的名字分解如下进行:
如果名字是合格的—即,名字包括被点分开的两段—则变量来自由点前面的段命名的命名用户变量集合。因此,上面的MyVars.X指MyVars集合中的X。名字“_UserVars”可以用于显式地表示缺省用户变量集合。
[135]如果名字不合格,且当前集合中有同一名字的常量或变量,则名字分解成常量或变量。
[136]否则,名字分解成缺省用户变量集合中的常量或变量。
[137]UserVars集合中定义块的估计可以看作在顺序发生的,从第一个定义到最后一个定义。这可能需要每个变量在其使用之前定义。
[138]此外,对于一个UserVars集合,可以有几个定义块,每个定义块定义几个变量。所有这些定义块都可以看作是按照测试计划中的声明次序进行估计,然后,每个块的变量也以声明次序检查。
[139]最后,可以有几个UserVars集合,每个集合定义几个定义块上的变量。所有变量同样可以看作是以声明次序初始化。因此,在上例中,估计次序将是:MyVars.X、MyVars.Y、YourVars.X、YourVars.Y1、YourVars.Y2、MyVars.Z。
[140]当UserVars集合使用来自另一集合的变量时,它优选地使用该变量的原始值。在集合之间不维护从属信息。因此,基于从属关系的重新估计可以限定到单个集合。
[141]每个用户变量集合都指C++UserVars类的一个实例。C++UserVars类的缺省对象命名为“_UserVars”。UserVars声明中未命名的变量是来自缺省用户变量集合,并添加到这个缺省对象。命名用户变量集合中的变量添加到具有该名字的C++UserVars类对象中。在上例中,“MyVars”C++对象将以变量X、Y和Z结束。
用于用户变量的C++
[142]用户变量实现为n元组的集合,每个n元组具有name串、const/var布尔值、作为枚举值的type和作为表达式树的expression。名字的表达式可以由以下调用设置:
      enum ElemenaryType{UnsignedIntegerT,IntegerT,
                         DoubleT,VoltageT,...};
      Status setExpression(const String&name,const bool isConst,
                               const elemenaryType,
                               const Expression& expression);
[143]类型表达式是对应于赋值右侧的文本的解析形式的类型。有UserVars全局可用的实例。例如,limits.usrv(cf.page)中用户变量的集合由以下所示的调用集合实现:
 _UserVars.setExpression(“MaxInteger”,true,IntegerT,
                           Expression(2147483647));
 _UserVars.setExpression(“MinInteger”,true,IntegerT,
                           Expression(-2147483648));
 _UserVars.setExpression(“Epsilon”,true,DoubleT,
                           Expression(2.2204460492503131c-016));
 _UserVars.setExpression(“MaxDouble”,true,DoubleT,
                           Expression(1.7976931348623158e+308));
 _UserVars.setExpression(“MinDouble”,true,DoubleT,
                           Expression(“-MaxDouble”));
 _UserVars.setExpression(“ZeroPlus”,true,DoubleT,
                           Expression(2.2250738585072014e-308));
 _UserVars.setExpression(“ZeroMinus”,true,DoubleT,
                           Expression(“-ZeroPlus”));
[144]以下是对myvars.usrv中声明的变量所执行的C++语句:
         myVars.setExpression(“VInLow”,true,VoltageT,
                             Expression(0.0));
         myVars.setExpression(“VInHigh”,true,VoltageT,
                             Expression(5.0));
         myVars.setExpression(“DeltaT”,true,TimeT,
                             Expression(2.0E-9));
         myVars.setExpression(“ClkTick”,true,TimeT,
                             Expression(1.0E-9));
         myVsrs.setExpression(“R10”,true,ResistanceT,
                             Expression(10.0E+3));
         myVars.setExpression(“ILow”,false,CurrentT,
                             Expression(1.0E-3));
         myVars.setExpression(“IHigh”,false,CurrentT,
                             Expression(2.0E-3));
         myVars.setExpression(“PLow”,false,PowerT,
                             Expression(“ILow*VInLow”));
         myVars.setExpression(“PHigh”,false,PowerT,
                             Expression(“IHigh*VInHigh”));
         myVars.setExpression(“ABusVil[0]”,false,VoltageT,
                             Expression(1.0));
         myVars.setExpression(“ABusVil[1]”,fall,VoltageT,
                             Expression(1.2));
         myVars.setExpression(“ABusVil[2]”,false,VoltageT,
                             Expression(1.5));
         myVars.setExpression(“ABusVil[3]”,false,VoltageT,
                             Expression(1.5));
         myVars.setExpression(“ABusVil[4]”,false,VoltageT,
                             Expression(1.5));
         myVars.setExpression(“ABusVil[5]”,false,VoltageT,
                             Expression(1.5));
         myVars.setExpression(“ABusVil[6]”,false,VoltageT,
                             Expression(1.5));
         myVars.setExpression(“ABusVil[7]”, false,VoltageT,
                             Expression(1.5));
[145]在以上代码中,Expression类优选地具有表示表达式解析形式的构造函数。Expression有几个构造函数,包括一个取字符串字面量并解析的,还有一个取字符串字面量并只是作为字符串字面量使用的。这是通过为了可读性在以上未指定的附加参数区分的。
[146]缺省用户变量集合中的用户变量将由类UserVars的_UserVars对象管理。命名用户变量集合Xxx中的用户变量将由名字为Xxx的UserVars对象管理。用于UserVars的运行时API
[147] 包含这些名字与表达式的C++UserVars类导出在运行时估计并修改这些值的应用编程接口(API)。与UserVars关联的表达式的修改也解决什么时候UserVars将重新估计和估计有什么影响的问题。
[148]首先考虑作为改变的结果,UserVars的重新估计什么时候应当被触发的问题。如果在对表达式进行改变后立即触发,则用户将不能够在触发重新估计之前进行一系列的相关改变。因此,重新触发是由用户的显式调用触发的。
[149]接下来考虑重新估计的影响。根据优选上述发送,有三种类型可用的重新估计:
[150]UserVars集合重新估计是限定到单个UserVars集合的重新估计。这种操作的语义是再次重新估计这个集合中的所有变量。
[151]UserVars目标重新估计是限定到对绑定到单个名字的表达式改变的重新估计。这将使用户能够改变单个名字的表达式,并使得集合的重新估计只考虑这个特定改变的发生。
[152]UserVars全局重新估计是所有UserVars集合的重新估计。这基本上以声明次序触发所有UserVars集合的重新估计,而且代价相当高。
[153]所有以上重新估计都将在重新估计UserVars之后重新估计例如Levels、Timings等的从属对象。从属对象将具有表示它需要重新估计的dirty位。在任何时候UserVars集合编程性改变时,它都将设置所有从属对象的dirty位。这将触发从属对象的重新估计。
[154]总的来说,命名UserVars集合帮助包含重新估计影响问题。重新估计通常限定到单个集合。使用UserVars的一种简单方式将是仅使用缺省UserVars集合。以这种方式,进行改变的连锁反应可以对所有UserVars发生。这种连锁反应可以限定到几个命名的UserVars集合。
[155]多个集合可以引用彼此的变量,但绑定到变量的值是在使用时绑定的。在UserVars集合之间不维护从属关系。
[156]对于每种基本类型Xxx(无符号整数、电流、电压等),获得值的方法是:
         Status getXxxValue(const String& name,Xxx& value)const;
应当指出,没有直接设置值的方法,它是通过在reevaluateCollection()的调用之后设置表达式的调用完成的。
[157]获得和设置表达式的方法。setExpression()调用还可以用于定义到目前为止还没有定义的新变量。
        enum elementaryType
        {
           UnsignedIntegerT,IntegerT,DoubleT,VoltageT,...
         };
         Status getExpression(const String& name,
                               Expression& expression)const;
         Status setExpression(const String& name,
                               const bool isConst,
                               const elementaryType,
                              const Expression& expression);
[158]setExpression()定义可能在表达式导致循环从属关系的情况下失败。例如,如果进行以下两个调用,则第二个调用将以循环从属错误而失败
      setExpression(“X”,true,IntegerT,Expression(“Y+1”));
      setExpression(“Y”,true,IntegerT,Expression(“X+1”));
这是因为绑定到名字的值是等式而不是赋值。当变量的值改变时,提供重新估计所有直接和间接从属名字的方法。例如以上成对调用的等式导致循环从属关系,这是不允许的。
[159] 应当指出,这个API一般不支持自发的重新估计。对setExpression()的调用不会使变量及依赖它的所有其它变量重新估计。绑定到所有变量的值将保持不变,直到发生对(以下)reevaluateCollection()的调用。
[160]确定特定名字是否为常量的方法是:
          Status getIsConst(const String& name,bool& isConst);
[161]获得类型的方法是:
          enum ElementaryType
          {
             UnsignedIntegerT,IntegerT,DoubleT,VoltageT,...
          };
          Status getType(const String& name,
                        ElementaryType& elementaryType)const;
[162]UserVars集合重新估计方法是
            Status reevaluateCollection();
[163]该类将维护关于所有变量的等式及其从属关系。当这个方法被调用时,所有变量都将重新估计。
[164]UserVars目标重新估计方法是
         Status reevaluateTargeted(const String& var);
[165]该类将维护关于所有变量的等式及其从属关系。当这个方法被调用时,命名变量及所有依赖它的对象都将重新估计。
UserVars全局重新估计方法是
       static Status reevaluateAllCollections();
[166]该类将维护关于所有变量的等式及其从属关系。当这个方法被调用时,以未指定的次序对所有UserVars集合调用reevaluateCollection()。
[167]确定是否定义了特定名字的方法:
         Status getIsDefined(const String& name,bool& isDefined)const;
[168]确定是否所有用户变量当前都定义了的方法:
         Status getNames(StringList& names)const;
[169]删除目前定义的变量的方法:
         Status deleteName(const String& name);
[170]如果名字用在涉及其它变量的表达式中,则这个操作将失败。
获得依赖于给定变量或常量的变量和常量列表的方法:
         Status getDependents(const String& name,StringList& dependents);
说明集
[171]说明集用于提供可以基于选择器取值的变量集合。例如,考虑以下使用选
择器Minnie、Mickey、Goofy和Daisy的说明集。
              # ----------------------------------------------------------
              # File Aaa.spec
              # ----------------------------------------------------------
              Version 1.0;
              Import Limits.usrv;
              SpecificationSet Aaa(Minnie,Mickey,Goofy,Daisy)
              {
                Double xxx=1.0,2.0,3.0,4.0;
                Integer yyy=10,20,3O,40;
                Integer zzz=MaxInteger-xxx,
                               MaxInteger-xxx-1,
                               MaxInteger-xxx-2,
                               MaxInteger-xxx;
               # The following declaration associates a single
               # value,which will be chosen regardless of the
               # selector.It is equivalent to:
               # Integer www=yyy+zzz,yyy+zzz,yyy+zzz,yyy+zzz
               Integer www=yyy+zzz;
             }
[172]以上利用选择器Goofy的说明集将进行以下关联:
         xxx=3.0;
         yyy=30;
         zzz=MaxInteger-xxx-2;
         www=yyy+zzz;
[173]在说明集上设置选择器的操作将在以后描述测试时讨论。
[174]按照句法,说明集是选择器(上例中的Minnie、Mickey、Goofy和Daisy)的列表及变量定义列表(上例中的xxx、yyy、zzz和www)。变量的定义涉及或者与选择器列表一样长或者只包括单个表达式的表达式列表。
[175]从概念上讲,说明集可以看作是表达式阵列,其列是选择器,行是变量,项是表达式。特定的选择器(列)将每个变量(行)绑定到特定的表达式(项)。如果列表具有单个表达式,则表示具有该表达式的行复制与选择器个数一样多的次数。
[176]说明集可以出现在两个独立的环境中。它们可以独立地在.spec文件中说明,在这种情况下它们如上所示出现。这是命名说明集。否则,本地说明集可以在测试条件组中声明。在这种声明中,说明集将没有名字。它将是本地说明集,只对所包含的测试条件组起作用。
[177]命名说明集可以在模仿命名用户变量集合。以上说明集可以建模为命名为Aaa的UserVars集合,该集合将具有用于xxx[Mickey]、xxx[Goofy]、xxx[Daisy]、yyy[Minnie]等的表达式。当在测试环境中选择特定的选择器(例如Mickey)时,xxx、yyy和zzz的值从变量名及说明集名获得。
 [178]测试条件组可以有最多一个说明集,或者是本地说明集,或者是对命名说明集的引用。本地说明集只出现在测试条件组的环境下,而且没有显式指定的名字。这种说明集具有由所包含的测试条件组的名字定义的隐含名字。为了在几个说明集和几个UserVars集合可见的时候在测试条件组中分解名字,应用以下规则:
1.如果名字是合格的,则它必须在命名用户变量集合中分解。
2.如果名字不合格,则如果它在测试条件组中声明,则名字在本地说明集
中分解,而如果是在测试条件组中引用,则名字在命名说明集中分解。
3.如果名字没有被以上规则分解,则在缺省用户变量集合中分解。
[179]为了说明这些规则,考虑以下利用(后述)测试条件组的例子。
           Version 1.2.3;
           Import limits.usrv;# Picks up the limits UserVars file above.
           Import aaa.spec;# Picks up the Specification Set AAA above.
           TestConditionGroup TCG1
           {
              SpecificationSet(Min,Max,Typ)
             {
                vcc=4.9,5.1,5.0;
             }
             # Rule 1:Resolution in a named user variables collection.
             # A reference to MyVars.VInLow refers to VIoLow from MyVars.
             # Rule 2:Resolution in a local specification set.
             # A reference to“vcc”here will resolve in the context
             # of the local specification set above.
             # Rule 3:Resolution in default user variables collection.
             # A reference to“MaxInteger”here will resolve to limits.usrv.
             # Error:Resolution of xxx
             # A reference to xxx does not resolve because it is neither in
             # the loeal specification set,nor in limits.usrv.
             # Error:Resolution of Aaa.xxx
             # Looks for a named UserVars collection named Aaa.The named
             # specification set does not qualify.
         }
         TestConditionGroup TCG2
         {
            SpecificationSet Aaa;# References the imported specification set
            # Rule 1:Resolution in a named user variables collection.
            # A reference to MyVars.VInLow refers to VInLow from MyVars.
            # Rule 2:Resolution in a named specification set.
            # A reference to“xxx”here will resolve in the context
            # of the local specification set Aaa above.
            # Rule 3:Resolution in default user variables collection.
            # A reference to“MaxInteger”here will resolve to limits.usrv.
            # Error:Resolution of vcc
            # A reference to vcc does not resolve because it is neither in
            # tbc named specification set Aaa,nor in limits.usrv.
            # Error:Resolution of Aaa.xxx
            # Looks for a named UserVars collection named Aaa.The named
            # specification set does not qualify.
         }
[180]说明集中名字的分解(以上规则)需要设置的选择器在需要名字分解时使能。这是通过测试条件组将通过指定选择器在测试中被引用的事实实现的。
用于说明集的C++
[181]利用以上规则,说明集可以由C++SpecificationSet类实现。SpecificationSet类具有基本上与UserVars类相同的API,除了用于选择器的额外字符串参数。因此,这个API不具体描述。
[182]所有命名说明集都优选地与该名字的C++对象关联。测试条件组环境中的本地说明集将具有对于该测试条件组唯一的名字。引用一个本地说明集的变量,而该变量处于它在其中定义的测试条件组环境之外,是非法的。
 电平
[183]电平用于指定引脚和引脚组的参数。它是以下形式的声明集合:
                     <pin-or-pin-group-name>
                     {
                        <pin-param-1>=xxx;
                        <Pin-param-2>=yyy;
                        ...
                     }
[184]这种声明指定命名引脚或引脚组的各种参数的设置。例如,如在以下例子中所示的,这种语句可以用于设置InputPins组中所有引脚的VIL值:
      # ----------------------------------------------------------
      # File CHIPlevels.lvl
      # ----------------------------------------------------------
      Version 1.0;
      Import CHIP3resources.rsc;
      Import CHIP3pins.pin;
      Levels CHIP3Levels
      {
         #
         # Specifies pin-parameters for various pins and
         # pin groups using globals and values from
         # the specification set.
         #
         # The order of specification is significant.
         # Pin parameters will be set in order from
         # first to last in this Levels section,and
         # from first to last for each pin or pin-group
         # subsection.
         #
         #From the imported pin description file CHIP3pins.pin,
         #the InPins group is in the“dpin”resource.From the
         # imported resource definition file CHIP3resources.rsc,
         # the“dps”resource has parameters named VIL and VIH.
         #
         InPins{VIL=v_il;VIH=v_ih+1.0;}
         # The following statement requires a delay of 10 uS after
         # the call to set the InPins levels.Actual delay will be
         # a small system defined range around 10.0E-6:
         #      10.0E-6-delta<=actual<=10.0E-6+delta
         Delay 10.0E-6;
         #
         # For the OutPins,the levels for the parameters
         # VOL and VOH are specified.
         #
         OutPins{VOL=v_ol/2.0;VOH=v_oh;}
         # The clock pin will have special values.
         Clock{VOL=0.0;VOH=v_ih/2.0;}
         # A Delay of 10 uS after the call to set Clock levels.
         # This is a minimum delay,that is guaranteed to be for
         # at least 10.0 uS,though it may be a little more:
         #       10.0E-6<=actual<=10.0E-6+delta
         MinDelay 10.0 uS;
         #
         # The PowerPins group is in the“dps”resource. Pins of this
         # pin group have special parameters:
         # PRE_WAIT specifies the time to wait after voltage
         #     reached its final value to start pattern
         #     generation. Actual wait time will be a small
         #     system defined range around PRE_WAIT (see)
         #  POST_WAIT specifies the time to wait after pattern
         #     generation ends to shut down the power.Actual
         #     wait time will be a small system defined range
         #     around PRE_WAIT(see).
         #
         PowerPins
         {
           PRE_WAIT=10.0 ms;
           POST_WAIT=10.0 ms;
           # VCC reaches its final value of 2.0 V from its
           # present value in a ramp with a Voltage Slew Rate
           # of±.01 Volts per Second.
           VCC=Slew(0.01,2.0 V);
        }
     }
     Levels CHIP4Levels
     {
        #...
     }
[185]如上面所看到的,每个Level块都优选地由多个level项构成,每个level项指定一个引脚或引脚组的参数。每个level项可以指定多个资源参数。用于设置这些level值的运行时语义如下:
[186]Level块的level项是以声明次序处理的。在多于一个Level项中出现的任何引脚都将被处理多次。用于单个参数的多个值说明应当以说明次序维护并应用。
[187]Level项中的资源参数以它们被指定的次序处理。
[188]在设置下一组电平时,Delay语句使设置电平的处理暂停大约所指示的持续时间。实际的等待时间可以在大约所指定延迟的小***定义范围之内。因此,如果延迟t秒,则实际的延迟将满足:
     t-Δt<=实际等待<=t+Δt
[189]Delay语句将Level说明分成多个子序列,每个子序列将需要独立测试条件存储器设置来处理。
[190]MinDelay语句使设置电平的处理在设置下一电平组之前暂停至少所指定的持续时间。实际的等待时间可以在具有所指定最小延迟的最小值的小的***定义范围之内。因此,如果最小延迟是t秒,则实际的延迟将满足:
     t<=实际等待<=t+Δt
[191]MinDelay语句将Level说明分成多个子序列,每个子序列将需要独立测试条件存储器设置来处理。
[192]每个引脚或引脚组名字精确地在引脚描述文件(suffix.pin)中的一个资源中指定,因此具有在资源文件(suffix.rsc)中指定的特定的可行资源参数集合。所有命名的参数必须来自这个可行的资源参数集合中,而且必须具有与用于设置其值的表达式相同的基本类型。关于资源参数的名字与类型的信息来自资源文件。
[193]资源文件Resources.rsc隐含导入,向测试器提供如dpin和dps的标准资源的参数的名字与类型。
[194]资源参数是可以使用UserVars及来自命名说明集或当前可视本地说明集的值的所分配表达式。
[195]Dps引脚资源具有特定的参数PRE_WAIT和POST_WAIT。PRE_WAIT参数指定从电源引脚达到其目的电压的时间到模式生成可以开始的时间所需要经过的时间段。POST_WAIT参数指定从模式生成停止的时间到电源引脚切断所需要经过的时间段。
[196]Dps引脚还指定电压参数如何到达其最终的值。它们可以简单地提供等式指定它,就象所有其它的引脚参数。在那种情况下,所述值将到达硬件所允许的值。它们还可以利用回转语句指定它。回转语句指定电源电压以具有指定绝对电压回转速度的斜率从初始值达到其最终值。
用于Levels的C++
[197]利用以上规则,C++Levels对象可以写成支持以下操作:有一种操作
    Status setParameter(const String& pinOrPinGroupName,
                       const String& parameterName,
                       ElementaryType elementaryType,
                       const Expression& Expression);
[198]这个操作将表达式绑定到引脚或引脚组的参数。例如,dpin.InPins VIH值由以下操作设置:
     setParameter(”InPins”,”VIH”,VoltageT,Expression(”v_ih+1.0”));
[199]对于Level对象中的所有声明,这个操作将调用几次。
有一种操作
  Status assignLevels(const String& selector);
如前面所描述的,该操作将通过并产生所有预定义的模块级接口以说明次序分配所有的参数电平。选择器参数用于根据前面所指定的规则分解表达式中的名字。
测试条件组
[200]测试条件组子语言将说明、定时与电平的描述包装在一起。定时对象常常利用参数指定。参数可以在定时中用于指定各种脉冲的上升边缘和下降边缘。同样,电平可以通过指定各种电压电平的最大、最小和一般值来参数化。测试条件组(TCG)对象根据这些说明将定时与电平的说明与实例化汇总到一起。
[201]TestConditionGroup声明包含可选的SpecificationSet。SpecificationSet声明可以是内联的(及未命名的)本地SpecificationSet,或者它也可以是对在其它地方声明的命名SpecificationSet的引用。TCG声明中可选的SpecificationSet声明后面跟着至少一个Level或Timing声明。它可以以任何次序既有Level又有Timing。但是,不允许有多于一个Level和Timing声明。这些约束是通过句法实施的。
[202]除了没有名字,TCG中的说明集声明与独立声明的声明设置完全一样。它的名字隐含地是包含它的TCG的名字。Timing声明包括来自指定定时文件的Timing对象的单个声明。这里是具有测试条件组的文件的例子:
    # ----------------------------------------------------------
    # File myTestConditionGroups.tcg
    # ----------------------------------------------------------
    Version 0.1;
    Import CHIPlevels.lvl;
    Import edges.spec;
    Import timing1.tim;
    Import timing2.tim;
    TestConditionGroup TCG1
    {
       # This Local SpecificationSet uses user-defined selectors
       #“min”,“max”and“typ”.Any number of selectors with any
       # user defined names is allowed.
       #
       # The specification set specifies a table giving values for
       # variables that can be used in expressions to initialize
       # timings and levels.The specification set below defines
       # values for variables as per the following table:
       #      min     max    typ
       # v_cc   2.9     3.1    3.0
       # v_ih vInHigh+0.0  vInHigh+0.2 vInHigh+0.1
       # v_il vInLow+0.0 vInLow+0.2 vInLow+0.1
       # ...
       # A reference such as“vInHigh”must be previously defined
       # in a block of UserVars.
       #
       # Thus,if the“max”selector was selected in a functional
       # test,then the“max”column of values would beund to
       # the variables,setting v_cc to 3.1,v_ih to vInHigh+2.0
       # and so on.
       #
       # Note that this is a local specification set,and has no
       # name.
       Specification Set(min,max,typ)
       {
          # Minimum,Maximum and Typical specifications for
          # voltages.
          Voltage v_cc=2.9,3.1,3.0;
          Voltage v_ih=vInHigh+0.0,
                        vInHigh+0.2,
                        vInHigh+0.1;
          Voltage v_il=vInLow+0.0,
                        vInLow+0.2,
                        vInLow+0.1;
          # Minimum,Maximum and Typical specifications for
          # leading and trailing timing edges.The base
          # value of 1.0E-6 uS corresponds to 1 picosecond,
          # and is given as an example of using scientific
          # notation for numbers along with units.
          Time t_le=1.0E-6 uS,
                1.0E-6 uS+4.0*DeltaT,
                1.0E-6 uS+2.0*DeltaT;
          Time t_te=30ns,
                     30ns+4.0*DeltaT,
                     30ns+2.0*DeltaT;
    }
    # Refere to the CHIP3Levels imported earlier.It
    # is one of possibly many levels objects that have been
    # imported from the above file.
    Levels CHIP3Levels;
       # Refers to file timing1.tim containing the single
       # timing Timing1.The filename should be quoted if
       # it has whitespace characters in it.
       Timings Timing1;
    }
    # Another test condition group
    TestConditionGroup TCG2
    {
       # ClockAndDataEdgesSpecs is a specification set which
       # is available in the edges.specs file. Assume it has
       # the following declaration:
       #   SpecificationSet ClockAndDataEdgesSpecs(min,max,typ)
       #   {
       #      Time clock_le=10.00 uS,10.02 uS,10.01 uS;
       #      Time clock_te=20.00 uS,20.02 uS,20.01 uS;
       #      Time data_le=10.0 uS,10.2 uS,10.1 uS;
       #      Time data_te=30.0 uS,30.2 uS,30.1 uS;
       # A SpecificationSet reference to this named set is below:
       SpecificationSet ClockAndDataEdgesSpecs;
       # An inlined levels declaration.Since the associated
       # specification set (above) does not have variables such
       # as VInLow,VInHigh,VOutLow and VOutHigh,they must
       # resolve in the default UserVars collection.
       Levels
       {
          InPins{VIL=VInLow;VIH=VInHigh+1.0;}
          OutPins{VOL=VOutLow/2.0;VOH=VOutHigh;}
       }
       # This Timing is from the file“timing2.tim”.The timings
       # will need the leading and trailing edge timings for clock
       # and data as specified in the above specificaion set.
       Timings Timing2;
[203]在以上例子中,测试条件组TCG1描述了具有名字为“min”、“typ”和“max”的三个选择器的说明集。可以有任何数量不同的选择器。在说明集的主体中,对应于选择器,变量v_il、v_ih、t_le和t_te以值的三元组初始化。因此,在以上例子中,TCG1具有选择器“min”的实例将绑定变量v_il具有第一数字值(vInputLow+0.0)。它支持用于说明集的选择器是用户定义的重复,而且允许任何次数的重复。唯一的要求是:
[204]说明集的选择器是唯一的标识符。
[205]在说明集中指定的每个值与精确地是与选择器集合元素个数相同的值数组关联。挑选第i个选择器将使每个值绑定到其关联的值向量的第i个值。
[206]在TCG中的说明集之后,可以有Level声明或Timing声明或两者都有。Level声明用于设置各种引脚参数的电平。在说明集中识别的变量将用于设置这些电平,以便允许用于引脚参数的不同实际值基于用于初始化TCG的选择器的动态绑定。
[207]为了示例说明,考虑启用选择器“min”的测试。参考页面上给出的说明集CHIP3Level,用于InPins组中引脚的引脚参数“VIH”将通过以下声明被初始化成表达式(v_ih+1.0):
InPins{VIL=v_il;VIH=v_ih+1.0;}
[208]当选择器“min”启用时,这分解成(VinHigh+0.0+1.0)。同样,Timing对象可以基于说明集变量所选的值初始化。没有必要同时具有Timing和Level声明。如由以下例子所说明的,每个都可以自己出现,或者以任何次序同时出现。
      # ----------------------------------------------------------
      # File LevelsOnlyAndTimingsOnly.tcg
      # ----------------------------------------------------------
      Version 0.1;
      # A Levels-only Test Condition Group.
      TestConditionGroup LevelsOnlyTCG
      {
         SpecificationSet(Min,Max,Typ)
         {
            Voltage v_il=0.0,0.2,0.1;
            Voltage v_ih=3.9,4.1,4.0;
         }
         # An inlined levels declaration.Since the associated
         # specification set(above)does not have variables such
         # as VInLow,VInHigh,VOutLow and VOutHigh,they must
         # resolve in the default UserVars collection.
         Levels
              {
                 InPins{VIL=v_il;VIH=v_ih+1.0;}
                 OutPins{VOL=v_il/2.0;VOH=v_ih;}
              }
          }
          # A Timings-only Test Condition Group
          TestConditionGroup TimingsOnlyTCG
          {
             SpecificationSet(Min,Max,Typ)
             {
               Time t_le=0.9E-3,1.1E-3,1.0E-3;
              }
              Timings Timing2;
           }
[209]但是,应当指出,在一个TCG中不应当有多于一个Timing和多于一个Level。因此,总的来说,应当有至少一个Timing或Level,且每个至多有一个。
测试条件
[210]TestCondition对象将TCG绑定到特定的选择器。一旦TCG已经如上所示进行了声明,则有可能如下所示声明TestCondition对象:
          TestCondition TCMin
          {
             TestConditionGroup=TCG1;
             Selector=min;
          }
          TestCondition TCTyp
          {
             TestConditionGroup=TCG1;
             Selector=typ;
          }
          TestCondition TCMax
          {
              TestConditionGroup=TCG1;
              Selector=max;
          }
[211]这些测试条件将在测试计划中如下实例化:
       #
       # Declare a FunctionalTest“MyFunctionalTest”that refers to three
       # Test Condition Group instances.
       #
       Test FunctionalTest MyFunctionalTest
       {
          # Specify the Pattern List
          PList=patlAlist;
          # Any number of TestConditions can be specified:
          TestCondition=TCMin;
          TestCondition=TCMax;
          TestCondition=TCTyp;
       }
在TCG(测试条件组)中命名分解
[212]测试条件组中名字的分解在前面已经讨论过了。但是,这些规则可以重复,而且以下再次给出:
1.如果名字是合格的(cf.page),则它必须在命名用户变量集合中分解。
2.如果名字不合格,则如果它在测试条件组中声明,则名字在本地说明集中分解,而如果是在测试条件组中引用,则名字在命名说明集中分解。
3.如果名字没有被以上规则分解,则在缺省用户变量集合中分解。
TCG运行时
[213]测试条件组具有以下运行时语义:
[214]利用实例化的TestCondition,测试(如FunctionalTest)将引用具有来自其SpecificationSet的特定选择器的TCG。这种选择器将SpecificationSet中的每个变量绑定到其与所选选择器关联的值。然后,变量与其值的绑定将用于确定Levels和Timings。
[215]TestConditionGroup中的参数Level优选地以Level块中出现的次序顺序设置。因此,在CHIP3Level块中,参数电平设置的次序如下(符号:
<resource-name>.<resource-parameter>):
    InputPins.VIL,
    InputPins.VIH,
    OutputPins.VIL,
    OutputPins.VIH,
    Clock.VOL,
    Clock.VOH.
[216]这种顺序的次序使测试写程序看着电源的形式供点顺序。此外,如果电平项出现两次,即为一个引脚命名相同的引脚参数,则该引脚参数被设置两次。这也可以编程发生。
[217]如果参数由Slew语句设置,如
         VCC=Slew(0.01,2.0V);
其意味着VCC将从其当前值以具有每秒±0.01伏特的电压回转速度的斜率达到其2.0伏特的最终值。
[218]说明集变量也可以传递到TCG中的Timings对象。然后,Timings对象将基于所选的变量初始化。例如,通过指定波形的上升边缘和下降边缘,这种机制可以用于定制Timings对象。
用于TCG的C++
[219]利用以上规则,测试条件组可以在C++TestConditionGroup类中声明并如下初始化:
[220]进行对TestConditionGroup成员函数的调用
         Status setSpecificationSet(SpecificationSet*pSpecificationSet);
该函数将设置TestConditionGroup的说明集。这可以是本地说明集,或者命名说明集,或者为空(如果都没有)。
[221]进行对TestConditionGroup成员函数的调用
          Status setLevels(Levels*pLevels);
该函数将设置TestConditionGroup的Level对象。这可以是局部声明的Level对象,或者是外部声明的Level对象,或者为空(如果都没有)。
[222]进行对TestConditionGroup成员函数的调用
           Status setTimings(Timings*pTimings);
该函数将设置TestConditionGroup的Timings对象。这可以是局部声明的Timings对象,或者为空(如果都没有)。
Bin定义
[223]Bin定义类定义Bin,即概括测试许多DUT的结果的计数器的集合。在测试DUT的过程中,DUT可以设置成任何bin,例如,指示特定测试的结果。在测试进行中,DUT可以设置成其它bin。DUT最终设置成的bin是在测试结束时所设置的最后一个。这种最终bin的计数器在这个DUT的测试结束时递增。具有bin定义的独立文件应当具有后缀.bdefs。
[224]Bin定义优选地是分层的。例如,在最外面的一层,可以有具有名字为Pass和Fail的两个bin的PassFailBins。然后,可以有几个HardBins,其中一些映射到Pass bin,其它则映射到Fail bin。HardBins被认为是PassFailBins的求精。最后,可以有大量的SoftBins,它们是HardBins的求精,其中很多映射到相同的HardBin。以下是说明bin层次的例子。
     # ----------------------------------------------------------
     # File CHIPbins.bdefs
     # ----------------------------------------------------------
     Version 1.2.3;
     BinDefs
     {
       # The HardBins are an outermost level of
       # bins.They are not a refinement of any other
       # bins.
       BinGroup HardBins
       {
        “3GHzPass”:“DUTs passing 3GHz”;
        “2.8GHzPass”:“DUTs passing 2.8GHz”;
        “3GHzFail”:“DUTs failing 3GHz”;
        “2.8GHzFail”:“DUTs failing 2.8GHz”;
         LeakageFail:“DUTs failing leakage”;
       }
       # The SoftBins are a next level of refinement.
       # SoftBins are a refincment of HardBins.
       BinGroup SoftBins:HardBins
       {
         “3 GHzAllPass”:
               “Good DUTs at 3GHz”,“3GHzPass”;
         “3 GHzCacheFail”:
               “Cache Fails at 3GHz”,“3GHzFail”;
         “3 GHzSBFTFail”:
               “SBFT Fails at 3GHz”;“3GHzFail”;
         “3GHzLeakage”:
               “Leakages at 3GHz”,LeakageFail;
         “2.8GHzAllPass”:
               “Good DUTs at 2.8GHz”,“2.8GHzPass”;
         “2.8GHzCacheFail”:
               “Cache Fails at 2.8GHz”,“2.8GHzFail”;
         “2.8GHzSBFTFail”:
               “SBFT Fails at 2.8GHz”,“2.8GHzFail”;
         “2.8GHzLeakage”:
               “Leakages at 2.8GHz”,LeakageFail;
          }
        }
[225]在以上例子中,最基本的bin是BinGroup HardBins。如果某个其它BinGroup是X的求精,则BinGroup X被看作是一组基本bin。因此,由于BinGroup SoftBins是HardBins的求精,所以BinGroup HardBins是一组基本bin。如果没有其它BinGroup是Y的求精,则BinGroup Y被看作是一组leafbin。
[226]其中具有单个BinGroup Z的BinDefs块的退化情况将使Z为一组最基本的bin及一组leafbin。BinGroup名字是全局范围的。可以有任何数量的BinDefs块,但所声明的BinDefs必须是独特的。来自一个BinDefs块的BinGroup允许来自另一BinDefs块的BinGroup的求精。因此,在以上例子中,SoftBins可以在与HardBins独立的BinDefs块中。但是,为了可读性,强烈推荐定义所有BinGroup的单个BinDefs块。
[227]现在,通过添加另一BinGroup,以上层次可以扩展成计算有多少DUT通过和失败。
 # ----------------------------------------------------------
 # File CHIPbins.bdefs
 # ----------------------------------------------------------
 Version 1.2.3;
BinDefs
{
  # The PassFailBins are an outermost level of
  # bins.They are not a refinement of any other
  # bins.
  BinGroup PassFailBins
  {
    Pass:“Count of passing DUTS.”;
    Fail:“Count of failing DUTS.”;
  }
  # The HardBins are a next level of refinement.
  # HardBins are a refinement of the PassFailBins,
  # as indicated by“HardBins:PassFailBins”.
  BinGroup HardBins:PassFailBins
  {
   “3GHzPass”:“DUTs passing 3GHz”,Pass;
   “2.8GHzPass”:“DUTs passing 2.8GHz”,Pass;
   “3GHzFail”:“DUTs failing 3GHz”,Fail;
   “2.8GHzFail”:“DUTs failing 2.8GHz”,Fail;
   LeakageFail:“DUTs failing leakage”,Fail;
  }
  # The SoftBins are a next level of refinement.
  # SoftBins are a refinement of HardBins.
  BinGroup SoffBins:HardBins
  {
   “3GHzAllPass”:
        “Good DUTs at 3GHz”,“3GHzPass”;
   “3GHzCacheFail”:
        “Cache Fails at 3GHz”,“3GHzFail”;
   “3GHzSBFTFail”:
        “SBFT Fails at 3GHz”,“3GHzFail”;
   “3GHzLeakage”:
         “Leakages at 3GHz”,LeakageFail;
   “2.8GHzAllPass”:
         “Good DUTs at 2.8GHz”,“2.8GHzPass”;
   “2.8GHzCacheFail”:
         “Cache Fails at 2.8GHz”,“2.8GHzFail”;
   “2.8GHzSBFTFail”:
         “SBFT Fails at 2.8GHz”,“2.8GHzFail”;
   “2.8GHzLeakage”:
         “Leakages at 2.8GHz”,LeakageFail;
[228]这次,最基本的bin是BinGroup PassFailBins。它们一般不是任何bin的求精。BinGroup HardBins是PassFailBins的求精,而且也是基本bin。SoftBins是HardBins的求精,而且是一组leafbin。
以上例子的层次中只有三个BinGroup。以下是更复杂的层次。
       BinDefs
       {
         # A group of most base bins
        BinGronp A{...}
         # Agroup of base bins that is a refinement of A
        BinGroup Ax:A{...}
         # A group of leaf bins that is a refinement of Ax
        BinGroup Axx:Ax{...}
         # A group of base bins that is a refinement of A
        BinGroup Ay:A{...}
         # A group of leaf bins that is a refinement of Ay
        BinGroup Ayy:Ay{...}
         # A group of most base bins
        BinGroup B{...}
         # A group of leaf bins that is a refinement of B
        BinGroup Bx:B{...}
      }
[229]在这个例子中,Ax和Ay是A的求精,Axx是Ax的求精,而Ayy是Ay的求精。这个例子还提供了BinGroup B和Bx,其中Bx是B的求精。以上具有名字为PassFailBins、HardBins和SoftBins的BinGroup的BinDefs声明将在这部分中继续用作例子。
[230]BinGroup中的每个bin具有:
1.或者是标识符或者是字符串文字的名字
2.描述这个bin概括什么的说明
3.如果这个bin是在求精的BinGroup中,则它求精的bin的名字也称为基本bin。
[231]PassFailBins中的两个bin名字为“Pass”和“Fail”。HardBins中的五个bin名字为“3GHzPass”、“2.8GHzPass”、“3GhzFail”、“.8GhzFail”、“LeakageFail”。Bin名字可以是文字字符串,或者是标识符。Bin名字在BinGroup中必须唯一,但不同BinGroup之间可以重复。但是,BinGroup名字是全局范围的,而且必须在整个测试计划中唯一。
[232]在五个HardBins中,“3GHzPass”和“2.8GHzPass”都映射到PassFailBins的“Pass”bin。剩余的HardBins映射到PassFailBins的“Fail”bin。
[233]最后,有八个SoftBins。用于SBFT(soft bin功能测试)和高速缓冲存储器在3GHz的两个失败映射到“3GhzFail”HardBin。同样,用于SBFT和高速缓冲存储器在2.8GHz的两个失败映射到“2.8GhzFail”HardBin。由于泄漏造成的两个失败都映射到相同的“LeakageFail”HardBin,而不管它们发生的速度。例如,最粗的测试(在最外面的级)是DUT通过还是未通过测试。例如,求精是DUT以特定频率,例如3Hz等,通过还是未通过测试。
[234]如下面所描述的,bin分配给测试计划流项(Test Plan FlowItem)中的DUT。测试计划流项具有结果子句,其中测试计划描述作为从执行测试而获得特定结果的结果所发生的动作与变化。在这个时候,SetBin语句可以发生:
    # A FlowItem Result clause.It is described later.
    Result 0
    {
       # Action to be taken on getting a 0 back from
       # executing a test.
       # Set the bin to SoftBin.“3GHZPass”expressing that the
       # DUT was excellent.
       SetBin SoftBins.“3GHzPass”;
    }
[235]许多SetBin语句可以在对DUT运行测试的过程中执行。当测试最终完成时,运行时将递增用于为该DUT和为所有其求精设置的final bin的计数器。
考虑具有在其测试过程中执行的以下SetBin语句的DUT:
          SetBin SoftBins.”3GHzSBFTFail”;
          SetBin SoftBins.”2.8GHzAllPass”;
[236]这个DUT通过3GHz的高速缓冲存储器与泄漏测试,但没有通过SBFT测试,因此分配给”3GHzSBFTFail”bin。然后,在2.8GHz进行测试,所有测试都通过。因此,最终bin分配是SoftBins集合中的”2.8GHzAllPass”。这个最终分配将递增以下bin的计数器:
1.SoftBins.”2.8GHzAllPass”
2.HardBins.”2.8GHzPass”的求精
3.PassFailBins.”Pass”的求精
[237]当测试完成时,运行时将递增该DUT的最终bin分配和所有其求精的其它bin的计数器。
[238]SetBin只允许对leaf bin进行。设置基本bin是非法的。以上计数器递增语义假设:
1.如果bin是leafbin,则是测试DUT结束时对该bin执行的SetBin语句的次数。
2.如果bin是基本bin,则是其求精的bin的计数器之和。
[239]因此,在以上例子中,在SetBin语句中只允许SoftBins。用于HardBins.”LeakageFail”的计数器是用于SoftBins.”3GHzLeakageFail”与SoftBins.”2.8GHzLeakageFail”的计数器之和。以下是关于bin定义的一些规则:
1.BinDefinitions声明包括几个BinGroup声明。
2.每个BinGroup声明都有名字及作为其求精的可选BinGroup名,后面是bin声明的一个块。
3.bin声明包括名字,后面是描述,可选地还跟着该bin是其求精的基本bin的名字。
4.bin名可以是字符串文字,或者是ID。空字符串不应当是有效的bin名。bin名应当在BinGroup声明的名字中唯一,但相同的名字可以在其它BinGroup声明中使用。
5.如果BinGroup声明Xxx是另一BinGroup声明Yyy的求精,则Xxx中的所有bin声明必须声明来自Yyy的基本bin的名字。因此,因为SoftBins声明为HardBins的求精,所以SoftBins中每个bin声明都是HardBins的bin的求精。
6.不是其它BinGroup声明的求精的BinGroup声明,例如PassFailBins,将优选地具有不声明基本bin的bin声明。
[240]binBbb具有一组Bbb是其求精的整个bin集合的base。它在形式上如下定义:
1.如果Aaa是Bbb的基本bin,则Aaa在Bbb的base集合中。
2.Aaa的任何base都在Bbb的base集合中。
[241]BinGroup名字在TestPlan中是全局的。
[242]bin名字对BinGroup是局部的。
[243]SetBin语句只允许对leaf bin进行。
用于bin定义的C++
[244]利用以上规则,可以为BinDefs声明中的每个BinGroup声明构造对象类型BinGroup。类BinGroup将具有子类LeafBinGroup。除了BinGroup::incrementBin是C++受保护操作,而LeafBinGroup::incrementBin是C++公有操作,这两个类的其它操作是相同的。
[245]以下是建立BinGroup或不是任何其它BinGroup求精的LeafBinGroup的缺省构造函数。
[246]构造函数:
         BinGroup(BinGroup& baseBinGroup);
         LeafBinGroup(BinGroup& baseBinGroup);
建立作为给定baseBinGroup的求精的baseBinGroup。
[247]一种方法
         Status addBin(const String& binName,
                       const String& description,
                 const String& baseBinName);
定义bin及其描述。如果它是最基本的bin,则baseBinName参数必须是空字符串。
[248]递增bin计数器的方法:
          Status incrementBin(cosnt String& binName);
这个操作将递增用于这个bin和用于作为该binbase的所有bin的计数器。这个操作在类BinGroup中是受保护的,而在类LeafBinGroup是公有的。
[249]复位bin计数器的方法:
          Status resetBin(const String& binName);
这个操作将复位用于该bin和用于作为该binbase的所有bin的计数器。
[250]获得关于bin的信息的方法:
         Status getBinDescription(const String& binName,String& description);
         Status getBaseBin(const String& binName,
                           BinGroup*pBaseBinGroup,
                           String& baseBinName);
         Status getBinValue(const String& binName,unsigned int& value);
[251]提供迭代器来获得所有当前定义的bin名字。
[252]TestPlan声明将包括BinGroup成员的个数,每个BinGroup声明一个。用于以上BinDefinitions的C++将如下:
   //TestPlan constructor
   TestPlan::TestPlan()
   :m_PassFailBins(),//Default Constructor
    m_HardBins(&m_PassFailBins),
    m_SoftBins(&m_HardBins)
   {}
   // Bin initializations
   m_PassFailBins.addBin(“Pass”,“Count of passing DUTS.”,“”);
   m_PassFailBins.addBin(“Fail”,“Count of failing DUTS.”,“”);
   m_HardBins.addBin(“3GHzPass”,“Duts passing 3GHz”,“Pass”);
   ...
[253]TestPlan的声明包括初始化为未定义BinGroup(NULL)的m_pCurrentBinGroup和初始化为未定义bin名(空字符串)的m_currentBin。每次当执行SetBin语句时,通过调用,将m_pCurrentBinGroup改变成指示BinGroup的名字,而m_currentBin改变成指示组中的命名bin:
     //Translation of:SetBin SoftBins.”3GHzAllPass”;
     pTestPlan->setBin(“SoftBins”,“3GHzAllPass”);
[254]当测试计划完成执行时,它将调用
            m_pCurrentBinGroup->incrementBin(m_currentBin);
使得这个bin和所有其基本bin都递增它们的计数器。
[255]当设计好测试计划时,测试计划BinGroup计数器复位,但不会在每次运行测试时重新初始化。计数器可以通过对BinGroup::resetBin的显式调用复位。
C.测试计划
[256]测试计划可以看作是测试程序的主要结构。测试计划可以导入文件及定义类似的构造内联函数。因此,有可能导入给出一些全局符定义及声明附加全局符内联函数的文件。
C1.测试计划流程与FlowItem
[257]测试计划的一个关键元素是流。流封装了有限状态机。它包括运行IFlowable对象然后转换到另一FlowItem的几个FlowItem。运行IFlowable涉及运行实现IFlowable接口的对象。实现IFlowable接口的典型对象是Test与Flow本身。
[258]因此,流程具有运行Test与其它流程,然后转换成另一FlowItem的FlowItem。它还提供对从运行IFlowable返回的各种结果调用用户定制例程的机会。一般来说,Flow具有以下形式:
       #
       # FlowTest1 implements a finite state machine for the
       # Min,Typ and Max flavors of MyFunctionalTest1.On
       # success it tests Test1Min,Test1Typ,Test1Max
       # and then returns to its caller with 0 as a successful
       # status.On failure,it returns 1 as a failing status.
       #
       # Assume that the tests MyFunctionalTest1Min,...all
       # return a Result of 0(Pass),1 and 2(for a couple
       # of levels of failure).
       #                   Result 0       Result 1       Result 2
       #  Test1Min         Test1Typ       return 1       return 1
       #  Test1Typ         Test1Max       return 1       return 1
       #  Test1Max         return 0       return 1       return 1
       Flow FlowTest1
       {
          FlowItem FlowTest1_Min MyFunctionalTest1Min
          {
             Result 0
             {
                Property PassFail=“Pass”;
                IncrementCounters PassCount;
                GoTo FlowTest1 Typ;
              }
              Result 1
              {
                 Property PassFail=“Fail”;
                 IncrementCounters FailCount;
                 Return 1;
              }
              # This result block will be executed if
              # MyFunctionalTest1 Min returns any of
              # 2,5,6,7,-6,-5 or -4
              Result 2,5:7,-6:-4
              {
                  Property PassFail=“Fail”;
                  IncrementCounters FailCount;
                  Return 1;
              }
          }
          FlowItem FlowTest1_Typ{...}
          FlowItem FlowTest1_Max{...}
       }
[259]流FlowTest1的操作如下:
1.以执行FlowItem FlowTest1_Min开始。
2.FlowTest1_Min运行功能性测试,MyFunctionTest1Min。这种测试的细节在以下给出完整的测试计划时提供。
3.期望从运行这个测试得到九种结果,0、1、2、5、6、7、-6、-5或-4。前两个Result子句分别处理0和1,第三个处理所有剩余的结果值。
4.如果结果“0”(通过)出现,则FlowTest1_Min将递增计数器PassCounter。然后,将转换到新的FlowItem FlowTest1_Typ。
5.如果结果“1”或结果“2”出现,则FlowTest1_Min将递增计数器FailCounter,然后从该流程返回。
6.FlowTest1_Typ将以相同的方式操作,后续调用FlowTest1_Max。
7.FlowTest1_Max将将以相同的方式操作,然后当结果成功时,从该流程返回(“0”)。
[260]因此,对于成功的运行,FlowTest1将通过Test1的最小化、典型和最大化版本运行设备,然后返回。FlowTest2将以类似的方式运行。
[261]如上所述的流程基本上描述了有限状态机的状态与转换。FlowItem基本上是状态,它将做以下动作:
1.执行IFlowable(它可以是前面定义的Flow或Test或可以利用以上规则在C++中实现的用户定义的流程)。
2.IFlowable的执行返回数字结果。基于该结果,特定的动作发生(更新一些计数器),然后发生以下两件事情中的一个:
a.流程返回到具有该数字结果的调用者。
b.流程通过转换到另一状态(FlowItem)继续。
[262]因此,FlowItem具有以下成分:
FlowItem有名字。
FlowItem有要执行的IFlowable。
FlowItem有数字或Result子句。
FlowItem的每个Result子句提供动作并以transition结束并与一个或多个结果值关联。
[263]这些项在FlowItem中的句法如下。
         FlowItem<name><IFlowable to be executed>
         {
            Result<one or more result values>
            {
                <actions for these result values>
                <transition for these result values>
            }
            Result<one or more other result values>
            {
               ...
            }
            ...
         }
[264]要执行的IFlowable可以是Test或者用户定义的IFlowable,或者是Flow。用于结果的动作可以是以下任何一个:
将由GUI工具使用的字符串值实体设置成属性结果的属性动作。这可以在以上FlowTest1例子中看到:
      Property PassFail=”Pass”;
[265]属性基本上是与结果语句关联的命名字符串或整数值实体。属性的数量可以是任意的,并且其优选由诸如GUI这样由用户用来显示与该结果关联的信息的工具使用。它们对实际测试结果或测试流程没有影响。
[266]一个计数行为将计数器的某些数字递增。这可以从上例中的语句
           Increment Counters PassCount;
看出。
一个例程调用程序调用一个任意的或用户的例程。这在下面讨论。
[267]最后,FlowItem具有一个Transition,其可以是将控制转移给另一FlowItem的GoTo语句,或者将控制返回给调用者(可以是调用流程,也可以是发起该测试计划的***例程)的Return语句。
预定义的流程(Flow)
[268]Flow对象的典型应用是定义测试顺序。然后,该顺序作为测试计划服务器(TPS)中所发生事件,即执行测试计划事件,的结果执行。每个站点控制器上的测试计划服务器执行用户的测试计划。但是,Flow对象也响应其它事件执行。圆括号中的名字是用于将Flow分配给这些事件的名字。
1.***加载流程(SysLoadFlow)。当测试计划加载到一个或多个站点控制器上时,这个流程在***控制器上执行。它是在测试计划实际加载到任何站点控制器上之前执行的。这个流程允许测试计划开发人员定义应当源自***控制器的动作。这种动作包括模式文件的广播加载、校准动作,等等。
2.站点加载流程(SiteLoadFlow)。这个流程在测试计划已经加载到站点上并初始化以后在站点控制器上执行。这允许任何特定于站点的初始化发生。
3.批(lot)启动/结束流程(LotStartFlow/LotEndFlow)。当通知测试计划服务器新批的启动时,这些流程在站点控制器上执行。这典型地用于生产环境中注释具有特定于批的信息的数据登录流程。
4.DUT改变流程(DutChangeFlow)。当其DUT信息改变时,这个流程在站点控制器上执行。同样,这也典型地用于生产环境中更新数据登录流程。
5.测试计划启动/结束流程(TestPlanStartFlow/TestPlanEndFlow)。当通知测试计划服务器开始执行当前测试流程时和当该流程结束执行时,这些流程在站点控制器上执行。
6.测试启动/结束流程(TestStartFlow/TestEndFlow)。当测试流程开始运行新测试和当该测试结束执行时,这些流程在站点控制器上执行。
7.测试流程(TestFlow)。这个流程是当测试计划服务器接收到“执行测试计划”消息时执行的主要流程对象。
[269]应当指出,如果用户在用户的测试计划中定义了不是TestFlow或其它预定义流程中一种的流程,则执行它的优选方式是将其包括在这些预定义流程中一个的转移状态中。
测试计划举例
[270]在以下例子中,一起给出流程与描述该流程实现的有限状态机的注释。有限状态机是作为转移矩阵给出的。矩阵的行对应于FlowItem,列对应于结果。矩阵行的项指示当返回结果是列中所指定值时从该行的FlowItem转移到的FlowItem。
[271]以下示出具有三个流程,FlowTest1、FlowTest2和FlowMain,的测试计划。FlowTest1如上所述操作。它将在“min”、“typ”与“max”中的每一个中运行名字为MyFunctionalTest1的测试。同样,FlowTest2将在这些配置的每个中运行MyFunctionalTest2。最后,FlowMain将运行FlowTest1和FlowTest2。有限状态机转移矩阵在这些流程中的每个开始部分的注释中提供。
      # ----------------------------------------------------------
      # File mySimpleTestPlan.tpl
      # ----------------------------------------------------------
      Version 0.1;
      Import xxx.pin;      # Pins
      # Constants and variables giving limiting values.
      Import limits.usrv;
      # Import test condition groups
      Import myTestConditionGroups.tcg;
      # Import some bin definitions.
      Import bins.bdefs;
      # ----------------------------------------------------------
      # Start of the test plan
      # ----------------------------------------------------------
      TestPlan Sample;
      # This block defines Pattern Lists file-qualified names and
      # Pattern List variables that are used in Test declarations.
      # Pattern list viables are deferred till customization is
      # examined.
     PListDefs
     {
        # File qualified pattern list names
        p11A.plist:pat1Alist,
        p12A.plist:pat2AList
     }
     # The socket for the tests in this test plan(this is not imported,
     # but resolved at activation time):
     SoeketDef=mytest.soc;
     # Declare some user variables inline
     UserVars
     {
        # String name for current test
        String CurrentTest=″MyTest″;
     }
     TestCondition TC1Min
     {
        TestConditionGronp=TCG1;
        Selector=min;
     }
     TestCondition TC1Typ
     {
        TestConditionGroup=TCG1;
        Selector=typ;
     }
     TestCondition TC1Max
     {
        TestConditionGroup=TCG1;
        Selector=max;
     }
     # Likewise for TC2Min,TC2Typ,TC2Max
     #
     # Declare a FunctionalTest″FunctionalTest″refers to a C++
     # test class that runs the test,and returns a 0,1 or 2 as
     # a Result.The Test Condition Group TCG1 is selected with
     # the″min″selector by referring to the TC1Min TestCondition.
     #
     Test FunctionalTest MyFunctionalTest1Min
     {
        PListParam=pat1AList;
        TestConditionParam=TC1Min;
     }
     # Another FunctionalTest selecting TCG1 with″typ″
     Test FunctionalTest MyFunctionalTest1Typ
     {
        PListParam=pat1AList;
        TestConditionParam=TC1Typ;
     }
     # Another FunctionalTest sclecting TCG1 with″max″
     Test FunctionalTest MyFunctionalTest1Max
     {
        PListParam=patlAList;
        TestConditionParam=TC1Max;
     }
     # Now select TCG2 with″min″
    Test FunctionalTest MyFunctionalTest2Min
    {
       PListParam=pat2AList;
       TestConditionParam=TC2Min;
    }
    # Likewise for TCG2 with″typ″and TCG2 with″max″
    Test FunctionalTest MyFunctionalTest2Typ
    {
       PListParam=pat1AList;
       TestConditionParam=TC2Typ;
    }
    Test FunctionalTest MyFunctionalTes12Max
    {
       PListParam=pat1AList;
       TestConditionParam=TC2Max;
    }
    #
    # At this time the following Test objects have been defined
    #       MyFunctionalTest1Min
    #       MyFunctionalTest1Typ
    #       MyFunctionalTest1Max
    #       MyFunctionalTest2Min
    #       MyFunctionalTest2Typ
    #       MyFunctionalTest2Max
    #
    #
    # Counters are variables that are incremented during the
    # execution of a test.They are UnsignedIntegers that are
    # initialized to zero.
    #
    Counters{PassCount,FailCount}
    #
    # Flows can now be presented.A Flow is an object that
    # essentially represents a finite state machine which
    # can execute “Flowables”,and transition to other flowables based
    # on the Result returned from executing a Flowable.A Flow can also
    # call another flow.
    #
    # A Flow consists of a number of FlowItems and transitions
    # between them.FlowItems have names which are unique in
    # the enclosing Flow,execute a“Flowable”object,and then
    # transition to another FlowItem in the same enclosing Flow.
    #
    # Flowable objects include Tests and other Flows.When
    # a Flowable object executes,it returns a numeric Result
    # which is used by the FlowItem to transition to another
    # Flowltem. As a result of this,both Tests and Flows
    # terminate by returning a numeric Result value.
    #
    # FlowTest1 implements a finite state machine for the
    # Min,Typ and Max flavors of MyFunctionalTest1.On
    # success it tests Test1Min,Test1Typ,Test1Max
    # and then returns to its caller with 0 as a successful
    # Result.On failure,it returns 1 as a failing Result.
    #
    # Assume that the tests MyFunctionalTest1Min,...all
    # return a Result of 0(Pass),1 and 2(for a couple
    # of levels of failure).The Transition Matrix of the
    # finite state machine implemented by FlowTest1 is:
    # ----------------------------------------------------------
    #                      Result 0         Result 1     Result 2
    # ----------------------------------------------------------
    #  FlowTest1_Min         FlowTest1_Typ         return 1     return 1
    #  FlowTest1_Typ         FlowTest1_Max         return 1     return 1
    #  FlowTest1_Max         return 0          return 1  return 1
    #
    # where the IFlowables run by each Flowltem are:
    #     FlowItem           IFlowable that is run
    #     FlowTest1_Min          MyFunctionalTest1Min
    #     FlowTest1_Typ          MyFunctionalTest1Typ
    #     FlowTest1_Max          MyFunctionalTest1Max
    #
Flow FlowTest1
{
   FlowItem FlowTest1_Min MyFunctionalTest1Min
   {
      Result 0
      {
         Property PassFail=″Pass″;
         IncrementCounters PassCount;
         GoTo FlowTest1_Typ;
      }
      Result 1,2
      {
         Property PassFail=″Fail″;
         IncrementCounters FailCount;
         Return 1;
      }
  }
  FlowItem FlowTest1_Typ MyFunctionalTest1Typ
  {
     Result 0
  {
        Property PassFail=″Pass″;
        IncrementCounters PassCount;
        GoTo FlowTest1_Max;
    }
    Result 1,2
    {
       Property PassFail=″Fail″;
       IncrementCounters FailCount;
       Return 1;
    }
}
# Likewise for FlowTest1_Max
FlowItem FlowTest1_Max MyFunctionalTest1Max
{
   Result 0
  {
      Property PassFail=″Pass″;
      IncrementCounters PassCount;
      Return 0;
   }
   Result 1,2
   {
          Property PassFail=″Fail″;
          IncremeutCounters FailCount;
          Return 1;
       }
    }
}
#
# FlowTest2 is similar to FlowTest1.It implements a
# finite state machine for the Min,Typ and Max flavors
# of MyFunctionalTest2.On success it tests Test2Min,
# Test2Typ,Test2Max and then returns to its caller with
# 0 as a successful Result.On failure,it returns 1 as
# a failing Result.
# Assume that the tests MyFunctionalTest2Min,...all
# return a Result of 0(Pass),1 and 2(for a couple
# of levels of failure).The Transition Matrix of the
# finite state machine implemented by FlowTest2 is:
# ----------------------------------------------------------
#                      Result 0         Result 1     Result 2
# ----------------------------------------------------------
#  FlowTest2_Min          FlowTest2_Typ        return 1     return 1
#  FlowTest2_Typ          FlowTest2_Max        return 1     return 1
#  FlowTest2_Max          return 0         return 1   return 1
#
# Where the IFlowables run by each Flowltem arc:
#     FlowItem          IFlowable that is run
#     FlowTest2_Min         MyFunctionalTest2Min
#     FlowTest2_Typ         MyFunctionalTest2Typ
#     FlowTest2_Max         MyFunctionalTest2Max
#
Flow FlowTest2
{
   # ...
}
#
# Now the FlowMain,the main test flow,can be presented.It
# implements a finite state machine that calls FlowTest1
# and FlowTest2 as below:
# ---------------------------------------------------------
#                Result 0        Result 1
# ---------------------------------------------------------
#  FlowMain_1    FlowMain_2      return 1
#  FlowMain_2    return 0        return 1
#
# Where the IFlowables run by each FlowItem are:
#     FlowItem      IFlowable that is run
#     FlowMain_1    FlowTest1
#    FlowMain_2     FlowTest2
Flow FlowMain
{
   # The first declared flow is the initial flow to be
   # executed.It goes to FlowMain_2 on success,and
   # returns 1 on failure.
   FlowItem FlowMain_1 FlowTest1
   {
      Result 0
      {
         Property PassFail=″Pass″;
         IncrementCounters PassCount;
         GoTo FlowMain_2;
      }
      Result 1
      {
        # Sorry...FlowTest1 failed
        Property PassFail=″Fail″;
        IncrementCounters FailCount;
        # Add to the right soft bin
        SetBin SoftBins.“3GHzSBFTFail”;
        Return 1;
      }
 }
 FlowItem FlowMain_2 FlowTest2
 {
    Result 0
    {
      # All passed!
      Property PassFail=″Pass″;
      IncrementCounters PassCount;
      # Add to the right soft bin
      SetBin SoftBins.“3GHzAllPass”;
      Return 0;
      }
      Result 1
      {
         # FlowTest1 passed,but FlowTest2 failed
         Property PassFail=″Fail″;
         IncrementCounters FailCount;
                     # Add to the right soft bin
                     SetBin SoftBins.“3GHzCacheFail”;
                     Return 1;
                    }
                 }
             }
             TestFlow=FlowMain;
[272]以上测试计划是以优选次序如下构造的:
1.首先,提供版本号。这个号用于确保与编译器版本的兼容性。
2.然后,声明多个导入。这些是具有分解测试计划中所使用名字所需的声明的各种文件。
3.接下来,声明测试计划名字,其后是测试计划的内联声明。
4.然后声明一组PlistDefs。这些包括指定来自所指定文件的GlobalPLists的文件限定名字。它们还包括模式列表变量。模式列表变量是可以在执行时的定制flowable中初始化的变量。它们提供了将测试与实际模式列表的绑定延迟到运行时的方式。
5.接下来,声明一组用户变量。这些包括字符串。
6.然后,声明一些计数器,以便确定通过和未通过的测试的个数。计数器是初始化为0并在IncrementCounter语句递增的简单变量。它们与前面描述的bin不同,bin的语义是只有当前设置的bin在DUT测试结束时递增。
7.接下来声明一系列测试条件。这些条件中的每个指定一个测试条件组和选择器。在这个例子中,测试条件组来自mytestconditionsgroups.tcg。但是,它们也可以内联在测试计划中。
8.接下来,声明一系列Flowables或测试。它们每一个都是选择模式列表与测试条件的已知测试功能测试。因此,例如,MyFunctionalTest1Max选择测试条件TC1Max与模式列表。
9.然后,声明三个流程,FlowTest1、FlowTest2和FlowMain。流程运行Flowables。Flowables包括测试(例如MyFunctionalTest1Max)和其它流程(例如FlowTest1和FlowTest2)。FlowTest1和FlowTest2中的每一个都分别运行通过Test1和Test2的最小、典型与最大版本。流程FlowMain调用前面声明的流程,先是FlowTest1,然后是FlowTest2。
10.最后,TestFlow事件分配给FlowMain流程。因此,流程FlowMain是当用户选择执行这个计划时由这个测试计划执行的流程。
用于流程的C++
[273]利用以上规则,大部分元素可以用C++实现,除了流程本身。
用于FlowItem的C++
[274]表示FlowItem的C++类可以具有以下接口:
一种操作
  Status seFlowable(IFlowable*pIFlowable);
该操作将设置对这个FlowItem要执行的IFlowable。
[275]一旦FlowItem从需要执行这个IFlowable的调用集合返回,它就将需要递增依赖于结果值的计数器列表。为此,FlowItem需要有要递增的计数器向量。这通过以下调用初始化:
       Status setCounterRefs(unsigned int result,
                               CounterRefList counterRefs);
这个调用将对计数器的引用向量设置到FlowItem中,使得一旦IFlowable完成执行它就可以递增它们。例如,语句
          IncrementCounters A,B,C;
将优选地如下使用以上调用:
             //Somewhere earlier
             CounterRefList counters;
             ...
             //Code for Result clause
             //Result 2,3 {...}
             //of flowObject.
             counters.reset();
             counters.add(&A);
             counters.add(&B);
             counters.add(&C);
             flowObject.setCounterRefs(2,counters);
             flowObject.setCounterRefs(3,counters);
[276]使用临时的CounterRefList对象指定计数器。最开始调用counters.reset(),然后是设置计数器列表的多个counters.add()调用。然后,这可以用于设置针对结果值2和3要更新的计数器向量。
[277]然后,FlowItem可能需要转移到关于特定结果的另一FlowItem:
Status setTransition(unsigned int result,FlowItem*pFlowItem);
在特定Result语句处理许多结果值的情况下,自然需要几个这样的调用。
[278]FlowItem可能需要返回结果。这可以通过以下进行:
Status setReturnResult(unsigned int result,unsigned int returnResult);
[279]例如,对于前面例子中的FlowItem FirstFlowItem,以上调用中“result”的值是“2”,而“returnResult”的值是“1”。
最后,FlowItem需要执行操作:
Status execute(unsigned int&result,FlowItem*pNextFlowItem);
[280]这个操作将执行IFlowable,然后更新所指示的计数器,然后或者返回结果,或者返回指向下一FlowItem的指针。如果这个指针为NULL,则结果是返回值。
[281]为FlowItem FlowMain_1生成的代码如下:
                FlowItem FlowMain_1;
                FlowItem FlowMain_2;
         CounterRefList counters;
         FlowMain_1.setFlowable(FlowTest1);
         //Result 0
         counters.reset();
         counters.add(&PassCount);
         FlowMain_1.setCounterRefs(0,counters);
         FlowMain_1.setTransition(0,&FlowMain_2);
         //Result 1
         counters.reset();
         counters.add(&FailCount);
         FlowMain_1.setCounterRefs(1,counters);
         //The following call from ITestPlan will set the
         //current bin group and bin name.
         pTestPlan->setBin(“SoftBins”,“3GHzSBFTFail”);
         FlowMain_1.setReturnResult(1,1);
[282]以上生成的代码设置FlowMain_1运行IFlowable“FlowTest1”,然后设置它递增用于每个结果的合适计数器列表,最后采取必需的动作。在结果“0”的情况下必需的动作是转移到FlowMain_1,而在结果“1”的情况下是返回。
C2.TestPlan中的计数器支持
[283]计数器是初始化为0并且可以在测试运行中的各个点由IncrementCounter语句递增的变量。它们与只在测试结束时递增的Bin不同。此外,bin是层次性的,而计数器是简单变量。因此,计数器比bin具有更简单更有限的功能。
[284]计数器可以通过维护一组作为无符号整数的指定计数器的Counter类在TestPlan中支持。对象将通过Counter声明在这个类中定义。计数器不能在测试开始时自动复位,从而允许TestPlan在测试许多DUT的过程中收集计数。需要提供对一个计数器的值进行复位、递增和查询的方法。这使得可以有bining的替代,以便确定作为运行测试结果的计数。
[285]TestPlan优选地包含成员变量,m_modifiedCounters,这是通过在DUT上运行测试修改的计数器的集合。这个集合在测试的开始初始化成空集合。在进行IncrementCounters调用的每个地方,将生成向m_modifiedCounters成员添加指定计数器的代码。因此,这个成员收集在DUT上测试执行过程中修改的所有计数器。
用于Flow对象的C++
[286]一旦所有的FlowItem都创建了,则Flow对象就可以如下所示作为C++对象创建:
添加FlowItem的操作
Status addFlowItem(FlowItem*pFlowItem,bool isInitalFlowItem);该操作向Flow添加所指示的FlowItem。如果这是Flow的初始FlowItem,则布尔值设置成True。
执行流程的操作
    Status executeFlow(unsigned int& result);
[287]这优选地在Flow返回时返回,结果是执行流程。其动作是利用初始FlowItem开始执行流程。只有当前FlowItem返回下一个要执行的FlowItem,它就将持续执行FlowItem。
[288]因此,为Flow生成的C++具有几个对addFlowItem()的重复调用,以便将FlowItem添加到Flow。当选择测试计划中的这个流程执行时,executeFlow()操作将发生。
C3.测试类
[289]总的来说,大部分程序代码是用于设备测试的数据,剩余的是实现测试方法的测试程序代码。数据是依赖DUT的(例如,电源条件、信号电压条件、定时条件等)。测试条件包括将指定的设备条件加载到ATE硬件上的方法,还有那些实现用户指定目标(如数据登录等)所需的方法。
[290]如上面所解释的,为了提高测试代码的重用性,这种代码一旦独立于任何特定于设备的数据(例如,引脚名、模拟数据等)或特定于设备测试的数据(例如,用于DC单元的条件、测量引脚、目标引脚的个数、模式文件的名字、模式程序的地址等)。如果测试代码利用这些类型的数据编译,则测试代码的重用性将降低。因此,应当使任何特定于设备的数据或特定于设备测试的数据对测试代码在外部可用,作为代码执行时的输入。
[291]在开放体系结构测试***中,作为Itest接口实现的Test类实现对于特定类型的测试测试数据与代码的分离(从而实现代码的重用性)。这种测试类可以看作是其独立实例的“模板”,独立实例彼此的区别只有特定于设备或特定于设备测试的数据。测试类在测试计划文件中指定。每个测试类典型地实现特定类型的设备测试或者设备测试的安装。例如,Functional、AC和DC参数化测试优选地是由独立的Test类实现的。但是,定制的测试类也可以用在测试计划中。
[292]测试类允许用户通过提供用于指定该测试的特定实例的选项的参数来配置类行为。例如,Functional Test将分别取参数Plist和TestConditions来指定要执行的模式列表和该测试的Level和Timing条件。(通过测试计划描述文件中不同“Test”块的使用)指定这些参数的不同值允许用户创建Functional Test的不同实例。图5示出了不同的测试实例502将如何从单个测试类504导出。
[293]这些类应当设计成允许编译器400从测试计划文件取测试的描述及其参数并生成正确的C++代码,该代码可以编译链接以生成测试程序。测试类实例可以添加到描述测试流程的对象,其中测试流程创建设备测试的复杂执行序列。
C4.从ITest和IFlowable的导出
[294]如上面所提到的,Test类从ITest导出。利用以上规则,这些可以在实现ITest接口的C++类中实现。除了为ITest接口指定的方法,这些类提供执行指定的设备测试类所需的特定于测试的智能与逻辑。Test类还实现IFlowable接口。因此,Test类的实例可以用在运行测试的FlowItem中。
定制
[295]提供定制机制来允许用户调用C函数并开发他们自己实现ITest与IFlowable接口的类。
Pre-Header
[296]TPL提供了用于在测试***中定义测试类的一般机制。测试工程师可以使用该机制来创建定制测试类,其可以在没有额外工具的情况下通过测试***来加载和使用。测试工程师还可以开发上述他们自己的实现ITest和IFlowable的类。Pre-Header通过向C++语言提供自我测量能力、支持定制测试类的特征。
[297]如果Test类的对象可以被询问关于其方法与签名,则可以验证合适的参数可以包括在所生成的源代码中。这种特征对于翻译阶段中的错误检查与验证是非常有用的。如果测试工程师在参数的名字上或在这些参数的变元个数(或者可能是类型)上犯了错误,则此错误可在翻译阶段被发现,并且可在翻译时产生有意义的错误消息,而不是等待来自C++编译器的编译时错误消息。
[298]自检(Introspection)指要求对象在其自身当中查找并返回关于其属性与方法的能力。例如Java的有些语言将这种能力作为语言的一部分提供。诸如Visual Basic的其它语言将这种需求强加到要与其一起使用的对象上。C++不提供这种特征。
[299]在一个实施例中,预头部的自查能力对于提供默认参数值以及可选参数的指示也是有用的。另外,如果此能力被提供为测试类实现的一部分,则图形用户接口(GUI)应用程序也可以使用此信息来动态建立会话和其它用户接口元件,以帮助测试工程师来有效利用这些类。在另一实施例中,测试类开发者可以(对于每一测试类)在单个基于文本的源文件中指定开发者已经设计的作为需要将测试类参数化的测试类的公共方法/属性。
[300]注意,单个源是优选的。换句话说,任何人都不想在一个文件中有Test类的参数化接口的描述,而在另一独立的(头)文件中有C++接口描述,然后麻烦地需要使这两个源保持同步。为此,该测试类的“基于文本的”描述嵌入到Preheader文件中,该Preheader文件由编译器用于自检的目的及用于生成测试类的C++头。所生成的C++头文件是用于最终编译Test类C++代码的头文件。
[301]C++中头的使用是众所周知的。然而,因为C++难以解析和解释,所以本发明的实施方式定义由TPL编译器编译用以创建C++头文件的Preheader文件,所述C++头文件又被C++编译器用来创建测试程序。根据这种实施方式,测试类开发人员写Preheader文件,其允许到对应测试类或其它测试实体的可见性。
[302]以下例子说明了根据本发明优选实施方式用于Test类的Preheader文件的概念。考虑以下从源文件的节选,对于测试FuncTest1:
  ...
  TestCondition TC1
  {
      TestConditionGroup=TCG1;# Previously defined TCG for Levels
      Selector=min;
  }
  TestCondition TC2
      TestConditionGroup=TCG2;# Previously defined TCG for Timing
      Selector=min;
  }
  ...
  Test FunctionalTest FuncTest1
  {
      PListParam=patList1;    # Previously defined pattern list
      TestConditionParam=TC1;
      TestConditionParam=TC2;
     }
[303]C++编译器需要知道哪个FunctionalTest是确定以上FuncTest1的说明是否合法所必需的。哪个FunctionalTest必需的定义可以在Preheader中定义,而不是在知道FunctionalTest的情况下建立到C++编译器中。
[304]假定C++类中的FunctionalTest具有基类Test1和Test2,并具有是Plist和TestConditions阵列的成员。C++编译器需要知道FunctionalTest成员的类型,以便识别以上FuncTest1的声明是否合法。
[305]此外,为了生成FunTest1的C++对象声明,需要构建类FunctionalTest的C++头文件。这需要C++编译器也知道FunctionalTest类的基本类、其成员名,以及其它这样的信息。
[306]本发明一个实施例的Pre-header子语言为编译器提供其识别声明的合法性和生成对应于声明的C++头文件和对象声明所需的信息。
[307]注意,FunctionalTest是简单的类型(如果考虑参数化),因此,将使用简单的描述用于参数化。测试类开发人员编写支持上述参数化的Pre-header,FunctionalTest.ph如下(假设Pre-header对于基本测试类Test1和Test2可用):
      1    Version 1.0;
      2    #
      3    # Parameterization specification pre-header for FunctionalTest
      4    #
      5    Import Test1.ph;             # For base class Test1
      6    Import Test2.ph;             # For base class Test2
      7    TestClass=FunctionalTest;# The name of this test class
      8    PublieBases=Test1,Test2;# List of public base classes
      9    # The parameters list or“parameter block”:
      10   Parameters
      11   {
      12      # The following declaration specifies that a FunctionalTest has
      13      # -a parameter of type PList
      14      # -[represented by C++ type Tester::PatternTree]
      15      # -stored in a member named m_pPatList
      16      # -a function to set it named setPatternTree.
      17      # -a parameter description for the GUI to use as a tool tip
      18      PList PListParam
      19      {
      20         Cardinality=1;
      21         Attribute=m_pPatList;
      22         SetFunction=setPatternTree;
      23         Description=“The PList parameter for a FunctionalTest”;
      24      }
      25      #
      26      # The following declaration specifies that a FunctionalTest has
      27    #  -1 or more pararneters of type TestCondition
      28    #  -[represented by C++ type Tester::TestCondition]
      29    #  -stored in a member named m_testCondnsArray
      30    #  -a function to set it named addTestCondition.
      31    #  -a parameter description for the GUI to use as a tool tip
      32    # The[implement]clause causes the translation phase of to
      33    # generate a default implementation of this function.
      34    #
      35    TestCondition TestConditionParam
      36    {
      37       Cardinality=1-n;
      38       Attribute=m_testCondnsArray;
      39       SetFunction=addTestCondition[Implement];
      40       Description=“The TestCondition parameter for a FunctionalTcst”;
      41    }
      42 }
      43 #
      44 # The section below is part of the Pre-Header which is an escape
      45 # into C++ code.This will be referred to as a“template block.”
      46 #
      47 # Everything in this section will be reproduced verbatim in the
      48 # generated header file,except for “$Class”,“$Inc”,
      49 # “$ParamAryTypes”,“$ParamAttrs”,“$ParamFns”and“$ParamImpls”.
      50 #
      51 # Note that no comments beginning with the‘#’character are supposed
      52 # within the following section.
      53 #
      54 CPlusPlusBegin
      55 $Inc
      56 namespace
      57 {
      58 class $Class
      59 {
      60 //Array types for parameters storage:
      61 $ParamAryTypes
      62 public:
      63    visual void preEx();
      64    virtual void exec();
      65    visual void postExec();
      66    $ParamFns
      67    ...
      68 private:
      69    double m_someVar;
      70    $ParamAttrs
      71     ...
      72  };
      73  ...
      74  $ParamImpls
      75  }//End namespace
      76  CPlusPlusEnd
用于参数化的测试类的C++
[308]当编译器处理Pre-Header文件时,它建立编译器变量的值,如$Inc,$Class、$ParamAryTypes及其它。这使得它能够通过逐字逐句地生成以上C++代码并在所指示的位置在编译器变量$Inc、$Class等的值中扩展来创建以下C++头文件。对于FunctionalTest.ph,它为FunctionalTest类创建以下C++头文件FunctionalTest.h。
           1  #line 7″./FunctionalTest.ph″
           2  #include<ITest.h>
           3  #line 5″./FunctionalTest.ph″
           4  #include<Test1.h>
           5  #line 6″./FunctionalTest.ph″
           6  #include<Tes2.h>
           7  #line 55″./FunctionalTest.ph″
           8  #include<vector>
           9  #line 55″./FunctionalTest.ph″
           10 #include<Levels.h>
           11 #line 55″./FunctionalTest.ph″
           12 #include<TestCondnGrp.h>
           13 ...
           14 #line 56″./FunctionalTest.ph″
           15 namespace
           16 {
           17 #line 7″./FunctionalTest.ph″
           18 class FunctionalTest:public ITest,
           19 #line 8″./FunctionalTest.ph″
           20                           public Test1,
           21 #line 8″./FunctionalTest.ph″
           22                            public Test2
           23 #line 59″./FunctionalTest.ph″
           24 {
           25 #Array types for parameters storage:
           26 #line 61″./FunctionalTest.ph″
           27 public:
           28 #line 37″./FunctionalTest.ph″
           29     typedef std::vector<Tester::TestCondition*>
              TestConditionPtrsAry_t;
           30 #line 62″./FunctionalTest.ph″
           31 public:
           32    virtual void preExec();
           33    virtual void exec();
           34    virtual void postExec();
           35 public:
           36 #line 7″./FunctionalTestph″
           37     void setName(OFCString &name);# Automatic for all tests
           38 #line 22″./FunctionalTest.ph″
           39     void setPatternTree(PatternTree*);
           40 #line 23″./FunctionalTest.ph″
           41     String getPListParamDescription()const;
           42 #line 39″./FunctionalTest.ph″
           43     void addTestCondition(TestCondition*);
           44 #line 40″./FunctionalTest.ph″
           45     void getTestConditionParamDescription()const;
           46 #line 67″./FunctionalTest.ph″
           47      ...
           48 private:
           49     double m_someVar;
           50 #line 70″./FunctionalTest.ph″
           51 private:
           52 #line 7″./FtnctionalTest.ph″
           53     OFCString m_name;# Automatic for all tests
           54 #line 21″./FunctionalTest.ph″
           55     Tester::PatternTree *m_PatList;
           56 #line 38″./FunctionalTest.ph″
           57     TestConditionPtrsAry_t m_testCondnsArray;
           58 #line 71″./FunctionalTest.ph″
           59     ...
           60 };
           61 ...
           62 #line 7″./FunctionalTest.ph″
           63 inline void
           64 #line 7″./FunctionalTest.ph″
           65 FunctionalTest::setName(OFCString& name)
           66 #line 74″./FunctionalTest.h″
           67 {
           68    m_name=name;
           69    return;
           70 }
           71 #line 39″./FunctionalTest.ph″
           72 inline void
           73 #line 39″./FunctionalTest.ph″
           74 FunctionalTest::addTestCondition(TestCondition*arg)
           75 #line 74″./FunctionalTest.ph″
           76 {
           77     m_testCondnsArray.push_baek(arg);
           78     return;
           79 }
           80 #line 23″./FunctionalTest.ph″
           81 inline void
           82 Tester::String FunctionalTest::getPListParamDescription()
           83 {
           84   return“The PList parameter for a FunctionalTest”;
           85 }
           86 #line 40″./FunctionalTest.ph″
           87 inline void
           88 Tester::String FunctionalTest::getTestConditionParamDescription()
           89 {
           90   return“The TestCondition parameter for a FunctionalTest”;
           91 }
           92 #line 75″./FunctionalTest.ph″
           93 }//End namespace
[309]如前面所描述的,这个Pre-Header使得编译器能够检查FunctionalTest类声明的有效性,来为其生成代码并生成它所需的C++头文件。
[310]作为例子,考虑前面给出的FunctionalTest声明,为了方便,以下进行了复制:
         Test FunctionalTest FuncTest1
         {
            PlistParam=patList1;    #Previously defined pattern list
            TestConditionParam=TC1;
            TestConditionParam=TC2;
         }
[311]编译器根据C++头文件的声明为以上FunctionalTest构造函数生成以下代码:
              FunctionalTest FuncTest1;
              FuncTest1.setName(″FuncTest1″);
              FuncTest1.satPatternTree(&patList1);
              FuneTest1.addTestCondition(&TC1);
              FuncTest1.addTestCondition(&TC2);
[312]应当注意还生成用于Description函数的名字。命名为Xxx的每个参数都与以下成员函数关联:
    Status getXxxDescription() const;
该函数返回具有GUI可以使用的工具提示描述的字符串。
其它的Pre-Header特征
[313]Pre-Header支持一些其它用户定义的枚举类型作为附加类型。这允许GUI提供可以用于设置特定参数值的可能选择的下拉列表。此外,Pre-Header提供关联可以看作表的多个参数的特征。例如,将“属性”阵列实现为关联的名字字符串阵列与值的整数阵列的集合可能是方便的。在一个实施例中,通过使用定制类型阵列来实施该特征。此特征在以下例子中说明:
          # ----------------------------------------------------------
          # File FooBarTest.ph
          #
          # Parameterization specification pre-header for
          # custom test class FoobarTest
          # ----------------------------------------------------------
          Version 1.0;
          Import Test1.ph;             # For base class Test1
          TestClass=FoobarTest;# The name of this test class
          PublicBases=Test1;# List of public base classes
          # The parametrs list:
          Parameters
          {
            # An enumerated type
            Enum FBEnum=FB1,FB2,FB3;
            # Detine an FBEnum parameter.
            FBEnum FBE
            {
              Cardinality=1;
              Attribute=m_fb;
              SetFunction=setFb;
              Description=“The FBE parameter for a Foobar Test”;
              # This class has an array of name-number pairs that is
              # interpreted in the class.
              ParamGroup
              {
                 Cardinality=0-n;
             # The Name field in this array is:
             # -of type String
             # -[represented by C++ type Tester::String]
             # -stored in a member named m_NameArray
             # -a function to set it named addName.
             # -a parameter deseription for the GUI to use as a tool tip
             String Name
            {
                Attribnte=m_NameArray;
                SetFunction=addName;
                Description=“A Name with a Value”;
             # The Number field in this array is:
             #  -of type Integer
             #  -[represented by C++ type int]
             #  -stored in a member named m_NumberArray
             #  -a function to set it named addNumber.
             #  -a parameter description for the GUI to use as a tool tip
             Integer Number
             {
                Attribute=m_NumberArray;
                SetFunction=addNumber;
                Description=“The value of the Name”;
              }
         }
          # The following declaration specifies that a FunctionalTest has
          #  -a parameter of type PList
          #  -[represented by C++ type Tester::PatternTree]
          #  -stored in a member named m_pPatList
          #  -a function to set it named setPatternTree.
          #  -a parameter description for the GUI to use as a tool tip
          PList PListParam
          {
              Cardinality=1;
              Attribute=m_pPatList;
              SetFunction=setPatternTree;
              Description=“The PLiet parameter for a FunctionalTest”;
          }
          #
          # The following declaration specifies that a FunctionalTest has
          #  -1 or more parameters of type TcstCondition
          #  -[represented by C++ type Tester::TestCondition]
          #  -stoted in a member named m_testCondnsArray
          #  -a function to set it named addTestCondition.
          # The[implement]clause causes the translation phase of to
          # generate a default implementation of this function.
          #
          TestCondition TestConditionParam
          {
              Cardinality=1-n;
              Attribute=m_testCondnsArray;
              SetFunction=addTestCondition[Implement];
              Description=“The TestCondition parameter for a
      FunctionalTest”;
         }
      }
               CPlusPlusBegin
               $Inc
               namespace
               {
               class $Class
               {
               //Array types for parameters storage:
               $ParamAryTypes
               public:
                    virtual void preExec();
                    virtual void exec();
                    virtual void postExec();
                    $ParamFns
                    //...
               private:
                   double m_someVar;
                   $ParamAttrs
                   //...
               };
               //...
               $ParamImpls
               }//End namespace
               CPlusPlusEnd
[314]注意,声明了定制类型的名称号对。定制类型的阵列参数可以用来实现与上述参数的ParamGroup相同的效果。上述技术是避免必须声明定制类型的一种方式。
[315]图13示出了根据本发明实施例的用于开发测试程序的方法。该方法用测试程序语言(TPL)描述了测试计划文件1302,其中测试计划文件描述了测试程序的至少一个测试。此方法还用***程序语言(SPL)描述了测试类文件1306并用TPL描述了该测试类文件的对应的pre-header文件1304,其中测试类文件描述了该测试程序的至少一个测试的实现。在这个实现的例子中,SPL是C/C++编程语言。本领域技术人员将认识到,也可以使用其它的***程序语言来代替C++编程语言。注意,用TPL描述测试计划的益处之一是允许其更接近问题的领域。TPL使测试计划开发者脱离了***编程的负担和复杂性。
[316]根据本发明的实施例,pre-header文件具有以下声明:
·如在其它TPL文件中的可选的导入。
·测试类的名称。
·可选的TestClass DLL关键字,其指定了用于该类实现的DLL。
·可选的公共基的列表。
·指定该测试类的参数的参数部分。
·提供用于测试类的内嵌模板的模板部分。
[317]pre-header文件的参数部分被测试类开发者用来指定用于测试类文件1306的参数,由此创建用户定义的测试。这些是用户可以用实例指定,由此向用户提供了对测试操作的更好控制的测试类文件的成员。例如,测试类开发者可以声明用户定义的参数TraceLevel,其在执行测试时由用户指定以便控制追踪的等级,诸如详细或简洁。
[318]有三种类型的可以在测试类文件的参数部分内声明的实体:
·使用Enum关键字的枚举。注意Enum关键字用来定义测试类枚举的类型。然后测试类文件可以具有此枚举类型的参数。这还可以由GUI使用,以构建允许用于该参数的值的下拉列表。
·使用诸如指定参数类型的Integer、PList等的关键字的参数,其中类型是有效的TPL类型。
·使用ParamGroup关键字的参数组。ParamGroup关键字用来集合一些不同的参数作为组,类似于C++类。
[319]测试类文件的各个参数可以在参数部分中声明。参数声明具有声明参数类型、其名称和参数各种特性的语法。以下是参数集的例子:
·集的势(Cardinality):其表明得到支持的该类型的参数的数目。
·属性:用作该类型参数值的存储的C++变量的名称。
·SetFunction:用于设置该参数值的函数的性质。该函数后的可选关键字“[implement]”可用作类头部中  (***在由$ParamFunctionImplementations指示的点)的内嵌方法。否则,用户负责提供该函数的实现。
·Description:例如,可由GUI将字符串文字用作工具提示,以在参数的运行时修改期间提供帮助。定制类中生成的用于名为Foo的参数的C++成员函数是“OFC:StringgetFooDescription()const”。此函数返回指定的字符串。
·GUIType:当为此测试类的一个实例生成XML描述器时,这个可选的关键字指定要传到GUI的字符串。其使GUI能够以特定方式来显示此参数值。
[320]pre-header的模板部分指定要***到头文件1312中的源代码。其给予测试类开发者对为此测试类文件生成的C++头的直接控制。模板部分位于关键字CPlusPlusBegin和CPlusPlusEnd之间。其使用指定多种声明的位置的多种替换指示器(诸如$ImportDeclarations,$ClassName,$ParamArrayTypes,$ParamFunctionDeclarations,$ParamAttributes,
$ParamFunctionImplementations等)。
[321]该方法应用了TPL编译器1308来编译测试计划文件1302和pre-header文件1304。TPL编译器编译测试计划文件1302,以形成用C++语言描述的得出的测试计划文件1310。TPL编译器在编译测试计划文件时,至少执行两个重要的函数。第一,其将测试计划文件从TPL描述翻译成SPL描述。第二,其使用pre-header文件验证测试计划文件。特别地,其检查测试计划文件中的语义错误。另外,其核实测试实体的属性。其确保测试实体的属性被声明并存在于测试计划文件中或pre-header文件中。此外,其证实函数调用和测试计划的对应参数。其确保了测试计划文件的函数调用存在于测试类实现中,且定义了函数调用的参数。
[322]类似的,TPL编译器1308编译pre-header文件1304,以形成用C++语言描述的头文件1312。TPL编译器将在pre-header文件1304的参数部分中描述的参数***头文件1312中。另外,TPL编译器1308将在pre-header文件1304的模板部分中引用的源代码***头文件1312中。头文件1312起两个作用。第一,其被SPL编译器1314用来生成测试类目标文件1316。第二,其被SPL编译器1314引用,以生成测试计划目标文件1318。
[323]最后,测试类目标文件1316和测试计划目标文件通过链接器1320链接,以生成测试程序1322的可执行的测试计划DLL文件(TPL.DLL)和可执行的测试类DLL文件(TCL.DLL)。
C5.定制函数声明
[324]这允许用户在流程转移发生时调用定制函数。定制函数是通过Pre-Header如下声明的:
    # ---------------------------------------------------------
    # File MyFunctions.ph
    #
    # Parameterization specification pre-header for MyFunctions
    # ---------------------------------------------------------
    Version 1.0;
    Functions=MyFunctions;      # The name of this group of functions
    # Declare the following C++ function in the
    # MyFunctions namespace to determine the minimum
    # of two values.
    #   //Return the minimum of x,y
    #   double MyRoutines::Min
    #            (ITestPlan* pITestPlan,int& x,int& y);
    Integer Min(Integer x,Integer y);
    # Declare the following C++ function in the
    # UserRoutines namespace to return the average of
    # an array.
    #   //Return the average of the array
    #   double MyRoutines::Avg
    #            (ITestPlan* pITestPlan,double* a,const int a_size);
    # The C++ function will be called with a and a’Length
    Double Avg(Double a[]);
    # Declare the following C++ function in the
    # UserRoutines namespace to print the dut id
    # and a message
    #   //Return the average of the array
    #   double MyRoutines::Print
    #          (ITestPlan*pITestPlan,String* msg,unsigned int&
    dutId);
    # The C++ function will be called with a and a’Length
         Void Print(String msg,UnsignedInteger dutId);
[325]一般来说,由于编译器将以标准方式扩展这些声明,因此需要为以上声明提供C++部分。用户当然要负责这些函数的C++实现。应当指出,所有的以上函数都将可能取ITestPlan指针作为隐含的第一个参数。这个指针向函数书写者提供对TestPlan中stateS的访问。例如,函数书写者可以使用ItestPlan接口来访问当前的Flow,流程中的当前FlowItem,当前的Result子句,UserVars的值,及其它这种信息。特定的测试器定义函数可以在文件Functions.ph中使用:
       Version 1.2.3;
       #
       # File Functions.ph
       #
       Functions=Functions;# The name of this group of functions
       # Declare the following C++ function in the
       # Functions namespace
       # Returns the ID of the current DUT being tested by the
       # caller.
       UnsignedInteger GetDUTID();
用于定制函数声明的C++
[326]由编译器为以上MyFunctions生成的C++代码是要简单地声明MyFunctions命名空间中的一些函数:
       namespace MyFunctions
       {
         double Min(ITestPlan* pITestPlan,int& x,int& y);
         double Avg(ITestPlan* pITestPlan,double* a,const int a_size);
         void Print(ITestPlan* pITestPlan,char* Msg,unsigned int dutID);
[327]这些函数将可以从流程调用。
C6.定制Flowable
[328]也有可能利用Pre-Header创建实现C++IFlowable接口的Pre-Header。这使得用户能够定义可以在FlowItem中运行的定制flowable。以下所示是用于用户定义的Flowable MyFlowable的Pre-Header:
    # ---------------------------------------------------------
    # File MyFlowable.ph
    #
    # Parameterization specification pre-header for MyFlowable
    # ---------------------------------------------------------
    Version 1.2.4;
    FlowableClass=MyFlowable;          # The name of this custom class
    # The parameters list:
    Parameters
    {
       # The following declaration specifies that a MyFlowable has
       #  -1 optional parameter Int1 of type Integer
       #  -[represented by C++ type int]
       #  -stored in a member named m_int1Val
       #  -a function to set it named setInt1Val.
       Integer Int1
       {
           Cardinality=0-1;
           Attribute=m_int1Val;
           SetFunction=setInt1Val;
       }
       # The following declaration specifies that a MyFlowable has
       #  -1 mandatory parameter Int2 of type Integer
       #  -[represented by C++ type int]
       #  -stored in a member named m_int2Val
       #  -a function to set it named setInt2Val.
       Integer Int2
       {
          Cardinality=1;
          Attribute=m_int2Val;
           SetFunction=setInt2Val;
       }
    # The following declaration specifies that a MyFlowable has
    #  -one or more parameters of type String
    #  -[represented by C++ type Tester::String]
    #  -stored in a member named m_stringArrVal
    #  -a function to set it named addStringVal.
    String StringItem
    {
        Cardinality=1-n;
       Attribute=m_stringArrVal;
       SetFunetion=addStringVal;
    }
    # The following declaration specifies that a MyFlowable has
    #  -A single PList parameter
    #  -[represented by the C++ type Tester::PList]
    #  -stored in a member named m_plist
    #  -a function to set it named setPListParam
    PList PListParam
    {
       Cardinality=1;
       Attribute=m_plist;
       SetFunction=setPListParam;
    }
  }
  #
  # The section below is part of the Pre-Header which is an escapc
  # into C++ code.
  #
  # Everything in this section will be reproduced verbatim in the
  # generated header file,except for“$Class”,“$Inc”,
  # “$ParamAryTypes”,“$ParamAttrs”,“$ParamFns”and
  “$ParamImpls”.
   #
   # Note that no comments beginning with the‘#’character are
   supported
   # within the following section.
   #
   CPlusPlusBegin
   $Inc
   namespace
   {
   class $Class
   {
   //Array types for parameters storage:
   $ParamAryTypes
   public:
               virtual void preExec();
               virtual void exec();
               virtual void postExec();
               $ParamFns
               //...
           private:
               double m_someVar;
               $ParamAttrs
               //...
             };
             //...
             $ParamImpls
         }// End namespace
         CPlusPlusEnd
[329]有几个实现IFlowable接口的类。这些类包括:
1.用于程序加载的流程,它检查测试计划是否可以在当前测试器配置中执行。
2.用于模式加载的流程,它将加载特定的模式与模式列表。
3.用于初始化的流程,它将硬件与软件放到已知的状态,加载全局变量,并进行其它初始化与确认功能。
4.其它通常有用的测试流程。
C7.定制类型
[330]前面关于Test类的讨论只允许测试类参数为已知类型,即,基本类型和测试器定义类型,例如PList和TestConditions。为了用户的灵活性,提供类型可扩展性是很重要的,由此可以创建和使用(对编译器是未知先验的)类型。Custom type(CT)将在定制类型中定义。这些可以用于定义对应于C语言struct(也称为Plain old Data类型或者POD,这与它们在C++中的同名物差别很大)的类型及对应于C语言函数签名typedefs的类型。具有用户类型的独立文件将有扩展名.ctyp。这里是根据本发明优选实施方式的用户类型声明的例子:
  # ---------------------------------------------------------
  # File MyCustomTypes.ctyp
  # ---------------------------------------------------------
  Version 1.0.0;
  CustomTypes
  {
     # A structured Plain-Old-Data type
     Pod Foo
     {
        String      S1;   # String is a standard type
        Integer I1;   #...and so is Integer
        String      S2;
      }
     # Another structured type using Foo
     Pod Bar
     {
        Foo            Foo1;
        String     S1;
        Foo            Foo2;
     #
     # A pointer to a function,
     #      Return type:     Integer
     #      Parameters:      Integer,Integer
     #
     Routine BinaryOp(Integer,Integer)Returns Iuteger;
     #
     # Another pointer to.a function.
     #      Return type:    Void
     #      Parameter: Integer
     Routine UnaryOp(Integer)Returns Void;
     #
     # A pointer to a function that takes
     # no parameters and does not return a value.
     #
     Routine NullaryOp() Returns Void;
     }
用于定制类型的C++
[331]以上提出的定制类型声明将由编译器翻译成以下C++代码:
              namespace CustomTypes
              {
                strnct Foo
                {
                    Tester::String   S1;
                    int              I1;
                    Tester::String   S2
                };
                struct Bar
                {
                    Foo                Fool;
                    Tester::String S1;
                    Foo                Foo2;
                 };
                 typedefint(*BinaryOp)(int&,int&);
                 typedcfvoid(*UnaryOp)(int);
                 typedefvoid(*NullaryOp)();
              }
[332]如以下所示出的,这些类型的对象可以作为参数传递到Test类。
使用定制类型作为测试类参数
[333]考虑用户具有对测试的扩展的情况,除了模式列表和测试条件,这需要初始化其它类对象及在包含定制类型的文件(即,.ctyp文件)中定义的任意(即,用户定义)对象。例如,假定用户想使用在文件MyTestCTs.ctyp中定义的CT:
     # File MyTesetCTs.ctyp
     Version 1.0;
     CustomTypes
     {
         Pod Foo
         {
             String name;
             PList patternList;
         }
         Pod Bar
         {
             Foo      someFoo;
             Double   dVal;
         }
         Routine BinaryOp(Integer,Integer)return Integer;
     }
[334]用户使用以上类型所需要做的就是在他的测试类pre-header中导入以上文件。由于编译器解释如此定义的CT,由此当其处理测试类pre-header时,用于Foo和Bar的定义可用。此外,编译器定义两个C语言strcut,分别对应于以上类型Foo和Bar的struct Foo和struct Bar,其定义放在文件myTestCTs.h中。myTestCTs.ctt的导入语句使文件myTestCTs.h包括在所生成的测试类C++头中。以下例子说明了这个处理。首先,考虑测试计划中对测试的声明(为了清楚,忽略了对模式列表和测试条件的声明):
         ...
         Import MyFunctions.ph;
         Import MyCustomTypes.ctyp;
         ...
         # The CustomVars block defines variables of the Custom
         # types defined earlier.
         CustomVars
         {
             ...
             Bar bar1=
            {
                {″This is a Foo″,somePatList},   # someFoo
                3.14159                                 # dVal
            }
            #
            # A function object that is a binary operator.
            # The name on the right hand side of the assignment
            # is a routine declared in MyFunctions,for which,
            # of course,the user has to provide an implementation.
            #
            BinaryOp bopl=MyFunctions.Min;
         }
         ...
         Test MyFancyTest MyTest1
         {
            ...
            BarParam=barl;
            BinaryOpParam=bop1;
         }
         ...
[335]在以上例子中,CustomVars块包括在测试计划中。具有定制变量的独立文件将具有扩展名.cvar。用户将如下写用于支持以上参数化的pre-header(为了清楚,忽略用于模式列表和测试条件的参数化声明):
      # ---------------------------------------------------------
      # File MyFancyTest.ph
      #
      # Parameterization specification pre-header for MyFancyTest
      # ---------------------------------------------------------
      Version 1.0.2;
      Import MyCustomTypes.ctyp;          # For CTs used in MyFancyTest
      Import FunetionalTest.ph;        # For base class FunctionalTest
      TestClass=MyFancyTest;          # The name of this test class
      PublicBases=FunctionalTest;     # List of public base classes
      # The parameters list:
      Parameters
      {
         # The following declaration specifies that a MyFancyTest has
         #  -an optional array of parameters of custom type Bar
         #  -[represented by C++ type CustomTypes::Bar]
         #  -stored in a member named m_barsArray
         #  -a function to set it named addBarParam.
         # An implementation will be generated for addBarParam.
         Bar BarParam
         {
             Cardinality=0-n;
             Attribute=m_barsArray;
             SetFunction=addBarParam[Implement];
          }
          # The following declaration specifies that a MyFancyTest has
          #  -an optional parameter of custom type BinaryOp
          #  -[represented by C++ type CustomTypes::BinaryOp]
          #  -stored in a member named m_binaryOp
          #  -a function to set it named setBinaryOpParam.
          # An implementation will be generated for setBinaryOpParam.
          BinaryOp BinaryOpParam
          {
             Cardinality=0-1;
             Attribute=m_binaryOp;
             SetFunction=setBinaryOpParam[Implement];
          }
      }
       CPlusPlusBegin
       $Inc
       namespace
        {
        class $Class
        {
         $ParamAryTypes
         public:
            virtual void preExec();
            virtual void exec();
            virtual void postExec();
            $ParamFns
            //...
        private:
            double m_someVar;
            $ParamAttrs
            //...
          };
          //...
          $ParamImpls
          }//End namespace
          CPlusPlusEnd
用于利用定制类型的定制测试类的C++
[336]最后,一旦编译器处理完这个pre-header文件,它就将创建以下用于MyFancyTest类的C++头文件,MyFancyTest.h:
       #include<MyCustomTypes.h>
       #include<ITest.h>
       #include<FunctionalTest.h>
       ...
       namespace
       {
       class MyFancyTest:public ITest,
                          public FunctionalTest
       {
       public:
          typedef std::vector<CustomTypes::Bar*>BarAry_t;
       public:
          virtual void preExec();
          virtual void exec();
          virtual void postExec();
       public:
          void setName(OFCString &name);# Automatic for all tests
          void setPatternTree(PatternTree*);
          void addTestCondition(TestCondition*);
          void addBarParam(CustomTypes::Bar*);
          void setBinaryOpParam(CustomTypes::BinaryOp*);
          ...
       private:
           double m_someVar;
       private:
           OFCString m_name;# Automatic for all tests
           PatternTree*m_PatList;
           TestConditionPtrsAry_t m_testCondnsArray;
           BarAry_t m_barsArray;
           BinaryOp *m_binaryOp;
           ...
       };//End class MyFancyTest
       ...
       inline void
       MyFancyTest::addBarParam(CustomTypes::Bar*arg)
       {
           m_barsArray.push_back(arg);
           returu;
       }
       inline void
       MyFancyTest::setBinaryOpParam(CustomTypes::BinaryOp*arg)
       {
         m_binaryOp=arg;
         return;
       }
       }// End namespace
C8.参数化
[337]如上面所看到的,用于Test类、定制Flowable类或定制函数定义的pre-header通过参数化说明部分提供了对类/函数有限的自我测量。编译器使用这个部分生成用于类/函数的参数化接口(并生成类/函数头本身)。对于Test类和Flowable类,它还使用这部分随后在测试计划代码中生成初始化该类实例的调用。应当注意以下关于pre-header和对应声明的点:
1.每个Test或定制Flowable类定义都优选地在pre-header中指定。pre-header中的Parameter块优选地是可以指定用于这种类的参数列表的唯一地方。(因此,作为必然的结果,用于Test的“标准”参数,例如模式列表和测试条件说明,也需要包括在Parameter块的pre-header中;这允许标准和CT的所有测试统一处理)。
2.在用于Test或Flowable的pre-header中定义为非可选(即,具有非零集的势)的所有参数都应当在用于该类实例的Test块或Flowable块声明中初始化。
3.用于Test/Flowable块中参数初始化的对象应当在前面已经定义了。
4.替换指示符$Class、$Inc、$ParamAryTypes、$ParamFns、$ParamAttrs与$ParamImpls必须出现在pre-header的用户代码部分中用户想将对应的所生成代码***所生成类头文件中的确切位置。由于为每个都生成特定的代码,因此这些应当确切地只出现一次。
5.pre-header的Parameter块中参数说明的名字(例如以上例子中的PListParam、TestConditionParam或BarParam)是要用于该类实例的声明中的参数名字。
6.以下是用于参数说明中的描述的语义:
a.Cardinality:这指出将支持的这种类型参数的个数。以下是一种实施方式中的可能值:
i  1:这个参数是强制的,而且应当确切地只指定一次。这个参数将作为对该类型参数对象的指针维护。
ii  0-1:这个参数是可选的;如果指定,则必须只指定一次。这个参数将作为指向该参数类型对象的指针保持。
iii  1-n:这个参数是强制的。而且,可以对这个参数指定多个值。值以指定的次序存储。
iv  0-n:这个参数是可选的。可以对这个参数指定多个值。值以指定的次序存储。
应当注意,对于以上的()和(),所有指定的值都存储在STL向量<>中,根据指向参数类型的指针建立模板。这个向量的类型将被定义并***到由$ParamAryTypes指示的点。对这些类型定义的访问级总是公有的。
b.Attribute:作为这种类型参数值的存储使用的C++变量的名字。该名字将作为C++类的私有数据成员逐字被复制,并且必须遵循C++标识符的需求。应当注意,这种属性的类型是:
i如果只允许单个值,则是指向参数类型的指针;
ii如果允许多个值(见以上()),则是关于指向参数类型的指针建立模板的STL向量<>。
应当注意,属性保持对由测试计划创建和构成的对象的引用,但不拥有这些对象。对象的寿命总是由测试计划本身管理的。
c.SetFunction:用于设置这个参数值所使用的函数名。以下要点应当注意:
i名字应当是逐字复制的,因此必须遵循C++语言需求。
ii函数的访问级总是公有的。
iii返回类型总是void。
iv函数总是只带单个变元,类型是指向参数类型的指针。
[338]应当注意,值总是单独设置的,即,对于允许指定多个值的参数,测试计划中所生成的代码将重复调用这个函数,对每个指定的值调用一次,每个值都将添加到STL向量(如上所述)。
[339]函数名之后的可选关键字“[implement]”指示这个函数的通常实现将作为内联方法在类头中可用(在由$ParamImpls指示的点***)。否则,用户负责提供该函数的实现。
d.Description:作为工具提示的字符串文字,将由GUI工具用于在这个参数的运行时修改中提供帮助。在用于名字为Xxx的参数的定制类中所生成的C++成员函数将是
              String getXxxDescription()const;
该函数将返回指定的字符串。
定制的测试计划例子
[340]以下所示是利用某种定制修饰的测试计划例子:
         # ---------------------------------------------------------
         # File MyCustomizedTestPlan.tpl
         # ---------------------------------------------------------
         Version 0.1;
         #
         # Imports as before ...
         # The following import is implicit,but can be explicitly
         # provided.
         Import FunctionalTest.ph;
         # Import for MyFlowables,MyFunctions and Functions
         Import MyFlowables.ph;
         Import MyFunctions.ph;
         Import Functions.ph;
         # ---------------------------------------------------------
         # Start of the test plan
         # ---------------------------------------------------------
         TestPlan Sample;
         # This block defines Pattern Lists file-qualified names and
         # Pattern List variables that are used in Test declarations.
         # The file-qualified names refer to pattern lists in the named
         # files.The variables refer to String variables which will
         # hold the pattern list names at run time.User defined Flowable
         # objects could set the values of these variables through an
         # API.
         PListDefs
         {
            # Filc qualified pattern list names
            p11A.plist:pat1Alist,
            p12A.plist:pat2AList,
            # Pattern list variables
            plistXxx,
            plistYyy,
            plistZzz
         }
         # SocketDef,UserVars declaration as before ...
         # Declarations of TestConditions TC1Min,TC1Typ,TC1Max,
         # TC2Min,TC2Typ,TC2Max as before ...
         #
         # Declare a FunctionalTest.“FunctionalTest”refers to a C++
         # test class that runs the test,and returns a 0,1or2 as
         # aResult.The Test Condition Group TCG1 is selected with
         # the″min″seleaor by referring to the TC1Min TestCondition.
         #
         # Note that compiler can compile this because of the imported
         # FunctionalTest.ph file.
         #
         Test FunctionalTest MyFunctionalTest1Min
         {
             PListParam=pat1AList;
             TestConditionParam=TC1Min;
         }
         #
         # Additional FunctionalTest declarations for the following,as before
         #      MyFunctionalTest1Typ
         #      MyFunctionalTest1Max
         #      MyFunctionalTest2Min
         #      MyFunctionalTest2Typ
         #      MyFunctionalTest2Max
         #
         # Here is a declaration of MyFlowable.It uses a PatternList variable
         # plistXxx which is initialized by the flowable prior to use here.
         #
         # Compiler can compile this because of the imported MyFlowables.ph file:
         Flowable MyFlowable MyFlowablel
         {
            Int1=10;
            Int2=20;
            StringItem=“Hello World”;
            PListParam=plistXxx;
         }
         # Counters for PassCount and FailCount as before ...
         # Flows as before.Flows FlowTest1 and FlowTest2 are
         # unchanged wrom the previous example.
         Flow FlowTest1
         {
             #...
         }
         Flow FlowTest2
         {
            #...
         }
         #
         # Now FlowMain,a main flow,can be presented.It
         # implements a finite state machine that calls FlowTest1
         # and FlowTest2 as below:
         # ---------------------------------------------------------
         #                Result 0        Result 1
         # ---------------------------------------------------------
         #  FlowMain_1    FlowMain_2      return 1
         #  FlowMain_2 FlowMain_3         return 1
         # FlowMain_3       FlowMain_4   return 1
         # FlowMain_4       FlowMain_5   return 1
         # FlowMain_5       return 0     return 1
         #
         # Where the IFlowables run by each FlowItem are:
         # ---------------------------------------------------------
         #     FlowItem          IFlowable that is run
         # ---------------------------------------------------------
         #     FlowMain_1        MyFlowable1
         #     FlowMain_2        DatalogStartFlow
         #     FlowMain_3        FlowTest1
         #     FlowMain_4        FlowTest2
         #     FlowMain_5        DatalogStopFlow
         #
         Flow FlowMain
         {
            #
            # The first declared flow is the initial flow to be
            # executed.It goes to FlowMain_InitializationFlow
            # on success,and returns 1 on failure.
            #
            FlowItem FlowMain_1 MyFlowable1
            {
               Result 0
               {
                  Property PassFail=″Pass″;
                  IncrementCounters PassCount;
                  # A user function call
                  MyFunctions. Print(“Passed MyFlowablel”,
                                       Functions.GetDUTID());
                  GoTo FlowMain_2;
               }
               Result 1
               {
                  Property PassFail=″Fail″;
                  IncrementCounters FailCount;
                  # A user function call
                  MyFunctions. Print(“Failed MyFlowable1”,
                                       Functions.GetDUTID());
                  SetBin SoftBins.“3GHzLeakage”;
                  Return 1;
               }
            }
            #
            # Goes to FlowMain_3 on success
         # and returns 1 on failure.
         #
         FlowItem FlowMain_2 DatalogStartFlow
         {
            Result 0
            {
               Property PassFail=″Pass″;
               IncrementCounters PassCount;
               # A user function call
               MyFunctions.Print(“Passed DatalogStartFlow”,
                                   Functions.GetDUTID());
               GoTo FlowMain_3;
             }
             Result 1
             {
                Property PassFail=″Fail″;
                IncrementCounters FailCount;
                MyFunctions.Print(“Failed DatalogStartFlow”,
                                    Functions.GetDUTID());
                Return 1;
             }
         }
         # This FlowItem calls the previously defined FlowTest1
         FlowItem FlowMain_3FlowTest1
         {
            Result 0
            {
               Property PassFail=″Pass″;
               IncrementCounters PassCount;
               # A user function call
               MyFunctions.Print(“Passed FlowTest1”,
                                  Functions.GetDUTID());
               GoTo FlowMain_4;
            }
            Result 1
            {
               Property PassFail=″Fail″;
               IncrementCounters FailCount;
               # A user function call
               MyFunctions.Print(“Failed FlowTest1” ,
                                  Functions. GetDUTID());
               SetBin SoftBins.“3GHzCacheFail”;
               Return 1;
           }
         }
         # This FlowItem calls the previously defined FlowTest2
         FlowItem FlowMain_4 FlowTest2
         {
            Result 0
            {
               Property PassFail=″Pass″;
               IncrementCounters PassCount;
               # A user function call
               MyFunctions.Print(“Passed FlowTest2”,
                                  Functions.GetDUTTID());
               GoTo FlowMain_5;
            }
            Result 1
            {
               # FlowTest1 passed, but FlowTest2 failed
               Property PassFail=″Fail″;
               IneremntCounters FailCount;
               # A user function call
               MyFunctions.Print(“Failed FlowTest2”,
                                  Functions.GetDUTID());
               SetBin SoftBins.“3GHzSBFTFail”;
               Return 1;
               }
         }
         FlowItem FlowMain_5 DatalogStopFlow
         {
            Result 0
            {
               # All Passed!
               Property PassFail=″Pass″;
               IncrementCounters PassCount;
               # A user function call
               MyFunctions.Print(“Passed all!”
                                  Functions.GetDUTID());
               SetBin SoftBins.“3GHzAllPass;
               Return 0;
           }
           Result 1
           {
              # FlowTest1 and FlowTest2 passed,
              # but DatalogStopFlow failed
              Property PassFail=″Fail″;
                IncrementCounters FailCount;
                # A user function call
                MyFunctions.Print(“Failed DatalogStopFlow”,
                                   Functions.GetDUTID());
                Return 1;
             }
           }
         }
[341]关于以上代码,需要指出以下要点:
1.这里的PListDefs部分有一些PList名字还有一些PList变量。PList名字是可以在测试中直接使用的名字。PList变量是可以在测试中使用的变量,其值在运行时由定制Flowable中的代码绑定到实际的PList。
2.PListDefs部分是可选的。如果不存在,则其内容可以由编译器从各测试声明中推断。如果存在,则必须声明测试所使用的所有PList参数,当然也可以声明更多个。
3.运行时API可用于向PList变量指定值。TestPlan类将具有函数:
Status SetPListVariable(const Tester::String& varName,
                        const Tester::String& fileQualifiedPListName);
Flowable将能够使用以上函数将PListVariable绑定到特定的PList。
4.用户函数可以在FlowItems中刚要转移之前调用,其中转移或者是将控制转移到其它FlowItem,或者是返回。
用于用户函数调用的C++
[342]除了在流中调用定制函数,由编译器生成的C++代码已经对前面给出的各种定制技术示出了。FlowItem中的用户函数调用优选地是由每个流的IUserCalls成员处理的。每个流优选地具有导出单个虚拟成员函数的接口IUserCalls的成员,如下所示:
      class IUserCalls
      {
      public:
         virtual void exec(const String& flowItemName,
                      unsigned int result)=0;
       };
[343]当遇到具有用户函数调用的流时,流以实现以上接口的类的实例构成。例如,在流例子中的FlowMain中将以以下类的实例构成:
      class FlowMain_UserCalls:public IUserCalls
      {
      public:
         virtual void exec(const String& flowItemName,
                            unsigned int result)
         {
             if(flowItemName==“FlowMain_1”)
             {
                //...
             }clsc if(flowItemName==“FlowMain_2”)
             {
                //...
             }else if(flowItemName==“FlowMain_3”)
             {
                switch(result)
                {
                case 0:
                    MyFuntions::Print(“Pased FlowTest1”,
                                       Functions::GetDUTID());
                    return;
                case 1:
                    MyFunctions::Print(“Failed FlowTest1”,
                                        Functions::GetDUTID());
                    return;
                default:
                    return;
                }
            }
            else if (flowItemName==“FlowMain_4”)
            {
                //...
            }
            else if(flowItemName==“FlowMain_5”)
            {
                //...
            }
         }
      };
[344]FlowItem::execute()操作知道流项的名字。在返回指向下一流的指针之前,它将对所包含的流调用IuserCalls::exec(),传递其自己的流项名字和当前结果的值。这将使以上代码执行,调用所需的用户定义函数。
C9.测试程序编译
[345]如上面所解释的,测试计划描述文件指定测试计划中所使用的对象及其彼此的关系。在一种实施方式中,这个文件翻译成将在站点控制器上执行的形式为标准接口ITestPlan实现的C++代码。这种代码将包装到可以加载到站点控制器上的Windows动态链接库(DLL)中。生成的测试程序DLL具有站点控制器软件可以用于生成并返回它所包含的TestPlan对象的标准已知输入点。
从测试计划描述的构造
[346]从测试计划描述到ITestPlan实现的转换处理是由测试程序编译器400实现的。这个处理发生在两个阶段:翻译与编译。
[347]在翻译阶段402,编译器400处理测试计划文件(及它导入的各种其它文件)及测试计划中所使用的所有测试类型的pre-header。在这个阶段,它创建测试计划对象的C++代码和所遇到的测试类型的C++头,及所有其它支持的文件,例如MSVC++(微软的Visual C++)工作区和项目文件、DLL“boilerplate”代码等。编译器400将文件和行伪指令***到所生成的代码中,以确保编译时错误消息指回描述文件中适当的位置,而不是指向所生成的代码。
[348]在发生在编译器创建必需文件之后的编译阶段,调用例如MSVC++编译器的标准编译器404来编译文件并将它们链接到DLL中。
[349]编译器取有效测试计划文件(和所有相关的文件)作为输入并根据需要生成TestPlan文件和由测试计划文件中“Import”伪指令表示的所有其它文件。此外,它生成MSVC++“解决方案”来建立测试计划DLL。例如,如果主文件(MyTestPlan.tpl)包括要结合定时信息的Timingl.tim,则除了别的以外,编译器还将创建以下文件:
  MyTestPlan.h
  MyTestPlan.cpp
  Timing 1.cpp
  MyTestPlan.sln(MSVC++“解决方案”文件)
  MyTestPlan.vcproj(MSVC++“项目”文件)
[350]在所有文件都创建(或更新)之后,编译器调用MSVC++“解决方案”应用,指定它所创建的“解决方案”并创建DLL。任何错误和/或警告都将显示给用户。
[351]在建立测试计划后,如果用户对Timingl.tim进行修改,则用户将调用编译器,向其传递MyTestPlan.tpl。编译器将(通过时间戳信息)识别出主测试计划未改变,因此MyTestPlan.h/.cpp将不再重新创建。但是,在处理主测试计划文件的同时,将看到Timing1.tim改变了。因此,将重新创建Timing1.cpp文件,并调用MSVC++应用重新建立DLL。这避免了重新编译MyTestPlan.cpp,而只编译Timing1.cpp并重新链接DLL。对于需要相当大量的时间进行编译的大测试计划,这种方法对于缩减重新编译和重新链接时间是非常有用的。
D.运行测试程序
[352]站点控制器软件将测试程序DLL加载到其处理空间中并调用DLL中的“工厂”函数来创建测试计划对象的实例。一旦测试计划对象已经创建,站点控制器软件就可以执行测试计划或者以任何其它必要的方式与其交互。
非交互式建立
[353]对于Windows环境中的大部分C++软件开发人员,建立应用(或DLL,或库,等等)意味着提供开发环境(微软Visual C++、Borland C++,或类似的其它环境)、编辑代码及(常常是)按下按钮来建立产品。
[354]本发明实施方式的测试环境将具有类似的动作集合。测试计划开发人员将需要编辑代码并建立他们的测试计划。但是,测试器不需要测试计划开发人员为了生产结果测试计划DLL而提出C++开发环境。
[355]为了实现这个目的,本发明采用非交互式建立的概念。非交互式建立定义为以非交互模式使用MS Visual C++的建立。应当注意,这仍然允许其它工具交互式地用于管理这种建立。唯一的含意是Visual C++是非交互式使用的。
假设的环境
[356]关于用户环境,进行特定的假设。这些假设是:
1.测试计划开发人员将根据以上方法与规则开发他的测试计划。
2.测试计划开发人员可能不具有对C++的专家级知识。
3.测试计划开发人员将能够访问将文件转换成测试计划DLL的命令行工具或GUI工具。
不用按钮建立应用
[357]利用MS Visual Studio非交互式地工作需要两种方法中的一种。第一种(最简单的一种)是使用命令行接口。第二种(更灵活的一种)是使用自动化接口。这部分描述这两种方法。
创建项目
[358]为了非交互式地使用MS Visual Studio,应当以包含一个或多个有效项目的工作解决方案开始。不幸的是,这是一个不能从命令行或自动化方法实现的任务。任何一种方法都不能提供用于项目创建的机制。但是,用于Visual Studio的项目与解决方案可以从模板创建。因此,给定开始的项目名和模板,我们就可以为Visual Studio创建解决方案/项目。
填充项目
[359]由于命令行不支持,因此向产生的项目添加新文件使用Visual Studio自动化模型。我们提供两种Visual Studio宏来向项目添加新的和现有文件。类似的代码可以由使用ActiveScript引擎的外部脚本(例如VBScript、JScript、ActivePerl、ActivePython等)用于执行相同的任务。因此,我们的代码生成工具可以创建新的文件并利用自动化模型将它们添加到现有的Visual Studio项目中。在文件创建之后,它们可以由工具根据需要更新。
建立项目
[360]一旦我们在适当的位置有了解决方案和项目,就有了利用Visual Studio非交互式地建立测试计划的几种选项。最简单的选项是从命令行调用它。这种命令行看起来象:
     devenv solutionFile/build solutionCfg
其中solutionFile是Visual Studio文件而solutionCfg是可用于解决方案中的项目的特定配置。另一解决方案是使用自动化的Visual Studio对象模型。这允许对建立与配置处理的更细粒度的控制。如上面所提到的,它包含从命令行建立项目的Perl脚本列表。这个程序读取指定要建立的项目与配置的配置文件(及其它关于项目的信息)并利用自动化模型建立它们。看这个脚本中$msdev对象的使用,作为脚本中如何使用自动化对象的例子。
调试器支持
[361]为了让Test类的开发人员验证并调试他们的工作,他们需要访问允许他们进入站点控制器并单步调试他们的代码的调试器。由于编译器生成的代码是由MSVC++编译的C++,因此我们使用MSVC++调试器来调试Test类的实现。应当注意,这个特征只对Test类开发人员或其它直接在C++中工作的人员有意义。其它机制将提供给希望调试或单步调试Test程序运行而不直接参考所生成的C++代码的测试工程师。
***软件环境
[362]这部分描述用于测试器的通用软件环境:用户测试计划所需文件的位置,指定这种文件可选位置的机制及用于指定测试计划和模块控制软件位置的方法。
测试计划所需的环境
[363]***标准位置及测试计划所需的用于
1.模式列表,
2.模式,
3.定时数据,及
4.测试类DLL
的搜索路径的运行时配置可以由“environment”变量配置并由环境配置文件指定。这些是文本文件,具有如下的简单语法:
Tester_PATOBJ_PATH=“patterns\data;D:\projects\SC23\patterns\data”
[364]在文本文件中定义这种“environment”变量而不是通过本地OS支持的环境变量定义的优点是实现不受OS支持环境变量所具有的共同约束的限制,例如最大字符串长度等。以下“environment”(设置)变量将用于以上列出的实体:
模式列表:Tester_PATLIST_PATH.
模式目标文件:Tester_PATOBJ_PATH.
模式源文件:Tester_PATSRC_PATH(这是可选的;请看).
定时数据文件:Tester_TIMING_PATH.
测试类DLL:Tester_TEST_CLASS_LIBPATH.
[365]为了支持特定的情况,在维持有用缺省特性的同时,我们提供三级配置。这以递增的优先次序描述:
[366]首先,***环境设置文件
$Tester_INSTALLATION_ROOT\cfg\setups\Setup.env,将指定“environment”变量的缺省值。如果没有其它的配置机制可用,则将需要这个文件。总的来说,它对运行在***上的所有测试计划可用。这个文件是由安装与配置管理(ICM)***在安装过程中创建的,其中自安装程序的输入指定上面提到的三个变量缺省值。(应当注意,如在以下子部分中所描述的,除了用于以上三个变量的***缺省值,这个文件还将包含用于特定的其它测试器“environment”变量的***缺省值)。
[367]其次,环境设置文件可以由用户作为对测试计划的运行时参数指定。这个运行时配置中的变量将比缺省定义优先。
[368]最后,测试计划可以使用特定的块来指定其执行中要使用的环境变量。在测试计划中定义的变量比***文件或用户定义文件中的那些变量优先。
[369]总的来说,所有必需的变量都应当通过上述一种机制定义。如果变量没有定义,则会发生运行时错误。
其它环境设置
[370]除了用户测试计划所需的“environment”变量,以下两个“environment”变量也是测试环境所需的:
1.Tester_TEST_PLAN_LIBPATH:这指定***控制器用于查找应当加载的测试计划DLL的搜索路径。应当注意,相同的搜索路径也将用于查找用户引脚描述和套接字文件。在安装时指定给ICM的这个变量的缺省值由ICM存储在文件
$Tester_INSTALLATION_ROOT\cfg\setups\Setup.env中。
2.Tester_MODULE_LIBPATH:这指定***将用于加载厂商提供的硬件模块控制软件DLL的搜索路径。从配置管理数据库(CMD)提取的这个信息也由ICM存储在文件
$Tester_INSTALLATION_ROOT\cfg\setups\Setup.env中。
[371]应当注意,尽管用户可以覆盖Setup.env文件中对
Tester_TEST_PLAN_LIBPATH变量给出的值,但Setup.env文件中对Tester_TEST_PLAN_LIBPATH变量给出的值不应当由用户改变,除非用户想显式改变用于厂商提供的硬件模块控制软件DLL的搜索路径。
搜索路径说明语义
[372]关于指定搜索路径的“environment”变量,应当注意以下要点:
1.每个都应当是***将要搜索的由分号(“;”)隔开的目录名列表,以便找到特定类型的引用文件。
2.在最初***查找这种“environment”变量的值以后,由用户对其值进行的任何改变(例如,通过编辑环境配置文件)都将只在用户显式“通知”***需要这么做的时候由***注册。
3.当关于“当前工作目录”(CWD)的路径可能导致不确定结果时,由于分布式环境中CWD的概念—例如其中测试器工作的环境—可能不是用户直观期望的概念,因此搜索路径中的相对路径名将解释为相关环境变量(提供定义根的功能性)的特定设置。指定搜索路径中所有相关路径名都将被假设与之相关的根的这个相关环境变量是“Tester_INSTALLATION_ROOT”变量,该变量给出用户***上测试器安装的顶级(即,“根”)目录的位置。
4.目录条目不能包含集合[V:*?<>|;]中的字符,应当注意除了分号(“;”)例外,这个集合中所有其它字符在Windows文件名中都是非法的。因为分号(“;”)用于区分搜索路径中的条目,所以它不应当用在搜索路径条目中。应当注意,路径名可以具有嵌入的空格,但紧挨着路径名前后出现(即,在路径名的第一个非空格字符之前和最后一个非空格字符之后)的所有空格都不看作是路径名的一部分并将被忽略。
5.搜索路径目录将以它们在定义中所遇到的次序搜索。文件的第一次出现将是被选择的那个。
E.测试模式
[373]有效的管理、处理、和加载非常大的测试模式集合是本发明一个实施方式框架的重要体系结构方面。层次模式列表的思想被看作是向终端用户提供易处理概念及容易使用的***的有效工具。
[374]通过测试向量使对DUT的刺激对测试***可用。向量通常可以分类为顺序的(或线性的)、扫描或算法模式生成器(APG)导出的。在本发明一个实施方式的***中,测试向量根据在测试时应用到DUT的模式组织。模式是由用户测试程序中的Pattern对象表示的。在该***中,模式组织为模式列表,由模式列表对象以程序方式表示。模式列表对象表示模式的有序列表或其它模式列表。排序隐含在列表组件的声明次序中。应当注意,如果需要单个模式,则需要由它自己封装在列表中。
[375]用户测试程序中的模式列表对象与磁盘上的模式列表文件关联,该文件包含模式列表的实际定义。因此,模式列表的内容是由相关磁盘文件的内容动态确定的(关于这个,随后将描述)。
[376]模式列表的定义提供了模式列表的显式名称并通过文件名关联来识别模式的有序列表和/或其它模式列表。它还提供执行选项的说明,由于选项可以应用到模式列表和模式,因此这将在描述模式对象后具体描述。模式列表应当遵循以下规则:
     file-contents:
          version-info global-pattern-list-definitions
     version-info:
          Version version-identifier;
     global-pattern-list-definitions:
         global-pattern-list-definition
         global-pattern-list-definitions global-pattern-list-definition
     global-pattern-list-definition:
   global-pattern-list-declaration{list-block}
global-pattern-list-declaration:
   GlobaIPList pattern-list-name optionsopt
list-block:
   list-entry
   list-block list-entry
list-entry:
   pattern-entry;
   pattern-list-entry;
   global-pattern-list-definition;
   local-pattern-list-definition;
pattern-entry:
   Pat pattern-name optionsopt
pattern-list-entry:
   PList pattern-list-reference optionsopt
pattern-list-reference:
   pattern-list-qualified-name
   file-name‘:’pattern-list-qualified-name
pattern-list-qualified-name:
   pattern-list-name
   pattern-list-qualified-name:’pattern-list-name
local-pattern-list-definifion:
   local-pattern-list-declaration{list-block}
local-pattern-list-declaration:
   LocalPList pattern-list-name optionsopt
options:
   option.
   options option
option:
   [option-definition]
option-definition:
   option-name option-parametersopt
option-parameters:
   option-parameter
   option-parameters,’option-parameter
[377]以下是以上所使用未定义非端子符的描述:
1.version-identitier:选自集合[0-9.]的一个或多个字符的序列,其中第一个字符必须是数字。
2.name:选自集合[a-zA-Z_0-9]的一个或多个字符的序列,其中第一个字符必须选自集合[a-zA-Z_]。
3.pattern-list-name:选自集合[a-zA-Z_0-9]的一个或多个字符的序列,其中第一个字符必须选自集合[a-zA-Z_]。
4.file-name:有效Windows文件名(如果文件名中包含任何空格,则必须包含在双引号中)。应当注意,这应当是简单的文件名,即,它不应当有目录成分。pattern-list-reference可以是内部的,指向相同文件中的模式列表,或者外部的,指向其它文件。外部引用需要由file-name限定。
5.option-name:选自集合[a-zA-Z_0-9]的一个或多个字符的序列,其中第一个字符必须选自集合[a-zA-Z_]。
6.option-parameter:选自集合[a-zA-Z_0-9]的一个或多个字符的序列。
[378]模式列表文件支持注释,这意味着可以由模式列表文件解析器忽略。注释以“#”字符开始,并延伸到一行的结束。
E1.模式列表的规则
[379]用于模式列表的静态或编译时规则管理名字的声明与分解。模式列表语言中的名字由global-pattern-list-definition和local-pattern-list-definition声明。它们由pattern-list-reference引用。以下是管理这些声明与引用的一些规则。
1.global-pattern-list-definition和local-pattern-list-definition声明模式列表的名字。pattern-list-reference引用所声明模式列表的名字。全局模式列表的名字是全局已知的。局部模式列表的名字只在它们被声明的列表块中已知。它们可以无需限定地在该列表块中直接引用。在更深的嵌套声明中,局部模式列表将需要由限定的名字引用。
2.局部模式列表名在所包含的模式列表范围内已知,而全局模式列表在***范围内已知。例如:
GlobalPList G1
{
   LocalPList L1
   {
      LocalPList L2
      {
         ...
      }
      GlobalPList G2
      {
         ...
      }
      PList L2;       # OK.Name L2 is known in this scope
      PList G2         # OK.Name G2 is global
      PList L2;       # Error.Name L2 is not known here.
      PList L1.L2;    # OK. Name L1 is known here.L2 is known by
                       #     qualification.
      PList G1.L1.L2; # OK.Qualification by G1 is not needed but
                       # is allowed.
      PList G2;       # OK.Name G2 is global
    }
3.全局模式列表可以是模式列表文件的最外面一级定义,或者在所包含的模式列表中嵌套定义。但嵌套仅仅是为了方便。它们在概念上定义为文件最外面一级的全局模式列表。嵌套的全局模式列表在语义上等于相同名字的最外面(非嵌套)全局模式列表。因此,例如:
        GlobalPList G1
        {
          GlobalPList G2...
        }
在语义上等同于
   GlobalPList G1
   {
     PList G2;# References G2
   }
   GlobalPList G2...
4.所有全局模式列表都是唯一命名的。
    GlobalPList G1
    {
      # Note that this is as if declared at the outermost level
      # with a reference to it right here.
      GlobalPList G2
      {
        ...
      }
    }
    # This declaration will be an error in this or any other file,
    # as the name G2 is already taken.
    GlobalPList G2 # Error.Global name G2 is taken.
    {
      ...
    }
5.局部模式列表总是在还定义局部模式列表名字范围的包含模式列表中嵌套定义。局部模式列表在其被包含的模式列表中唯一命名。局部模式列表在语义上不允许出现在模式列表文件的最外面一级。
       GlobalPList G1
       {
         LocalPList L1
         {
         }
         LocalPList L2
         {
           LocalPList L1 # OK.No local name L1 is declared
   directly
                 # in the enclosing scope defined by L2.
         {
         }
         PList L1;# OK.Refers to L1 declared in L2
         PList G1.L1;# OK.Refers to L1 declared in G1.
       }
       # Error. Redeclaring name L1 when the enclosing
  scope
       # defined by G1 already has an L1 declared in it.
       LocalPList L1;
       {
       }
    }
6.每个模式列表文件都包含用于一个或多个全局模式列表的定义。这直接遵循语法。最外面一级是global-pattern-list-definition,而且必须至少有一个。
7.pattern-name是对模式的引用,在Pat关键字之后。它引用其名字通过将后缀.pat连接到模式名而获得的模式文件中的模式。该文件指示将与为模式定义的搜索路径一起获得的文件。
8.pattern-list-reference是对PList关键字之后的模式列表的引用。该引用包括可选文件名,后面跟着只是由点隔开的名字列表的限定模式列表名。因此,例如,以下可以是pattern-list-reference:
   Plist foo.plist:G1.L1.L2.L3;
其引用文件foo.plist中的全局模式列表G1中所嵌套的L1中所嵌套的L2中所嵌套的局部模式列表L3。以上名字中最左边的名字段是G1。
[380]最左边的名字段必须分解成全局模式列表或者可以从引用点看到的局部模式列表。
[381]pattern-list-reference的名字分解如下进行:
1.每个名字段都分解成在其前面的前缀上下文中声明的名字。
2.如果有文件限定,则最左边的名字段分解成在所命名文件中声明的全局模式列表。
3.如果没有文件限定,则最左边的名字可以分解成所包含范围内的局部模式,而且如果失败,则利用下一包含的范围,等等,直到所包含的全局范围。
4.为了保持全局范围的语义,就象它们在模式列表文件的最外面一级声明的一样,需要将范围的搜索限定到最靠近的包含全局范围。如果嵌套的全局范围是在最外面一级(等效)文本声明的,则名字分解搜索将在检查其范围后终止。
5.如果引用未能由前面的步骤分解,则最左边的名字段可以分解成该相同文件中的全局模式列表。
6.如果引用未能由前面的步骤分解,则最左边的名字段可以分解成通过将.plist后缀添加到最左边名字段所获得的文件中指定的全局模式列表。
7.如果引用未能由前面的步骤分解,则引用是错误的。
[382]如前面所提到的,以上规则指示最左边的名字段分解成可以从引用点看到的局部模式列表或者分解成全局模式列表。
[383]以下例子说明了这些思想中的一些。
             GlobalPlist G1
             {
               PList G3;# OK.Refers to a pattern list later in this
         file.
               PList G4;# OK.Refers to a pattern list in filc
          “G4.plist”
               # OK.Refers to G1 in the file“my_plists.plist”.
               PList my_plists.plist:G1;
               # OK.Refers to a pattern list in file“my_plists.plist”.
         The
               # qualified name refers to a local pattern list named L2
         declared
               # in the scope of a local pattern list named L1 declared
         in the
               # scope of a global pattern list named G1.
               PList my_plists.plist:G1.L1.L2;
               LocalPList L1
               {
                 LocalPList L2
                 {
                 }
               }
               PList L1;# OK.Refers to L1 declared in the
                       # enclosing scope of G1
           }
           GlobalPlist G2
             {
                 LocalPList L2
                 {
                 }
                 GlobalPList G3
                 {
             LocalPList L3
        {
        }
        PList L1;# Error.No L1 declared in this or any enclosing
              # scope;
        # Error.The name L2 is not declared in this scope.Also
        # though L2 is declared in the enclosing scope,this scopc
        # is global,and so no further enclosing scope is examined.
        #
        # Contrast with reference to name L2 in LocalPList L3 below.
        PList L2;
        PList G1.L1;# OK.Refers to L1 in G1.
        # Error.G3 is not really nested inside G1.Since G3
        # is global,it is really declared at an outermost level,
        # and so G1.G3 is meaningless.
        PList G2.G3.L3;
      }
      LocalPList L3
      {
        # OK.Refers to G2.L2.The enclosing global scope is G2
        # and the name L2 is declared in G2.
        PList L2;
      }
    }
[384]所有模式列表文件名与模式文件名都要求在利用它们的整个测试计划中是唯一的。
[385]模式列表引用可以指在相同文件中在引用前或引用后定义的模式列表。
[386]递归与互相递归的模式列表定义是不允许的。尽管在模式列表文件语法中没有什么可以防止用户创建这种定义,但解析器在检测到这种状况时会标记错误。应当注意,有一些成本与这种状态的检测关联。如果用户可以承担保证输入空间没有互相递归定义的责任,则他/她将可以关掉该检查。
          GlobalPList G1
          {
            LocalPList L2
            {
              LocalPList L3
              {
                # Error.L2 runs L3 which runs L2.
                # This is a recursive reference to L2
                PList L2;
                PList G2;
              }
            }
         }
         GlobalPList G2
         {
           # Error.G1.L2 runs L3 which runs G2 which runs
       G1.L2.
           # This is a mutually recursive reference to G1.L2.
           PList G1.L2;
        }
[387]模式与模式列表的语法描述允许对其指定选项。通常,选项是厂商特定的。该语法允许任何模式或模式列表具有多个指定的选项,每个选项具有多个参数。我们描述由大部分厂商识别的一些支持选项。
[388]模式树的动态(即,执行)语义是在定义模式执行序列之后描述的。
E2.模式
[389]图6说明了根据本发明实施方式的模式编译器602和模式加载器604。模式的用户定义内容在纯文本文件的模式源文件606中可以获得。模式编译器将负责将源文件编译成适用加载到测试器硬件上的特定于模块的格式;该后一种文件称为模式目标文件。以下是通用的属性:
1.模式对象是不可以由用户创建的;而用户总是处理模式列表,模式列表是其它模式列表和/或模式的集合。模式列表对象创建、拥有并维护包含在其中的模式对象,同时如果必要则使它们可以由用户访问。
2.模式是在测试计划中唯一命名的,即,测试计划中没有两个模式有相同的名字。模式的名字不同于包含它的文件名。模式文件名是用在模式列表文件中用于指示模式的名字,而模式的实际名字在模式文件中定义。
[390]总的来说,在本发明的一个实施方式中,单个DUT(被测试的设备)可以连接到来自不同厂商的测试器模块。这包括整个模式编译—加载—执行链。主要部分在这部分描述。
E3.模式编译
[391]由此,模式编译器602需要将特定的站点配置作为目标(依照使用的特定于厂商的数字模块)。对于剩下的讨论,术语“module”将用来表示例如数字模块。为了允许将来自不同厂商的模块608集成到***中,以下过程是优选地:
1.每个模块厂商负责以动态可加载的库或单独可执行程序的形式提供其自己的特定于模块的模式编译器610。此编译器库/可执行程序将至少提供采用以下变元的熟知的compile()函数。
a.模式元文件路径名的阵列(一个或多个),
b.引脚描述文件名,
c.套接字文件名,
d.指定编译对象目的地的可选的目录路径名,
e.字符串名称/值对的可选阵列,其允许任意特定于厂商的参数的说明(其可以被其它厂商忽略)
2.模式源文件将提供两种不同类型的部分:
a.“公共”部分,其将包含所有编译器可以访问(但不是必须使用)的信息,以及
b.一个或多个可选的特定于厂商的部分,每个由唯一的厂商代码标识,用于可以通过特定厂商的编译器使用的信息。
3.厂商的编译器将不会直接创建模式目标文件。而是测试设备将提供由目标文件管理器(OFM)614管理的模式对象“metafile”612,目标文件管理器(OFM)614是模式编译器的一部分。模式编译器可位于用作***控制器的计算机上,或者离线,例如在连接***控制器的网络上。到目前为止以抽象术语指代的“模式目标文件”实际上就是该目标metafile。该目标metafile将被命名为与模式源文件相同,伴随由目标文件扩展来代替源文件的扩展。OFM将提供应用编程接口(API)以读出和写入此文件。目标metafile将具有用于存储以下的规定
a.公共头信息
b.特定于模块的头信息,包括标识相应模块和用于该模块的模式数据的位置的信息,
c.特定于模块的模式数据,如模块厂商要求地被组织,且可被模块厂商解释。
[392]OFM API将允许模块厂商的编译器将特定于模块的头信息和数据写入到目标metafile中。注意,目标metafile的这种布局允许模式数据逐模块地被组织,即使在其中在目标站点中的两个或多个模块相同的情况下。
[393]注意,模式编译器可能需要附加的厂商供给的配置信息,以促进特定于模块的硬件加载信息的生成,其可以利用诸如直接存储器存取(DMA)的高效数据通信。
E4.用于模块的模式导入
[394]在一般的过程之后,每个模块厂商将负责提供其自己的模式加载机制615。模块608的模式目标metafile612将特定于模块的数据存储在不同的部分616中。厂商实现将使用OFM API用于从模式目标metafile中访问相关的特定于模块的部分的。测试设备框架将负责依次调用每个模块的加载方法,以将特定于模块的数据从metafile的适当部分加载到模块中。
E5.模式文件
[395]有可能使每个编译器厂商为模式指定完全不同的纯文本格式,实际上这在大多数情况下是真正需要的。但是,总的来说,对应基于循环的测试环境,在对每个向量需要跨模块的相关并完全相同语义的情况下,用于模式文件的共享、通用的语法不仅是期望的,而且是必需的。这种共享的语法是对模式源文件中的“公共”部分指定的。实际上,对于大多数情况,设想“公共”部分是(除头信息以外)在模式文件中需要的唯一部分,而且每个厂商的编译器将只利用该部分工作。这部分给出了所有编译器都应当能够解释的用于模式文件的规则。模式文件应当如下组织:
file_contents        :
                            version_info pattern_definitions
version_info          :
                  Version version-identifier′;′
pattern_definitions            :
                  pattern_definition
               pattern_definitions pattern_definition
pattern_definition       :
                   main_header′{′main_section′}′
                   main_header′{′main_section vendor_sections′}′
                   subr_header′{′subr_section′}′
                   subr_header′{′subr_section vendor_sections′}′
main_header           :
                   MainPattern identifier
main_section          :
                   CommonSection′{′common_contents
main_section_domains′}′
common_contents       :
                   timing_reference timing_map_reference
timing_reference       :
                   Timingfile-name′;′
timing_map_reference     :
                   TimingMap file-name′;′
main_sectio_domains      :
                  main_section_domains main_section_domain
                  main_section_domain
main_section_domain      :
                  Domain domain_name ′{′main_section_contents ′}′
domain_name          :
                  identifier
main_section_contents    :
                  main_section_contents main_section_content
                  main_section_content
main_section_content    :
                  label_spec main_pattern_spec
                  main_pattern_spec
label_spec          :
                  label′:′
label             :
                  identifier
main_pattern_spec        :
                  main_operation_capture_mask_ftag′{′
vectors_and_waveforms′}′
main_operation     :/*empty */
                common_operation
                jal_op
                jsr_op
                jsrc_op
                jsc_op
                exit_op
common_operation        :
                idxi_op
                idxin_op
                    jec_op
                    jech_op
                    jff_op
                    jffi_op
                    jni_op
                    ldin_op
                    nop_op
                    pause_op
                    sndc_op
                    sndt_op
                    stfi_op
                    sti_op
                    stps_op
                    wait_op
   /*
    * Instructions specific to the MAIN Patterns
    */
    jsr_op          :
                    JSR identifier
    jsrc_op          :
                    JSRC identifier
    jsc_op          :
                    JSC identifier
    jal_op          :
                    JAL identifier
    exit_op         :
                    EXIT
   /*
    * Instructions common to both MAIN and SUBR Patterns
    */
    idxi_op        :
                   IDXI 24-bit number
    idxin_op        :
                   IDXIn index-register
    jec_op         :
                   JEC idenifier
    jech_op         :
                   JECH identifier
    jff_op         :
                   JFF identifier
    iffi_op        :
                   JFFI identifier
    jni_op         :
                   JNI identifier
    ldin_op        :
                   LDIN index-register
    nop_op         :
                       NOP
    pause_op            :
                       PAUSE
    sndc_op             :
                       SNDC 8-bit number
    sndt_op             :
                       SNDT 8-bit number
    stfi_op            :
                       STFI 24-bit number
    sti_op             :
                       STI 24-bit number
    stps_op             :
                       STPS
    wait_op             :
                       WAIT
    capture_mask_flag     :  /*empty*/
                       capture_mask_flag CTV
                       capture_mask_flag MTV
                       capture_mask_flag MATCH
    vectors_and_waveforms     :  /*empty*/
                       vectors_and_waveforms vector
                       vectors_and_waveforms waveform
    vector             :
                        vector_declaration′{′vector_data′}′
    vector_declaration     :
                     Vector
                     V
    vector_data        :
                    vector_datum
                    vector_data vector_datum
    vector_datum       :
                    pin_name′=′vector-value ′;′
                    pin_name′=′identifier′;′
    waveform          :
                    waveform_declaraion′{′waveform_data′}′
    waveform_declaration   :
                    Waveform
                    W
    waveform_data       :
                    waveform_datum
                    waveform_data waveform_datum
    waveform_datum         :
                    waveform-table-pin-group-name′=′identifier′;′
    pin_name         :
                    identifier
    vendor_sections        :
                        vendor_sections vendor_section{}
                        vendor_section{}
    vendor_section         :
                        VendorSection′{′vendor_section_contents′}′
    subr header           :
                        SubrPattern
    subr_section          :
                        CommonSection′{′common_contents
    source_selection_table subr_section_domains′}′
                        CommonSection′{′common_contents
    subr_section_domains′}′
    subr_section_domains   :
                        subr_section_domains subr_section_domain
                        subr_section_domain
    subr_section_domain         :
                        Domain domain_name′{′subr_section_contents′}′
    source_selection_table  :
                        SourceSelectionTable′{′source_elector_definitions′}′
    source_selector_definitions:
                        source_selector_definitions source_selector_definition
                        source_selector_definition
    source_selector_definition:
                        SourceSelector source_selector_name′{′
    source_mappings′}′
    source_selector name      :
                        identifier
    source_mappings            :
                          source_mappings source_mapping
                          source_mapping
    source_mapping           :
                          pin_name′=′source′;′
    source                :
                          MAIN
                    INVERT_MAIN
                    SUBR
                    INVERT_SUBR
    subr_section_contents    :
                           subr_section_contents subr_section_content
                           subr_section_content
    subr_section_content     :
                           label_spec subr_pattern_spec
                           subr_pattern_spec
    subr_pattern_spec         :
                           subr_operation capture_mask_flag′{′
    vectors_and_waveforms′}′
    subr_operation     :/* empty*/
                    common_operation
                    rtn_op
                    stss_op
   /*
    * Instructions specific to the SUBR Patterns
    */
    rtn_op         :
                   RTN
    stss_op        :
                   STSS identifier
[396]以下是以上所使用的未定义非终止符的描述:
1.version-identifier:选自集合[0-9.]的一个或多个字符的序列,其中第一个字符必须是数字。
2.identifier:选自集合[a-zA-Z_0-9]的一个或多个字符的序列,其中第一个字符必须选自集合[a-zA-Z_]。
3.vender-section-contents:只对特定于厂商的编译器有意义的任意文本。
4.file-name:有效的Windows文件名(如果在文件名中包含任何空格,则必须包含在双引号中)。应当注意,这应当是简单文件名,即,不应当具有目录成分。
5.waveform-table-pin-group-name:选自集合[a-zA-Z_0-9]的一个或多个字符的序列,其中第一个字符必须选自集合[a-zA-Z_]。这个变量是在其它某个地方声明的,并保留对引脚组公用的波形表的名字。
6.24-bit number:最大为16777215的有限十进制数。
7.8-bit number:最大为256的有限十进制数。
8.index-register:有效十进制数。在模块的一种实施方式中,这可以是值[1-8]。
9.vector:这类似于STIL中的Vector语句。应当注意,这指的是信号名与信号组名,使得对于编译器有必要能够访问引脚描述文件。
10.waveform-time-reference:选自集合[a-zA-Z_0-9]的一个或多个字符的序列,其中第一个字符必须选自集合[a-zA-Z_]。
[397]模式文件将支持注释,注释的意思是将被模式文件编译器忽略。注释以“#”字符开始,延伸到一行的结束。
[398]关于模式文件头和“公共”部分中的结构,应当注意以下要点:
1.pattern-name项指定将与模式文件包含用于其的数据的模式对象关联的名字。这在对应的模式目标元文件中转移到头。
2.waveform-time-reference是用于在模式文件外部,在Timing文件中定义的特定waveform-and-timing定义的名字。模式文件中waveform-time-reference的说明将(用于waveform-and-timing的)特定名字绑定到所有后续的向量,直到遇到另一waveform-time-reference。
3.用于子例程(例如,JSR与JSRC)调用的操作数是应当是在相同模式文件中先前遇到的pattern-spec label或者外部定义的子例程模式中的pattern-spec label。这种操作数最终为加载/处理而分解。用于子例程调用的操作数的标签需要在整个***中唯一。
[399]应当注意,尽管waveform-time-reference名字可以是句法上正确的任何名字,但由于特定的硬件暗示waveform-time-reference名字可能需要限制到先前已知的、很好定义的集合(为了更多的可读性,这可以由用户可选地映射到用户选择的名字,映射在可选文件中给出)。
[400]还应当注意,模式与waveform-time-reference源文件应当提供用于连接到物理测试器通道的所有DUT通道的初始配置。如果后续数据对任何DUT通道忽略,则模式编译器将“***”模式数据,保留来自初始级的输出。
模式文件例子
[401]MAIN模式源文件的简单例子将帮助说明该使用。
#
# Filename:good1.pat
#
Version 1,0;
# ---------------------------------------------------------
# Main Pattern definition:
# ---------------------------------------------------------
MainPattern good1
{
 CommonSection
 {
  MacroDef   defaultDataVal   (XXXXXXXX)
  MacroDef   nopInstr       (NOP)
  MacaoDef   label1         (Label1:)
  MacroDef   jniInst        (JNI)
  # ----------------------------------------------------------
  # Timing Specifications
  # ----------------------------------------------------------
   Timing″productionTiming.tim″;
   TimingMap″productionTimingOpenSTARMap.tmap″;
  # ----------------------------------------------------------
  # Default Domain Cycles
  # ----------------------------------------------------------
  Domain default
  {
   # ---------------------------------------------------------
   # label:instruction{Vector/Waveform Data}
   # ---------------------------------------------------------
       NOP           {V{DATA=$dcfaultDataVal;CLK=1;}W
{DATA=wfsl;CLK=wfsl;}}
     JAL   myAPG     {V{DATA=00000000;}}
     JSC   mySCAN     {V{DATA=10101010;}}
     JSRC   mySubroutine{V{DATA=01010101;}}
     JSR   myAPG      {V{DATA=00110011;}}
     STI   100     {}
 labZero:NOP          {V{DATA=00000011;}}
      JNI  labZero  {V{DATA=11111100;}}
      IDXI  3000    {V{DATA=10101010;}}
      IDXIn  3     {V{DATA=01010101;}}
 $label1 NOP        {V{DATA=$defaultDataVal;}}
          IDXI 2000{V{DATA=10101010;}}
          NOP     {}
         EXIT{V{DATA=LLHHLLHH;}}
 }
  }
}
[402]以下说明用于说明SUBROUTINE模式源文件的另一例子。
         # ---------------------------------------------------------
         # Subroutine Pattern mySubratl definition:
         # ---------------------------------------------------------
         SubrPattern mySubrPatl
         {
          CommonSection
          {
          # ---------------------------------------------------------
          #  Timing Specifications
          # ---------------------------------------------------------
          Timing″productionTiming.tim″;
          TimingMap″productionTimingOpenSTARMap.tmap″;
          # ---------------------------------------------------------
          #  Source Selection Specifications
          # ---------------------------------------------------------
            SourceSelectionTable
            {
            SourceSelector SrcSelDef
             {
                 DATA=SUBR;CLK=SUBR;DATA=SUBR;
               }
               SourceSelector SrcSelOne
               {
                 DATA=MAIN;CLK=MAIN;
               }
            }
          # ---------------------------------------------------------
          #  Default Domain Cycles
          # ---------------------------------------------------------
          Domain default
          {
          # ---------------------------------------------------------
          #label:   instruction{Vector and Waveform Data setups}
          # ---------------------------------------------------------
                  STI    100  {Vector{DATA=00000000;}}
                  IDXI    3000 {Vector{DATA=00001111;}}
                  IDXIn   3   {Vector{DATA=00110011;}}
          $label1 NOP         {Vector{DATA=LLHHLLHH;}}
               NOP           {Vector{DATA=LLXXXXXX;}}
               NOP           {Vector{DATA=LLHHXXXX;}}
               JNI Label1     {Vector{DATA=LLHHLLHH;}}
               STSS SrcSelOne   {Vector{DATA=LHLHLHLH;}}
               RTN        {Vector{DATA=LLXXXXXX;}}
        }
      }
[403]来自模式源文件的主头和公共部分的概述信息存储在目标元文件的主头中。概述包括用于快速提取一般所需的信息,用于帮助地址等的预加载分解或用于帮助数据登录。由于公共部分的语义对于所有编译器都是完全相同的,因此每个编译器都就能够提供相同的概述信息,而且写元文件的第一编译器将存储这种信息。以下是将要存储的信息:
1.模式源文件名。
2.在源文件中所声明的模式类型。
3.来自源文件的版本信息。
4.用在模式源文件的公共部分中的所有waveform-and-timing名字列表。
5.引用模式源文件中公共部分的(相对)向量地址的所有子例程的映射。
6.引用模式源文件中公共部分的(相对)向量地址的所有标签的映射。
7.通用的簿记信息:向量计数、指令计数,等等。
[404]开放体系结构的测试***需要模式与模式列表文件都具有显式和不同的扩展名。对于模式文件,这适用于纯文本源与编译后的目标文件。这被看作是方便用户快速识别目录列表中可见的文件类型等并允许以扩展名为基础进行关联。模式列表文件解析器将期望具有以下扩展名的文件名:
纯文本模式源文件:.pat
编译后的模式目标元文件:.pobj
模式列表文件:.plst
[405]用户可以重写这些缺省值,例如通过测试器环境变量或者设置选项。
[406]测试器将需要在至少一个环境配置文件中定义用于文件搜索路径的以下“环境”变量:
Tester_PATLIST_PATH:用于模式列表文件。
Tester_PATSRC_PATH:用于模式源文件(可选的)。
Tester_PATOBJ_PATH:用于模式目标元文件。
[407]应当注意,如果可选的环境/设置变量Tester_PATSRC_PATH没有定义,则将假定与Tester PATOBJ_PATH相同。总的来说,不定义Tester_PATSRC_PATH比用与Tester_PATOBJ_PATH相同的值来定义更有效。
E6.软件表示
[408]模式对象不是由用户创建的;相反,用户总是处理模式列表对象,其中模式列表对象是其它模式列表和/或模式的集合。模式列表对象创建、拥有并维护包含在其中的模式对象,同时使用户可以访问它们。用户测试程序中的模式列表对象与磁盘上包含模式列表实际定义的模式列表文件关联。模式列表的定义提供模式列表的显式名字并通过文件名关联识别模式和/或其它模式列表的有序列表。这部分描述模式列表和列表的软件表示,作为理解它们如何在测试器框架中操作的开头。
模式列表关联
[409]测试环境中的单个测试站点(及通过扩展还有其中的测试计划)可以与多个顶级模式列表关联。但是,在任何给定时间,对于测试计划都只有一个执行环境。由于高级模式列表为其(分层)引用的模式定义了执行序列,因此活动执行环境是对应于当前所选的顶级模式列表的环境。应当注意,这并不暗示一次只有包含在单个模式列表中的模式可以加载到硬件上;相反,为了使执行序列可行而需要加载到硬件上的模式集合必须总是所有当前加载模式的子集。
模式树
[410]直观上可以感到表示高级模式列表的一种方式是通过树数据结构的某种排序。图7说明了本发明有序模式树的一种实施方式,假定模式列表A是高级模式列表。
模式树信息内容
[411]以下信息将存储在模式树的每个节点上:
1.与该节点关联的实体(模式列表或模式)的名字。
2.定义源的类型。对于叶子(模式节点),这总是模式文件;对于中间(模式列表)节点,这可以是“顶级文件”(对于顶级模式列表定义)或者“嵌入在文件中”(对于嵌套的模式列表定义)。
3.磁盘上节点关联的文件的最后修改时间戳。
[412]以下附加信息将只存储在中间节点(模式列表)上:
1.(如果有的话)关于由该节点表示的模式列表对象设置的执行选项—即,其对象选项。
2.(如果有的话)关于由该节点表示的模式列表定义内的每个孩子引用的执行选项—即,对于其每个孩子的引用选项。
[413]因此,在从根到中间节点的唯一路径上遇到的节点集合和其中遇到它们的序列包含确定由该节点表示的组合、有效的执行选项所必需的所有信息。模式的执行选项是由其中间父亲的有效执行选项结合其中间父亲可能有的用于其的引用选项确定的。
[414]在这里,应当注意尽管模式列表解析器是在创建模式树的过程中,但由于它们的使用环境要到稍后才能分解,因此特定的执行选项可能需要简单地作为字符串的值的初始存储。这种选项的例子是“掩码”选项,它指定引脚掩码信息:模式列表不与套接字信息关联,因此引脚掩码信息(引脚与组名)存储为字符串,在加载之前分解。
[415]以下附加信息将只存储在叶子(模式)节点中:
1.对由该模式调用的子例程的所有(可能是传递的)引用,作为执行树,既有外部的又有内部的。
[416]当然,所有模式节点都将附加地具有对目标元文件公共头中可用的所有模式文件概述信息的访问并可以选择对其高速缓冲。
处理模式列表修改
[417]对模式列表内容进行的改变从概念上影响对该模式列表的所有引用。适当地应用到模式对象及模式列表对象的以下规则将用于管理这种改变:
1.对磁盘上模式列表文件的内容所进行的改变将通过测试***只在关于该模式列表(或关于引用其的任何其它模式列表)执行的load()命令上传播。换句话说,软件中的模式列表层次将总是反映当前加载到硬件上的模式列表。
2.用户将能够设置使加载过程中所进行的同步模式列表与其磁盘文件源的测试失败的模式;这将允许生产模式中更快/更安全的操作。
模式树导航
[418]与测试站点(及通过扩展还与该站点的测试计划)关联的顶级模式列表具有公有(全局)范围。***提供导航表示顶级模式列表的模式树的API,使得用户可以获得对单独节点和子树的访问。
E7.模式列表动态特征
[419]前面描述了模式列表的静态规则。现在给出模式列表动态(执行)规则的描述。
[420]模式树对于总的模式管理是基本的。例如,模式加载序列的起始点是对当前与站点或测试计划关联的模式树调用load()方法。但是,模式树不能孤立地操作。完全初始化的模式树将引用创建以下两个框架对象:
[421]1.顶级模式列表定义模式的模式执行序列。它描述这种执行序列可以如何从对应于该顶级模式列表的模式树导出。例如,图7所示对应于模式树A的模式执行序列是{q,s,t,q,r,q,u,u,v}。模式执行序列是从概念上反映通过模式树描述的执行序列的有序列表。框架建立并维护模式执行序列中模式树节点与对应输入之间的任何必要的导航链接。
[422]2.模式集合,它简单地是模式树中所有唯一模式(包括子例程)的列表。因此,该列表是将用于确定应当加载到硬件上的单独模式列表。框架建立并维护模式集合中模式树节点与对应输入之间的任何必要的导航链接。图7模式树的模式集合是(q,s,t,r,u,v)(假定模式列表A中没有模式包含任何子例程调用)。
[423]应当注意,模式执行序列和模式集合总是可以从模式树导出;但是,只要是可行的,在初始构造之后对它们进行告诉缓冲常常是有意义的。
模式列表执行选项
[424]如上所示,(定义之前的)每个模式列表声明或模式列表/模式引用输入可以后面跟着多个执行选项。模式列表执行选项修改模式列表的运行时执行。为了允许进一步的扩展,用于这些选项的名字(和可选值)将简单地被模式编译器的模式列表文件解析器看作字符串,适当地由特定版本解释。测试器规定以下所述的一组选项及其解释。但是,厂商可以扩展选项集合。为了允许选项语法的解析时确认,模式列表文件解析器可以读取特定版本的信息文件。这种信息文件还可以用于执行特定版本是否从根本上支持执行选项的说明。
[425]对于支持一组执行选项的版本,以下通用规则将管理它们的使用。为了理解这些规则,将模式列表/模式的层次集合可视化为有序的树是有用的。
1.关于模式列表定义设置的固有选项(即,在文件中的“local-pattern-list-declaration,global-pattern-list-declaration”结果中)有效地指导用户测试程序中关于对应模式列表对象设置的选项设置。因此,它们适用于该模式列表对象的所有引用并称为对象选项。
2.关于对模式列表/模式的引用设置的引用选项(即,在文件中的“pattern-entry”和“pattern-list-entry”结果中)限制层次中对特定路径选项的范围—从树的根到所考虑引用的(由模式列表/模式的声明次序建立的)路径。因此,这些是关于特定对象引用(而不是对对象本身)的选项,并称为引用选项。
3.用于层次集合中任何列表/模式的(由模式列表/模式的声明次序建立的)有效选项设置是沿从树的根到该列表/模式的路径遇到的对象与引用选项的组合。特定的组合机制(例如,设置联合、设置交集或任何其它冲突解决算法)是选项本身的属性。
[426]应当注意,以上规则的结果—及没有设置关于模式文件中模式定义的执行选项的工具的事实—是没有设置应用到对模式的所有引用的选项的直接规则。用于实现这个目的的机制是使用单模式模式列表。
[427]测试器指定修改其burst特性并修改其执行序列的模式列表执行选项的特定集合。
[428]当用于模式列表的执行序列提交给硬件时,硬件产生burst。burst是直接由硬件执行模式序列,而不需要软件的任何介入。burst中断是执行序列中前一burst终止而新burst开始的位置。
[429]模式管理软件的一个目标是向硬件提供需要产生burst的执行序列。缺省地,一个模式树生成一个执行序列,该序列如果提交给硬件,就将会导致单个burst。但是,这种特性可以提供使用关于模式列表的选项修改。因此,选项结果的使用会导致burst中断。
[430]此外,用户有时候将需要在每个模式或每个burst之前或其后运行的序言或结尾模式。这修改将要提交给硬件的执行序列。
[431]在创建或修改模式执行序列对象的过程中,框架具有确定(如果需要的话还报告)模式burst中的中断所需要的所有信息,该burst是由所指定执行选项与由模式树体现的特定执行序列的组合而产生的。这么做时,可能需要调查***中模块的硬件能力。例如,一种硬件实现允许引脚掩码的四种存储配置,其中两种(0和3)用于缺省掩码(以支持Marks This Vector,MTV)和非掩码操作。因此,允许用户的两种不同的全局引脚掩码配置,而不需要中断burst模式。
[432]应当注意,如果模块厂商不支持硬件中的模式列表实现,则厂商对模式执行序列的处理将导致执行序列中所有模式的单独执行。在站点兼容和站点异类***中,站点的burst能力将受“最低公分母”的限制。测试器提供特定的缺省选项集合,以下描述其参数。每个选项都是通过声明以下开始的:
它是是固有的(即,与Global或Local关键字的定义关联)还是引用的(即,与Pat或PList关键字的引用关联)。固有选项在定义点和每个引用应用,而引用选项只在其关联的引用时应用。
此外,如果选项假定为递归应用到所有静态(句法上)或动态(通过引用语义上)嵌套的模式或模式列表,则选项称为是被孩子继承的。
[433]以下是选项列表。每个兼容的厂商都将根据指定解释这些选项。
1.Mask<pin/pin group>
当应用到GlobalPList、LocalPList时是固有的,
当应用到PList、Pat时是引用的。
被孩子继承。
这个模式列表将总是具有由禁用的所指示引脚或引脚组引用的引脚比较电路。有时候,硬件限制可能导致burst中断。
2.BurstOff
当应用到GlobalPList、LocalPList时是固有的,
当应用到PList、Pat时是引用的。
不被孩子继承。
这个模式列表将总是在非burst模式执行。这个选项不被孩子继承,但BurstOffDeep选项(下面)是由孩子继承的。
3.BurstOffDeep
当应用到GlobalPList、LocalPList时是固有的,
当应用到PList、Pat时是引用的。
被孩子继承。
这个模式列表将总是在非burst模式执行。这个选项被孩子继承,但BurstOff选项(上面)是不由孩子继承的。应当注意,BurstOffDeep选项不能被孩子关闭。
4.PreBurst<pattern>
当应用到GlobalPList、LocalPList时是固有的,只被不具有所指定burst选项的孩子节点继承。
所指示的模式放到这个模式列表的所有burst之前。PreBurst模式就在每次burst由于这个模式列表节点而开始之前发生。当已经在具有是相同模式的PreBurst选项的burst中时,这个选项不应用。
5.PostBurst<pattern>
当应用到GlobalPList、LocalPList时是固有的,
只被不具有所指定burst选项的孩子节点继承。
所指示的模式放到这个模式列表的所有burst之后。PostBurst模式就在每次burst由于这个模式列表节点而开始之后发生。当已经在具有是相同模式的PostBurst选项的burst中时,这个选项不应用。
6.PrePattern<pattern>
当应用到GlobalPList、LocalPList时是固有的,
不被孩子节点继承。
所指示的模式放到这个模式列表的所有模式之前。
7.PostPattern<pattern>
当应用到GlobalPList、LocalPList时是固有的,
不被孩子节点继承。
所指示的模式放到这个模式列表的所有模式之后。
8.Alpg<alpg object name>
当应用到GlobalPList、LocalPList时是固有的,
不被孩子节点继承。
所指定的ALPG对象存储例如低速APG寄存器设置、读取等待时间、中间数据寄存器、地址数据求逆、数据生成等的相关信息。
9.StartPattern<pattern>
当应用到GlobalPList、LocalPList时是固有的,
不被孩子节点继承。
模式列表将在其执行序列中StartPattern第一次出现时开始执行。
10.StopPattern<pattern>
当应用到GlobalPList、LocalPList时是固有的,
不被孩子节点继承。
模式列表将在其执行序列中StopPattern第一次出现时开始停止执行。
11.StartAddr<vector offset or label>
当应用到GlobalPList、LocalPList时是固有的,
不被孩子节点继承。
这必须与StartPattern选项同时出现。模式列表将在其执行序列中StartPattern第一次出现时在StartAddr开始执行。
12.StopAddr<vector offset or label>
当应用到GlobalPList、LocalPList时是固有的,
不被孩子节点继承。
这必须与StopPattern选项同时出现。模式列表将在其执行序列中StopPattern第一次出现时在StopAddr停止执行。
13.EnableCompare StartPattern<pattern>
当应用到GlobalPList、LocalPList时是固有的,
不被孩子节点继承。
模式比较将在所指示模式第一次出现时开始。
14.EnableCompare_StartAddr,EnableCompare_StartCycle
当应用到GlobalPList、LocalPList时是固有的,
不被孩子节点继承。
这必须与EnableCompare_StartPattern同时出现。指示模式中模式比较要开始的地址或循环。
15.EnableCompare_StopPattern<pattern>
当应用到GlobalPList、LocalPList时是固有的,
不被孩子节点继承。
模式比较将在所指示模式第一次出现时完成。
16.EnableCompare_StopAddr,EnableCompare_StopCycle
当应用到GlobalPList、LocalPList时是固有的,
不被孩子节点继承。
这必须与EnableCompare_StopPattern同时出现。指示模式中模式比较要完成的地址或循环。
17.Skip
当应用到PList、Pat时是引用的。
不被孩子节点继承。
使得跳过由模式列表支配的模式或整个序列。这还使得跳过在这个模式列表子树根的所有选项。就象这个模式子树对于执行目的来说不存在一样。
模式列表burst控制
[434]如前面所描述的,当用于模式列表的执行序列提交给硬件时,硬件产生模式序列的burst,而不需要软件的任何介入。burst中断是执行序列中前一burst终止而新burst开始的位置。如在以上选项列表中所描述的,PreBurst、PostBurst、BurstOff和BurstOffDeep选项控制burst中断在哪里发生。PreBurst和PostBurst选项确定服从下述特定附加规则的burst中断:
1.当父亲列表具有PreBurst和PostBurst选项且嵌套列表具有相同的对应选项时,没有burst中断,且嵌套列表的PreBurst和PostBurst选项不应用。只有单个burst应用父亲列表的PreBurst和PostBurst。
2.注意,当嵌套列表不具有burst选项时,等效于具有通过这些选项的描述与父亲列表相同的PreBurst和PostBurst选项。因此,不具有burst选项的嵌套列表不会导致burst中断。
3.如果以上规则1不应用且对从父亲列表开始到嵌套列表开始的模式执行序列有影响,则在嵌套列表的开始有burst中断。在这种情况下,父亲列表的PreBurst和PostBurst应用到从父亲列表开始的模式执行序列的这种影响。嵌套列表的PreBurst和PostBurst应用到嵌套列表。
4.如果以上规则1不应用且对从嵌套列表结束到父亲列表结束的模式执行序列有影响,则在嵌套列表的结束有burst中断。在这种情况下,父亲列表的PreBurst和PostBurst应用到对从父亲列表开始的模式执行序列的这种影响。嵌套列表的PreBurst和PostBurst应用到嵌套列表。
5.如果规则1不应用且对从除嵌套列表以外的父亲列表开始的模式执行序列没有影响,则父亲列表的PreBurst和PostBurst不应用。只有单个burst应用嵌套列表的PreBurst和PostBurst。
[435]以下是说明选项对执行序列作用的一些例子。为了简化,假定所有模式列表都在单个文件中指定。
[436]例子1:BurstOff的使用
[437]这个例子说明BurstOff和PreBurst。特别要强调的是BurstOff使模式单独运行在一个模式长的burst中。因此PreBurst选项仍然应用。输入模式列表如下:
   Global A[BurstOff][PreBurst pat_z]
   {
       Pat   q;
       PList B;
       Pat   r;
       Pat   s;
   Global C
   {
       Pat   t;
       PList D;
    };
       PList D;
       PList E;
    };
    Global B
    {
       Pat a;
       Pat b;
    };
    Global D[BurstOff]
    {
       Pat c;
       Pat d;
     };
     Global E
     {
       Pat e;
     };
根在A的树可以在图8中表示。
[438]以下是用于这个模式的执行序列。字符|指示burst中断。这个模式列
表在10个burst中执行,第一个具有模式z和q,最后一个具有模式e:
     z q|a b|z r|z s|t|c|d|c|d|e
[439]应当注意以下关于这个执行序列的要点:
1.由于关于A的BurstOff选项没有被B继承,因此B中的模式a和b作为burst操作。
2.由于关于A的PreBurst选项没有被B继承,因此B的burst中的a和b前面没有加上z。
3.前面加z只对由于作为a的直接孩子,即模式q、r和s,而执行的模式发生。由于A具有BurstOff选项,因此这些模式是单独执行的,就象在只有一个模式长的burst中。BurstOff需要模式在一个模式长的burst中单独运行。因此,PreBurst和PostBurst选项仍然应用。
4.模式列表D具有使其孩子c和d单独执行的固有burstoff选项。它们不从A继承PreBurst z。
[440]例子2:BurstOffDeep的使用
[441]这个例子说明了BurstOffDeep选项。模式列表定义过程中的BurstOffDeep影响嵌套定义与引用列表。但是,PreBurst和PostBurst选项不被嵌套和引用列表继承。该例子使用与例子1中相同的模式A、B、C、D、E,但选项是不同的:
5.关于A定义的选项:[BurstOffDeep]、[PreBurst z]、[PostBurst y]
6.对任何其它节点都没有其它选项。
[442]执行序列如下。就象前面,|字符指示burst中断。
     z q y|a|b|z r y|z s y|t|c|d|c|d|e
注意,以下关于这个执行序列的要点:
1.PreBurst和PostBurst选项不被B、C、D、E继承。
2.BurstOffDeep被B、C、D和E继承。
[443]例子3:PreBurst和PostBurst继承
[444]现在假定考虑例子1的模式列表树,其中选项是:
1.关于A定义的选项:[PreBurst x]、[PostBurst y]
2.关于A定义的选项:[PreBurst x]、[PostBurst z]
3.对任何其它节点都没有其它选项。
[445]执行序列将是:
x q a b r s t c d c d e y
[446]“t c d”子序列不是“x t c d z”的原因如下:
1.第一个x是禁止的,因为它等于与有效的当前burst关联的pre-burst选项。
2.最后一个z是禁止的,因为PostBurst z没有继承到D,而且没有从C生成的z可以附加到其上面的模式。
[447]例子4:Skip的使用
[448]这个例子说明了关于嵌套定义和引用列表的Skip选项的作用。该例子使用与例子1中相同的模式A、B、C、D、E,但选项是不同的:
1.关于A定义的选项:[Skip]、[PreBurst z]、[PostBurst y]
2.关于对r引用的选项:[Skip]
3.关于C定义的选项:[Skip]
[449]执行序列是如下没有中断的单个burst:
z q a b s c d e y
[450]注意以下关于这个执行序列的要点:
1.用于r和C的节点被跳过。
2.根本没有burst中断。
[451]例子5:Mask的使用
[452]这个例子说明了Mask的作用及其对模式和模式列表定义与引用的作用。该例子使用与例子1中相同的模式A、B、C、D、E,但选项是不同的:
1.关于A定义的选项:[mask pin1_pin2]、[PreBurst z]
2.关于对B引用的选项:[mask pin3]
3.关于B定义的选项:[mask pin4]
4.关于对e引用的选项:[mask pin5]
5.对任何节点都没有其它选项。
[453]名字“pin1_pin2”指定掩码Pin1和Pin2的组。名字“pin3”、“pin4”和“pin5”分别指定掩码Pin3、Pin4和Pin5。以下提供该执行序列,|指示burst中断。每个模式下的数字指示在该模式执行过程中被掩码的引脚。
           z q a b z r z s t c d c d | e
           1 1 1 1 1 1 1 1 1 1 1 1 1   1
           2 2 2 2 2 2 2 2 2 2 2 2 2   2
                 3 3                   5
                 4 4
[454]注意以下关于这个执行序列的要点:
1.厂商的硬件如果没burst中断的话只可以容纳两个掩码块。在e执行之前,这两个掩码块是引脚{1,2}和引脚{1,2,3,4}。当模式e以引脚{1,2,5}的不同掩码块到达时,硬件需要burst中断。
[455]例子6:继承选项与引用的使用
[456]这个例子说明了当定义被引用时,在定义处的继承选项不应用。考虑以下例子:
               Global A
               {
                  Global B[BuestOffDeep]
                  {
                   Global C
                   {
                   ...
                   };
                   ...
                  };
                ...
                PList C;
              };
              Global D
              {
                PList C;
              };
[457]BurstOffDeep选项是由C在其定义的点继承的。但是,它不是固有选项,因此在其两个引用点不会应用到C。
[458]例子7:对于嵌套列表的PreBurst和PostBurst
[459]考虑以下例子:
             GlobalPList A[PreBurst x][PostBurst y]
             {
               Pat p1;
               LocalPList B[PreBurst x][PostBurst y]
               {
                 Pat p2;
               }
                         LocalPList C
                         {
                           Pat p3;
                         }
                         LocalPList D[PreBurst x][PostBurst z]
                         {
                         Pat p4;
                         }
                         LocalPList E[PreBurst w][PostBurst y]
                         {
                           Pat p5;
                         }
                         Pat p6;
             }
[460]该执行序列是:
     x p1 p2 p3 y|x p4 z|w p5 y|x p6 y
1.因为嵌套列表的PreBurst和PostBurst选项指定为与父亲的相同,所以模式p2在与p1相同的burst中。因为这些选项继承为与父亲的相同,所以模式p3也在相同的burst中。这些选项在剩余的嵌套列表中有至少一个不同的成员,从而造成burst中断。
定时
[461]用户主要通过利用模式文件定义测试设置来与***交互。定时文件用于描述这些模式的定时。这个文件需要分解用于底层定义的其它***文件(例如,Pin、SpecSelector)。此外,用在定时定义中分解各种变量的Spec-Selectors和Global定义封装在合成的TestConditionGroup对象中。例如测试计划文件的较高级文件又使用这个TestConditionGroup实例。
[462]测试计划文件包含对TestConditionGroup对象的引用。模式源文件对TimingMap对象中的WaveformSelector进行引用。Timing对象本身引用Pin对象。可选地,Timing对象还可以引用由SpecSelector对象调制的变量。这些关系在图9中说明。
[463]Pattern-List中的Pattern对象指定用于一组模式特征的WaveformSelector对象的名字。还要注意,Timing Map文件在模式中指定。如果这个映射未改变,则模式不需要编译。
[464]TestConditionGroup File对象导入要使用的Timing对象和要使用的TimingMap对象。每个测试都使用从用于该实例的TestConditionGroup对象导出的TimingCondition实例。因此,支持相同波形表的集合的多个Timing对象可以存储在测试器框架中并可以根据需要交换。类似地,多个测试计划文件可以共享公共的TestConditionGroup对象。
[465]以下测试计划描述文件的例子说明了Timing对象的使用。
    {
        TestConditionGroup=tim2_prod;
      Selector=max;
    }
    Test FunctionalTest MyFunctionalTestSlow
    {
         PListParam=patlist1;
         TestConditionParam=tim1_prod_typ;
    }
    Test FunctionalTest MyFunctionalTestFast
    {
        PListParam=patList1;
        TestConditionParam=tim2_prod_max;
    }
[466]Timing对象以每个引脚为基础定义了各种波形。用在Timing文件和Timing Map文件中的引脚需要在引脚定义文件中适当地定义。
[467]Timing对象可以使用SpecificationSet对象来定义wavefonn对象中的值。尽管Timing对象可以包括用于各种属性的硬编码值,但情况通常是用户利用变量指定各个值。这些变量又可以依赖SpecificationSet对象。以下说明这种使用的例子。
[468]SpecSelector如下说明地定义。
               SpecificationSet prodTmgSpec(min,max,typ)
               {
                  t_le=10ns,14ns,12ns;
                  t_te=30ns,34ns,32ns;
                  ...
               {
[469]通过改变spec而使用的timing的改变在以下例子中说明。
F2.映射到测试器的定时部件
[470]测试器模块的两个部件直接涉及波形的生成及其关联的定时。这两个模块是模式生成器(PG)和框架处理器(FP)。说明开放体系结构测试***体系结构中框架处理器的波形格式化与定时生成的简化框图在图10中说明。以下给出波形生成的简单描述。
[471]模式生成器1002生成模块中所有引脚公共的定时集合。该定时集合称为全局定时集合(GTS)。有三种其中模式生成器可以设置的模式。这三种模式影响可以用于描述GTS的位数。此外,这些设置还影响用于选择簇及Capture This Vector(CTV)和Mask This Vector(MTV)位是否设置的位数。为了通知测试器捕捉这个向量的结果,用户在模式文件中使用CTV标志。类似地,用户在模式中使用MTV标志来通知测试器掩蔽当前向量的结果。这在下面的表1中说明。模式生成器1002还负责波形特征(WFC)的生成。WFC以每个引脚为基础生成。测试器模块使用固定位数来描述WFC。
  GTS bits     GTS in aBank    GTS Bank     CTV     MTV
  8bits     256    4     NO     NO
  7bits     128    8     YES     NO
  6bits     64    16     YES     YES
表1
[472]测试器模块为每个引脚提供框架处理器1004。每个框架处理器都包含定时设置扰频器(TSS)1006,在这个例子中该定时设置扰频器具有高达1024的总深度。依赖于前面所述和在图10中说明的模式生成器的模式,其中使用每个簇64输入的16个簇,TSS 1006可以分成多个簇1008。提供TSS,从而允许为每个引脚定义波形表的能力中更大的灵活性。在“FP”模式,TSS使用2比特输出一个定时设置。因此,TSS将生成每个引脚总共四种不同的物理定时设置。这些定时设置称为局部定时设置(LTS)。
[473]框架处理器1004组合LTS和WFC并创建到波形存储器1012和定时存储器1014的索引1010。在“FP”模式中,5位值分成由LTS生成的2位和由WFC生成的3位。因此,尽管可以使用最大4种物理定时设置,但物理波形存储器和定时存储器的深度是每引脚32深。波形存储器保护形成波形的使能定时边缘。用于使能边缘的定时值是从定时存储器获得的。因此,框架处理器格式化波形。
映射方法
[474]该方法是以每引脚为基础将WaveformTable块映射到测试器中的LTS中。如果测试器硬件支持4个LTS,则用户可以定义最大4个WaveformTable块。每个WaveformTable块可以具有最大n个用于测试器数字模块的波形定义。
[475]Timing-Map文件提供开放体系结构的测试***中在Timing-Map块中定义的逻辑WaveformSelector到模块的WaveformTable的映射。在该情况下,测试器支持高达256个逻辑WaveformSelector。在开放体系结构的测试***中,这些逻辑WaveformSelector直接映射到GTS。模式编译器依赖于Timing-Map和Timing块,才能够编译模式文件。但是,如果Timing块的WaveformTable中的波形特征未改变或者映射到Timing-Map块中的WaveformSelector未改变,则不需要重新编译模式。
[476]使用映射方法的例子
[477]为了说明到测试器数字模块的映射,进行以下假设:框架处理器设置成FP模式;CTV和MTV位设置成使GTS位的总数是6,而定时簇选择器位的总数是4。
[478]Timing块中定义的每个WaveformTable都映射到Timing文件中不同的LTS。这是以每个引脚为基础完成的。因此,WaveformTable seq1映射到LTS1。在“SIG”引脚的情况下,所有8个可能的波形输入都用完了。但是,“CLK”引脚需要单个波形输入,从而用完波形存储器(WFT)和波形定时存储器(WTM)中的单个行。
[479]“SIG”引脚的前两个物理波形的映射在图11中说明。由于这个WaveformTable映射需要边缘独立配置的两个波形特征,因此我们结束分配波形存储器(WFT)1112和波形定时存储器(WTM)1114中的两个输入。该模块的一种实施方式具有总共6个定时边缘,T1、T2、T3、T4、T5和T6。这些直接映射到在Timing块的Edge Resource部分中的波形中定义的事件E1、E2、......。如果在Timing块中定义了多于6个事件且与以上模块一起使用,则将会导致错误。
[480]在图11的例子中,第一个波形特征“0”使用Timing Edge T1来编程“Force Down”或“D”事件,该事件发生在循环开始10ns的时间。TimingEdge T2也用于在30ns的时间生成“Force Down”或“D”事件。最后,TimingEdge T3用于在45ns的时间生成“Force Off”或“Z”事件。
[481]第二个波形特征“1”使用Timing Edge T1来编程“Force Up”或“U”事件,该事件发生在循环开始10ns的时间。Timing Edge T2也用于在30ns的时间生成“Force Down”或“D”事件。最后,Timing Edge T3用于在45ns的时间生成“Force Off”或“Z”事件。
[482]以这种方式,WFC映射到框架处理器的WFM存储器和WTM存储器中。用于引脚“SIG”的LTS1的波形存储器WFM的最终设置在以下表2中说明。
  Index   (WFC)   TISet   TIReSet   T2Set   T2ReSet   T2Drel   T2Dret   EXPH   EXPHZ   T3Set   T3ReSet   T3Drel   T3Dret   T4Drel   T4Dret   EXPL   EXPHZ
  0   0   1   1   1
  1   1   1   1   1
  2   d   1   1   1
  3   u   1   1   1
  4   L   1
  5   H   1
  6   m   1
7 n   1
表2
[483]用于引脚“SIG”的LTS1的波形定时存储器WTM的最终设置在以下表3中说明。
 Index  (WFC)  T1  T2  EXPH  T3   T4  EXPL
 0  0  10ns  30ns  45ns
 1  1  10ns  30ns  45ns
 2  d  12ns  32ns  42ns
 3  u  12ns  32ns  42ns
 4  L  17ns
 5  H  17ns
 6  m  15ns
7 n 15ns
表3
[484]“CLK”引脚用完了单个波形,因此用于这个引脚的WFM和WFT是非常简单的。用于“CLK”引脚的LTS1的波形存储器WFM的最终设置在以下表4中说明。
  Index     (WFC   T1Set   T1ReSet   T2Set   T2ReSet   T2Drel   T2Dret   EXPH   EXPHZ   T3Set   T3ReSer   T3Dret   T3Dret   T4Dret   T4Dret   EXPL   EXPHZ
  0     1   1   1
  1
  2
  3
  4
  5
  6
  7
表4
[485]LTS2的波形定时存储器WTM的最终设置在以下表5中说明。
Index   (WFC)   T1   T2   EXPH   T3   T4   EXPL
0  1   20ns   40ns
1
2
3
4
5
6
7
表5
[486]TimingMap块显式地将WaveformSelector映射到Timing块的Waveformtable。对于测试器***,这简化为设置定时设置扰频器(TSS)存储器。TSS基本上包含从GTS到保留所述设置的LTS的映射。用于我们例子的引脚SIG的TSS设置看起来象以下的表6。
 GTS LTS
 0(wfs1) 1
 1(wfs2) 1
 2(wfs3) 2
 3(wfs4) 1
 4(wfs5) 3
 5(wfs6) 1
 N(wfs1) 1
 255
表6
[487]最后,在TSS和LTS设置映射分解后,模式编译器可以使用这种信息来利用要使用的正确波形表(LTS)和正确波形特征来编程模式。因此,只考虑引脚“SIG”的我们的例子伪码模式在图11中说明。应当注意,这种编译不依赖于Timing块,而只依赖于Timing-Map块。
G测试器操作
[488]这部分描述测试器操作***(TOS)的基本操作。在这部分中考虑的动作是:
***初始化
测试计划加载
模式加载
运行测试计划
运行单独的测试
***初始化
[489]在一种实施方式中,为了初始化***,必须满足特定的假设且必须满足特定的条件。以下子部分列出这些假设和条件。
前提
[490]相关***软件组件的拷贝具有中心存储器,其位置是***控制器已知的。这可以是在***控制器上,或者在具有网络安装目录的其它***上(或者通过其它机制对SYSC已知)—不管使用什么机制,在***可以工作之前,所有软件都必须对***控制器可用。这种软件包括:
厂商硬件控制(即,模块软件)DLL;
标准的或用户测试类DLL;及
用户测试计划DLL。
[491]***模块配置文件在***控制器上可用。回想这个文件使用户可以指定测试器的物理配置,例如***底盘中每个模块的物理位置和类型,及模块软件DLL的名字。
[492]***配置文件在***控制器上可用。回想这个文件包含***中站点控制器的列表及站点控制器主机名到开关矩阵输入端口地址的映射。
[493]站点控制器具有称为站点配置管理器(SCM)运行的服务。这种服务负责通过称为“硬件发现”的处理确定在每个槽中安装了什么硬件。它还负责参与***控制器的***初始化处理。应当注意,在一种实施方式中,开关矩阵操作协议指示单个站点控制器上的SCM应当总是利用开关矩阵输入端口连接地址1配置与模块的开关矩阵连接。回想这个“特定”站点标记为SITEC-1。
[494]***控制器负责向每个站点控制器的SCM提供其开关矩阵连接地址。
[495]每个站点控制器的SCM都能够开始称为测试计划服务器(TPS)的处理。每个站点控制器上的测试计划服务器从根本上负责包含并执行用户的测试计划(或在单个站点控制器在多个DUT上运行测试的情况下是测试计划)。
初始化阶段I:***确认
[496]一旦以上假设和前提都已经满足,***初始化首先进行如下的***确认步骤:
1.***控制器读取***与模块配置文件,来初始化***的特定于用户的视图。
2.利用所指定的***配置信息,***控制器验证所指定的站点控制器是否活动、可到达并已经准备好(即,有SCM在运行)。这个验证步骤中的任何错误都将造成发生***错误,并且初始化将异常中断。
3.然后,***控制器通知在SITEC-1的SCM服务配置开关矩阵具有对所有硬件模块的访问,并请求它执行硬件发现。
4.在SITEC-1的SCM服务向所有可用的模块槽(已知的硬件位置)轮询{厂商,硬件}元组并生成{厂商,硬件}元组到槽的映射。结果是这种轮询识别出完整***中存在的{厂商,硬件,槽}绑定的整个集合。这种轮询的结果发送到***控制器。
5.***控制器验证以上硬件发现步骤的结果匹配模块配置文件中特定于用户的配置。这个验证步骤中的任何错误都将造成发生***错误并且初始化将异常中断。
6.然后,***控制器从已知位置的环境设置文件加载缺省环境(例如模块DLL的搜索路径、模式列表、模式、测试计划DLL、测试类DLL等)。
7.***控制器确保所有识别出的模块软件DLL都存在。如果有在***控制器上不可用的,则如果可能的话就从中心存储器检索;否则将发生***错误并且初始化将异常中断。
初始化阶段II:站点配置(可选的)
[497]站点配置,或站点分区,涉及可用***硬件模块到不同站点的软件级指定(即,为多个DUT提供服务)。回想站点分区信息是在套接字文件中提供的。
[498]测试器***允许站点(重新)分区既可用作为测试计划加载的一部分(由于每个测试计划都与特定的套接字关联)也可以作为独立的用户调用步骤执行。在后一种情况下,用户通过提供单独用于分区***的套接字文件启动站点分区。在每个站点测试不同DUT类型的多DUT测试情况下,这在***初始化过程中是特别有用的。但是,这个步骤在初始化阶段是可选的,并且用户可以选择不执行它,而是选择允许测试计划加载来适当地分区***。
[499]不管选择来实现站点分区的方式是什么(通过独立调用或者隐含地通过测试计划加载),机制都是相同的。以下描述这种机制。
1.给定套接字,***控制器首先确定当前现有的***分区是否与套接字兼容,或者是否需要重新分区。初始化过程中的缺省分区是所有可用模块都连接到SITEC-1的分区。以下剩余步骤只有在需要重新分区时才执行。
2.系9统控制器向每个站点控制器的SCM发送配置信息,以利用在新套接字下已经使能的DUT站点个数和标识符重新配置。应当注意,这个是通用过程并处理由站点控制器控制的DUT站点个数为一的情况。新套接字信息也传送到SCM。
3.如果有的话,则每个SCM都停止运行的TPS并启动新的TPS,利用新的套接字和在新套接字下已经使能的DUT站点个数和标识符初始化它。
4.***控制器确定哪个站点需要所需***模块的什么子集。在这么做的同时,它还为该站点准备硬件槽信息。对于每个站点,净结果是指定给该站点的槽对站点模块DLL的一个列表。特定于站点的列表将标记为站点模块DLL槽列表(SITE-MDSL)。
5.站点控制器向每个SCM提供合适的SITE-MDSL及必要的模块DLL。每个SCM又使这种信息对新启动的TPS可用。
6.然后,***控制器请求SITEC-1为合适的站点到槽连接(即为站点分区操作)配置开关矩阵。
7.站点1至n上的TPS加载在其SITE-MDSL中指定的DLL。这些DLL中的每一个都具有名字为initialize()的函数,该函数取槽编号的阵列。在这个时候如果有任何误动作,将发生***错误并且初始化将异常中断。initialize()方法进行以下动作:
a.创建基于标准接口IXXXModule的具体类。例如,与数字模块关联的DLL将创建单个基于IPinModule的对象来为与其关联的每个槽服务。
b.创建基于接口IResource的具体类,对模块中的每个“资源单元”创建一个。同样,对于数字模块,每个基于IPinModule的对象将为由该数字模块专用的槽集合中的所有引脚创建基于ITesterPin的对象。
8.然后,站点1至n上的TPS对每个加载模块DLL调用getXXXModule()来检索模块内容信息。
9.对getXXXModule()的每次调用都返回作为IModule指针的<VendorHWType>Module类(例如,AdvantestPinModule)。每个这样的IModule指针都被TPS高速缓冲,这使得这些对于框架/用户代码可用。应当注意,IModule、IResource等的集合是永久性的(至少对于TPS的生命周期)。
10.一旦以上步骤都完成了,TPS就在其指定的(众所周知的)端口上开始listen()。这向***控制器发出TPS已经“准备好”开始正常(即,站点分区)操作的信号。
测试计划加载
[500]这部分描述用户测试计划DLL加载到站点控制器上的步骤(对于单个或多个DUT测试)。
[501]一旦***初始化(及可选地还有启动站点分区)已经完成,用户测试计划就可以加载。用户测试计划在站点控制器上的加载如下进行:
1.***控制器首先将测试计划DLL加载到其自己的处理空间中,查询其关联的套接字文件及其DUT类型标识符。这种信息用于识别运行这个测试计划的站点,由此识别这个测试计划将加载到的站点控制器。
2.然后,***控制器使用与测试计划关联的套接字信息启动如上概述的重新分区处理。
3.***控制器从测试计划DLL提取由测试计划所使用的测试类DLL,并且一旦***控制器验证TPS已经准备好开始正常(即,站点分区)操作,就向适当的TPS发送测试类DLL并最终发送测试计划DLL本身。
4.TPS调用LoadLibray()将其加载到其处理空间中。它对DLL调用众所周知的函数来创建与其服务的站点(即,DUT)个数一样多的TestPlan对象。
5.TPS利用必要的测试器框架对象初始化TestPlan对象。在初始化过程中,TPS将由TestPlan对象所使用的测试类的适当DLL加载到处理空间中并创建测试类实例。
6.TPS设置***控制器到TestPlan对象的通信通道。
7.***控制器与TPS通信并建立其用于TestPlan对象的代理服务器。
[502]这决定了用户测试计划在站点控制器上的成功加载。
运行测试计划
[503]根据预定义流逻辑执行测试计划中所有测试的方法如下:
1.用户的应用程序将RunTestPlan消息发送到TPS。TPS向所连接的所有应用程序发送ExecutingTestPlan消息。然后,TPS对测试计划调用execute()。
2.利用单个站点控制器测试多个DUT是利用该站点控制器上的多个线程执行的,每个DUT一个线程。每个线程运行相同TestPlan对象的不同、独立的实例。在这种情况下,由于模块控制软件DLL可能跨DUT共享,因此需要用于硬件通信的模块命令取DUT标识符参数。
3.TestPlan对象对其集合中的每个测试迭代(可选地,告诉其流对象根据流逻辑处理每个测试),调用preExec()、execute()和postExec()。
4.在每个测试执行时,状态消息发送回所连接的所有应用程序。
执行单个测试
[504]用户可能希望在一个测试计划中执行单个测试而不是所有测试。对于单个测试的执行,方法如下。
1.用户应用程序向TPS发送RunTest消息;TPS向所连接的所有应用程序发送ExecutingTest消息。然后,TPS对测试计划调用executeTest(),指定要运行的测试。
2.测试计划对象通过对该测试对象调用preExec()、execute()和postExec()来执行所指定的测试。
3.当测试执行时,它将状态消息发送回所连接的所有应用程序。
[505]所公开的用于开发测试程序的方法至少可以实现两个优点。第一,该方法通过用更接近测试计划旨在针对的问题领域的语言来描述测试计划,使测试计划开发者脱离了***编程的复杂性。第二,该方法使得测试工程师能够在测试程序开发的早期阶段识别测试计划中的错误,这可以降低测试程序的开发时间和被测试的相应DUT。
[506]本领域技术人员将认识到,采用相同的基础机制和方法,可以使用所公开的实施例的许多可能的修改和组合。为了解释说明的目的,参考了特定实施例进行了之前的描述。然而,上述示例性的讨论并非是穷举性的或是将本发明限制成所公开的精确的形式。在以上教示的基础上可进行多种修改和变化。选择和描述上述实施例是为了解释本发明的原理和它们的实际应用,并使得本领域技术人员能够在进行适用于所考虑的特定应用的各种修改的基础上最好地利用本发明和各种实施例。

Claims (32)

1.一种开发用于半导体测试***的测试程序的方法,所述测试***包括至少一个测试模块,用于根据所述测试程序对被测设备施加至少一个测试,包括:
以测试程序语言(TPL)描述测试计划文件,其中测试计划文件描述所述测试程序的至少一个测试;
以***程序语言(SPL)描述测试类文件且以TPL描述所述测试类文件中相应的预编译头文件,其中测试类文件描述所述测试程序中至少一个测试的实现;以及
使用测试计划文件、测试类文件和预编译头文件生成测试程序。
2.如权利要求1的方法,其中***程序语言为C/C++。
3.如权利要求1的方法,其中生成所述测试程序包括:
由TPL编译器对所述测试计划文件进行编译,以形成以SPL描述的得出的测试计划文件;以及
由TPL编译器对所述预编译头文件进行编译,以形成以SPL描述的头文件。
4.如权利要求3的方法,其中编译所述测试计划文件包括:
将所述测试计划文件从TPL翻译成SPL,以及
使用预编译头文件对所述测试计划文件进行验证。
5.如权利要求3的方法,其中编译预编译头文件包括:
将预编译头文件的参数部分中描述的参数***头文件;以及
将预编译头文件的模板部分中引用的源代码***头文件。
6.如权利要求3的方法,进一步包括:
由SPL编译器对所述得出的测试计划文件进行编译,以形成测试计划目标文件,其中所述测试计划目标文件引用所述头文件;以及
由SPL编译器对所述测试类文件进行编译,以形成测试类目标文件,其中所述SPL编译器使用头文件以形成该测试类目标文件。
7.如权利要求6的方法,进一步包括:
链接测试计划目标文件和测试类目标文件,以形成测试程序,其中所述测试程序可以由半导体测试***来执行。
8.一种产生用于半导体测试***的测试程序的预编译头,所述预编译头包括:
用于指定所述测试程序的至少一个属性的参数部分;以及
用于将源代码***到所述测试程序的头文件中的模板部分。
9.如权利要求8的预编译头,其中所述测试程序的至少一个属性涉及模式列表和测试条件。
10.如权利要求9的预编译头,其中所述模式列表包括以下参数中的至少一个:
集的势;
追踪等级;
成员名称;
设置函数;以及
参数描述。
11.如权利要求9的预编译头,其中所述测试条件包括以下参数中的至少一个:
集的势;
追踪等级;
成员名称;
设置函数;以及
参数描述。
12.如权利要求8的预编译头,其中所述模板部分包括:
类名称;
导入声明;
参数阵列类型;
参数属性;
参数函数;以及
参数函数实现。
13.如权利要求8的预编译头,其中所述预编译头被测试程序语言(TPL)编译器用来生成头文件,且其中所述头文件以***程序语言(SPL)来描述。
14.如权利要求13的预编译头,其中所述头文件被SPL编译器用来生成测试类目标文件,且其中所述头文件被SPL编译器引用,以生成测试计划目标文件。
15.如权利要求8的预编译头,其中所述预编译头被用来支持在所述测试程序中用户定义的测试。
16.一种验证用于半导体测试***的测试程序的方法,所述测试***包括至少一个测试模块,用于根据所述测试程序对被测设备施加至少一个测试,包括:
以测试程序语言(TPL)来描述测试计划文件,其中所述测试计划文件描述所述测试程序的至少一个测试;
以TPL来描述预编译头文件;以及
使用所述预编译头文件对所述测试计划文件进行验证。
17.如权利要求16的方法,其中所述预编译头文件包括:
用于指定所述测试程序的至少一个属性的参数部分;以及
用于将源代码***到所述测试程序的头文件中的模板部分。
18.如权利要求16的方法,其中所述测试程序的所述至少一个属性涉及模式列表和测试条件。
19.如权利要求16的方法,其中验证所述测试计划文件包括核实所述测试计划文件的语义。
20.如权利要求16的方法,其中验证所述测试计划文件还包括核实所述测试计划文件的测试实体属性。
21.如权利要求16的方法,其中验证所述测试计划文件还包括核实所述测试计划的功能调用以及它们相应的参数。
22.一种半导体测试***,包括:
用于对被测设备施加至少一个测试的至少一个测试模块;
用于接收测试计划文件、测试类文件和所述测试类文件的相应预编译头文件的控制器,其中所述测试计划文件以测试程序语言(TPL)描述至少一个测试,且其中所述测试类文件以***程序语言(SPL)描述所述至少一个测试的实现;
用于对所述测试计划文件和所述预编译头文件进行编译、以分别形成得出的测试计划文件和头文件的装置;以及
用于使用所述测试类文件、得出的测试计划文件以及所述头文件来生成测试程序的装置。
23.如权利要求22的半导体测试***,其中所述预编译头文件包括:
用于指定所述测试程序的至少一个属性的参数部分;以及
用于将源代码***到所述测试程序的头文件中的模板部分。
24.如权利要求23的半导体测试***,其中所述测试程序的至少一个属性涉及模式列表和测试条件。
25.如权利要求24的半导体测试***,其中所述模式列表包括以下参数中的至少一个:
集的势;
追踪等级;
成员名称;
设置函数;以及
参数描述。
26.如权利要求24的半导体测试***,其中所述测试条件包括以下参数中的至少一个:
集的势;
追踪等级;
成员名称;
设置函数;以及
参数描述。
27.如权利要求23的半导体测试***,其中所述模板部分包括:
类名称;
导入声明;
参数阵列类型;
参数属性;
参数函数;以及
参数函数实现。
28.如权利要求22的半导体测试***,其中所述***程序语言为C/C++。
29.如权利要求22的半导体测试***,其中用于编译所述测试计划文件的装置包括:
用于将所述测试计划文件从TPL翻译成SPL的装置;以及
用于使用所述预编译头文件来验证所述测试计划的装置。
30.如权利要求22的半导体测试***,其中用于编译所述预编译头文件的装置包括:
用于将所述预编译头文件的参数部分中描述的参数***所述头文件的装置;以及
用于将所述预编译头文件的模板部分中引用的源代码***所述头文件的装置。
31.如权利要求22的半导体测试***,其中用于生成所述测试程序的装置包括:
用于对所述得出的测试计划文件进行编译以形成测试计划目标文件的装置,其中所述测试计划目标文件引用所述头文件;以及
用于对所述测试类文件进行编译以形成测试类目标文件的装置,其中所述头文件用于形成所述测试类目标文件。
32.如权利要求31的半导体测试***,还包括:
用于链接所述测试计划目标文件和所述测试类目标文件以形成所述测试程序的装置,其中所述测试程序可由所述半导体测试***来执行。
CNB2005800164373A 2004-05-22 2005-05-23 开发用于半导体集成电路的测试程序的方法和结构 Expired - Fee Related CN100541218C (zh)

Applications Claiming Priority (3)

Application Number Priority Date Filing Date Title
US57357704P 2004-05-22 2004-05-22
US60/573,577 2004-05-22
US10/918,714 2004-08-13

Publications (2)

Publication Number Publication Date
CN1981200A true CN1981200A (zh) 2007-06-13
CN100541218C CN100541218C (zh) 2009-09-16

Family

ID=38131583

Family Applications (6)

Application Number Title Priority Date Filing Date
CN 200580015953 Pending CN1981202A (zh) 2004-05-22 2005-05-23 模块化测试***中的数据日志支持
CN200580016355A Expired - Fee Related CN100580473C (zh) 2004-05-22 2005-05-23 支持开放架构测试***中的校准和诊断
CN2005800163968A Expired - Fee Related CN1989417B (zh) 2004-05-22 2005-05-23 开发半导体集成电路测试程序的方法和结构
CNB2005800164373A Expired - Fee Related CN100541218C (zh) 2004-05-22 2005-05-23 开发用于半导体集成电路的测试程序的方法和结构
CN200580016215A Expired - Fee Related CN100585422C (zh) 2004-05-22 2005-05-23 用于对模块化测试***进行仿真的方法和***
CN2005800164369A Expired - Fee Related CN1997909B (zh) 2004-05-22 2005-05-23 用于控制模块化测试***中可互换部件的方法和***

Family Applications Before (3)

Application Number Title Priority Date Filing Date
CN 200580015953 Pending CN1981202A (zh) 2004-05-22 2005-05-23 模块化测试***中的数据日志支持
CN200580016355A Expired - Fee Related CN100580473C (zh) 2004-05-22 2005-05-23 支持开放架构测试***中的校准和诊断
CN2005800163968A Expired - Fee Related CN1989417B (zh) 2004-05-22 2005-05-23 开发半导体集成电路测试程序的方法和结构

Family Applications After (2)

Application Number Title Priority Date Filing Date
CN200580016215A Expired - Fee Related CN100585422C (zh) 2004-05-22 2005-05-23 用于对模块化测试***进行仿真的方法和***
CN2005800164369A Expired - Fee Related CN1997909B (zh) 2004-05-22 2005-05-23 用于控制模块化测试***中可互换部件的方法和***

Country Status (4)

Country Link
JP (1) JP4332200B2 (zh)
CN (6) CN1981202A (zh)
AT (3) ATE451625T1 (zh)
DE (3) DE602005015848D1 (zh)

Cited By (12)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN101980174A (zh) * 2010-11-24 2011-02-23 中国人民解放军国防科学技术大学 一种自动测试计算机应用程序区间能耗的方法
CN102608517A (zh) * 2012-02-16 2012-07-25 工业和信息化部电子第五研究所 一种创建集成电路测试程序包的快速方法
US9672020B2 (en) 2014-09-19 2017-06-06 Microsoft Technology Licensing, Llc Selectively loading precompiled header(s) and/or portion(s) thereof
TWI643064B (zh) * 2014-04-09 2018-12-01 南韓商三星電子股份有限公司 系統單晶片及其驗證方法
CN109324956A (zh) * 2018-08-20 2019-02-12 深圳前海微众银行股份有限公司 ***测试方法、设备及计算机可读存储介质
CN113050952A (zh) * 2021-04-19 2021-06-29 杭州至千哩科技有限公司 伪指令编译方法、装置、计算机设备及存储介质
CN113051114A (zh) * 2021-03-19 2021-06-29 无锡市软测认证有限公司 一种用于提高芯片测试效率的方法
CN113342649A (zh) * 2021-05-31 2021-09-03 上海创景信息科技有限公司 基于真实目标机实现单元测试的***、方法、介质和设备
CN113740077A (zh) * 2021-09-13 2021-12-03 广州文远知行科技有限公司 车辆底盘测试方法、装置、设备及存储介质
CN114646867A (zh) * 2022-05-18 2022-06-21 南京宏泰半导体科技有限公司 一种集成电路并发测试装置及方法
CN116520754A (zh) * 2023-06-27 2023-08-01 厦门芯泰达集成电路有限公司 基于预加载模式的dps模块控制方法、***
CN116547666A (zh) * 2020-12-03 2023-08-04 美商新思科技有限公司 硬件设计编译故障时自动顺序重试

Families Citing this family (26)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US7925940B2 (en) * 2007-10-17 2011-04-12 Synopsys, Inc. Enhancing speed of simulation of an IC design while testing scan circuitry
US8094566B2 (en) * 2009-12-24 2012-01-10 Advantest Corporation Test apparatus and test method
CN102215140B (zh) * 2010-04-02 2013-03-27 英业达股份有限公司 储存局域网络的检验装置
CN102378232A (zh) * 2010-08-23 2012-03-14 财团法人资讯工业策进会 无线网络信号的测试***及其测量方法
US9317351B2 (en) * 2010-09-07 2016-04-19 Advantest Corporation System, methods and apparatus using virtual appliances in a semiconductor test environment
JP2012167958A (ja) * 2011-02-10 2012-09-06 Nippon Syst Wear Kk 試験情報表示装置、方法、プログラム、および該ソフトウェアを格納したコンピュータ可読媒体
US9606183B2 (en) * 2012-10-20 2017-03-28 Advantest Corporation Pseudo tester-per-site functionality on natively tester-per-pin automatic test equipment for semiconductor test
US10161993B2 (en) * 2013-02-21 2018-12-25 Advantest Corporation Tester with acceleration on memory and acceleration for automatic pattern generation within a FPGA block
JP6174898B2 (ja) * 2013-04-30 2017-08-02 ルネサスエレクトロニクス株式会社 半導体試験装置
TWI490689B (zh) * 2013-05-17 2015-07-01 英業達股份有限公司 不間斷自動更新測試命令之系統及方法
CN104298590B (zh) * 2013-07-16 2019-05-10 爱德万测试公司 用于按管脚apg的快速语义处理器
CN103413003B (zh) * 2013-08-21 2016-07-06 浪潮(北京)电子信息产业有限公司 一种序列传输、接收装置及方法
WO2016095993A1 (de) 2014-12-17 2016-06-23 Siemens Aktiengesellschaft Überprüfen eines funktionsmoduls einer automatisierungsanlage
CN107454124B (zh) * 2016-05-31 2020-11-03 创新先进技术有限公司 设备自动化方法及装置
CN106507098B (zh) * 2016-10-09 2018-10-19 珠海市魅族科技有限公司 数据处理的方法和装置
CN106603074A (zh) * 2016-11-03 2017-04-26 武汉新芯集成电路制造有限公司 一种dac电路并行测试***及并行测试方法
CN107959981B (zh) * 2017-10-30 2020-07-10 捷开通讯(深圳)有限公司 一种通信终端和通信测试方法
CN109508290A (zh) * 2018-10-25 2019-03-22 深圳点猫科技有限公司 一种基于教育***的自动化测试方法及电子设备
CN109884923A (zh) * 2019-02-21 2019-06-14 苏州天准科技股份有限公司 一种自动化设备控制模块化可配置***
CN109975650B (zh) * 2019-04-30 2024-07-12 珠海市运泰利自动化设备有限公司 一种TypeC接头连板多通道测试平台
CN110954804B (zh) * 2019-12-19 2021-11-02 上海御渡半导体科技有限公司 一种批量精确诊断cBit阵列故障的装置和方法
CN113238834B (zh) * 2021-05-31 2023-08-08 北京世冠金洋科技发展有限公司 仿真模型文件的处理方法、装置及电子设备
KR102314419B1 (ko) * 2021-07-27 2021-10-19 (주) 에이블리 반도체 테스트 패턴 발생 장치 및 방법
CN114252758A (zh) * 2021-12-03 2022-03-29 杭州至千哩科技有限公司 Ate测试通道资源配置方法、装置、设备及存储介质
CN115630594B (zh) * 2022-12-19 2023-03-21 杭州加速科技有限公司 一种芯片设计仿真文件到Pattern文件的转换方法及其***
CN116257037B (zh) * 2023-05-15 2023-08-11 通达电磁能股份有限公司 控制器测试程序的生成方法、***、电子设备及存储介质

Family Cites Families (4)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
GB2150696B (en) * 1983-11-25 1988-09-01 Mars Inc Automatic test equipment
US6208439B1 (en) * 1990-11-09 2001-03-27 Litel Instruments Generalized geometric transforms for computer generated holograms
US6779140B2 (en) * 2001-06-29 2004-08-17 Agilent Technologies, Inc. Algorithmically programmable memory tester with test sites operating in a slave mode
WO2003085706A1 (en) * 2002-04-11 2003-10-16 Advantest Corporation Manufacturing method and apparatus to avoid prototype-hold in asic/soc manufacturing

Cited By (17)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN101980174A (zh) * 2010-11-24 2011-02-23 中国人民解放军国防科学技术大学 一种自动测试计算机应用程序区间能耗的方法
CN102608517A (zh) * 2012-02-16 2012-07-25 工业和信息化部电子第五研究所 一种创建集成电路测试程序包的快速方法
TWI643064B (zh) * 2014-04-09 2018-12-01 南韓商三星電子股份有限公司 系統單晶片及其驗證方法
US9672020B2 (en) 2014-09-19 2017-06-06 Microsoft Technology Licensing, Llc Selectively loading precompiled header(s) and/or portion(s) thereof
CN109324956B (zh) * 2018-08-20 2021-11-05 深圳前海微众银行股份有限公司 ***测试方法、设备及计算机可读存储介质
CN109324956A (zh) * 2018-08-20 2019-02-12 深圳前海微众银行股份有限公司 ***测试方法、设备及计算机可读存储介质
CN116547666A (zh) * 2020-12-03 2023-08-04 美商新思科技有限公司 硬件设计编译故障时自动顺序重试
CN116547666B (zh) * 2020-12-03 2024-03-22 美商新思科技有限公司 硬件设计编译故障时自动顺序重试
CN113051114A (zh) * 2021-03-19 2021-06-29 无锡市软测认证有限公司 一种用于提高芯片测试效率的方法
CN113050952A (zh) * 2021-04-19 2021-06-29 杭州至千哩科技有限公司 伪指令编译方法、装置、计算机设备及存储介质
CN113342649A (zh) * 2021-05-31 2021-09-03 上海创景信息科技有限公司 基于真实目标机实现单元测试的***、方法、介质和设备
CN113342649B (zh) * 2021-05-31 2023-11-14 上海创景信息科技有限公司 基于真实目标机实现单元测试的方法、介质和设备
CN113740077A (zh) * 2021-09-13 2021-12-03 广州文远知行科技有限公司 车辆底盘测试方法、装置、设备及存储介质
CN114646867A (zh) * 2022-05-18 2022-06-21 南京宏泰半导体科技有限公司 一种集成电路并发测试装置及方法
CN114646867B (zh) * 2022-05-18 2022-10-28 南京宏泰半导体科技有限公司 一种集成电路并发测试装置及方法
CN116520754A (zh) * 2023-06-27 2023-08-01 厦门芯泰达集成电路有限公司 基于预加载模式的dps模块控制方法、***
CN116520754B (zh) * 2023-06-27 2023-09-22 厦门芯泰达集成电路有限公司 基于预加载模式的dps模块控制方法、***

Also Published As

Publication number Publication date
ATE451625T1 (de) 2009-12-15
CN100585422C (zh) 2010-01-27
JP2009008683A (ja) 2009-01-15
ATE438865T1 (de) 2009-08-15
CN1981202A (zh) 2007-06-13
DE602005015848D1 (de) 2009-09-17
ATE451624T1 (de) 2009-12-15
CN1997908A (zh) 2007-07-11
DE602005018204D1 (de) 2010-01-21
CN100541218C (zh) 2009-09-16
CN1989417B (zh) 2011-03-16
DE602005018205D1 (de) 2010-01-21
JP4332200B2 (ja) 2009-09-16
CN1997909B (zh) 2010-11-10
CN1997909A (zh) 2007-07-11
CN100580473C (zh) 2010-01-13
CN1989417A (zh) 2007-06-27
CN1981203A (zh) 2007-06-13

Similar Documents

Publication Publication Date Title
CN100541218C (zh) 开发用于半导体集成电路的测试程序的方法和结构
CN1784609B (zh) 开发半导体集成电路测试程序的方法和构造
EP1756603B1 (en) Method and system for controlling interchangeable components in a modular test system
JP4516961B2 (ja) 半導体試験システム、試験プログラムを生成するための方法、及びプリヘッダ
US7209851B2 (en) Method and structure to develop a test program for semiconductor integrated circuits
US8255198B2 (en) Method and structure to develop a test program for semiconductor integrated circuits
JP2007528993A5 (zh)
CN100456043C (zh) 检测集成电路的方法和装置
KR20070035507A (ko) 모듈식 테스트 시스템에서 호환성있는 컴포넌트를 제어하는방법 및 시스템
KR20070023762A (ko) 반도체 집적 회로를 위한 테스트 프로그램을 개발하는 방법및 구조
Rajsuman et al. Architecture and design of an open ATE to incubate the development of third-party instruments
Rajsuman et al. Open architecture test system: System architecture and design

Legal Events

Date Code Title Description
C06 Publication
PB01 Publication
C10 Entry into substantive examination
SE01 Entry into force of request for substantive examination
C14 Grant of patent or utility model
GR01 Patent grant
C17 Cessation of patent right
CF01 Termination of patent right due to non-payment of annual fee

Granted publication date: 20090916

Termination date: 20140523