MCMInterfaceImpl:
CEDAR
PROGRAM
IMPORTS CD, CDCells, CDPinObjects, MC, PW, PWPins, Rope
EXPORTS MCMInterface =
BEGIN OPEN PW;
AllButVddAndGnd: MC.SelectPinProc
-- [pin: CD.ApplicationPtr] RETURNS [sel: BOOL] -- = {
name: Rope.ROPE ← CDPinObjects.GetName[pin];
sel ← NOT (Rope.Match["Vdd", name, FALSE] OR Rope.Match["Gnd", name, FALSE])
};
InputSection:
PROC [design:
CD.Design]
RETURNS [result: ObPtr] = {
phBSlice: PW.ObPtr ← PW.Get[design, "phBLatchandDriveSlice"];
drCtlSlice: PW.ObPtr ← PW.Get[design, "DrCtlSlice"];
fillerSlice: PW.ObPtr ← PW.Get[design, "FillerSlice"];
slice: PW.ObPtr;
sliceIR: CD.Rect ← CD.InterestRect[phBSlice];
inputName, outputName, drName: Rope.ROPE;
index, inputBase, outputBase: INT;
NewName: PWPins.RenameProc = {
SELECT
TRUE
FROM
Rope.Equal[oldRope, "in"] => newRope← Rope.Cat[MC.IndexedName[inputName, index-inputBase], ".dataIn"];
Rope.Equal[oldRope, "out"] => newRope ← MC.IndexedName[outputName, index-outputBase];
Rope.Equal[oldRope, "Dr"] => newRope ← drName;
ENDCASE => newRope ← oldRope;
};
result ← PW.CreateEmptyCell[];
index ← 0;
First put MBusHi25 slices
outputName ← "PBus"; drName ← "PSelMBusHi25xAB";
MCmd slices
inputBase ← outputBase ← index;
inputName ← "MCmd";
THROUGH [0..3]
DO
slice ← PWPins.RenamePins[design, phBSlice, NewName];
PW.IncludeInCell[design, result, slice, [index*(sliceIR.x2-sliceIR.x1), 0]];
index ← index+1;
ENDLOOP;
slice ← PWPins.RenamePins[design, drCtlSlice, NewName];
PW.IncludeInCell[design, result, slice, [index*(sliceIR.x2-sliceIR.x1), 0]];
index ← index+1;
MExt slices
inputBase ← outputBase ← index;
inputName ← "MExt";
THROUGH [0..3]
DO
slice ← PWPins.RenamePins[design, fillerSlice, NewName];
PW.IncludeInCell[design, result, slice, [index*(sliceIR.x2-sliceIR.x1), 0]];
index ← index+1;
ENDLOOP;
MData slices
inputBase ← index; outputBase ← index-4;
inputName ← "MData";
THROUGH [0..20]
DO
slice ← PWPins.RenamePins[design, phBSlice, NewName];
PW.IncludeInCell[design, result, slice, [index*(sliceIR.x2-sliceIR.x1), 0]];
index ← index+1;
ENDLOOP;
slice ← PWPins.RenamePins[design, drCtlSlice, NewName];
PW.IncludeInCell[design, result, slice, [index*(sliceIR.x2-sliceIR.x1), 0]];
index ← index+1;
Now put MBusLo25 slices
outputName ← "PBus"; drName ← "PSelMBusLo25xAB";
inputBase ← index-3; outputBase ← index;
THROUGH [0..24]
DO
slice ← PWPins.RenamePins[design, phBSlice, NewName];
PW.IncludeInCell[design, result, slice, [index*(sliceIR.x2-sliceIR.x1), 0]];
index ← index+1;
ENDLOOP;
slice ← PWPins.RenamePins[design, drCtlSlice, NewName];
PW.IncludeInCell[design, result, slice, [index*(sliceIR.x2-sliceIR.x1), 0]];
index ← index+1;
And finally the MBusLo10 slices — omit for debugging version
outputName ← "QBus"; drName ← "QSelMBusLo10xAB";
inputBase ← index-18; outputBase ← index;
THROUGH [0..9] DO
slice ← PWPins.RenamePins[design, phBSlice, NewName];
PW.IncludeInCell[design, result, slice, [index*(sliceIR.x2-sliceIR.x1), 0]];
index ← index+1;
ENDLOOP;
slice ← PWPins.RenamePins[design, drCtlSlice, NewName];
PW.IncludeInCell[design, result, slice, [index*(sliceIR.x2-sliceIR.x1), 0]];
index ← index+1;
CDCells.SetInterestRect[result, [0, 0, index*(sliceIR.x2-sliceIR.x1), sliceIR.y2-sliceIR.y1]];
PW.IncludeInDirectory[design, result, "MInterfaceInputSection"];
};
OutputSection:
PROC [design:
CD.Design]
RETURNS [result: ObPtr] = {
phASlice: PW.ObPtr ← PW.FlipY[design, PW.Get[design, "phALatchandDriveSlice"]];
drCtlSlice: PW.ObPtr ← PW.FlipY[design, PW.Get[design, "DrCtlSlice"]];
fillerSlice: PW.ObPtr ← PW.FlipY[design, PW.Get[design, "FillerSlice"]];
slice: PW.ObPtr;
sliceIR: CD.Rect ← CD.InterestRect[phASlice];
inputName, outputName: Rope.ROPE;
index, inputBase, outputBase: INT;
NewName: PWPins.RenameProc = {
SELECT
TRUE
FROM
Rope.Equal[oldRope, "in"] => newRope ← MC.IndexedName[inputName, index-inputBase];
Rope.Equal[oldRope, "out"] => newRope← Rope.Cat[MC.IndexedName[outputName, index-outputBase], ".dataOut"];
ENDCASE => newRope ← oldRope;
};
result ← PW.CreateEmptyCell[];
index ← 0;
inputName ← "PBus"; -- for debugging version
MCmd slices
outputName ← "MCmd";
inputBase ← outputBase ← index;
THROUGH [0..3]
DO
slice ← PWPins.RenamePins[design, phASlice, NewName];
PW.IncludeInCell[design, result, slice, [index*(sliceIR.x2-sliceIR.x1), 0]];
index ← index+1;
ENDLOOP;
slice ← PWPins.RenamePins[design, drCtlSlice, NewName];
MExt slices
outputName ← "MExt";
inputBase ← outputBase ← index;
THROUGH [0..3]
DO
slice ← PWPins.RenamePins[design, phASlice, NewName];
PW.IncludeInCell[design, result, slice, [index*(sliceIR.x2-sliceIR.x1), 0]];
index ← index+1;
ENDLOOP;
MData slices— of course the bottom 3 bits will not be driven
outputName ← "MData";
inputBase ← index-4; outputBase ← index;
THROUGH [0..20]
DO
slice ← PWPins.RenamePins[design, phASlice, NewName];
PW.IncludeInCell[design, result, slice, [index*(sliceIR.x2-sliceIR.x1), 0]];
index ← index+1;
ENDLOOP;
CDCells.SetInterestRect[result, [0, 0, index*(sliceIR.x2-sliceIR.x1), sliceIR.y2-sliceIR.y1]];
PW.IncludeInDirectory[design, result, "MInterfaceOutputSection"];
};
MBusInterface:
PUBLIC
PROC [design:
CD.Design, ySize:
INT]
RETURNS [result: ObPtr] = {
inSect: PW.ObPtr ← InputSection[design];
ioGlue: PW.ObPtr ← FlipX[design, PW.Get[design, "FeedBackLatchToOutputLatchGlue"]];
outSect: PW.ObPtr ← OutputSection[design];
inSectSize: CD.Position ← PW.Size[inSect];
ioGlueSize: CD.Position ← PW.Size[ioGlue];
outSectSize: CD.Position ← PW.Size[outSect];
result ← PW.CreateEmptyCell[];
CDCells.SetInterestRect[result, [0, 0, inSectSize.x+ioGlueSize.x+outSectSize.x, ySize]];
Fill the input and output sections up so their y dimention equals ySize
inSect ← AbutY[design, inSect, MC.TopFillerCell[design, inSect, ySize-inSectSize.y, AllButVddAndGnd]];
outSect ← AbutY[design, outSect, MC.TopFillerCell[design, outSect, ySize-outSectSize.y, AllButVddAndGnd]];
Now put them together
PW.IncludeInCell[design, result, inSect, [0, 0]];
PW.IncludeInCell[design, result, ioGlue, [inSectSize.x, 0]];
PW.IncludeInCell[design, result, outSect, [inSectSize.x+ioGlueSize.x, 0]];
PW.IncludeInDirectory[design, result, "MInterface"];
};
AlpsToMBusInterfaceGlue:
PUBLIC
PROC [design:
CD.Design, mcCtl:
PW.ObPtr]
RETURNS[result:
PW.ObPtr] = {
kludgeSlicephB: PW.ObPtr ← PW.Get[design, "MInterfaceKludgeSlicephB"];
kludgeSliceCycleABZero: PW.ObPtr ← PW.Get[design, "MInterfaceCycleABZero"];
biasSlice: PW.ObPtr ← PW.Get[design, "BiasGenerator"];
fillerSlice: PW.ObPtr ← PW.Get[design, "FillerSlice"];
drCtlSlice: PW.ObPtr ← PW.Get[design, "DrCtlSlice"];
bottom, topFiller, topAlpsConnection: PW.ObPtr;
bottomSize: CD.Position;
mcCtlSize: CD.Position ← PW.Size[mcCtl];
name, drName: Rope.ROPE;
index: INT;
NewName: PWPins.RenameProc = {
SELECT
TRUE
FROM
Rope.Equal[oldRope, "in"] => newRope ← Rope.Cat[name, ".dataIn"];
Rope.Equal[oldRope, "outxBA"] => newRope ← Rope.Cat[name, "xBA"];
Rope.Equal[oldRope, "NotoutxBA"] => newRope ← Rope.Cat["Not", name, "xBA"];
Rope.Equal[oldRope, "Dr"] => newRope ← drName;
ENDCASE => newRope ← oldRope;
};
IndexedNewName: PWPins.RenameProc = {
SELECT
TRUE
FROM
Rope.Equal[oldRope, "in"] => newRope ← Rope.Cat[MC.IndexedName[name, index], ".dataIn"];
Rope.Equal[oldRope, "outxBA"] => newRope ← MC.IndexedName[Rope.Cat[name, "xBA"], index];
Rope.Equal[oldRope, "NotoutxBA"] => newRope ← MC.IndexedName[Rope.Cat["Not", name, "xBA"], index];
ENDCASE => newRope ← oldRope;
};
First make the bottom part
Drive ctl slice for alps
name ← ""; drName ← "NotDebug";
bottom ← PWPins.RenamePins[design, drCtlSlice, NewName];
bottom ← AbutX[design, fillerSlice, bottom, biasSlice];
name ← "nMAdCycle";
bottom ← AbutX[design, bottom, PWPins.RenamePins[design, kludgeSliceCycleABZero, NewName]];
name ← "MCmd"; index ← 0;
THROUGH [0..3]
DO
bottom ← AbutX[design, bottom, PWPins.RenamePins[design, kludgeSliceCycleABZero, IndexedNewName]];
index ← index+1;
ENDLOOP;
name ← "MCSelected";
bottom ← AbutX[design, bottom, PWPins.RenamePins[design, kludgeSliceCycleABZero, NewName]];
name ← "MData"; index ← 2;
THROUGH [2..5]
DO
bottom ← AbutX[design, bottom, PWPins.RenamePins[design, kludgeSliceCycleABZero, IndexedNewName]];
index ← index+1;
ENDLOOP;
name ← "Reset";
bottom ← AbutX[design, bottom, PWPins.RenamePins[design, kludgeSlicephB, NewName]];
bottomSize ← PW.Size[bottom];
Now put result together
result ← PW.CreateEmptyCell[];
CDCells.SetInterestRect[result, [0, 0, bottomSize.x, mcCtlSize.y]];
topFiller ← MC.TopFillerCell[design, bottom, mcCtlSize.y-bottomSize.y, AllButVddAndGnd];
topAlpsConnection ← MC.ConnectRightToBus[design, mcCtl, topFiller];
PW.IncludeInCell[design, result, bottom, [0, 0]];
PW.IncludeInCell[design, result, topFiller, [0, bottomSize.y]];
PW.IncludeInCell[design, result, topAlpsConnection, [0, 0]];
PW.IncludeInDirectory[design, result, "MInterface"];
};
END.