<> <> <> <> <> <<>> DIRECTORY CD, CDAtomicObjects, CDBasics, CDCells, CDDirectory, CDInstances, CDLayers, CDProperties, CDRects, CDSymbolicObjects, CDTexts, CMosB, Core, CoreClasses, CoreOps, CoreProperties, CoreGeometry, PW, PWObjects, Rope, Sinix, SinixOps; SinixCMosB: CEDAR PROGRAM IMPORTS CD, CDBasics, CDCells, CDDirectory, CDInstances, CDLayers, CDProperties, CDRects, CDSymbolicObjects, CDTexts, CMosB, CoreClasses, CoreGeometry, CoreOps, CoreProperties, PW, PWObjects, Rope, Sinix, SinixOps SHARES CDCells, CDLayers, CDRects, CDSymbolicObjects, CDTexts = BEGIN <> CellType: TYPE = Core.CellType; Wire: TYPE = Core.Wire; Object: TYPE = CD.Object; Properties: TYPE = Core.Properties; ROPE: TYPE = Core.ROPE; ROPES: TYPE = LIST OF ROPE; <> mode: Sinix.Mode _ NEW [Sinix.ModeRec _ [ extractProcProp: PW.RegisterProp[$CMosBExtractProc, TRUE], decoration: CoreGeometry.CreateDecoration["CMosB"], nbOfLayers: NbOfInterestingLayers, instanceLayer: InstanceLayer, touchProc: CoreGeometry.Touch, 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; SELECT TRUE FROM inst.ob.class=CDRects.bareRectClass => layer _ inst.ob.layer; CDSymbolicObjects.IsSymbolicOb[inst.ob] => layer _ CDSymbolicObjects.GetLayer[inst]; ENDCASE => RETURN [[0, NbOfInterestingLayers-1]]; -- could be optimized for contacts! layer _ CDLayers.AbstractToPaint[layer]; FOR i: NAT IN [0 .. NbOfInterestingLayers) DO IF InterestingLayers[i]=layer THEN RETURN [[i, i]]; ENDLOOP; RETURN [[0, NbOfInterestingLayers-1]]; }; ExtractRect: Sinix.ExtractProc = { RETURN (IF obj.layer=CMosB.pwell OR obj.layer=CMosB.nwell THEN Sinix.ExtractNull ELSE Sinix.ExtractRect)[obj, mode, properties, userData]; }; AddRect: PROC [mode: Sinix.Mode, wire: Wire, rect: CD.Rect, layer: CD.Layer] = { instance: CD.Instance _ CDInstances.NewInst[ ob: CDRects.CreateRect[CDBasics.SizeOfRect[rect], layer], location: CDBasics.BaseOfRect[rect] ]; CoreGeometry.PutPins[mode.decoration, wire, CONS [instance, CoreGeometry.GetPins[mode.decoration, wire]]]; }; <> PropsFromSatellites: PROC [obj: Object, properties: CD.PropList] RETURNS [props: Core.Properties _ NIL] = { name: ROPE _ NIL; FOR ropes: ROPES _ NARROW [CDProperties.GetListProp[properties, Sinix.satellitesProp]], ropes.rest WHILE ropes#NIL DO IF name#NIL AND NOT Rope.Equal[ropes.first, name] THEN SIGNAL Sinix.FusionPropMismatch[CDDirectory.Name[obj], CoreOps.nameProp, name, ropes.first]; name _ ropes.first; ENDLOOP; IF name#NIL THEN props _ CoreProperties.Props[[CoreOps.nameProp, name]]; }; MakeAbstract: PROC [abstract, represents: CD.Layer] RETURNS [sameAbstract: CD.Layer] = { CDLayers.MakeAbstract[abstract, represents]; RETURN [abstract]; }; <> 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]; ExtractTransistor: 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[[ type: IF dif=CMosB.pdif THEN pE ELSE nE, length: (obj.size.y-2*ext-2*wellSurr)/lambda-2, width: (obj.size.x-2*ext-2*innerX)/lambda]]; props _ PropsFromSatellites[obj, properties]; gateWire _ cellType.public[0]; sourceWire _ cellType.public[1]; drainWire _ cellType.public[2]; AddRect[mode, sourceWire, [x1: innerX+ext, x2: obj.size.x-ext-innerX, y1: wellSurr, y2: ext+wellSurr], IF dif=CMosB.pdif THEN psource ELSE nsource]; AddRect[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 => AddRect[mode, gateWire, rect, CMosB.pol]; CMosB.nwell, CMosB.pwell => {}; ENDCASE => ERROR; ENDLOOP; CoreGeometry.PutIR[mode.decoration, cellType, CD.InterestRect[obj]]; result _ cellType; }; ExtractTransistorL: 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; IF obj.layer=CMosB.wpdif OR obj.layer=CMosB.wndif THEN { wellSurr _ wellSurround; innerX _ wellSurround-ext; }; cellType _ CoreClasses.CreateTransistor[[ type: IF obj.layer=CMosB.wpdif OR obj.layer=CMosB.pdif THEN pE ELSE nE, length: 2, width: (obj.size.x+obj.size.y-2*innerX-2*wellSurr)/lambda - 12]]; props _ PropsFromSatellites[obj, properties]; gateWire _ cellType.public[0]; sourceWire _ cellType.public[1]; drainWire _ cellType.public[2]; <> AddRect[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]; AddRect[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]; AddRect[mode, drainWire, [x1: innerX+ext, x2: obj.size.x-wellSurr, y1: wellSurr, y2: wellSurr+2*lambda], IF dif=CMosB.pdif THEN pdrain ELSE ndrain]; AddRect[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 => AddRect[mode, gateWire, rect, CMosB.pol]; CMosB.ndif => {}; CMosB.pdif => {}; CMosB.nwell, CMosB.pwell => {}; ENDCASE => ERROR; ENDLOOP; CoreGeometry.PutIR[mode.decoration, cellType, CD.InterestRect[obj]]; result _ cellType; }; <> Atomic: PROC [className: ATOM] = { class: CD.ObjectClass = CD.FetchObjectClass[className, CMosB.cmosB]; CDProperties.PutProp[class, mode.extractProcProp, $ExtractAtomic]; }; FilterMask: SinixOps.FilterProc = {RETURN [Rope.Match["*.mask", name]]}; <> CDProperties.PutLayerProp[CMosB.pwell, $Well, $PWell]; CDProperties.PutLayerProp[CMosB.nwell, $Well, $NWell]; CDProperties.PutLayerProp[CMosB.ndif, $RoutingLayer, $RoutingLayer]; CDProperties.PutLayerProp[CMosB.pdif, $RoutingLayer, $RoutingLayer]; CDProperties.PutLayerProp[CMosB.pol, $RoutingLayer, $RoutingLayer]; CDProperties.PutLayerProp[CMosB.met, $RoutingLayer, $RoutingLayer]; CDProperties.PutLayerProp[CMosB.met2, $RoutingLayer, $RoutingLayer]; CDProperties.PutLayerProp[CMosB.ovg, $RoutingLayer, $RoutingLayer]; <> SinixOps.RegisterDefaultLayoutMode[CMosB.cmosB, mode]; SinixOps.RegisterBackgroundExtractionCommand[CMosB.cmosB, mode, "CMosB background extraction", $CMosBBackgroundExtract, FilterMask]; <> Sinix.RegisterExtractProc[$CMosBExtractRect, ExtractRect]; Sinix.RegisterExtractProc[$CMosBExtractTransistor, ExtractTransistor]; Sinix.RegisterExtractProc[$CMosBExtractTransistorL, ExtractTransistorL]; <> CDProperties.PutProp[CDCells.cellClass, mode.extractProcProp, $ExtractCell]; CDProperties.PutProp[PWObjects.abutXClass, mode.extractProcProp, $ExtractAbut]; CDProperties.PutProp[PWObjects.abutYClass, mode.extractProcProp, $ExtractAbut]; <> CDProperties.PutProp[CDSymbolicObjects.pinClass, mode.extractProcProp, $ExtractPin]; CDProperties.PutProp[CDSymbolicObjects.segmentClass, mode.extractProcProp, $ExtractPin]; CDProperties.PutProp[CDSymbolicObjects.markClass, mode.extractProcProp, $ExtractPin]; <> CDProperties.PutProp[CDRects.bareRectClass, mode.extractProcProp, $CMosBExtractRect]; <> 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]; Atomic[className: $C2NDifRect]; <> CDProperties.PutProp[CD.FetchObjectClass[$C2Trans, CMosB.cmosB], mode.extractProcProp, $CMosBExtractTransistor]; CDProperties.PutProp[CD.FetchObjectClass[$C2WellTrans, CMosB.cmosB], mode.extractProcProp, $CMosBExtractTransistor]; <> CDProperties.PutProp[CD.FetchObjectClass[$C2LTrans, CMosB.cmosB], mode.extractProcProp, $CMosBExtractTransistorL]; CDProperties.PutProp[CD.FetchObjectClass[$C2LWellTrans, CMosB.cmosB], mode.extractProcProp, $CMosBExtractTransistorL]; <> CDProperties.PutProp[CDTexts.textClass, mode.extractProcProp, $ExtractNull]; END.