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.ROPE ← ALL[NIL]; -- rngByte
colNm: ARRAY Col OF PW.ROPE ← ALL[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] };