tessent edt occ insert flow introduction

在 # [tessent dft memory bist 和 boundry scan flow introducation ] 里我们已经插入了mem bist , 插入了boundry scan cell 穿通了 jtag network

下一步我们要插入 occ和edt

set_context dft -no_rtl -design_id id2

设置一个新id 来保存下一步网表

set_tsdb_output_directory …/tsdb_outdir

读取cell mdt lib mem verliog mem core description 这里就不说了上次说过了一样

set_drc_handling DFT_C9 -auto_fix off

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

read_deisgn xxx -design_id step_before -verbose

design_id 设置上一步的id 然后工具会自动到tsdb_outdir 里面去吃上一步的memory bist boundry scan 插完的设计

这里为什么不用第一步吐出来的netlist再用read_verilog 吃进来设计是因为tessent flow 推荐当reload之前dft 做一半的结果时候用read_design (可能会连带读icl等东西吧)

set_system_mode insertion

还记得第一步加的那个auxiliary 对 scan_en test_clock edt_update 复用的端口不。 其中 TEST_CLOCK_AUL_PORT 需要在dft 模式下不要影响内部的func 逻辑(本质上因为这个口是个func 口只是dft 模式下被我用在做test clock 输入口了。 我需要让dft_mode 1 时候TEST_CLOCK_AUL_PORT 上的test_clock toggle 不要影响内部fun 逻辑toggle (要在test_clock toggle dft_mode 1 时候func 逻辑tie 0)。 dft_mode 0 时候 TEST_CLOCK_AUL_PORT 就是正常的fun 口。

我需要人为的修改网表

create_instance dft_inv_for_auxi_test_clock -of_mode INV_CELL
create_connection dft_inv_for_auxi_test_clock/I dft_mode
intercept_connection deisgn_name_id_name_tessent_bscan_logical_group_DEF_inst/TEST_CLOCK_AUL_PORT_toCore -cell_function_name clock_and -input2 dft_inv_for_auxi_test_clock/ZN

auxiliary port 插入的逻辑前后缀包括pin名字都是固定的。 具体可以看tessent ug

add_black_box -auto

这个没啥说的根据情况来

set_system_mode setup

切setup mode 准备添加dft signal

set_design_level chip

set_dft_specification_requirements -logic_test on

准备加occ edt 切logic test 为design check rule (告诉工具我要做组合逻辑scan chain 相关工作了。spec 切对,design rule 检查方式切对)

add_dft_signals ltest_en

logic test en pin 根据需要加 后面产pattern需要用set_static_dft_signal_values 来控制
add_dft_signals scan_en -source_nodes SCAN_EN_AUL_PORT
指定前面的加的auxi port 为scan_en port
add_dft_signals edt_mode
添加edt_mode signal 后面产pattern需要用set_static_dft_signal_values 来控制

add_dft_signals test_clock edt_update -source_nodes { TEST_CLOCK_AUL_PORT,EDT_UPDATE_AUL_PORT}

指定之前的auxiliary port 为test_clock edt_update

add_dft_signals edt_clock shift_capture_clock -create_from_other_signals
add_dft_signals memory_bypass_en 后面产pattern需要用set_static_dft_signal_values 来控制
add_dft_signals tck_occ_en 后面产pattern需要用set_static_dft_signal_values 来控制

report_dft_signals

报告下添加的dft signals , 总之add_dft_signals 如果跟-source_node 那么生成的电路就会把我指定的port和内部的模板dft电路接起来。 如果是-create_from_other_signals 或者 什么都不加就是默认的模板dft 电路(这些节点都会加到tdr ctrl inst 上。 其中上面的ltest_en edt_mode memory_bypass_en tck_occ_en 都需要在产不同的pattern时候用 set_static_dft_signals_value控制到不同的值上(就类似 test procedure 的iCall )最后这些都会在最终的pattern上有所反应。
类似这样

好吧又扯多了。继续回到正题上。
add_nonscan -instance { inst_clock_gen/rst inst_clock_gen/cgu }

设置non scan instance CGU RGU 这样的模块是不上chain的。否则你的电路clock 和reset 如果都上chain , 一开始电路就运转不了了。(你必须要让clock 分频正常,reset 正常,然后再去测试后面挂的func 逻辑)

check_design_rules

做design rule check 看看电路有没啥问题(做什么检查和前面的set_dft_specification_requirement 设置相关)准备设置dft spec

read_config_data /xxx/userdefine_dft_setting.spec

和前面mbist一样读取default spec , (读取用户的default dft spec 设置, 提一句 default spec 和 create_dft_specification 做的那个是两码事)

set spec [create_dft_specification -replace]
report_config_data $spec

创建dft spc

source xx/xx/clock_define.tcl

先设置好clock 参数准备做occ 大致就这样
set clock_list {pll/node_1 $period_1 $pll_clock_name
inst_clock_gen/buffer/Z $period_2 $div_clock_name
}

read_config_data -in $spec -from_string {
OCC {
ijtag_host_interface : Sib(occ);
}}

dft spec 设置occ wrapper 用sib挂到 ijtag host network 上

foreach {clock period id} $clock_list {
set occ [add_confit_element OCC/Controller($id) -in $spec]
set_configa_value clock_intercept_node -in $occ $clock}

设置occ controller 挂载位置, id 就是func clock的名字 , 挂载位置就是前面的clock list 设置的node

还没有完,第一步mbist时候解决dft clock drc的时候做了很多bypass mux inst 名字是occ_node_xx (可以回看前一个文章, 如果我没记错的话) 这些也需要加occ 单独控制

set num 0
foreach occ_node [get_name_list [get_pins -hierarchical occ_node*/Z]] {
set occ [add_confit_element OCC/Controller(insert_mux_clock_occ_$num) -in $spec]
set_config_value clock_intercept_node -in $occ $occ_node
incr $num}

给前面做mbist时候解drc加的clock mux 后面加OCC控制

read_confit_data -in $spec -from_string {
EDT {
ijtag_host_interface : Sib(edt);
Controller( design_name) {
longest_chain_range : your_chain_length_min, your_chain_length_max;
scan_chain_count : your_chain_num;
input_channel_count : your_chain_input_num;
output_channel_count :your_chain_output_num;
Connections + {
EdtChannelsIn(1) {
port_pin_name: design/scan_channel_in_0_output;
PipelineStage {
leaf_instance_name: design_top_edt_channel_0_pip_reg;
}}
EdtChannelsIn(2) {…}
EdtChannelsOut(1) {
port_pin_name : design/scan_channel_out_0_in;
PipelineStage {
leaf_instance_name: design_top_edt_channe_out_0_pip_reg;
}}
EdtChannelOut(2) {…}
}}}

指定edt 链的input out 节点。 这些节点是designer预留的它和chip顶层的SCAN 使用的input & output port 穿通。 input节点的个数就是your_chain_input_num output节点个数就是your_chain_output_num 其中EdtChannelOUT EdtChannelsIn 也要与前面对应。 其中your_chain_length_min, your_chain_length_max 就是链长大概500左右吧, 其实就是压缩率和input channel output channel 以及总flipflop数的一个平衡。 总flipflop数能从综合DC 的报告report_qor 里面的sequential count 得到。 压缩率大概150 200 左右不要超过300。 当然你做到150以下也不是不行。
例如你有110000flop 链长500 链个数就是220 ; 如果input channel output channel 都是2 的话压缩率就是 110 , 好继续下一步。

process_dft_specification

处理dft spec 产生instrument

extract_icl

抽取icl
write_design_import_scripts dc_syn.tcl -replace
把给生成rtl.tcl 给写出来准备给dc 吃

run_synthesis -startup_file dc.setup

dc.setup 里面就是dc的 target 以及link library设置以及一些dc setting
会调用dc 进行综合,用一开始吃进来的tsdb 下面的rtl
把合并的netlist 存储在tsdb 的 dft_inserted_designs directory下面

当然这个用dc合并出来的netlist 没有做uniquify (dc 的实例化单元唯一性这里不详细解释,详细看另一篇介绍dc的文章)
之后进行第三步前需要调用dc把存储的netlist吃进来做uniquify 然后再存出来再跑第三步。

好了occ edt insert 完毕,下来要进行穿scan chain。在下一篇文章介绍

看完请点赞哦

3 个赞