Rosemary.mesa
Barth, April 4, 1986 3:30:00 pm PST
DIRECTORY Core, CoreClasses, CoreFlat, HashTable, Ports;
Rosemary: CEDAR DEFINITIONS = BEGIN
ROPE: TYPE = Core.ROPE;
Behaviour Registration
BindCellType: PROC [cellType: Core.CellType, roseClassName: ROPE] RETURNS [sameCellType: Core.CellType];
BindCellClass: PROC [cellClass: Core.CellClass, roseClassName: ROPE] RETURNS [sameCellClass: Core.CellClass];
Register: PROC [roseClassName: ROPE, init: InitProc ← NIL, evalSimple: EvalProc ← NIL] RETURNS [sameRoseClassName: ROPE];
InitProc: TYPE = PROC [cellType: Core.CellType, p: Ports.Port] RETURNS [stateAny: REF ANYNIL];
Initializes the state and the value from the context contained in the cell type. Multiple calls must return different copies of the any bits in the state record which actually represent the state of the simulation.
StateCopyProc: TYPE = PROC [from: REF ANY, to: REF ANY];
Copies the state.
EvalProc: TYPE = PROC [p: Ports.Port, stateAny: REF ANY];
Must be idempotent.
Stop: SIGNAL [msg: ROPENIL, data: REF ANYNIL];
This signal may be raised when a behavioural proc wishes to display a string to a user and wait for a proceed or abort.
Instantiation and Relaxation
AddCutSets: PROC [cellType: Core.CellType, cs1, cs2, cs3, cs4, cs5, cs6: ROPENIL] RETURNS [sameCellType: Core.CellType];
Adds the cell type to the specified cut sets.
SetFixedWire: PROC [wire: Core.Wire, level: Ports.Level] RETURNS [sameWire: Core.Wire];
Sets the value of the wire and indicates that the value of the wire may not be changed by Rosemary.
SetWireSize: PROC [wire: Core.Wire, size: WireSize] RETURNS [sameWire: Core.Wire];
Sets the order of magnitude wire size.
WireSize: TYPE = Ports.Drive[chargeWeak..chargeStrong];
SetTransistorCellTypeSize: PROC [transistor: Core.CellType, size: TransistorSize] RETURNS [sameTransistor: Core.CellType];
Sets the order of magnitude transistor size.
SetTransistorInstanceSize: PROC [transistor: CoreClasses.CellInstance, size: TransistorSize] RETURNS [sameTransistor: CoreClasses.CellInstance];
TransistorSize: TYPE = Ports.Drive[driveWeak..driveStrong];
InstantiateCellType: PROC [cellType: Core.CellType, testPort: Ports.Port, statePoints: NAT ← 0] RETURNS [simulation: Simulation];
The cellType must have a behavioural class on its property list.
InstantiateInstances: PROC [cellType: Core.CellType, testPort: Ports.Port, cutSet: ROPENIL, statePoints: NAT ← 0] RETURNS [simulation: Simulation];
Initialize: PROC [simulation: Simulation, steady: BOOLTRUE];
Reset the state. If steady then the wires are initialized to "easy" values like L and 0. If not steady then they are initialized to X, if possible, otherwise they are initialized randomly. The init procs are called again for each cell.
Settle: PROC [simulation: Simulation, updateProc: UpdateProc ← NIL];
UpdateProc: TYPE = PROC [wire: RoseWire];
Relaxes the simulation. The port supplied to either flavor of instantiate must not be changed during the execution of this procedure. If an update procedure is supplied it is called each time a RoseWire changes value.
State Access
GetWirePath: PROC [wire: RoseWire] RETURNS [path: CoreFlat.PackedPath, coreWire: Core.Wire];
Maps the Rosemary wire back into the Core data structure. Useful in UpdateProcs.
GetCellTypeState: PROC [simulation: Simulation] RETURNS [stateAny: REF ANY];
Returns the ref to the cell types state. Raises an ERROR if the simulation was not instantiated with InstantiateCellType.
GetInstanceState: PROC [simulation: Simulation, instantiationPath: CoreFlat.InstantiationPath, instance: CoreClasses.CellInstance] RETURNS [stateAny: REF ANY];
Returns the ref to the indicated instance's state. Raises an ERROR if the instance was not a leaf during instantiation.
WireValue: PROC [simulation: Simulation, instantiationPath: CoreFlat.InstantiationPath, wire: Core.Wire] RETURNS [value: Ports.LevelSequence];
Gets the current value of the wire. Raises an ERROR if the wire was not instantiated.
StatePoint: PROC [simulation: Simulation, point: NAT];
Saves the current state of the simulation. Raises an ERROR if the index is greater than or equal to the number of statepoints passed to the instantiation procedure.
RestoreState: PROC [simulation: Simulation, point: NAT];
Restores the state of the simulation.
Data Structures
Not intended to be understood by clients.
The data structures have been optimized for atomic wires with transistors on them. Space optimization of more abstract objects was not a design goal.
The following space estimates are not up to date. This is an unnecessary statement since documentation is always out of date. Right?
Space allocation (including overhead of 2 words per allocated record)
transistor: (7 + 2 + 1) words/RoseTransistorRec + 2 words/RoseTransistor * 3 RoseTransistor/RoseTransistorRec => 16 words/transistor
wire: (25 + 2 + 2) words/RoseWireRec + (1 + 2) words/RoseTransistorSeq * 2 RoseTransistorSeq/RoseWireRec => 32 words/wire + quantization of RoseTransistorSeq
A circuit with 200,000 transistors and 70,000 wires requires ~5.5 MWord of memory. You might conceive of simulating 400,000 transistor circuits on a Dorado with 12 MWord of memory. Maybe. With luck. When hell freezes over. Which is when a simulation will finish if very many of those wires or transistors have to be considered by the simulator during each evaluation.
RoseCellType: TYPE = REF RoseCellTypeRec;
RoseCellTypeRec: TYPE = RECORD [
evalSimple: EvalProc ← NIL,
init: InitProc ← NIL,
copy: StateCopyProc ← NIL];
Simulation: TYPE = REF SimulationRec;
SimulationRec: PUBLIC TYPE = RECORD [
coreCellType: Core.CellType ← NIL,
cutSet: ROPENIL,
coreToRoseWires: HashTable.Table ← NIL,
coreToRoseInstances: HashTable.Table ← NIL,
coreToValues: ValueBindings ← NIL,
instanceNeedEval: RoseCellInstance ← NIL,
perturbed: RoseWire ← NIL,
roseBoolWires: LIST OF RoseWire ← NIL,
publicBindings: PortBindings ← NIL,
scratchValue: Ports.LevelSequence ← NIL,
scratchDrive: DriveSequence ← NIL,
vicinityByStrength: ARRAY Ports.Drive OF VicinityRec,
testPort: Ports.Port ← NIL,
statePoints: PortSequence ← NIL];
DriveSequence: TYPE = REF DriveRec;
DriveRec: TYPE = RECORD [drives: SEQUENCE size: CARDINAL OF Ports.Drive];
VicinityRec: TYPE = RECORD[
wires: RoseWires,
firstFree: CARDINAL ← 0];
PortSequence: TYPE = REF PortSequenceRec;
PortSequenceRec: TYPE = RECORD [ports: SEQUENCE size: NAT OF Ports.Port];
RoseCellInstance: TYPE = REF RoseCellInstanceRec;
RoseCellInstanceRec: TYPE = RECORD [
nextNeedEval: RoseCellInstance ← NIL,
roseCellType: RoseCellType ← NIL,
publicPort: Ports.Port ← NIL,
portBindings: PortBindings ← NIL,
state: REF ANYNIL,
statePoints: SRANIL,
path: CoreFlat.PackedPath,
instance: CoreClasses.CellInstance ← NIL];
SRA: TYPE = REF SRASeq;
SRASeq: TYPE = RECORD [elements: SEQUENCE size: CARDINAL OF REF ANY];
PortBindings: TYPE = REF PortBindingSeq;
PortBindingSeq: TYPE = RECORD [elements: SEQUENCE size: CARDINAL OF PortBinding];
PortBinding: TYPE = REF PortBindingRec;
PortBindingRec: TYPE = RECORD [
instance: RoseCellInstance ← NIL,
clientPort: Ports.Port ← NIL,
fields: Fields ← NIL,
currentDrive: Ports.Drive ← none,
statePoints: DriveSequence ← NIL];
Fields: TYPE = REF FieldSeq;
FieldSeq: TYPE = RECORD [elements: SEQUENCE size: CARDINAL OF Field];
Field: TYPE = REF FieldRec;
FieldRec: TYPE = RECORD [
portBinding: PortBinding ← NIL,
portStartBit: NAT ← 0,
roseWire: RoseWire ← NIL,
currentValue: Ports.LevelSequence ← NIL,
statePoints: LevelSequenceSeq ← NIL];
RoseWires: TYPE = REF RoseWireSeq;
RoseWireSeq: TYPE = RECORD [elements: SEQUENCE size: CARDINAL OF RoseWire];
RoseWire: TYPE = REF RoseWireRec;
RoseWireRec: TYPE = RECORD [
connections: Fields ← NIL,
currentValue: Ports.LevelSequence ← NIL,
currentValue=NIL => the wire is atomic. The following fields are only significant if the wire is atomic.
nextPerturbedWire: RoseWire ← NIL,
previousPerturbedWire: RoseWire ← NIL,
nextRecomputed: RoseWire ← NIL,
channels: RoseTransistors ← NIL,
gates: RoseTransistors ← NIL,
connectionDrive: Ports.Drive ← none,
switchDrive: Ports.Drive ← none,
upDrive: Ports.Drive ← none,
downDrive: Ports.Drive ← none,
wireDrive: Ports.Drive ← charge,
connectionLevel: Ports.Level ← L,
wireLevel: Ports.Level ← L,
mark: BOOLFALSE,
statePoints: REF ANYNIL, -- TypeUnion[Ports.LevelSequence, LevelSequenceSeq]
path: CoreFlat.PackedPath,
wire: Core.Wire ← NIL];
LevelSequenceSeq: TYPE = REF LevelSequenceSeqRec;
LevelSequenceSeqRec: TYPE = RECORD [elements: SEQUENCE size: CARDINAL OF Ports.LevelSequence];
RoseTransistors: TYPE = REF RoseTransistorSeq;
RoseTransistorSeq: TYPE = RECORD [elements: SEQUENCE size: CARDINAL OF RoseTransistor];
RoseTransistor: TYPE = REF RoseTransistorRec;
RoseTransistorRec: TYPE = RECORD [
gate: RoseWire ← NIL,
ch1: RoseWire ← NIL,
ch2: RoseWire ← NIL,
conductivity: Ports.Drive ← drive,
type: CoreClasses.TransistorType ← nE];
ValueBindings: TYPE = LIST OF ValueBinding;
ValueBinding: TYPE = RECORD [
path: CoreFlat.PackedPath,
wire: Core.Wire ← NIL,
values: Values ← NIL];
Values: TYPE = LIST OF Value;
Value: TYPE = RECORD [
roseWire: RoseWire ← NIL,
firstBit: NAT ← 0,
size: NAT ← 0];
RoseWireHashKey: TYPE = REF RoseWireHashKeyRec;
RoseWireHashKeyRec: TYPE = RECORD[
path: CoreFlat.PackedPath,
wire: Core.Wire];
RoseInstanceHashKey: TYPE = REF RoseInstanceHashKeyRec;
RoseInstanceHashKeyRec: TYPE = RECORD[
path: CoreFlat.PackedPath,
instance: CoreClasses.CellInstance];
END.