<> <> <> <> DIRECTORY CD, CDBasics, CDDirectory, CDInstances, CDIO, CDOps, CDProperties, CDRects, CDValue, CDViewer, Convert, Core, CoreIO, CoreOps, CoreGeometry, CoreProperties, HashTable, IO, PWCLayoutCheckpoint, PW, PWC, Rope; PWCLayoutCheckpointImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDDirectory, CDInstances, CDIO, CDOps, CDProperties, CDRects, CDValue, CDViewer, Convert, CoreIO, CoreOps, CoreGeometry, CoreProperties, HashTable, IO, PW, PWC, Rope EXPORTS PWCLayoutCheckpoint SHARES CDRects = BEGIN CellType: TYPE = Core.CellType; ROPE: TYPE = Core.ROPE; Wire: TYPE = Core.Wire; <<>> <> Store: PUBLIC PROC [cellType: CellType] = { props: LIST OF ATOM; classes: LIST OF Core.CellClass; name: ROPE _ CoreOps.GetCellTypeName[cellType]; PW.WriteF["Saving the Core for cell %g ...\n", IO.rope[name]]; [props, classes] _ CoreIO.ReportSaveCellType[cellType]; PW.WriteF["... core stored in %g.core\n", IO.rope[name]]; Checkpoint[cellType]}; <<>> Retrieve: PUBLIC PROC [name: ROPE] RETURNS [cellType: CellType] = { PW.WriteF["Retrieving the Core for cell %g\n", IO.rope[name]]; cellType _ CoreIO.RestoreCellType[name]; PW.WriteF["Core retrieved from %g.core\n", IO.rope[name]]; SetFromCheckpoint[cellType]}; <<>> <> Checkpoint: PUBLIC PROC [cellType: CellType, withCuteFonts: BOOL _ FALSE] = { sourceObj: CD.Object _ PWC.Layout[cellType]; ir: CD.Rect _ PWC.InterestRect[cellType]; name: ROPE _ CoreOps.GetCellTypeName[cellType]; layoutFileName: ROPE _ IO.PutFR["%gLayout", IO.rope[name]]; shellFileName: ROPE _ IO.PutFR["%gShell", IO.rope[name]]; layoutDesign: CD.Design _ CDOps.CreateDesign[CD.FetchTechnology[$cmosB]]; shellDesign: CD.Design _ CDOps.CreateDesign[CD.FetchTechnology[$cmosB]]; layout: CD.Object _ PW.CreateEmptyCell[]; shell: CD.Object; tCount: INT _ PWC.CountTransistors[cellType]; PW.WriteF["Making shell for cell %g\n", IO.rope[name]]; shell _ PWC.CellShell[cellType]; [] _ PW.IncludeInCell[layout, sourceObj]; PW.SetInterestRect[layout, CD.InterestSize[sourceObj]]; PW.RepositionCell[layout]; layoutDesign.name _ layoutFileName; shellDesign.name _ shellFileName; [] _ CDDirectory.Include[layoutDesign, layout, name]; [] _ CDDirectory.Include[shellDesign, shell, name]; CDOps.IncludeObjectI[layoutDesign, sourceObj]; CDOps.IncludeObjectI[shellDesign, shell]; CDValue.Store[layoutDesign, $KeepObjects, $KeepObjects]; -- to avoid finalization!!! CDValue.Store[shellDesign, $KeepObjects, $KeepObjects]; -- to avoid finalization!!! <> CDProperties.PutDesignProp[shellDesign, PWC.transistorCount, NEW [INT _ tCount]]; CDProperties.PutDesignProp[shellDesign, $IRX1, NEW [INT _ ir.x1]]; CDProperties.PutDesignProp[shellDesign, $IRX2, NEW [INT _ ir.x2]]; CDProperties.PutDesignProp[shellDesign, $IRY1, NEW [INT _ ir.y1]]; CDProperties.PutDesignProp[shellDesign, $IRY2, NEW [INT _ ir.y2]]; PW.WriteF["Writing layout for cell %g\n", IO.rope[name]]; [] _ CDIO.WriteDesign[layoutDesign, layoutFileName]; PW.WriteF["Writing shell for cell %g\n", IO.rope[name]]; [] _ CDIO.WriteDesign[shellDesign, shellFileName]; PW.WriteF["Layout checkpoint stored in %g.dale and %g.dale\n", IO.rope[layoutFileName], IO.rope[shellFileName]]}; <<>> SetFromCheckpoint: PROC [cellType: CellType] = { <> RetrieveDecorate[cellType, NIL]; PWC.SetLayout[cellType, $RetrieveLayout]}; designs: HashTable.Table _ HashTable.Create[equal: HashTable.RopeEqual, hash: HashTable.HashRope]; OpenDesign: PROC[name: ROPE] RETURNS[design: CD.Design] = { design _ NARROW[HashTable.Fetch[designs, name].value]; IF design#NIL THEN RETURN[design]; design _ CDViewer.FindDesign[name]; [] _ HashTable.Store[designs, name, design]; IF design#NIL THEN RETURN[design]; design _ PW.OpenDesign[name]; [] _ HashTable.Store[designs, name, design]}; RetrieveLayout: PWC.LayoutProc = { fileName: ROPE _ NARROW [cellType.data]; name: ROPE _ Rope.Substr[fileName, 0 , Rope.Length[fileName]-5]; -- strip ".core" layoutFileName: ROPE _ IO.PutFR["%gLayout", IO.rope[name]]; layoutDesign: CD.Design _ OpenDesign[layoutFileName]; obj _ PW.Get[layoutDesign, name]; IF CD.InterestRect[obj]#PWC.InterestRect[cellType] THEN ERROR}; RetrieveDecorate: PWC.DecorateProc = { fileName: ROPE _ NARROW [cellType.data]; name: ROPE _ Rope.Substr[fileName, 0 , Rope.Length[fileName]-5]; -- strip ".core" shellFileName: ROPE _ IO.PutFR["%gShell", IO.rope[name]]; shellDesign: CD.Design _ OpenDesign[shellFileName]; tCountRef: REF INT _ NARROW [CDProperties.GetDesignProp[shellDesign, PWC.transistorCount]]; ir: CD.Rect _ [ x1: NARROW [CDProperties.GetDesignProp[shellDesign, $IRX1], REF INT]^, x2: NARROW [CDProperties.GetDesignProp[shellDesign, $IRX2], REF INT]^, y1: NARROW [CDProperties.GetDesignProp[shellDesign, $IRY1], REF INT]^, y2: NARROW [CDProperties.GetDesignProp[shellDesign, $IRY2], REF INT]^ ]; shell: CD.Object _ PW.Get [shellDesign, name]; cellPtr: CD.CellPtr _ NARROW [shell.specificRef]; offset: CD.Position _ CDBasics.SubPoints [CDBasics.BaseOfRect[ir], CDBasics.BaseOfRect[CD.InterestRect[shell]]]; IF CD.InterestSize[shell]#CDBasics.SizeOfRect[ir] THEN ERROR; CoreProperties.PutCellTypeProp[cellType, $PWCShell, shell]; CoreGeometry.PutIR[PWC.extractMode.decoration, cellType, ir]; IF tCountRef#NIL THEN CoreProperties.PutCellTypeProp [cellType, PWC.transistorCount, NEW [INT _ tCountRef^]]; FOR list: LIST OF CD.Instance _ cellPtr.contents, list.rest WHILE list#NIL DO wireName: ROPE; wire: Wire; instance: CD.Instance; IF list.first.ob.class # CDRects.bareRectClass THEN LOOP; instance _ NEW [CD.InstanceRep _ list.first^]; instance.properties _ NIL; wireName _ NARROW [CDProperties.GetInstanceProp[list.first, $InstanceName]]; wire _ FindWire[cellType.public, wireName]; IF wireName=NIL OR wire=NIL THEN ERROR; CDInstances.Translate[instance, offset]; AddUniquePinsProp[PWC.extractMode.decoration, wire, instance]; ENDLOOP}; FindWire: PROC[wire: Wire, name: ROPE] RETURNS[Wire] = { base: ROPE; names: LIST OF ROPE; IF (wire _ CoreOps.FindWire[wire, name]) # NIL THEN RETURN[wire]; [base, names] _ CoreOps.ParseWireName[name]; names _ CONS[base, names]; FOR names _ names, names.rest WHILE names # NIL DO SELECT names.first.Fetch[] FROM IN ['0..'9] => wire _ wire[Convert.IntFromRope[names.first]]; ENDCASE => { FOR i: NAT IN [0..wire.size) DO IF ~Rope.Equal[names.first, CoreOps.GetShortWireName[wire[i]]] THEN LOOP; wire _ wire[i]; EXIT; REPEAT FINISHED => ERROR ENDLOOP}; ENDLOOP; RETURN[wire]}; AddUniquePinsProp: PROC [decoration: CoreGeometry.Decoration, wire: Wire, pin: CD.Instance] = { FOR pins: LIST OF CD.Instance _ CoreGeometry.GetPins[decoration, wire], pins.rest WHILE pins#NIL DO IF pins.first^=pin^ THEN RETURN ENDLOOP; CoreGeometry.PutPins[decoration, wire, CONS[pin, CoreGeometry.GetPins[decoration, wire]]]}; <<>> <> [] _ PWC.RegisterLayoutAtom[$RetrieveLayout, RetrieveLayout, RetrieveDecorate]; END.