[Indigo]<Rosemary>®>Rosemary.DF=>RoseTypes.Mesa
Last Edited by: Spreitzer, May 6, 1985 5:17:29 pm PDT
DIRECTORY AMTypes, Asserting, Basics, IO, OrderedSymbolTableRef, PrincOps, Rope, RoseEvents, VFonts;
RoseTypes: CEDAR DEFINITIONS =
This module defines the data types used in Rosemary circuit representations, as well as the data types used by the Rosemary simulator; they are wonderfully commingled.
BEGIN
Error: ERROR [msg: ROPE, data: REF ANY ← NIL];
Warning: SIGNAL [msg: ROPE, data: REF ANY ← NIL];
Stop: SIGNAL [msg: ROPE, data: REF ANY ← NIL];
LORA: TYPE = LIST OF REF ANY;
ROPE: TYPE = Rope.ROPE;
RopeList: TYPE = LIST OF ROPE;
STREAM: TYPE = IO.STREAM;
TV: TYPE = AMTypes.TV;
Assertion: TYPE = Asserting.Assertion;
Assertions: TYPE = Asserting.Assertions;
SymbolTable: TYPE = OrderedSymbolTableRef.Table;
WatcherList: TYPE = RoseEvents.WatcherList;
Watcher: TYPE = RoseEvents.Watcher;
WordPtr: TYPE = LONG POINTER TO CARDINAL;
Ptr: TYPE = PrincOps.BitAddress;
nilPtr: Ptr = [word: NIL, bit: 0];
Field:
TYPE =
RECORD [
wordOffset: CARDINAL,
bitOffset: BitOffset,
bitCount: CARDINAL];
BitOffset: TYPE = [0 .. Basics.bitsPerWord);
noField: Field = [LAST[CARDINAL], LAST[BitOffset], LAST[CARDINAL]];
NodeType: TYPE = REF NodeTypeRep;
NodeTypeRep:
TYPE =
RECORD [
procs: NodeProcs,
typeData: REF ANY,
simple: BOOLEAN ← TRUE,
other: Assertions ← NIL,
structure:
SELECT structureType: StructureType
FROM
atom => [flavor: ATOM],
array => [length: NAT, element: AtomNodeType],
ENDCASE
];
StructureType: TYPE = {atom, array};
ArrayNodeType: TYPE = REF NodeTypeRep[array];
AtomNodeType: TYPE = REF NodeTypeRep[atom];
NodeProcs: TYPE = REF NodeProcsRep;
NodeProcsRep:
TYPE =
RECORD [
Interface
UserDescription: PROC [NodeType] RETURNS [ROPE],
ListFormats: PROC [NodeType] RETURNS [RopeList],
GetFormat: PROC [NodeType, ROPE] RETURNS [Format],
MesaForSelf:
PROC [NodeType]
RETURNS [Mesa],
a Mesa expression that evaluates to this NodeType
Structure
SelectorOffset:
PROC [NodeType, Selector]
RETURNS [
NAT] ←
NIL,
Offset, in bits, from begin of interesting data (not container) to begin of selected data.
SubType: PROC [NodeType, Selector] RETURNS [NodeType] ← NIL,
Representation
Bits:
PROC [NodeType]
RETURNS [container, data, leftPad:
INT],
The number of bits occupied by the MesaRepresentation is returned in `container'; the number of interesting bits is returned in `data'; the number of bits in the container in front of the interesting bits is returned in `leftPad'.
MesaRepresentation:
PROC [NodeType]
RETURNS [Mesa],
the Mesa type of the representation
MesaRepAux:
PROC [NodeType]
RETURNS [Mesa] ←
NIL,
Mesa code (e.g. declaration) to establish mesa type
Behavior
Equivalent:
PROC [self, other: NodeType]
RETURNS [
BOOL] ←
NIL,
Says whether we can freely copy bits between them.
SwitchEquivalent:
PROC [NodeType]
RETURNS [NodeType] ←
NIL,
Gives the type to transduce to, when necessary.
SimpleEquivalent:
PROC [NodeType]
RETURNS [NodeType] ←
NIL,
For a switch-level type, gives a simple type that can transduce to it.
Transduce: PROC [fromS: Strength, fromT, toT: NodeType, fromP, toP: Ptr] ← NIL,
InitNode:
PROC [node: Node, steady:
BOOL] ←
NIL,
If steady, initialize for steady-state work; otherwise, for initialization work.
InitPort: PROC [Node, Ptr] ← NIL,
InitQ, InitUD: PROC [Node] ← NIL,
NewVal: PROC [Node] RETURNS [delay: BOOL] ← NIL,
CopyVal: PROC [nt: NodeType, from, to: Ptr] ← NIL,
NewQ, NewUD: PROC [Node, Ptr] RETURNS [BOOL] ← NIL,
QFromNode, UDFromNode, ValFromNode, SetNode: PROC [Node, Ptr] ← NIL,
CompareUD: PROC [nt: NodeType, p1, p2: Ptr] RETURNS [BOOL] ← NIL
];
Conforming: PROC [NodeType, NodeType] RETURNS [BOOL];
Equivalent: PROC [NodeType, NodeType] RETURNS [BOOL];
TransduceNeeded: PROC [NodeType, NodeType] RETURNS [BOOL];
BothTypes: PROC [nt: NodeType] RETURNS [simple, switch: NodeType];
Selector:
TYPE =
RECORD [variant:
SELECT kind: *
FROM
whole => [],
number => [index: INT],
range => [first, count: INT, up: BOOL],
ENDCASE];
SelectorToRope: PROC [s: Selector] RETURNS [r: ROPE];
Mesa: TYPE = RECORD [mesa: ROPE, directory, imports: RopeList ← NIL];
NodeList: TYPE = LIST OF Node;
Format: TYPE = REF FormatRep;
FormatRep:
TYPE =
RECORD [
FormatValue: PROC [Node, Format, Ptr] RETURNS [ROPE],
ParseValue: PROC [Node, Format, Ptr, STREAM] RETURNS [BOOLEAN],
FormatTest: PROC [NodeType, Format, NodeTest] RETURNS [ROPE],
ParseTest: PROC [NodeType, Format, STREAM] RETURNS [BOOLEAN, NodeTest],
MaxWidth: PROC [NodeType, Format, VFonts.Font] RETURNS [INT],
formatData: REF ANY ← NIL,
key: ROPE
];
NodeTest: TYPE = RECORD [proc: NodeTestProc, data: REF ANY];
NodeTestProc:
TYPE =
PROC
[
where: Ptr,
testData: REF ANY,
nodeType: NodeType]
RETURNS [passes: BOOLEAN];
NodeExpression: TYPE = REF NodeExpressionRep;
PrimaryNE: TYPE = REF NodeExpressionRep.primary;
UnnamedConsNE: TYPE = REF NodeExpressionRep.unnamedCons;
CatenateNE: TYPE = REF NodeExpressionRep.catenate;
NodeExpressionRep:
TYPE =
RECORD [variant:
SELECT kind: *
FROM
primary => [node: Node, selector: Selector],
unnamedCons => [elts: LIST OF PrimaryNE],
catenate => [pieces: LIST OF NodeExpression]
ENDCASE];
Node: TYPE = REF NodeRep;
NodeRep:
TYPE =
RECORD [
name: ROPE,
type: NodeType,
valRef: REF ANY ← NIL,
valPtr: Ptr ← nilPtr,
Pointer to the interesting data.
A fromDesign node keeps a copy of its entire value;
An implOnly node keeps here a pointer into one of its parents.
ctnPtr: Ptr ← nilPtr,
Pointer to the container of the data, for a fromDesign node.
bitCount:
INT ← 0,
Size of value.
strength: Strength ← charge,
A node has an intrinsic strength (its capacitance).
currentStrength: Strength ← charge,
For simple nodes, the strength of the strongest drivers.
cap:
REAL ← 0,
Some jokers may want to accumulate strength here.
cellIn: Cell ←
NIL,
A fromDesign node tells who created it;
an implOnly node notes lowest common ancestor of contributing fromDesign nodes.
strIn: Structure,
switchConnections: SlotList ← NIL,
byStrength: ARRAY Strength OF StrengthRingHead ← ALL[emptyHead],
found, XPhobic, isInput:
BOOLEAN ←
FALSE,
The NodeType is responsible for maintaining "isInput".
nextPerturbed, nextAffected, nextDelayed, prevDelayed: Node ← NIL--compiler can't handle: notInNodeList--,
watchers: ARRAY Priority OF WatcherList ← ALL[NIL],
significances: NodeSignificances,
designNext: Node ←
NIL
--compiler can't handle: notInNodeList--,
For a fromDesign node, link in order of def.
implNext: Node ←
NIL
--compiler can't handle: notInNodeList--,
For an inImpl node, link to others in strIn.
parentPieces: PieceList ←
NIL,
For a implOnly node, the containing designOnly nodes, and pointers into their values;
for a NOT fromDesign node during creation, the breaking toward design nodes.
childPieces: PieceList ←
NIL,
For a designOnly node, the breaking into implOnly nodes;
for a NOT inImpl node during creation, the breaking toward impl nodes.
other: Assertions ← NIL];
notInNodeList: Node;
PortIndex: TYPE = CARDINAL;
EffectivePortIndex: TYPE = CARDINAL;
nilPortIndex: PortIndex = LAST[CARDINAL];
nilEffectivePortIndex: EffectivePortIndex = LAST[CARDINAL];
StrengthRingHead: TYPE = RECORD [first, last: Slot];
emptyHead: StrengthRingHead = [head, head];
head: Slot --don't look:-- = nilSlot;
StrengthRingElement: TYPE = REF StrengthRingElementRep;
StrengthRingElementRep:
TYPE =
RECORD [
next, prev: StrengthRingElement,
slot: Slot];
SlotList: TYPE = LIST OF Slot;
Slot:
TYPE =
RECORD [
cell: Cell,
effectivePortIndex: EffectivePortIndex
];
nilSlot: Slot = [NIL, nilEffectivePortIndex];
SlotToPtr: PROC [s: Slot, useBryant: BOOL ← FALSE] RETURNS [p: Ptr];
ValPtr: PROC [n: Node] RETURNS [p: Ptr];
Priority:
TYPE = {ordinary, high};
"ordinary" is for ordinary mortals, like breakpoints
"high" is for things like the display, which should be updated first
NodeSignificances: TYPE = ARRAY NodeSignificance OF BOOL;
NodeSignificance: TYPE = {fromDesign, inImpl};
designOnly: NodeSignificances = [TRUE, FALSE];
implOnly: NodeSignificances = [
FALSE,
TRUE];
A fromDesign node appears in the designer's model; it comes from an ExpandProc.
An inImpl node is used by the simulator for communicating values.
An implOnly node is used by some client code to implement something (e.g, split/joiners); it corresponds to a piece of a fromDesign node (or nodes).
A designOnly node is used to relate the designer's model to what the simulator is doing.
A [TRUE, TRUE] node is that happy coincidence between the designer's model and what the simulator is doing.
A [FALSE, FALSE] node was a designOnly node that got further decomposed.
PieceList: TYPE = LIST OF Piece;
Piece:
TYPE =
RECORD [
twardDesign, twardImpl: Node,
reln: Selector
twardDesign.reln=twardImpl
];
Cell: TYPE = REF CellRep;
CellRep:
TYPE =
RECORD [
name: ROPE,
type: CellType,
nextInstance: Cell,
sim: Simulation,
parent, leftChild, rightSibling: Cell,
firstInternalNode: Node,
internalNodes, components: SymbolTable,
interfaceNodes: NodeS,
other: Assertions,
substantiality: CellSubstantiality,
expansion: ExpandDecision,
realCellStuff: RealCellStuff -- non-NIL only for Real Cells
];
notInCellList: Cell;
ExpandDecision: TYPE = {Leaf, Expand};
CellSubstantiality: TYPE = {Real, Shadow};
RealCellStuff: TYPE = REF RealCellStuffRep;
RealCellStuffRep:
TYPE =
RECORD [
effectivePorts: EffectivePorts,
implNodes: NodeS,
schedNext, nextNeeded, nextNoted: Cell ← NIL--notInCellList--,
newIO, oldIO, switchIO, newDriveAsAny, oldDriveAsAny: REF ANY,
newIOAsWP, oldIOAsWP, switchIOAsWP: WordPtr,
newDrive, oldDrive: Drive,
locked: BOOLEAN ← FALSE,
hasTransducedPort: BOOL ← FALSE,
affectedFlags: AffectedFlags ← ALL[FALSE],
initQed, propQed, initUDed, propUDed: BOOLEAN ← FALSE,
state: REF ANY,
evals: EvalProcs,
schedWatchers, evalWatchers: WatcherList ← NIL];
AffectedFlags: TYPE = ARRAY Speciality OF BOOLEAN;
Speciality: TYPE = {transducedToSwitch, modeledAsSwitch};
EvalProcs:
TYPE =
RECORD [
InitQ, PropQ, InitUD, PropUD, FinalUD: CellProc ← NIL,
ValsChanged, EvalSimple: SimpleEval ← NIL,
EnumerateVicinity:
PROC [
cell: Cell,
portIndex: PortIndex,
evenIfInput: BOOL ← FALSE,
consume: PROC [PortIndex]
] ← NIL
];
noPort: PortIndex = nilPortIndex;
CellProc: TYPE = PROC [cell: Cell];
SimpleEval: TYPE = PROC [cell: Cell, perturb: PROC [portIndex: PortIndex]];
Structure: TYPE = REF StructureRep;
StructureRep:
TYPE =
RECORD [
root: Cell,
sim: Simulation,
schedFirst, schedLast, firstNeeded: Cell ← NIL,
locked, running: BOOLEAN ← FALSE,
firstPerturbed, firstAffected, firstDelayed, lastDelayed, firstImplNode: Node ← NIL];
notInStrList: Structure;
CellToStr:
PROC [cell: Cell]
RETURNS [str: Structure] =
INLINE
{str ← cell.sim.str};
ContainingStr:
PROC [cell: Cell]
RETURNS [str: Structure] =
INLINE
{str ← cell.sim.str};
NodeS: TYPE = REF NodeSR;
NodeSR: TYPE = RECORD [nodes: SEQUENCE length: CARDINAL OF Node];
ExpandProc:
TYPE =
PROC [thisCell: Cell, to: ExpansionReceiver];
ExpansionReceiver: TYPE = RECORD [instance: REF ANY, class: ERClass];
ERClass: TYPE = REF ERClassRep;
ERClassRep:
TYPE =
RECORD [
CellInstance: PROC [erInstance: REF ANY, instanceName, typeName, interfaceNodes: ROPE, other: Assertions ← NIL] RETURNS [cell: Cell],
NodeInstance: PROC [erInstance: REF ANY, name: ROPE, type: NodeType, initialValue, initialValueFormat: ROPE ← NIL, initData: REF ANY ← NIL, other: Assertions ← NIL] RETURNS [node: Node],
Equivalence:
PROC [erInstance:
REF
ANY, a, b: NodeExpression]
Aliases two NodeExpressions together; they must both have the same structure.
];
IOCreator: TYPE = PROC [ct: CellType, switch: BOOL] RETURNS [ioAsAny: REF ANY];
DriveCreator: TYPE = PROC [ct: CellType] RETURNS [driveAsAny: REF ANY];
Initializer: TYPE = PROC [cell: Cell];
CellType: TYPE = REF CellTypeRep;
CellTypeRep:
TYPE =
RECORD [
name: ROPE,
expand: ExpandProc,
ioCreator: IOCreator,
driveCreator: DriveCreator,
initializer: Initializer,
evals: EvalProcs,
testers: SymbolTable,
ports: Ports,
simpleWordCount, switchWordCount: CARDINAL ← 0,
hasASwitchPort: BOOL ← FALSE,
typeData: REF ANY ← NIL,
other: Assertions ← NIL,
firstInstance: Cell ← NIL
];
CellTest: TYPE = REF CellTestRep;
CellTestRep:
TYPE =
RECORD [
name: ROPE,
proc: CellTestProc,
stateToo: BOOL
];
CellTestProc: TYPE = PROC [handle: CellTestHandle, testeeType: CellType, testData, switchInstructions, simpleInstructions, driveAsAny, stateAsAny: REF ANY];
CellTestHandle: TYPE = REF CellTestHandleRep;
CellTestHandleRep: TYPE;
NarrowToCellTestHandle: PROC [any: REF ANY] RETURNS [cth: CellTestHandle];
GetSimulationFromCellTestHandle: PROC [CellTestHandle] RETURNS [Simulation];
Strength: TYPE = DriveLevel[ignore .. input];
DriveLevel:
TYPE = {
test,--for TestProcs to say "test it for me"
see,--for TestProcs to say "I'll test it"
ignore,
--from a TestProc it means neither driven nor tested; in switch-level it means no strength at all
chargeWeak, chargeMediumWeak,
charge,
chargeMediumStrong, chargeStrong, chargeVeryStrong,
driveWeak, driveMediumWeak,
drive,
driveMediumStrong, driveStrong, driveVeryStrong,
input--the strongest drive level: how circuit inputs are driven
};
Drive:
TYPE =
REF DriveRep;
The layout of a drive record should correspond to this.
DriveRep:
TYPE =
RECORD [
tag: DriveTagType,
tag is not meaningful; it only provides space for CellTypes that need it.
drives: PACKED SEQUENCE COMPUTED NAT--portIndex-- OF DriveLevel];
DriveTagType: TYPE = CARDINAL;
Ports: TYPE = REF PortsRep;
PortsRep: TYPE = RECORD [ports: SEQUENCE length: PortIndex OF Port];
Port:
TYPE =
RECORD [
simple, switch: Field,
Where this port is to be found in the new/old and switch IO records.
name: ROPE,
type: NodeType,
The type of values that the EvalProcs, if any, deal in.
input, output, XPhobic: BOOL ← FALSE,
instructionsSimple: BOOL ← TRUE,
other: Assertions ← NIL];
EffectivePorts: TYPE = REF EffectivePortsRep;
EffectivePortsRep: TYPE = RECORD [ports: SEQUENCE length: EffectivePortIndex OF EffectivePort];
EffectivePort:
TYPE =
RECORD [
simple, switch: Field,
name: ROPE,
type: NodeType,
The type the CellType's eval procs deal in.
input, output, XPhobic: BOOLEAN ← FALSE,
other: Assertions ← NIL,
implType: NodeType ←
NIL,
The type the simulator deals in, = type of node connected to this port.
containingPort: PortIndex ← nilPortIndex,
The CellType's Port that this EffectivePort is all or part of.
firstEffectivePortIndex: EffectivePortIndex ← nilEffectivePortIndex,
cell.realCellStuff.effectivePorts[pi].firstEffectivePort is minimal epi such that cell.realCellStuff.effectivePorts[epi].containingPort = pi
Note the oddity: subscripting effectivePorts by pi (a PortIndex).
strengthNext, strengthPrev: Slot ← nilSlot, curStrength: DriveLevel ← test
Links around the strength ring, and which ring currently in.
];
GetIndex:
PROC [ports:
REF
ANY
--actually UNION [Ports, EffectivePorts]--, key:
ROPE]
RETURNS [index:
CARDINAL];
notFound: CARDINAL = nilPortIndex;
Simulation: TYPE = REF SimulationRep;
SimulationRep:
TYPE =
RECORD [
steady: BOOL,
root: Cell ← NIL,
cth: CellTestHandle ← NIL,
str: Structure ← NIL,
other: Assertions ← NIL];
END.