<> <> <> <> <<>> 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; <<-- We flush the Sinix cache for name>> 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.