tessent dft memory bist 和 boundry scan flow introducation

最近忙于项目,长时间不更新。准备写一个dft 的合集,具体写到哪里到时候再看吧,这只是个初步计划。
闲话不说开始上菜。

set design_id xxx

设置design id 之后自动保存的data 名字会根据design id 生成

set_drc_handling DFT_C9 -auto_fix off

关掉clock 不可控自动fix 功能,采用手动fix 。

set_context dft -no_rtl design_id $design_id

设置context 由于我这里是基于gate netlist flow做dft所以-no_rtl 如果是基于rtl level做的话相应改变

set_tsdb_output_directory …/tsdb_outdir

设置tessent db 保存dir 之后生成的dft netlist 以及pattern都会保存在这里

read_cell_library …/cell_select.mdt

读取dft cell select mdt 指定dft 过程中使用的cell 类型
大致这个样子
dft_cell_selection (TEST_DFT_CELL_SELECT) (
clock_mux = cell_name;
clock_buffer =xx;
clock_inverter = xx;
clock_and = xx;
clock_gating_and = xxx;
clock_gating_or = xx;
active_low_latch = xx;
active_high_latch = xx;
mux = xx;
buffer = xx;
inverter = xx;
or = xx;
and = xx;
nor = xx;
xor = xx;
posedge_dff =xx;
negedge_dff = xx;
xxx
)

read_cell_library xxx/xxx/cell.mdt (ip $ std cell 的mdt 文件)
有的厂商只提供.atpg 文件不提供mdt文件,mdt文件需要自己生成。

生成方式如下。
read_cell_library xxxxx/xxxx/test.atpg
read_liberty xxxxx/xxxx/test.lib
write_cell_library xxxxx/xxxx/test.mdt
atpa与mdt文件相比是不同的。缺少一些信息。比如
atpg


mdt

mdt与atpg 库相比多了cell pin 描述不但有那些是io那些clock 包括是什么edge trigger 。tessent建模需要用到这些

read_verilog xxx/xx/mem.v -interface_only -exclude_from_file_dictionary

读取mem ip .v 只读interface 接口防止报错。不想读也可以add_black_boxes

read_core_descriptions xxx/xxx/.lvlib or xxx/xxx/.memlib

读取mem core description mbist 需要使用。描述了pattern 产生用什么算法。以及mem port function 描述类似这样

read_verilog xxx/xxx/xxx/syn.netlist

吃综合的网表进来

read_verilog user_define_dft.v

user 自定义的模块用于之后的dft 网表连接。(不一定需要)

set_current_design ${design_name}

设置顶层设计名用于design link

add_black_boxes -auto

在读mem netlist 时候介绍过了不一定需要

add_input_constraints DFT_MODE -C1

对boundry port case 值 让设计处于dft mode下。

set_system_mode insertion

设置tessent 工具到insertion mode下 要对网表进行人为bypass等操作 (一共三个mode如果我没记错的话 setup analysis insertion 有些命令需要特定mode下执行。这很正常,什么mode干什么事)

intercept_connection design/internal_clock_pin -cell_function_name clock_mux -input2 ref_clock -select dft_mode -leaf_instance_prefix occ_node_xx

intercept_connection design/rst -cell_function_name clock_mux -input2 xxxx/xx/rst -select dft_mode

解dft drc bypass 命令。具体怎么写得根据design来 一般check_design_rules 会报告,当然这得add_clock 之后才会有效,我还没有写到这个命令。然后open_visual 打开tessent gui 根据netlist 可以具体看哪一个信号不可控。bypass到哪里等。这个需要和designer沟通。我的另一个文章有介绍。至于前面-leaf_instance_prefix occ_node_xx 是为了后面的flow往后面接occ 需要的所以实例化的instance加了前缀。
这里我再多说一下。 比如chip的tck 口在顶层 需要做func 复用。所以可能需要bypass 一个ref clock 过来当做func clock。 然后在后面再垫occ 来和test_clock 切换

set_system_mode setup

人工bypass 结束切换mode setup

set_design_level chip

我是chip顶层level 具体设置什么切换参照tessent ug 三个level chip → 不解释 physical_block 就是会用来syn pr的level sub_block → 更下层的level

set_attribute_value JTAG_TCK -name function -value tck
set_attribute_value JTAG_TDI -name function -value tdi
set_attribute_value JTAG_TMS -name function -value tms
set_attribute_value JTAG_TRST_N -name function -value trst
set_attribute_value JTAG_TDO -name function -value tdo

指定设计的TJTAG TAP 口 tessent 做IJTAG NETWORK 需要用到

report_dft_signals

报告目前设计的dft 信号 。 比如那些是add_dft_signal 添加的还是说design insert 进去的是已经存在还是 to be created 等等。

add_clock $clk -period $period

添加clock 到design 当中用于trace 整个dft clock network 是不是通的。
一般会在ref pll 出口 或者div clock instance 分频后的pin 上
需要对整个design clock network 结构了解。

set_boundary_scan_port_options $boundry_scan_dont_touch_port_list -cell_option dont_touch

对芯片顶层的模拟模块port, ref_clock 输入port, DFT使能port , 系统复位port, 模拟使能port 设置不穿boundry scan.
这些口要么是模拟口要么是需要芯片上电后直接控制来使芯片进入dft 测试模式,不能穿boundry scan (JTAG 相关PAD 也不穿bscan TCK TDI TDO TRST_N TMS)

set_dft_specificaton_requirements -boundary_scan on -memory_test on -memory_bisr_chains off -memory_bisr_controller off

告诉之后的create_dft_spec 我要干嘛我要穿boundry scan chain 和做memory bist . check_design_rule 也会根据这个做相应的check

check_design_rules

好了不解释

report_memory_instances

报告下memory tessent core description 状态

有时候做mem bist controller 需要根据pr floorplan 摆在一起的memory ip 给做controller 这样对pr timing 有利
需要指定mem group

如 set_memory_instance_options { mema memb memc } -partitioning_group group1
set_memory_instance_options {memc memd meme } -partitioning_group group2

tessent 会把这些分组的mem 用一个controller控制

read_config_data /xxx/userdefine_dft_setting.spec

读取用户定义的dft default spec 这个tessent ug 上有详细描述
例如
DefaultsSpecification(user) {
DftSpecification {
use_rtl_cells : auto
use_rtl_synchronizer_cell : on;
use_synchronizer_cell_with_reset : on;
dft_cell_selection_name : TEST_DFT_CELL_SELECT ;
IjtagNetwork {
ImplementationOptions {
scan_path_retiming: flop:
}
}
MemoryBist {
max_steps_per_controller : 2;
max_memories_per_step : 30;
max_power_per_step : 400;
MemoryInterfaceOptions {
scan_bypass_logic :sync_mux;
}
}
BoundaryScan {
ImplementationOptions {
update_stage : flop;
scan_path_retiming : flop;
}
}
}

定义的default dft spec 前面写的dft cell selection mdt 就这里指定进去的。
Ijtag网络用什么retime Boundry scan 用什么retime 来优化timing
每个mbist controller 几个step 每个step 最大挂几个mem 等等

set spec [create_dft_specification -replace]
report_config_data $spec

创建dft spec 并report 并且$spec 句柄可以用来之后修改dft spec 使用

read_config_data -in $spec/BoundaryScan -from_string {
AuxiliaryInputOutputPorts {
auxiliary_input_ports : SCAN_EN_AUL_PORT , TEST_CLOCK_AUL_PORT, EDT_UPDATE_AUL_PORT;
}
}

设置chip上用来复用的port 比如上面三个port其实是function data port 在dft模式下被用来做 scan_en test_clock edt_update 口
这个需要和designer 以及封装的同事协商

说到这里为了保证boundry scan 和 PD layout 的一致性。 需要read_def pr.def 读取pr顶层的def 然后check_design_rules 会dump pin_order_file 告诉chip 顶层io是什么顺序。依照这个顺序来穿scan chain

set_boundary_scan_port_options -pin_order_file pin_order_file 来吃pin order file

pin order file 可以人为修改比如修改最后一列的 LogicalGroups 来对IO PAD 进行划分组别。用来穿不同的boundary scan chain

有的时候boundry可能需要穿不同的chain 这是因为一款chip die可能有好几种封装 。 流片一种die 可以封装成好几个chip 引不同的pad出来就是不同的功能chip, 都是为了芯片产品的竞争。 这时候当然不同的封装要穿不同的boundry chain 比如

read_config_data -in_wrapper $spec/BoundaryScan -last -from_string {
BondingConfigurations {
BoundingConfiguration(package1) {
enable_signal: xxx/xxx/buf/Z;
unused_ports : PORTA , PORTB;
bypassed_logical_groups : Anlog_PKG;
}
BoundingConfiguration (package2) {
enable_signal: xxx/xxx/buf/Z;
unused_ports : PORTC, PORTD;
bypassed_logical_groups : Anlog_PKG;
}
}
}

比如这里有两个封装。都是由enable_signal 这个buf控制 1 开启。 其中封装1排除A,B 口封装2 排除C D 口 bypass_logical_groups 的group就是 前面的pin order list 里面的LogicalGroups 可以指定某些模拟的port boundry scan chain 不要穿在这个封装中。

有的时候ijtag 控制逻辑designer已经做进去了。 前面已经指定了chip port 上的jtag tap 口。为了让工具识别你的internal tap 口把JTAG netlist 接到internal tap 口上,需要指定。
read_config_data -in_wrapper $spec/IjtagNetwork -last -from_string {
HostScanInterface(tap_internal) {
Interface {
tck : design_design_jtag/tck;
trst : design_design_jtag/trst;
tms: design_design_jtag/tms;
tdi:design_design_jtag/tdi;
tdo: design_design_jtag/tdo;
tdo_en: design_design_jtag/en;
tdo_en_polarity: active_high/active_low;
}}}

可以用report_config_data $spec > spec.debug
来看看产生的spec 样子
可以使用move_config_element $spec/IjtagNetwork/HostScanInterface(tap)/Tap(main) -in_wrapper $spec/IjtagNetwork/HostScanInterface(tap_inernal)
来移动dft spec 中的instrument 部分。比如上面的例子。 因为我后面的tdr sib 会接到tap(internal) 上

read_config_data -in_wrapper DftSpecification($design_name,$id)/IjtagNetwork/HostScanInterface(tap_internal)/Tap(main) -last -from_string {
DeviceIDRegister {
version_code :xxx;
part_number_code : xxx;
manufacturer_id_code : xxx;
}}

设置CHIP ID register

下一步插入tdr 来控制jtag network 上的一些模拟ip 让chip 上电后 进入dft模式后通过jtag network 来 控制tdr 输入数据使得一些ip运转起来比如 pll.

read_config_data -in_wrapper DftSpecification($design_name,$deisgn_id)/IjtagNetwork/HostScanInterface(tap_internal)/Tap(main)/HostIjtag(id) -last -from_string {
Sib(PLL_SIB) {
Tdr(PLL_CFG) {
keep_active_during_scan_test : on;
leaf_instance_name : pll_tdr_inst:
reset_value : xxxxxxx;
DataOutPorts {
multiplexing: on;
connection (2:0): xxx/pll/in;
connection (3): xxx/pll/sel;
}
DataInPorts {
connection (0) : xx/pll/lock_o ; ///需要观测的口比如pll有没有lock
}
}}}

用report_config_data $spec > final_dft_spec.rpt
把spec写出来
如果设计中有rom 需要打开文件
人为的指定 spec 当中的 rom_content_file : xxxx/xx/xx/rom.rcf;

指定设计中rom的rcf code file chip boot 需要的code

read_config_data final_dft_spec.rpt

把改过rcf路径的spec 读回来

然后
set_confit_value DftSpecification($design_name, $design_id)/MemoryBist/Controller(id_1)/AdvancedOptions/pipeline_controller_outputs on
set_confit_value DftSpecification($design_name, $design_id)/MemoryBist/Controller(id_2)/AdvancedOptions/pipeline_controller_outputs on

控制每一个membist的controller 输出都有pipeline 来优化timing

process_dft_specification

工具处理你的dft spec 植入mbist 电路 boundry scan 穿通jtag network

extract_icl

抽取icl 到tsdb_outdir 里面会有dir dft_inserted_designs dir
你的deisgn_name_id_name.dft_inserted_design dir >> sdc tcd 等
instruments dir >> bscan / cells/ ijtag / mbist 等instrument dir

这里不细说了

write_design_import_scripts dc_syn_netlist.tcl -replace

把置入网标的rtl 文件吐出来准备综合

用system “dc_shell -f dc.tcl” 调取dc 来吧dc_syn_netlist.tcl 综合了

注意点
在 dc.tcl 里面要source dc_syn_netlist.tcl
记得设置svf
记得吃mbist sdc >>> 和func sdc 很像可以自己写。 你也可以用tessent 吐出来的sdc

再来补充一点。 也是闲谈。一般mbist clock 也就慢速tck 做寄存器配置,然后mbist测试时候切换到func clock 测试。 high speed mbist 测试。 (听说有的mbist 测试时候timing有问题还会做slow speed mbist测试就是用 慢速的tck ,这个我不是很了解) mbist 全程不会有test clock 参与
反正本质上都是用occ 切换么, (func clock , test clock , tck 切换)
然后再说shift capture , shift 时候 用tck 配置寄存器 ,用test clock 把sequence shift 进去
stuck at capture , 用test clock 做capture
at speed capture , 用 func clock 做capture

好了扯远了。我们继续前面的话题 ,总之这一步综合就是
把func netlist 和dft netlist 合并一起

ok 大功告成产生 design.v (func + mbist + boundryscan + jtag network)

还没有植入 edt, occ , 也没有穿scan chain 换下一篇介绍。

麻烦点个赞哦,欢迎讨论评论

3 个赞

大佬 后续还会有更新嘛? 关于edt_occ scan_chain相关的这些