<> <> DIRECTORY AbSets, Atom, BasicTime, BiRels, CedarProcess, CoreFiddling, FS, FunsimToCore, IO, IOClasses, Lichen, LichenDataOps, LichenDataStructure, LichenFiling, LichenFlatPrivate, LichenFromCore, LichenFromExt, LichenPrinting, Rope, SafeStorage, SetBasics, ViewerIO, ViewerTools; LichenKeyImpl: CEDAR PROGRAM IMPORTS AbSets, Atom, BasicTime, BiRels, CedarProcess, CoreFiddling, FS, FunsimToCore, IO, IOClasses, LichenDataOps, LichenDataStructure, LichenFiling, LichenFlatPrivate, LichenFromCore, LichenFromExt, LichenPrinting, Rope, SafeStorage, SetBasics, ViewerIO, ViewerTools EXPORTS Lichen = BEGIN OPEN Sets:AbSets, Lichen, LichenDataStructure, LDO:LichenDataOps; Do: PUBLIC PROC [prefix, suffix: ROPE, Key: KeyProc, from, to: INT] ~ { dName: ROPE ~ prefix.Concat[suffix]; logScript: IO.STREAM ~ ViewerIO.CreateViewerStreams[dName].out; logFile, log: IO.STREAM _ NIL; d: Design _ NIL; at: INT _ INT.FIRST; doing: BOOL _ FALSE; allocd: INT _ SafeStorage.NWordsAllocated[]; recld: INT _ SafeStorage.NWordsReclaimed[]; phaseSecs, totSecs: INT _ 0; At: PROC [i: INT] ~ { toDo: BOOL ~ i IN [from .. to); CheckStep: PROC ~ {LDO.CheckDesign[d]}; PrettyPrintStep: PROC ~ { rootName: ROPE ~ IO.PutFR["%g/%g.d%d", [rope[dName]], [rope[Describe[d, d.root, d]]], [integer[i]]]; LichenPrinting.PrintDesignOnFiles[d: d, fnPrefix: dName, fnSuffix: IO.PutFR["d%d", [integer[i]]], pacify: log]; {full: ROPE ~ FS.FileInfo[rootName].fullFName; [] _ ViewerTools.MakeNewTextViewer[[name: full, file: full]]; RETURN}}; WriteStep: PROC ~ { binName: ROPE ~ IO.PutFR["%g.des%d", [rope[dName]], [integer[i]]]; fullBin: ROPE; binBytes: INT; binCreated: BasicTime.GMT; [] _ LichenFiling.WriteDesign[binName, d, log]; [fullBin,,,binBytes,binCreated,] _ FS.FileInfo[binName]; log.PutF["%g %g %g\n", [rope[fullBin]], [integer[binBytes]], [time[binCreated]]]; }; at _ i; IF doing THEN { DoStep[IO.PutFR["Check at point %g", [integer[i]]], CheckStep]; IF i>0 THEN DoStep[IO.PutFR["PrettyPrint at point %g", [integer[i]]], PrettyPrintStep]; DoStep[IO.PutFR["Write at point %g", [integer[i]]], WriteStep]; totSecs _ totSecs + phaseSecs; log.PutF["Phase %d took %d seconds; total is now %d\n", [integer[i]], [integer[phaseSecs]], [integer[totSecs]]]; phaseSecs _ 0; logFile.Close[]; logScript.PutRope["\n"]; }; IF toDo THEN { logFile _ FS.StreamOpen[fileName: IO.PutFR["log-%g-%d.txt", [rope[dName]], [integer[i+1]]], accessOptions: create, keep: 10]; log _ IOClasses.CreateDribbleOutputStream[logFile, logScript]; }; IF doing = toDo THEN RETURN; doing _ toDo; IF NOT doing THEN RETURN; IF i >= 0 THEN { file: ROPE ~ IO.PutFR["%g.des%d", [rope[dName]], [integer[i]]]; ReadStep: PROC ~ { d _ LichenFiling.ReadDesign[file, log]; Atom.PutProp[$d, $d, d]}; DoStep[Rope.Cat["Read ", file], ReadStep]; DoStep["Check after read", CheckStep]; }; RETURN}; DoStep: PROC [descr: ROPE, Step: PROC] ~ {IF doing THEN { log.PutF["\n%g starting at %g\n", [rope[descr]], [time[BasicTime.Now[]]]]; log.Flush[]; SafeStorage.ReclaimCollectibleObjects[]; {am: INT ~ SafeStorage.NWordsAllocated[]; rm: INT ~ SafeStorage.NWordsReclaimed[]; tm: BasicTime.GMT ~ BasicTime.Now[]; Step[]; SafeStorage.ReclaimCollectibleObjects[]; {af: INT ~ SafeStorage.NWordsAllocated[]; rf: INT ~ SafeStorage.NWordsReclaimed[]; tf: BasicTime.GMT ~ BasicTime.Now[]; secs: INT ~ BasicTime.Period[tm, tf]; log.PutFL["%g %gs (%g+%g=%g) - (%g+%g=%g) = %g+%g = %g\n", LIST[ [rope[descr]], [integer[secs]], [integer[am-allocd]], [integer[af-am]], [integer[af-allocd]], [integer[rm-recld]], [integer[rf-rm]], [integer[rf-recld]], [integer[am-allocd-(rm-recld)]], [integer[af-am-(rf-rm)]], [integer[af-allocd-(rf-recld)]] ]]; allocd _ af; recld _ rf; phaseSecs _ phaseSecs + secs}}}; RETURN}; ReadExt: PROC [rootCellFileName, renamingFileName: ROPE, labelCellTypes: REF ANY] ~ { ReadExtStep: PROC ~ { d _ LichenFromExt.ReadDesign[rootCellFileName, renamingFileName]; Atom.PutProp[$d, $d, d]; {labCells: Set--of CellType-- ~ ToTSet[labelCellTypes]; [] _ d.labelCellTypes.AddSet[labCells]; LDO.CheckDesign[d]; RETURN}}; DoStep["ReadExt", ReadExtStep]}; ReadFunsim: PROC [rootName: ROPE] ~ { ReadFunsimStep: PROC ~ { rt: FunsimToCore.Table; cs: FunsimToCore.Counts; CoreFiddling.log _ log; [rt, cs] _ FunsimToCore.Convert[rootName.Concat["-Funsim.str"]]; CoreFiddling.SortPublics[rt]; CoreFiddling.PrintCellTypeGraph[log, FunsimToCore.callOrder]; CoreFiddling.PrintCellInstanceGraph[log, FunsimToCore.callOrder]; CoreFiddling.PrintCellTypes[log, FunsimToCore.callOrder]; d _ LichenFromCore.GetDesign[rt, rootName, "-f", log]; Atom.PutProp[$d, $d, d]; LDO.CheckDesign[d]; RETURN}; DoStep["ReadFunsim", ReadFunsimStep]}; RipoutDebugging: PROC ~ { RipoutDebuggingStep: PROC ~ { xstrs: Set ~ d.ciType.Image[d.transistorCellTypes, rightToLeft]; goners: Set ~ d.root.Subcells[].Intersection[xstrs].CreateHashCopy[]; [] _ LDO.DeleteInsts[d, goners, TRUE]}; DoStep["RipoutDebugging", RipoutDebuggingStep]}; ExternallyMerged: PROC [portsA: REF ANY] ~ { ExternallyMergedStep: PROC ~ { ports: Set ~ TopPSet[d.root, portsA].CreateHashCopy[]; wires: Set ~ d.root.asu.exports.Image[ports].CreateHashCopy[]; IF NOT ports.Size[] = wires.Size[] THEN ERROR; [] _ LDO.MergeWireSet[d, wires, TRUE]; [] _ LDO.MergePorts[d.root, ports]}; DoStep["ExternallyMerged", ExternallyMergedStep]}; UndistinguishPorts: PROC ~ { UndistinguishPortsStep: PROC ~ {[] _ LDO.UndistinguishPorts[d, log]}; DoStep["UndistinguishPorts", UndistinguishPortsStep]}; ImportAtomicWireOnceToRoot: PROC [name: ROPE] RETURNS [internal: Wire _ NIL] ~ { ImportAtomicWireOnceToRootStep: PROC ~ { names: Set ~ OneSteppy[ParseSteppyName[name]]; internal _ LDO.CreateWire[d.root, names, FALSE, FALSE, FALSE, nilBiRel]; [] _ LDO.FullySfwdlyExportWires[d.root, Sets.CreateSingleA[internal, d.eSpace]]}; DoStep["ImportAtomicWireOnceToRoot", ImportAtomicWireOnceToRootStep]}; ImportAtomicWireOnce: PROC [ctA, fromA: REF ANY] RETURNS [internal: Wire _ NIL] ~ { ImportAtomicWireOnceStep: PROC ~ { ct: CellType ~ ToT[ctA]; from: Wire ~ ToW[fromA]; internal _ LDO.ImportAtomicWireOnce[d, ct, from].internal}; DoStep["ImportAtomicWireOnce", ImportAtomicWireOnceStep]}; DeduceWireStructure: PROC ~ { DeduceWireStructureStep: PROC ~ {LDO.AddDeducedStructureToDesign[d, log]}; DoStep["DeduceWireStructure", DeduceWireStructureStep]}; CleanupDesign: PROC ~ { CleanupDesignStep: PROC ~ {[] _ LDO.CleanDesign[d, log]}; DoStep["CleanupDesign", CleanupDesignStep]}; Group: PROC [iName, tName: ROPE, parentA, sibsA: REF ANY] ~ { GroupStep: PROC ~ { [] _ LichenFlatPrivate.GroupInstancesToNewCT[d, TopISet[parentA, sibsA], iName, tName]; RETURN}; DoStep["Group", GroupStep]}; ExpandInstance: PROC [instA: REF ANY] ~ { ExpandInstanceStep: PROC ~ { [] _ LDO.ExpandInstance[d, ToI[instA]]; }; DoStep["ExpandInstance", ExpandInstanceStep]}; ExpandType: PROC [tName: ROPE] ~ { ExpandTypeStep: PROC ~ { [] _ LDO.ExpandType[d, ToT[tName]]; }; DoStep["ExpandType", ExpandTypeStep]}; FlattenArrays: PROC ~ { FlattenArraysStep: PROC ~ { arrays: Set ~ d.arrayElt.SetOn[left].CreateHashCopy[]; dblArrays: Set ~ d.arrayElt.Image[arrays, rightToLeft].CreateHashCopy[]; oks: Set--of CellType--; errs: Fn--CellType [oks, errs] _ LDO.FlattenArrays[d, dblArrays, TRUE, log]; log.PutRope["OK: "]; oks.PrintSet[log]; log.PutRope[", errs: "]; errs.PrintBiRel[log]; log.PutRope["\n"]}; DoStep["FlattenArrays", FlattenArraysStep]}; RaiseGCs: PROC [childA, gcsA: REF ANY] RETURNS [sibs: RefSet--of raised instances-- _ NIL] ~ { RaiseGCsStep: PROC ~ { gcs: Set ~ TopISet[childA, gcsA]; sibs _ LichenFlatPrivate.RaiseGCs[d, gcs].Refify}; DoStep["RaiseGCs", RaiseGCsStep]}; ShortenArrayInstance: PROC [inst: REF ANY, end: ArrayEnd, sDim: Dim3 _ Z, by: NAT _ 1] ~ { ShortenArrayInstanceStep: PROC ~ { LDO.ShortenArrayInstance[d, ToI[inst], end, sDim, by]; }; DoStep["ShortenArrayInstance", ShortenArrayInstanceStep]}; LowerArrayStructure: PROC [outerA: REF ANY] ~ { LowerArrayStructureStep: PROC ~ {LDO.LowerArrayStructure[ToT[outerA]]}; DoStep["LowerArrayStructure", LowerArrayStructureStep]}; SimilarizeArrays: PROC ~ { SimilarizeArraysStep: PROC ~ {[] _ LDO.SimilarizeArrays[d, d.cellTypes]}; DoStep["SimilarizeArrays", SimilarizeArraysStep]}; PrefixifyDesign: PROC ~ { PrefixifyDesignStep: PROC ~ {LDO.PrefixifyDesign[d]}; DoStep["PrefixifyDesign", PrefixifyDesignStep]}; InheritNames: PROC [renamesFileName: ROPE] ~ { InheritNamesStep: PROC ~ {LDO.InheritNames[d, TRUE, FALSE, LDO.ReadRenames[d, renamesFileName]]}; DoStep["InheritNames", InheritNamesStep]}; CleanupNames: PROC ~ { CleanupNamesStep: PROC ~ {LDO.CleanupDesignNames[d]}; DoStep["CleanupNames", CleanupNamesStep]}; DropPhysical: PROC ~ { DropPhysicalStep: PROC ~ {LDO.DropPhysical[d]}; DoStep["DropPhysical", DropPhysicalStep]}; DeduceArrayness: PROC [ctsA: REF ANY] ~ { DeduceArraynessStep: PROC ~ {[] _ LDO.DeduceArrayness[d, ToTSet[ctsA], log]}; DoStep["DeduceArrayness", DeduceArraynessStep]}; MinimizeArrayPeriods: PROC ~ { MinimizeArrayPeriodsStep: PROC ~ { arrays: Set ~ d.arrayElt.SetOn[left].CreateHashCopy[]; periods: Fn ~ LDO.MinimizeArraysPeriod[d, arrays, log]; periods.PrintBiRel[log]; log.PutRope["\n"]}; DoStep["MinimizeArrayPeriods", MinimizeArrayPeriodsStep]}; Subcells: PROC [parentName: ROPE, instanceTypes, instanceNames: REF ANY] RETURNS [--constant--RefSet] ~ { IF doing THEN { parent: CellType ~ ToT[parentName]; cis: Set _ parent.CTParts[i]; IF instanceTypes#NIL THEN { icts: Set ~ ToTSet[instanceTypes]; x: Set ~ d.ciType.Image[icts, rightToLeft]; cis _ cis.Intersection[x]}; IF instanceNames#NIL THEN { x: Set ~ TopISet[parent, instanceNames]; cis _ cis.Intersection[x]}; RETURN [cis.CreateHashCopy[].Refify]} ELSE RETURN [NIL]}; <<PrefixifyDesign: PROC ~ {>> <<ReadFunsimStep: PROC ~ {>> <<};>> <> ToTSet: PROC [ra: REF ANY] RETURNS [Set--of CellType--] ~ {WITH ra SELECT FROM ct: CellType => RETURN [Sets.CreateSingleA[ct, d.eSpace]]; rope: ROPE => RETURN d.ctName.Image[Sets.RopesMatching[[rope, TRUE, star]], rightToLeft]; x: REF READONLY TEXT => RETURN ToTSet[Rope.FromRefText[x]]; x: REF TEXT => RETURN ToTSet[Rope.FromRefText[x]]; x: RefSet => RETURN [x^]; x: LORA => { cts: Set ~ Sets.CreateHashSet[d.eSpace]; FOR y: LORA _ x, y.rest WHILE y#NIL DO sub: Set ~ ToTSet[y.first]; IF sub.Empty THEN ERROR; [] _ cts.AddSet[sub]; ENDLOOP; RETURN [cts]}; ENDCASE => ERROR}; ToT: PROC [ra: REF ANY] RETURNS [CellType] ~ { WITH ra SELECT FROM x: CellType => RETURN [x]; x: ROPE => RETURN [NARROW[d.ctName.InvApplyA[x].MA]]; x: REF READONLY TEXT => RETURN ToT[Rope.FromRefText[x]]; x: REF TEXT => RETURN ToT[Rope.FromRefText[x]]; ENDCASE => ERROR}; TopISet: PROC [parentA, ra: REF ANY] RETURNS [Set--of CellInstance--] ~ { parent: CellType ~ ToT[parentA]; WITH ra SELECT FROM x: ROPE => {sn: SteppyName ~ ParseSteppyName[x]; RETURN [parent.fullName[i].Mapping[sn.SnV, rightToLeft].CreateHashCopy]}; x: REF READONLY TEXT => RETURN TopISet[parent, Rope.FromRefText[x]]; x: REF TEXT => RETURN TopISet[parent, Rope.FromRefText[x]]; lora: LORA => { cis: Set ~ Sets.CreateHashSet[d.eSpace]; FOR l: LORA _ lora, l.rest WHILE l#NIL DO subs: Set ~ TopISet[parent, l.first]; IF subs.Empty THEN ERROR; [] _ cis.AddSet[subs]; ENDLOOP; RETURN [cis]}; x: RefSet => RETURN [x^]; ENDCASE => ERROR}; ToI: PROC [ra: REF ANY] RETURNS [CellInstance] ~ {WITH ra SELECT FROM x: CellInstance => RETURN [x]; x: ROPE => {path: SteppyName ~ ParseSteppyName[x]; tName: ROPE ~ NARROW[path.steps.first]; iName: SteppyName ~ path.SNTail; cct: CellType ~ ToT[tName]; RETURN [NARROW[cct.fullName[i].InvApply[SnV[iName]].MA]]}; x: REF READONLY TEXT => RETURN ToI[Rope.FromRefText[x]]; x: REF TEXT => RETURN ToI[Rope.FromRefText[x]]; ENDCASE => ERROR}; TopI: PROC [cct: CellType, ra: REF ANY] RETURNS [CellInstance] ~ {WITH ra SELECT FROM x: CellInstance => RETURN [x]; x: ROPE => {sn: SteppyName ~ ParseSteppyName[x]; RETURN [NARROW[cct.fullName[i].InvApply[SnV[sn]].MA]]}; x: REF READONLY TEXT => RETURN TopI[cct, Rope.FromRefText[x]]; x: REF TEXT => RETURN TopI[cct, Rope.FromRefText[x]]; ENDCASE => ERROR}; ToW: PROC [ra: REF ANY] RETURNS [Wire] ~ {WITH ra SELECT FROM x: Wire => RETURN [x]; x: ROPE => {path: SteppyName ~ ParseSteppyName[x]; tName: ROPE ~ NARROW[path.steps.first]; wName: SteppyName ~ path.SNTail; cct: CellType ~ ToT[tName]; RETURN [NARROW[cct.fullName[w].InvApply[SnV[wName]].MA]]}; x: REF READONLY TEXT => RETURN ToW[Rope.FromRefText[x]]; x: REF TEXT => RETURN ToW[Rope.FromRefText[x]]; ENDCASE => ERROR}; TopPSet: PROC [parentA, ra: REF ANY] RETURNS [Set--of Port--] ~ { parent: CellType ~ ToT[parentA]; WITH ra SELECT FROM x: ROPE => {sn: SteppyName ~ ParseSteppyName[x]; RETURN [parent.fullName[p].Mapping[sn.SnV, rightToLeft].CreateHashCopy]}; x: REF READONLY TEXT => RETURN TopPSet[parent, Rope.FromRefText[x]]; x: REF TEXT => RETURN TopPSet[parent, Rope.FromRefText[x]]; lora: LORA => { cis: Set ~ Sets.CreateHashSet[d.eSpace]; FOR l: LORA _ lora, l.rest WHILE l#NIL DO subs: Set ~ TopPSet[parent, l.first]; IF subs.Empty THEN ERROR; [] _ cis.AddSet[subs]; ENDLOOP; RETURN [cis]}; x: RefSet => RETURN [x^]; ENDCASE => ERROR}; Action: PROC ~ { At[-1]; Key[RipoutDebugging, ExternallyMerged, UndistinguishPorts, ImportAtomicWireOnceToRoot, ImportAtomicWireOnce, DeduceWireStructure, CleanupDesign, Group, ExpandInstance, ExpandType, FlattenArrays, RaiseGCs, ShortenArrayInstance, LowerArrayStructure, SimilarizeArrays, PrefixifyDesign, InheritNames, CleanupNames, DropPhysical, DeduceArrayness, MinimizeArrayPeriods, Subcells, At, ReadExt, ReadFunsim]; RETURN}; CedarProcess.DoWithPriority[background, Action]; RETURN}; END.