DIRECTORY CD, CDBasics, CDCells, CDDirectory, CDProperties, CDRects, CDSymbolicObjects, CDTexts, CMosB, Core, CoreClasses, CoreGeometry, CoreOps, CoreProperties, HashTable, IO, PWObjects, Rope, Sinix, SinixOps, SinixRawCMosB, TerminalIO; SinixRawCMosBImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDCells, CDDirectory, CDProperties, CDRects, CDSymbolicObjects, CDTexts, CMosB, CoreGeometry, CoreClasses, CoreOps, CoreProperties, HashTable, IO, PWObjects, 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]; mode: PUBLIC Sinix.Mode _ NEW [Sinix.ModeRec _ [ extractProcProp: PWObjects.RegisterProp[$RawCMosBExtractProc, TRUE], decoration: CoreGeometry.CreateDecoration["RawCMosB"], nbOfLayers: standardMode.nbOfLayers, instanceLayer: standardMode.instanceLayer, touchProc: CoreGeometry.Touch, fusionByName: none, equalProc: SmallerOverlap, userData: UserData ]]; SmallerOverlap: PROC [obj: Object, cacheProperties: CD.PropList, cacheUserData: REF, properties: CD.PropList, userData: REF] RETURNS [cacheOK: BOOL] = { cacheData: REF INT = NARROW [cacheUserData]; data: REF INT = NARROW [userData]; cacheOK _ Sinix.CompareProps[obj, cacheProperties, cacheUserData, properties, userData] AND cacheData^>=data^; }; UserData: PROC [design: CD.Design] RETURNS [REF] = {RETURN [NEW [INT _ 0]]}; ExtractCellAsWire: Sinix.ExtractProc = { EachInst: CDCells.InstEnumerator = {pins _ CONS [[inst.ob, inst.trans], pins]}; pins: CoreGeometry.Instances _ NIL; wire: Wire _ CoreOps.CreateWire[]; CoreGeometry.PutPins[mode.decoration, wire, pins]; [] _ CDCells.EnumerateInstances[obj, EachInst]; result _ wire; }; Mark: PROC [design: CD.Design] RETURNS [total, marked: INT _ 0] = { usage: HashTable.Table = HashTable.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.EachEntryAction = { EachInst: CDCells.InstEnumerator = { value: REF = HashTable.Fetch[usage, inst.ob].value; IF NOT CDCells.IsCell[inst.ob] THEN RETURN; [] _ HashTable.Store[usage, inst.ob, IF value=NIL THEN $unique ELSE $many]; }; IF NOT CDCells.IsCell[ob] THEN RETURN; total _ total + 1; [] _ CDCells.EnumerateInstances[ob, EachInst]; }; MarkUniques: HashTable.EachPairAction = { IF value=$many THEN RETURN; marked _ marked + 1; CDProperties.PutProp[key, $RawFlatten, $RawFlatten]; }; [] _ CDDirectory.Enumerate[design, CountEachUse]; [] _ HashTable.Pairs[usage, MarkUniques]; }; MatchSourceToExtracted: PROC [sourcePublic: Wire, extractedCT: CellType, name: ROPE _ NIL, props: Properties _ NIL] RETURNS [new: CellType] = { FillTable: PROC [extractedWire: Wire] = { FillTableInternal: PROC [sourcePublic, newPublic: Wire] = { prevSource: Wire; sourcePins: CoreGeometry.Instances _ CoreGeometry.GetPins[standardMode.decoration, sourcePublic]; IF NOT CoreGeometry.TouchListList[sourcePins, extractedPins] THEN RETURN; prevSource _ NARROW [HashTable.Fetch[table, extractedWire].value]; IF prevSource#NIL AND prevSource#newPublic THEN ERROR; [] _ HashTable.Store[table, extractedWire, newPublic]; }; EachWirePair: CoreOps.EachWirePairProc = {FillTableInternal[actualWire, publicWire]}; extractedPins: CoreGeometry.Instances _ CoreGeometry.GetPins[mode.decoration, extractedWire]; [] _ CoreOps.VisitBindingSeq[sourcePublic, public, EachWirePair]; }; public: Wire _ CoreOps.CopyWire[sourcePublic]; table: HashTable.Table _ HashTable.Create[]; CoreOps.VisitRootAtomics[extractedCT.public, FillTable]; new _ CoreClasses.CreatePermutedRecordCell[iconPublic: public, schCell: extractedCT, table: table, name: name, props: props]; }; ExplicitPins: CoreOps.EachWireProc = { CoreGeometry.PutPins[mode.decoration, wire, CoreGeometry.GetPins[mode.decoration, wire]]; }; 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; [] _ CoreOps.VisitWireSeq[record.public, ExplicitPins]; -- we want to avoid the TransWireIR lazyness which is using the InterestRect IF NOT flattenSomeChild THEN RETURN; TerminalIO.PutF["In cell %g, flattening:", IO.rope[CDDirectory.Name[obj]]]; [] _ CoreOps.VisitWireSeq[record.public, ExplicitPins]; 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 _ CoreGeometry.GetGeometry[mode.decoration, old]; IF geometry#NIL THEN geometry _ LIST [CoreGeometry.Transform[trans, geometry.first]]; -- Hack to save some space for now! wire _ CoreOps.CreateWire[]; CoreGeometry.PutGeometry[mode.decoration, wire, geometry]; newInternals _ CONS [wire, newInternals]; }; AddInTable: PROC [subInternal: Wire] = { IF HashTable.Fetch[intToInt, subInternal].value#NIL THEN RETURN; [] _ HashTable.Store[intToInt, subInternal, CreateWire[subInternal]]; }; CreateActual: PROC [oldAct: Wire] RETURNS [newAct: Wire] = { newAct _ NARROW [HashTable.Fetch[intToInt, oldAct].value]; IF newAct#NIL THEN RETURN; IF oldAct.size=0 THEN [] _ HashTable.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: HashTable.EachPairAction = { pub: Wire = NARROW [key]; act: Wire = NARROW [value]; geometry: CoreGeometry.Instances _ CoreGeometry.GetGeometry[mode.decoration, pub]; IF geometry#NIL THEN CoreGeometry.AddGeometry[ mode.decoration, act, LIST [CoreGeometry.Transform[trans, geometry.first]] ]; -- 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: HashTable.Table _ CoreOps.CreateBindingTable[rct[i].type.public, rct[i].actual]; [] _ HashTable.Pairs[intToInt, DecorateBinding]; IF NOT Rope.Equal[CDDirectory.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; 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]]; IF CDProperties.GetObjectProp[obj, $RawFlatten]#$RawFlatten AND instances=NIL THEN CoreProperties.PutCellTypeProp[new, $RawFlatten, $Keep]; 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]; Sinix.RegisterExtractProc[$ExtractCellAsWire, ExtractCellAsWire]; CDProperties.PutProp[CDCells.pCellClass, mode.extractProcProp, $RawExtractCell]; Same[CDSymbolicObjects.pinClass]; Same[CDSymbolicObjects.segmentClass]; Same[CDSymbolicObjects.markClass]; Same[CDRects.bareRectClass]; Same[$C2SimpleCon]; Same[$C2WellSimpleCon]; Same[$C2LargeSimpleCon]; Same[$C2LargeWellSimpleCon]; Same[$C2DifShortCon]; Same[$C2WellDifShortCon]; Same[$C2Via]; Same[$C2LargeVia]; Same[$C2PDifRect]; Same[$C2NDifRect]; Same[$C2Trans]; Same[$C2WellTrans]; Same[$C2LTrans]; Same[$C2LWellTrans]; Same[CDTexts.rigidTextClass]; Same[CDTexts.flipTextClass]; SinixOps.RegisterModeCommands[mode, CMosB.cmosB]; END. 6SinixRawCMosBImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reversed. Created by Bertrand Serlet October 30, 1986 12:49:32 pm PST Bertrand Serlet December 19, 1986 4:17:28 pm PST Types Mode we use the knowledge of what is the cache and what is the call Extracting PadBlank Marking Cells used once Computing corresponding cells Cell extraction IF flattenSomeChild OR CoreProperties.GetCellTypeProp[record, $RawFlatten]#NIL THEN [] _ CoreOps.VisitWireSeq[record.public, ExplicitPins]; we explicit the pins to avoid circularity (and to gain some speed up in the shared case) The following code does not deal properly with DAGS. Who cares? -- We flush the Sinix cache for name Initialization Registering extract procs Cells Pins Rectangles Contacts Diffusion wires Transistors Angle Transistors Texts Κ ˜codešœ™Kšœ Οmœ1™˜…—K˜•StartOfExpansion[]šΟnœžœžœ˜!Kšžœžœ›žœ/˜ΦKšžœ˜Kšžœ0ž˜;—head™Jšœ žœ˜Jšœžœ ˜Jšœžœ˜Jšœžœžœ˜Jšœ žœ˜#Jšžœžœžœ˜—™šœ@˜@K˜—šœžœžœ˜0Jšœ>žœ˜DJšœ6˜6Jšœ$˜$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]šœ>™>šŸœžœ žœžœžœžœžœ žœ˜˜Jšœ žœžœžœ˜,Jšœžœžœžœ ˜"JšœXžœ˜nJšœ˜J˜—JšŸœžœ žœ žœžœžœžœžœ˜L—™šŸœ˜(JšŸœ#žœ ˜OJšœžœ˜#J˜"Jšœ2˜2Jšœ/˜/J˜J˜——™š Ÿœžœ žœ žœžœ ˜CJšœ-ΟcŠ˜·šŸ œ!˜-šŸœ˜$Jšœžœ)˜3Kšžœžœžœžœ˜+Kš œ%žœžœžœ žœ˜KJ˜—Kšžœžœžœžœ˜&Kšœ˜Jšœ.˜.J˜—šŸ œ˜)Jšžœ žœžœ˜Kšœ˜Jšœ4˜4J˜—Jšœ1˜1Jšœ)˜)J˜——™š Ÿœžœ3žœžœžœžœ˜šŸ œžœ˜)šŸœžœ$˜;J˜Jšœa˜aJšžœžœ7žœžœ˜IJšœ žœ/˜BJš žœ žœžœžœžœ˜6Jšœ6˜6Jšœ˜—JšŸ œI˜UJšœ]˜]JšœA˜AJ˜—Jšœ.˜.Jšœ,˜,Jšœ8˜8Jšœ}˜}J˜——™šŸ œ˜&K˜YK˜K˜—šŸœ˜%Kšœžœžœ˜Kšœ ˜ Kšœ˜Kšœžœ ,˜GKšœ žœžœžœ ,˜_KšœE˜EKšœ žœ ˜Kšœžœ˜Kšžœ žœ<˜NKšžœ:žœ=˜}šžœžœžœž˜ Kšžœ:žœžœžœ˜]Kšžœ˜—KšΠbkΟb‘’5‘’‘’8™‹Kšœ8 L˜„Kšžœžœžœžœ˜$Kšœ+žœ˜KJšœX™XKšœ7˜7šžœžœžœž˜ šžœ:žœ˜@Kšžœ žœ˜*šžœ˜Kšœ/žœ ™@šŸ œžœ žœ˜5JšœR˜RJš žœ žœžœ žœ2 #˜yJšœ˜Jšœ:˜:Jšœžœ˜)J˜—šŸ œžœ˜(Jšžœ.žœžœžœ˜@JšœE˜EJ˜—šŸ œžœžœ˜