#!/usr/bin/perl # Date : 8th Jan 2010 # Author : Quek Hong Cheang # Solution : 11609162 # This script runs Assura LVS and QRC extraction on all cells in a library # Layout input can be dfII layout, gds2 or oasis files # Schematic input can be dfII schematic or cdl netlist # Selectable QRC outputs are spice, spectre, dspf, extracted view and lvs_extracted_view # Selectable extraction modes are rc_coupled/decoupled, c_only_coupled/decoupled, r_only # Syntax: genRC.pl ### The following variables need to be defined by user ### $inputLayType="df2"; #df2, gds2 or oasis # if layout input type is df2, please specify libPath and viewName $libPath="/abc/myLayoutLib"; #Note that this is path, not just a name $layViewName="layout"; # if layout input type is gds2 or oasis, please specify path to gds2/oasis file $gdsOasisFile="./gdsLib/design.gds"; $inputSchType="cdl"; #cdl or df2 # if input type is cdl, please specify location of cdl netlist $cdlNetlist="netlists/cdl/design.cdl"; # if input type is df2, please specify name of sch lib & view $schLibName="mySchLib"; #Name of sch library $schViewName="schematic"; $extRules="assuraRules/extract.rul"; $comRules="assuraRules/compare.rul"; $bindRules="assuraRules/bind.rul"; $lvsIncludeFile=""; #Optional $lvsSw="cdl_input"; $qrcTechDir="qrcTech/typ"; $capGndNet="AGND"; #spectre, spice, dspf, lvs_extracted_view or extracted_view $outputType="spectre"; #r_only, c_only_coupled, c_only_decoupled, rc_coupled, rc_decoupled $extractType="rc_coupled"; ### The above variables need to be defined by user ### @pathList=split /\//, $libPath; $libName=@pathList[len-1]; @corList=split /\//, $qrcTechDir; $corName=@corList[len-1]; print "Start: ".`date`; print "=== Generating $outputType output for library $libName ===\n\n"; @swList=split / /, $lvsSw; foreach $sw (@swList) { $lvsSw2="$lvsSw2 \"$sw\""; } #foreach if(!open(qrcTechLib, ">my_qrcTech.lib")) { die("Cannot create file my_qrcTech.lib\n") } #if print qrcTechLib "DEFINE myTech $qrcTechDir\n"; unless( -e "LVS" ) { system "mkdir LVS"; } if( $outputType =~ /spice|spectre|dspf/ ) { unless( -e "qrcOutput" ) { system "mkdir qrcOutput"; } unless( -e "qrcOutput/$corName" ) { system "mkdir qrcOutput/$corName"; } } #if if($outputType eq "spectre") { $fileExt="scs"; } #spectre elsif($outputType eq "spice") { $fileExt="sp"; } #spice elsif($outputType eq "dspf") { $fileExt="dspf"; } #dspf @dirContents=<$libPath/*>; foreach $item (@dirContents) { @itemList=split /\//, $item; $cellName=@itemList[@itemList-1]; if( -d $libPath."/" . $cellName . "/" . $layViewName ) { print "Running Assura LVS for cell : $cellName ... "; unless( -e "LVS/$cellName" ) { system "mkdir LVS/$cellName"; } &createLVSrsf; if( $inputSchType eq "df2" ) { system "dfIItoVldb LVS/$cellName/$cellName.vlr"; } #if system "assura /tmp/lvs.rsf > LVS/$cellName/$cellName.log"; system "cp /tmp/lvs.rsf LVS/$cellName/$cellName.rsf"; if(!open(lvsLogFile, "LVS/$cellName/$cellName.log")) { die("Cannot read Assura log file LVS/$cellName/$cellName.log\n") } #if $lvsResults="LVS errors"; while( chomp($inLine=)) { if( $inLine =~ /Schematic and Layout Match/ ) { $lvsResults="LVS match"; } #if } #while close lvsLogFile; print "Completed. $lvsResults\n"; &createQRCccl; print "Running QRC extraction for cell : $cellName ... "; #system "cd LVS/$cellName"; system "qrc -cmd /tmp/qrc.ccl > LVS/$cellName/$cellName.qrc.log"; #system "cd ../.."; system "cp /tmp/qrc.ccl LVS/$cellName/$cellName.qrc.ccl"; if(!open(qrcLogFile, "LVS/$cellName/$cellName.qrc.log")) { die("Cannot read qrc log file LVS/$cellName/$cellName.qrc.log\n") } #if $qrcResults="Completed with errors"; while( chomp($inLine=)) { if( $inLine =~ /QRC terminated normally/ ) { $qrcResults="Completed sucessfully"; } #if } #while close qrcLogFile; print "$qrcResults\n"; } #if } #foreach print "\n=== LVS run data is at ./LVS directory ===\n"; print "=== QRC output netlists are at ./qrcOutput/$corName directory ===\n"; system "rm -f /tmp/lvs.rsf /tmp/qrc.ccl my_qrcTech.lib"; print "End: ".`date`; sub createLVSrsf { if(!open(lvsFile, ">/tmp/lvs.rsf")) { die("Cannot create file /tmp/lvs.rsf\n") } #if print lvsFile "avParameters(\n"; if( $inputLayType eq "df2" ) { print lvsFile " ?inputLayout (\"$inputLayType\" \"$libName\")\n"; } #if else { print lvsFile " ?inputLayout (\"$inputLayType\" \"$gdsOasisFile\")\n"; } #else print lvsFile " ?cellName \"$cellName\"\n"; print lvsFile " ?viewName \"$layViewName\"\n"; print lvsFile " ?workingDirectory \"./LVS/$cellName\"\n"; print lvsFile " ?rulesFile \"$extRules\"\n"; print lvsFile " ?set ($lvsSw2)\n"; print lvsFile " ?avrpt t\n"; print lvsFile ") ;avParameters\n\n"; print lvsFile "load \"$comRules\"\n\n"; if( -e $lvsIncludeFile ) { print lvsFile "load \"$lvsIncludeFile\"\n\n"; } #if print lvsFile "avCompareRules(\n"; print lvsFile " schematic(\n"; if( $inputSchType eq "cdl" ) { print lvsFile " netlist(cdl \"$cdlNetlist\")\n"; } #if else { &createLVSvlr; print lvsFile " netlist(df2 \"LVS/$cellName/$cellName.vlr\")\n"; } #else print lvsFile " filterOptions(\"XZ\")\n"; print lvsFile " ) ;schematic\n"; print lvsFile " layout(\n"; print lvsFile " filterOptions(\"XZ\")\n"; print lvsFile " ) ;layout\n"; print lvsFile " bindingFile(\"$bindRules\")\n"; print lvsFile " abortOnUnboundDevices(nil)\n"; print lvsFile " autoPinSwap(t 250000)\n"; print lvsFile " expandOnError( (unstableDevices t) (swap t) (reduce t) (pins t) (match t) (swapThres t) (instCount t) (skipMatchOnReduceError t) (ambiguousPinAssignment t) (parameter t) )\n"; print lvsFile " listFilteredDevices()\n"; print lvsFile " mergeSplitGate( mergeAll )\n"; print lvsFile ") ;avCompareRules\n\n"; print lvsFile "avLVS()"; close lvsFile; } #createLVSrsf sub createLVSvlr { if(!open(vlrFile, ">LVS/$cellName/$cellName.vlr")) { die("Cannot create file LVS/$cellName/$cellName.vlr\n") } #if print vlrFile "avSimName = \"auLvs\"\n"; print vlrFile "avDisableWildcardPG = nil\n"; print vlrFile "avLibName = \"$schLibName\"\n"; print vlrFile "avCellName = \"$cellName\"\n"; print vlrFile "avViewName = \"$schViewName\"\n"; print vlrFile "avViewList = \"auLvs $schViewName symbol\"\n"; print vlrFile "avStopList = \"auLvs\"\n"; print vlrFile "avVldbFile = \"LVS/$cellName/$cellName.sdb\"\n"; close vlrFile; } #createLVSvlr sub createQRCccl { if(!open(qrcFile, ">/tmp/qrc.ccl")) { die("Cannot create file /tmp/qrc.ccl\n") } #if print qrcFile "process_technology \\\n"; print qrcFile " -technology_library_file \"my_qrcTech.lib\" \\\n"; print qrcFile " -technology_name \"myTech\"\n\n"; if($outputType eq "spectre") { print qrcFile "output_db -type spice \\\n"; print qrcFile " -postprocess_output_netlist \"spp -convert ". "-log $cellName.scs.log\" \n\n"; } #spectre else { print qrcFile "output_db -type $outputType \n"; } #Others print qrcFile "output_setup \\\n"; if( $outputType =~ /spectre|spice|dspf/) { print qrcFile " -file_name \"qrcOutput/$corName/$cellName.$fileExt\" \\\n"; print qrcFile " -net_name_space \"SCHEMATIC\" \\\n"; } #if print qrcFile " -temporary_directory_name \"$cellName\"\n\n"; print qrcFile "input_db -type assura \\\n"; print qrcFile " -design_cell_name \"$cellName $layViewName $libName\" \\\n"; print qrcFile " -directory_name \"LVS/$cellName\" \\\n"; print qrcFile " -format \"DFII\" \\\n"; print qrcFile " -library_definitions_file \"cds.lib\" \\\n"; print qrcFile " -run_name \"$cellName\" \n\n"; if( $outputType ne "lvs_extracted_view") { print qrcFile "extract \\\n"; print qrcFile " -selection \"all\" \\\n"; print qrcFile " -type \"$extractType\" \n\n"; } #unless if( $extractType ne "r_only" ) { print qrcFile "capacitance \\\n"; print qrcFile " -ground_net \"$capGndNet\" \n\n"; } #unless close qrcFile; } #createQRCccl