DIRECTORY Basics, CD, CDCells USING [CreateEmptyCell, SetInterestRect], CDDirectory, CMos, CMosContacts, IFUPW, IO, PW, PWBasics, SymTab; IFUPWSwitchBox: CEDAR PROGRAM IMPORTS CD, CDCells, CMosContacts, CMos, IFUPW, IO, PW, PWBasics, SymTab EXPORTS IFUPW = BEGIN OPEN IFUPW; Node: TYPE = REF NodeRec; NodeRec: TYPE = RECORD[ name: PW.ROPE, row: INT _ rowNotAssigned, minX: INT _ rightEdge, maxX: INT _ 0, top: LIST OF INT_NIL, bot: LIST OF INT_NIL ]; rightEdge: INT = rngBit*rngByte*cellWidth-leftTail; leftEdge: INT = - leftTail; rowNotAssigned: INT = -1; SwitchBoxRow: PUBLIC PROC [ -- Assumes byte interleaving (rngBit cells of rngByte bits) design: CD.Design, name: PW.ROPE, rowType: CD.Layer, topSeq: BOOL _ FALSE, top: LIST OF REF, left: List, right: List, bot: LIST OF REF, botSeq: BOOL _ FALSE, fixGV: BOOL _ TRUE ] RETURNS [cellName: PW.ObjName] = { colType: CD.Layer _ CMos.met; pitch: Size _ [metPitch, (IF rowType=CMos.pol THEN polPitch ELSE met2Pitch)]; cntctW: INT _ IF rowType = CMos.pol THEN 8 ELSE 10; cntctBotTail: INT _ IF rowType = CMos.pol THEN 2 ELSE 2; colWW: INT _ (pitch.x-2)/2; -- 14=>6 rowWW: INT _ (pitch.y-2)/2; -- 10=>4, 18=>8 ctct: CD.ObPtr _ (SELECT rowType FROM CMos.pol => CMosContacts.CreatePolyCon [l: cntctW], CMos.met2 => CMosContacts.CreateMmCon [l: cntctW], ENDCASE => ERROR); nofRows: INT _ 0; nodes: LIST OF Node _ NIL; assigned: LIST OF Node _ NIL; nAsigned: LIST OF Node _ NIL; straightPass: LIST OF Node _ NIL; tempNodes: LIST OF Node _ NIL; cell: CD.ObPtr _ CDCells.CreateEmptyCell[]; cellMinX: INT _ rightEdge; topTail: INT _ 4; botTail: INT _ SELECT rowType FROM CMos.pol=>2, CMos.met2=>4, ENDCASE=>ERROR; yMax: INT _ 0; yMin: INT _ 0; iRect: CD.Rect; symTab: SymTab.Ref _ SymTab.Create[]; SortNodes: SymTab.EachPairAction = { node: Node _ NARROW[val]; IF node.row#rowNotAssigned THEN assigned _ AddAssignedNodeToAssigned[node, assigned] -- Unique rows ELSE IF node.minX=node.maxX THEN straightPass _ UpdateNotAssigned[straightPass, node] -- Biggest first ELSE nAsigned _ UpdateNotAssigned[nAsigned, node]; -- Biggest first RETURN[FALSE] }; IF fixGV THEN { left _ DelGVFromList[left]; right _ DelGVFromList[right]; top _ AddGVToLIST[top, IF topSeq=botSeq THEN TRUE ELSE FALSE]; bot _ AddGVToLIST[bot, IF topSeq=botSeq THEN TRUE ELSE FALSE] }; nofRows _ UpdateSymTabWithList[symTab, left, left, pitch, nofRows]; nofRows _ UpdateSymTabWithList[symTab, right, right, pitch, nofRows]; FOR index: INT DECREASING IN [0..rngBit) DO FOR byte: INT DECREASING IN [0..rngByte) DO topl: List _ ExpandList[byte, index, top]; botl: List _ ExpandList[byte, index, bot]; IF fixGV THEN { topl _ DelGVFromList[topl]; -- won't delete indexed versions (ie. "GND.23") botl _ DelGVFromList[botl]}; -- won't delete indexed versions (ie. "GND.23") [ ] _ UpdateSymTabWithList[symTab, topl, top, pitch, 0, byte, index, topSeq]; [ ] _ UpdateSymTabWithList[symTab, botl, bottom, pitch, 0, byte, index, botSeq]; ENDLOOP; ENDLOOP; [ ] _ SymTab.Pairs[symTab, SortNodes]; FOR nodePtr: LIST OF Node _ nAsigned, nodePtr.rest WHILE nodePtr#NIL DO assigned _ AddUnassignedNodeToAssigned [nodePtr.first, assigned, nofRows, pitch, rowType]; ENDLOOP; yMax _ 0; FOR nodePtr: LIST OF Node _ assigned, nodePtr.rest WHILE nodePtr#NIL DO yMax _ MAX[yMax, nodePtr.first.row]; ENDLOOP; yMax _ yMax - cntctBotTail + cntctW + topTail; yMin _ 0 - cntctBotTail - botTail; FOR nodePtr: LIST OF Node _ straightPass, nodePtr.rest WHILE nodePtr#NIL DO name: PW.ROPE _ nodePtr.first.name; minX: INT _ nodePtr.first.minX; maxX: INT _ nodePtr.first.maxX; cellMinX _ MIN[ cellMinX, minX]; IF nodePtr.first.top=NIL OR nodePtr.first.bot=NIL THEN ERROR Error[ IO.PutFR[ "Signal %g is not connected anywhere", IO.rope[nodePtr.first.name]]]; AddRet [cell, [colWW, yMax-yMin], [minX, yMin], colType]; PutPin [cell, [colWW, colWW], [minX, yMax-colWW], colType, name]; PutPin [cell, [colWW, colWW], [minX, yMin], colType, name]; ENDLOOP; FOR nodePtr: LIST OF Node _ assigned, nodePtr.rest WHILE nodePtr#NIL DO yMid: INT _ nodePtr.first.row; name: PW.ROPE _ nodePtr.first.name; minX: INT _ nodePtr.first.minX; maxX: INT _ nodePtr.first.maxX; cellMinX _ MIN[ cellMinX, minX]; IF minX=leftEdge THEN { PutPin [cell, [rowWW, rowWW], [minX, yMid], rowType, name]}; IF maxX=rightEdge THEN { PutPin [cell, [rowWW, rowWW], [maxX-rowWW, yMid], rowType, name]}; AddRet [cell, [maxX-minX, rowWW], [minX, yMid], rowType]; FOR nodeTop: LIST OF INT _ nodePtr.first.top, nodeTop.rest WHILE nodeTop#NIL DO xx: INT _ nodeTop.first; AddRet [cell, [colWW, yMax-yMid], [xx, yMid], colType]; PutPin [cell, [colWW, colWW], [xx, yMax-colWW], colType, name]; cellMinX _ MIN[ cellMinX, xx-2]; -- -2 for left contact overhang [] _ PWBasics.IncludeApplication[cell, ctct, [xx-2, yMid-2]]; ENDLOOP; FOR nodeBot: LIST OF INT _ nodePtr.first.bot, nodeBot.rest WHILE nodeBot#NIL DO xx: INT _ nodeBot.first; AddRet [cell, [6, yMid-yMin], [xx, yMin], colType]; PutPin [cell, [6, 6], [xx, yMin], colType, name]; cellMinX _ MIN[ cellMinX, xx-2]; -- -2 for left contact overhang [] _ PWBasics.IncludeApplication[cell, ctct, [xx-2, yMid-2]]; ENDLOOP ; ENDLOOP; PWBasics.RepositionCell[design, cell]; iRect _ CD.InterestRect[cell]; iRect.x1 _ iRect.x1 - (cellMinX-leftEdge); iRect.x2 _ iRect.x1 + (rightEdge-leftEdge); CDCells.SetInterestRect[cell, iRect]; cellName _ PWBasics.NameFromObj[cell]; cellName _ PW.ReName[cellName, name]; RETURN[cellName]}; UpdateSymTabWithList: PROC [symTab: SymTab.Ref, names: List, side:Side, pitch: Size, startRows, idx1, idx2: INT _ 0, seq: BOOL _ FALSE] RETURNS[INT] ={ FOR index: INT _ 0, index+1 WHILE names#NIL DO node: Node; found: BOOL; val: REF; coord: INT; IF names.first#NIL THEN { [found, val] _ SymTab.Fetch[symTab, names.first]; IF found THEN node _ NARROW[val] ELSE { node _ NEW[NodeRec _ [name: names.first]]; [ ] _ SymTab.Store[symTab, names.first, node] }; IF side IN [right..left] THEN {coord _ startRows*pitch.y; startRows _ startRows+1} ELSE coord _ IFUPW.ByteBitToIndex[idx1, idx2, seq]*cellWidth + index*pitch.x; SELECT side FROM left => {node.row _ coord; node.minX _ leftEdge}; right => {node.row _ coord; node.maxX _ rightEdge}; top => { node.top _ CONS [coord, node.top]; node.minX _ MIN [coord, node.minX]; node.maxX _ MAX [coord, node.maxX] }; bottom => { node.bot _ CONS [coord, node.bot]; node.minX _ MIN [coord, node.minX]; node.maxX _ MAX [coord, node.maxX] }; ENDCASE => ERROR }; names _ names.rest; ENDLOOP; RETURN[startRows]}; UpdateNotAssigned: PROC[list: LIST OF Node, node: Node] RETURNS [LIST OF Node] = { test: INT; IF list = NIL THEN RETURN[CONS[node, list]]; test _ (list.first.maxX-list.first.minX)-(node.maxX-node.minX); IF test = 0 THEN test _ (node.minX)-(list.first.minX); IF test < 0 THEN RETURN[CONS[node, list]] ELSE {list.rest _ UpdateNotAssigned[list.rest, node]; RETURN[list]}}; AddAssignedNodeToAssigned: PROC -- Assume rows are unique [node: Node, orig: LIST OF Node] RETURNS [list: LIST OF Node] = { list _ orig; IF list=NIL OR node.row < list.first.row THEN {RETURN[ CONS[node, list] ]}; FOR sList: LIST OF Node _ list, sList.rest DO IF sList.rest=NIL OR node.row < sList.rest.first.row THEN {sList.rest _ CONS[node, sList.rest]; EXIT} ENDLOOP; RETURN[list]}; AddUnassignedNodeToAssigned: PROC [node: Node, orig: LIST OF Node, startRows: INT, pitch: Size, rowType: CD.Layer] RETURNS [list: LIST OF Node] = { padX: INT _ IF rowType=CMos.met2 THEN pitch.x ELSE 0; -- met2 => can't be adjacent list _ orig; IF list=NIL THEN {node.row _ startRows*pitch.y; RETURN[CONS[node, list]]}; IF node.maxX < list.first.minX-padX THEN {node.row _ list.first.row; RETURN[CONS[node, list] ]}; FOR sList: LIST OF Node _ list, sList.rest DO nextMinX, nextRow: INT; IF sList.rest#NIL THEN {nextMinX _ sList.rest.first.minX; nextRow _ sList.rest.first.row} ELSE {nextMinX _ rightEdge+padX+1; nextRow _ sList.first.row+pitch.y}; IF sList.first.row#nextRow THEN { IF sList.first.maxX+padX >= node.minX AND node.maxX+padX >= nextMinX THEN LOOP; IF sList.first.maxX+padX < node.minX THEN node.row _ sList.first.row ELSE node.row _ nextRow; sList.rest _ CONS[node, sList.rest]; EXIT} ELSE { IF sList.first.maxX+padX >= node.minX OR node.maxX+padX >= nextMinX THEN LOOP; node.row _ sList.first.row; sList.rest _ CONS[node, sList.rest]; EXIT} ENDLOOP; RETURN[list]}; GenMetalPinRow: PUBLIC PROC [ design: CD.Design, name: PW.ROPE, height: INT _ 6, top: LIST OF REF, seq: BOOL _ FALSE, fixGV: BOOL _ TRUE ] RETURNS [cellName: PW.ObjName] = { obj: CD.ObPtr _ CDCells.CreateEmptyCell[]; iRect: CD.Rect; FOR ii: INT IN [0..rngByte*rngBit) DO names: List; byte, index: INT; sigIndex: INT _ -1; [byte, index] _ IFUPW.ByteBitFromIndex[ii, seq]; names _ ExpandList[byte, index, top]; IF fixGV THEN names _ FixGVInList[names]; FOR names _ names, names.rest WHILE names#NIL DO sigIndex _ sigIndex+1; IF names.first=NIL THEN LOOP; AddRet [obj, [6, height], [ii*cellWidth+sigIndex*metPitch, 0], CMos.met]; PutPin [obj, [6, 6], [ii*cellWidth+sigIndex*metPitch, 0], CMos.met, names.first]; ENDLOOP; ENDLOOP; PWBasics.RepositionCell[design, obj]; iRect _ CD.InterestRect[obj]; iRect.x1 _ iRect.x1 - leftTail; iRect.x2 _ rngByte*rngBit*cellWidth + iRect.x1; CDCells.SetInterestRect[obj, iRect]; cellName _ PWBasics.NameFromObj[obj]; cellName _ PW.ReName[cellName, name]; RETURN[cellName]}; END. IFUPWSwitchBoxOld.mesa, Copyright c 1985 by Xerox Corporation. All rights reserved. Last Edited by Curry, June 6, 1985 0:50:51 am PDT Check for internal connections Draw wires SwitchBoxRowTest: PW.UserProc = { RETURN[ SwitchBoxRow[ design: design, rowType: CMos.met2, top: LIST[NIL, "PBus." ], right: LIST ["Alpha.0", "Alpha.1", "Alpha.2", "Alpha.3", "Alpha.4", "Alpha.5", "Alpha.6", "Alpha.7"], left: NIL, bot: LIST[LIST["Alpha.", NIL, NIL, NIL], "PBus." ] ] ] }; PW.Register [SwitchBoxRowTest, "SwitchBoxRowTest"]; Ê ˜šœ™Jšœ<™Jšœœœœ˜@—JšœC˜CJšœE˜Eš œœ œœ ˜+š œœ œœ˜+Jšœ*˜*Jšœ*˜*šœœ˜JšœŸ0˜LJšœŸ0˜M—JšœN˜NJšœP˜PJšœ˜—Jšœ˜—Jšœ™Jšœ&˜&š œ œœœ œ˜Gšœ&˜&Jšœ3˜3—Jšœ˜—J™ Jšœ ˜ š œ œœœ œ˜GJšœœ˜$Jšœ˜—Jšœ.˜.Jšœ-˜-š œ œœ#œ œ˜KJšœœœ˜$Jšœœ˜!Jšœœ˜!Jšœœ˜#š œœœœœœ˜MJšœ'œ˜E—Jšœ;˜;JšœC˜CJšœ?˜?Jšœ˜—š œ œœœ œ˜GJšœœ˜ Jšœœœ˜$Jšœœ˜!Jšœœ˜!Jšœœ˜#šœœ˜Jšœ>˜>—šœœ˜JšœB˜B—Jšœ9˜9š œ œœœ#œ œ˜OJšœœ˜Jšœ9˜9Jšœ@˜@Jšœ œŸ˜EJšœ=˜=Jšœ˜—š œ œœœ#œ œ˜OJšœœ˜Jšœ4˜4Jšœ6˜6Jšœ œŸ˜EJšœ=˜=Jšœ˜ —Jšœ˜—Jšœ&˜&Jšœœ˜Jšœ+˜+Jšœ+˜+Jšœ%˜%Jšœ&˜&Jšœ œ˜%Jšœ ˜J˜—šžœ˜Jš œQœ œœœœ˜|š œœœœ˜.Jšœ ˜ Jšœœ˜ Jšœœ˜ Jšœœ˜ šœ œœ˜Jšœ1˜1šœ˜Jšœœ˜šœ˜Jšœœ ˜*Jšœ0˜0——šœœ˜Jšœ5˜9šœ˜ Jšœ;˜@——šœ˜Jšœ1˜1Jšœ3˜3šœ˜Jšœ œ˜#Jšœ œ˜#Jšœ œ˜%—šœ ˜ Jšœ œ˜#Jšœ œ˜#Jšœ œ˜%—Jšœœ˜——Jšœ˜Jšœ˜—Jšœ ˜—J˜šžœœœœœœœ ˜RJšœ ˜ Jšœœ œœ˜,Jšœ?˜?Jšœ œ&˜6šœ ˜ Jšœœœ˜Jšœ2œ ˜E——J˜šžœœŸ˜9Jš œœœœœœ ˜AJšœ ˜ Jš œœœœœœ˜Kšœœœ˜-šœ œœ ˜4Jšœœœœ˜9——Jšœ˜—J˜šžœ˜!š œœœœœ˜PJšœœœ ˜ —Jš œœœœ œŸ˜RJšœ ˜ šœœ˜Jšœœœ˜9—šœ!˜#Jšœœœ˜<—šœœœ˜-Jšœœ˜šœ ˜JšœC˜GJšœB˜F—šœ˜šœ˜šœ#˜%Jšœœœ˜)—šœ"˜$Jšœ˜Jšœ˜—Jšœ œ˜$Jšœ˜—šœ˜Jšœ$œœœ˜NJšœ˜Jšœ œ˜$Jšœ˜——Jšœ˜—Jšœ˜—J˜J˜šžœœœ˜Jšœ œ˜Jšœœœ˜Jšœ œ˜Jšœœœœ˜Jšœœœ˜šœœœ˜Jšœ œ ˜"—Jšœœ#˜*Jšœœ˜šœœœ˜%Jšœ ˜ Jšœ œ˜Jšœ œ˜Jšœœ˜0Jšœ'˜'Jšœœ˜)šœœœ˜0Jšœ˜Jšœ œœœ˜JšœI˜IJšœS˜SJšœ˜—Jšœ˜—Jšœ%˜%Jšœœ˜Jšœ˜Jšœ/˜/Jšœ$˜$Jšœ%˜%Jšœ œ˜%Jšœ ˜—J˜šœ7™7J™Jšœ™Jšœ™šœ ™ JšœY™Y—Jšœ ™ Jšœ9™9—J™Jšœ4™4J˜Jšœ˜—J™—…—$Î3ö