热度 5| |||
该脚本也是诞生于想偷懒的想法。公司 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。
本人写脚本感觉更多是为了学习脚本语言知识而不是为了实用,因此脚本可能没经过太多验证及测试,也并非专业编程人员,因此写得挺乱,实现功能时的环境也比较理想,可能脚本遇到点状况就用不了。