IFUCoreCtlStatic.mesa
Copyright c 1985 by Xerox Corporation. All rights resersed.
Last Edited by: Curry, September 19, 1986 1:40:51 pm PDT
DIRECTORY CD, CDSymbolicObjects, Core, CoreBlock, CoreFrame, CoreLibrary, CoreName, PLAOps, PW, IFUCoreCells, IFUCoreCtl, IFUCoreDrive, IO, PWPins, REFBit, Rope;
IFUCoreCtlStatic: CEDAR PROGRAM
IMPORTS CD, CDSymbolicObjects, CoreBlock, CoreFrame, CoreLibrary, CoreName, PLAOps, PW, IFUCoreCells, IFUCoreDrive, IO, PWPins, REFBit, Rope
EXPORTS IFUCoreCtl =
BEGIN
ROPE:    TYPE = Core.ROPE;
PLADescription: TYPE = IFUCoreCtl.PLADescription;
RowType:  TYPE = IFUCoreDrive.RowType;
Drive:    TYPE = IFUCoreDrive.Drive;
Drives:   TYPE = IFUCoreDrive.Drives;
DriveRec:   TYPE = IFUCoreDrive.DriveRec;
Signal: SIGNAL = CODE;
MakeStaticPLA: PUBLIC PROC[desc: PLADescription] = {
log.PutF["\n Make Static PLA %g", IO.rope[desc.name]];
GetOuts  [desc];
GetBins  [desc];
MakePla  [desc];
DressInDrs [desc];
DressOutDrs [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: 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: 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: PLADescription] = {
name: ROPE ← CoreName.RopeNm[desc.name.Cat["Body"]];
IF (desc.outBodyCT ← CoreFrame.ReadFrameCache[name])=NIL THEN {
sd:    REF SDesc ← NARROW[desc.data];
cellType:  Core.CellType;
body:   CD.Object;
rowType:  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
rowList ← CONS[tiles[v][leftSide], NIL];
FOR bin: INT IN [0..sd.bins.size) DO
term: PLAOps.Term;
first: BOOL ← bin=0 OR level#0 OR desc.plaType=decoder;
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;
IF term=NIL
THEN segList ← CONS[
IF ~first
THEN tiles[v][andPass]
ELSEIF levelRng=0 AND desc.plaType#decoder
THEN tiles[v][andTrue] -- for term at right
ELSE tiles[v][andFalse] -- for decoder OR gate
, segList ]
ELSE
segList ← CONS[ SELECT PLAOps.GetInQrt[term, iForm[index].firstBit] FROM
zero  => IF first THEN tiles[v][andIfNot] ELSE tiles[v][andNot],
one  => IF first THEN tiles[v][andIf]  ELSE tiles[v][and],
ENDCASE => IF first THEN tiles[v][andTrue] ELSE tiles[v][andPass], segList];
first ← FALSE;
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[PW.Reverse[segList]];
seg ← PW.SharedAbutListX[PW.Reverse[segList]];
segList ← NIL;
rowList ← CONS[ seg, rowList];
ENDLOOP;
row ← PW.AbutListX[PW.Reverse[rowList]];
row ← PW.SharedAbutListX[PW.Reverse[rowList]];
rowList ← NIL;
secList ← CONS[ row, secList];
ENDLOOP;
sec ← PW.AbutListY[PW.Reverse[secList]];
sec ← PW.SharedAbutListY[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;
body ← PW.AbutListY[PW.Reverse[colList]];
body ← ApplyNames[body, desc];
cellType ← CoreLibrary.ObjCell[body, name, NIL, 0];
CoreBlock.MarkSides[cellType, desc.capSides];
desc.outBodyCT ← CoreFrame.NewFrameCell[0, name, [first: left, cell: cellType] ];
CoreFrame.WriteFrameCache[desc.outBodyCT]} };
in0:   ROPE ← CoreName.RopeNm["in0"];
in1:   ROPE ← CoreName.RopeNm["in1"];
out0:   ROPE ← CoreName.RopeNm["out0"];
out1:   ROPE ← CoreName.RopeNm["out1"];
VDD:   ROPE ← CoreName.RopeNm["VDD"];
GND:   ROPE ← CoreName.RopeNm["GND"];
ApplyNames: PROC[oldObj: CD.Object, desc: PLADescription] RETURNS[newObj: CD.Object]= {
sd:    REF SDesc ← NARROW[desc.data];
SSRope:  TYPE = RECORD[SEQUENCE size: CARDINAL OF REF SRope];
SRope:  TYPE = RECORD[SEQUENCE size: CARDINAL OF ROPE];
tiles:   REF StaticTiles ← GetStaticPLATiles[];
drTiles:  REF IFUCoreDrive.DrTileRec ← IFUCoreDrive.GetDriverTiles[];
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;
headHt:  INTCD.InterestSize[tiles[header ][v][outerRt]].y;
rowHt:  INTCD.InterestSize[tiles[conn ][v][outerRt]].y;
renameProc: PWPins.ChangePinProc ~ {
old: ROPE ← CoreName.RopeNm[CDSymbolicObjects.GetName[oldPin]];
side: CoreBlock.Sides;
loc: INT;
newPin ← oldPin;
[side, loc, ] ← CoreBlock.GetInstSideLocSize[oldObj, newPin];
SELECT old FROM
GND => RETURN;
VDD => RETURN;
out1 => RETURN[NIL];
out0 => {
name: ROPE;
yPos: INT ← headHt;
FOR out: INT IN [0..sd.outs.size) DO
IF out IN [1..sd.outs.size-1) AND (out MOD desc.termsPerHeader)=0 THEN yPos ← yPos + 2*headHt;
IF loc IN (yPos..(yPos + rowHt)) THEN {
name ← IFUCoreDrive.DriveName[desc.connSeq[out].dr, in];
CDSymbolicObjects.SetName[newPin, name];
RETURN};
yPos ← yPos + (sd.outs[out].lv +1)*rowHt;
ENDLOOP;
Signal[]};
in0,
in1 => {
xpos: INT ← leftSize;
FOR bin: INT IN [0..sd.bins.size) DO
index: INT ← (loc-xpos)/andWidth;
IF index < inName[bin].size THEN {
IF old=in0
THEN CDSymbolicObjects.SetName[newPin, inName  [bin][index]]
ELSE CDSymbolicObjects.SetName[newPin, inNameInv [bin][index]];
RETURN};
xpos ← xpos + inName[bin].size*andWidth + sd.bins[bin].cols*orWidth + innerSize;
REPEAT FINISHED => Signal[] ENDLOOP };
ENDCASE => RETURN};
FOR bin: INT IN [0..sd.bins.size) DO
list: LIST OF 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;
newObj ← PWPins.ChangePins[oldObj, renameProc]};
DressInDrs: PROC [desc: PLADescription] = {
sd:  REF SDesc ← NARROW[desc.data];
DeleteUnusedStaticInDrs [desc];
desc.inDrs ← CONS[ NEW[DriveRec ← [drRowType: xfooter]], desc.inDrs];
FOR list: Drives ← desc.inDrs, list.rest WHILE list.rest#NIL DO REPEAT
FINISHED => list.rest ← CONS [NEW[DriveRec ← [drRowType: xheader]], NIL] ENDLOOP};
DressOutDrs: PROC [desc: PLADescription] = {
sd:  REF SDesc ← NARROW[desc.data];
desc.outDrs ← CONS[ NEW[DriveRec ← [drRowType: 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 {
desc.outDrs ← CONS[ NEW[DriveRec ← [drRowType: header]], desc.outDrs];
desc.outDrs ← CONS[ NEW[DriveRec ← [drRowType: footer]], desc.outDrs] };
FOR term: INT IN [0..sd.outs[out].lv] DO
desc.outDrs ← CONS[ NEW[DriveRec ← desc.connSeq[out].dr^], desc.outDrs];
desc.outDrs.first.drRowType ← IF term=0 THEN conn ELSE blank
ENDLOOP;
ENDLOOP;
desc.outDrs ← CONS[ NEW[DriveRec ← [drRowType: header]], desc.outDrs];
desc.outDrs ← IFUCoreDrive.ReverseDrives[desc.outDrs]};
DeleteUnusedStaticInDrs: PUBLIC PROC [desc: PLADescription] = {
sd:    REF SDesc ← NARROW[desc.data];
index:   INT  ← 0;
useSize:  INT  ← sd.bins[0].size;
tempUse:  REF Use ← NewUse[useSize];
drs:   Drives ← NIL;
delIns:  Drives ← NIL;
FOR bin: INT IN [0..sd.bins.size) DO UseOr[sd.bins[bin], tempUse, tempUse] ENDLOOP;
IF tempUse.wt=useSize THEN RETURN;
FOR temp: Drives ← desc.inDrs, temp.rest WHILE temp#NIL DO
IF tempUse[index] THEN drs ← CONS[temp.first, drs];
index ← index +1 ENDLOOP;
desc.inDrs ← IFUCoreDrive.ReverseDrives[drs]};
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
staticTiles:  REF StaticTiles;
StaticTiles:  TYPE = ARRAY 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 ] = {
Get: PROC[name: ROPE] RETURNS[CD.Object] =
{RETURN[PW.Get[design: library.design, name: name ]]};
library: CoreLibrary.Library ← IFUCoreCells.library;
IF staticTiles#NIL THEN RETURN[staticTiles];
log.PutRope["\n Initialize static pla tiles"];
tiles ← NEW[StaticTiles];
FOR row: RowType IN RowType DO
tiles[row] ←NEW[StaticTileRow] ENDLOOP;
tiles [header][s][leftSide]  ← Get[ "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] ← Get[ "SPlaHAnd"  ];
tiles [header][s][or]   ←
tiles [header][s][orNot]  ←
tiles [header][s][orPass]  ←
tiles [header][s][orBlank] ←
tiles [header][s][orConn]  ← Get[ "SPlaHOr"   ];
tiles [header][s][innerPass] ←
tiles [header][s][innerRt] ←
tiles [header][s][outerRt]  ← Get[ "SPlaHOuterRt" ];
tiles [footer][s][leftSide]  ← PW.FlipY[ 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[ 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[ tiles [header][s][orConn]];
tiles [footer][s][innerPass] ←
tiles [footer][s][innerRt]  ←
tiles [footer][s][outerRt]  ← PW.FlipY[ tiles [header][s][outerRt]];
tiles [conn][s][leftSide]  ← Get[ "SPlaLeftSide" ];
tiles [conn][s][andTrue]  ← Get[ "SPlaAndTrue" ];
tiles [conn][s][andFalse]  ← Get[ "SPlaAndFalse" ];
tiles [conn][s][andIf]   ← Get[ "SPlaAndIf"  ];
tiles [conn][s][andIfNot]  ← Get[ "SPlaAndIfNot" ];
tiles [conn][s][and]   ← Get[ "SPlaAnd"  ];
tiles [conn][s][andNot]  ← Get[ "SPlaAndNot" ];
tiles [conn][s][andPass]  ← Get[ "SPlaAndPass" ];
tiles [conn][s][or]    ← Get[ "SPlaOr"    ];
tiles [conn][s][orNot]   ← Get[ "SPlaOrNot"  ];
tiles [conn][s][orPass]  ← Get[ "SPlaOrPass"  ];
tiles [conn][s][orBlank]  ← Get[ "SPlaOrBlank" ];
tiles [conn][s][orConn]  ← Get[ "SPlaOrConn" ];
tiles [conn][s][innerPass] ← Get[ "SPlaInnerPass" ];
tiles [conn][s][innerRt]  ← Get[ "SPlaInnerRt" ];
tiles [conn][s][outerRt]  ← Get[ "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] ← Get[ "DPlaHRt"  ];
tiles [footer][d][innerPass] ←
tiles [footer][d][innerRt]  ←
tiles [footer][d][outerRt]  ← PW.FlipY[ tiles [header][d][outerRt]];
tiles [conn][d][leftSide]  ← Get[ "DPlaLeftSide" ];
tiles [conn][d][andTrue]  ← Get[ "DPlaAndTrue" ];
tiles [conn][d][andFalse]  ← Get[ "DPlaAndFalse" ];
tiles [conn][d][andIf]   ← Get[ "DPlaAndIf"  ];
tiles [conn][d][andIfNot]  ← Get[ "DPlaAndIfNot" ];
tiles [conn][d][and]   ← Get[ "DPlaAnd"  ];
tiles [conn][d][andNot]  ← Get[ "DPlaAndNot" ];
tiles [conn][d][andPass]  ← Get[ "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]  ← Get[ "DPlaRt"   ];
}; 
log: IO.STREAM ← CoreFrame.GetLog[];
END.