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��