<> <> <> <<>> <<>> 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]}; <> <> <> <> <> <> <> <> <> <> <> <> <> <<[byte, index] _ IFUPW.ByteBitFromIndex[ii, rp];>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<["Alpha.0", "Alpha.1", "Alpha.2", "Alpha.3", "Alpha.4", "Alpha.5", "Alpha.6", "Alpha.7"],>> <> <> <<>> <> END. <<>>