DIRECTORY CD, IFUPW, PW, Rope; IFUPWMatch: CEDAR PROGRAM IMPORTS IFUPW, PW, Rope EXPORTS IFUPW = 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.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; 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 ]; 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]; 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]}; END.  IFUPWMatch.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Last Edited by Curry, November 4, 1985 11:55:14 am PST Construct interfaces Gate cells Check bottom specification 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"]; Ê Ã˜šœ™Jšœ<™