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;
Check for internal connections
[ ] ← 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;
Draw wires
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]};
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]};