LichenFileIn.Mesa
Last tweaked by Mike Spreitzer on November 29, 1988 7:36:57 pm PST
DIRECTORY AbSets, BiRels, FS, IntStuff, IO, LichenArrayPrivate, LichenDataOps, LichenDataStructure, LichenFiling, LichenIntBasics, PBasics, Process, RefText, Rope, SetBasics;
LichenFileIn: CEDAR PROGRAM
IMPORTS AbSets, BiRels, FS, IO, LichenArrayPrivate, LichenDataOps, LichenDataStructure, LichenIntBasics, PBasics, Process, Rope, SetBasics
EXPORTS LichenFiling
=
BEGIN OPEN IS:IntStuff, LIB:LichenIntBasics, LIB, LichenDataStructure, LichenDataOps, Sets:AbSets;
vMin: INTEGER ← 10;
vMax: INTEGER ← 11;
firstNeg: BYTE ~ BYTE.LAST/2+1;
lastPos: BYTE ~ BYTE.LAST/2;
ReadDesign: PUBLIC PROC [fileName: ROPE, pacify: IO.STREAMNIL] 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: BOOLTRUE] ~ {
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, 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]};
GetCellTypeBBox: PROC [ctv: Sets.Value] ~ {
ct: CellType ~ NARROW[ctv.VA];
ct.bbox ← GetRange2[];
RETURN};
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];
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 b 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 b 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];
{bits: [0 .. 3] ~ GetInt[]; d.inheritNames ← VAL[bits MOD 2]; d.physd ← bits>1};
rootName ← GetRope[];
d.scale ← GetReal[];
AddSet[d.cellTypes, 'B, GetCellType];
AddSet[d.labelCellTypes, 'Z, GetOldV];
IF version >= 11 THEN AddSet[d.crossedCellTypes, 'Y, GetOldV] ELSE pacify.PutRope["( assuming no crossed cell types )"];
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 d.physd THEN {
AddBiRel[d.ciXfm, 'M, GetOldV, GetIntV];
EnumSet[d.cellTypes, 'G, GetCellTypeBBox]}
ELSE d.ciXfm ← nilBiRel;
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.