DIRECTORY CD, CDBasics, CDCells, CDDirectory, CDProperties, CDRects, CDRoutingObjects, CDSymbolicObjects, CDTexts, CMosB, Core, CoreClasses, CoreGeometry, CoreGeometryBackdoor, CoreOps, CoreProperties, IO, PW, RefTab, Rope, Sinix, SinixOps, SinixRawCMosB, TerminalIO; SinixRawCMosBImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDCells, CDDirectory, CDProperties, CDRects, CDRoutingObjects, CDSymbolicObjects, CDTexts, CMosB, CoreGeometry, CoreGeometryBackdoor, CoreClasses, CoreOps, CoreProperties, IO, PW, RefTab, Rope, Sinix, SinixOps, TerminalIO EXPORTS SinixRawCMosB SHARES CDCells, CDRects, CDSymbolicObjects, CDTexts = BEGIN CellType: TYPE = Core.CellType; Wire: TYPE = Core.Wire; Wires: TYPE = Core.Wires; Object: TYPE = CD.Object; Properties: TYPE = Core.Properties; ROPE: TYPE = Core.ROPE; standardMode: Sinix.Mode = SinixOps.GetExtractMode[CMosB.cmosB]; justKeepOne: BOOL _ FALSE; mode: PUBLIC Sinix.Mode _ NEW [Sinix.ModeRec _ [ extractProcProp: PW.RegisterProp[$RawCMosBExtractProc, TRUE], decoration: CoreGeometry.CreateDecoration["RawCMosB"], instanceEqualProc: InstanceEqual, objectEqualProc: ObjectEqual, nbOfLayers: standardMode.nbOfLayers, instanceLayer: standardMode.instanceLayer, touchProc: standardMode.touchProc, fusionByName: none, userData: UserData, nameProc: standardMode.nameProc ]]; ObjectEqual: PROC [obj: Object, cacheUserData: REF, userData: REF] RETURNS [cacheOK: BOOL] = { cacheData: REF INT = NARROW [cacheUserData]; data: REF INT = NARROW [userData]; RETURN [cacheData^>=data^]; }; InstanceEqual: PROC [obj: Object, cacheProperties: CD.PropList, cacheUserData: REF, properties: CD.PropList, userData: REF] RETURNS [cacheOK: BOOL] = { cacheOK _ Sinix.CompareProperties[obj, cacheProperties, cacheUserData, properties, userData] AND ObjectEqual[obj, cacheUserData, userData]; }; UserData: PROC [design: CD.Design] RETURNS [REF] = {RETURN [NEW [INT _ 0]]}; Mark: PROC [design: CD.Design] RETURNS [total, marked: INT _ 0] = { usage: RefTab.Ref = RefTab.Create[]; -- maps every cell to the containing cell. Objects are keys, and values are either $unique, or $many if several cell contain that object. CountEachUse: CDDirectory.EachObjectProc = { EachInst: CDCells.InstEnumerator = { value: REF = RefTab.Fetch[usage, inst.ob].val; IF NOT CDCells.IsCell[inst.ob] THEN RETURN; [] _ RefTab.Store[usage, inst.ob, IF value=NIL THEN $unique ELSE $many]; }; IF NOT CDCells.IsCell[me] THEN RETURN; total _ total + 1; [] _ CDCells.EnumerateInstances[me, EachInst]; }; MarkUniques: RefTab.EachPairAction = { IF val=$many THEN RETURN; marked _ marked + 1; CDProperties.PutProp[key, $RawFlatten, $RawFlatten]; }; [] _ CDDirectory.EnumerateDesign[design, CountEachUse]; [] _ RefTab.Pairs[usage, MarkUniques]; }; IsOverglass: PROC [obj: CD.Object] RETURNS [BOOL] = { RETURN [obj.class=CDRects.bareRectClass AND obj.layer=CMosB.ovg]; }; SpecialGetGeometry: PROC [wire: Wire] RETURNS [geometry: CoreGeometry.Instances _ NIL, ovg: BOOL _ FALSE] = { ConsEachGeom: CoreGeometry.EachInstanceProc = { SELECT TRUE FROM IsOverglass[instance.obj] => {ovg _ TRUE; geometry _ CONS [instance, geometry]}; geometry=NIL => geometry _ LIST [instance]; ENDCASE => IF NOT justKeepOne THEN geometry _ CONS [instance, geometry]; }; [] _ CoreGeometry.EnumerateGeometry[mode.decoration, wire, ConsEachGeom]; }; RawExtractCell: Sinix.ExtractProc = { flattenSomeChild: BOOL _ FALSE; rct: CoreClasses.RecordCellType; new, record: CellType; newInternals: Wires _ NIL; -- used only if flatten of a child necessary instances: LIST OF CoreClasses.CellInstance _ NIL; -- used only if flatten of a child necessary [result, props] _ Sinix.ExtractCell[obj, mode, properties, userData]; record _ NARROW [result]; rct _ NARROW [record.data]; IF rct.size=0 THEN CoreProperties.PutCellTypeProp[record, $RawFlatten, $Keep]; IF CDProperties.GetObjectProp[obj, $RawFlatten]=$RawFlatten THEN CoreProperties.PutCellTypeProp[record, $RawFlatten, $Smash]; FOR i: NAT IN [0 .. rct.size) DO IF CoreProperties.GetCellTypeProp[rct[i].type, $RawFlatten]#NIL THEN flattenSomeChild _ TRUE; ENDLOOP; IF NOT flattenSomeChild THEN RETURN; TerminalIO.PutF["In cell %g, flattening:", IO.rope[PW.Name[obj]]]; FOR i: NAT IN [0 .. rct.size) DO IF CoreProperties.GetCellTypeProp[rct[i].type, $RawFlatten]=NIL THEN instances _ CONS [rct[i], instances] ELSE { CreateWire: PROC [old: Wire] RETURNS [wire: Wire] = { geometry: CoreGeometry.Instances; ovg: BOOL; [geometry, ovg] _ SpecialGetGeometry[old]; geometry _ CoreGeometry.TransformList[trans, geometry]; wire _ CoreOps.CreateWire[]; CoreGeometry.PutGeometry[mode.decoration, wire, geometry]; newInternals _ CONS [wire, newInternals]; }; AddInTable: PROC [subInternal: Wire] = { IF RefTab.Fetch[intToInt, subInternal].val#NIL THEN RETURN; [] _ RefTab.Store[intToInt, subInternal, CreateWire[subInternal]]; }; CreateActual: PROC [oldAct: Wire] RETURNS [newAct: Wire] = { newAct _ NARROW [RefTab.Fetch[intToInt, oldAct].val]; IF newAct#NIL THEN RETURN; IF oldAct.size=0 THEN [] _ RefTab.Store[intToInt, oldAct, newAct _ CreateWire[oldAct]] ELSE { newAct _ CoreOps.CreateWires[size: oldAct.size]; FOR i: NAT IN [0 .. oldAct.size) DO newAct[i] _ CreateActual[oldAct[i]] ENDLOOP; }; }; DecorateBinding: RefTab.EachPairAction = { pub: Wire = NARROW [key]; act: Wire = NARROW [val]; CoreGeometry.AddGeometry[ mode.decoration, act, CoreGeometry.TransformList[trans, SpecialGetGeometry[pub].geometry] ]; -- Hack to save some space for now! }; name: ROPE = CoreOps.GetCellTypeName[rct[i].type]; trans: CoreGeometry.Transformation = CoreGeometry.GetTrans[mode.decoration, rct[i]]; subrct: CoreClasses.RecordCellType = NARROW [rct[i].type.data]; intToInt: RefTab.Ref _ CoreOps.CreateBindingTable[rct[i].type.public, rct[i].actual]; [] _ RefTab.Pairs[intToInt, DecorateBinding]; IF NOT Rope.Equal[PW.Name[CoreGeometry.GetObject[mode.decoration, rct[i].type]], name] THEN ERROR; TerminalIO.PutF[" %g[%g]", IO.rope[name], IO.int[subrct.size]]; CoreOps.VisitRootAtomics[subrct.internal, AddInTable]; FOR j: NAT IN [0 .. subrct.size) DO instance: CoreClasses.CellInstance _ CoreClasses.CreateInstance[actual: CreateActual[subrct[j].actual], type: subrct[j].type, props: subrct[j].properties]; CoreGeometry.PutTrans[mode.decoration, instance, CDBasics.ComposeTransform[itemInCell: CoreGeometry.GetTrans[mode.decoration, subrct[j]], cellInWorld: trans]]; instances _ CONS [instance, instances] ENDLOOP; IF CoreProperties.GetCellTypeProp[rct[i].type, $RawFlatten]=$Smash THEN Sinix.FlushCache[CoreGeometry.GetObject[mode.decoration, rct[i].type]]; }; ENDLOOP; IF instances=NIL AND newInternals=NIL AND record.public.size=1 AND rct.internal.size=1 THEN {result _ record.public[0]; RETURN}; -- optimization good for Big contacts! new _ CoreClasses.CreateRecordCell[ record.public, CoreOps.UnionWire[rct.internal, CoreOps.CreateWire[newInternals]], instances, NIL, record.properties, TRUE ]; CoreGeometry.PutObject[mode.decoration, new, CoreGeometry.GetObject[mode.decoration, record]]; TerminalIO.PutF[".\n"]; result _ new; }; Same: PROC [nameOrClass: REF] = { class: CD.ObjectClass; WITH nameOrClass SELECT FROM c: CD.ObjectClass => class _ c; r: ATOM => class _ CD.FetchObjectClass[r, CMosB.cmosB]; ENDCASE => ERROR; CDProperties.PutProp[class, mode.extractProcProp, CDProperties.GetProp[class, standardMode.extractProcProp]]; }; Sinix.RegisterExtractProc[$RawExtractCell, RawExtractCell]; CDProperties.PutProp[CDCells.pCellClass, mode.extractProcProp, $RawExtractCell]; Same[PW.indirectClass]; Same[PW.rotationClass]; Same[CDRoutingObjects.routingClass]; Same[CDSymbolicObjects.pinClass]; Same[CDSymbolicObjects.segmentClass]; Same[CDSymbolicObjects.markClass]; Same[CDRects.bareRectClass]; Same[CDRects.wellRectClass]; Same[$C2SimpleCon]; Same[$C2WellSimpleCon]; Same[$C2LargeSimpleCon]; Same[$C2LargeWellSimpleCon]; Same[$C2DifShortCon]; Same[$C2DiffShortCon]; Same[$C2WellDifShortCon]; Same[$C2Via]; Same[$C2LargeVia]; Same[$C2Trans]; Same[$C2WellTrans]; Same[$C2LTrans]; Same[$C2LWellTrans]; Same[CDTexts.rigidTextClass]; Same[CDTexts.flipTextClass]; SinixOps.RegisterModeCommands[mode, CMosB.cmosB]; CoreGeometryBackdoor.RegisterDecorationIO[mode.decoration] END. ”SinixRawCMosBImpl.mesa Copyright Σ 1985, 1987 by Xerox Corporation. All rights reversed. Created by Bertrand Serlet October 30, 1986 12:49:32 pm PST Bertrand Serlet September 15, 1987 7:33:28 pm PDT Last Edited by: Louis Monier March 3, 1987 10:28:59 pm PST Types Mode Attention: we use the knowledge of what is the cache and what is the call Marking Cells used once Cell extraction same as CoreGeometry.GetGeometry, but only keeps 1 instances (+ all overglass rectangles!). The following code does not deal properly with DAGS. Who cares? -- We flush the Sinix cache for name. When we flush, we do not need to explicit the pins because there is no circularity Commented for testing If obj had already the $RawFlatten property, fine. If it did not have it and we have zero instance, let's make sure we'll flatten this cell. We do not flatten cell with only one instance, since wire decorations might kill us! IF CDProperties.GetObjectProp[obj, $RawFlatten]#$RawFlatten AND instances=NIL THEN CoreProperties.PutCellTypeProp[new, $RawFlatten, $Keep]; Initialization Registering extract procs Cells Pins Rectangles Contacts Transistors Angle Transistors Texts Κ Y˜codešœ™KšœB™BKšœ8Οk™;Kšœ1™1Kšœ7™:K™—š œ˜ Kšœn˜pKšœP˜PKšœœ;˜A—K˜•StartOfExpansion[]šΟnœœœ˜!KšœœΈœœ,˜τKšœ˜Kšœ0˜;—head™Jšœ œ˜Jšœœ ˜Jšœœ˜Jšœœœ˜Jšœ œ˜#Jšœœœ˜—™šœ@˜@K˜—Jšœ œœ˜šœœœ˜0Jšœœ$œ˜=Jšœ6˜6Jšœ!˜!Jšœ˜Jšœ$˜$Jšœ*˜*Jšœ"˜"Jšœ˜Jšœ˜Jšœ˜J˜J˜—J–‘ -- [obj: CD.Object, mode: Sinix.Mode, properties: PropertyLists.PropList _ NIL, userData: REF ANY _ NIL] RETURNS [result: REF ANY, props: Core.Properties _ NIL]šΟb œ@™Iš ž œœœ œœ œ˜^Jšœ œœœ˜,Jšœœœœ ˜"Jšœ˜Jšœ˜J˜—šž œœ œœœœœ œ˜—Jšœ]œ+˜‹Jšœ˜J˜—Jšžœœ œ œœœœœ˜L—™š žœœ œ œœ ˜CJšœ%ΟcŠ˜―šž œ ˜,šžœ˜$Jšœœ$˜.Kšœœœœ˜+Kš œ"œœœ œ˜HJ˜—Kšœœœœ˜&Kšœ˜Jšœ.˜.J˜—šž œ˜&Jšœ œœ˜Kšœ˜Jšœ4˜4J˜—Jšœ7˜7Jšœ&˜&J˜——™š ž œœœ œœ˜5Kšœ"œ˜AK˜K˜—Kšœ]™]š žœœœ%œœœ˜mšž œ#˜/šœœ˜Kšœ$œ œ˜PKšœ œœ ˜+Kš œœœ œ œ˜H—K˜—KšœI˜IK˜K˜—šžœ˜%Kšœœœ˜Kšœ ˜ Kšœ˜Kšœœ ,˜GKšœ œœœ ,˜_KšœE˜EKšœ œ ˜Kšœœ˜Kšœ œ<˜NKšœ:œ=˜}šœœœ˜ Kšœ:œœœ˜]Kšœ˜—Kšœœœœ˜$Kšœ+œœ ˜Bšœœœ˜ šœ:œ˜@Kšœ œ˜*šœ˜Kšœ/œ ™@šž œœ œ˜5Jšœ'œ˜,Jšœ*˜*Jšœ7˜7Jšœ˜Jšœ:˜:Jšœœ˜)J˜—šž œœ˜(Jšœ)œœœ˜;JšœB˜BJ˜—šž œœœ˜