<> <> <> <> <<>> DIRECTORY CD, CDAtomicObjects, CDBasics, CDCells, CDInstances, CDLayers, CDProperties, CDOrient, CDRects, CDSimpleRules, CDSymbolicObjects, CDTexts, CMosB, Core, CoreClasses, CoreOps, CoreProperties, PW, PWObjects, PWPins, Sinix, SinixCMos, SinixHighlight; SinixCheckB: CEDAR PROGRAM IMPORTS CD, CDBasics, CDCells, CDOrient, CDInstances, CDLayers, CDProperties, CDRects, CDSimpleRules, CDSymbolicObjects, CDTexts, CMosB, CoreClasses, CoreOps, CoreProperties, PW, PWObjects, PWPins, Sinix, SinixCMos, SinixHighlight EXPORTS SinixCMos SHARES CDCells, CDRects, CDSymbolicObjects, CDTexts = BEGIN OPEN SinixCMos; <> checkBMode: PUBLIC Sinix.Mode _ NEW [Sinix.ModeRec _ [ name: "CheckB", extractProcProp: PW.RegisterProp[$SinixCMosCheckBProc, TRUE], pinsProp: CoreProperties.RegisterProperty[$SinixCMosCheckBPins], wireGeometryProp: CoreProperties.RegisterProperty[$SinixCMosCheckBWireGeometry, CoreProperties.Props[[CoreProperties.propCopy, CoreProperties.PropDoCopy]]], instanceProp: CoreProperties.RegisterProperty[$SinixCMosCheckBInstance, CoreProperties.Props[[CoreProperties.propCopy, CoreProperties.PropDoCopy]]], cacheProp: PW.RegisterProp[$SinixCheckBCache, FALSE, TRUE], cachePropsProp: PW.RegisterProp[$SinixCheckBCacheProps, FALSE, TRUE], nbOfLayers: NbOfInterestingLayers, instanceLayer: InstanceLayer, flatNameSpace: TRUE, equalProc: Sinix.CompareProps ]]; InterestingLayers: ARRAY [0 .. NbOfInterestingLayers) OF CD.Layer _ [CMosB.met2, CMosB.cut2, CMosB.met, CMosB.cut, CMosB.ovg, CMosB.pol, CMosB.pdif, CMosB.ndif, CMosB.pwellCont, CMosB.nwellCont]; NbOfInterestingLayers: NAT = 10; InstanceLayer: PROC [inst: CD.Instance] RETURNS [Sinix.LayerRange] = { layer: CD.Layer _ CDLayers.AbstractToPaint[IF CDSymbolicObjects.IsSymbolicOb[inst.ob] THEN CDSymbolicObjects.GetLayer[inst] ELSE inst.ob.layer]; FOR i: NAT IN [0 .. NbOfInterestingLayers) DO IF InterestingLayers[i]=layer THEN RETURN [[i, i]]; ENDLOOP; RETURN [[0, NbOfInterestingLayers-1]]; }; CheckBPin: Sinix.ExtractProc = { wire: Wire; instance: CD.Instance _ PWPins.NewInstance[ob: obj, properties: properties]; layer: CD.Layer _ CDSymbolicObjects.GetLayer[instance]; name: ROPE _ CDSymbolicObjects.GetName[instance]; IF IsWellLayer[layer] OR layer=CD.commentLayer THEN RETURN [NIL]; wire _ CoreOps.CreateWire[]; CheckAddRect[mode, wire, CDBasics.RectAt[[0, 0], obj.size], CDLayers.AbstractToPaint[layer]]; -- CDLayers.AbstractToPaint important to not create geometry bigger than pin [] _ CoreOps.SetShortWireName[wire, name]; AddNamesToWire[wire, properties]; result _ wire; }; <> nbOfCheckedLayers: NAT = 8; checkedLayers: ARRAY [0 .. nbOfCheckedLayers) OF CD.Layer _ [CMosB.met, CMosB.met2, CMosB.pol, CMosB.ndif, CMosB.pdif, CMosB.cut, CMosB.cut2, CMosB.ovg]; MaxClipDistance: PROC RETURNS [max: INT _ 0] = { FOR i: NAT IN [0 .. nbOfCheckedLayers) DO FOR j: NAT IN [i .. nbOfCheckedLayers) DO max _ MAX [max, CDSimpleRules.MinDist[checkedLayers[i], checkedLayers[j]]]; ENDLOOP; ENDLOOP; }; CheckTouchRect: Sinix.TouchProc = { RETURN [CheckTouchRectObject[mode, instance2, CDInstances.InstRectO[instance1], instance1.ob.layer]]; }; CheckTouchRectObject: PROC [mode: Sinix.Mode, instance: CD.Instance, rect: CD.Rect, layer: CD.Layer] RETURNS [yes: BOOL _ FALSE] = { rectInstance: CD.Instance; IF instance.ob.class=CDRects.bareRectClass THEN { minDist: INT _ CDSimpleRules.MinDist[CDLayers.AbstractToPaint[layer], CDLayers.AbstractToPaint[instance.ob.layer]]; IF minDist=0 THEN RETURN [CDLayers.AbstractToPaint[instance.ob.layer]=CDLayers.AbstractToPaint[layer]]; RETURN [CDBasics.Intersect[CDBasics.Extend[CDInstances.InstRectO[instance], minDist-1], rect]]; }; rectInstance _ PWPins.NewInstance[ ob: CDRects.CreateRect[CDBasics.SizeOfRect[rect], layer], location: CDBasics.BaseOfRect[rect] ]; yes _ Sinix.Touch[mode, instance, rectInstance]; }; CheckAddRect: PROC [mode: Sinix.Mode, wire: Wire, rect: CD.Rect, layer: CD.Layer] = { instance: CD.Instance _ PWPins.NewInstance[ ob: CDRects.CreateRect[CDBasics.SizeOfRect[rect], layer], location: CDBasics.BaseOfRect[rect] ]; CDProperties.PutInstanceProp[instance, Sinix.touchProcProp, NEW [Sinix.TouchProc _ CheckTouchRect]]; Sinix.AddPinsProp[mode, wire, instance]; }; CheckBRect: Sinix.ExtractProc = { wire: Wire; IF IsWellLayer[obj.layer] OR obj.layer=CD.commentLayer THEN RETURN [NIL]; wire _ CoreOps.CreateWire[]; CheckAddRect[mode, wire, CDBasics.RectAt[[0, 0], obj.size], obj.layer]; AddNamesToWire[wire, properties]; result _ wire; }; <> <> CheckBAtomicWell: PUBLIC Sinix.ExtractProc = { wire: Wire; wire _ CoreOps.CreateWire[]; FOR rList: CDAtomicObjects.DrawList _ NARROW [obj.specificRef, CDAtomicObjects.AtomicObsPtr].rList, rList.rest WHILE rList#NIL DO IF ~IsWellLayer[rList.first.lev] THEN CheckAddRect[mode, wire, rList.first.r, rList.first.lev]; ENDLOOP; AddNamesToWire[wire, properties]; result _ wire; }; <> <> <> <> <<};>> <> CheckBWellDiff: Sinix.ExtractProc = { wire: Wire; wire _ CoreOps.CreateWire[]; CheckAddRect[mode, wire, CDBasics.Extend[CDBasics.RectAt[[0, 0], obj.size], -CMosB.wellSurround], CMosB.pdif]; AddNamesToWire[wire, properties]; result _ wire; }; <> <> <> <> <> <> <> <> <<};>> <> <> nsource: CD.Layer _ MakeAbstract[CD.NewLayer[CMosB.cmosB, $CNSource], CMosB.ndif]; ndrain: CD.Layer _ MakeAbstract[CD.NewLayer[CMosB.cmosB, $CNDrain], CMosB.ndif]; psource: CD.Layer _ MakeAbstract[CD.NewLayer[CMosB.cmosB, $CPSource], CMosB.pdif]; pdrain: CD.Layer _ MakeAbstract[CD.NewLayer[CMosB.cmosB, $CPDrain], CMosB.pdif]; CheckBTransistor: Sinix.ExtractProc = { cellType: CellType; lambda: CD.Number = CMosB.lambda; ext: CD.Number = 2*lambda; wellSurr: CD.Number _ 0; innerX: CD.Number _ 0; dif: CD.Layer _ IF obj.layer=CMosB.wpdif OR obj.layer=CMosB.pdif THEN CMosB.pdif ELSE CMosB.ndif; gateWire, sourceWire, drainWire: Wire; IF obj.layer=CMosB.wpdif OR obj.layer=CMosB.wndif THEN { wellSurr _ CMosB.wellSurround; innerX _ CMosB.wellSurround-ext; }; cellType _ CoreClasses.CreateTransistor[[IF dif=CMosB.pdif THEN pE ELSE nE]]; gateWire _ cellType.public[0]; sourceWire _ cellType.public[1]; drainWire _ cellType.public[2]; CheckAddRect[mode, sourceWire, [x1: innerX+ext, x2: obj.size.x-ext-innerX, y1: wellSurr, y2: ext+wellSurr], IF dif=CMosB.pdif THEN psource ELSE nsource]; CheckAddRect[mode, drainWire, [x1: innerX+ext, x2: obj.size.x-ext-innerX, y1: obj.size.y-wellSurr-ext, y2: obj.size.y-wellSurr], IF dif=CMosB.pdif THEN pdrain ELSE ndrain]; FOR rList: CDAtomicObjects.DrawList _ NARROW [obj.specificRef, CDAtomicObjects.AtomicObsPtr].rList, rList.rest WHILE rList#NIL DO rect: CD.Rect _ rList.first.r; layer: CD.Layer _ rList.first.lev; SELECT layer FROM CMosB.ndif => {}; CMosB.pdif => {}; CMosB.pol => CheckAddRect[mode, gateWire, rect, CMosB.pol]; CMosB.nwell, CMosB.pwell => {}; ENDCASE => ERROR; ENDLOOP; result _ cellType; }; CheckBTransistorL: Sinix.ExtractProc = { cellType: CellType; lambda: CD.Number = CMosB.lambda; wellSurround: CD.Number = CMosB.wellSurround; ext: CD.Number = 2*lambda; wellSurr: CD.Number _ 0; innerX: CD.Number _ 0; gateWire, sourceWire, drainWire: Wire; dif: CD.Layer _ IF obj.layer=CMosB.wpdif OR obj.layer=CMosB.pdif THEN CMosB.pdif ELSE CMosB.ndif; cellType _ CoreClasses.CreateTransistor[[IF obj.layer=CMosB.wpdif OR obj.layer=CMosB.pdif THEN pE ELSE nE]]; gateWire _ cellType.public[0]; sourceWire _ cellType.public[1]; drainWire _ cellType.public[2]; IF obj.layer=CMosB.wpdif OR obj.layer=CMosB.wndif THEN { wellSurr _ wellSurround; innerX _ wellSurround-ext; }; <> CheckAddRect[mode, sourceWire, [x1: innerX+ext, x2: obj.size.x-wellSurr-6*lambda, y1: wellSurr+6*lambda, y2: wellSurr+8*lambda], IF dif=CMosB.pdif THEN psource ELSE nsource]; CheckAddRect[mode, sourceWire, [x1: obj.size.x-wellSurr-8*lambda, x2: obj.size.x-wellSurr-6*lambda, y1: wellSurr+6*lambda, y2: obj.size.y-innerX-ext], IF dif=CMosB.pdif THEN psource ELSE nsource]; CheckAddRect[mode, drainWire, [x1: innerX+ext, x2: obj.size.x-wellSurr, y1: wellSurr, y2: wellSurr+2*lambda], IF dif=CMosB.pdif THEN pdrain ELSE ndrain]; CheckAddRect[mode, drainWire, [x1: obj.size.x-wellSurr-2*lambda, x2: obj.size.x-wellSurr, y1: wellSurr, y2: obj.size.y-innerX-ext], IF dif=CMosB.pdif THEN pdrain ELSE ndrain]; FOR rList: CDAtomicObjects.DrawList _ NARROW [obj.specificRef, CDAtomicObjects.AtomicObsPtr].rList, rList.rest WHILE rList#NIL DO rect: CD.Rect _ rList.first.r; layer: CD.Layer _ rList.first.lev; SELECT layer FROM CMosB.pol => CheckAddRect[mode, gateWire, rect, CMosB.pol]; CMosB.ndif => {}; CMosB.pdif => {}; CMosB.nwell, CMosB.pwell => {}; ENDCASE => ERROR; ENDLOOP; result _ cellType; }; <> CheckBContextCreator: SinixHighlight.ExtractContextCreator = { context _ NEW [SinixHighlight.ExtractContextRec _ [mode: checkBMode, userData: NIL]]; }; Atomic: PROC [className: ATOM, extractProc: ATOM _ $CheckBAtomicWell] = { class: CD.ObjectClass = CD.FetchObjectClass[className, CMosB.cmosB]; CDProperties.PutProp[class, checkBMode.extractProcProp, extractProc]; }; checkBMode.clipDistance _ MaxClipDistance[]; <<>> <> SinixHighlight.RegisterHighlightCommand[CMosB.cmosB, CheckBContextCreator, "Highlight net for CheckB", $HighlightNetForCheckB]; SinixHighlight.RegisterExtractCommand[CMosB.cmosB, CheckBContextCreator, "Extract for CheckB", $ExtractForCheckB]; <> Sinix.RegisterExtractProc[$CheckBPin, CheckBPin]; Sinix.RegisterExtractProc[$CheckBRect, CheckBRect]; Sinix.RegisterExtractProc[$CheckBAtomicWell, CheckBAtomicWell]; Sinix.RegisterExtractProc[$CheckBWellDiff, CheckBWellDiff]; Sinix.RegisterExtractProc[$CheckBTransistor, CheckBTransistor]; Sinix.RegisterExtractProc[$CheckBTransistorL, CheckBTransistorL]; <> CDProperties.PutProp[CDCells.cellClass, checkBMode.extractProcProp, $ExtractCell]; CDProperties.PutProp[CDSymbolicObjects.pinClass, checkBMode.extractProcProp, $CheckBPin]; CDProperties.PutProp[CDSymbolicObjects.segmentClass, checkBMode.extractProcProp, $CheckBPin]; CDProperties.PutProp[CDSymbolicObjects.markClass, checkBMode.extractProcProp, $CheckBPin]; CDProperties.PutProp[PWObjects.abutXClass, checkBMode.extractProcProp, $ExtractAbut]; CDProperties.PutProp[PWObjects.abutYClass, checkBMode.extractProcProp, $ExtractAbut]; <> CDProperties.PutProp[CDRects.bareRectClass, checkBMode.extractProcProp, $CheckBRect]; <> Atomic[className: $C2SimpleCon]; Atomic[className: $C2WellSimpleCon]; Atomic[className: $C2LargeSimpleCon]; Atomic[className: $C2LargeWellSimpleCon]; Atomic[className: $C2DifShortCon]; Atomic[className: $C2WellDifShortCon]; Atomic[className: $C2Via]; Atomic[className: $C2LargeVia]; <> Atomic[className: $C2PDifRect, extractProc: $CheckBWellDiff]; Atomic[className: $C2NDifRect, extractProc: $CheckBWellDiff]; <> CDProperties.PutProp[CD.FetchObjectClass[$C2Trans, CMosB.cmosB], checkBMode.extractProcProp, $CheckBTransistor]; CDProperties.PutProp[CD.FetchObjectClass[$C2WellTrans, CMosB.cmosB], checkBMode.extractProcProp, $CheckBTransistor]; <> CDProperties.PutProp[CD.FetchObjectClass[$C2LTrans, CMosB.cmosB], checkBMode.extractProcProp, $CheckBTransistorL]; <> CDProperties.PutProp[CD.FetchObjectClass[$C2LWellTrans, CMosB.cmosB], checkBMode.extractProcProp, $CheckBTransistorL]; <> CDProperties.PutProp[CDTexts.textClass, checkBMode.extractProcProp, $ExtractNull]; END.