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˜