第四章:测试向量基础——什么是测试向量、向量格式(STIL/WGL)、向量生成与加载
各位同学,今天我们来聊聊测试向量。说实话,这玩意儿是ATE测试的“灵魂”。你设备再牛,通道再多,没有好的测试向量,一切都是白搭。我刚开始带项目那会儿,就吃过向量的亏,后面慢慢才摸清门道。
4.1 什么是测试向量?
测试向量,说白了就是一张“指令表”。它告诉ATE设备:在哪个时间点,往哪个管脚上,灌什么电平,然后期望读到什么电平。
你可以把它想象成一张二维表格:
- 行:代表一个测试周期(Cycle),也就是一个时间单位
- 列:代表芯片的每一个管脚(Pin)
- 单元格:代表该管脚在该周期内的状态(比如H、L、Z、X)
举个例子,一个简单的与非门测试向量可能长这样:
Cycle 1: A=H, B=H, 期望输出=L
Cycle 2: A=H, B=L, 期望输出=H
Cycle 3: A=L, B=H, 期望输出=H
Cycle 4: A=L, B=L, 期望输出=H
嗯,这里要注意:向量里的“期望输出”是ATE用来判断芯片好坏的依据。如果实际采到的值和期望值不一样,ATE就会报Fail。
核心要点:测试向量 = 输入激励 + 期望响应 + 时序控制。三者缺一不可。
4.2 向量格式:STIL vs WGL
做ATE这么多年,我接触过两种主流的向量格式:STIL和WGL。它们就像英语和中文,都能表达意思,但语法和习惯不同。
4.2.1 STIL格式(Standard Test Interface Language)
STIL是IEEE 1450标准。我个人比较喜欢STIL,因为它结构清晰,可读性强。它把时序、管脚、向量分开定义,维护起来很方便。
一个典型的STIL文件结构如下:
STIL 1.0 {
Signals {
A In;
B In;
Y Out;
}
SignalGroups {
inputs = 'A B';
}
Timing {
WaveformTable wft_main {
Period '100ns';
Waveforms {
A { H { '0ns' D/U; } L { '0ns' D/L; } }
B { H { '0ns' D/U; } L { '0ns' D/L; } }
Y { H { '50ns' Compare; } L { '50ns' Compare; } }
}
}
}
PatternBurst burst1 {
PatList { pat1; }
}
Pattern pat1 {
W wft_main;
V { 'A=H B=H'; 'Y=H'; }
V { 'A=H B=L'; 'Y=L'; }
}
}
你看,它把“什么时候驱动”、“什么时候采样”都写得明明白白。我在项目中遇到过,有些EDA工具导出的STIL文件时序定义有歧义,导致ATE上跑出来的结果和仿真不一致。后来我养成了一个习惯:拿到STIL文件后,先检查Timing部分,特别是Compare strobe的位置。
我的小技巧:STIL文件里的WaveformTable,建议把Compare strobe放在周期的50%~70%位置。太早了信号没稳定,太晚了可能错过有效窗口。
4.2.2 WGL格式(Waveform Generation Language)
WGL是另一种常见的向量格式,由Teradyne等公司推广。它比STIL更“扁平化”,所有信息都揉在一起。说实话,WGL看起来有点“乱”,但它的优点是紧凑,解析速度快。
WGL的典型写法:
// WGL Example
TIMING_UNIT 1NS;
WAVEFORM UNIT 100NS;
VECTOR $A $B $Y;
PATTERN
H H L;
H L H;
L H H;
L L H;
END;
WGL没有STIL那么强的结构化能力,但它简单直接。我记得早期有些老式的ATE只支持WGL,那时候我不得不写脚本把STIL转成WGL。
| 对比项 | STIL | WGL |
|---|---|---|
| 标准化 | IEEE 1450标准 | 行业事实标准 |
| 可读性 | 高,结构清晰 | 低,信息密集 |
| 时序定义 | 独立Timing块 | 内嵌在向量中 |
| 工具支持 | 主流EDA都支持 | 老设备兼容性好 |
| 我的推荐 | 新项目首选 | 兼容旧设备时用 |
4.3 向量生成与加载
向量怎么来的?又怎么进到ATE里的?这里我分两步讲。
4.3.1 向量生成
向量的生成通常有两种方式:
- EDA工具自动生成:仿真通过后,工具(如Synopsys TetraMAX、Mentor FastScan)会输出测试向量。这是最常用的方式。
- 手动编写:对于一些简单的功能测试,或者调试阶段,我经常手写向量。比如验证一个寄存器读写,手写几行向量比跑一遍ATPG快得多。
我曾经遇到过一个案例:ATPG生成的向量有上百万条,但加载到ATE上后,发现前1000条向量就跑不过。后来排查发现,是EDA工具里某个时序约束没设对。所以,我建议你拿到向量后,先抽一小段在ATE上跑跑看,别一股脑全加载。
避坑指南:我曾经因为向量文件编码问题,在ATE上浪费了整整一天。STIL文件默认是ASCII,但有些工具会输出UTF-8 with BOM。ATE解析器不认BOM头,直接报错。解决办法:用Notepad++另存为ANSI格式。
4.3.2 向量加载到ATE
向量加载到ATE,一般分三步:
- 格式转换:把STIL/WGL转成ATE厂商的私有格式(比如Teradyne的.tdf、Advantest的.pat)。这一步通常由ATE自带的转换工具完成。
- 时序映射:把向量里的时序定义,映射到ATE的硬件资源上。比如,把“50ns处采样”映射到某个定时器通道。
- 向量下载:把转换后的向量数据,下载到ATE的向量存储器(Pattern Memory)中。
这里有个关键点:向量存储器的深度是有限的。比如老一点的Teradyne J750,向量深度只有16M。如果你的向量超过这个数,就得拆分成多个Pattern Segment,分段加载。
用Python写个简单的向量加载监控脚本,大概长这样:
import time
def load_pattern_to_ate(pattern_file, ate_interface):
"""
模拟向量加载过程
"""
print(f"[INFO] 开始加载向量: {pattern_file}")
# 步骤1: 格式转换
print("[INFO] 步骤1: 格式转换...")
time.sleep(0.5)
# 步骤2: 时序映射
print("[INFO] 步骤2: 时序映射...")
time.sleep(0.3)
# 步骤3: 下载到向量存储器
print("[INFO] 步骤3: 下载到Pattern Memory...")
time.sleep(1.0)
# 检查向量深度
pattern_depth = ate_interface.get_pattern_depth()
max_depth = ate_interface.get_max_pattern_depth()
if pattern_depth > max_depth:
print(f"[WARNING] 向量深度 {pattern_depth} 超过最大限制 {max_depth}")
print("[WARNING] 建议拆分为多个Pattern Segment")
return False
print(f"[INFO] 向量加载完成,深度: {pattern_depth}")
return True
# 使用示例
if __name__ == "__main__":
# 假设ate_interface是ATE的API对象
load_pattern_to_ate("test_pattern.stil", ate_interface)
你想想看,如果向量加载这一步出了问题,后面所有的测试都是白费功夫。所以,我每次加载完向量,都会先跑一个空跑(Dry Run),确认ATE能正确解析所有向量,再开始真正的测试。
总结一下:测试向量是ATE测试的“剧本”。STIL和WGL是两种主流的剧本格式,各有优劣。向量生成靠EDA工具或手写,加载到ATE时要特别注意格式转换和存储器深度。记住,向量质量直接决定测试质量,别在这上面偷懒。
好了,这一章就到这里。下一章我们聊聊测试程序的结构,看看怎么把向量、时序、测试项串成一个完整的测试程序。