<> <> <> <<>> <<>> DIRECTORY CD, CMos, IFUPW, PW, Rope; IFUPWMatch: CEDAR PROGRAM IMPORTS CMos, IFUPW, Rope EXPORTS IFUPW = BEGIN OPEN IFUPW; 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; <> 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; <> 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 ]; <> 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]; <> 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] }; 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]}; <> <> <> <<"XBus.",>> <> <> <> <> <> <> <> <> <<>> <> END.