MCImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Created by: Sindhu, June 23, 1985 2:57:33 pm PDT
Last Edited by: Sindhu, July 10, 1985 7:57:27 pm PDT
Last Edited by: Serlet, July 6, 1985 11:48:32 am PDT
DIRECTORY
CD, CDOrient, CDCells, CDPinObjects, CDProperties, CMos, Convert, MC, MCCtl, PW, TerminalIO, PWCmos, PWPins, Rope;
MCImpl: CEDAR PROGRAM
IMPORTS CD, CDOrient, CDCells, CDPinObjects, CDProperties, CMos, Convert, TerminalIO, PWCmos, PWPins, PW, Rope
EXPORTS MC =
BEGIN
l: INT = CD.lambda;
nLines: PUBLIC INT ← 32;
nCamColumns: PUBLIC INT ← 20;
nRamColumns: PUBLIC INT ← 44;
nEntriesPerLine: PUBLIC INT ← 4;
VddRingWidth: PUBLIC INT ← 100*l;
GndRingWidth: PUBLIC INT ← 100*l;
CellToIR: PUBLIC PROC [cellpos: CD.Position, obj: CD.ObPtr] RETURNS [irpos: CD.Position] = {
ir: CD.Rect ← CD.InterestRect[obj];
irpos ← [cellpos.x-ir.x1, cellpos.y-ir.y1];
};
IRToCell: PUBLIC PROC [irpos: CD.Position, obj: CD.ObPtr] RETURNS [cellpos: CD.Position] = {
ir: CD.Rect ← CD.InterestRect[obj];
cellpos ← [irpos.x+ir.x1, irpos.y+ir.y1];
};
SelectAll: PUBLIC MC.SelectPinProc = {sel ← TRUE};
IndexedName: PUBLIC PROC [name: Rope.ROPE, index: INT] RETURNS [Rope.ROPE] = {
RETURN[Rope.Cat[name, "[", Convert.RopeFromInt[index], "]"]];
};
TTYOut: PUBLIC PROC [r1, r2, r3, r4, r5, r6: Rope.ROPENIL] = {
TerminalIO.WriteRope[Rope.Cat[r1, r2, r3, r4, r5, r6]];
};
CreateFillerCell: PUBLIC PROC [design: CD.Design, size: CD.Position] RETURNS [result: PW.ObPtr] = {
result ← PW.CreateEmptyCell[];
CDCells.SetInterestRect[result, [0, 0, size.x, size.y]];
PW.IncludeInCell[design,
result,
CDPinObjects.CreatePinOb[[2, 2]],
[size.x/2, size.y/2]];
PW.IncludeInDirectory[design, result, "FillerCell"];
};
TopFillerCell: PUBLIC PROC [design: CD.Design, obj: PW.ObPtr, fillDist: INT, selectPinProc: MC.SelectPinProc ← SelectAll] RETURNS [result: PW.ObPtr] = {
objIR: CD.Rect ← CD.InterestRect[obj];
resultPtr: CD.CellPtr;
ProcessEdgePin: PWPins.AppEnumerator = {
side: PWPins.Side ← PWPins.GetSide[obj, app].side;
newPin: CD.ApplicationPtr;
IF side=PWPins.top AND selectPinProc[app] THEN {
pinSize: CD.Position ← CDOrient.OrientedSize[app.ob.size, app.orientation];
Put down the rectangle
PW.IncludeInCell[design,
result,
PWCmos.Rect[CDPinObjects.GetLayer[app],
[pinSize.x, fillDist]],     -- size
[app.location.x-objIR.x1, 0]];    -- location
Put down a pin at the end of it
newPin ← NEW[CD.Application ← [
ob: CDPinObjects.CreatePinOb[app.ob.size],
location: [app.location.x-objIR.x1, fillDist-pinSize.y], orientation: app.orientation,
properties: CDProperties.CopyProps[app.properties]]];
CDPinObjects.SetName[newPin, CDPinObjects.GetName[app]];
resultPtr.contents ← CONS[newPin, resultPtr.contents];
};
};
IF fillDist<=0 THEN ERROR;
result ← PW.CreateEmptyCell[]; resultPtr ← NARROW[result.specificRef];
CDCells.SetInterestRect[result, [0, 0, objIR.x2-objIR.x1, fillDist]];
[] ← PWPins.EnumerateEdgePins[obj, ProcessEdgePin];
PW.IncludeInDirectory[design, result, "Filler"];
result ← PWPins.RenamePins[design, result];
};
LeftFillerCell: PUBLIC PROC [design: CD.Design, obj: PW.ObPtr, fillDist: INT, selectPinProc: MC.SelectPinProc ← SelectAll] RETURNS [result: PW.ObPtr] = {
RETURN[PW.Rot90[design, TopFillerCell[design, PW.Rot270[design, obj], fillDist, selectPinProc]]];
};
RightFillerCell: PUBLIC PROC [design: CD.Design, obj: PW.ObPtr, fillDist: INT, selectPinProc: MC.SelectPinProc ← SelectAll] RETURNS [result: PW.ObPtr] = {
RETURN[PW.Rot270[design, TopFillerCell[design, PW.Rot90[design, obj], fillDist, selectPinProc]]];
};
MakeBusX: PUBLIC PROC [design: CD.Design, layer: CD.Layer, names: LIST OF Rope.ROPE, wireLength, wireThickness, wireSeparation: INT] RETURNS [result: PW.ObPtr] = {
resultPtr: CD.CellPtr;
nWires: INT ← 0;
IF wireLength<=0 OR wireThickness<=0 THEN ERROR;
result ← PW.CreateEmptyCell[]; resultPtr ← NARROW[result.specificRef];
FOR l: LIST OF Rope.ROPE ← names, l.rest UNTIL l=NIL DO
leftPin, rightPin: CD.ApplicationPtr;
wireLocation: CD.Position ← [0, wireSeparation+nWires*(wireThickness+wireSeparation)];
PW.IncludeInCell[design,
result,
PWCmos.Rect[layer, [wireLength, wireThickness]],
wireLocation];
Put pins at both ends
leftPin ← NEW[CD.Application ← [
ob: CDPinObjects.CreatePinOb[[2, wireThickness]],
location: wireLocation, orientation: CDOrient.original]];
rightPin ← NEW[CD.Application ← [
ob: CDPinObjects.CreatePinOb[[2, wireThickness]],
location: [wireLength-2, wireLocation.y], orientation: CDOrient.original]];
CDPinObjects.SetName[leftPin, l.first];
CDPinObjects.SetName[rightPin, l.first];
CDPinObjects.SetLayer[leftPin, layer];
CDPinObjects.SetLayer[rightPin, layer];
resultPtr.contents ← CONS[leftPin, resultPtr.contents];
resultPtr.contents ← CONS[rightPin, resultPtr.contents];
nWires ← nWires+1;
ENDLOOP;
CDCells.SetInterestRect[result, [0, 0, wireLength, wireSeparation+nWires*(wireThickness+wireSeparation)]];
PW.IncludeInDirectory[design, result, "Bus"];
};
MakeBusY: PUBLIC PROC [design: CD.Design, layer: CD.Layer, names: LIST OF Rope.ROPE, wireLength, wireThickness, wireSeparation: INT] RETURNS [result: PW.ObPtr] = {
result ← PW.Rot270[design, MakeBusX[design, layer, names, wireLength, wireThickness, wireSeparation]];
};
ConnectTopToBus: PUBLIC PROC [design: CD.Design, obj: PW.ObPtr, bus: PW.ObPtr] RETURNS[result: PW.ObPtr] = {
objIR: CD.Rect ← CD.InterestRect[obj];
busIR: CD.Rect ← CD.InterestRect[bus];
resultIR: CD.Rect ← [0, 0, objIR.x2-objIR.x1, busIR.y2-busIR.y1];
ProcessObjPin: PWPins.AppEnumerator = {
[app: CD.ApplicationPtr] RETURNS [quit: BOOLFALSE]
side: PWPins.Side ← PWPins.GetSide[obj, app].side;
objPinName: Rope.ROPE ← CDPinObjects.GetName[app];
objPinLayer: CD.Layer ← CDPinObjects.GetLayer[app];
busPin: CD.ApplicationPtr ← NIL;
SetBusPin: PWPins.AppEnumerator = {
[app: CD.ApplicationPtr] RETURNS [quit: BOOLFALSE]
side: PWPins.Side ← PWPins.GetSide[bus, app].side;
IF Rope.Equal[CDPinObjects.GetName[app], objPinName] AND side=PWPins.left
THEN busPin ← app;
};
IF side=PWPins.top THEN {
appSize: CD.Position ← CDOrient.OrientedSize[app.ob.size, app.orientation];
busPinSize: CD.Position;
Set the global variable busPin corresponding to this obj pin - yuck!
[] ← PWPins.EnumerateEdgePins[bus, SetBusPin];
IF busPin=NIL THEN {
TTYOut["\n** MCImpl Warning: pin named """, objPinName, """ not found."];
TTYOut[" MCImpl: ", objPinName, " "];
RETURN;
};
busPinSize ← CDOrient.OrientedSize[busPin.ob.size, busPin.orientation];
Put down rectangle
PW.IncludeInCell[design,
result,
PWCmos.Rect[CDPinObjects.GetLayer[app],
[appSize.x, busPin.location.y+busPinSize.y-busIR.y1]], -- size
[app.location.x-objIR.x1, 0]];          -- location
Put down contact
PW.IncludeInCell[design,
result,
PWCmos.Contact[CMos.met, CMos.met2],
[app.location.x-objIR.x1-2, busPin.location.y-busIR.y1]];
};
};
result ← PW.CreateEmptyCell[];
CDCells.SetInterestRect[result, resultIR];
[] ← PWPins.EnumerateEdgePins[obj, ProcessObjPin];
PW.IncludeInDirectory[design, result, "ExtensionTopToBus"];
};
ConnectBotToBus: PUBLIC PROC [design: CD.Design, obj: PW.ObPtr, bus: PW.ObPtr] RETURNS[result: PW.ObPtr] = {
result ← PW.FlipY[design, ConnectTopToBus[design, PW.FlipY[design, obj], PW.FlipY[design, bus]]];
};
ConnectRightToBus: PUBLIC PROC [design: CD.Design, obj: PW.ObPtr, bus: PW.ObPtr] RETURNS[result: PW.ObPtr] = {
result ← PW.Rot270[design, ConnectTopToBus[design, PW.Rot90[design, obj], PW.Rot90[design, bus]]];
};
ConnectLeftToBus: PUBLIC PROC [design: CD.Design, obj: PW.ObPtr, bus: PW.ObPtr] RETURNS[result: PW.ObPtr] = {
result ← PW.Rot90[design, ConnectTopToBus[design, PW.Rot270[design, obj], PW.Rot270[design, bus]]];
};
END.