DIRECTORY AbSets, BiRels, FS, IntStuff, IO, LichenDataOps, LichenDataStructure, LichenFiling, LichenFromCore, LichenIntBasics, PBasics, Process, RefText, Rope, SetBasics;

LichenFileOut: CEDAR PROGRAM
IMPORTS AbSets, BiRels, FS, IntStuff, IO, LichenDataStructure, LichenFromCore, PBasics, Process, Rope, SetBasics
EXPORTS LichenFiling
=

BEGIN OPEN IS:IntStuff, LIB:LichenIntBasics, LIB, LichenDataStructure, LichenDataOps, Sets:AbSets, LichenFiling;

version: INTEGER _ 11;

firstNeg: BYTE ~ BYTE.LAST/2+1;
lastPos: BYTE ~ BYTE.LAST/2;

okOther: Set ~ Sets.CreateSingleA[LichenFromCore.implKey, SetBasics.reps];

WriteDesign: PUBLIC PROC [fileName: ROPE, d: Design, pacify: IO.STREAM _ NIL] RETURNS [refcs, ropecs, slcs: CacheStats _ []] ~ {
out: IO.STREAM ~ FS.StreamOpen[fileName: fileName, accessOptions: create, keep: 10];
refs: Seq ~ CreateSeq[len: d.cellTypes.Size.EN + d.parts.Size.EN, oneToOne: TRUE, dense: TRUE, rightSpace: d.eSpace];
ropes: Seq ~ CreateSeq[len: 1000, oneToOne: TRUE, dense: TRUE, rightSpace: SetBasics.ropes[TRUE]];
steplists: Seq ~ CreateSeq[len: 1000, oneToOne: TRUE, dense: TRUE, rightSpace: steplistSpace];
fullBuf: REF PBasics.FWORD ~ NEW [PBasics.FWORD];
maxRopeLen: INT _ -1;
cellTypeN: INT _ 0;
OutEnd: PROC ~ {
out.PutChar[VAL[lastPos]];
RETURN};
PutInt: PROC [v: Sets.Value] ~ {
f: PBasics.FWORD ~ PBasics.FFromInt32[v.VI];
Process.CheckForAbort[];
IF f.hi = [0, 0] AND f.lo.hi < lastPos OR f.hi = [BYTE.LAST, BYTE.LAST] AND f.lo.hi > firstNeg THEN {
out.PutChar[VAL[f.lo.hi]];
out.PutChar[VAL[f.lo.lo]];
}
ELSE {
out.PutChar[VAL[firstNeg]];
fullBuf^ _ f;
TRUSTED {out.UnsafePutBlock[[base: LOOPHOLE[fullBuf], count: BYTES[PBasics.FWORD]]]};
};
RETURN};
PutReal: PROC [r: REAL] ~ TRUSTED {
out.UnsafePutBlock[[base: @r, count: BYTES[REAL]]];
RETURN};
PutSet: PROC [set: Set, key: CHAR, PutElt: PROC [Sets.Value]] ~ {
out.PutChar[key];
pacify.PutChar[key];
set.Enumerate[PutElt];
OutEnd[];
RETURN};
PutSeq: PROC [seq: Seq, key: CHAR, PutElt: PROC [Sets.Value], pac: BOOL _ TRUE] ~ {
len: INT ~ seq.Size.EN;
i: INT _ 0;
PutPair: PROC [pair: BiRels.Pair] RETURNS [BOOL] ~ {
IF i # pair[left].VI THEN ERROR;
PutElt[pair[right]];
i _ i + 1;
RETURN [FALSE]};
out.PutChar[key];
IF pac THEN pacify.PutChar[key];
PutInt[[i: len]];
IF seq.Scan[PutPair, BiRels.leftFwd].found THEN ERROR;
IF i # len THEN ERROR;
OutEnd[];
RETURN};
PutBiRel: PROC [br: BiRel, key: CHAR, PutLeft, PutRight: PROC [Sets.Value], pac: BOOL _ TRUE] ~ {
PutPair: PROC [pair: BiRels.Pair] RETURNS [BOOL] ~ {
PutLeft[pair[left]];
PutRight[pair[right]];
RETURN [FALSE]};
out.PutChar[key];
IF pac THEN pacify.PutChar[key];
IF br.Scan[PutPair].found THEN ERROR;
OutEnd[];
RETURN};
PutNewIndex: PROC [v: Sets.Value] ~ {PutIndex[v, TRUE]};
PutOldIndex: PROC [v: Sets.Value] ~ {PutIndex[v, FALSE]};
PutIndex: PROC [v: Sets.Value, mayBeNew: BOOL] ~ {
mv: Sets.MaybeValue ~ refs.Lookup[goal: v, order: Sets.alleq];
idx: INT;
refcs.probes _ refcs.probes + 1;
IF mv.found THEN {
idx _ mv.MI + 1;
IF idx < 1 THEN ERROR}
ELSE {
IF NOT mayBeNew THEN ERROR;
idx _ refs.Size.EN;
IF idx < 0 THEN ERROR;
refcs.misses _ refcs.misses + 1;
IF refcs.misses # idx THEN ERROR;
refs.AddNewPair[[IV[idx], v]];
idx _ -(idx+1)};
PutInt[[i: idx]];
RETURN};
PutInt2: PROC [i2: Int2] ~ {
PutInt[[i:i2[X]]];
PutInt[[i:i2[Y]]];
RETURN};
PutRange2: PROC [r2: Range2] ~ {
PutInt2[[r2[X].min, r2[Y].min]];
PutInt2[[r2[X].maxPlusOne, r2[Y].maxPlusOne]];
RETURN};
PutRope: PROC [v: Sets.Value] ~ {
mv: Sets.MaybeValue ~ ropes.Lookup[goal: v, order: Sets.alleq];
idx: INT;
ropecs.probes _ ropecs.probes + 1;
IF mv.found THEN idx _ mv.MI ELSE {
idx _ ropes.Size.EN;
IF ropecs.misses # idx THEN ERROR;
ropecs.misses _ ropecs.misses + 1;
ropes.AddNewPair[[IV[idx], v]];
};
IF idx<0 THEN ERROR;
PutInt[[i:(1+idx) * (IF mv.found THEN 1 ELSE -1)]];
IF NOT mv.found THEN {
r: ROPE ~ NARROW[v.VA];
l: INT ~ r.Length;
maxRopeLen _ MAX[maxRopeLen, l];
PutInt[[i: l]];
out.PutRope[r]};
RETURN};
PutStepList: PROC [v: Sets.Value] ~ {
mv: Sets.MaybeValue ~ steplists.Lookup[goal: v, order: Sets.alleq];
idx: INT;
slcs.probes _ slcs.probes + 1;
IF mv.found THEN idx _ mv.MI ELSE {
idx _ steplists.Size.EN;
slcs.misses _ slcs.misses + 1;
IF slcs.misses # idx THEN ERROR;
steplists.AddNewPair[[IV[idx], v]];
};
IF idx<0 THEN ERROR;
IF mv.found THEN PutInt[[i: idx]] ELSE {
sl: NameStepList ~ NARROW[v.VA];
WITH sl.first SELECT FROM
x: ROPE => {PutInt[[i: (idx+1)*-2]]; PutRope[[x]]};
x: REF INT => {PutInt[[i: (idx+1)*-2 + 1]]; PutInt[[i:x^]]};
ENDCASE => ERROR;
PutStepList[[sl.rest]]};
RETURN};
PutSteppyName: PROC [snv: Sets.Value] ~ {
PutInt[[i:snv.i]];
PutStepList[[snv.ra]];
RETURN};
PutPAI: PROC [paiv: Sets.Value] ~ {
pai: PortAtIndex ~ VPai[paiv];
PutOldIndex[AV[pai.port]];
PutInt2[pai.ai];
RETURN};
PutStatVert: PROC [paiv: Sets.Value] ~ PutPAI;
PutSub: PROC [kidsv: Sets.Value] ~ {
kids: Seq ~ BiRels.VB[kidsv];
PutSeq[kids, 'O, PutOldIndex, FALSE];
RETURN};
PutCellTypeBBox: PROC [ctv: Sets.Value] ~ {
ct: CellType ~ NARROW[ctv.VA];
PutOldIndex[ctv];
PutRange2[ct.bbox];
RETURN};
PutCellTypeDetails: PROC [ctv: Sets.Value] ~ {
ct: CellType ~ NARROW[ctv.VA];
IF ct.other.SetOn[left].Difference[okOther].NonEmpty THEN ERROR;
pacify.PutF["\n%g: ", [integer[cellTypeN]]];
cellTypeN _ cellTypeN + 1;
Sets.PrintSet[d.CTNames[ct], pacify];
PutOldIndex[ctv];
PutInt[[i: (IF ct.asTrans#NIL THEN 1 ELSE 0) + (IF ct.asu#NIL THEN 2 ELSE 0) + (IF ct.asArray#NIL THEN 4 ELSE 0)]];
PutBiRel[ct.fullName[p], 'P, PutOldIndex, PutSteppyName];
IF ct.asu#NIL THEN {
PutBiRel[ct.fullName[w], 'Q, PutOldIndex, PutSteppyName];
PutBiRel[ct.fullName[i], 'R, PutOldIndex, PutSteppyName];
PutBiRel[ct.asu.exports, 'a, PutOldIndex, PutOldIndex];
PutSet[ct.Subcells, 'b, PutSubcellDetails];
};
IF ct.asArray#NIL THEN {
a: Array ~ ct.asArray;
PutStatEdge: PROC [sev: Sets.Value] ~ {
se: StatEdge ~ NARROW[sev.VA];
PutStatVert[se.SeRSvV[a.statrep, FALSE]];
PutStatVert[se.SeRSvV[a.statrep, TRUE]];
PutInt2[se.d];
RETURN};
PutDWDetails: PROC [dwv: Sets.Value] ~ {
dw: DumbWire ~ NARROW[dwv.VA];
PutOldIndex[dwv];
PutBiRel[dw.eps, 'k, PutOldIndex, PutInt, FALSE];
IF dw.children=nilBiRel THEN PutInt[[i:0]]
ELSE {
PutInt[[i:1]];
PutSeq[dw.children, 'l, PutOldIndex, FALSE]};
RETURN};
PutInt2[a.size2];
PutInt2[a.basePeriod];
PutInt[[i: (IF a.fXfm#nilBiRel THEN 1 ELSE 0) + (IF a.offsets#NIL THEN 2 ELSE 0)]];
IF a.fXfm#nilBiRel THEN PutBiRel[a.fXfm, 'e, PutInt, PutInt];
IF a.offsets#NIL THEN {
PutInt[IV[a.offsets.length]];
FOR i: NATURAL IN [0 .. a.offsets.length) DO
PutInt2[a.offsets[i].o0];
PutInt2[a.offsets[i].o1];
ENDLOOP;
};
PutSet[a.statrep.edges, 'f, PutStatEdge];
PutBiRel[a.statrep.apToPAI, 'g, PutOldIndex, PutPAI];
PutSet[a.dumrep.wires, 'h, PutNewIndex];
PutSet[a.dumrep.wires, 'i, PutDWDetails];
PutBiRel[a.dumrep.apToWire, 'j, PutOldIndex, PutOldIndex];
};
IF ct.asTrans#NIL THEN {
t: Transistor ~ ct.asTrans;
PutRope[[t.type]];
PutInt[[i: t.length]];
PutInt[[i: t.width]];
PutInt[[i: t.area]];
PutInt[[i: t.perimeter]]};
RETURN};
PutSubcellDetails: PROC [civ: Sets.Value] ~ {
ci: CellInstance ~ NARROW[civ.VA];
PutOldIndex[civ];
PutInt2[ci.offset];
PutBiRel[ci.conns, 'c, PutOldIndex, PutOldIndex, FALSE];
RETURN};
IF NOT d.other.Empty THEN ERROR;
IF pacify=NIL THEN pacify _ IO.noWhereStream;
pacify.PutF["Total: %g cell types\n", [integer[d.cellTypes.Size.EN]]];
steplists.AddNewIA[0, NIL];
refs.AddNewIA[0, NIL];
PutInt[[i:version]];
out.PutRope["123456789"];
out.SetIndex[10];
PutSet[d.names, 'A, PutRope];
PutInt[[i: (IF d.inheritNames THEN 1 ELSE 0) + (IF d.physd THEN 2 ELSE 0)]];
PutRope[[d.root.ACtName[] ]];
PutReal[d.scale];
PutSet[d.cellTypes, 'B, PutNewIndex];
PutSet[d.labelCellTypes, 'Z, PutOldIndex];
PutSet[d.crossedCellTypes, 'Y, PutOldIndex];
PutBiRel[d.cct[p], 'C, PutNewIndex, PutOldIndex];
PutBiRel[d.cct[w], 'D, PutNewIndex, PutOldIndex];
PutBiRel[d.cct[i], 'E, PutNewIndex, PutOldIndex];
PutBiRel[d.sub, 'F, PutOldIndex, PutSub];
PutBiRel[d.ciType, 'J, PutOldIndex, PutOldIndex];
PutBiRel[d.ctName, 'K, PutOldIndex, PutRope];
PutBiRel[d.arrayElt, 'L, PutOldIndex, PutOldIndex];
IF d.physd THEN {
PutBiRel[d.ciXfm, 'M, PutOldIndex, PutInt];
PutSet[d.cellTypes, 'G,  PutCellTypeBBox]};
PutSet[d.cellTypes, 'N,  PutCellTypeDetails];
pacify.PutRope["\n"];
{tail: INT ~ out.GetIndex[];
out.SetIndex[5];
PutInt[[i: tail]];
out.SetIndex[tail]};
out.PutRope["paSsword "];
PutInt[[i:refs.Size.EN]];
PutInt[[i:ropes.Size.EN]];
PutInt[[i:steplists.Size.EN]];
PutInt[[i:maxRopeLen]];
PutInt[[i:d.cellTypes.Size.EN]];
out.Close[];
RETURN};

PrintCTGraph: PROC [d: Design, fileName: ROPE, omitTransistors: BOOL] RETURNS [nOmitted: INT _ 0] ~ {
out: IO.STREAM ~ FS.StreamOpen[fileName, create];
calls: BiRel ~ d.cct[i].Invert.Compose[d.ciType, ALL[FALSE]].CreateHashCopy[mappable: ALL[TRUE]];
PerCT: PROC [ctv: Sets.Value] RETURNS [BOOL] ~ {
IF omitTransistors AND d.transistorCellTypes.HasMember[ctv] THEN {nOmitted _ nOmitted + 1; RETURN [FALSE]};
{ct: CellType ~ NARROW[ctv.VA];
name: ROPE ~ d.Describe[ct, d];
PrintDep: PROC [dtv: Sets.Value] RETURNS [BOOL] ~ {
IF omitTransistors AND d.transistorCellTypes.HasMember[dtv] THEN RETURN [FALSE];
{dt: CellType ~ NARROW[dtv.VA];
name: ROPE ~ d.Describe[dt, d];
out.PutF[" \"%q\"", [rope[name]]];
RETURN [FALSE]}};
out.PutF["(\"%q\" %g", [rope[name]], [rope[IF calls.MappingEmpty[ctv, rightToLeft] THEN "root" ELSE "NIL"]]];
IF calls.ScanMapping[ctv, PrintDep].found THEN ERROR;
out.PutRope[")\n\n"];
RETURN [FALSE]}};
[] _ calls.AddSet[d.arrayElt];
out.PutRope["(\n\n"];
IF d.cellTypes.Scan[PerCT].found THEN ERROR;
out.PutRope[")\n"];
out.Close[];
RETURN};

END.
���\��LichenFileOut.Mesa
Last tweaked by Mike Spreitzer on November 29, 1988 7:37:17 pm PST
Ê’��–
"cedar" style˜�codešœ™KšœB™B—K˜�KšÏk	œœœ€˜ªK˜�šÏn
œœ˜KšœœœH˜pKšœ
˜K˜—K˜�Kšœœœœœ&žœ˜pK˜�Kšœ	œ˜K˜�Kšœ
œœœ˜Kšœ	œœœ˜K˜�K˜JK˜�šžœœœœœœœœ+˜€KšœœœœA˜TKš	œ,œœœ	œ˜uKšœ,œ	œœ˜bKšœ0œ	œ˜^Kš	œ	œ	œœ
œ˜1Kšœœ˜Kšœœ˜šžœœ˜Kšœœ˜Kšœ˜—šžœœ˜ Kšœœœ˜,Kšœ˜šœœœ	œœœœœœ˜eKšœœ˜Kšœœ˜K˜—šœ˜Kšœœ˜Kšœ
˜
Kšœœœ	œ˜UK˜—Kšœ˜—šžœœœœ˜#Kšœ%œœ˜3Kšœ˜—š
žœœœžœœ˜AKšœ˜Kšœ˜Kšœ˜Kšœ	˜	Kšœ˜—šžœœœžœœœœ˜SKšœœœ˜Kšœœ˜šžœœœœ˜4Kšœœœœ˜ Kšœ˜K˜
Kšœœ˜—K˜Kšœœ˜ Kšœ˜Kšœ)œœ˜6Kšœ	œœ˜Kšœ	˜	Kšœ˜—šžœœœžœœœœ˜ašžœœœœ˜4K˜K˜Kšœœ˜—Kšœ˜Kšœœ˜ Kšœœœ˜%Kšœ	˜	Kšœ˜—Kšžœœ œ˜8Kšžœœ œ˜9šžœœœ˜2Kšœ>˜>Kšœœ˜	K˜ šœ
œ˜Kšœ	œ˜Kšœ	œœ˜—šœ˜Kšœœ
œœ˜Kšœœ˜Kšœ	œœ˜K˜ Kšœœœ˜!Kšœœ˜K˜—K˜Kšœ˜—šžœœ˜K˜K˜Kšœ˜—šž	œœ˜ K˜ K˜.Kšœ˜—šžœœ˜!Kšœ?˜?Kšœœ˜	K˜"šœ
œ
œœ˜#Kšœœ˜Kšœœœ˜"K˜"Kšœœ˜K˜—Kšœœœ˜Kšœœ
œœ˜3šœœ
œ˜Kšœœœœ˜Kšœœ˜Kšœ
œ˜ K˜K˜—Kšœ˜—šžœœ˜%KšœC˜CKšœœ˜	K˜šœ
œ
œœ˜#Kšœœ˜K˜Kšœœœ˜ Kšœœ˜#K˜—Kšœœœ˜šœ
œœ˜(Kšœœœ˜ šœ
œ˜Kšœœ,˜3Kšœœœ2˜<Kšœœ˜—Kšœ˜—Kšœ˜—šž
œœ˜)K˜Kšœ˜Kšœ˜—šžœœ˜#Kšœ˜Kšœœ˜K˜Kšœ˜—Kšžœœ˜.šžœœ˜$Kšœœ˜Kšœœ˜%Kšœ˜—šžœœ˜+Kšœœœ˜K˜K˜Kšœ˜—šžœœ˜.Kšœœœ˜Kšœ3œœ˜@K˜,K˜K˜%K˜Kšœœœœœœœœœœœœœ˜sKšœ9˜9šœœœ˜Kšœ9˜9Kšœ9˜9Kšœ7˜7K˜+K˜—šœœœ˜K˜šžœœ˜'Kšœœœ˜Kšœ!œ˜)Kšœ!œ˜(KšœÏgœ˜Kšœ˜—šžœœ˜(Kšœœœ˜K˜Kšœ*œ˜1Kšœœ˜*šœ˜K˜Kšœ%œ˜-—Kšœ˜—K˜Kšœ˜KšœœŸœ
œœœœœœ˜SKšœŸœ
œŸœ˜=šœœœ˜Kšœœ˜šœœœ˜,K˜K˜Kšœ˜—K˜—Kšœ)˜)Kšœ5˜5Kšœ(˜(Kšœ)˜)Kšœ:˜:Kšœ˜—šœœœ˜Kšœ˜K˜K˜K˜K˜K˜—Kšœ˜—šžœœ˜-Kšœœœ˜"K˜K˜Kšœ1œ˜8Kšœ˜—Kšœœœœ˜ Kšœœœ
œ˜-Kšœ@œ˜FKšœœ˜Kšœœ˜K˜K˜K˜K˜Kš
œœœœœ	œœ˜LKšœ˜Kšœ˜Kšœ%˜%Kšœ*˜*Kšœ,˜,Kšœ1˜1Kšœ1˜1Kšœ1˜1Kšœ)˜)Kšœ1˜1Kšœ-˜-Kšœ3˜3šœ	œ˜Kšœ+˜+Kšœ+˜+—Kšœ-˜-K˜Kšœœ˜K˜K˜K˜K˜Kšœœ˜Kšœœ˜Kšœœ˜Kšœ˜Kšœœ˜ K˜Kšœ˜—K˜�šžœœœœœœ	˜eKšœœœœ˜1Kš	œ1œœœœ˜ašžœœœœ˜0Kš
œœ&œœœ˜kKšœœœ˜Kšœœ˜šžœœœœ˜3Kš
œœ&œœœ˜PKšœœœ˜Kšœœ˜Kšœ"˜"Kšœœ˜—Kšœ+œ&œœ
˜mKšœ(œœ˜5K˜Kšœœ˜—Kšœ˜K˜Kšœœœ˜,K˜K˜Kšœ˜—K˜�Kšœ˜—�…—����%b��2P��