Ports.mesa
Barth, May 6, 1986 5:42:35 pm PDT
Last Edited by: Gasbarro January 23, 1986 11:32:11 am PST
Bertrand Serlet January 27, 1986 4:01:32 pm PST
DIRECTORY Core;
Ports: CEDAR DEFINITIONS = BEGIN
Theory
A port is a DAG which is a subgraph of a Core.Wire DAG. A port requires that the leaves of the port DAG form a disjoint cover of the leaves of the Core.Wire DAG. This eliminates aliases of values.
A port is used for representing an interface to a Core.wire. A port defines an interface to a wire rather than the wire itself. Thus a port represents a current strength as well as a voltage level.
A voltage level in a port can be represented as a boolean value or as a member of the set L, H, or X. A leaf port can represent aggregates of either of these value sets. A current strength is only represented once for any leaf port. This means that a leaf port which represents an interface to an aggregate of many wires can specify multiple voltage levels but only a single current strength.
Types
Port: TYPE = REF PortRec;
The comment definition of a port record captures the semantics. However it introduces a number of runtime checks and excess verbiage in the source. The uncommented definition is used to eliminate them.
PortRec: TYPE = RECORD [
port: SELECT type: PortType FROM
l => [d: Drive ← none, l: Level ← L],
ls => [d: Drive ← none, ls: LevelSequence ← NIL],
b => [d: Drive ← none, b: BOOLFALSE],
bs => [d: Drive ← none, bs: BitSequence ← NIL],
c => [d: Drive ← none, fieldStart: [0..16), c: CARDINAL ← 0],
lc => [d: Drive ← none, fieldStart: [0..32), lc: LONG CARDINAL ← 0],
composite => [composite: SEQUENCE size: NAT OF Port],
ENDCASE];
PortRec: TYPE = RECORD [
type: PortType ← composite,
d: Drive ← none,
l: Level ← L,
ls: LevelSequence ← NIL,
b: BOOLFALSE,
bs: BoolSequence ← NIL,
fieldStart: [0..32) ← 0,
c: CARDINAL ← 0,
lc: LONG CARDINAL ← 0,
composite: SEQUENCE size: NAT OF Port];
PortType: TYPE = {l, ls, b, bs, c, lc, composite};
Drive: TYPE = {
expect, -- allows port to specify expected value
none, --from a test proc it means neither driven nor checked; in switch-level it means no strength at all
chargeWeak, chargeMediumWeak,
charge,
chargeMediumStrong, chargeStrong,
force, -- weakest drive level, allows test procs to check if device has tristated
driveWeak, driveMediumWeak,
drive,
driveMediumStrong, driveStrong,
infinite -- drive for nodes which have infinite current sources
};
Level: TYPE = {L, H, X};
LevelSequence: TYPE = REF LevelSequenceRec;
LevelSequenceRec: TYPE = RECORD [levels: PACKED SEQUENCE size: NAT OF Level];
BoolSequence: TYPE = REF BoolSequenceRec;
BoolSequenceRec: TYPE = RECORD [bools: PACKED SEQUENCE size: NAT OF BOOL];
PortList: TYPE = LIST OF Port;
PortData: TYPE = REF PortDataRec;
PortDataRec: TYPE = RECORD [
type: PortType,
drive: Drive];
portTypeNames: ARRAY PortType OF Core.ROPE;
driveNames: ARRAY Drive OF Core.ROPE;
levelNames: ARRAY Level OF Core.ROPE;
Operations
FindPortType: PROC [portTypeID: Core.ROPE] RETURNS [portType: PortType];
FindDrive: PROC [driveID: Core.ROPE] RETURNS [drive: Drive];
FindLevel: PROC [levelID: Core.ROPE] RETURNS [level: Level];
CreatePort: PROC [wire: Core.Wire, testerPort: BOOLFALSE] RETURNS [port: Port];
InitPort: PROC [wire: Core.Wire, initType: PortType ← b, initDrive: Drive ← none] RETURNS [sameWire: Core.Wire];
InitTesterDrive: PROC [wire: Core.Wire, initDrive: Drive ← none];
WirePortType: PROC [wire: Core.Wire] RETURNS [type: PortType];
PortLeaves: PROC [port: Port] RETURNS [leaves: CARDINAL];
PortIndex: PROC [wire: Core.Wire, name: Core.ROPE] RETURNS [NAT];
LevelSequenceToRope: PROC [container: Ports.LevelSequence, size: NAT ← 0, base: NAT ← 16] RETURNS [val: Core.ROPE];
CopyPortValue: PROC [from: Port, to: Port];
Raises an error if the ports are not isomorphic.
CheckPortValue: PROC [root: Core.Wire, truth: Port, question: Port];
Raises an error if the ports are not isomorphic or the question port does not match the requirements of the truth port. Uses wire to generate a sensible error message; it should be the wire which was the argument to CreatePort.
CheckError: SIGNAL [msg: Core.ROPE];
Enumerating Pairs
EachPortPairProc: TYPE = PROC [onePort: Port, anotherPort: Port] RETURNS [subElements: BOOLTRUE, quit: BOOLFALSE];
VisitPortPair: PROC [onePort: Port, anotherPort: Port, eachPortPair: EachPortPairProc] RETURNS [quit: BOOL];
TRUE is returned if some invocation of eachPortPair returns quit=TRUE or if the ports do not conform.
EachWirePortPairProc: TYPE = PROC [wire: Core.Wire, port: Port] RETURNS [subElements: BOOLTRUE, quit: BOOLFALSE];
VisitBinding: PROC [wire: Core.Wire, port: Port, eachWirePortPair: EachWirePortPairProc] RETURNS [quit: BOOL];
TRUE is returned if some invocation of eachWirePortPair returns quit=TRUE. Wire and port need not conform, but port must be a subgraph of wire. If the port is a strict subgraph of the wire then the EachWirePortPairProc will be called with port: NIL;
END.