IFUPWContStaticPLA.mesa
Copyright c 1985 by Xerox Corporation. All rights resersed.
Last Edited by: Curry, January 28, 1986 4:47:16 pm PST
DIRECTORY
CD,
CDFrame,
CDPinObjects,
PLAOps,
PW,
IFUPWControl,
IO,
PWPins,
REFBit,
Rope;
IFUPWContStaticPLA: CEDAR PROGRAM
IMPORTS CD, CDFrame, CDPinObjects, IFUPWControl, IO, PLAOps, PW, PWPins, REFBit, Rope
EXPORTS IFUPWControl =
BEGIN
MakeStaticPLASection: PUBLIC PROC
[desc: IFUPWControl.PLADescription] = {
log.PutF["\n Make Static PLA Section %g", IO.rope[desc.drFrame.shell.name]];
GetOuts  [desc];
GetBins  [desc];
MakePla  [desc];
MakeOutDrs [desc]};
SDesc: TYPE = RECORD[bins: REF Bins, outs: REF Outs];
Use: TYPE = RECORD[cols, wt: INT,  seq: SEQUENCE size: CARDINAL OF  BOOL];
SSInt: TYPE = RECORD[      seq: SEQUENCE size: CARDINAL OF REF SInt];
SInt: TYPE = RECORD[      seq: SEQUENCE size: CARDINAL OF  INT];
Bins: TYPE = RECORD[      seq: SEQUENCE size: CARDINAL OF REF Use];
Outs: TYPE = RECORD[ttt: PLAOps.PLA, seq: SEQUENCE size: CARDINAL OF REF OUse];
OUse: TYPE = RECORD[lv: INT,   seq: SEQUENCE size: CARDINAL OF REF TermUse];
TermUse:  TYPE = RECORD[term: PLAOps.Term, bin: INT, use: REF Use];
NewUse: PROC[size: INT] RETURNS [use: REF Use] = {use ← NEW[Use[size]];
use.cols ← 0; use.wt ← 0; FOR bit: INT IN [0..size) DO use[bit] ← FALSE ENDLOOP};
NewSInt: PROC[size: INT, init: INT ← 0] RETURNS [seq: REF SInt] =
{seq ← NEW[SInt[size]]; FOR ii: INT IN [0..size) DO seq[ii] ← init ENDLOOP};
NewSSInt: PROC[size0, size1: INT] RETURNS [seq: REF SSInt] = {
seq ← NEW[SSInt[size0]];
FOR ii: INT IN [0..size0) DO seq[ii] ← NewSInt[size1] ENDLOOP};
NewBins: PROC[size0, size1: INT] RETURNS [seq: REF Bins] = {
seq ← NEW[Bins[size0]];
FOR ii: INT IN [0..size0) DO seq[ii] ← NewUse[size1] ENDLOOP};
GetOuts: PROC[desc: IFUPWControl.PLADescription]= {
sd:   REF SDesc ← NEW[SDesc];
TListSeq: TYPE = RECORD[SEQUENCE size: CARDINAL OF PLAOps.TermList];
nofBins:  INT ← desc.nofTermCols;
nofTerms: INT ← 0;
iFormat: REFBit.Format ← REFBit.Desc[desc.ttt.data].bitForm;
oFormat: REFBit.Format ← REFBit.Desc[desc.ttt.out].bitForm;
tListSeq: REF TListSeq  ← NEW[TListSeq[oFormat.size] ];
sd.outs  ← NEW[Outs[oFormat.size] ];
sd.outs.ttt  ← desc.ttt;
desc.data  ← sd;
IF desc.plaType=decoder THEN desc.nofOrCols ← 0;
FOR out: INT IN [0..desc.smlToBigOut.size) DO
bigOut:  INT ← desc.smlToBigOut[out];
tListSeq[out] ← PLAOps.CopyTermListForField[desc.ttt.termList, oFormat[bigOut].firstBit, 1];
[ ] ← PLAOps.ConvertTermListToCompleteSum[tListSeq[out], TRUE, TRUE, log];
[ ] ← PLAOps.FindAMinimalCover[tListSeq[out], 10, log];
nofTerms ← MAX[nofTerms, tListSeq[out].length];
ENDLOOP;
IF desc.plaType=decoder THEN desc.nofTermCols ← nofBins ← nofTerms;
FOR out: INT IN [0..desc.smlToBigOut.size) DO
term:   PLAOps.Term;
level:   INT;
level   ← IF desc.plaType=decoder
THEN 0 ELSE (tListSeq[out].length+nofBins-2)/nofBins;
nofTerms  ← IF level=0 THEN nofBins ELSE level*nofBins+1;
sd.outs[out]  ← NEW[OUse[nofTerms]];
sd.outs[out].lv ← level;     -- = number of rows to be ORed with top row
term   ← tListSeq[out].begin;
FOR termIdx: INT IN [0..nofTerms) DO
use: REF Use  ← NEW[Use[iFormat.size]];
sd.outs[out][termIdx] ← NEW[TermUse ← [term, -1, use]];
use.wt ← 0;
FOR bit: INT IN [0..use.size) DO
use[bit] ← desc.fullWidthTerms OR
(term#NIL AND PLAOps.GetInQrt[term, iFormat[bit].firstBit]#dontcare);
IF use[bit] THEN use.wt ← use.wt + 1;
ENDLOOP;
IF term#NIL THEN term ← term.next;
ENDLOOP;
ENDLOOP };
GetBins: PROC[desc: IFUPWControl.PLADescription]={
sd:   REF SDesc ← NARROW[desc.data];
useSize: INT  ← sd.outs[0][0].use.size;
nofBins: INT  ← desc.nofTermCols;
sd.bins    ← NewBins[nofBins, useSize];
FOR out: INT IN [0..sd.outs.size) DO
nofTerms: INT  ← sd.outs[out].size;
minTBins: REF SInt ← NewSInt[nofTerms];
curTBins:  REF SInt ← NewSInt[nofTerms, -1];
minTotalWt: INT  ← useSize*nofTerms+1;
Enum: PROC[left, wt: INT, termBins: REF SInt] = {
tempUse: REF Use;
bin: INT ← (nofTerms-left) MOD nofBins;
IF wt >= minTotalWt THEN RETURN;
IF left=0 THEN {
FOR tt: INT IN [0..nofTerms) DO minTBins[tt] ← termBins[tt]; ENDLOOP;
minTotalWt ← wt; RETURN};
tempUse ← NewUse[useSize];
FOR sel: INT DECREASING IN [0..left) DO
cnt, term: INT ← 0;
cnt ← sel;
FOR term ← 0, term+1 DO
IF termBins[term]>=0 THEN LOOP; IF cnt=0 THEN EXIT; cnt ← cnt-1 ENDLOOP;
UseOr[sd.bins[bin],   sd.bins[bin], tempUse];
UseOr[sd.outs[out][term].use, sd.bins[bin], sd.bins[bin]];
termBins[term] ← bin;
Enum[left-1, wt + sd.bins[bin].wt - tempUse.wt, termBins];
UseOr[tempUse,   tempUse, sd.bins[bin]];
termBins[term] ← -1;
ENDLOOP};
IF desc.fullWidthTerms THEN {
FOR term: INT IN [0..nofTerms)
DO sd.outs[out][term].bin ← term MOD nofBins ENDLOOP;
LOOP};
Enum[nofTerms, 0, curTBins];
FOR term: INT IN [0..nofTerms) DO
UseOr[sd.outs[out][term].use, sd.bins[minTBins[term]], sd.bins[minTBins[term]]];
sd.outs[out][term].bin ← minTBins[term] ENDLOOP;
ENDLOOP;
FOR out: INT IN [0..sd.outs.size) DO   -- sd.bins[bin].cols used to determine OR columns/bin
FOR bin: INT IN [0..nofBins) DO
binCnt: INT ← 0;
IF desc.fullWidthTerms THEN {
FOR bit: INT IN [0..useSize) DO sd.bins[bin][bit] ← TRUE ENDLOOP;
sd.bins[bin].wt ← useSize};
FOR level: INT IN [1..sd.outs[out].lv] DO
IF GetTerm[sd.outs, out, level, bin]#NIL THEN binCnt ← binCnt + 1 ENDLOOP;
sd.bins[bin].cols ← MAX[sd.bins[bin].cols, binCnt, desc.nofOrCols] ENDLOOP;
ENDLOOP};
MakePla: PROC[desc: IFUPWControl.PLADescription] = {
sd:    REF SDesc ← NARROW[desc.data];
rowType:  IFUPWControl.RowType ← header;
out:   INT ← 0;
tileRows:  REF StaticTiles ← GetStaticPLATiles[];
useSize:  INT    ← sd.bins[0].size;
index:   INT ← 0;
iForm:  REFBit.Format ← REFBit.Desc[sd.outs.ttt.data].bitForm;
tiles:   REF StaticTileRow;
levelRng:  INT;
nofOrTerms: REF SInt;
v:    Variety ← IF desc.plaType=static THEN s ELSE d;
seg,  row,  sec:     CD.Object ← NIL;
segList, rowList, secList, colList: PW.ListOb ← NIL;
DO
rowType ← IF out = sd.outs.size THEN header
ELSE IF rowType=header THEN footer
ELSE IF rowType=footer THEN conn
ELSE IF (out MOD desc.termsPerHeader) = 0 THEN header ELSE conn;
levelRng  ← IF rowType = conn THEN sd.outs[out].lv ELSE 0; -- OR sub rows
tiles   ← tileRows[rowType];
nofOrTerms ← NewSInt[sd.bins.size];
IF rowType = conn THEN FOR tt: INT IN [0..sd.outs[out].size) DO
IF sd.outs[out][tt].term=NIL THEN LOOP;
nofOrTerms[sd.outs[out][tt].bin]←MIN[sd.outs[out].lv,nofOrTerms[sd.outs[out][tt].bin]+1];
ENDLOOP;
FOR level: INT IN [0..levelRng] DO
init: BOOLFALSE;
rowList ← CONS[tiles[v][leftSide], NIL];
FOR bin: INT IN [0..sd.bins.size) DO
term: PLAOps.Term;
IF level#0 THEN init ← FALSE;
term ← IF rowType = conn THEN GetTerm[sd.outs, out, level, bin] ELSE NIL;
IF nofOrTerms[bin] > sd.bins[bin].cols THEN ERROR;
FOR index IN[0..useSize) DO
IF NOT sd.bins[bin][index] THEN LOOP;
segList ← CONS[ IF term=NIL
THENIF ~init THEN tiles[v][andFalse] ELSE tiles[v][andPass]
ELSE SELECT PLAOps.GetInQrt[term, iForm[index].firstBit] FROM
zero  => IF ~init THEN tiles[v][andIfNot] ELSE tiles[v][andNot],
one  => IF ~init THEN tiles[v][andIf]  ELSE tiles[v][and],
ENDCASE => IF ~init THEN tiles[v][andTrue] ELSE tiles[v][andPass], segList];
init ← TRUE;
ENDLOOP;
FOR index ← 0, index+1 WHILE index < nofOrTerms[bin] DO
segList ← CONS[ tiles[v][SELECT index+1 FROM
< level => orBlank,
= level => orConn,
> level => IF level=0 THEN or ELSE orPass,
ENDCASE => ERROR], segList]; ENDLOOP;
THROUGH [nofOrTerms[bin]..sd.bins[bin].cols)
DO segList ← CONS[ tiles[v][orBlank] , segList] ENDLOOP;
segList ← CONS[ tiles[v][ IF level#0
THEN innerRt
ELSEIF bin+1 < sd.bins.size
THEN innerPass
ELSE outerRt ], segList];
seg ← PW.AbutListX[desc.design, PW.Reverse[segList]];
segList ← NIL;
rowList ← CONS[ seg, rowList];
ENDLOOP;
row ← PW.AbutListX[desc.design, PW.Reverse[rowList]];
rowList ← NIL;
secList ← CONS[ row, secList];
ENDLOOP;
sec ← PW.AbutListY[desc.design, PW.Reverse[secList]];
secList ← NIL;
colList ← CONS[ sec, colList];
IF rowType=conn THEN out ← out+1 ELSE IF out = sd.outs.size THEN EXIT;
ENDLOOP;
desc.cell ← PW.AbutListY[desc.design, PW.Reverse[colList]];
ReNameInputPins[desc]};
MakeOutDrs: PROC [desc: IFUPWControl.PLADescription] = {
SetNewOfCnt: PROC
[drRowType: IFUPWControl.RowType, driver: REF IFUPWControl.DriveRec] = {
new[cnt] ← CDFrame.NewObjectFrame[
IFUPWControl.DriverCell[desc.plaType, drRowType, driver, desc.design]];
cnt ← cnt+1};
sd:  REF SDesc ← NARROW[desc.data];
new: CDFrame.Frame;
cnt: INT ← 2;
FOR out: INT IN [0..sd.outs.size) DO
IF out IN [1..sd.outs.size-1) AND (out MOD desc.termsPerHeader)=0 THEN cnt ← cnt+2;
cnt ← cnt + sd.outs[out].lv+1 ENDLOOP;
new ← CDFrame.NewFrame[cnt, y, desc.name.Cat["-OutDr"]];
cnt ← 0;
SetNewOfCnt[footer, NIL];
FOR out: INT IN [0..sd.outs.size) DO
IF out IN [1..sd.outs.size-1) AND (out MOD desc.termsPerHeader)=0 THEN
{SetNewOfCnt[header, NIL]; SetNewOfCnt[footer, NIL]};
FOR term: INT IN [0..sd.outs[out].lv] DO
SetNewOfCnt[IF term=0 THEN conn ELSE blank, desc.connSeq[out].dr] ENDLOOP;
ENDLOOP;
SetNewOfCnt[header, NIL];
desc.drFrame ← new};
DeleteUnusedStaticInDrs: PUBLIC PROC
[desc: IFUPWControl.PLADescription, drs: CDFrame.Frame] = {
enum: CDFrame.EnumProc = {
IF tempUse[oldIdx] THEN
{new[newIdx] ← frame; new[newIdx].father ← new; newIdx ← newIdx +1};
oldIdx ← oldIdx+1};
sd:   REF SDesc ← NARROW[desc.data];
oldIdx:  INT   ← 0;
newIdx:  INT   ← 0;
useSize: INT   ← sd.bins[0].size;
tempUse: REF Use  ← NewUse[useSize];
new:  CDFrame.Frame;
FOR bin: INT IN [0..sd.bins.size) DO UseOr[sd.bins[bin], tempUse, tempUse] ENDLOOP;
IF tempUse.wt=useSize THEN RETURN;
new    ← NEW[CDFrame.FrameSeq[tempUse.wt]];
new.shell   ← drs[1].shell;
new.data   ← drs[1].data;
new.father  ← drs[1].father;
new.xory   ← drs[1].xory;
new.unordered ← drs[1].unordered;
new.orient  ← drs[1].orient;
CDFrame.EnumFrameBotOnly[drs[1], enum];
drs[1]    ← new};
UseOr: PROC[useArg0, useArg1, useOr: REF Use] = {
IF useArg0.size#useArg1.size OR useArg1.size#useOr.size THEN ERROR;
useOr.wt ← 0;
FOR bit: INT IN [0..useArg0.size) DO
useOr[bit] ← useArg0[bit] OR useArg1[bit];
IF useOr[bit] THEN useOr.wt ← useOr.wt + 1;
ENDLOOP };
GetTerm: PROC[outs: REF Outs, out, level, bin: INT] RETURNS[term: PLAOps.Term] = {
found: INT ← 0;
FOR tt: INT IN [0..outs[out].size) DO
IF outs[out][tt].bin#bin THEN LOOP;
found ← found+1;
term ← outs[out][tt].term;
IF found = level THEN RETURN[term];
ENDLOOP;
IF found=0 THEN ERROR; -- Just checking, term can be NIL but bin must be represented
IF level#0 THEN ERROR; -- level 0 => last term
IF outs[out].lv#0 AND bin#0 THEN RETURN[NIL];
RETURN[term]}; -- last term for level 0 when outs[out].lv=0 OR bin=0
ReNameInputPins: PROC[desc: IFUPWControl.PLADescription] = {
sd:    REF SDesc ← NARROW[desc.data];
SSRope:  TYPE = RECORD[SEQUENCE size: CARDINAL OF REF SRope];
SRope:  TYPE = RECORD[SEQUENCE size: CARDINAL OF IO.ROPE];
tiles:   REF StaticTiles ← GetStaticPLATiles[];
format:  REFBit.Format ← REFBit.Desc[sd.outs.ttt.data].bitForm;
inName:  REF SSRope ← NEW[SSRope[sd.bins.size]];
inNameInv: REF SSRope ← NEW[SSRope[sd.bins.size]];
v:    Variety ← IF desc.plaType=static THEN s ELSE d;
leftSize:  INTCD.InterestSize[tiles[header][v][leftSide]].x;
andWidth: INTCD.InterestSize[tiles[header][v][and]].x;
orWidth:  INTCD.InterestSize[tiles[header][v][or]].x;
innerSize: INTCD.InterestSize[tiles[header][v][innerRt]].x;
changeProc: PWPins.ChangePinProc ~ {
pos: INT ← leftSize;
oldRope: Rope.ROPE ← CDPinObjects.GetName[oldPin];
in0: BOOL ← Rope.Equal[oldRope, "in0"];
in1: BOOL ← Rope.Equal[oldRope, "in1"];
IF NOT(in0 OR in1) THEN RETURN[oldPin];
FOR bin: INT IN [0..sd.bins.size) DO
index: INT ← (oldPin.location.x-pos)/andWidth;
IF index < inName[bin].size THEN {
CDPinObjects.SetName[oldPin,
IF in1 THEN inNameInv[bin][index] ELSE inName[bin][index]];
RETURN[oldPin]};
pos ← pos + inName[bin].size*andWidth + sd.bins[bin].cols*orWidth + innerSize;
REPEAT FINISHED => ERROR ENDLOOP};
FOR bin: INT IN [0..sd.bins.size) DO
list: LIST OF IO.ROPE ← desc.plaInNames;
in:  INT ← 0;
inName[bin]  ← NEW[SRope[sd.bins[bin].wt]];
inNameInv[bin] ← NEW[SRope[sd.bins[bin].wt]];
FOR bit: INT IN [0..sd.bins[bin].size) DO
IF sd.bins[bin][bit] THEN {
inName  [bin][in] ← list.first;
inNameInv [bin][in] ← list.rest.first;
in ← in+1};
list ← list.rest.rest;
ENDLOOP;
ENDLOOP;
desc.cell ← PWPins.ChangePins[desc.design, desc.cell, changeProc];
PW.RenameObject[desc.design, desc.cell, desc.name]};
staticTileDesign: CD.Design;
staticTiles:  REF StaticTiles;
StaticTiles:  TYPE = ARRAY IFUPWControl.RowType OF REF StaticTileRow;
StaticTileRow:  TYPE = ARRAY Variety OF StaticTileVar;
StaticTileVar:  TYPE = ARRAY StaticTileType OF CD.Object;
Variety:   TYPE = {s, d}; -- static or decode
StaticTileType : TYPE = {leftSide, andTrue, andFalse, andIf, andIfNot, and, andNot, andPass, or, orNot, orPass, orBlank, orConn, innerPass, innerRt, outerRt};
GetStaticPLATiles: PROC RETURNS [tiles: REF StaticTiles ] = {
tDesign: CD.Design;
IF staticTiles#NIL THEN RETURN[staticTiles];
log.PutRope["\n Initialize static pla tiles"];
tDesign ← staticTileDesign ← PW.OpenDesign["IFUPWControl.dale"];
IF tDesign=NIL THEN
ERROR PW.Error[MissingDesign, "TileSet design not found or empty"];
tiles ← staticTiles ← NEW[StaticTiles];
FOR row: IFUPWControl.RowType IN IFUPWControl.RowType DO
tiles[row] ←NEW[StaticTileRow] ENDLOOP;
tiles [header][s][leftSide]  ← PW.Get[design: tDesign, name: "SPlaHLeftSide" ];
tiles [header][s][andTrue] ←
tiles [header][s][andFalse] ←
tiles [header][s][andIf]  ←
tiles [header][s][andIfNot] ←
tiles [header][s][and]   ←
tiles [header][s][andNot]  ←
tiles [header][s][andPass] ← PW.Get[design: tDesign, name: "SPlaHAnd"  ];
tiles [header][s][or]   ←
tiles [header][s][orNot]  ←
tiles [header][s][orPass]  ←
tiles [header][s][orBlank] ←
tiles [header][s][orConn]  ← PW.Get[design: tDesign, name: "SPlaHOr"    ];
tiles [header][s][innerPass] ←
tiles [header][s][innerRt] ←
tiles [header][s][outerRt]  ← PW.Get[design: tDesign, name: "SPlaHOuterRt" ];
tiles [footer][s][leftSide]  ← PW.FlipY[tDesign, tiles [header][s][leftSide]];
tiles [footer][s][andTrue]  ←
tiles [footer][s][andFalse] ←
tiles [footer][s][andIf]  ←
tiles [footer][s][andIfNot] ←
tiles [footer][s][and]   ←
tiles [footer][s][andNot]  ←
tiles [footer][s][andPass]  ← PW.FlipY[tDesign, tiles [header][s][andPass]];
tiles [footer][s][or]   ←
tiles [footer][s][orNot]  ←
tiles [footer][s][orPass]  ←
tiles [footer][s][orBlank]  ←
tiles [footer][s][orConn]  ← PW.FlipY[tDesign, tiles [header][s][orConn]];
tiles [footer][s][innerPass] ←
tiles [footer][s][innerRt]  ←
tiles [footer][s][outerRt]  ← PW.FlipY[tDesign, tiles [header][s][outerRt]];
tiles [conn][s][leftSide]  ← PW.Get[design: tDesign, name: "SPlaLeftSide"  ];
tiles [conn][s][andTrue]  ← PW.Get[design: tDesign, name: "SPlaAndTrue" ];
tiles [conn][s][andFalse]  ← PW.Get[design: tDesign, name: "SPlaAndFalse" ];
tiles [conn][s][andIf]   ← PW.Get[design: tDesign, name: "SPlaAndIf"  ];
tiles [conn][s][andIfNot]  ← PW.Get[design: tDesign, name: "SPlaAndIfNot" ];
tiles [conn][s][and]   ← PW.Get[design: tDesign, name: "SPlaAnd"   ];
tiles [conn][s][andNot]  ← PW.Get[design: tDesign, name: "SPlaAndNot"  ];
tiles [conn][s][andPass]  ← PW.Get[design: tDesign, name: "SPlaAndPass"  ];
tiles [conn][s][or]    ← PW.Get[design: tDesign, name: "SPlaOr"    ];
tiles [conn][s][orNot]   ← PW.Get[design: tDesign, name: "SPlaOrNot"  ];
tiles [conn][s][orPass]  ← PW.Get[design: tDesign, name: "SPlaOrPass"  ];
tiles [conn][s][orBlank]  ← PW.Get[design: tDesign, name: "SPlaOrBlank"  ];
tiles [conn][s][orConn]  ← PW.Get[design: tDesign, name: "SPlaOrConn"  ];
tiles [conn][s][innerPass] ← PW.Get[design: tDesign, name: "SPlaInnerPass" ];
tiles [conn][s][innerRt]  ← PW.Get[design: tDesign, name: "SPlaInnerRt"  ];
tiles [conn][s][outerRt]  ← PW.Get[design: tDesign, name: "SPlaOuterRt"  ];
FOR type: StaticTileType IN StaticTileType DO
tiles[header] [d][type] ← tiles[header] [s][type];
tiles[footer] [d][type] ← tiles[footer]  [s][type] ENDLOOP;
tiles [header][d][innerPass] ←
tiles [header][d][innerRt] ←
tiles [header][d][outerRt] ← PW.Get[design: tDesign, name: "DPlaHRt" ];
tiles [footer][d][innerPass] ←
tiles [footer][d][innerRt]  ←
tiles [footer][d][outerRt]  ← PW.FlipY[tDesign, tiles [header][d][outerRt]];
tiles [conn][d][leftSide]  ← PW.Get[design: tDesign, name: "DPlaLeftSide"  ];
tiles [conn][d][andTrue]  ← PW.Get[design: tDesign, name: "DPlaAndTrue" ];
tiles [conn][d][andFalse]  ← PW.Get[design: tDesign, name: "DPlaAndFalse" ];
tiles [conn][d][andIf]   ← PW.Get[design: tDesign, name: "DPlaAndIf"  ];
tiles [conn][d][andIfNot]  ← PW.Get[design: tDesign, name: "DPlaAndIfNot" ];
tiles [conn][d][and]   ← PW.Get[design: tDesign, name: "DPlaAnd"   ];
tiles [conn][d][andNot]  ← PW.Get[design: tDesign, name: "DPlaAndNot"  ];
tiles [conn][d][andPass]  ← PW.Get[design: tDesign, name: "DPlaAndPass"  ];
tiles [conn][d][or]   ←
tiles [conn][d][orNot]   ←
tiles [conn][d][orPass]  ←
tiles [conn][d][orBlank]  ←
tiles [conn][d][orConn]  ← tiles[conn][s][or];
tiles [conn][d][innerPass] ←
tiles [conn][d][innerRt]  ←
tiles [conn][d][outerRt]  ← PW.Get[design: tDesign, name: "DPlaRt"   ];
}; 
log: IO.STREAM ← CDFrame.GetLog[];
END.