ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Tessent MBIST内存测试从零搭建:参考脚本与实操避坑指南

Tessent MBIST内存测试从零搭建:参考脚本与实操避坑指南 1. 从零理解Tessent MBIST为什么内存测试绕不开这套流程1.1 一颗芯片里内存测试到底在测什么做DFT这行的朋友都知道芯片里最让人头疼的模块往往不是那些几百万门的逻辑电路而是密密麻麻嵌在角落里的SRAM和寄存器堆。一颗中等规模的SoC内嵌SRAM动辄几十上百个实例每个实例的位宽、深度、端口配置都不一样。这些内存一旦在流片后出现制造缺陷轻则功能异常重则整颗芯片报废。所以Memory BIST内建自测试就成了DFT流程里不可跳过的一环。Tessent MBIST是西门子EDA原Mentor Graphics旗下Tessent产品线中的内存测试解决方案。它的核心思路是在芯片内部插入一套硬件测试逻辑由MBIST控制器自动生成地址、数据和控制信号对每个内存实例执行写入和读取操作然后通过比较器判断读回的数据是否与预期一致。整个过程不需要外部ATE提供复杂的测试向量只需要给一个启动信号剩下的交给片上逻辑自己跑。这套方案解决的核心问题是内存测试的自动化与可重复性。如果没有MBIST你得为每个内存实例手工编写测试向量考虑地址译码、数据背景模式、读写时序工作量巨大且容易出错。而Tessent MBIST通过工具自动插入测试电路配合参考脚本可以在几小时内完成从内存模型导入到最终测试电路生成的全流程。适合阅读这篇文章的读者包括刚入行的DFT工程师、需要接手MBIST流程的验证人员、以及想了解Tessent工具链实操细节的在校研究生。我默认你已经有基本的数字电路概念知道什么是扫描链、什么是ATPG但对Tessent MBIST的具体操作流程可能还不太熟悉。1.2 为什么需要“参考脚本”而不是纯GUI操作Tessent工具本身提供了图形界面但真正在项目里跑MBIST流程没人会一步步点GUI。原因很简单一颗芯片可能有几十个内存实例每个实例的配置参数不同GUI操作无法批量处理也无法版本管理。参考脚本的价值在于把整个MBIST流程固化成可重复执行的命令序列今天跑和明天跑结果一致张三跑和李四跑结果也一致。Tessent MBIST的参考脚本通常是一组Tcl脚本配合Shell脚本做流程调度。Tcl负责调用Tessent的命令接口Shell负责环境变量设置、文件路径管理、日志记录。这种组合在DFT领域非常常见因为Tcl是EDA工具的事实标准脚本语言而Shell擅长做流程控制和文件操作。我见过不少新手一上来就想跳过脚本直接操作工具结果遇到问题连日志都找不到。所以我的建议是先把参考脚本的骨架搭起来哪怕一开始只是空跑也要把流程框架建立起来。后面再往里面填充具体的内存配置和测试算法。1.3 整体流程的五个阶段从零搭建一个完整的MBIST测试环境大致可以分成五个阶段环境准备安装Tessent工具、配置License、准备工艺库和内存模型文件。内存模型导入与配置把SRAM的.lib或.db文件导入Tessent定义每个内存实例的物理属性。MBIST电路生成选择合适的测试算法配置控制器参数生成MBIST逻辑。插入与验证把MBIST逻辑插入到设计网表中跑仿真验证功能正确性。测试向量生成与ATPG衔接生成MBIST的测试向量并与扫描链测试流程对接。这五个阶段环环相扣任何一个环节出问题都会导致后续流程卡住。下面我会逐个拆解每个阶段的核心操作和踩坑经验。2. 环境搭建与工具配置把地基打牢2.1 Tessent工具的安装与License配置Tessent的安装本身不复杂但License配置经常让新手卡住。Tessent通常和Calibre、Questa等工具共用一套License管理机制你需要确认License文件里包含tessent_mbist这个feature。如果没有工具启动时会直接报错退出。安装路径建议不要有空格和中文这是EDA工具的通病。我一般会把Tessent装在/opt/siemens/tessent下面版本号单独建目录比如/opt/siemens/tessent/2023.4。这样多版本共存时切换方便。环境变量需要设置以下几个export TESSENT_HOME/opt/siemens/tessent/2023.4 export PATH$TESSENT_HOME/bin:$PATH export LM_LICENSE_FILE27000license_server export TESSENT_LICENSE_FILE$LM_LICENSE_FILE注意LM_LICENSE_FILE和TESSENT_LICENSE_FILE最好都设置有些版本的Tessent只认后者。License服务器地址根据你实际的环境填写。验证安装是否成功可以跑一个最简单的命令tessent -version如果输出了版本号说明基本环境没问题。如果报License错误检查feature是否齐全。2.2 工艺库与内存模型的准备MBIST流程需要两类输入文件工艺库文件和内存模型文件。工艺库文件通常是.lib或.db格式包含了标准单元和内存单元的时序、功耗信息。Tessent需要这些信息来确保MBIST逻辑插入后不会引入时序违例。如果你拿到的库是.lib格式需要用Library Compiler转成.dbTessent读.db更稳定。内存模型文件是MBIST的核心输入。每个SRAM实例都需要一个对应的模型文件描述它的地址位宽、数据位宽、端口类型单端口/双端口、读写时序参数等。这些文件通常由内存IP供应商提供格式可能是.lib、.db或Tessent专用的.mem格式。我遇到过一种情况供应商只给了.lib文件但Tessent的MBIST流程需要.mem格式。这时候需要用Tessent自带的转换工具tessent -shell read_lib -format lib -library sram_1024x32.lib write_mem -format mem -output sram_1024x32.mem转换完成后检查.mem文件里的地址位宽和数据位宽是否与预期一致。我踩过一次坑供应商的.lib文件里地址位宽写的是10位但实际SRAM是1024深度应该是10位没错但数据位宽写成了32位实际是36位带校验位。这种细节不检查后面MBIST电路生成出来就是错的。2.3 目录结构设计与Shell脚本框架一个清晰的目录结构能让后续调试省很多事。我通常这样组织mbist_project/ ├── scripts/ # Tcl和Shell脚本 │ ├── run_mbist.sh │ ├── setup.tcl │ └── insert_mbist.tcl ├── libs/ # 工艺库和内存模型 │ ├── std_cell.db │ └── sram_*.mem ├── design/ # 设计网表和约束 │ ├── top.v │ └── top.sdc ├── work/ # 工具运行目录 └── reports/ # 输出报告和日志Shell脚本的框架大致如下#!/bin/bash # run_mbist.sh - MBIST流程主控脚本 set -e # 遇到错误立即退出 # 环境变量 export TESSENT_HOME/opt/siemens/tessent/2023.4 export PATH$TESSENT_HOME/bin:$PATH export TESSENT_LICENSE_FILE27000license_server # 路径定义 PROJ_DIR$(cd $(dirname $0)/.. pwd) LIB_DIR$PROJ_DIR/libs DESIGN_DIR$PROJ_DIR/design WORK_DIR$PROJ_DIR/work REPORT_DIR$PROJ_DIR/reports # 清理工作目录 rm -rf $WORK_DIR/* mkdir -p $WORK_DIR $REPORT_DIR # 进入工作目录 cd $WORK_DIR # 执行Tcl脚本 tessent -shell -f $PROJ_DIR/scripts/setup.tcl -log $REPORT_DIR/setup.log tessent -shell -f $PROJ_DIR/scripts/insert_mbist.tcl -log $REPORT_DIR/insert.log echo MBIST flow completed.这个框架的好处是所有路径都是相对项目根目录定义的换一台机器只要改PROJ_DIR的父目录即可。set -e确保任何一步失败都会立即停止不会带着错误继续跑。提示Shell脚本里的for循环在批量处理多个内存实例时特别有用。比如你有20个SRAM需要生成MBIST逻辑可以用循环逐个调用Tessent命令每个实例单独输出日志方便定位问题。3. 内存模型导入与MBIST电路生成的核心操作3.1 用Tcl脚本导入内存模型并定义实例Tessent MBIST的第一步是把内存模型读进来然后告诉工具设计里有哪些内存实例每个实例对应哪个模型。# setup.tcl - 导入库和设计 # 设置搜索路径 set search_path [list . ../libs ../design] set link_path * std_cell.db # 读取设计网表 read_verilog ../design/top.v set_current_design top # 读取内存模型 read_mem -format mem ../libs/sram_1024x32.mem read_mem -format mem ../libs/sram_512x64.mem # 列出设计中所有内存实例 set mem_insts [get_instances -hier -filter is_memory true] puts Found [llength $mem_insts] memory instances foreach inst $mem_insts { puts - $inst : [get_attribute $inst ref_name] }这段脚本跑完后你会看到设计里所有内存实例的列表。如果某个实例没被识别为内存说明它的模型文件没读进来或者实例名匹配不上。我遇到过一种情况设计里例化的SRAM模块名是sram_1024x32_wrapper但模型文件里定义的是sram_1024x32。这时候需要用set_attribute手动绑定set_attribute [get_instances u_sram_wrapper] ref_name sram_1024x323.2 选择测试算法March C-还是March SSMBIST的核心是测试算法。不同的算法覆盖不同的故障模型跑的时间也不同。常用的几种算法故障覆盖测试时长适用场景March C-固定故障、跳变故障中等通用SRAM测试March SS固定故障、跳变故障、耦合故障较长高可靠性场景Checkerboard固定故障短快速筛查GALPAT固定故障、耦合故障很长小容量内存选择算法时需要考虑两个因素故障覆盖需求和测试时间预算。如果芯片对可靠性要求极高比如汽车电子选March SS如果是消费类芯片March C-通常够用。在Tessent里指定算法# 为所有内存实例设置March C-算法 set_mbist_algorithm -type march_c_minus -instances $mem_insts注意March C-的“C-”是算法名称的一部分不是减号的意思。有些文档写成March C减容易让人困惑。3.3 配置MBIST控制器参数MBIST控制器负责生成地址、数据和控制信号。它的参数直接影响测试电路的面积和功耗。关键参数包括数据背景模式全0、全1、棋盘格、行走1等。背景模式越多故障覆盖越高但测试时间越长。地址顺序升序、降序、随机。升序最快随机覆盖最好。并行测试实例数同时测试多少个内存实例。并行度高则测试时间短但峰值功耗大。# 配置MBIST控制器 create_mbist_controller -name mbist_ctrl \ -instances $mem_insts \ -algorithm march_c_minus \ -data_background {all_0 all_1 checkerboard} \ -address_order ascending \ -max_parallel 4max_parallel 4表示最多同时测试4个内存实例。这个数字需要根据芯片的电源网络能力来定。如果电源网络较弱并行度太高会导致电压降过大测试结果不可靠。我一般会先算一下峰值功耗每个SRAM在读写时的动态功耗大约是C * V^2 * f其中C是负载电容V是电压f是频率。假设单个SRAM动态功耗是5mW4个并行就是20mW。如果电源网络能提供100mW那并行度还可以再提高。3.4 生成MBIST逻辑并检查报告配置完成后执行生成命令# 生成MBIST逻辑 insert_mbist -controller mbist_ctrl # 输出报告 report_mbist -controller mbist_ctrl -file ../reports/mbist_report.rpt report_area -file ../reports/area_report.rpt生成完成后重点检查三个报告MBIST报告确认每个内存实例都被正确覆盖算法和背景模式符合预期。面积报告MBIST逻辑的面积增量。如果面积增加超过5%需要检查是否有冗余逻辑。时序报告MBIST逻辑插入后是否引入时序违例。如果有需要调整控制器位置或插入流水线。我踩过一次坑生成MBIST逻辑后没看时序报告直接跑仿真结果发现MBIST控制器的输出到SRAM的路径有setup违例。原因是控制器放在芯片角落而SRAM在另一个角落走线太长。后来把控制器移到SRAM集群中间问题解决。4. 仿真验证与测试向量生成4.1 搭建MBIST仿真环境MBIST逻辑插入后必须跑仿真验证功能正确性。仿真环境需要三样东西测试平台Testbench、MBIST启动序列、结果检查机制。Testbench通常用Verilog或SystemVerilog写核心是给MBIST控制器一个启动信号然后等待测试完成信号。// mbist_tb.v - MBIST测试平台 module mbist_tb; reg clk; reg rst_n; reg mbist_start; wire mbist_done; wire mbist_fail; // 例化设计顶层 top u_top ( .clk(clk), .rst_n(rst_n), .mbist_start(mbist_start), .mbist_done(mbist_done), .mbist_fail(mbist_fail) ); // 时钟生成 initial begin clk 0; forever #5 clk ~clk; end // 测试序列 initial begin rst_n 0; mbist_start 0; #100 rst_n 1; #100 mbist_start 1; #20 mbist_start 0; // 等待测试完成 wait(mbist_done 1); #100; if (mbist_fail 1) begin $display(MBIST FAILED at time %t, $time); end else begin $display(MBIST PASSED at time %t, $time); end $finish; end endmodule跑仿真时我习惯用VCS或Questa命令大致如下vcs -full64 -sverilog mbist_tb.v top.v -o simv ./simv -l sim.log提示仿真时间可能很长因为March C-算法要遍历所有地址。如果SRAM是1024深度March C-大约需要10个周期每地址总共约10000个周期。在100MHz时钟下大约100微秒。仿真时可以把时钟频率调高缩短仿真时间。4.2 生成MBIST测试向量仿真通过后需要生成ATE用的测试向量。Tessent可以输出STIL或WGL格式的向量文件。# 生成测试向量 create_test_pattern -controller mbist_ctrl -format stil -output ../reports/mbist_pattern.stil生成的STIL文件包含了MBIST启动、地址遍历、数据比较的完整时序。ATE工程师会把这个文件转换成特定测试机的格式。我遇到过一种情况生成的STIL文件里MBIST启动信号的时序与ATE的时钟域不匹配。原因是Tessent默认按设计时钟生成向量但ATE的时钟可能不同。解决方法是在生成向量时指定时钟频率create_test_pattern -controller mbist_ctrl -format stil -clock_period 10 -output ../reports/mbist_pattern.stil4.3 与扫描链测试的衔接MBIST和扫描链测试是DFT的两个独立流程但它们共享芯片的引脚和测试模式。衔接时需要注意测试模式切换MBIST模式和扫描模式不能同时激活。需要在测试控制器里定义模式选择信号。引脚复用MBIST启动信号和扫描使能信号可能复用同一个引脚。需要在测试协议里明确切换时序。测试时间调度MBIST测试和扫描测试的总时间不能超过ATE的测试预算。我通常会在测试控制器里加一个简单的状态机根据外部引脚的电平组合决定进入MBIST模式还是扫描模式。这部分逻辑用Tessent的create_test_controller命令生成。5. 常见问题与排查技巧实录5.1 内存实例未被识别现象get_instances -filter is_memory true返回空列表。排查思路检查模型文件是否成功读入。用report_mem命令查看已加载的内存模型。检查实例名是否匹配。用get_instances -hier列出所有实例看内存实例的名字是否与模型文件里的定义一致。检查网表是否完整。如果网表里SRAM被优化掉了工具自然找不到。解决方法手动绑定实例和模型set_attribute [get_instances u_sram] ref_name sram_1024x325.2 MBIST逻辑插入后时序违例现象report_timing显示MBIST控制器到SRAM的路径有setup违例。排查思路检查控制器和SRAM的物理位置。如果距离太远走线延迟大。检查是否插入了流水线寄存器。MBIST控制器的输出可以直接打拍减少组合逻辑延迟。检查时钟约束是否正确。MBIST逻辑可能工作在慢时钟域约束要相应调整。解决方法在控制器输出插入一级寄存器set_mbist_option -pipeline_output true5.3 仿真时MBIST不启动现象Testbench给了启动信号但mbist_done一直为0。排查思路检查复位信号是否释放。MBIST控制器需要复位后才能工作。检查时钟是否在跑。用$monitor打印时钟信号。检查启动信号的脉宽是否足够。有些控制器需要至少2个时钟周期的启动脉冲。解决方法延长启动脉冲宽度确保复位释放后再给启动信号。5.4 常见问题速查表问题现象可能原因快速排查解决方法内存实例未识别模型未加载/实例名不匹配report_mem手动绑定ref_name时序违例控制器位置远/组合逻辑长report_timing插入流水线寄存器MBIST不启动复位未释放/时钟未跑打印复位和时钟延长启动脉冲测试向量格式错误时钟周期不匹配检查STIL时序指定clock_period面积超预算并行度过高/算法复杂report_area降低并行度/换算法5.5 独家避坑经验经验一先跑通一个内存实例再批量处理。我见过新手一上来就把所有内存实例一起配置结果一个出错全部卡住。正确做法是先拿一个最简单的SRAM跑通全流程确认脚本没问题后再扩展到所有实例。经验二日志分级记录。Tessent的日志信息量很大全部输出到终端会刷屏。我习惯把详细日志写到文件终端只输出关键步骤tessent -shell -f setup.tcl -log setup.log -verbose 0经验三版本控制。MBIST脚本和配置文件一定要纳入Git管理。我遇到过因为脚本改动导致流片版本MBIST失效的情况后来每次改动都提交Git出问题可以快速回滚。经验四仿真加速。如果SRAM容量很大仿真时间会很长。可以用Tessent的-fast_sim选项生成简化模型仿真速度能提升10倍以上但会牺牲一些时序精度。适合前期功能验证后期签核时再用完整模型。经验五与ATE工程师提前沟通。MBIST测试向量的格式和时序要求最好在生成向量之前就和ATE工程师确认。我踩过一次坑向量生成完了才发现ATE测试机不支持STIL格式只能重新生成WGL格式浪费了两天时间。6. 从脚本到流程我的实操体会整套MBIST流程跑下来最深的体会是脚本的健壮性比功能完整性更重要。一个能跑通但脆弱的脚本不如一个功能少但稳定的脚本。我现在的习惯是每加一个新功能先跑10次确认结果一致再纳入正式流程。另外Tessent的版本更新比较频繁不同版本之间的命令参数可能有细微差异。建议在项目开始时锁定一个版本不要中途升级。如果必须升级先在测试用例上验证所有脚本确认无误后再迁移。最后分享一个小技巧Tessent的Tcl接口支持catch命令可以把可能出错的命令包起来出错时输出友好提示而不是直接崩溃if {[catch {read_mem -format mem $mem_file} err]} { puts ERROR: Failed to read $mem_file: $err exit 1 }这个技巧在批量处理多个内存模型时特别有用能快速定位是哪个文件出了问题。
返回列表