热度 10| |||
该脚本也是诞生于想偷懒的想法。公司 MPW 流片一般会有几十个版本,每次在 tapeout 前都需要每个版本 LVS 验证一遍,相当费时费力,因此想着写个脚本解放双手(但实际上由于不是很信任自己写的脚本,还是会手动检查
)。该脚本会批量跑完 LVS , 创建一个“LvsData”的文件夹,将结果存档于文件夹中,同时创建一个“BatchLvsReport.txt”的文档,里面简单记录了 Run Lvs 的 cell 是否通过LVS。
该脚本适合之前已经验证通过的,只是想 double check 防止遗漏的场景。
脚本运行前需要先手动 Run 一遍 Calibre LVS,保存RunSet文件,记下路径后面需要填入脚本中。有RunSet还是比较舒服的,可以保存适合自己的各种设置,比如“connect all nets by name”、忽略dummy mos dummy res 等等。
使用脚本:
在脚本存放目录创建空文档,将脚本复制进去保存,拓展名改为sh,例如“BatchLvs.sh”
在脚本指定位置填入 layout library name 以及 sch library name(在同个 library 就填同样名字);
填入需要 LVS 验证的 cell list,或者填入正则表达式去匹配需要 LVS 验证的 cell ;
填入library的文件夹路径,(填该路径是为了获取cell名单,方便去匹配正则表达式,如果不使用正则表达式就不用填);
填入 source.added 的路径,一般该文件跟 LVS 文件放一起 ;
填入前面提到的 RunSet文件路径 。
然后在 virtuoso 启动目录 open terminal ,填入脚本路径启动开启脚本,例如“./BatchLvs.sh”
#创建于2024/6/5,作者Fabian
#工作原理:导出gds->导出cdl网表->calibre run lvs
#原本设想使用skill调用shell来完成,但某些步骤调用shell会严重卡顿,后放弃而完全使用shell来完成
#跑LVS过程中产出的文件都存在设定的文件夹中
#使用方法:
#1.将本文件放到任意位置,建议放到virtuso的启动目录底下;
#2.先打开calibre跑过一遍LVS,save runset,会有个Runset文件
#2.打开本文件,修改开头没注释的6行
#3.在virtuoso启动目录打开Terminal,加载本文件。直接输入文件目录即可
#注意:本脚本只能对cellname相同的layout和schematic Run LVS。
#需要略懂正则表达式,如果不懂可以在”筛选符合正则表达式的cell“那里,用井号注释掉for循环,
#然后将所有要跑LVS的cellname填进cell_list=()的括号里,用空格隔开。
#!/bin/bash
#以下内容需要每次使用脚本时都确认或修改##############################################################
Llibname=Ltestlib #版图library的名字
Slibname=Stestlib #原理图library的名字
cell_list_all=($(ls ./$Llibname)) #路径填library的文件夹所在路径,获取该文件夹作用是为了获取library的cell名单
regex=^chip_[A-Za-z0-9]+$ #输入打算Run LVS的cell名字正则表达式的匹配式
CdlIncludeFile=./PDK/Calibre/source.added #网表include文件,该文件一般可在LVS rule的同个文件夹中找到
LvsRunsetPath=runset #runset文件路径
#####################################################################################################
mkdir ./LvsData #创建存放lvs过程产出的文件的文件夹
datapath=$PWD\/LvsData #存放路径的变量
if [ -e $LvsRunsetPath ]; then
echo LvsRunSetPath:$LvsRunsetPath
else
echo LvsRunSet is not exist
fi
#筛选符合正则表达式的cell################################
cell_list=()
for cellname in ${cell_list_all[@]}
do
if [[ $cellname =~ $regex ]]; then
cell_list+=($cellname)
fi
done
#echo Regexcell\:${cell_list[@]}
#########################################################
> BatchLvsReport.txt #创建用于存只有通过与不通过的LVS结果的文档
#生成si.env文件,用于导出cdl网表###################
cat << EOF > $datapath/si.envori
simLibName = "$Slibname"
simCellName = "cellname"
simViewName = "schematic"
simSimulator = "auCdl"
simNotIncremental = 't
simReNetlistAll = nil
simViewList = '("auCdl" "schematic")
simStopList = '("auCdl")
hnlNetlistFileName = "cellname.cdl"
resistorModel = ""
shortRES = 2000.0
preserveRES = 't
checkRESVAL = 't
checkRESSIZE = 'nil
preserveCAP = 't
checkCAPVAL = 't
checkCAPAREA = 'nil
preserveDIO = 't
checkDIOAREA = 't
checkDIOPERI = 't
checkCAPPERI = 'nil
simPrintInhConnAttributes = 'nil
checkScale = "meter"
checkLDD = 'nil
pinMAP = 'nil
preserveBangInNetlist = 'nil
shrinkFACTOR = 0.0
globalPowerSig = ""
globalGndSig = ""
displayPININFO = 't
preserveALL = 't
setEQUIV = ""
incFILE = "$CdlIncludeFile"
auCdlDefNetlistProc = "ansCdlSubcktCall"
EOF
##F##################################################
#for循环:导出gds->导出cdl网表->calibre run lvs,三个步骤都放在同一循环执行
for cellname in ${cell_list[@]}
do
if [ -d ./$Llibname/$cellname/layout ] && [ -d ./$Slibname/$cellname/schematic ]; then #判断layout跟schematic是否都存在
#导出gds#############################
strmout\
-library $Llibname\
-toPCell $cellname\
-view layout\
-strmFile $cellname.gds\
-outputDir $datapath\
-convertDot node\
-case preserve\
#####################################
#修改si.env文件并导出cdl网表########
cp $datapath/si.envori $datapath/si.env #复制原始si.env文件覆盖si.env
sed -i s/cellname/$cellname/g $datapath/si.env
si $datapath -batch -command netlist
####################################
#修改LVS RUNSET文件####################################################################
cp $LvsRunsetPath $datapath/LvsNow.RunSet #copy一份临时runset文件
RunSetNow=$datapath\/LvsNow.RunSet #临时runset文件的路径
if [ -e $RunSetNow ]; then
sed -i s#lvsRunDir:\ [a-zA-Z0-9\/\.\_]*#lvsRunDir:\ $datapath#g $RunSetNow
sed -i s/lvsLayoutPaths:\ [a-zA-Z0-9_.]*/lvsLayoutPaths:\ $cellname\.gds/g $RunSetNow
sed -i s/lvsLayoutPrimary:\ [a-zA-Z0-9_.]*/lvsLayoutPrimary:\ $cellname/g $RunSetNow
sed -i s/lvsLayoutLibrary:\ [a-zA-Z0-9_.]*/lvsLayoutLibrary:\ $Llibname/g $RunSetNow
sed -i s/lvsSourcePath:\ [a-zA-Z0-9_.]*/lvsSourcePath:\ $cellname\.cdl/g $RunSetNow
sed -i s/lvsSourcePrimary:\ [a-zA-Z0-9_.]*/lvsSourcePrimary:\ $cellname/g $RunSetNow
sed -i s/lvsSourceLibrary:\ [a-zA-Z0-9_.]*/lvsSourceLibrary:\ $Slibname/g $RunSetNow
sed -i s/lvsSpiceFile:\ [a-zA-Z0-9_.]*/lvsSpiceFile:\ $cellname\.sp/g RunSetNow
sed -i s/lvsERCDatabase:\ [a-zA-Z0-9_.]*/lvsERCDatabase:\ $cellname\.erc\.results/g $RunSetNow
sed -i s/lvsERCSummaryFile:\ [a-zA-Z0-9_.]*/lvsERCSummaryFile:\ $cellname\.erc\.summary/g $RunSetNow
sed -i s/lvsReportFile:\ [a-zA-Z0-9_.]*/lvsReportFile:\ $cellname\.lvs\.report/g $RunSetNow
sed -i s/cmnFDIDEFLayoutPath:\ [a-zA-Z0-9_.]*/cmnFDIDEFLayoutPath:\ $cellname\.def/g $RunSetNow
fi
#######################################################################################
if [ -e $datapath/$cellname.cdl ] && [ -e $datapath/$cellname.gds ]; then
calibre -gui -lvs -runset $RunSetNow -batch
fi
NowReport=$datapath/$cellname.lvs.report
if [ -e $NowReport ]; then
if grep -q "CORRECT" $NowReport; then
if grep -q "INCORRECT" $NowReport; then
echo $cellname\ LVS\ ERROR >> BatchLvsReport.txt
else
echo $cellname\ LVS\ PASS >> BatchLvsReport.txt
fi
fi
fi
fi
done
echo LVS\ Over
#Fabian Z该脚本参考借鉴甚至抄袭了 David.Z 的 使用Perl编写脚本完成批量calibre lvs,十分感谢 David.Z。
本人写脚本感觉更多是为了学习脚本语言知识而不是为了实用,因此脚本可能没经过太多验证及测试,也并非专业编程人员,因此写得挺乱,实现功能时的环境也比较理想,可能脚本遇到点状况就用不了。
/1