IFUCoreDataSBImpl.mesa,
Copyright c 1986 by Xerox Corporation. All rights reserved.
Last Edited by Curry, April 10, 1986 11:40:44 am PST
DIRECTORY CD, CCDUtils, Core, CoreBlock, CoreClasses, CoreCreate, CoreFrame, CoreGlue, CoreName, CoreOps, CoreWire, CoreXform, HashTable, IFUCoreData, IO, Rope;
IFUCoreDataSBImpl: CEDAR PROGRAM
IMPORTS CCDUtils, CoreBlock, CoreCreate, CoreFrame, CoreGlue, CoreName, CoreOps, CoreWire, CoreXform, HashTable, IFUCoreData, Rope =
BEGIN OPEN CM: CCDUtils;
ROPE: TYPE = Core.ROPE;
Signal: SIGNAL = CODE;
ExpandDataSBFrameSoft: CoreFrame.ExpandProc = { -- frameCT
eachWire: CoreOps.EachWireProc = {
IF wire.size#0 THEN RETURN;
wire ← CoreName.CtxWire[ctx, CoreName.WireNm[wire].n ];
[ ] ← CoreBlock.AddWireSide[wire, current]};
ctx:  CoreName.Context   ← CoreName.NewContext[];
rowPub: CoreWire.CWire    ← [frameCT.public];
frame:  REF CoreFrame.FrameRec ← NEW[CoreFrame.FrameRec ← [first: left]];
current: CoreBlock.Sides;
current ← left;  [ ] ← CoreOps.VisitWire[rowPub.f["left"].w,  eachWire];
current ← right;  [ ] ← CoreOps.VisitWire[rowPub.f["right"].w, eachWire];
frame.seq   ← NEW[CoreFrame.FrameSeq[0]];
frame.cell   ← CoreCreate.Cell[
public: CoreOps.CreateWire[CoreName.WiresFromCtx[ctx]], instances: NIL];
ctx    ← CoreName.KillContext[ctx];
frameCT.class ← CoreFrame.frameCellClass;
frameCT.data  ← frame;
CoreFrame.SetFrameExpandProc[soft, frameCT, NIL]};
CWire:  TYPE = CoreWire.CWire;
Node:   TYPE = CoreGlue.Node;
NodeRec:  TYPE = CoreGlue.NodeRec;
ExpandDataSBFrameHard: CoreFrame.ExpandProc = {
rowPub: CoreWire.CWire    ← [frameCT.public];
data:  IFUCoreData.DpCellData ← NARROW[frameCT.data];
name:  ROPE ← CoreName.CellNm[frameCT].n;
frame:  REF CoreFrame.FrameRec ← NEW[CoreFrame.FrameRec ←
[first: left, seq: NEW[CoreFrame.FrameSeq[0]]]];
frame.cell ← ThreeLevelSB[ cwire: rowPub, channels: data.channels, polyMaxRef: data.data ];
frameCT.data  ← frame;
frameCT.class ← CoreFrame.frameCellClass;
CoreFrame.SetFrameExpandProc[hard, frameCT, NIL];};
ThreeLevelSB: PROC[
cwire:   CWire,
channels:  INT,
polyMaxRef: REFNIL ] -- REF INT, lengths less than or equal to this are poly
RETURNS[cellType: Core.CellType] = {
range:   INT ← CoreXform.XformSize[cwire.f["top"].i[0]];
cellWidth: INT ← IFUCoreData.CellWidth[channels];
left:   INT ← CM.metW/2-CM.leftTail;
right:   INT ← CM.metW/2-CM.leftTail+range*cellWidth;
polyMax:  INTIF polyMaxRef#NIL THEN NARROW[polyMaxRef, REF INT]^ ELSE -1;
symTab:  HashTable.Table ←
BuildSymbolTable[cwire, CM.metPitch, polyMax, left, right, channels];
cellType  ← CoreGlue.ThreeLevelRoute[symTab, range, left, right, cellWidth, channels];
RETURN[cellType]};
BuildSymbolTable: PROC[cwire: CWire, pitchX, polyMax, left, right, channels: INT]
RETURNS[symTab: HashTable.Table] = {
cellWidth: INT ← IFUCoreData.CellWidth[channels];
GetNode: PROC[name: ROPE] RETURNS[node: Node] = {
IF IsPwr[name] THEN RETURN[NIL];
IF name=NIL THEN RETURN[NIL];
node ← NARROW[HashTable.Fetch[symTab, name].value];
IF node=NIL THEN {
node ← NEW[NodeRec ← [name: name, minX: right, maxX: 0, type: CM.cmosMet2]];
[ ] ← HashTable.Store[symTab, name, node] } };
MarkPolys: HashTable.EachPairAction = {
node: Node ← NARROW[value];
node.type ← IF node.maxX-node.minX <= polyMax THEN CM.cmosPoly ELSE CM.cmosMet2;
RETURN[FALSE] };
symTab ← HashTable.Create[equal: HashTable.RopeEqual, hash: HashTable.HashRope];
FOR row: INT IN [0..cwire.f["left"].w.size) DO
node: Node ← GetNode[cwire.f["left"].i[row].n];
IF node=NIL THEN LOOP;
node.minX ← left ENDLOOP;
FOR row: INT IN [0..cwire.f["right"].w.size) DO
node: Node ← GetNode[cwire.f["right"].i[row].n];
IF node=NIL THEN LOOP;
node.maxX ← right ENDLOOP;
FOR wd: INT IN [0..cwire.f["top"].w.size) DO
FOR bit: INT IN [0..CoreXform.XformSize[cwire.f["top"][0]]) DO
coord: INT ← bit*cellWidth + wd*pitchX;
node: Node ← GetNode[cwire.f["top"].i[wd].x[bit].n];
IF node=NIL THEN LOOP;
node.top  ← CONS [coord, node.top];
node.minX ← MIN [coord, node.minX];
node.maxX ← MAX [coord, node.maxX] ENDLOOP ENDLOOP;
FOR wd: INT IN [0..cwire.f["bot"].w.size) DO
FOR bit: INT IN [0..CoreXform.XformSize[cwire.f["bot"][0]]) DO
coord: INT ← bit*cellWidth + wd*pitchX;
node: Node ← GetNode[cwire.f["bot"].i[wd].x[bit].n];
IF node=NIL THEN LOOP;
node.bot  ← CONS [coord, node.bot];
node.minX ← MIN [coord, node.minX];
node.maxX ← MAX [coord, node.maxX] ENDLOOP ENDLOOP;
[ ] ← HashTable.Pairs[symTab,  MarkPolys]};
IsPwr: PROC[name: ROPE] RETURNS[BOOL] =
{RETURN[Rope.Find[name,"GND"]#-1 OR Rope.Find[name,"VDD"]#-1]};
log: IO.STREAM ← CoreFrame.GetLog[];
IFUCoreData.RegisterSubClassExpand[soft, "SwitchBox", ExpandDataSBFrameSoft];
IFUCoreData.RegisterSubClassExpand[hard, "SwitchBox", ExpandDataSBFrameHard];
END.