Instantiation and Relaxation
AddCutSets:
PROC [cellType: Core.CellType, cs1, cs2, cs3, cs4, cs5, cs6:
ROPE ←
NIL]
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:
ROPE ←
NIL, statePoints:
NAT ← 0]
RETURNS [simulation: Simulation];
Initialize:
PROC [simulation: Simulation, steady:
BOOL ←
TRUE];
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.
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: ROPE ← NIL,
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 ANY ← NIL,
statePoints: SRA ← NIL,
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: BOOL ← FALSE,
statePoints: REF ANY ← NIL, -- 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 BOOL ← ALL[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];