Do:
PUBLIC
PROC [prefix, suffix:
ROPE,
Key: KeyProc, from, to:
INT, startD: Design ←
NIL]
RETURNS [Design] ~ {
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: ARRAY StepKind OF INT ← ALL[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];
[] ← TiogaMenuOps.Open[rootName];
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, IO.PutFR["Check at point %g", [integer[i]]], CheckStep];
IF i>0 THEN DoStep[io, IO.PutFR["PrettyPrint at point %g", [integer[i]]], PrettyPrintStep];
DoStep[io, IO.PutFR["Write at point %g", [integer[i]]], WriteStep];
FOR kind: StepKind
IN StepKind
DO
totSecs[kind] ← totSecs[kind] + phaseSecs[kind] ENDLOOP;
log.PutF["Phase %d took %d work & %d I/O seconds; totals are now %d & %d\n", [integer[i]], [integer[phaseSecs[work]]], [integer[phaseSecs[io]]], [integer[totSecs[work]]], [integer[totSecs[io]]]];
phaseSecs ← ALL[0];
logFile.Close[]; logFile ← NIL; 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
IF startD=
NIL
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[io, Rope.Cat["Read ", file], ReadStep];
DoStep[io, "Check after read", CheckStep]}
ELSE {
IF NOT startD.names.HasMemA[dName] THEN ERROR;
d ← startD;
log.PutRope["Starting with given design "];
startD.names.PrintSet[log];
log.PutRope["\n"]}
ELSE IF startD#NIL THEN ERROR;
RETURN};
DoStep:
PROC [kind: StepKind, 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[ !ABORTED => log.PutF["ABORTED at %g\n", [time[BasicTime.Now[]]]] ];
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[kind] ← phaseSecs[kind] + secs}}}; RETURN};
ReadExt:
PROC [rootCellFileName, clippingFileName:
ROPE, readPorts:
BOOL, labelCellTypes:
REF
ANY] ~ {
ReadExtStep:
PROC ~ {
d ← LichenFromExt.ReadDesign[rootCellFileName, IF readPorts THEN readPorts ELSE none, NIL, clippingFileName];
Atom.PutProp[$d, $d, d];
{labCells: Set--of CellType-- ~ ToTSet[labelCellTypes];
[] ← d.labelCellTypes.AddSet[labCells];
LDO.CheckDesign[d];
RETURN}};
DoStep[io, "ReadExt", ReadExtStep]};
ExtractPads:
PROC ~ {
ExtractPadsStep:
PROC ~ {
exCells: BiRel;
newPorts: Set;
[exCells, newPorts] ← LDO.ExtractPads[d, log];
log.PutRope["exCells="]; exCells.PrintBiRel[log];
log.PutRope["\nnewPorts="]; newPorts.PrintSet[log];
log.PutRope["\n"]};
DoStep[work, "ExtractPads", ExtractPadsStep]};
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[io, "ReadFunsim", ReadFunsimStep]};
RipoutTransistors:
PROC [inA:
REF
ANY] ~ {
RipoutTransistorsStep:
PROC ~ {
xstrs: Set ~ d.ciType.Image[d.transistorCellTypes, rightToLeft];
in: CellType ~ ToT[inA];
goners: Set ~ in.Subcells[].Intersection[xstrs].CreateHashCopy[];
[] ← LDO.DeleteInsts[d, goners, TRUE, FALSE, log]};
DoStep[work, "RipoutTransistors", RipoutTransistorsStep]};
RipoutInsts:
PROC [parentA, cisA:
REF
ANY] ~ {
RipoutInstsStep:
PROC ~ {
parent: CellType ~ ToT[parentA];
cis: Set ~ TopISet[parent, cisA];
[] ← LDO.DeleteInsts[d, cis, TRUE, TRUE, log]};
DoStep[work, "RipoutInsts", RipoutInstsStep]};
MergeWireKludge:
PROC [wiresA:
REF
ANY] ~ {
MergeWireKludgeStep:
PROC ~ {
wires: Set ~ TopWSet[d.root, wiresA];
ports: Set ~ d.root.asu.exports.Image[wires, rightToLeft].CreateHashCopy[];
[] ← LDO.MergeWireSet[d, wires, TRUE];
IF ports.NonTrivial[] THEN [] ← LDO.MergePorts[d.root, ports];
RETURN};
DoStep[work, "MergeWireKludge", MergeWireKludgeStep]};
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[work, "ExternallyMerged", ExternallyMergedStep]};
UndistinguishPorts:
PROC ~ {
UndistinguishPortsStep: PROC ~ {[] ← LDO.UndistinguishPorts[d, log]};
DoStep[work, "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[work, "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[work, "ImportAtomicWireOnce", ImportAtomicWireOnceStep]};
ExportWires:
PROC [ctA, wiresA:
REF
ANY] ~ {
ExportWiresStep:
PROC ~ {
ct: CellType ~ ToT[ctA];
wires: Set ~ TopWSet[ct, wiresA];
[] ← LDO.FullySfwdlyExportWires[ct, wires];
RETURN};
DoStep[work, "ExportWires", ExportWiresStep]};
DeduceWireStructure:
PROC ~ {
DeduceWireStructureStep: PROC ~ {LDO.AddDeducedStructureToDesign[d, log]};
DoStep[work, "DeduceWireStructure", DeduceWireStructureStep]};
CleanupDesign:
PROC ~ {
CleanupDesignStep: PROC ~ {[] ← LDO.CleanDesign[d, log]};
DoStep[work, "CleanupDesign", CleanupDesignStep]};
Group:
PROC [iName, tName:
ROPE, parentA, sibsA:
REF
ANY] ~ {
GroupStep:
PROC ~ {
[] ← LichenFlatPrivate.GroupInstancesToNewCT[d, TopISet[parentA, sibsA], iName, OneRope[tName]];
RETURN};
DoStep[work, "Group", GroupStep]};
ExpandInstance:
PROC [instA:
REF
ANY] ~ {
ExpandInstanceStep:
PROC ~ {
[] ← LDO.ExpandInstance[d, ToI[instA]];
};
DoStep[work, "ExpandInstance", ExpandInstanceStep]};
ExpandType:
PROC [tName:
ROPE] ~ {
ExpandTypeStep:
PROC ~ {
[] ← LDO.ExpandType[d, ToT[tName]];
};
DoStep[work, "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 b err msg--;
[oks, errs] ← LDO.FlattenArrays[d, dblArrays, TRUE, log];
log.PutRope["OK: "];
oks.PrintSet[log];
log.PutRope[", errs: "];
errs.PrintBiRel[log];
log.PutRope["\n"]};
DoStep[work, "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[work, "RaiseGCs", RaiseGCsStep]};
LowerKidsOnce:
PROC [parentA, kidsA, sibA:
REF
ANY]
RETURNS [loweredKids: RefSet
--of CellInstance-- ←
NIL] ~ {
LowerKidsOnceStep:
PROC ~ {
parent: CellType ~ ToT[parentA];
kids: Set ~ TopISet[parent, kidsA];
sib: CellInstance ~ TopI[parent, sibA];
loweredKids ← LichenFlatPrivate.LowerKidsOnce[d, kids, sib].Refify};
DoStep[work, "LowerKidsOnce", LowerKidsOnceStep]};
ShortenArrayInstance:
PROC [inst:
REF
ANY, end: ArrayEnd, sDim: Dim3 ← Z, by:
NAT ← 1] ~ {
ShortenArrayInstanceStep:
PROC ~ {
LDO.ShortenArrayInstance[d, ToI[inst], end, sDim, by];
};
DoStep[work, "ShortenArrayInstance", ShortenArrayInstanceStep]};
LowerArrayStructure:
PROC [outerA:
REF
ANY] ~ {
LowerArrayStructureStep: PROC ~ {LDO.LowerArrayStructure[ToT[outerA]]};
DoStep[work, "LowerArrayStructure", LowerArrayStructureStep]};
SimilarizeArrays:
PROC ~ {
SimilarizeArraysStep: PROC ~ {[] ← LDO.SimilarizeArrays[d, d.cellTypes]};
DoStep[work, "SimilarizeArrays", SimilarizeArraysStep]};
PrefixifyDesign:
PROC ~ {
PrefixifyDesignStep: PROC ~ {LDO.PrefixifyDesign[d]};
DoStep[work, "PrefixifyDesign", PrefixifyDesignStep]};
InheritNames:
PROC [renamesFileName:
ROPE] ~ {
InheritNamesStep:
PROC ~ {
renames: Fn;
renamesCount: INT;
[renames, renamesCount] ← LDO.ReadRenames[d, renamesFileName];
log.PutF["%g renaming statements read.\n", [integer[renamesCount]]];
LDO.InheritNames[d, TRUE, FALSE, renames]};
DoStep[work, "InheritNames", InheritNamesStep]};
CleanupNames:
PROC ~ {
CleanupNamesStep: PROC ~ {LDO.CleanupDesignNames[d]};
DoStep[work, "CleanupNames", CleanupNamesStep]};
DropPhysical:
PROC ~ {
DropPhysicalStep: PROC ~ {LDO.DropPhysical[d]};
DoStep[work, "DropPhysical", DropPhysicalStep]};
DeduceArrayness:
PROC [ctsA:
REF
ANY] ~ {
DeduceArraynessStep: PROC ~ {[] ← LDO.DeduceArrayness[d, ToTSet[ctsA], log]};
DoStep[work, "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[work, "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]};
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};
TopWSet:
PROC [parentA, ra:
REF
ANY]
RETURNS [Set
--of Wire--] ~ {
parent: CellType ~ ToT[parentA];
WITH ra
SELECT
FROM
x:
ROPE => {sn: SteppyName ~ ParseSteppyName[x];
RETURN [parent.fullName[w].Mapping[sn.SnV, rightToLeft].CreateHashCopy]};
x: REF READONLY TEXT => RETURN TopWSet[parent, Rope.FromRefText[x]];
x: REF TEXT => RETURN TopWSet[parent, Rope.FromRefText[x]];
lora:
LORA => {
ws: Set ~ Sets.CreateHashSet[d.eSpace];
FOR l:
LORA ← lora, l.rest
WHILE l#
NIL
DO
subs: Set ~ TopWSet[parent, l.first];
IF subs.Empty THEN ERROR;
[] ← ws.AddSet[subs];
ENDLOOP;
RETURN [ws]};
x: RefSet => RETURN [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 => {
ps: 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;
[] ← ps.AddSet[subs];
ENDLOOP;
RETURN [ps]};
x: RefSet => RETURN [x^];
ENDCASE => ERROR};
Action:
PROC ~ {
ENABLE UNWIND => IF logFile#NIL THEN logFile.Close[];
At[-1];
Key[RipoutTransistors, RipoutInsts, MergeWireKludge, ExternallyMerged, UndistinguishPorts, ImportAtomicWireOnceToRoot, ImportAtomicWireOnce, ExportWires, DeduceWireStructure, CleanupDesign, Group, ExpandInstance, ExpandType, FlattenArrays, RaiseGCs, LowerKidsOnce, ShortenArrayInstance, LowerArrayStructure, SimilarizeArrays, PrefixifyDesign, InheritNames, CleanupNames, DropPhysical, DeduceArrayness, MinimizeArrayPeriods, Subcells, At, ReadExt, ExtractPads, ReadFunsim];
RETURN};
CedarProcess.DoWithPriority[background, Action];
RETURN [d]};