<> <> DIRECTORY AbSets, BiRels, Convert, FS, IntStuff, IO, LichenDataOps, LichenDataStructure, LichenIntBasics, Rope, SetBasics; LichenFiling: CEDAR PROGRAM IMPORTS AbSets, BiRels, Convert, FS, IntStuff, IO, LichenDataOps, LichenDataStructure, SetBasics = BEGIN OPEN IS:IntStuff, LIB:LichenIntBasics, LIB, LichenDataStructure, LichenDataOps, Sets:AbSets; version: INTEGER _ 1; 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. 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. 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}; END.