IFUMatchRow:
PUBLIC
PROC[
design: CD.Design,
name: PW.ROPE,
type: LIST OF REF ← NIL,
chkFor1s: BOOL,
top: LIST OF REF ← NIL,
in1: INT ← 0, -- column index
in2: INT ← 1, -- column index
extra: INT ← 2, -- third column needed for routing
sideOuts: List ← NIL, -- up to four bytes can be checked, NIL => blank
outsSide: Side[right..left] ← right,
bot: LIST OF REF ← NIL, -- must be same as top with 3 used columns NIL
seq:
BOOL ←
FALSE ]
RETURNS[cellName: PW.ObjName]= {
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..rngByte) OF PW.ROPE ← ALL[NIL];
colNm: ARRAY Col OF PW.ROPE ← ALL[NIL];
cellList: LIST OF PW.ObjName;
xors: PW.ObjName;
routingTop: PW.ObjName;
routingBot: PW.ObjName;
gates: PW.ObjName;
colLt: INT ← in1;
colOut: INT ← in2;
colRt: INT ← extra;
IF colLt>colOut THEN {temp: INT ← colLt; colLt ← colOut; colOut ← temp};
IF colOut>colRt THEN {temp: INT ← colOut; colOut ← colRt; colRt ← temp};
IF colLt>colOut THEN {temp: INT ← colLt; colLt ← colOut; colOut ← temp};
tList ← sideOuts;
top ← AddGVToLIST[top, FALSE];
bot ← AddGVToLIST[bot, FALSE];
FOR byte:
INT
IN [0..rngByte)
WHILE tList#
NIL
DO
byNm[byte] ← tList.first; tList ← tList.rest ENDLOOP;
FOR byte:
INT
DECREASING
IN [0..rngByte)
DO
by[lt] ← NIL;
IF byNm[byte]#
NIL
THEN
FOR index:
INT
DECREASING
IN [0..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..rngByte)
DO
FOR col: Col IN Col DO by[col] ← NIL ENDLOOP;
IF byNm[byte]#
NIL
THEN
FOR index:
INT
DECREASING
IN [0..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..rngByte)
DO
FOR col: Col IN Col DO by[col] ← NIL ENDLOOP;
IF byNm[byte]#
NIL
THEN
FOR index:
INT
DECREASING
IN [0..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=(rngBit-1)) THEN colNm[lt] ← colNm[rt] ← colNm[out] ← NIL;
IF (index=(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;
Xor Cells
cellList ← NIL;
FOR ii:
INT
DECREASING
IN [0..rngByte*rngBit)
DO
byte, index: INT;
[byte, index] ← ByteBitFromIndex[ii, seq];
cellList ←
CONS[ GVCell[
design: design,
type: ExpandList[byte, index, type],
top: ExpandList[byte, index, top],
in: LIST[ ListIndexItem[ExpandList[byte, index, top], in1],
ListIndexItem[ExpandList[byte, index, top], in2] ],
out: LIST[ ListIndexItem[ExpandList[byte, index, lTop[sw1]], colLt] ],
bot: ExpandList[byte, index, lTop[sw1]] ], cellList];
ENDLOOP;
xors ← AbutListX[design, cellList];
routingTop ← SwitchBoxRow[
design: design,
name: name.Cat["RtngTop"],
rowType: CMos.met2,
topSeq: seq,
top: lTop[sw1],
left: NIL,
right: NIL,
bot: lTop[sw2],
botSeq: seq,
fixGV: TRUE ];
routingBot ← SwitchBoxRow[
design: design,
name: name.Cat["RtngBot"],
rowType: CMos.met2,
topSeq: seq,
top: lTop[sw2],
left: (IF outsSide=left THEN sideOuts ELSE NIL),
right: (IF outsSide=right THEN sideOuts ELSE NIL),
bot: lTop[gate],
botSeq: seq,
fixGV: TRUE ];
Gate cells
cellList ← NIL;
FOR ii:
INT
DECREASING
IN [0..rngByte*rngBit)
DO
nor: List = LIST["GVNor"];
nand: List = LIST["GVNand"];
level: INT ← 0;
byte, index: INT;
[byte, index] ← ByteBitFromIndex[ii, seq];
FOR val: INT ← index, val/2 WHILE (val MOD 2) = 1 DO level ← level+1 ENDLOOP;
cellList ←
CONS[ GVCell[
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 ← AbutListX [design, cellList];
cellName ← AbutY [design, xors, cellName];
cellName ← AbutY [design, routingTop, cellName];
cellName ← AbutY [design, routingBot, cellName];
cellName ← AbutY [design, gates, cellName];
Check bottom specification
FOR ii:
INT
DECREASING
IN [0..rngByte*rngBit)
DO
byte, index: INT;
[byte, index] ← ByteBitFromIndex[ii, seq];
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;
cellName ← AssignRowPinsAndRename[design, cellName, name];
RETURN[cellName] };