DIRECTORY AbSets, BiRels, FS, IntStuff, IO, LichenArrayPrivate, LichenDataOps, LichenDataStructure, LichenIntBasics, PBasics, Process, RefText, Rope, SetBasics; LichenFileIn: CEDAR PROGRAM IMPORTS AbSets, BiRels, FS, IO, LichenArrayPrivate, LichenDataOps, LichenDataStructure, LichenIntBasics, PBasics, Process, Rope, SetBasics = BEGIN OPEN IS:IntStuff, LIB:LichenIntBasics, LIB, LichenDataStructure, LichenDataOps, Sets:AbSets; vMin: INTEGER _ 7; vMax: INTEGER _ 7; firstNeg: BYTE ~ BYTE.LAST/2+1; lastPos: BYTE ~ BYTE.LAST/2; ReadDesign: PROC [fileName: ROPE, pacify: IO.STREAM _ NIL] RETURNS [d: Design] ~ { in: IO.STREAM ~ FS.StreamOpen[fileName]; fullBuf: REF PBasics.FWORD ~ NEW [PBasics.FWORD]; refs, ropes, steplists: Seq; dNames: Set ~ Sets.CreateHashSet[SetBasics.ropes[TRUE]]; rootName: ROPE; maxRopeLen, nRefs, nRopes, nSteplists, nCellTypes, tail, version: INT _ -1; cellTypeN: INT _ 0; GetInt: PROC RETURNS [INT] ~ { c0: BYTE ~ in.GetChar[].ORD; Process.CheckForAbort[]; SELECT c0 FROM firstNeg => { TRUSTED {IF in.UnsafeGetBlock[[base: LOOPHOLE[fullBuf], count: BYTES[PBasics.FWORD]]] # BYTES[PBasics.FWORD] THEN ERROR}; RETURN PBasics.Int32FromF[fullBuf^]}; lastPos => ERROR; ENDCASE => RETURN [PBasics.Int16FromH[[hi: c0, lo: in.GetChar[].ORD]]]; }; GetIntV: PROC RETURNS [Sets.Value] ~ {RETURN [IV[GetInt[]]]}; GetRope: PROC RETURNS [ROPE] ~ { i: INT ~ GetInt[]; IF i >0 THEN RETURN [NARROW[ropes.ApplyI[i-1].MA]]; {len: INT ~ GetInt[]; IF len > maxRopeLen THEN ERROR; {GetChar: PROC RETURNS [CHAR] ~ {RETURN in.GetChar[]}; r: ROPE ~ Rope.FromProc[len, GetChar]; ropes.AddNewIA[-i - 1, r]; RETURN [r]}}}; GetRopeV: PROC RETURNS [Sets.Value] ~ {RETURN [AV[GetRope[]]]}; GetReal: PROC RETURNS [r: REAL] ~ TRUSTED { IF in.UnsafeGetBlock[[base: @r, count: BYTES[REAL]]] # BYTES[REAL] THEN ERROR; RETURN}; GetInt2: PROC RETURNS [Int2] ~ { x: INT ~ GetInt[]; RETURN [[X: x, Y: GetInt[]]]}; GetRange2: PROC RETURNS [Range2] ~ { min: Int2 ~ GetInt2[]; mp1: Int2 ~ GetInt2[]; RETURN [[ X: [min: min[X], maxPlusOne: mp1[X]], Y: [min: min[Y], maxPlusOne: mp1[Y]] ]]}; GetStepList: PROC RETURNS [NameStepList] ~ { idx: INT _ GetInt[]; IF idx >= 0 THEN RETURN [NARROW[steplists.ApplyI[idx].MA]]; idx _ -idx; {this: REF ANY ~ SELECT idx MOD 2 FROM 0 => GetRope[], 1 => NEW [INT _ GetInt[]], ENDCASE => ERROR; all: NameStepList ~ CONS[this, GetStepList[]]; steplists.AddNewIA[(idx+1)/2-1, all]; RETURN [all]}}; GetSteppyName: PROC RETURNS [Sets.Value] ~ { gradeI: INT ~ GetInt[]; steps: NameStepList ~ GetStepList[]; RETURN [[ra: steps, i: gradeI]]}; AddSet: PROC [set: Set, key: CHAR, GetEltV: PROC RETURNS [Sets.Value]] ~ { startIdx: INT ~ in.GetIndex[]; IF in.GetChar[] # key THEN ERROR; pacify.PutChar[key]; UNTIL in.PeekChar[].ORD = lastPos DO elt: Sets.Value ~ GetEltV[]; IF NOT set.AddElt[elt] THEN ERROR; ENDLOOP; IF in.GetChar[].ORD # lastPos THEN ERROR; RETURN}; EnumSet: PROC [set: Set, key: CHAR, Per: PROC [Sets.Value]] ~ { startIdx: INT ~ in.GetIndex[]; IF in.GetChar[] # key THEN ERROR; UNTIL in.PeekChar[].ORD = lastPos DO elt: Sets.Value ~ GetOldV[]; IF NOT set.HasMember[elt] THEN ERROR; Per[elt]; ENDLOOP; IF in.GetChar[].ORD # lastPos THEN ERROR; RETURN}; AddBiRel: PROC [br: BiRel, key: CHAR, GetLeft, GetRight: PROC RETURNS [Sets.Value], pac: BOOL _ TRUE] ~ { startIdx: INT ~ in.GetIndex[]; IF in.GetChar[] # key THEN ERROR; IF pac THEN pacify.PutChar[key]; UNTIL in.PeekChar[].ORD = lastPos DO left: Sets.Value ~ GetLeft[]; right: Sets.Value ~ GetRight[]; [] _ br.AddPair[[left, right]]; ENDLOOP; IF in.GetChar[].ORD # lastPos THEN ERROR; RETURN}; GetSeq: PROC [key: CHAR, space: Sets.Space, oneToOne: BOOL] RETURNS [Sets.Value] ~ { startIdx: INT ~ in.GetIndex[]; len: INT; seq: Seq; IF in.GetChar[] # key THEN ERROR; len _ GetInt[]; seq _ CreateSeq[len: len, oneToOne: oneToOne, dense: TRUE, rightSpace: space]; FOR i: INT IN [0 .. len) DO seq.AddNewPair[[IV[i], GetOldV[]]]; ENDLOOP; IF in.GetChar[].ORD # lastPos THEN ERROR; RETURN seq.BV}; GetIndex: PROC [Create: PROC RETURNS [REF ANY]] RETURNS [Sets.Value] ~ { idx: INT ~ GetInt[]; IF idx>0 THEN RETURN refs.ApplyI[idx-1].Val; {ref: REF ANY ~ Create[]; refs.AddNewIA[-idx - 1, ref]; RETURN [AV[ref]]}}; GetOldV: PROC RETURNS [Sets.Value] ~ {RETURN GetIndex[NIL]}; GetCellType: PROC RETURNS [Sets.Value] ~ { Create: PROC RETURNS [REF ANY] ~ { ct: CellType ~ CreateCellType[d, leaf, emptyRange2, emptyRopeSet]; IF NOT d.cellTypes.RemA[ct] THEN ERROR; RETURN [ct]}; RETURN GetIndex[Create]}; GetPort: PROC RETURNS [Sets.Value] ~ { Create: PROC RETURNS [REF ANY] ~ {RETURN [NEW [PortPrivate _ []]]}; RETURN GetIndex[Create]}; GetWire: PROC RETURNS [Sets.Value] ~ { Create: PROC RETURNS [REF ANY] ~ {RETURN CreateBareWire[d]}; RETURN GetIndex[Create]}; GetInst: PROC RETURNS [Sets.Value] ~ { Create: PROC RETURNS [REF ANY] ~ {RETURN CreateBareInstance[d, [0, 0]]}; RETURN GetIndex[Create]}; GetSub: PROC RETURNS [Sets.Value] ~ { RETURN GetSeq['O, d.eSpace, TRUE]}; GetCellTypeDetails: PROC [ctv: Sets.Value] ~ { ct: CellType ~ NARROW[ctv.VA]; intKey: [0 .. 8) ~ GetInt[]; bits: PACKED ARRAY [0 .. 3) OF BOOL ~ LOOPHOLE[intKey]; pacify.PutF["\n%g: ", [integer[cellTypeN]]]; cellTypeN _ cellTypeN + 1; Sets.PrintSet[d.CTNames[ct], pacify]; AddBiRel[ct.fullName[p], 'P, GetOldV, GetSteppyName]; AddSet[ct.isDeduced[p][FALSE], 'S, GetOldV]; AddSet[ct.isDeduced[p][TRUE], 'T, GetOldV]; AddSet[ct.isDeduced[w][FALSE], 'U, GetOldV]; AddSet[ct.isDeduced[w][TRUE], 'V, GetOldV]; ct.bbox _ GetRange2[]; IF bits[1] THEN { DupExp: PROC [pair: BiRels.Pair] RETURNS [BOOL] ~ { p: Port ~ NARROW[pair[left].VA]; w: Wire ~ NARROW[pair[right].VA]; [] _ w.conns.AddAA[p, ct]; RETURN [FALSE]}; FinishCreatingUnorganized[ct]; AddBiRel[ct.fullName[w], 'Q, GetOldV, GetSteppyName]; AddBiRel[ct.fullName[i], 'R, GetOldV, GetSteppyName]; AddBiRel[ct.asu.exports, 'a, GetOldV, GetOldV]; EnumSet[ct.Subcells, 'b, GetSubcellDetails]; IF ct.asu.exports.Scan[DupExp].found THEN ERROR; }; IF bits[0] THEN { ect: CellType ~ ct.EltType; size2: Int2 ~ GetInt2[]; basePeriod: Int2 ~ GetInt2[]; akey: INT ~ GetInt[]; fXfm: Fn--phase _ Transform-- _ nilBiRel; offsets: OffsetSeq _ NIL; IF akey MOD 2 # 0 THEN { fXfm _ BiRels.CreateHashTable[[int2s, xfmSpace]]; AddBiRel[fXfm, 'e, GetIntV, GetIntV]}; IF akey MOD 4 > 1 THEN { len: INT ~ GetInt[]; offsets _ NEW [OffsetSequence[len]]; FOR i: NATURAL IN [0 .. NATURAL[len]) DO o0: Int2 ~ GetInt2[]; offsets[i] _ [o0: o0, o1: GetInt2[]]; ENDLOOP; }; {a: Array ~ CreateArrayPart[ct, ect, size2, basePeriod, fXfm, offsets]; GetStatEdge: PROC RETURNS [sev: Sets.Value] ~ { v0: StatVertex ~ GetStatVert[]; v1: StatVertex ~ GetStatVert[]; delta: Int2 ~ GetInt2[]; se: StatEdge ~ NEW [StatEdgePrivate _ [d.PWRank[v0.port], delta]]; IF se.rank # d.PWRank[v1.port] THEN ERROR; a.statrep.portEdge[FALSE].AddNewAA[v0.port, se]; a.statrep.portEdge[TRUE].AddNewAA[v1.port, se]; a.statrep.svEdge[FALSE].AddNewPair[[SvV[v0], AV[se]]]; a.statrep.svEdge[TRUE].AddNewPair[[SvV[v1], AV[se]]]; RETURN [AV[se]]}; GetStatVert: PROC RETURNS [StatVertex] ~ { port: Port ~ NARROW[GetOldV[].VA]; phase: Int2 ~ GetInt2[]; RETURN [[port, phase]]}; GetStatVertV: PROC RETURNS [Sets.Value] ~ {RETURN GetStatVert[].SvV}; GetDumbWire: PROC RETURNS [Sets.Value] ~ { Create: PROC RETURNS [REF ANY] ~ {RETURN [CreateBareDumbWire[ct]]}; RETURN GetIndex[Create]}; GetDWDetails: PROC [dwv: Sets.Value] ~ { dw: DumbWire ~ NARROW[dwv.VA]; AddBiRel[dw.eps, 'k, GetOldV, GetIntV, FALSE]; {kidsKey: INT ~ GetInt[]; SELECT kidsKey FROM 0 => NULL; 1 => { dw.children _ BiRels.VB[GetSeq['l, a.dumrep.dwSpace, FALSE]]; }; ENDCASE => ERROR; RETURN}}; FillinDW: PROC [dwv: Sets.Value] RETURNS [BOOL] ~ { dw: DumbWire ~ NARROW[dwv.VA]; PerEP: PROC [pair: BiRels.Pair] RETURNS [BOOL] ~ { ep: Port ~ NARROW[pair[left].VA]; cai: INT ~ pair[right].VI; dws: RefBiRel--cai _ DumbWire-- ~ LichenArrayPrivate.GetDumbWires[a, ep, TRUE]; dws^.AddNewIA[cai, dw]; RETURN [FALSE]}; PerKid: PROC [pair: BiRels.Pair] RETURNS [BOOL] ~ { index: INT ~ pair[left].VI; kid: DumbWire ~ NARROW[pair[right].VA]; IF kid.parent#NIL THEN ERROR; kid.parent _ dw; kid.index _ index; RETURN [FALSE]}; IF dw.eps.Scan[PerEP].found THEN ERROR; IF dw.children#nilBiRel AND dw.children.Scan[PerKid].found THEN ERROR; RETURN [FALSE]}; SetArrayPart[ct, ect, a]; FinishedMakingArrayConnections[ct]; AddSet[a.statrep.edges, 'f, GetStatEdge]; AddBiRel[a.statrep.apToPAI, 'g, GetOldV, GetStatVertV]; AddSet[a.dumrep.wires, 'h, GetDumbWire]; EnumSet[a.dumrep.wires, 'i, GetDWDetails]; AddBiRel[a.dumrep.apToWire, 'j, GetOldV, GetOldV]; IF a.dumrep.wires.Scan[FillinDW].found THEN ERROR; }}; IF bits[2] THEN { t: Transistor ~ NEW [TransistorPrivate _ [NIL]]; t.type _ GetRope[]; t.length _ GetInt[]; t.width _ GetInt[]; t.area _ GetInt[]; t.perimeter _ GetInt[]; ct.asTrans _ t; }; RETURN}; GetSubcellDetails: PROC [civ: Sets.Value] ~ { ci: CellInstance ~ NARROW[civ.VA]; DupConn: PROC [pair: BiRels.Pair] RETURNS [BOOL] ~ { p: Port ~ NARROW[pair[left].VA]; w: Wire ~ NARROW[pair[right].VA]; [] _ w.conns.AddAA[p, ci]; RETURN [FALSE]}; ci.offset _ GetInt2[]; AddBiRel[ci.conns, 'c, GetOldV, GetOldV, FALSE]; IF ci.conns.Scan[DupConn].found THEN ERROR; RETURN}; IF pacify=NIL THEN pacify _ IO.noWhereStream; version _ GetInt[]; IF NOT version IN [vMin .. vMax] THEN ERROR; in.SetIndex[5]; tail _ GetInt[]; in.SetIndex[tail]; IF NOT in.GetTokenRope[IO.IDProc].token.Equal["paSsword"] THEN ERROR; IF NOT in.GetChar[]=' THEN ERROR; nRefs _ GetInt[]; nRopes _ GetInt[]; nSteplists _ GetInt[]; maxRopeLen _ GetInt[]; nCellTypes _ GetInt[]; IF NOT in.EndOf[] THEN ERROR; pacify.PutF["Total: %g cell types\n", [integer[nCellTypes]]]; refs _ CreateSeq[len: nRefs, rightSpace: SetBasics.refs]; ropes _ CreateSeq[len: nRopes, rightSpace: SetBasics.ropes[TRUE]]; steplists _ CreateSeq[len: nSteplists, rightSpace: steplistSpace]; steplists.AddNewIA[0, NIL]; refs.AddNewIA[0, NIL]; in.SetIndex[10]; AddSet[dNames, 'A, GetRopeV]; d _ CreateDesign[dNames]; d.inheritNames _ VAL[CARDINAL[GetInt[]]]; rootName _ GetRope[]; d.scale _ GetReal[]; AddSet[d.cellTypes, 'B, GetCellType]; AddSet[d.labelCellTypes, 'Z, GetOldV]; AddBiRel[d.cct[p], 'C, GetPort, GetOldV]; AddBiRel[d.cct[w], 'D, GetWire, GetOldV]; AddBiRel[d.cct[i], 'E, GetInst, GetOldV]; AddBiRel[d.sub, 'F, GetOldV, GetSub]; AddBiRel[d.ciType, 'J, GetOldV, GetOldV]; AddBiRel[d.ctName, 'K, GetOldV, GetRopeV]; AddBiRel[d.arrayElt, 'L, GetOldV, GetOldV]; IF version < 5 THEN AddBiRel[d.ciXfm, 'M, GetOldV, GetIntV] ELSE SELECT GetInt[] FROM 0 => d.ciXfm _ nilBiRel; 1 => AddBiRel[d.ciXfm, 'M, GetOldV, GetIntV]; ENDCASE => ERROR; EnumSet[d.cellTypes, 'N, GetCellTypeDetails]; pacify.PutRope["\n"]; IF in.GetIndex[] # tail THEN ERROR; IF (d.root _ d.FetchCellType[rootName]) = NIL THEN ERROR; {PerSub: PROC [pair: BiRels.Pair] RETURNS [BOOL] ~ { parent: PW ~ pair[left].VA; kids: Seq ~ BiRels.VB[pair[right]]; [] _ d.parent.AddSet[BiRels.CreateProduct[[kids.SetOn[right], Sets.CreateSingleA[parent, d.eSpace]]]]; RETURN [FALSE]}; IF d.sub.Scan[PerSub].found THEN ERROR}; RETURN}; END. XLichenFileIn.Mesa Last tweaked by Mike Spreitzer on July 25, 1988 12:01:50 pm PDT ΚD– "cedar" style˜codešœ™Kšœ?™?—K˜KšΟk œœ œv˜ K˜šΟn œœ˜Kšœœœl˜ŠK˜—K˜Kš œœœ œœ&žœ˜bK˜Kšœœ˜Kšœœ˜K˜Kšœ œœœ˜Kšœ œœœ˜K˜šž œœ œ œœœœ˜RKšœœœœ˜(Kš œ œ œœ œ˜1Kšœ˜Kšœ1œ˜8Kšœ œ˜KšœBœ˜KKšœ œ˜šžœœœœ˜Kšœœœ˜Kšœ˜šœ˜šœ ˜ Kšœœœœ œœ œœœ˜yKšœ˜%—Kšœ œ˜Kšœœ/œ˜G—K˜—Kš žœœœœœ ˜=šžœœœœ˜ Kšœœ ˜Kš œœœœœ˜3Kšœœ ˜Kšœœœ˜Kš œžœœœœœ˜6Kšœœ˜&K˜Kšœ˜—Kš žœœœœœ˜?š žœœœœœ˜+Kšœ%œœœœœœ˜NKšœ˜—šžœœœ ˜ Kšœœ ˜Kšœ žœ˜—šž œœœ ˜$K˜K˜šœ˜ K˜%K˜)——šž œœœ˜,Kšœœ ˜Kš œ œœœœ˜;K˜ š œœœœœ˜&K˜Kšœœœ ˜Kšœœ˜—Kšœœ˜.Kšœ%˜%Kšœ ˜—šž œœœ˜,Kšœœ ˜Kšœ$˜$Kšœ˜!—š žœœœžœœœ˜JKšœ œ˜Kšœœœ˜!K˜šœœ ˜$K˜Kšœœœœ˜"Kšœ˜—Kšœœ œœ˜)Kšœ˜—š žœœœžœœ˜?Kšœ œ˜Kšœœœ˜!šœœ ˜$K˜Kšœœœœ˜%K˜ Kšœ˜—Kšœœ œœ˜)Kšœ˜—šžœœœ žœœœœœ˜iKšœ œ˜Kšœœœ˜!Kšœœ˜ šœœ ˜$Kšœ˜Kšœ˜K˜Kšœ˜—Kšœœ œœ˜)Kšœ˜—š žœœœœœ˜TKšœ œ˜Kšœœ˜ K˜ Kšœœœ˜!K˜Kšœ5œ˜Nšœœœ ˜Kšœœ˜#Kšœ˜—Kšœœ œœ˜)Kšœœ˜—šžœœžœœœœœœ˜HKšœœ ˜Kšœœœ˜,Kšœœœ ˜K˜Kšœœ ˜—Kš žœœœœ œ˜<šž œœœ˜*š žœœœœœ˜"KšœB˜BKšœœœœ˜'Kšœ˜ —Kšœ˜—šžœœœ˜&Kšžœœœœœœœ˜CKšœ˜—šžœœœ˜&Kš žœœœœœœ˜