WriteDesign:
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};
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];
PutSet[ct.isDeduced[p][FALSE], 'S, PutOldIndex];
PutSet[ct.isDeduced[p][TRUE], 'T, PutOldIndex];
PutSet[ct.isDeduced[w][FALSE], 'U, PutOldIndex];
PutSet[ct.isDeduced[w][TRUE], 'V, PutOldIndex];
PutRange2[ct.bbox];
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]];
PutRope[[d.root.ACtName[] ]];
PutReal[d.scale];
PutSet[d.cellTypes, 'B, PutNewIndex];
PutSet[d.labelCellTypes, 'Z, 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.ciXfm=nilBiRel
THEN PutInt[[i:0]]
ELSE {
PutInt[[i:1]];
PutBiRel[d.ciXfm, 'M, PutOldIndex, PutInt];
};
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};