Rosemary.mesa
Barth, March 24, 1986 12:45:28 pm PST
Bertrand Serlet March 14, 1986 4:41:10 pm PST
DIRECTORY Core, CoreClasses, 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
InstantiationPath: TYPE = LIST OF CoreClasses.CellInstance; -- top level first
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: 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.
GetWireValue: PROC [simulation: Simulation, instantiationPath: InstantiationPath, wire: Core.Wire, container: Ports.LevelSequence];
Puts the current value of the wire into the container. Raises an ERROR if the container is too small or 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.
Private
Not intended to be used by normal clients.
GetCellType: PROC [rootCellType: Core.CellType, path: PackedPath] RETURNS [cellType: Core.CellType ← NIL];
Recordify: PROC [ct: Core.CellType] RETURNS [rc: Core.CellType];
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.
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: ARRAY HashIndex OF RoseWire ← ALL[NIL],
coreToRoseInstances: ARRAY HashIndex OF RoseCellInstance ← ALL[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];
HashIndex: TYPE = [0..512);
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: PackedPath,
instance: CoreClasses.CellInstance ← NIL,
nextBucket: RoseCellInstance ← 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: PackedPath,
wire: Core.Wire,
nextBucket: RoseWire ← 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];
PackedPath: TYPE = RECORD [
length: PathIndex ← 0,
bits: PACKED ARRAY PathIndex OF BOOLALL[FALSE]];
PathIndex: TYPE = [0..32);
ValueBindings: TYPE = LIST OF ValueBinding;
ValueBinding: TYPE = RECORD [
path: 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];
END.