DIRECTORY CD, CDCells, CDDirectory, CDProperties, CDRects, CDSymbolicObjects, CDTexts, CMosB, Core, CoreClasses, CoreGeometry, CoreOps, CoreProperties, HashTable, IO, PW, Rope, Sinix, SinixOps, SinixRawCMosB, TerminalIO; SinixRawCMosBImpl: CEDAR PROGRAM IMPORTS CD, CDCells, CDDirectory, CDProperties, CDRects, CDSymbolicObjects, CDTexts, CMosB, CoreGeometry, CoreClasses, CoreOps, CoreProperties, HashTable, IO, PW, Rope, Sinix, SinixOps, TerminalIO EXPORTS SinixRawCMosB SHARES CDCells, CDRects, CDSymbolicObjects, CDTexts, Sinix = 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: PW.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 = { pins: LIST OF CD.Instance _ NARROW [obj.specificRef, CD.CellPtr].contents; wire: Wire _ CoreOps.CreateWire[]; CoreGeometry.PutPins[mode.decoration, wire, pins]; 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 = { cp: CD.CellPtr; IF NOT CDCells.IsCell[ob] THEN RETURN; total _ total + 1; cp _ NARROW [ob.specificRef]; FOR il: CD.InstanceList _ cp.contents, il.rest WHILE il#NIL DO value: REF = HashTable.Fetch[usage, il.first.ob].value; IF NOT CDCells.IsCell[il.first.ob] THEN LOOP; [] _ HashTable.Store[usage, il.first.ob, IF value=NIL THEN $unique ELSE $many]; ENDLOOP; }; 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: LIST OF CD.Instance _ 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: LIST OF CD.Instance _ 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; 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 flattenSomeChild OR CoreProperties.GetCellTypeProp[record, $RawFlatten]#NIL THEN [] _ CoreOps.VisitWireSeq[record.public, ExplicitPins]; IF NOT flattenSomeChild THEN RETURN; TerminalIO.WriteF["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: LIST OF CD.Instance _ CoreGeometry.GetGeometry[mode.decoration, old]; IF geometry#NIL THEN geometry _ LIST [CoreGeometry.Transform[transf, 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: LIST OF CD.Instance _ CoreGeometry.GetGeometry[mode.decoration, pub]; IF geometry#NIL THEN CoreGeometry.PutGeometry[ mode.decoration, act, CONS [CoreGeometry.Transform[transf, geometry.first], CoreGeometry.GetGeometry[mode.decoration, act]] ]; -- Hack to save some space for now! }; name: ROPE = CoreOps.GetCellTypeName[rct[i].type]; transf: CD.Instance = CoreGeometry.GetTransf[mode.decoration, rct[i]]; subObj: CD.Object = transf.ob; 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[subObj], name] THEN ERROR; TerminalIO.WriteF[" %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.PutTransf[mode.decoration, instance, CoreGeometry.Transform[transf, CoreGeometry.GetTransf[mode.decoration, subrct[j]]]]; instances _ CONS [instance, instances] ENDLOOP; IF CoreProperties.GetCellTypeProp[rct[i].type, $RawFlatten]=$Smash THEN CDProperties.PutObjectProp[subObj, Sinix.cacheProp, NIL]; }; ENDLOOP; result _ CoreClasses.CreateRecordCell[record.public, CoreOps.UnionWire[rct.internal, CoreOps.CreateWire[newInternals]], instances, NIL, record.properties, TRUE]; IF CDProperties.GetObjectProp[obj, $RawFlatten]#$RawFlatten AND instances=NIL THEN CoreProperties.PutCellTypeProp[NARROW [result], $RawFlatten, $Keep]; TerminalIO.WriteF[".\n"]; }; Meme: PROC [className: ATOM] = {Same[CD.FetchObjectClass[className, CMosB.cmosB]]}; Same: PROC [class: CD.ObjectClass] = { CDProperties.PutProp[class, mode.extractProcProp, CDProperties.GetProp[class, standardMode.extractProcProp]]; }; Sinix.RegisterExtractProc[$RawExtractCell, RawExtractCell]; Sinix.RegisterExtractProc[$ExtractCellAsWire, ExtractCellAsWire]; CDProperties.PutProp[CDCells.cellClass, mode.extractProcProp, $RawExtractCell]; Same[CDSymbolicObjects.pinClass]; Same[CDSymbolicObjects.segmentClass]; Same[CDSymbolicObjects.markClass]; Same[CDRects.bareRectClass]; Meme[$C2SimpleCon]; Meme[$C2WellSimpleCon]; Meme[$C2LargeSimpleCon]; Meme[$C2LargeWellSimpleCon]; Meme[$C2DifShortCon]; Meme[$C2WellDifShortCon]; Meme[$C2Via]; Meme[$C2LargeVia]; Meme[$C2PDifRect]; Meme[$C2NDifRect]; Meme[$C2Trans]; Meme[$C2WellTrans]; Meme[$C2LTrans]; Meme[$C2LWellTrans]; Same[CDTexts.textClass]; SinixOps.RegisterExtractCommand[CMosB.cmosB, mode, "Raw Extraction", $RawCMosBExtract]; SinixOps.RegisterHighlightCommand[CMosB.cmosB, mode, "Raw Highlight", $RawCMosBHighlight]; END. ¨SinixRawCMosBImpl.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 4, 1986 4:14:56 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 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 Κ W˜codešœ™Kšœ Οmœ1™™>šŸœžœ žœžœžœžœžœ žœ˜˜Jšœ žœžœžœ˜,Jšœžœžœžœ ˜"JšœXžœ˜nJšœ˜J˜—JšŸœžœ žœ žœžœžœžœžœ˜L—™šŸœ˜(Jš œžœžœžœ žœžœ˜JJ˜"Jšœ2˜2J˜J˜——™š Ÿœžœ žœ žœžœ ˜CJšœ-ΟcŠ˜·šŸ œ!˜-Kšœžœ ˜Kšžœžœžœžœ˜&Kšœ˜Kšœžœ˜š žœžœ%žœžœž˜>Jšœžœ-˜7Kšžœžœžœžœ˜-Kš œ)žœžœžœ žœ˜OKšžœ˜—J˜—šŸ œ˜)Jšžœ žœžœ˜Kšœ˜Jšœ4˜4J˜—Jšœ1˜1Jšœ)˜)J˜——™š Ÿœžœ3žœžœžœžœ˜šŸ œžœ˜)šŸœžœ$˜;J˜Jšœ žœžœžœH˜^Jšžœžœ7žœžœ˜IJšœ žœ/˜BJš žœ žœžœžœžœ˜6Jšœ6˜6Jšœ˜—JšŸ œI˜UJšœžœžœžœA˜ZJšœ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šžœžœ5žœžœ8˜‹Kšžœžœžœžœ˜$Kšœ-žœ˜MJšœX™XKšœ7˜7šžœžœžœž˜ šžœ:žœ˜@Kšžœ žœ˜*šžœ˜Kšœ/žœ ™@šŸ œžœ žœ˜5Jšœ žœžœžœ;˜OJš žœ žœžœ žœ3 #˜zJšœ˜Jšœ:˜:Jšœžœ˜)J˜—šŸ œžœ˜(Jšžœ.žœžœžœ˜@JšœE˜EJ˜—šŸ œžœžœ˜