| |||
前两天有朋友问怎么检查出有超压风险的器件。他们应用的场景是存在负压的情况。导致在电源与这个负压电源之间的器件有耐压不够的风险。下面是我搭个简单示意图,主要就是找出粉色的器件是否是5v器件,如果不是需要报出来。上面的pmos也是需要做检查如果在正压电源域下,衬底不是接正压电源同样需要报出来。
如果在复杂的电路中快速检查出这些风险点,我推荐他使用perc来检查。以前有写过多篇检查低压器件接到高压信号的perc脚本。稍作修改即可满足这样的检查需求。
很方便的检查出risk的mos,perc支持flatten和hierarchy的cdl,同样可以检查spice和layout 数据。
Perc的参考code在文章最后面。
是否还有其他方式可以检查出来,这里介绍下PrimeSim 的CCK feature也可以提供类似的检查。
CCK 是primeSim 中用于做ERC和ESD 检查的feature。像一些floating gate node analysis,Hi-Z node analysis,DC path analysis,device parameter analysis,misssing level shifter analysis,等等。我们可以使用built-in command 与API 来定制相关的检查。跟perc 有些相似。
这里举个简单的例子:检查mos的width/length的比是否小于8.
对应的网表如下:
下面是cck的tcl script:
# callback function to check the device w/l ratio proc wlratioCheck {inst} { global resultFile global wlratioMax set type [ cckGetInstType $inst ] if { $type==$::CCK_MOS } { set w [cckGetInstProp $inst "w"] set l [cckGetInstProp $inst "l"] if { $w/$l < $wlratioMax } { set instName [ cckGetInstFullName $inst ] puts $resultFile "device $instName W/L ratio is smaller than $wlratioMax" } } return $CCK_FALSE } # checking flow starts from reading in the netlist set wlratioMax 8.0 netlist add20.sp set fileName "cck.wl" set resultFile [ open $fileName w ] cckSearcInst -proc wlratioCheck close $resultFile
结果:
The cck.wl output file contains the following example result:
device m172 W/L ratio is smaller than 8.0
device m174 W/L ratio is smaller than 8.0
device m175 W/L ratio is smaller than 8.0
PERC的参考代码如下:
LVS POWER NAME "?VDD?" LVS GROUND NAME "?VSS?" VARIABLE HV_POWER "VDD25" VARIABLE HV_NPOWER "VDDN25" LAYOUT CASE YES SOURCE CASE YES PERC NETLIST SOURCE PERC REPORT "perc.rep" MASK SVDB DIRECTORY "svdb" QUERY PERC LOAD perclib INIT init SELECT deviceInRiskVoltageCheck //========= Include Files =========== TVF FUNCTION perclib [/* package require CalibreLVS_PERC proc deviceInRiskVoltageCheck {} { set rules "Device has risk\n" perc::check_device \ -pinPathType { {s d} {HV_Domain} } -condition voltageRisk_cond \ -comment "$rules" } proc init {} { array set ::mos {} set ::mos(IO5_mos) [list pch45 nch45] set ::mos(IO_mos) [list pch18 nch18 pch25 nch25] set ::mos(All) [concat $::mos(IO5_mos) $::mos(IO_mos)] perc::define_net_type "Power" lvsPower perc::define_net_type "Ground" lvsGround perc::define_net_type "AllPad" lvsTopPorts if {[perc::expand_list [tvf::svrf_var HV_POWER] -type net] != ""} { puts ">>[perc::expand_list [tvf::svrf_var HV_POWER] -type net]" perc::define_net_type "HV_Domain" [perc::expand_list [tvf::svrf_var HV_POWER] -type net] } if {[perc::expand_list [tvf::svrf_var HV_NPOWER] -type net] != ""} { puts ">>[perc::expand_list [tvf::svrf_var HV_NPOWER] -type net]" perc::define_net_type "NHV_Domain" [perc::expand_list [tvf::svrf_var HV_NPOWER] -type net] } perc::create_net_path -subtype $::mos(All) -pin {s d} -break {Power || Ground} -exclude {Power Ground} perc::create_net_path -type $::mos(All) -pin {s d} } proc voltageRisk_cond {instance} { set select 0 set mosType [perc::type $instance] set mosName [perc::subtype $instance] if {[lsearch $::mos(IO_mos) $mosType] || [lsearch $::mos(IO_mos) $mosName]} { if {[perc::is_pin_of_path_type $instance {S D} {HV_Domain}] == 1 && \ [perc::is_pin_of_path_type $instance {S D} {NHV_Domain}] == 1 } { if {[perc::is_pin_of_path_type $instance {B} {HV_Domain}] ==1} { set select 0 } else { set select 1 } } } else { set select 0 } return $select } */]