<> <> <> <> <> <> <> <<>> DIRECTORY CD, CDAtomicObjects, CDBasics, CDCells, CDInstances, CDLayers, CDProperties, CDRects, CDSymbolicObjects, CDTexts, CMos, Core, CoreClasses, CoreGeometry, PW, Sinix, SinixOps; SinixCMosA: CEDAR PROGRAM IMPORTS CD, CDBasics, CDCells, CDInstances, CDLayers, CDProperties, CDRects, CDSymbolicObjects, CDTexts, CMos, CoreClasses, CoreGeometry, PW, 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; <> mode: Sinix.Mode _ NEW [Sinix.ModeRec _ [ extractProcProp: PW.RegisterProp[$CMosAExtractProc, TRUE], decoration: CoreGeometry.CreateDecoration["CMosA"], equalProc: Sinix.CompareProps, instanceLayer: Sinix.DefaultInstanceLayer, touchProc: CoreGeometry.Touch ]]; 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]]]; }; <> MakeAbstract: PUBLIC PROC [abstract, represents: CD.Layer] RETURNS [sameAbstract: CD.Layer] = { CDLayers.MakeAbstract[abstract, represents]; RETURN [abstract]; }; <> nsource: CD.Layer _ MakeAbstract[CD.NewLayer[CMos.cmos, $CNSource], CMos.ndif]; ndrain: CD.Layer _ MakeAbstract[CD.NewLayer[CMos.cmos, $CNDrain], CMos.ndif]; psource: CD.Layer _ MakeAbstract[CD.NewLayer[CMos.cmos, $CPSource], CMos.pdif]; pdrain: CD.Layer _ MakeAbstract[CD.NewLayer[CMos.cmos, $CPDrain], CMos.pdif]; ExtractTransistor: Sinix.ExtractProc = { cellType: CellType; lambda: CD.Number = CMos.lambda; ext: CD.Number = 2*lambda; wellSurr: CD.Number _ 0; innerX: CD.Number _ 0; dif: CD.Layer _ IF obj.layer=CMos.wpdif OR obj.layer=CMos.pdif THEN CMos.pdif ELSE CMos.ndif; gateWire, sourceWire, drainWire: Wire; IF obj.layer=CMos.wpdif OR obj.layer=CMos.wndif THEN { wellSurr _ CMos.wellSurround; innerX _ CMos.wellSurround-ext; }; cellType _ CoreClasses.CreateTransistor[[ type: IF dif=CMos.pdif THEN pE ELSE nE, length: (obj.size.y-2*ext-2*wellSurr)/lambda, width: (obj.size.x-2*ext-2*innerX)/lambda]]; 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=CMos.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=CMos.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 CMos.ndif => {}; CMos.pdif => {}; CMos.pol => AddRect[mode, gateWire, rect, CMos.pol]; CMos.nwell, CMos.pwell => {}; ENDCASE => ERROR; ENDLOOP; CoreGeometry.PutIR[mode.decoration, cellType, CD.InterestRect[obj]]; result _ cellType; }; ExtractTransistorL: Sinix.ExtractProc = { cellType: CellType; lambda: CD.Number = CMos.lambda; wellSurround: CD.Number = CMos.wellSurround; ext: CD.Number = 2*lambda; wellSurr: CD.Number _ 0; innerX: CD.Number _ 0; gateWire, sourceWire, drainWire: Wire; dif: CD.Layer _ IF obj.layer=CMos.wpdif OR obj.layer=CMos.pdif THEN CMos.pdif ELSE CMos.ndif; IF obj.layer=CMos.wpdif OR obj.layer=CMos.wndif THEN { wellSurr _ wellSurround; innerX _ wellSurround-ext; }; cellType _ CoreClasses.CreateTransistor[[ type: IF dif=CMos.pdif THEN pE ELSE nE, length: (obj.size.x+obj.size.y-2*innerX-2*wellSurr)/lambda - 10, width: 2]]; gateWire _ cellType.public[0]; sourceWire _ cellType.public[1]; drainWire _ cellType.public[2]; <> AddRect[mode, sourceWire, [x1: innerX+ext, x2: obj.size.x-wellSurr-4*lambda, y1: wellSurr+4*lambda, y2: wellSurr+6*lambda], IF dif=CMos.pdif THEN psource ELSE nsource]; AddRect[mode, sourceWire, [x1: obj.size.x-wellSurr-6*lambda, x2: obj.size.x-wellSurr-4*lambda, y1: wellSurr+4*lambda, y2: obj.size.y-innerX-ext], IF dif=CMos.pdif THEN psource ELSE nsource]; AddRect[mode, drainWire, [x1: innerX+ext, x2: obj.size.x-wellSurr, y1: wellSurr, y2: wellSurr+2*lambda], IF dif=CMos.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=CMos.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 CMos.pol => AddRect[mode, gateWire, rect, CMos.pol]; CMos.ndif => {}; CMos.pdif => {}; CMos.nwell, CMos.pwell => {}; ENDCASE => ERROR; ENDLOOP; CoreGeometry.PutIR[mode.decoration, cellType, CD.InterestRect[obj]]; result _ cellType; }; <> Atomic: PROC [className: ATOM] = { class: CD.ObjectClass = CD.FetchObjectClass[className, CMos.cmos]; CDProperties.PutProp[class, mode.extractProcProp, $ExtractAtomic]; }; <> CDProperties.PutLayerProp[CMos.pwell, $Well, $PWell]; CDProperties.PutLayerProp[CMos.nwell, $Well, $NWell]; CDProperties.PutLayerProp[CMos.ndif, $RoutingLayer, $RoutingLayer]; CDProperties.PutLayerProp[CMos.pdif, $RoutingLayer, $RoutingLayer]; CDProperties.PutLayerProp[CMos.pol, $RoutingLayer, $RoutingLayer]; CDProperties.PutLayerProp[CMos.met, $RoutingLayer, $RoutingLayer]; CDProperties.PutLayerProp[CMos.met2, $RoutingLayer, $RoutingLayer]; <> SinixOps.RegisterDefaultLayoutMode[CMos.cmos, mode]; <> Sinix.RegisterExtractProc[$CMosAExtractTransistor, ExtractTransistor]; Sinix.RegisterExtractProc[$CMosAExtractTransistorL, ExtractTransistorL]; <> CDProperties.PutProp[CDCells.cellClass, mode.extractProcProp, $ExtractCell]; 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, $ExtractRect]; <> Atomic[className: $CSimpleCon]; Atomic[className: $CWellSimpleCon]; Atomic[className: $CButtingCont]; Atomic[className: $CWellButtingCont]; Atomic[className: $CVia]; Atomic[className: $CDifShortCon]; Atomic[className: $CWellDifShortCon]; <> Atomic[className: $CMosPDifRect]; <> CDProperties.PutProp[CD.FetchObjectClass[$CTrans, CMos.cmos], mode.extractProcProp, $CMosAExtractTransistor]; CDProperties.PutProp[CD.FetchObjectClass[$CWellTrans, CMos.cmos], mode.extractProcProp, $CMosAExtractTransistor]; <> CDProperties.PutProp[CD.FetchObjectClass[$CLTrans, CMos.cmos], mode.extractProcProp, $CMosAExtractTransistorL]; CDProperties.PutProp[CD.FetchObjectClass[$CLWellTrans, CMos.cmos], mode.extractProcProp, $CMosAExtractTransistorL]; <> CDProperties.PutProp[CDTexts.textClass, mode.extractProcProp, $ExtractNull]; END.