DIRECTORY BasicTime, Core, CoreClasses, CoreFlat, Ports, RefTab, Rope; Rosemary: CEDAR DEFINITIONS = BEGIN ROPE: TYPE = Core.ROPE; Stop: SIGNAL [msg: ROPE _ NIL, data: REF ANY _ NIL, reason: ATOM _ $Client]; 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]; StateCopyProc: TYPE = PROC [from: REF ANY, to: REF ANY]; EvalProc: TYPE = PROC [p: Ports.Port, stateAny: REF ANY, clockEval: BOOL] RETURNS [stateValue: Ports.LevelSequence _ NIL]; SetFixedWire: PROC [wire: Core.Wire, level: Ports.Level _ L] RETURNS [sameWire: Core.Wire]; SetWire: PROC [wire: Core.Wire, level: Ports.Level _ L, size: WireSize _ charge, memory: BOOL _ FALSE] RETURNS [sameWire: Core.Wire]; WireSize: TYPE = Ports.Drive[chargeWeak..chargeStrong]; SetTransistorCellTypeSize: PROC [transistor: Core.CellType, size: TransistorSize] RETURNS [sameTransistor: Core.CellType]; 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]; Initialize: PROC [simulation: Simulation, steady: BOOL _ TRUE, updateCellProc: UpdateCellProc _ NIL]; SettleToTest: PROC [simulation: Simulation, flatCell: CoreFlat.FlatCellType, test: Ports.Port]; Settle: PROC [simulation: Simulation, updateProc: UpdateProc _ NIL, memory: BOOL _ TRUE, clockEval: BOOL _ FALSE, updateCellProc: UpdateCellProc _ NIL]; UpdateProc: TYPE = PROC [roseWire: RoseWire]; UpdateCellProc: TYPE = PROC [roseInstance: RoseCellInstance, stateValue: Ports.LevelSequence]; NotInstantiated: SIGNAL; GetFlatWire: PROC [roseWire: RoseWire] RETURNS [flatWire: CoreFlat.FlatWireRec]; WireValue: PROC [simulation: Simulation, flatWire: CoreFlat.FlatWire] RETURNS [value: Ports.LevelSequence]; GetValues: PROC [simulation: Simulation, flatWire: CoreFlat.FlatWire] RETURNS [values: RoseValues]; GetState: PROC [simulation: Simulation, flatCell: CoreFlat.FlatCellType] RETURNS [stateAny: REF ANY]; StatePoint: PROC [simulation: Simulation, point: NAT]; RestoreState: PROC [simulation: Simulation, point: NAT]; PrintPeriod: PROC [prefix: Rope.ROPE, from, to: BasicTime.GMT]; 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, 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]; END. ΚRosemary.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Barth, September 30, 1987 2:24:49 pm PDT Jean-Marc Frailong December 17, 1987 3:05:58 pm PST Theory Rosemary is a simulator which combines a MOSSIM switch level model for transistors with a simple selective trace algorithm for higher level functional blocks. Behavioural procedures must be registered for the functional blocks. A Core data structure is used to express the net list. The net list is flattened into a Rosemary simulation data structure. The simulation data structure can be initialized to hold zeroes or X's everywhere. The steady state reponse to a test vector can be computed. This signal may be raised when a behavioural proc is annoyed by something. It is raised by Rosemary with reason = $BoolWireHasX and data = CoreFlat.FlatWire if some wire attached to a port containing boolean values settles to an X. Behaviour Registration 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. Copies the state. Only needed if statePoints > 0 upon instantiation of a simulation which uses the celltype's EvalProc. 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 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. 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. Sets the order of magnitude transistor size. 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. Relaxation 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. The InitProc for each behaviour class is called for each instance. The UpdateCellProc is called after each init (c.f. Settle). Given a settled simulation, an instance in it and a test port this procedure converts the values in the settled simulation into a test vector for another simulation. The port of the instance and the test port must have identical structure and may not have port.driveType=separate. Relaxes the simulation. The port supplied to 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. May raise Stop. If memory is false then all wires which do not have memory are set to X if they are not driven. clockEval is simply passed to all of the eval procs so that they may take appropriate action. State Access Raised when access is requested to data not contained in the current simulation. Maps the Rosemary wire back into the Core data structure. Useful in UpdateProcs. Gets the current value of the wire. May raise NotInstantiated. 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. Returns the ref to flatCell's state. Raises NotInstantiated if flatCell was not a leaf during instantiation. 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. 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. Hack 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. currentValue=NIL => The wire is atomic. The following fields are only significant if the wire is atomic. Κ =˜šœ ™ Icodešœ Οmœ1™žœ,˜K™Kšœžœ'˜;J˜—š Ÿ œžœKžœžœžœ˜˜Kšœέžœt™ΥJ˜——šœ ™ š Ÿ œžœ"žœžœ!žœ˜eKšœˆ™ˆK™—šŸ œžœM˜_K™™K˜—šŸœžœ3žœ žœžœ žœžœ#žœ˜˜KšŸ œžœžœ˜-KšŸœžœžœC˜^Kšœ›™›K™——™ šŸœžœ˜K™PK™—šŸ œžœžœ"˜PKšœQ™QK™—šŸ œžœ7žœ˜kKšœ?™?K˜—šŸ œžœ7žœ˜cKšœλ™λK˜—š Ÿœžœ;žœ žœžœ˜eKšœm™mK™—šŸ œžœ!žœ˜6Kšœ¬™¬K˜—šŸ œžœ!žœ˜8Kšœ§™§K˜——™KšŸ œžœžœžœ˜?—™K™)K™K™–Kšœk œ™…™EKšœ„™„Kšœ™—™τK™—Kšœžœžœ˜)šœžœžœ˜ Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœžœ˜#K˜—Kšœ žœžœ˜%šœžœžœžœ˜%Kšœžœ˜Kšœžœ˜"Kšœ"žœ˜&Kšœžœ˜#Kšœ%žœ˜)Kšœ5žœ˜9Kšœžœ˜Kšœžœ˜"Kšœžœ˜#Kšœ$žœ˜(Kšœ$žœ˜(Kšœžœ žœ ˜5Kšœžœ˜Kšœžœ˜ Kšœ žœ˜K˜—šœ žœžœ˜Kšœ˜Kšœ žœ˜K˜—Kšœžœžœ˜)š œžœžœžœžœžœ ˜IK˜—Kšœžœžœ˜1šœžœžœ˜$Kšœ!žœ˜%Kšœ1žœ˜5Kšœžœ˜!Kšœžœ˜Kšœžœ˜!Kšœžœžœžœ˜Kšœ žœžœ˜Kšœ#˜#Kšœžœžœžœ˜K˜—Kšžœžœžœ˜Kšœžœžœ žœžœžœžœžœ˜EK˜Kšœžœžœ˜(Kš œžœžœ žœžœžœ˜QKšœ žœžœ˜'šœžœžœ˜Kšœžœ˜!Kšœžœ˜Kšœžœ˜Kšœ!˜!Kšœ#žœ˜(K˜—Kšœžœžœ˜;Kš œžœžœ žœžœžœ˜cK˜Kšœžœžœ ˜Kš œ žœžœ žœžœžœ˜EKšœžœžœ ˜šœ žœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœ$žœ˜(Kšœ$žœ˜(Kšœ*žœ˜.Kšœ%žœ˜*K˜—Kšœžœžœžœ ˜&Kšœ žœžœ ˜"Kš œ žœžœ žœžœžœ ˜KKšœ žœžœ ˜!šœ žœžœ˜Kšœžœ˜"Kšœžœ˜Kšœ$žœ˜(™iKšœžœ˜"Kšœ"žœ˜&Kšœžœ˜Kšœžœ˜!Kšœžœ˜ Kšœ"žœ˜&Kšœžœ˜"Kšœžœ˜Kšœ ˜ Kšœ˜Kšœ˜Kšœ ˜ Kšœ$˜$Kšœ!˜!K˜Kšœžœžœ˜Kšœžœžœ˜—Kšœ žœžœΟc3˜PKšœžœžœžœ‘-˜BKšœ˜K˜—Kšœžœžœ˜1š œžœžœ žœžœžœ˜^K˜—Kšœ žœžœžœ ˜%šœ žœžœ˜Kšœžœ˜Kšœ žœ˜Kšœ žœ˜K™—Kšœžœžœ˜)šœžœžœ1žœ˜UK˜—Kšœžœžœ˜.Kš œžœžœ žœžœžœ˜WKšœžœžœ˜-šœžœžœ˜"Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœ"˜"Kšœ&˜&Kšœ$˜$K˜——Jšžœ˜—…—Ό=Γ