RoseFromStructure.Mesa
Last Edited by: Spreitzer, March 12, 1985 10:29:03 am PST
DIRECTORY Asserting, CompareDataStructure, CompareOps, CompareTransforms, Convert, IO, OrderedSymbolTableRef, Rope, RoseTypes, RoseCreate, SwitchTypes, Transistors;
RoseFromStructure: CEDAR PROGRAM
IMPORTS Asserting, SO: CompareOps, CT: CompareTransforms, Convert, IO, OrderedSymbolTableRef, Rope, RoseCreate, RoseTypes, SwitchTypes, Transistors
= {OPEN S: CompareDataStructure, R: RoseTypes;
ROPE: TYPE = Rope.ROPE;
GenericIO: TYPE = REF GenericIORep;
GenericIORep: TYPE = RECORD [
ports: SEQUENCE COMPUTED CARDINAL OF SwitchTypes.SwitchValHolder];
Thresholds: TYPE = REF ThresholdsRep;
ThresholdsRep: TYPE = RECORD [
weakRatio, strongRatio: REAL];
thresholdsFn: REF ANYNEW [ROPE ← "thresholdsFn"];
MergeFromStructure: PROC [design: S.Design, weakRatio: REAL ← 3.0, strongRatio: REAL ← 0.3] = {
thresholds: Thresholds ← NEW [ThresholdsRep ← [weakRatio, strongRatio]];
FOR sct: S.CellType ← CT.FirstCellType[design], CT.NextCellType[sct] WHILE sct # NIL DO
cellTypeName: ROPESO.PickAName[sct.names];
oldCellType: R.CellType ← RoseCreate.GetCellType[cellTypeName];
IF oldCellType = NIL THEN ReallyDefineCellType[sct, cellTypeName, thresholds];
ENDLOOP;
weakRatio ← weakRatio;
};
DefineCellType: PROC [design: S.Design, cellTypeName: ROPE, weakRatio: REAL ← 3.0, strongRatio: REAL ← 0.3] = {
thresholds: Thresholds ← NEW [ThresholdsRep ← [weakRatio, strongRatio]];
sct: S.CellType ← SO.ToType[design, cellTypeName];
ReallyDefineCellType[sct, cellTypeName, thresholds];
};
ReallyDefineCellType: PROC [sct: S.CellType, cellTypeName: ROPE, thresholds: Thresholds] = {
SO.EnsureParts[sct];
SO.EnsurePorts[sct];
IF SO.ExpansionKnown[sct] THEN {
rosePorts: R.Ports ← RosePortsFromStructure[sct];
rct: R.CellType;
rct ← RoseCreate.RegisterCellType[
name: cellTypeName,
expandProc: ExpandFromStructure,
ioCreator: CreateIOForStructure,
evals: [],
ports: rosePorts,
typeData: sct];
sct.otherPrivate ← Asserting.AssertFn1[fn: thresholdsFn, val: thresholds, inAdditionTo: sct.otherPrivate];
};
};
RosePortsFromStructure: PROC [sct: S.CellType] RETURNS [rosePorts: R.Ports] = {
strPorts: S.PortS ← sct.ports;
rosePorts ← NEW [R.PortsRep[strPorts.length]];
FOR pi: NAT IN [0 .. strPorts.length) DO
portName: ROPESO.PickAName[strPorts[pi].names];
isIn: BOOL ← Asserting.Test[$IN, NIL, strPorts[pi].other];
isOut: BOOL ← Asserting.Test[$OUT, NIL, strPorts[pi].other];
isBi: BOOL ← Asserting.Test[$BIDIR, NIL, strPorts[pi].other];
isDird: BOOL ← isIn OR isOut OR isBi;
confused: BOOL ← (isIn AND isOut) OR (isOut AND isBi) OR (isBi AND isIn);
IF confused THEN SO.Warn[[], "Confused port %g", IO.rope[SO.GlobalPortName[sct, pi]]];
FOR nnl: S.RopeList ← strPorts[pi].netNames, nnl.rest WHILE nnl # NIL DO
net: S.Vertex ← NARROW[SO.Lookup[sct.parts, nnl.first]];
IF NOT SO.PickAName[net.names].Equal[portName] THEN ERROR;
ENDLOOP;
rosePorts[pi] ← [
firstWord: pi,
wordCount: SwitchTypes.wordsPerSwitchValPort,
name: portName,
type: SwitchTypes.bitType,
input: isIn OR isBi OR NOT isDird,
output: isOut OR isBi OR NOT isDird,
XPhobic: FALSE];
ENDLOOP;
};
CreateIOForStructure: PROC [ct: R.CellType] RETURNS [ioAsAny: REF ANY] = {
sct: S.CellType ← NARROW[ct.typeData];
ioAsAny ← NEW [GenericIORep[sct.ports.length]];
};
ExpandFromStructure: PROC [thisCell: R.Cell, to: R.ExpansionReceiver] = {
PerNode: PROC [ra: REF ANY] RETURNS [stop: BOOL] = {
v: S.Vertex ← NARROW[SO.AntiAlias[ra]];
name: ROPESO.PickAName[v.names];
already: R.Node ← RoseCreate.LookupCellNode[thisCell, name];
stop ← FALSE;
IF already # NIL THEN RETURN;
SELECT v.class FROM
net => {
[] ← to.class.NodeInstance[
erInstance: to.instance,
name: name,
type: SwitchTypes.bitType];
};
cell => NULL;
ENDCASE => ERROR};
PerCell: PROC [ra: REF ANY] RETURNS [stop: BOOL] = {
v: S.Vertex ← NARROW[SO.AntiAlias[ra]];
name: ROPESO.PickAName[v.names];
already: R.Cell ← NARROW[thisCell.components.Lookup[name]];
stop ← FALSE;
IF already # NIL THEN RETURN;
SELECT v.class FROM
net => NULL;
cell => {
typeName: ROPE;
connections: ROPE ← EncodeConnections[v];
isTrans: BOOL;
nType: BOOL;
mode: Transistors.Mode;
ratio: REAL;
[isTrans, nType, mode, ratio] ← TransistorStuff[v.type];
IF isTrans
THEN typeName ← Transistors.Transistor[[
strength: SELECT ratio FROM
>thresholds.weakRatio => driveWeak,
<thresholds.strongRatio => driveStrong,
ENDCASE => drive,
positive: nType,
mode: mode
]].name
ELSE typeName ← SO.PickAName[v.type.names];
[] ← to.class.CellInstance[
erInstance: to.instance,
instanceName: name,
typeName: typeName,
interfaceNodes: connections];
};
ENDCASE => ERROR};
sct: S.CellType ← NARROW[thisCell.type.typeData];
thresholds: Thresholds ← NARROW[Asserting.FnVal[fn: thresholdsFn, from: sct.otherPrivate]];
sct.parts.EnumerateIncreasing[PerNode];
sct.parts.EnumerateIncreasing[PerCell];
};
EncodeConnections: PROC [cell: S.Vertex] RETURNS [connections: ROPE] = {
connections ← NIL;
FOR e: S.Edge ← cell.firstEdge, e.sides[cell].next WHILE e # NIL DO
IF e.sides[cell].v # cell THEN ERROR;
IF connections # NIL THEN connections ← connections.Cat[", "];
connections ← connections.Cat[
Convert.RopeFromRope[SO.PickAName[cell.type.ports[e.portIndex].names]],
": ",
Convert.RopeFromRope[SO.PickAName[e.sides[net].v.names]]
];
ENDLOOP;
};
TransistorStuff: PROC [sct: S.CellType] RETURNS [isTrans, nType: BOOL, mode: Transistors.Mode, ratio: REAL] = {
lora, lenwid: Asserting.Terms;
len: REAL ← 2;
wid: REAL ← 2;
isTrans ← FALSE;
nType ← TRUE;
mode ← Enhancement;
ratio ← 1.0;
lenwid ← Asserting.FnVals[fn: $MOSFETShape, from: sct.otherPublic];
IF lenwid = NIL OR lenwid.rest = NIL OR lenwid.rest.rest # NIL THEN RETURN;
WITH lenwid.first SELECT FROM
rr: REF REAL => len ← rr^;
ri: REF INT => len ← ri^;
ENDCASE => SIGNAL R.Warning[IO.PutFR["Ill-formatted assertion ($MOSFETShape %g ..) on %g", IO.refAny[lenwid.first], IO.rope[SO.GlobalCellTypeName[sct]]]];
WITH lenwid.rest.first SELECT FROM
rr: REF REAL => wid ← rr^;
ri: REF INT => wid ← ri^;
ENDCASE => SIGNAL R.Warning[IO.PutFR["Ill-formatted assertion ($MOSFETShape .. %g) on %g", IO.refAny[lenwid.rest.first], IO.rope[SO.GlobalCellTypeName[sct]]]];
ratio ← len/wid;
lora ← Asserting.FnVals[fn: $MOSFETFlavor, from: sct.otherPublic];
IF lora = NIL THEN RETURN;
IF lora.rest = NIL OR lora.rest.rest # NIL THEN SIGNAL R.Warning[IO.PutFR[
"Ill-formatted assertion %g on %g",
IO.refAny[CONS[$MOSFETFlavor, lora]],
IO.rope[SO.GlobalCellTypeName[sct]] ]]
ELSE {
SELECT lora.first FROM
$n => nType ← TRUE;
$p => nType ← FALSE;
ENDCASE => SIGNAL R.Warning[IO.PutFR["Illegal $MOSFETFlavor type %g on %g", IO.refAny[lora.first], IO.rope[SO.GlobalCellTypeName[sct]]]];
SELECT lora.rest.first FROM
$E => mode ← Enhancement;
$D => mode ← Depletion;
ENDCASE => SIGNAL R.Warning[IO.PutFR["Illegal $MOSFETFlavor mode %g on %g", IO.refAny[lora.rest.first], IO.rope[SO.GlobalCellTypeName[sct]]]];
};
isTrans ← TRUE;
};
}.