WriteDesign:
PROC [fileName:
ROPE, d: Design, pacify:
IO.
STREAM ←
NIL] ~ {
out: IO.STREAM ~ FS.StreamOpen[fileName, create];
refs: Seq ~ CreateSeq[len: d.cellTypes.Size.EN + d.parts.Size.EN, oneToOne: TRUE, dense: TRUE, rightSpace: d.eSpace];
IndexRef:
PROC [r:
REF
ANY]
RETURNS [
INT] ~ {
mv: Sets.MaybeValue ~ refs.Lookup[goal: AV[r], order: Sets.alleq];
IF mv.found THEN RETURN [mv.MI];
{i: INT ~ refs.Size.EN;
refs.AddNewIA[i, r];
RETURN [i]}};
PutSet:
PROC [set: Set,
PutElt:
PROC [Sets.Value]] ~ {
out.PutRope[" {"];
set.Enumerate[PutElt];
out.PutRope["}"];
RETURN};
PutBiRel:
PROC [br: BiRel, PutLeft,
PutRight:
PROC [Sets.Value], size:
BOOL] ~ {
PutPair:
PROC [pair: BiRels.Pair]
RETURNS [
BOOL] ~ {
PutLeft[pair[left]];
PutRight[pair[right]];
RETURN [FALSE]};
out.PutChar[' ];
IF size THEN out.Put[[integer[br.Size.EN]]];
out.PutRope["{"];
IF br.Scan[PutPair].found THEN ERROR;
out.PutRope["}"];
RETURN};
PutIndices:
PROC [set: Set] ~ {
PutSet[set, PutIndex];
RETURN};
PutIndex:
PROC [v: Sets.Value] ~ {
idx: INT ~ IndexRef[v.VA];
out.PutChar[' ];
out.Put[[character[' ]], [integer[idx]]];
RETURN};
PutInt:
PROC [v: Sets.Value] ~ {
int: INT ~ v.VI;
out.Put[[character[' ]], [integer[int]]];
RETURN};
PutInt2:
PROC [i2: Int2] ~ {
out.Put[[character[' ]], [integer[i2[X]]], [character[' ]], [integer[i2[Y]]] ];
RETURN};
PutRope:
PROC [rv: Sets.Value] ~ {
r: ROPE ~ NARROW[rv.VA];
out.PutF[" \"%q\"", [rope[r]]];
RETURN};
PutPAI:
PROC [paiv: Sets.Value] ~ {
pai: PortAtIndex ~ VPai[paiv];
PutIndex[AV[pai.port]];
PutInt2[pai.ai];
RETURN};
PutStatVert: PROC [paiv: Sets.Value] ~ PutPAI;
PutSub:
PROC [kidsv: Sets.Value] ~ {
kids: Seq ~ BiRels.VB[kidsv];
PutBiRel[kids, PutInt, PutIndex, TRUE];
RETURN};
PutCellTypeDetails:
PROC [ctv: Sets.Value] ~ {
ct: CellType ~ ctv.VA;
IF NOT ct.other.Empty THEN ERROR;
PutIndex[ctv];
out.PutF[" %g %g %g %g", [boolean[ct.inheritNames]], [boolean[ct.asu#NIL]], [boolean[ct.asArray#NIL]], [boolean[ct.asTrans#NIL]] ];
FOR pc: PartClass IN PartClass DO PutBiRel[ct.fullName[pc], PutIndex, PutSteppyName, FALSE] ENDLOOP;
FOR pc: PWClass
IN PWClass
DO
FOR b:
BOOL
IN
BOOL
DO
PutSet[ct.isDeduced[pc][b], PutIndex];
ENDLOOP ENDLOOP;
PutRange2[ct.bbox];
IF ct.asu#
NIL
THEN {
PutBiRel[ct.asu.exports, PutIndex, PutIndex, FALSE];
ct.Subcells.Enumerate[PutSubcell];
};
IF ct.asArray#
NIL
THEN {
a: Array ~ ct.asArray;
PutStatEdge:
PROC [sev: Sets.Value] ~ {
se: StatEdge ~ NARROW[sev.VA];
PutStatVert[SvV[se.vs[FALSE]]];
PutStatVert[SvV[se.vs[TRUE]]];
PutInt2[se.d];
RETURN};
PutDWDetails:
PROC [dwv: Sets.Value] ~ {
dw: DumbWire ~ NARROW[dwv.VA];
PutIndex[dwv];
PutBiRel[dw.eps, PutIndex, PutInt, FALSE];
PutBiRel[dw.children, PutInt, PutIndex, TRUE];
RETURN};
PutInt2[a.size2];
PutInt2[a.basePeriod];
PutBiRel[a.fXfm, PutInt, PutInt, FALSE];
IF a.offsets=
NIL
THEN out.PutRope[" NIL"]
ELSE {
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, PutStatEdge];
PutBiRel[a.statrep.apToPAI, PutIndex, PutPAI, FALSE];
PutSet[a.dumrep.wires, PutIndex];
PutSet[a.dumrep.wires, PutDWDetails];
PutBiRel[a.dumrep.apToWire, PutIndex, PutIndex, FALSE];
RETURN};
IF ct.asTrans#
NIL
THEN {
t: Transistor ~ ct.asTrans;
out.PutF[" \"%q\" %g %g %g %g", [rope[t.type]], [integer[t.length]], [integer[t.width]], [integer[t.area]], [integer[t.perimeter]] ]};
RETURN};
PutSubcell:
PROC [civ: Sets.Value] ~ {
ci: CellInstance ~ NARROW[civ.VA];
PutInt2[ci.offset];
PutBiRel[ci.conns, PutIndex, PutIndex, FALSE];
RETURN};
IF NOT d.other.Empty THEN ERROR;
out.PutF["%g\n", [integer[version]] ];
PutSet[d.names, PutRope];
out.PutF["\"%q\" %g\n", [rope[d.root.ACtName[]]], [real[d.scale]] ];
PutIndices[d.cellTypes];
PutIndices[d.partses[p]];
PutIndices[d.partses[w]];
PutIndices[d.partses[i]];
PutBiRel[d.sub, PutIndex, PutSub, FALSE];
FOR pc: PartClass IN PartClass DO PutBiRel[d.cct[pc], PutIndex, PutIndex, FALSE] ENDLOOP;
PutBiRel[d.ciType, PutIndex, PutIndex, FALSE];
PutBiRel[d.ctName, PutIndex, PutRope, FALSE];
PutBiRel[d.arrayElt, PutIndex, PutIndex, FALSE];
PutBiRel[d.ciXfm, PutIndex, PutInt, FALSE];
PutSet[d.cellTypes, PutCellTypeDetails];
out.Close[];
RETURN};