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, copy: StateCopyProc ←
NIL, scheduleIfClockEval:
BOOL ←
FALSE]
RETURNS [sameRoseClassName:
ROPE];
InitProc:
TYPE =
PROC [cellType: Core.CellType, p: Ports.Port, oldStateAny:
REF
ANY ←
NIL, steady:
BOOL ←
FALSE]
RETURNS [stateAny:
REF
ANY ←
NIL, stateValue: Ports.LevelSequence ←
NIL];
Initializes the state and the value from the context contained in the cell type. Multiple calls must return different copies of any bits in the state record which actually represent the state of the simulation. If oldStateAny is not NIL then the procedure should reset the state to its initial value rather than allocating new state. Steady=FALSE means that the state variables should be initialized to X if possible. stateValue contains a representation of the state value. It is not required. The InitProc and EvalProc own stateValue, Rosemary guarantees not to change it. The size of stateValue, when specified, must be constant across calls to InitProc and EvalProc.
StateCopyProc:
TYPE =
PROC [from:
REF
ANY, to:
REF
ANY];
Copies the state. Only needed if statePoints > 0 upon instantiation of a simulation which uses the celltype's EvalProc.
EvalProc:
TYPE =
PROC [p: Ports.Port, stateAny:
REF
ANY, clockEval:
BOOL]
RETURNS [stateValue: Ports.LevelSequence ←
NIL];
Must be idempotent. clockEval indicates that only ports combinatorially derived from a clock should be changed, i.e. no state should be updated during such an evaluation. stateValue is the same as in InitProc.
Instantiation
SetFixedWire:
PROC [wire: Core.Wire, level: Ports.Level ← L]
RETURNS [sameWire: Core.Wire];
Sets the value of the wire and indicates that the value of the wire may not be changed by Rosemary. This is only intended to be used for atomic public wires of the root cell type such as Vdd and Gnd. These wires partition the network into disjoint blocks connected through transistor gates. It is not a general purpose mechanism for jamming a value onto a wire.
SetWire:
PROC [wire: Core.Wire, level: Ports.Level ← L, size: WireSize ← charge, memory:
BOOL ←
FALSE]
RETURNS [sameWire: Core.Wire];
Sets the initial value and order of magnitude wire size. If memory is false then the wire is set to X whenever the wire is not driven and the memory boolean in the Settle call is false. This procedure may only be called with atomic, canonical (in the CoreFlat sense) wires.
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];
Instantiate:
PROC [cellType: Core.CellType, testPort: Ports.Port, cutSet: CoreFlat.CutSet ←
NIL, statePoints:
NAT ← 0]
RETURNS [simulation: Simulation];
Flattens the given cell type using the cutSet to determine the leaves of the simulation. statePoints determines the number of checkpoints allocated. The testPort must be constructed by Ports.CreatePort[cellType.public, TRUE]. The testPort is bound into the simulation so that the client may stimulate the network and examine the response.
State Access
NotInstantiated:
SIGNAL;
Raised when access is requested to data not contained in the current simulation.
GetFlatWire:
PROC [roseWire: RoseWire]
RETURNS [flatWire: CoreFlat.FlatWireRec];
Maps the Rosemary wire back into the Core data structure. Useful in UpdateProcs.
WireValue:
PROC [simulation: Simulation, flatWire: CoreFlat.FlatWire]
RETURNS [value: Ports.LevelSequence];
Gets the current value of the wire. May raise NotInstantiated.
GetValues:
PROC [simulation: Simulation, flatWire: CoreFlat.FlatWire]
RETURNS [values: RoseValues];
Not for the faint of heart. Returns a data structure which describes where the value of the Core wire may be found. Depends upon the Rosemary internal data structures which are not guaranteed to be stable. May raise NotInstantiated.
GetState:
PROC [simulation: Simulation, flatCell: CoreFlat.FlatCellType]
RETURNS [stateAny:
REF
ANY];
Returns the ref to flatCell's state. Raises NotInstantiated if flatCell was not a leaf during instantiation.
StatePoint:
PROC [simulation: Simulation, point:
NAT];
Saves the current state of the simulation. Raises NotInstantiated 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. Raises NotInstantiated if the index is greater than or equal to the number of statepoints passed to the instantiation procedure.
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,
scheduleIfClockEval: BOOL ← FALSE];
Simulation: TYPE = REF SimulationRec;
SimulationRec:
PUBLIC
TYPE =
RECORD [
cellType: Core.CellType ← NIL,
coreToRoseWires: RefTab.Ref ← NIL,
coreToRoseInstances: RefTab.Ref ← NIL,
coreToRoseValues: RefTab.Ref ← NIL,
instanceNeedEval: RoseCellInstance ← NIL,
instanceNeedEvalWhenNotClockEval: RoseCellInstance ← NIL,
perturbed: RoseWire ← NIL,
roseBoolWires: RoseWireList ← NIL,
publicBindings: PortBindings ← NIL,
scratchValue: Ports.LevelSequence ← NIL,
scratchDrive: Ports.DriveSequence ← NIL,
vicinityByStrength: ARRAY Ports.Drive OF VicinityRec,
testPort: Ports.Port ← NIL,
statePoints: PortSequence ← NIL,
mosSimTime: INT ← 0];
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,
nextNeedEvalWhenNotClockEval: RoseCellInstance ← NIL,
roseCellType: RoseCellType ← NIL,
publicPort: Ports.Port ← NIL,
portBindings: PortBindings ← NIL,
state: REF ANY ← NIL,
statePoints: SRA ← NIL,
instance: CoreFlat.FlatCellTypeRec,
data: REF ANY ← 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: Ports.DriveSequence ← NIL];
DriveSequenceSequence: TYPE = REF DriveSequenceSequenceRec;
DriveSequenceSequenceRec: TYPE = RECORD [elements: SEQUENCE size: CARDINAL OF Ports.DriveSequence];
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,
currentDrive: Ports.DriveSequence ← NIL,
currentValue: Ports.LevelSequence ← NIL,
driveStatePoints: DriveSequenceSequence ← NIL,
valueStatePoints: LevelSequenceSeq ← NIL];
RoseWireList: TYPE = LIST OF RoseWire;
RoseWires: TYPE = REF RoseWireSeq;
RoseWireSeq: TYPE = RECORD [elements: SEQUENCE size: CARDINAL OF RoseWire];
RoseWire: TYPE = REF RoseWireRec;
RoseWireRec:
TYPE =
RECORD [
firstFreeConnection: CARDINAL ← 0,
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,
nextVicinityWire: RoseWire ← NIL,
channels: RoseTransistors ← NIL,
notOffChannels: RoseTransistors ← NIL,
validNotOffChannels: CARDINAL ← 0,
gates: RoseTransistors ← NIL,
switchDrive: Ports.Drive ← none,
upDrive: Ports.Drive ← none,
downDrive: Ports.Drive ← none,
wireDrive: Ports.Drive ← charge,
connectionDrive: Ports.Drive ← none,
connectionLevel: Ports.Level ← L,
wireLevel: Ports.Level ← L,
mark: BOOL ← FALSE,
memory: BOOL ← FALSE,
statePoints: REF ANY ← NIL, -- TypeUnion[Ports.LevelSequence, LevelSequenceSeq]
data: REF ANY ← NIL, -- Normally used by RosemaryUser for plotting
wire: CoreFlat.FlatWireRec];
LevelSequenceSeq: TYPE = REF LevelSequenceSeqRec;
LevelSequenceSeqRec:
TYPE =
RECORD [elements:
SEQUENCE size:
CARDINAL
OF Ports.LevelSequence];
RoseValues: TYPE = LIST OF RoseValue;
RoseValue:
TYPE =
RECORD [
roseWire: RoseWire ← NIL,
fieldStart: NAT ← 0,
fieldWidth: NAT ← 0];
RoseWireData: TYPE = REF RoseWireDataRec;
RoseWireDataRec:
TYPE =
RECORD [value: Ports.Level, size: Ports.Drive, memory:
BOOL];
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,
instance: CoreFlat.FlatCellTypeRec];