MCGen:
CEDAR
PROGRAM
IMPORTS CD, CDBasics, CDCells, CDDirectory, CDOrient, CDPinObjects, CDProperties, CMos, MC, MCCtl, MCMInterface, MCPadFrame, Onion, PW, PWPins, Rope=
BEGIN OPEN PW;
ROPE: TYPE = Rope.ROPE;
l: INT = CD.lambda;
-- Descriptors for the pad frame
MapCacheArray:
PROC [design:
CD.Design, nLines
, nCamColumns
, nRamColumns:
INT]
RETURNS [ObPtr] = {
pbusix: INT;
RepeatingCell:
PROC [cell: ObPtr]
RETURNS [ObPtr] =
INLINE {
RETURN[AbutY[design, FlipY[design, cell], cell]];
};
PBusName: PWPins.RenameProc = {
SELECT
TRUE
FROM
Rope.Equal[oldRope, "bus"] => newRope ← MC.IndexedName["PBus", pbusix];
Rope.Equal[oldRope, "adrsInLineMSB"] => newRope ← "PBus[20]";
Rope.Equal[oldRope, "adrsInLineLSB"] => newRope ← "PBus[21]";
ENDCASE => newRope ← oldRope;
};
Ram:
PROC[nColumns, nLines:
INT]
RETURNS [ObPtr] = {
ramCell: ObPtr ← Get[design, "SRamTwoBits"];
ramTop: ObPtr ← Get[design, "RamTop"];
ramColumn: ObPtr ← ArrayY[design, ramCell, nLines];
ramDualColumn: ObPtr ← AbutY[design,
AbutX[design, ramColumn, ramColumn],
ramTop];
renamedDualColumn, result: ObPtr;
pbusix ← 0;
result ← PWPins.RenamePins[design, ramDualColumn, PBusName];
pbusix ← pbusix+1;
THROUGH [2..nColumns/2]
DO
renamedDualColumn ← PWPins.RenamePins[design, ramDualColumn, PBusName];
result ← AbutX[design, result, renamedDualColumn];
pbusix ← pbusix+1;
ENDLOOP;
RETURN[result];
};
PowerStrap:
PROC[nLines:
INT]
RETURNS[ObPtr] = {
powerStrapCell: ObPtr ← Get[design, "PowerStrap"];
repeatingCell: ObPtr ← AbutY[design, FlipY[design, powerStrapCell], powerStrapCell];
powerStrapTop: ObPtr ← Get[design, "PowerStrapTop"];
RETURN[AbutY[design,
ArrayY[design, repeatingCell, nLines/2],
powerStrapTop]];
};
RamAccess:
PROC[nLines:
INT]
RETURNS [ObPtr] = {
ramAccessCell: ObPtr ← Get[design, "RamAccessCore"];
repeatingCell: ObPtr ← AbutY[design, FlipY[design, ramAccessCell], ramAccessCell];
ramAccessCtlTop: ObPtr ← Get[design, "RamAccessCtlTop"];
ramAccessCtlTop ← PWPins.RenamePins[design, ramAccessCtlTop, PBusName];
RETURN[AbutY[design,
ArrayY[design, repeatingCell, nLines/2],
ramAccessCtlTop]];
};
Cam:
PROC[nColumns, nLines:
INT]
RETURNS [ObPtr] = {
groupSize: INT = 10; -- number of cells between straps to metal2
nGroups: INT = nColumns/groupSize;
nRemainingColumns: INT = nColumns MOD groupSize;
column, strapColumn, renamedColumn: ObPtr;
camBitCell: ObPtr ← Get[design, "SCamBit"];
camBitTop: ObPtr ← Get[design, "CamTop"];
camStrapCell: ObPtr ← Get[design, "SCamStrap"];
camStrapTop: ObPtr ← Get[design, "SCamStrapTop"];
result: ObPtr;
column ← AbutY[design,
ArrayY[design, RepeatingCell[camBitCell], nLines/2],
camBitTop];
strapColumn ← AbutY[design,
ArrayY[design, RepeatingCell[camStrapCell], nLines/2],
camStrapTop] ;
This is a hack that'll work only for this version; must fix for later
pbusix ← 0;
result ← strapColumn;
THROUGH [1..groupSize]
DO
renamedColumn ← PWPins.RenamePins[design, column, PBusName];
result ← AbutX[design, result, renamedColumn];
pbusix ← pbusix+1;
ENDLOOP;
THROUGH [2..nGroups]
DO
result ← AbutX[design, result, strapColumn];
THROUGH [1..groupSize]
DO
renamedColumn ← PWPins.RenamePins[design, column, PBusName];
result ← AbutX[design, result, renamedColumn];
pbusix ← pbusix+1;
ENDLOOP;
ENDLOOP;
THROUGH [1..nRemainingColumns]
DO
renamedColumn ← PWPins.RenamePins[design, column, PBusName];
result ← AbutX[design, result, renamedColumn];
pbusix ← pbusix+1;
ENDLOOP;
result ← AbutX[design, result, strapColumn];
RETURN[result];
};
VPValid:
PROC [nLines:
INT]
RETURNS [ObPtr] = {
vpValidCoreCell: ObPtr ← Get[design, "VPValidCore"];
vpValidTop: ObPtr ← Get[design, "VPValidTop"];
RETURN[AbutY[design,
ArrayY[design, RepeatingCell[vpValidCoreCell], nLines/2],
vpValidTop]];
};
CamAccess:
PROC [nLines:
INT]
RETURNS [ObPtr] = {
camAccessCell: ObPtr ← Get[design, "CAMAccessCore"];
camAccessTop: ObPtr ← Get[design, "CamAccessTop"];
RETURN[AbutY[design,
ArrayY[design, RepeatingCell[camAccessCell], nLines/2],
camAccessTop]];
};
RPValid:
PROC [nLines:
INT]
RETURNS [ObPtr] = {
rpValidCoreLeftCell: ObPtr ← Get[design, "RPValidCoreLeft"];
rpValidTopLeft: ObPtr ← Get[design, "RPValidTopLeft"];
rpValidCoreBitCell: ObPtr ← Get[design, "RPValidCoreBit"];
rpValidTop: ObPtr ← Get[design, "RPValidTop"];
rpValidCoreCell: ObPtr;
rpValidTop ← PWPins.RenamePins[design, rpValidTop, PBusName];
rpValidCoreCell ← rpValidCoreLeftCell;
THROUGH [1..
MC.nEntriesPerLine]
DO
rpValidCoreCell ← AbutX[design, rpValidCoreCell, rpValidCoreBitCell];
ENDLOOP;
RETURN[AbutY[design,
ArrayY[design, RepeatingCell[rpValidCoreCell], nLines/2],
AbutX[design, rpValidTopLeft, rpValidTop]]];
};
Ref:
PROC [nLines:
INT]
RETURNS [ObPtr] = {
refCoreCell: ObPtr ← Get[design, "RefCore"];
refTop: ObPtr ← Get[design, "RefTop"];
RETURN[AbutY[design,
ArrayY[design, RepeatingCell[refCoreCell], nLines/2],
refTop] ];
};
Adrs:
PROC [nLines:
INT]
RETURNS [ObPtr] = {
DecoderFunction: XYFunction = {
op: ObPtr;
IF XthBitOfN[nCols-1-x, y]
THEN op ← adrsDecoderOneCell
ELSE op ← adrsDecoderZeroCell;
IF XthBitOfN[0, y]
THEN RETURN[op]
ELSE RETURN[FlipY[design, op]];
};
adrsGndLeftCell: ObPtr ← Get[design, "AdrsGndLeft"];
adrsGndLeftTop: ObPtr ← Get[design, "AdrsGndLeftTop"];
adrsDecoderZeroCell: ObPtr ← Get[design, "AdrsDecoderZero"];
adrsDecoderOneCell: ObPtr ← Get[design, "AdrsDecoderOne"];
adrsDecoderBitTop: ObPtr ← Get[design, "AdrsDecoderBitTop"];
adrsGndRightCell: ObPtr ← Get[design, "AdrsGndRight"];
adrsGndRightTop: ObPtr ← Get[design, "AdrsGndRightTop"];
adrsDriverCell: ObPtr ← Get[design, "AdrsDriver"];
adrsDriverTop: ObPtr ← Get[design, "AdrsDriverTop"];
gndLeftColumn, gndRightColumn, driverColumn, top: ObPtr;
col, nCols: INT;
NewName: PWPins.RenameProc = {
SELECT
TRUE
FROM
Rope.Equal[oldRope, "adrs"] => newRope ← MC.IndexedName["ArrayAdrsxAB", col];
ENDCASE => newRope ← oldRope;
};
nCols ← IF nLines=TwoToTheLog2[nLines] THEN Log2[nLines] ELSE Log2[nLines]+1;
gndLeftColumn ← ArrayY[design, RepeatingCell[adrsGndLeftCell], nLines/2];
gndRightColumn ← ArrayY[design, RepeatingCell[adrsGndRightCell], nLines/2];
driverColumn ← ArrayY[design, RepeatingCell[adrsDriverCell], nLines/2];
top ← adrsGndLeftTop; col ← 0;
THROUGH [1..nCols]
DO
renamed: ObPtr ← PWPins.RenamePins[design, adrsDecoderBitTop, NewName];
top ← AbutX[design, top, renamed];
col ← col+1;
ENDLOOP;
top ← AbutX[design, top, adrsGndRightTop, adrsDriverTop];
RETURN[AbutY[design,
AbutX[design, gndLeftColumn, MapFunction[design, DecoderFunction, 0, nCols, 0, nLines], gndRightColumn, driverColumn],
top]];
};
RETURN[AbutListX[design, LIST[Adrs[nLines], Ref[nLines], RPValid[nLines], CamAccess[nLines], VPValid[nLines], Cam[nCamColumns, nLines], RamAccess[nLines], PowerStrap[nLines], Ram[nRamColumns, nLines]]]];
};
inputs:
LIST
OF
ROPE ←
LIST[
counter inputs (should go away in version 2 of Map Cache)
"Incr", "ArrayAdrsxBA[4]", "ArrayAdrsxBA[3]", "ArrayAdrsxBA[2]", "ArrayAdrsxBA[1]", "ArrayAdrsxBA[0]",
normal inputs
"nMAdCyclexBA",
"MCmdxBA[0]", "MCmdxBA[1]", "MCmdxBA[2]", "MCmdxBA[3]",
"MCSelectedxBA",
"MDataxBA[2]", "MDataxBA[3]", "MDataxBA[4]", "MDataxBA[5]",
"CyclexBA[0]", "CyclexBA[1]",
"CyclexAB[0]", "CyclexAB[1]",
"arrayMatchxAB",
"wtProtectFlag",
"ResetxBA", "ResetxAB"];
MapCacheControl:
PROC [design:
CD.Design]
RETURNS [result: ObPtr] = {
alpsResult, alpsResultLatchandDrive, feedBack, feedBackLatchandDrive: CD.ObPtr;
fedBackSignals: LIST OF ROPE ← LIST ["CyclexAB[0]", "CyclexAB[1]", "CyclexBA[0]", "CyclexBA[1]", "ArrayAdrsxAB[0]", "ArrayAdrsxAB[1]", "ArrayAdrsxAB[2]", "ArrayAdrsxAB[3]", "ArrayAdrsxAB[4]", "ResetxBA"];
arrayDrivenSignals: LIST OF ROPE ← LIST ["Incr", "arrayMatchxBA", "wtProtectFlag"];
table: AlpsBool.TableOfVariables ← MCCtl.CreateTable[inputs];
Get each generator to put its outputs into table
MCCtl.Microcode[table];
MCCtl.Counter[table];
MCCtl.Order[table]; -- omit order for debugging version
MCCtl.StateMachine[table];
Optimize the table as required
table ← MCCtl.Permute[table, permuteFast];
table ← MCCtl.Permute[table, permuteAllCases];
alpsResult ← Rot270[design, MCCtl.GenerateLayout[design, table]];
alpsResultLatchandDrive ← MCCtl.MakeAlpsLatchandDrive[design, alpsResult];
feedBackLatchandDrive ← MCCtl.MakeFeedBackLatchandDrive[design, MCCtl.ListCat[fedBackSignals, arrayDrivenSignals]];
feedBack ← MCCtl.MakeFeedBack[design, alpsResult, feedBackLatchandDrive];
result ← AbutX[design,
AbutY[design, feedBackLatchandDrive, feedBack],
AbutY[design, alpsResultLatchandDrive, alpsResult]];
result ← PWPins.RenamePins[design, result];
Record the alps outputs and the array driven signals in ctlOutNames
MCCtl.InitCtlOutNames[];
MCCtl.AddTableToCtlOutNames[table];
MCCtl.AddListToCtlOutNames[arrayDrivenSignals];
};
busNames: LIST OF ROPE ← NIL;
MapCacheBuses:
PROC [design:
CD.Design, len:
INT]
RETURNS [result: ObPtr] = {
layer: CD.Layer ← CMos.met2;
wireLength: INT ← len;
wireThickness: INT ← 4*2;
wireSeparation: INT ← 5*2;
CtlOut Signals
busNames ← MCCtl.ctlOutNames;
Utility Signals
busNames ← MCCtl.ListCat[LIST["phA", "nphA", "phB", "nphB", "Vnbias", "Vpbias", "NotDebug"], busNames];
RBus Signals — omit for debugging version
FOR i: INT DECREASING IN [0..31] DO busNames ← CONS[MC.IndexedName["RBus", i], busNames] ENDLOOP;
QBus Signals — omit for debugging version
FOR i: INT DECREASING IN [0..9] DO busNames ← CONS[MC.IndexedName["QBus", i], busNames] ENDLOOP;
PBus Signals
FOR i: INT DECREASING IN [0..24] DO busNames ← CONS[MC.IndexedName["PBus", i], busNames] ENDLOOP;
VBus Signals
busNames ← MCCtl.ListCat[LIST["VBus.VPV", "VBus.RPV"], busNames];
result ← MC.MakeBusX[design, layer, busNames, wireLength, wireThickness, wireSeparation];
Now rename all the pins so they'll pop out to the topmost level
result ← PWPins.RenamePins[design, result];
};
RingWidth: Onion.RingWidthProc
-- [netName: ROPE] RETURNS [ringWidth: D2Basic.Number] -- = {
ringWidth ← IF Rope.Equal[netName, "Vdd"] THEN MC.VddRingWidth ELSE IF Rope.Equal[netName, "Gnd"] THEN MC.GndRingWidth ELSE 8;
};
SelectInnerPins: PWPins.RenameProc
-- [oldRope: ROPE] RETURNS [newRope: ROPE] -- = {
IF Rope.Equal[oldRope, "Vdd"] OR Rope.Equal[oldRope, "Gnd"] OR Rope.Equal[oldRope, "drMBusxBA"] THEN RETURN[oldRope];
SELECT
TRUE
FROM
Rope.Equal["vdd", oldRope] => RETURN["Vdd"];
Rope.Equal["gnd", oldRope] => RETURN["Gnd"];
Rope.Match["MExt[*].dataIn", oldRope] => RETURN[oldRope];
Rope.Match["MExt[*].dataOut", oldRope] => RETURN[oldRope];
Rope.Match["MCmd[*].dataIn", oldRope] => RETURN[oldRope];
Rope.Match["MCmd[*].dataOut", oldRope] => RETURN[oldRope];
Rope.Match["MData[*].dataIn", oldRope] => RETURN[oldRope];
Rope.Match["MData[*].dataOut", oldRope] => RETURN[oldRope];
Rope.Equal["MCSelected.dataIn", oldRope] => RETURN["MCSelected"];
Rope.Equal["Reset.dataIn", oldRope] => RETURN["Reset"];
Rope.Equal["Reset.dataOut", oldRope] => RETURN["Reset"];
Rope.Equal["nMAdCycle.dataIn", oldRope] => RETURN["nMAdCycle"];
Rope.Equal["nMAdCycle.dataOut", oldRope] => RETURN["nMAdCycle"];
Rope.Match["CycleABZeroxAB", oldRope] => RETURN[NIL];
ENDCASE => {};
FOR names:
LIST
OF
ROPE ← MCPadFrame.padNames, names.rest
WHILE names#
NIL
DO
IF Rope.Equal[names.first, oldRope] THEN RETURN[oldRope];
ENDLOOP;
FOR names:
LIST
OF
ROPE ← busNames, names.rest
WHILE names#
NIL
DO
IF Rope.Equal[names.first, oldRope] THEN RETURN[oldRope];
ENDLOOP;
FOR names:
LIST
OF
ROPE ← inputs, names.rest
WHILE names#
NIL
DO
IF Rope.Equal[names.first, oldRope] OR Rope.Equal[Rope.Cat["Not", names.first], oldRope] THEN RETURN[NIL];
ENDLOOP;
newRope ← NIL; MC.TTYOut[" killed ", oldRope, " "];
};
Channel:
PUBLIC
PROC [design:
CD.Design, bottomOb, topOb:
CD.ObPtr, size:
INT, params: Onion.LayersParameters ← Onion.channelDefaultParameters]
RETURNS [cell:
CD.ObPtr] = {
bottomObRect: CD.Rect ← CD.InterestRect[bottomOb];
topObRect: CD.Rect ← CD.InterestRect[topOb];
inner: CD.ObPtr ← CDCells.CreateEmptyCell[];
outer: CD.ObPtr ← CDCells.CreateEmptyCell[];
KeepInner: PWPins.AppEnumerator
-- [app: CD.ApplicationPtr] RETURNS [quit: BOOL ← FALSE] -- = {
name: ROPE ← CDPinObjects.GetName[app];
realSize: CD.Position ← CDOrient.OrientedSize[app.ob.size, app.orientation];
location: CD.Position ← CDBasics.SubPoints[app.location, CDBasics.BaseOfRect[bottomObRect]];
IF PWPins.GetSide[bottomOb, app].side#PWPins.top THEN RETURN;
IF CDPinObjects.GetLayer[app]#params.radialLayer
THEN {
Output["*** Top Pin ", name, " on BottomOb discarded: not of radialLayer material.\n"];
RETURN;
};
[] ← Onion.IncludePin[inner, name, CDPinObjects.GetLayer[app], realSize, location];
};
KeepOuter: PWPins.AppEnumerator
-- [app: CD.ApplicationPtr] RETURNS [quit: BOOL ← FALSE] -- = {
name: ROPE ← CDPinObjects.GetName[app];
realSize: CD.Position ← CDOrient.OrientedSize[app.ob.size, app.orientation];
location: CD.Position ← CDBasics.SubPoints[app.location, CDBasics.BaseOfRect[topObRect]];
IF PWPins.GetSide[topOb, app].side#PWPins.bottom THEN RETURN;
IF CDPinObjects.GetLayer[app]#params.radialLayer
THEN {
Output["*** Bottom Pin ", name, " on TopOb discarded: not of radialLayer material.\n"];
RETURN;
};
[] ← Onion.IncludePin[outer, name, CDPinObjects.GetLayer[app], realSize, location];
};
[] ← PWPins.EnumerateEdgePins[bottomOb, KeepInner];
[] ← Onion.IncludeOb[inner, bottomOb, [0, 0]];
[] ← CDCells.RepositionCell[inner, NIL];
[] ← CDDirectory.Include[design, inner, "BottomInner"];
[] ← PWPins.EnumerateEdgePins[topOb, KeepOuter];
[] ← Onion.IncludeOb[outer, topOb, [0, 0]];
CDCells.SetInterestRect[outer, [0, -(bottomObRect.y2-bottomObRect.y1+size), MAX[bottomObRect.x2-bottomObRect.x1, topObRect.x2-topObRect.x1], 0]];
[] ← CDCells.RepositionCell[outer, NIL];
[] ← CDDirectory.Include[design, outer, "TopOuter"];
cell ← Onion.LRSRoute[design, inner, outer, [0, 0], params].cell;
CDCells.SetInterestRect[cell, [0, 0, PW.Size[cell].x, PW.Size[cell].y+topObRect.y2-topObRect.y1]];
};
KeepPinsOnRight:
PUBLIC
PROC [design:
CD.Design, ob:
CD.ObPtr]
RETURNS [cell:
CD.ObPtr] =
BEGIN
cellPtr: CD.CellPtr;
KeepPinOnEdge: PWPins.AppEnumerator
-- [app: CD.ApplicationPtr] RETURNS [quit: BOOL ← FALSE] -- = {
newApp: CD.ApplicationPtr;
name: ROPE ← CDPinObjects.GetName[app];
IF PWPins.GetSide[ob, app].side#PWPins.right THEN RETURN;
newApp ←
NEW[
CD.Application ← [
ob: CDPinObjects.CreatePinOb[app.ob.size],
location: app.location, orientation: app.orientation,
properties: CDProperties.CopyProps[app.properties]]];
CDPinObjects.SetName[newApp, name];
cellPtr.contents ← CONS[newApp, cellPtr.contents];
};
app: CD.ApplicationPtr ← NEW[CD.Application ← [ob: ob]];
CDProperties.PutPropOnApplication[app, $StopEnumerateDeepPins, $StopEnumerateDeepPins];
cell ← CDCells.CreateEmptyCell[]; cellPtr ← NARROW[cell.specificRef];
[] ← PWPins.EnumerateEdgePins[ob, KeepPinOnEdge];
cellPtr.contents ← CONS[app, cellPtr.contents];
CDCells.SetInterestRect[cell, CD.InterestRect[ob]];
[] ← CDCells.RepositionCell[cell, NIL];
[] ← CDDirectory.Include[design, cell, "KeepPinsOnRight"];
END;
MakeMapCache: UserProc = {
mc, mcCtl, topToBus, mcArray, arrayToBus, mcBus, mcTop, mcMInterface, mcCtlToInterfaceGlue, frame, copyrightSign, myName: PW.ObPtr;
mcSize: CD.Position;
params: Onion.LayersParameters ← NEW[Onion.LayersParametersRec ← Onion.defaultLayersParameters^];
params.ringWidth ← RingWidth;
params.wireExtendProc ← Onion.WireExtendMetToMet;
SetDefaultSource[design, OpenDesign["///MapCacheCellLibrary.dale"]];
mcArray ← MapCacheArray[design, MC.nLines, MC.nCamColumns, MC.nRamColumns];
mcCtl ← MapCacheControl[design];
mcMInterface ← MCMInterface.MBusInterface[design, PW.Size[mcCtl].y];
mcCtlToInterfaceGlue ← MCMInterface.AlpsToMBusInterfaceGlue[design, mcCtl];
mcTop ← AbutX[design, mcCtl, mcCtlToInterfaceGlue, mcMInterface];
mcSize.x ← MAX[PW.Size[mcArray].x, PW.Size[mcTop].x]+16;
mcTop ← AbutX[design, mcTop, MC.RightFillerCell[design, mcTop, mcSize.x-PW.Size[mcTop].x]];
mcArray ← AbutX[design, mcArray, MC.RightFillerCell[design, mcArray, mcSize.x-PW.Size[mcArray].x]];
mcBus ← MapCacheBuses[design, mcSize.x];
arrayToBus ← MC.ConnectTopToBus[design, mcArray, mcBus];
topToBus ← MC.ConnectBotToBus[design, mcTop, mcBus];
mcBus ← KeepPinsOnRight[design, mcBus];
mc ← PW.CreateEmptyCell[];
mcSize.y ← PW.Size[mcArray].y+2*PW.Size[mcBus].y+PW.Size[mcTop].y;
PW.IncludeInCell[design, mc, mcArray, [0, 0]];
PW.IncludeInCell[design, mc, arrayToBus, [0, PW.Size[mcArray].y]];
PW.IncludeInCell[design, mc, mcBus, [0, PW.Size[mcArray].y]];
PW.IncludeInCell[design, mc, mcBus, [0, PW.Size[mcArray].y+PW.Size[mcBus].y]];
PW.IncludeInCell[design, mc, topToBus, [0, PW.Size[mcArray].y+PW.Size[mcBus].y]];
PW.IncludeInCell[design, mc, mcTop, [0, PW.Size[mcArray].y+2*PW.Size[mcBus].y]];
CDCells.SetInterestRect[mc, [0, 0, mcSize.x, mcSize.y]];
PW.IncludeInDirectory[design, mc, "mc"];
mc ← PWPins.RenamePins[design, mc, SelectInnerPins];
mc ← Onion.MakeInner[design, mc];
mc ← MCPadFrame.Shell[design, mc];
mc ← Onion.MakeInner[design, mc];
MC.TTYOut["\nMap Cache Generation Done.\n"];
frame ← MCPadFrame.PadFrame[design];
mc ← Onion.LRSRoute[design, mc, frame, Onion.Center[mc, frame], params].cell;
-- include the logo
SetDefaultSource[design, OpenDesign["///MCLogo.dale"]];
copyrightSign ← PW.Get[design, "copyrightSign"];
myName ← PW.Get[design, "myName"];
PW.IncludeInCell[design, mc, copyrightSign, [-500*l, 0], 2];
PW.IncludeInCell[design, mc, myName, [PW.Size[mc].x+300*l, 5*l], 6];
RETURN[mc];
};
MakeMapCacheArray: UserProc = {
SetDefaultSource[design, OpenDesign["///MapCacheCellLibrary.dale"]];
RETURN[MapCacheArray[design, 4, 4, 4]];
};
MakeMapCacheControl: UserProc = {
SetDefaultSource[design, OpenDesign["///MapCacheCellLibrary.dale"]];
RETURN[MapCacheControl[design ]];
};
MakePadFrame: UserProc = {
SetDefaultSource[design, OpenDesign["///MapCacheCellLibrary.dale"]];
RETURN[MCPadFrame.PadFrame[design]];
};
SimpleTest: UserProc = {
SetDefaultSource[design, OpenDesign["///MapCacheCellLibrary.dale"]];
RETURN[MCMInterface.AlpsToMBusInterfaceGlue[design, MapCacheControl[design]]];
};
Register[MakePadFrame, "MakePadFrame"];
Register[MakeMapCacheArray, "MakeMapCacheArray"];
Register[MakeMapCacheControl, "MakeMapCacheControl"];
Register[MakeMapCache, "MakeMapCache"];
Register[SimpleTest, "SimpleTest"];
END.