Layout Versus Schematic verification (LVS)

LVS verification checks two schematics for correspondence of their topology and parameter values. In particular, schematics extracted from a layout can be compared with schematics with target parameters.

Preparation

lvs netlisting setup:

Netlisting process produces schematics netlistings using lvs views of the elements. (e.g. rsfq.basic/jj/lvs) Unfortunately, nlpExpr function can not evaluate functions such as division. It is required, for example, to convert bias supply cell to its resistor representation in the netlisting. To solve this problem and to use bias supplies with one connector, we implemented the following script:
/cadence/tools/dfII/etc/skill/fnl/LVS.il(e) To use it, make NLPElementPostamble property of the corresponding lvs cell view in rsfq.basic library call this function.
;---- Feb  9 17:12 96 cdsmgr 1271  --------------------------------------
;;
;; A. Rylyakov June 6 1995
;; functions for LVS netlister
;; should be kept in /home/cadence/tools/dfII/etc/skill/fnl/LVS.ile to work
;; encrypt("/home/cadence/tools/dfII/etc/skill/fnl/LVS.il"
;;         "/home/cadence/tools/dfII/etc/skill/fnl/LVS.ile" )
;;
;; N. Joukov (Kolya) October 2001 - Revised for Cadence 4.4.5
;; Some functions became obsolete - replaced
;; VDD net is now created by placing VDD symbol somewhere on schematics
;;
(procedure lvsNetlistISCRG(termName elemName)
    prog( (cellViewId vddName libName libId current biasVoltage res UPnum VDDnum formatString)
        cellViewId = fnlTopCell()
        libName =  cellViewId -> libName
        libId = ddGetObj(libName)
        current = cdfGetInstCDF( fnlCurrentInst())-> pnValue ->value
        biasVoltage = dbGet(libId "rsfqBiasVoltage")
        (cond ( ! biasVoltage biasVoltage = 8.66667 ))
        res = biasVoltage / (current + 0.00001)

        ;;; Feb 9, 1996 addition: if current is exactly zero
        ;;; do not netlist this element,
        ;;; a way out when we want to use the same schematic for
        ;;; lm2cir, LVS and PSCAN in cases when there's a non-trivial
        ;;; resistive tree
        (cond ( current == 0 return("") ))
        vddName = "VDD!"
        UPnum = fnlTermCdsNameExtName(termName)
        VDDnum = 1
        sprintf(formatString "i %s %s %s %d \"R %f\"" fnlCurrentInstExtName elemName UPnum VDDnum res)
        return(formatString)
    )
)


Schematics view:

  • Place an instance of the basic/VDD/symbol.

    Layout view:

  • Mark the inductances to be extracted by placing shapes in the layer m1l and m2l over the corresponding shapes in m1 and m2.
  • Mark the ground with 'GND!' shape pin. It should be just a two point line on the edge of some shape in the ground layer. (type: InputOutput)
  • Mark the power supply wire with 'VDD!' pin. (type: InputOutput)
  • Mark input and output terminals with pins. Note that pins directions should correspond to the directions of the corresponding pins in the schematics view.

    Extracted view:

  • From the layout view run verify->Extract command.
    Specify the rules file or library location (e.g. uncheck Rules Library checkbox if you store DRC/Extraction rules in a file and specify path to that file)
    Type in 'lvs' in the switches input field in order for marked inductances to be extracted
    Press OK button.

    Running LVS

  • From 'layout' or 'extracted' view run Verify->LVS
  • Specify run directory (e.g. LVS)
  • Specify the rules file or library location (e.g. uncheck Rules Library checkbox if you store LVS rules in a file and specify path to that file)
  • Fill in schematics and extracted views to run LVS on.
  • Run LVS.
  • Wait for a message box informing about successfull or unsuccessful LVS termination.
  • In case of success, check that netlists match by pressing the output button in the LVS dialog. If netlists match, but there are matching errors reported you can press 'Error display' button to see particular errors either on schematics or layout views.

    LVS rules file for diva:

    (download it)
  • lvsRules((L = 3.945)
        (L = 5.786)
        procedure((compareJunction layPlist schPlist)
    	prog((errstring Icl Ics)
    	    (Icl = (layPlist->Ic))
    	    (Ics = (schPlist->Ic))
    	    (Icdiff = abs((Icl - Ics)))
    	    cond(((Icl && Ics && (Icdiff > 0.007))
    		    sprintf(errstring "Value mismatch: %g (layout) %g (schematic)"
    			float(Icl)
    			float(Ics)
    		    )
    		    return(errstring)
    		)
    		(t
    		    return(nil)
    		)
    	    )
    	)
        )
        procedure((compareInductor layPlist schPlist)
    	prog((errstring Ll Ls)
    	    (Ll = (1.2 * (layPlist->L)))
    	    (Ls = (schPlist->L))
    	    (Lmax = max(Ls Ll))
    	    (Ldiff = abs((Ls - Ll)))
    	    cond(((Ll && Ls && (Lmax > 0.37) && (Ldiff > 0.33) && (Ldiff > (0.33 * Lmax)))
    		    sprintf(errstring "Value mismatch: %g (layout) %g (schematic)"
    			float(Ll)
    			float(Ls)
    		    )
    		    return(errstring)
    		)
    		(t
    		    return(nil)
    		)
    	    )
    	)
        )
        procedure((compareResistor layPlist schPlist)
    	prog((errstring Rl Rs)
    	    (Rl = (layPlist->R))
    	    (Rs = (schPlist->R))
    	    cond(((Rl && Rs && (Rs > 0.51) && (abs((Rs - Rl)) > (0.04 * max(Rs Rl))))
    		    sprintf(errstring "Value mismatch: %g (layout) %g (schematic)"
    			float(Rl)
    			float(Rs)
    		    )
    		    return(errstring)
    		)
    		(t
    		    return(nil)
    		)
    	    )
    	)
        )
        procedure((parallelInductor e1Plist e2Plist)
    	prog((parInd L1 L2)
    	    (parInd = ncons(nil))
    	    (L1 = (e1Plist->L))
    	    (L2 = (e2Plist->L))
    	    cond(((L1 && L2)
    		    (parInd->L = ((L1 * L2) / (L1 + L2)))
    		)
    	    )
    	    return(parInd)
    	)
        )
        procedure((seriesInductor e1Plist e2Plist)
    	prog((serInd L1 L2)
    	    (serInd = ncons(nil))
    	    (L1 = (e1Plist->L))
    	    (L2 = (e2Plist->L))
    	    cond(((L1 && L2)
    		    (serInd->L = (L1 + L2))
    		)
    	    )
    	    return(serInd)
    	)
        )
        procedure((parallelResistor e1Plist e2Plist)
    	prog((parRes R1 R2)
    	    (parRes = ncons(nil))
    	    (R1 = (e1Plist->R))
    	    (R2 = (e2Plist->R))
    	    cond(((R1 && R2)
    		    (parRes->R = ((R1 * R2) / (R1 + R2)))
    		)
    	    )
    	    return(parRes)
    	)
        )
        procedure((seriesResistor e1Plist e2Plist)
    	prog((serRes R1 R2)
    	    (serRes = ncons(nil))
    	    (R1 = (e1Plist->R))
    	    (R2 = (e2Plist->R))
    	    cond(((R1 && R2)
    		    (serRes->R = (R1 + R2))
    		)
    	    )
    	    return(serRes)
    	)
        )
        permuteDevice(parallel "inductor" parallelInductor)
        permuteDevice(series "inductor" seriesInductor)
        permuteDevice(parallel "resistor" parallelResistor)
        permuteDevice(series "resistor" seriesResistor)
        compareDeviceProperty("jjunction" compareJunction)
        compareDeviceProperty("inductor" compareInductor)
        compareDeviceProperty("resistor" compareResistor)
    ) 



    [Cadence IntegrationCadence Integration][ERC][DRC][Extract]

    Nikolai Joukov (kolya@rsfq1.physics.sunysb.edu) KTRACK statistics engine