SwitchBoxRow:
PUBLIC
PROC [
-- Assumes byte interleaving (rngBit cells of rngByte bits)
design: CD.Design,
name: PW.ROPE,
rowType: CD.Layer,
topSeq: BOOL ← FALSE,
top: LIST OF REF,
left: List,
right: List,
bot: LIST OF REF,
botSeq: BOOL ← FALSE,
fixGV:
BOOL ←
TRUE ]
RETURNS [cellName: PW.ObjName] = {
colType: CD.Layer ← CMos.met;
pitch: Size ← [metPitch, (IF rowType=CMos.pol THEN polPitch ELSE met2Pitch)];
cntctW: INT ← IF rowType = CMos.pol THEN 8 ELSE 10;
cntctBotTail: INT ← IF rowType = CMos.pol THEN 2 ELSE 2;
colWW: INT ← (pitch.x-2)/2; -- 14=>6
rowWW: INT ← (pitch.y-2)/2; -- 10=>4, 18=>8
ctct:
CD.ObPtr ← (
SELECT rowType
FROM
CMos.pol => CMosContacts.CreatePolyCon [l: cntctW],
CMos.met2 => CMosContacts.CreateMmCon [l: cntctW],
ENDCASE => ERROR);
nofRows: INT ← 0;
nodes: LIST OF Node ← NIL;
assigned: LIST OF Node ← NIL;
nAsigned: LIST OF Node ← NIL;
straightPass: LIST OF Node ← NIL;
tempNodes: LIST OF Node ← NIL;
cell: CD.ObPtr ← CDCells.CreateEmptyCell[];
cellMinX: INT ← rightEdge;
topTail: INT ← 4;
botTail: INT ← SELECT rowType FROM CMos.pol=>2, CMos.met2=>4, ENDCASE=>ERROR;
yMax: INT ← 0;
yMin: INT ← 0;
iRect: CD.Rect;
symTab: SymTab.Ref ← SymTab.Create[];
SortNodes: SymTab.EachPairAction = {
node: Node ← NARROW[val];
IF node.row#rowNotAssigned
THEN assigned ← AddAssignedNodeToAssigned[node, assigned] -- Unique rows
ELSE
IF node.minX=node.maxX
THEN straightPass ← UpdateNotAssigned[straightPass, node] -- Biggest first
ELSE nAsigned ← UpdateNotAssigned[nAsigned, node]; -- Biggest first
RETURN[FALSE] };
IF fixGV
THEN {
left ← DelGVFromList[left];
right ← DelGVFromList[right];
top ← AddGVToLIST[top, IF topSeq=botSeq THEN TRUE ELSE FALSE];
bot ← AddGVToLIST[bot, IF topSeq=botSeq THEN TRUE ELSE FALSE] };
nofRows ← UpdateSymTabWithList[symTab, left, left, pitch, nofRows];
nofRows ← UpdateSymTabWithList[symTab, right, right, pitch, nofRows];
FOR index:
INT
DECREASING
IN [0..rngBit)
DO
FOR byte:
INT
DECREASING
IN [0..rngByte)
DO
topl: List ← ExpandList[byte, index, top];
botl: List ← ExpandList[byte, index, bot];
IF fixGV
THEN {
topl ← DelGVFromList[topl]; -- won't delete indexed versions (ie. "GND.23")
botl ← DelGVFromList[botl]}; -- won't delete indexed versions (ie. "GND.23")
[ ] ← UpdateSymTabWithList[symTab, topl, top, pitch, 0, byte, index, topSeq];
[ ] ← UpdateSymTabWithList[symTab, botl, bottom, pitch, 0, byte, index, botSeq];
ENDLOOP;
ENDLOOP;
Check for internal connections
[ ] ← SymTab.Pairs[symTab, SortNodes];
FOR nodePtr:
LIST
OF Node ← nAsigned, nodePtr.rest
WHILE nodePtr#
NIL
DO
assigned ← AddUnassignedNodeToAssigned
[nodePtr.first, assigned, nofRows, pitch, rowType];
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 - cntctBotTail + cntctW + topTail;
yMin ← 0 - cntctBotTail - botTail;
FOR nodePtr:
LIST
OF Node ← straightPass, nodePtr.rest
WHILE nodePtr#
NIL
DO
name: PW.ROPE ← nodePtr.first.name;
minX: INT ← nodePtr.first.minX;
maxX: INT ← nodePtr.first.maxX;
cellMinX ← MIN[ cellMinX, minX];
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]]];
AddRet [cell, [colWW, yMax-yMin], [minX, yMin], colType];
PutPin [cell, [colWW, colWW], [minX, yMax-colWW], colType, name];
PutPin [cell, [colWW, colWW], [minX, yMin], colType, name];
ENDLOOP;
FOR nodePtr:
LIST
OF Node ← assigned, nodePtr.rest
WHILE nodePtr#
NIL
DO
yMid: INT ← nodePtr.first.row;
name: PW.ROPE ← nodePtr.first.name;
minX: INT ← nodePtr.first.minX;
maxX: INT ← nodePtr.first.maxX;
cellMinX ← MIN[ cellMinX, minX];
IF minX=leftEdge
THEN {
PutPin [cell, [rowWW, rowWW], [minX, yMid], rowType, name]};
IF maxX=rightEdge
THEN {
PutPin [cell, [rowWW, rowWW], [maxX-rowWW, yMid], rowType, name]};
AddRet [cell, [maxX-minX, rowWW], [minX, yMid], rowType];
FOR nodeTop:
LIST
OF
INT ← nodePtr.first.top, nodeTop.rest
WHILE nodeTop#
NIL
DO
xx: INT ← nodeTop.first;
AddRet [cell, [colWW, yMax-yMid], [xx, yMid], colType];
PutPin [cell, [colWW, colWW], [xx, yMax-colWW], colType, name];
cellMinX ← MIN[ cellMinX, xx-2]; -- -2 for left contact overhang
[] ← PWBasics.IncludeApplication[cell, ctct, [xx-2, 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-yMin], [xx, yMin], colType];
PutPin [cell, [6, 6], [xx, yMin], colType, name];
cellMinX ← MIN[ cellMinX, xx-2]; -- -2 for left contact overhang
[] ← PWBasics.IncludeApplication[cell, ctct, [xx-2, yMid-2]];
ENDLOOP ;
ENDLOOP;
PWBasics.RepositionCell[design, cell];
iRect ← CD.InterestRect[cell];
iRect.x1 ← iRect.x1 - (cellMinX-leftEdge);
iRect.x2 ← iRect.x1 + (rightEdge-leftEdge);
CDCells.SetInterestRect[cell, iRect];
cellName ← PWBasics.NameFromObj[cell];
cellName ← PW.ReName[cellName, name];
RETURN[cellName]};
GenMetalPinRow:
PUBLIC
PROC [
design: CD.Design,
name: PW.ROPE,
height: INT ← 6,
top: LIST OF REF,
seq: BOOL ← FALSE,
fixGV:
BOOL ←
TRUE ]
RETURNS [cellName: PW.ObjName] = {
obj: CD.ObPtr ← CDCells.CreateEmptyCell[];
iRect: CD.Rect;
FOR ii:
INT
IN [0..rngByte*rngBit)
DO
names: List;
byte, index: INT;
sigIndex: INT ← -1;
[byte, index] ← IFUPW.ByteBitFromIndex[ii, seq];
names ← ExpandList[byte, index, top];
IF fixGV THEN 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], CMos.met];
PutPin [obj, [6, 6], [ii*cellWidth+sigIndex*metPitch, 0], CMos.met, names.first];
ENDLOOP;
ENDLOOP;
PWBasics.RepositionCell[design, obj];
iRect ← CD.InterestRect[obj];
iRect.x1 ← iRect.x1 - leftTail;
iRect.x2 ← rngByte*rngBit*cellWidth + iRect.x1;
CDCells.SetInterestRect[obj, iRect];
cellName ← PWBasics.NameFromObj[obj];
cellName ← PW.ReName[cellName, name];
RETURN[cellName]};