<> <> <> <> <<>> <<>> DIRECTORY Basics, CD, CDCells USING [CreateEmptyCell], CDDirectory, CMos, CMosContacts, IFUPW, PW, PWBasics, Rope; SwitchBox: CEDAR PROGRAM IMPORTS CDCells, CMosContacts, CMos, IFUPW, PWBasics, Rope EXPORTS IFUPW = BEGIN OPEN IFUPW; rngByte: INT = 4; rngBit: INT = 8; ioRestRef: List _ LIST["VDD", "GND"]; <<>> SwitchBoxRow: PUBLIC PROC [ -- Assumes byte interleaving (rngBit cells of rngByte bits) design: CD.Design, topSeq: BOOL _ FALSE, topRow: LIST OF REF, leftCol: List, rightCol: List, botRow: LIST OF REF, botSeq: BOOL _ FALSE ] RETURNS [PW.ObjName] = { nofRows: INT _ 0; nodes: LIST OF Node _ NIL; Node: TYPE = REF NodeRec; NodeRec: TYPE = RECORD [name:PW.ROPE, top,bot:LIST OF INT_NIL, row:INT_none, left,right:BOOL_FALSE]; Side: TYPE = {top, bot, left, right}; none: INT _ -1; pitch: Size _ [mPitch, 10]; cell: CD.ObPtr _ CDCells.CreateEmptyCell[]; cellMinX: INT _ rngByte*rngBit*cellWidth; iRect: CD.Rect; AddNodes: PROC [side: Side, list: List, index1, index2, index3: INT _ 0, sequential: BOOL _ FALSE] = { UpdateNode: PROC[node: Node] RETURNS[Node] = { coord: INT _ (IF side IN [left..right] THEN index3*pitch.y ELSE (IF sequential THEN ((index1*rngBit +index2)*cellWidth + index3*pitch.x) ELSE ((index2*rngByte +index1)*cellWidth + index3*pitch.x) ) ); SELECT side FROM left => {node.row _ coord; node.left _ TRUE; nofRows _ nofRows+1}; right => {node.row _ coord; node.right _ TRUE; nofRows _ nofRows+1}; top => {node.top _ CONS[coord, node.top]}; bot => {node.bot _ CONS[coord, node.bot]}; ENDCASE => ERROR; RETURN[node] }; IF list = NIL THEN RETURN; IF list.rest # NIL THEN AddNodes[side, list.rest, index1, index2, index3+1, sequential]; IF list.first=NIL THEN RETURN; IF nodes = NIL THEN {nodes _ CONS[UpdateNode[NEW[NodeRec _ [name: list.first]]], nodes]; RETURN}; SELECT Rope.Compare[nodes.first.name, list.first] FROM equal => {[ ] _ UpdateNode[nodes.first]; RETURN}; greater => {nodes _ CONS[UpdateNode[NEW[NodeRec_[name: list.first]]], nodes]; RETURN}; ENDCASE; FOR names: LIST OF Node _ nodes, names.rest DO IF names.rest = NIL THEN { names.rest _ CONS[UpdateNode[NEW[NodeRec_[name: list.first]]], names.rest]; RETURN }; SELECT Rope.Compare[names.rest.first.name, list.first] FROM equal => {[ ] _ UpdateNode[names.rest.first]; RETURN}; greater => { names.rest _ CONS[UpdateNode[NEW[NodeRec_[name: list.first]]], names.rest]; RETURN }; ENDCASE; ENDLOOP}; AddNodes[left, leftCol]; AddNodes[right, rightCol]; FOR index: INT DECREASING IN [0..rngBit) DO FOR byte: INT DECREASING IN [0..rngByte) DO top: List _ ExpandList[byte, index, topRow, ioRestRef]; bot: List _ ExpandList[byte, index, botRow, ioRestRef]; AddNodes[top, top, byte, index, 0, topSeq]; AddNodes[bot, bot, byte, index, 0, botSeq]; ENDLOOP; ENDLOOP; <> FOR nodePtr: LIST OF Node _ nodes, nodePtr.rest WHILE nodePtr#NIL DO IF nodePtr.first.row=none AND (nodePtr.first.top#NIL AND nodePtr.first.top.rest#NIL) OR (nodePtr.first.bot#NIL AND nodePtr.first.bot.rest#NIL) OR (nodePtr.first.top#NIL AND nodePtr.first.bot#NIL AND nodePtr.first.top.first#nodePtr.first.bot.first) THEN {nodePtr.first.row _ nofRows*pitch.y; nofRows _nofRows+1}; ENDLOOP; <> FOR nodePtr: LIST OF Node _ nodes, nodePtr.rest WHILE nodePtr#NIL DO name: PW.ROPE _ nodePtr.first.name; minX: INT _ rngBit*rngByte*cellWidth; maxX: INT _ 0; FOR nodeTop: LIST OF INT _ nodePtr.first.top, nodeTop.rest WHILE nodeTop#NIL DO minX _ MIN[ nodeTop.first, minX]; maxX _ MAX[ nodeTop.first, maxX]; ENDLOOP; FOR nodeBot: LIST OF INT _ nodePtr.first.bot, nodeBot.rest WHILE nodeBot#NIL DO minX _ MIN[ nodeBot.first, minX]; maxX _ MAX[ nodeBot.first, maxX]; ENDLOOP; cellMinX _ MIN[ cellMinX, minX]; IF nodePtr.first.row=none THEN { yMax: INT _ nofRows*pitch.y; AddRet [cell, [6, yMax], [minX, -2], CMos.met]; PutPin [cell, [6, 6], [minX, yMax-6-2], CMos.met, name]; PutPin [cell, [6, 6], [minX, -2], CMos.met, name]} ELSE { ctct: CD.ObPtr _ CMosContacts.CreatePolyCon[l: 8]; xEnd: INT _ rngBit*rngByte*cellWidth-leftTail; yMax: INT _ nofRows*pitch.y; yMid: INT _ nodePtr.first.row; AddRet [cell, [maxX-minX, 4], [minX, yMid], CMos.pol]; IF nodePtr.first.left THEN { cellMinX _ -leftTail; AddRet [cell, [minX+leftTail, 4], [-leftTail, yMid], CMos.pol]; PutPin [cell, [ 4, 4], [-leftTail, yMid], CMos.pol, name]}; IF nodePtr.first.right THEN { AddRet [cell, [xEnd-maxX, 4], [maxX, yMid], CMos.pol]; PutPin [cell, [ 4, 4], [xEnd-4, yMid], CMos.pol, name]}; FOR nodeTop: LIST OF INT _ nodePtr.first.top, nodeTop.rest WHILE nodeTop#NIL DO xx: INT _ nodeTop.first; AddRet [cell, [6, yMax-yMid], [xx, yMid-2], CMos.met]; PutPin [cell, [6, 6], [xx, yMax-6-2], CMos.met, name]; [] _ PWBasics.IncludeApplication[cell, ctct, [xx, 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], [xx, -2], CMos.met]; PutPin [cell, [6, 6], [xx, -2], CMos.met, name]; [] _ PWBasics.IncludeApplication[cell, ctct, [xx, yMid-2]]; ENDLOOP }; ENDLOOP; PWBasics.RepositionCell[design, cell]; iRect _ PWBasics.GetIRect[cell]; iRect.x1 _ iRect.x1 - (leftTail+cellMinX); iRect.x2 _ rngByte*rngBit*cellWidth + iRect.x1; PWBasics.SetIRect[cell, iRect]; RETURN[PWBasics.NameFromObj[cell]]}; GenMetalPinRow: PUBLIC PROC [ design: CD.Design, signals: LIST OF REF, sequential: BOOL _ FALSE ] RETURNS [cell: PW.ObjName] = { obj: CD.ObPtr _ CDCells.CreateEmptyCell[]; iRect: CD.Rect; FOR ii: INT IN [0..rngByte*rngBit) DO index: INT _ IF sequential THEN ii MOD rngBit ELSE ii / rngByte; byte: INT _ IF sequential THEN ii / rngBit ELSE ii MOD rngByte; names: List _ ExpandList[byte, index, signals, ioRestRef]; sigIndex: INT _ -1; FOR names _ names, names.rest WHILE names#NIL DO sigIndex _ sigIndex+1; IF names.first=NIL THEN LOOP; AddRet [obj, [6, 6], [ii*cellWidth+sigIndex*mPitch, 0], CMos.met]; PutPin [obj, [6, 6], [ii*cellWidth+sigIndex*mPitch, 0], CMos.met, names.first]; ENDLOOP; ENDLOOP; PWBasics.RepositionCell[design, obj]; iRect _ PWBasics.GetIRect[obj]; iRect.x1 _ iRect.x1 - leftTail; iRect.x2 _ rngByte*rngBit*cellWidth + iRect.x1; PWBasics.SetIRect[obj, iRect]; cell _ PWBasics.NameFromObj[obj] }; <> <> <> <> <<["Alpha.0", "Alpha.1", "Alpha.2", "Alpha.3", "Alpha.4", "Alpha.5", "Alpha.6", "Alpha.7"],>> <> <> <> <> <> <> <> <<>> <<>> <> <> END. <<>>