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:
REF ←
NIL ]
-- 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: INT ← IF 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.