RoseReadSimImpl:
CEDAR
PROGRAM
IMPORTS FS, IO, Rope, RoseCreate, SimRead, SwitchTypes, Transistors
EXPORTS RoseReadSim =
ReadSim:
PUBLIC
PROCEDURE [to: RoseTypes.ExpansionReceiver, within: Cell, fileName:
ROPE, formatName:
ROPE ←
NIL
--means Chipmonk .sim format--, smallNode:
REAL ← 1E-14, bigNode:
REAL ← 1E-12] =
BEGIN
EnsureNode:
PROC [name:
ROPE]
RETURNS [node: Node]=
BEGIN
initialValue: ROPE ← NIL;
strength: REF SwitchTypes.Strength ← SwitchTypes.refCharge;
node ← RoseCreate.LookupNode[from: within, path: LIST [name]];
IF node =
NIL
THEN {
IF name.Equal["VDD",
FALSE]
THEN {initialValue ← "H"; strength ← SwitchTypes.refInput}
ELSE
IF name.Equal["GND",
FALSE]
THEN {initialValue ← "L"; strength ← SwitchTypes.refInput};
node ← to.class.NodeInstance[
erInstance: to.instance,
name: name,
type: SwitchTypes.bitType,
initialValue: initialValue,
initData: strength];
};
END;
GotTransistor:
PROCEDURE [pd: SimRead.ParseData, cd: SimRead.ClientData] =
BEGIN
gate: Node ← EnsureNode[pd.gate];
[] ← EnsureNode[pd.source];
[] ← EnsureNode[pd.drain];
[] ← to.class.CellInstance[
erInstance: to.instance,
instanceName: IO.PutFR["t%g", IO.card[tCount ← tCount + 1]],
typeName: Transistors.Transistor[[
strength:
SELECT pd.transistorType
FROM
nD, pD => driveWeak,
nE, pE => drive,
ENDCASE => ERROR,
positive:
SELECT pd.transistorType
FROM
nE, nD => TRUE,
pE, pD => FALSE,
ENDCASE => ERROR,
mode:
SELECT pd.transistorType
FROM
nD, pD => Depletion,
nE, pE => Enhancement,
ENDCASE => ERROR]].name,
interfaceNodes:
IO.PutFR["gate: %g, ch1: %g, ch2: %g",
IO.rope[pd.gate], IO.rope[pd.source], IO.rope[pd.drain]]
];
AddCap[gate, pd];
END;
tCount: INT ← 0;
GotNode:
PROCEDURE [pd: SimRead.ParseData, cd: SimRead.ClientData] =
{AddCap[EnsureNode[pd.name], pd]};
AddCap:
PROC [node: Node, pd: SimRead.ParseData] =
BEGIN
cap: REAL;
size: SwitchTypes.Strength;
IF pd.capEstimateClass = ignore OR node.name.Equal["vdd", FALSE] OR node.name.Equal["gnd", FALSE] THEN RETURN;
cap ← SwitchTypes.GetCapacitance[node];
IF (pd.capEstimateClass = absolute) AND (cap > 0) THEN ERROR;
cap ← cap + pd.capacitanceEstimate;
size ← IF cap < smallNode THEN chargeWeak ELSE IF cap > bigNode THEN chargeStrong ELSE charge;
SwitchTypes.SetCapacitance[node, cap];
SwitchTypes.SetSizes[node, size, size];
END;
from: IO.STREAM ← NIL;
roseSimClient: SimRead.Client;
format: SimRead.Format ← SimRead.GetFormat[IF formatName # NIL THEN formatName ELSE "Chipmonk"];
TRUSTED {roseSimClient ←
NEW [SimRead.ClientRep ← [
GotTransistor: GotTransistor,
GotNode: GotNode]]};
from ← FS.StreamOpen[fileName: fileName];
SimRead.FromStream[from: from, client: roseSimClient, format: format];
from.Close[];
END;