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÷