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;
Check for internal connections
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;
Draw wires
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] };
SwitchBoxRowTest: PW.UserProc = { RETURN[ SwitchBoxRow[
design: design,
topRow: LIST["PBus." ],
rightCol: LIST
["Alpha.0", "Alpha.1", "Alpha.2", "Alpha.3", "Alpha.4", "Alpha.5", "Alpha.6", "Alpha.7"],
leftCol: NIL,
botRow: LIST["PBus.", LIST["Alpha.", NIL, NIL, NIL] ] ] ] };
BusXForm: PW.UserProc = {
signals: LIST OF REF ← LIST["IPBus.", "PCBus."];
topName: PW.ObjName ← GenMetalPinRow[design, signals, TRUE];
botName: PW.ObjName ← GenMetalPinRow[design, signals];
RETURN[PW.AbutY[botName,topName]]};