IFUPWMatch.mesa
Copyright c 1985 by Xerox Corporation. All rights reserved.
Last Edited by Curry, November 4, 1985 11:55:14 am PST
DIRECTORY
CD,
IFUPW,
PW,
Rope;
IFUPWMatch: CEDAR PROGRAM
IMPORTSIFUPW, PW, Rope
EXPORTSIFUPW =
BEGIN OPEN IFUPW;
IFUMatchRow: PUBLIC PROC[
design: CD.Design,
name:  PW.ROPE,
chkFor: LIST OF REF,     -- GND or VDD at byte level of tree
top:  LIST OF REF  ← NIL,
in1:  INT,       -- input must be leftmost column, also used for routing
col2:  INT,       -- blank column needed for routing
col3:  INT,       -- blank column needed for routing
sideOuts: List    ← NIL, -- up to four bytes can be checked, NIL => blank
outsSide: Side    ← right,
bot:  LIST OF REF  ← NIL, -- must be same as top with 3 used columns NIL
rp:   RowParams  ← IFUDataColNSeq ]
RETURNS[cell: CD.Object]= {
ColIndex: PROC[col: Col] RETURNS[index: INT] =
{RETURN[(SELECT col FROM lt=>colLt, rt=>colRt, ENDCASE=>colOut)]};
Level:  TYPE = {sw1, sw2, gate, bot};
Col:  TYPE = {lt, out, rt};
lTop:  ARRAY Level OF LIST OF REF      ← ALL[NIL];
by:  ARRAY Col  OF LIST OF REF      ← ALL[NIL];
wd:  ARRAY Level OF ARRAY Col OF LIST OF REF ← ALL[ALL[NIL]];
tLIST:   LIST OF REF ← NIL;
tList:   List   ← NIL;
byNm:  ARRAY [0..4) OF PW.ROPEALL[NIL]; -- rngByte
colNm:  ARRAY Col OF PW.ROPEALL[NIL];
cellList:  PW.ListOb;
routingTop: CD.Object;
routingBot: CD.Object;
gates:   CD.Object;
colLt:  INT ← in1;
colOut: INT ← col2;
colRt:  INT ← col3;
IF rp.rngByte#4 THEN ERROR; -- see byNm above
IF colLt>colOut OR colLt> colRt THEN ERROR Error["Input must be leftmost column"];
IF colOut>colRt THEN {temp: INT ← colOut; colOut ← colRt; colRt  ← temp};
tList ← sideOuts;
top ← AddGVToLIST[top, FALSE];
bot ← AddGVToLIST[bot, FALSE];
FOR byte: INT IN [0..rp.rngByte) WHILE tList#NIL DO
byNm[byte] ← tList.first; tList ← tList.rest ENDLOOP;
FOR byte: INT DECREASING IN [0..rp.rngByte) DO
by[lt] ← NIL;
IF byNm[byte]#NIL THEN FOR index: INT DECREASING IN [0..rp.rngBit) DO
by[lt]  ← CONS[AppendIndexToRope[index, Rope.Cat[byNm[byte], ".x."]], by[lt]];
ENDLOOP;
wd[sw1][lt] ← CONS[by[lt], wd[sw1][lt]];
ENDLOOP;
FOR byte: INT DECREASING IN [0..rp.rngByte) DO
FOR col: Col IN Col DO by[col] ← NIL ENDLOOP;
IF byNm[byte]#NIL THEN FOR index: INT DECREASING IN [0..rp.rngBit) DO
size: INT ← 1;
FOR val: INT ← index, val/2 WHILE (val MOD 2) = 1 DO size ← size*2 ENDLOOP;
IF size=1
THEN {
colNm[lt] ← AppendIndexToRope[index,   Rope.Cat[byNm[byte], ".x."]];
colNm[rt] ← AppendIndexToRope[index +1,  Rope.Cat[byNm[byte], ".x."]]}
ELSE {colNm[lt] ← colNm[rt] ← NIL};
by[lt]  ← CONS[colNm[lt], by[lt]];
by[rt]  ← CONS[colNm[rt], by[rt]];
ENDLOOP;
wd[sw2][lt]  ← CONS[by[lt], wd[sw2][lt]];
wd[sw2][rt]  ← CONS[by[rt], wd[sw2][rt]];
ENDLOOP;
FOR byte: INT DECREASING IN [0..rp.rngByte) DO
FOR col: Col IN Col DO by[col] ← NIL ENDLOOP;
IF byNm[byte]#NIL THEN FOR index: INT DECREASING IN [0..rp.rngBit) DO
size: INT ← 1;
FOR val: INT ← index, val/2 WHILE (val MOD 2) = 1 DO size ← size*2 ENDLOOP;
IF size=1
THEN {
colNm[lt] ← AppendIndexToRope[index,   Rope.Cat[byNm[byte], ".x."]];
colNm[rt] ← AppendIndexToRope[index +1,  Rope.Cat[byNm[byte], ".x."]]}
ELSE {
colNm[lt] ← AppendIndexToRope[index - size/2, Rope.Cat[byNm[byte], ".g."]];
colNm[rt] ← AppendIndexToRope[index + size/2, Rope.Cat[byNm[byte], ".g."]]};
colNm[out]  ← AppendIndexToRope[index,    Rope.Cat[byNm[byte], ".g."]];
IF (index=(rp.rngBit-1)) THEN colNm[lt] ← colNm[rt] ← colNm[out] ← NIL;
IF (index=(rp.rngBit/2-1)) THEN colNm[out] ← byNm[byte]; -- output colNm
by[lt]  ← CONS[colNm[lt], by[lt]];
by[rt]  ← CONS[colNm[rt], by[rt]];
by[out] ← CONS[colNm[out], by[out]];
ENDLOOP;
wd[gate][lt]  ← CONS[by[lt], wd[gate][lt]];
wd[gate][rt]  ← CONS[by[rt], wd[gate][rt]];
wd[gate][out] ← CONS[by[out], wd[gate][out]];
ENDLOOP;
Construct interfaces
FOR index: INT ← nofVWires-1, index-1 WHILE index >= 0 DO
item: REF ← LISTIndexItem[top, index];
SELECT index FROM
colLt  =>
{FOR lv: Level IN Level DO lTop[lv] ← CONS[wd[lv][lt],  lTop[lv]] ENDLOOP};
colOut  => 
{FOR lv: Level IN Level DO lTop[lv] ← CONS[wd[lv][out], lTop[lv]] ENDLOOP};
colRt =>
{FOR lv: Level IN Level DO lTop[lv] ← CONS[wd[lv][rt],  lTop[lv]] ENDLOOP};
ENDCASE =>
{FOR lv: Level IN Level DO lTop[lv] ← CONS[item,   lTop[lv]] ENDLOOP};
ENDLOOP;
routingTop ← SwitchBoxRow[
design: design,
name:  name.Cat["RtngTop"],
rowType: cmosMet2,
topRP:  rp,
top:  lTop[sw1],
left:  NIL,
right:  NIL,
bot:  lTop[sw2],
botRP:  rp ];
routingBot ← SwitchBoxRow[
design: design,
name:  name.Cat["RtngBot"],
rowType: cmosMet2,
topRP:  rp,
top:  lTop[sw2],
left:  (IF outsSide=left  THEN sideOuts ELSE NIL),
right:  (IF outsSide=right THEN sideOuts ELSE NIL),
bot:  lTop[gate],
botRP:  rp ];
Gate cells
cellList ← NIL;
FOR ii: INT DECREASING IN [0..rp.rngByte*rp.rngBit) DO
nor:  List = LIST["GPNor"];
nand:  List = LIST["GPNand"];
level:  INT ← 0;
chkFor1s: BOOL;
byte, index: INT;
[byte, index] ← ByteBitFromIndex[ii, rp];
FOR val: INT ← index, val/2 WHILE (val MOD 2) = 1 DO level ← level+1 ENDLOOP;
chkFor1s ← Rope.Equal[ExpandList[byte, index, chkFor].first,"VDD"];
cellList ← CONS[ GPCell[
design: design,
type:  IF ((level MOD 2)=0)=chkFor1s THEN nand ELSE nor,
top:  ExpandList[byte, index, lTop[gate]],
in:   LIST[ ListIndexItem[ExpandList[byte, index, lTop[gate]], colLt],
     ListIndexItem[ExpandList[byte, index, lTop[gate]], colRt] ],
out:  LIST[ ListIndexItem[ExpandList[byte, index, lTop[gate]], colOut] ],
bot:  ExpandList[byte, index, lTop[bot]] ], cellList];
ENDLOOP;
gates  ← PW.AbutListX [design, cellList];
cell  ← PW.AbutY  [design, routingTop, cell];
cell  ← PW.AbutY  [design, routingBot,  cell];
cell  ← PW.AbutY  [design, gates,   cell];
Check bottom specification
FOR ii: INT DECREASING IN [0..rp.rngByte*rp.rngBit) DO
byte, index: INT;
[byte, index] ← ByteBitFromIndex[ii, rp];
IF NOT ListEqual[
ExpandList[byte, index, bot],
ExpandList[byte, index, lTop[bot]]]
THEN ERROR Error
["The 3 columns designated for use in a match row cannot be used to pass data."];
ENDLOOP;
cell ← RenameObjAndAssignRowPins[design, cell, name];
RETURN[cell] };
ListEqual: PROC[l1, l2: List] RETURNS[BOOL] = {
FOR l1 ← l1, l1.rest WHILE l1# NIL DO
IF l2=NIL OR NOT Rope.Equal[l1.first, l2.first] THEN RETURN[FALSE];
l2 ← l2.rest ENDLOOP;
RETURN[l2=NIL]};
MatchTest: IFUPW.UserProc = {RETURN[ IFUMatchRow[
design: design,
top:  LIST[
"XBus.",
LIST["AmatLt.", "BmatLt.", "CmatLt."],
LIST["AmatRt.", "BmatRt.", "CmatRt."] ],
in1:  1,
in2:  2,
extra:  3,
sideOuts: LIST["MatchA", "MatchB", "MatchC"],
outsSide: left,
rp:   IFUDataColNSeq ]]};
PW.Register[MatchTest,  "MatchTest"];
END.