DIRECTORY Basics, CD, CDCells USING [CreateEmptyCell, SetInterestRect], CDDirectory, IFUPW, IO, PW, Rope, SymTab; IFUPWSwitchBox: CEDAR PROGRAM IMPORTS CD, CDCells, IFUPW, IO, PW, Rope, SymTab EXPORTS IFUPW = BEGIN OPEN IFUPW; Node: TYPE = REF NodeRec; NodeRec: TYPE = RECORD[ name: Rope.ROPE, row: INT _ rowNotAssigned, minX: INT, maxX: INT _ 0, top: LIST OF INT_NIL, bot: LIST OF INT_NIL ]; rowNotAssigned: INT = -1; LeftEdge: PROC RETURNS[INT] = {RETURN[- leftTail]}; RightEdge: PROC[rp: RowParams] RETURNS[INT] = {RETURN[LeftEdge[] + rp.rngBit*rp.rngByte*cellWidth]}; SwitchBoxRow: PUBLIC PROC [ design: CD.Design, name: PW.ROPE, rowType: CD.Layer, topRP: RowParams _ IFUDataColNSeq, top: LIST OF REF, left: List, right: List, bot: LIST OF REF, botRP: RowParams _ IFUDataColNSeq, m2Pitch: BOOL _ FALSE ] RETURNS [cell: CD.Object] = { rowWW: INT _ IF rowType = cmosPoly THEN polW ELSE met2W; xTweak: INT _ (cnctSize-metW)/2; pFrng: INT _ (pwrW-metW)/2; pitch: Size _ [metPitch, (IF rowType#cmosPoly OR m2Pitch THEN met2Pitch ELSE polPitch)]; ctct: CD.Object _ IFUPW.Contact[rowType]; nofRows: INT _ 0; nodes: LIST OF Node _ NIL; ltEdge: LIST OF Node _ NIL; rtEdge: LIST OF Node _ NIL; pass: LIST OF Node _ NIL; conn: LIST OF Node _ NIL; assigned: LIST OF Node _ NIL; temps: LIST OF Node _ NIL; cellMinX: INT _ RightEdge[topRP]; yMax: INT _ 0; yMin: INT _ 0; iRect: CD.Rect; symTab: SymTab.Ref _ SymTab.Create[]; SortNodes: SymTab.EachPairAction = { node: Node _ NARROW[val]; SELECT TRUE FROM node.minX = LeftEdge[ ] => ltEdge _ UpdateNotAssigned[ltEdge, node]; node.maxX = RightEdge[topRP] => rtEdge _ UpdateNotAssigned[rtEdge, node]; node.maxX - node.minX = 0 => pass _ UpdateNotAssigned[pass, node]; ENDCASE => conn _ UpdateNotAssigned[conn, node]; RETURN[FALSE] }; cell _ CDCells.CreateEmptyCell[]; left _ DelGVFromList[left]; right _ DelGVFromList[right]; UpdateSymTabWithList[topRP, symTab, left, left, pitch]; UpdateSymTabWithList[topRP, symTab, right, right, pitch]; FOR index: INT DECREASING IN [0..topRP.rngBit ) DO FOR byte: INT DECREASING IN [0..topRP.rngByte) DO topl: List _ ExpandList[byte, index, top]; botl: List _ ExpandList[byte, index, bot]; topl _ DelGVFromList[topl]; -- won't delete indexed versions (ie. "GND.23") botl _ DelGVFromList[botl]; -- won't delete indexed versions (ie. "GND.23") UpdateSymTabWithList[topRP, symTab, topl, top, pitch, byte, index]; UpdateSymTabWithList[botRP, symTab, botl, bottom, pitch, byte, index]; ENDLOOP; ENDLOOP; [ ] _ SymTab.Pairs[symTab, SortNodes]; FOR nodePtr: LIST OF Node _ ltEdge, nodePtr.rest WHILE nodePtr#NIL DO assigned _ AddUnassignedNodeToAssigned [nodePtr.first, assigned, pitch, rowType, topRP]; ENDLOOP; FOR nodePtr: LIST OF Node _ rtEdge, nodePtr.rest WHILE nodePtr#NIL DO assigned _ AddUnassignedNodeToAssigned [nodePtr.first, assigned, pitch, rowType, topRP]; ENDLOOP; FOR nodePtr: LIST OF Node _ conn, nodePtr.rest WHILE nodePtr#NIL DO assigned _ AddUnassignedNodeToAssigned [nodePtr.first, assigned, pitch, rowType, topRP]; ENDLOOP; yMax _ 0; FOR nodePtr: LIST OF Node _ assigned, nodePtr.rest WHILE nodePtr#NIL DO yMax _ MAX[yMax, nodePtr.first.row] ENDLOOP; yMax _ yMax + cnctSize/2 + topTail; yMin _ 0 - cnctSize/2 - botTail - lambda; FOR ii: INT IN [0..topRP.rngBit*topRP.rngByte) DO FOR jj: INT IN [6..7] DO -- GND VDD name: Rope.ROPE _ (IF jj=6 THEN GND ELSE VDD); xx: INT _ ii*cellWidth + jj*pitch.x; cellMinX _ MIN[ cellMinX, xx-pFrng]; PutPin [cell, [metW, metW], [xx, yMax-metW], cmosMet, name]; PutPin [cell, [metW, metW], [xx, yMin], cmosMet, name]; AddRet [cell, [pwrW, yMax-yMin], [xx-pFrng, yMin], cmosMet]; ENDLOOP ENDLOOP; FOR nodePtr: LIST OF Node _ pass, nodePtr.rest WHILE nodePtr#NIL DO -- pass name: Rope.ROPE _ nodePtr.first.name; vgNode: BOOL _ Rope.Find[name,"GND"]#-1 OR Rope.Find[name,"VDD"]#-1; xx: INT _ nodePtr.first.minX; xxx: INT _ xx; wireW: INT _ metW; IF vgNode THEN {wireW _ pwrW; xxx _ xx-pFrng}; 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]]]; cellMinX _ MIN[ cellMinX, xx]; PutPin [cell, [wireW, metW], [xx, yMax-metW], cmosMet, name]; PutPin [cell, [wireW, metW], [xx, yMin], cmosMet, name]; AddRet [cell, [wireW, yMax-yMin], [xxx, yMin], cmosMet]; ENDLOOP; FOR nodePtr: LIST OF Node _ assigned, nodePtr.rest WHILE nodePtr#NIL DO -- top bot name: Rope.ROPE _ nodePtr.first.name; vgNode: BOOL _ Rope.Find[name,"GND"]#-1 OR Rope.Find[name,"VDD"]#-1; yMid: INT _ nodePtr.first.row; minX: INT _ nodePtr.first.minX; maxX: INT _ nodePtr.first.maxX; cellMinX _ MIN[ cellMinX, minX]; IF minX=LeftEdge[] THEN { PutPin[cell, [rowWW, rowWW], [minX, yMid-rowWW/2], rowType, name]}; IF maxX=RightEdge[topRP] THEN { PutPin[cell, [rowWW, rowWW], [maxX-rowWW, yMid-rowWW/2], rowType, name]}; AddRet [cell, [maxX-minX, rowWW], [minX, yMid-rowWW/2], rowType]; FOR nodeTop: LIST OF INT _ nodePtr.first.top, nodeTop.rest WHILE nodeTop#NIL DO xx: INT _ nodeTop.first; IF vgNode THEN AddRet[cell, [pwrW, yMax-yMid], [xx-pFrng, yMin], cmosMet] ELSE AddRet[cell, [metW, yMax-yMid], [xx, yMid], cmosMet]; PutPin [cell, [metW, metW], [xx, yMax-metW], cmosMet, name]; cellMinX _ MIN[ cellMinX, xx-xTweak]; [] _ PW.IncludeInCell[cell, ctct, [xx-xTweak, yMid-cnctSize/2]]; ENDLOOP; FOR nodeBot: LIST OF INT _ nodePtr.first.bot, nodeBot.rest WHILE nodeBot#NIL DO xx: INT _ nodeBot.first; IF vgNode THEN AddRet[cell, [pwrW, yMid-yMin], [xx-pFrng, yMin], cmosMet] ELSE AddRet[cell, [metW, yMid-yMin], [xx, yMin], cmosMet]; PutPin [cell, [metW, metW], [xx, yMin], cmosMet, name]; cellMinX _ MIN[ cellMinX, xx-xTweak]; [] _ PW.IncludeInCell[cell, ctct, [xx-xTweak, yMid-cnctSize/2]]; ENDLOOP ; ENDLOOP; PW.IncludeInDirectory[design, cell]; iRect _ CD.InterestRect[cell]; iRect.x1 _ iRect.x1 - (cellMinX-LeftEdge[ ]); iRect.x2 _ iRect.x1 + (RightEdge[topRP]-LeftEdge[ ]); CDCells.SetInterestRect[cell, iRect]; PW.RenameObject[design, cell, name]; RETURN[cell]}; UpdateSymTabWithList: PROC [rp: RowParams, symTab: SymTab.Ref, names: List, side:Side, pitch: Size, idx1, idx2: INT _0]={ 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, minX: RightEdge[rp]]]; [ ] _ SymTab.Store[symTab, names.first, node] }; coord _ IFUPW.ByteBitToIndex[idx1, idx2, rp]*cellWidth + index*pitch.x; SELECT side FROM left => {node.minX _ LeftEdge[ ]}; right => {node.maxX _ RightEdge[rp]}; 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}; 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]}}; AddUnassignedNodeToAssigned: PROC [node: Node, orig: LIST OF Node, pitch: Size, rowType: CD.Layer, rp: RowParams] RETURNS [list: LIST OF Node] = { padX: INT _ IF rowType=cmosMet2 THEN pitch.x ELSE 0; -- met2 => can't be adjacent list _ orig; IF list=NIL THEN {node.row _ 0; 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[rp]+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]}; END.  IFUPWSwitchBox.mesa, Copyright c 1985 by Xerox Corporation. All rights reserved. Last Edited by Curry, November 26, 1985 7:26:40 pm PST Check for internal connections Draw wires GenMetalPinRow: PUBLIC PROC [ design: CD.Design, name: Rope.ROPE, height: INT _ 6, top: LIST OF REF, rp: RowParams _ IFUDataColNSeq ] RETURNS [cellName: CD.Object] = { obj: CD.Object _ CDCells.CreateEmptyCell[]; iRect: CD.Rect; FOR ii: INT IN [0..rp.rngByte*rp.rngBit) DO names: List; byte, index: INT; sigIndex: INT _ -1; [byte, index] _ IFUPW.ByteBitFromIndex[ii, rp]; names _ ExpandList[byte, index, top]; 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], cmosMet]; PutPin [obj, [6, 6], [ii*cellWidth+sigIndex*metPitch, 0], cmosMet, names.first]; ENDLOOP; ENDLOOP; PW.IncludeInDirectory[design, obj]; iRect _ CD.InterestRect[obj]; iRect.x1 _ iRect.x1 - leftTail; iRect.x2 _ rp.rngByte*rp.rngBit*cellWidth + iRect.x1; CDCells.SetInterestRect[obj, iRect]; cellName _ PWBasics.NameFromObj[obj]; cellName _ PW.ReName[cellName, name]; RETURN[cellName]}; SwitchBoxRowTest: IFUPW.UserProc = { RETURN[ SwitchBoxRow[ design: design, rowType: cmosMet2, 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š�œ˜—š �œ �œ�œ�œ �œ�œŸ ˜RJšœ �œ˜&Jšœ�œ�œ˜FJšœ�œ˜!Jšœ�œ˜"Jšœ�œ˜"Jšœ�œ˜$š�œ�œ˜JšœF˜F—š�œ�œ˜JšœI˜I—JšœA˜Aš �œ �œ�œ�œ#�œ �œ�˜OJšœ�œ˜š�œ˜ Jš�œ<˜@Jš�œ;˜?—JšœA˜AJšœ �œ˜&Jšœ@˜@Jš�œ˜—š �œ �œ�œ�œ#�œ �œ�˜OJšœ�œ˜š�œ˜ Jš�œ;˜?Jš�œ9˜=—Jšœ=˜=Jšœ �œ˜&Jšœ@˜@Jš�œ˜ —Jš�œ˜—Jšœ$˜$Jšœ�œ˜Jšœ.˜.Jšœ5˜5Jšœ%˜%Jš�œ"˜$Jš�œ˜J˜—šžœ�˜JšœU�œ˜^š �œ�œ�œ�œ�˜.Jšœ ˜ Jšœ�œ˜ Jšœ�œ˜ Jšœ�œ˜ š�œ�œ�œ˜Jšœ1˜1š�œ˜Jš�œ�œ˜š�œ˜Jšœ�œ5˜?Jšœ0˜0——Jšœ�œ:˜Gš�œ�˜Jšœ"˜"Jšœ%˜%šœ˜Jšœ �œ˜#Jšœ �œ˜#Jšœ �œ˜%—šœ ˜ Jšœ �œ˜#Jšœ �œ˜#Jšœ �œ˜%—Jš�œ�œ˜——Jšœ˜Jš�œ˜ ——J˜šžœ�œ�œ�œ�œ�œ�œ ˜RJšœ�œ˜ Jš �œ�œ�œ�œ�œ˜,Jšœ?˜?Jš�œ �œ&˜6š�œ ˜ Jš�œ�œ�œ˜Jš�œ2�œ ˜E——J˜šžœ�˜!Jšœ�œ�œ�œ˜OJš�œ�œ�œ ˜ Jš œ�œ�œ�œ �œŸ˜QJšœ ˜ Jš �œ�œ�œ�œ�œ˜:š�œ!˜#Jš�œ�œ�œ˜<—š�œ�œ�œ�˜-Jšœ�œ˜š�œ �˜Jš�œC˜GJš�œF˜J—š�œ˜š�œ˜š�œ#˜%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šœ'™'Jšœ™š�œ�œ�œ�™0Jšœ™Jš�œ �œ�œ�œ™JšœH™HJšœR™RJš�œ™—Jš�œ™—Jšœ#™#Jšœ�œ™Jšœ™Jšœ5™5Jšœ$™$Jšœ%™%Jšœ �œ™%Jš�œ ™—J˜šœ:™:J™Jšœ™Jšœ™šœ ™ JšœY™Y—Jšœ ™ Jšœ9™9—J™Jšœ4™4J˜Jš�œ˜—J™—…—!3÷