首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

自动实现半导体器件系统强化测试的方法(2)

自动实现半导体器件系统强化测试的方法(2)

测试参数
        测试事件模块将使用一个或多个随机选择的测试参数来执行测试操作。常见的测试参数如:源和目的存储器地址、块大小、数据样式、读写宽度(如8、16或32位)、DMA通道和UART端口。
        虽然随机地选择测试事件函数看起来比较简单,但究竟应当如何选择随机测试参数值,同时确保这些值对系统有效,而且不与其它测试发生交叠从而导致干扰呢?例 如,如果某个测试选择一个随机的存储器地址和大小,需要知道(1)存储器确实存在;(2)其它测试没有选择与这片存储器交叠的存储器区域(因为一个测试有 可能改写另一个测试的存储器并导致故障)。另一个资源竞争的例子是,两个测试都随机地选中同一个DMA通道来进行数据传输。
        框架提供的支持功能使测试模块可以安全地选择任意测试参数。为了帮助理解这一点,这里举一个最常用的测试参数的例子:随机选择的系统存储器块。随机选择的存 储器块有一个起始地址值和一个大小值,它都是随机数值。这个存储器块可以位于CPU地址空间的任何位置,包括在SRAM、PCMCIA或Flash存储器 中。
        在列表3所示的例子中,memPool数组中填入了存储器段的起始地址和大小,它位于系统的地址空间中,可供测试进行随 机选择。每个条目都有一个保留标志(inUse项)。为了选择一个随机存储器块,函数首先选择一个随机的指向存储器段数组的索引。然后在这个段中选择一个 随机的起始地址和大小。最大块的大小值是存储器段的结束地址减去所选的起始地址。一旦随机块的起始地址和大小选定了,整个存储器段就通过设置保留标志被标 记为保留。
列表3:随机存储器块选择

============================

typedef struct

{

uint32_t start_addr;

uint32_t size;

bool inUse;

} memSeg;

memSeg memPool[] =

{

/* start addr size inUse */

{ 0x10000000,0x00040000, 0},

{ 0x10040000,0x00040000, 0},

{ 0x10080000,0x00040000, 0},

{ 0x100c0000,0x00040000, 0},

{ 0x30000000,0x00040000, 0},

{ 0x30040000,0x00040000, 0},

{ 0x30080000,0x00040000, 0},

{ 0x300c0000,0x00040000, 0},

{ 0x30100000,0x00008000, 0},

{ 0x40004000,0x00004000, 0},

{ 0x40008000,0x00004000, 0},

{ 0x4000c000,0x00004000, 0},

{ 0xa0000000,0x00002000, 0},

{ 0xb0000000,0x00008000, 0},

{ 0xb0008000,0x00008000, 0},

{ 0xb0010000,0x00004000, 0}

};

int SelectAndReserveBlock(unsigned int *addr, unsigned int *size)

{

int retries=0; /* limit the number of times we try to get a segment */

int seg;

while(retries < MAX_RETRY_COUNT)

{

/* Select a random memory segment (index into memPool array) */

seg = GetRandomNumber(sizeof(memPool)/sizeof(memSeg));

if (memPool[seg].inUse)

{

retries++;

continue;

}

/* reserve the segment */

memPool[seg].inUse = 1;

/* select random block in segment, and don't let it run past the end

of the segment. */

*addr = memPool[seg].start_addr + GetRandomNumber(memPool[seg].size);

max_size = memPool[seg].size - (*addr - memPool[seg].start_addr);

if (max_size > MAX_BLOCK_SIZE)

max_size = MAX_BLOCK_SIZE;

*size = GetRandomNumber(max_size);

break;

}

/* return the segment number so it can be used to free it later,

or return -1 if we gave up looking for a free segment */

return (retries >= MAX_RETRY_COUNT) ? -1 : seg;

}

void FreeMemorySegment(int seg)

{

memPool[seg].inUse = 0;

}

===============================================
        这种方法的一个缺点是,使用存储器段中的某个随机存储器块时,按照存储器段数组中的定义方式,整个存储器段都将被保留。如果所有存储器段都被保留了,还有存 储器可用吗?解决的办法是将存储器分为更小的段。可能希望以不同的方式来分割存储器段,以便消除跨越数据宽度和类型各不相同的多个存储器器件来选择存储器 块的可能性。注意这些方案都比较简单,也可以加强它的功能,关键只是直接控制指示哪些存储器区域可以使用。
        管理其它资源的选 择和保留可能更加简单。例如,保留标志数组可用来管理DMA通道,数组的索引代表通道。设计人员可以编写一个ReserveDmaChannel()函 数,它返回一个随机DMA通道号,这个通道号处于芯片上的DMA通道数目范围之内,并且其保留标志未被设置。然后,函数将设置保留标志来保留这个通道。测 试完成时,可以调用FreeDmaChannel()来清除该标志。
调试技巧
        调试和分离与系统相互作用有关的问题可能比较困难,在这个过程中可以通过设计强化测试框架来提供帮助。根据运行是在芯片生产前的仿真环境下进行,还是在一个安装有实际芯片的板卡上进行,所遇到的问题将会有差异。
        在仿真环境下运行时,速度是最大的问题,仿真CPU的运行速度要比实际器件慢得多。仿真环境的优势在于仿真工具可以输出芯片设计内部信号的详细记录,这将简 化调试工作,但它也有一个很大的缺点,即问题复现困难。如果为了暴露问题要花费太长的时间来运行强化测试,这将是难以接受的。
        解决的办法是将强化测试作为许多较短(例如30分钟)的测试来运行,这可以通过用一组测试事件模块来创建不同的测试来实现。此外,还应该给每个测试分配一个专门的随机数种子(seed),以便使用这个种子的其它测试每次运行时,都能重新产生准确的测试事件和测试参数序列。
        好的运行脚本可以随机产生种子值,然后创建一个测试并加以运行。种子值应当与运行结果一起记录下来。为了复现一个故障,可以用这个种子重新创建测试(因为可能不希望保留所有的可运行测试程序,其数量可能达到几千个),然后在短时间内复现这个问题。
        在实际的芯片上可以运行更多强化测试,因为其执行速度要快得多。但在理论上,它可能还是要花费同样长的时间,因为比较常见的问题应该在芯片生产前的强化测试 中就已经暴露出来了。在这里,问题的复现同样是一个很大的困难,读者可以尝试在芯片生产前的测试中应用所介绍的技术,但它可能不会同样有效,因为实际系统 可能不如在仿真环境下那样确定。换句话说,两个采用同一随机测试种子运行的测试可能不会每次都获得精确相同的运行序列。另外,此时也无法记录内部信号的行 为,因此应该依靠一些技术,如将检测点的信息记录到存储器或高速端口、插入各种逻辑分析仪触发事件,以及采用其它技术来帮助深入跟踪问题的详细情况。
        在实际芯片上调试系统问题时,没有什么通用的方法。设计人员应当周密考虑,并象即将遇到难以捉摸的故障一样来进行计划,编写程序代码,为分析问题提供尽可能多的线索。
        此外,测试框架还应该包含这样一种能力,它创建的测试运行程序能将某些测试模块排除在外,从而使强化测试无需在已知的问题上停止下来而得以继续运行。另一方面,将其余功能排除在外也将使设计人员能够对某些特定的芯片功能进行重点测试。
        框架需要组织良好的软件代码来生成种子、创建测试、运行、存储测试记录和后续处理,并向设计人员报告所遇到的问题。这个过程应当是完全自动化的,这样就可长时间运行测试而无需人员维护。
记录测试过程
        强化测试框架最少应该记录哪个测试模块在运行,以及发生的所有故障。完善的记录将包括更多的信息,如选择的随机参数,各个测试事件是何时启动、退出和检验 (针对延迟检验函数)的。这样,设计人员就可以了解各个测试是如何相互联系地运行的。后续处理软件可以生成一些有用的报告,以显示测试的覆盖范围。
        开发记录功能时,应使强化测试软件尽可能简单方便地记录事件。在仿真环境下,可编写HDL代码来提供一个记录外设,这样设计人员只需写下一个数值记号, HDL就将产生完整的记录信息。在实际芯片上,可以将字节记号和数值发送到存储器板卡或输出到调试端口。关键之处是要避免记录操作本身过多占用宝贵的测试 运行时间,并导致过度干扰。通过后续处理软件,可以使记录更清楚、更美观。
本文小结
        由于框架将涉及对中断处理程序所读写的共享数据结构的使用,因此访问这些数据结构时,应在软件代码中对重要的存储器段进行保护。例如,如果一个测试事件刚刚 读取了一个存储器段的inUse标志并发现它未被使用,但在它将该存储器段设置为保留之前,又发生了一个时隙中断,中断启动的测试模块结束时,可能将同一 存储器段设置为保留,因为此时该存储器段仍表现为未被使用。在这种类似的重要全局数据访问期间,应该将时隙定时器中断予以禁止。
        设计一个强化测试框架时,有许多扩展可能性。如可以调节测试事件模块的概率权重,或调整测试参数以便对强化测试进行精密调节。举个例子,高速缓存切换事件可 能是100个测试事件模块之一,但测试时可能希望它运行比1%多得多的时间,此时便可通过调整测试参数来实现。规划、设计和实现性能优良可靠的半导体器件 强化测试框架是一项重大投入,虽然需要花费大量的时间,但它可以帮助提高产品的质量。
继承事业,薪火相传
返回列表