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 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];
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};