基于skeleton生成EDT模块(DFT)

张开发
2026/4/17 21:49:16 15 分钟阅读

分享文章

基于skeleton生成EDT模块(DFT)
1、背景 目前主流的可测性方案大多采用了基于tessent的two pass flow: (1)mbist insertion:在收到FE release的function代码后,DFT owner将建立mbist insertion flow,即在原始function代码上插入针对memory(包括SRAM和ROM)的测试电路。 (2)OCC/EDT insertion:在function+mbist代码的基础上,DFT owner将建立OCC/EDT insertion flow,即保证插入了针对logic的测试电路。 可以看到,EDT逻辑是DFT owner后续生成的,即在two pass flow之前的function代码中是不存在的。 考虑一个情况,DFT owner是否可以将EDT module提前准备好,让前端将EDT逻辑直接例化在function代码中,甚至将OCC、ijtag等相关逻辑也提前例化。 当然是可以的,并且也有很多公司采用提前例化的方式,其流程大致为: (1)例化:DFT owner提前准备好OCC、EDT、ijtag network和test controller等代码,指导前端owner将这些电路例化在代码中; (2)mbist insertion:mbist owner基于(1)的输出代码,建立基于LV或者tessent工具的mbist insertion flow,插入针对memory(包括SRAM和ROM)的测试电路; (3)综合:综合owner对(2)中的输出代码进行综合; (4)scan insertion:DFT owner基于DC工具完成DFF replacement和scan stitch操作。 所以接下来,将介绍基于skeleton如何生成EDT电路。2、生成skeleton电路 为了生成EDT电路,必须依托一个实际的待测电路,因此这里需要工具帮我们生成一个skeleton电路。2.1 定义skeleton电路输入信息 (1)定义scan chain的input/output的命名规则,同时选择是否采用bus的定义方式,生成的skeleton电路中将存在int_si和int_so两组port,对应每条短chain的头尾;scan_chain_input int_si bused scan_chain_output int_so bused (2)定义scan_enable的命名规则,生成的skeleton电路中将使用scan_en信号接管SDFF的SE端;scan_enable scan_en (3)定义执行移位过程所需的test clock,生成的skeleton电路中将使用testclock信号接管SDFF的CLK端;begin_clocks testclock 0 end_clocks (4)定义scan chain的配置信息:包括chain数目、chain length、chain头采用leading edge的驱动方式和chain尾采用trailing edge的驱动方式。 其中:chain的数目需要匹配实际值CHAIN_COUNT,这需要提前知道综合网表中DFF的数量;chain length可以任意定义,实际值需要等到scan insertion之后才能确定;定义chain头/尾的时钟驱动边沿,是为了保证生成的EDT与scan chain交界处的hold timing。begin_chains 1 CHAIN_COUNT 40 LE testclock TE testclock end_chains 按照上述(1)~(4)的语法规则,生成skeleton电路需要的输入信息就准备好了,完整内容如下,文件名为ptn.des:scan_chain_input int_si bused scan_chain_output int_so bused scan_enable scan_en begin_clocks testclock 0 end_clocks begin_chains 1 CHAIN_COUNT 40 LE testclock TE testclock end_chains2.2 修改skeleton电路输入信息 当DFT owner确定好scan chain的数量后,就需要将ptn.des文件中的关键字CHAIN_COUNT替换为实际chain number,输出最终的skeleton输入文件skeleton_design.inputsed 's/CHAIN_COUNT/$(TOP_chain_count)/' skel/ptn.des ./skel/skeleton_design.inputscan_chain_input int_si bused scan_chain_output int_so bused scan_enable scan_en begin_clocks testclock 0 end_clocks begin_chains 1 60 40 LE testclock TE testclock end_chains2.3 skeleton电路输出 基于skeleton_design.input文件,通过tessent工具内嵌的功能“create_skeleton_design”,输出skeleton相关文件,执行命令和输出文件如下:${TESSENT_DIR}/create_skeleton_design -o skel/skel_design/$(PART) -i skel/skeleton_design.input -module_name $(PART) -simulation_library1. pcie_518_device.v 2. pcie_518_device_lib.v 3. pcie_518_device.atpglib 4. pcie_518_device.dofile 5. pcie_518_device.testproc 下面对上述5个文件的内容做一个展示。 (1)skeleton design代码module pcie_518_device ( int_si, int_so, testclock, scan_en); input [59:0] int_si; output [59:0] int_so; input testclock; input scan_en; ****** ****** muxd_scan_cell chain60_cell0 ( .Q(int_so[59]), .QB(), .SI(chain60_cell1_out), .D(1'b0), .CLK(testclock_inv), .SE(scan_en) ); muxd_scan_cell chain60_cell1 ( .Q(chain60_cell1_out), .QB(), .SI(chain60_cell2_out), .D(1'b0), .CLK(testclock_inv), .SE(scan_en) ); muxd_scan_cell chain60_cell2 ( .Q(chain60_cell2_out), .QB(), .SI(chain60_cell3_out), .D(1'b0), .CLK(testclock_inv), .SE(scan_en) ); muxd_scan_cell chain60_cell3 ( .Q(chain60_cell3_out), .QB(), .SI(chain60_cell4_out), .D(1'b0), .CLK(testclock_inv), .SE(scan_en) ); muxd_scan_cell chain60_cell4 ( .Q(chain60_cell4_out), .QB(), .SI(chain60_cell5_out), .D(1'b0), .CLK(testclock_inv), .SE(scan_en) ); muxd_scan_cell chain60_cell5 ( .Q(chain60_cell5_out), .QB(), .SI(chain60_cell6_out), .D(1'b0), .CLK(testclock_inv), .SE(scan_en) ); muxd_scan_cell chain60_cell6 ( .Q(chain60_cell6_out), .QB(), .SI(chain60_cell7_out), .D(1'b0), .CLK(testclock_inv), .SE(scan_en) ); muxd_scan_cell chain60_cell7 ( .Q(chain60_cell7_out), .QB(), .SI(chain60_cell8_out), .D(1'b0), .CLK(testclock_inv), .SE(scan_en) ); muxd_scan_cell chain60_cell8 ( .Q(chain60_cell8_out), .QB(), .SI(chain60_cell9_out), .D(1'b0), .CLK(testclock_inv), .SE(scan_en) ); muxd_scan_cell chain60_cell9 ( .Q(chain60_cell9_out), .QB(), .SI(chain60_cell10_out), .D(1'b0), .CLK(testclock_inv), .SE(scan_en) ); muxd_scan_cell chain60_cell10 ( .Q(chain60_cell10_out), .QB(), .SI(chain60_cell11_out), .D(1'b0), .CLK(testclock_inv), .SE(scan_en) ); muxd_scan_cell chain60_cell11 ( .Q(chain60_cell11_out), .QB(), .SI(chain60_cell12_out), .D(1'b0), .CLK(testclock_inv), .SE(scan_en) ); muxd_scan_cell chain60_cell12 ( .Q(chain60_cell12_out), .QB(), .SI(chain60_cell13_out), .D(1'b0), .CLK(testclock_inv), .SE(scan_en) ); muxd_scan_cell chain60_cell13 ( .Q(chain60_cell13_out), .QB(), .SI(chain60_cell14_out), .D(1'b0), .CLK(testclock_inv), .SE(scan_en) ); muxd_scan_cell chain60_cell14 ( .Q(chain60_cell14_out), .QB(), .SI(chain60_cell15_out), .D(1'b0), .CLK(testclock_inv), .SE(scan_en) ); muxd_scan_cell chain60_cell15 ( .Q(chain60_cell15_out), .QB(), .SI(chain60_cell16_out), .D(1'b0), .CLK(testclock_inv), .SE(scan_en) ); muxd_scan_cell chain60_cell16 ( .Q(chain60_cell16_out), .QB(), .SI(chain60_cell17_out), .D(1'b0), .CLK(testclock_inv), .SE(scan_en) ); muxd_scan_cell chain60_cell17 ( .Q(chain60_cell17_out), .QB(), .SI(chain60_cell18_out), .D(1'b0), .CLK(testclock_inv), .SE(scan_en) ); muxd_scan_cell chain60_cell18 ( .Q(chain60_cell18_out), .QB(), .SI(chain60_cell19_out), .D(1'b0), .CLK(testclock_inv), .SE(scan_en) ); muxd_scan_cell chain60_cell19 ( .Q(chain60_cell19_out), .QB(), .SI(chain60_cell20_out), .D(1'b0), .CLK(testclock_inv), .SE(scan_en) ); muxd_scan_cell chain60_cell20 ( .Q(chain60_cell20_out), .QB(), .SI(chain60_cell21_out), .D(1'b0), .CLK(testclock_inv), .SE(scan_en) ); muxd_scan_cell chain60_cell21 ( .Q(chain60_cell21_out), .QB(), .SI(chain60_cell22_out), .D(1'b0), .CLK(testclock_inv), .SE(scan_en) ); muxd_scan_cell chain60_cell22 ( .Q(chain60_cell22_out), .QB(), .SI(chain60_cell23_out), .D(1'b0), .CLK(testclock_inv), .SE(scan_en) ); muxd_scan_cell chain60_cell23 ( .Q(chain60_cell23_out), .QB(), .SI(chain60_cell24_out), .D(1'b0), .CLK(testclock_inv), .SE(scan_en) ); muxd_scan_cell chain60_cell24 ( .Q(chain60_cell24_out), .QB(), .SI(chain60_cell25_out), .D(1'b0), .CLK(testclock_inv), .SE(scan_en) ); muxd_scan_cell chain60_cell25 ( .Q(chain60_cell25_out), .QB(), .SI(chain60_cell26_out), .D(1'b0), .CLK(testclock_inv), .SE(scan_en) ); muxd_scan

更多文章