--Transistors.Mesa
--created by RoseTranslate from Transistors.Rose of March 20, 1984 1:59:42 pm PST for Preas.pa at May 7, 1984 3:21:15 pm PDT
DIRECTORY
RoseTypes, RoseCreate, RoseRun, SwitchTypes;
Transistors: CEDAR PROGRAM
IMPORTS RoseCreate, RoseRun, RoseTypes, SwitchTypes =
BEGIN OPEN
RoseTypes, SwitchTypes, RoseRun, RoseCreate;
RegisterCells: PROC =
BEGIN
CreateNETransPorts[];
[] ← RoseCreate.RegisterCellClass[className: "NETrans",
expandProc: NIL,
ioCreator: CreateNETransIO, initializer: InitializeNETrans,
evals: [ValsChanged: NETransValsChanged, PropQ: NETransPropQ, PropUD: NETransPropUD, FindVicinity: NETransFindVicinity],
blackBox: NIL, stateToo: NIL,
ports: NETransPorts,
drivePrototype: NEW [NETransDrive]];
CreatePETransPorts[];
[] ← RoseCreate.RegisterCellClass[className: "PETrans",
expandProc: NIL,
ioCreator: CreatePETransIO, initializer: InitializePETrans,
evals: [ValsChanged: PETransValsChanged, PropQ: PETransPropQ, PropUD: PETransPropUD, FindVicinity: PETransFindVicinity],
blackBox: NIL, stateToo: NIL,
ports: PETransPorts,
drivePrototype: NEW [PETransDrive]];
CreatePDTransPorts[];
[] ← RoseCreate.RegisterCellClass[className: "PDTrans",
expandProc: NIL,
ioCreator: CreatePDTransIO, initializer: InitializePDTrans,
evals: [PropQ: PDTransPropQ, PropUD: PDTransPropUD, FindVicinity: PDTransFindVicinity],
blackBox: NIL, stateToo: NIL,
ports: PDTransPorts,
drivePrototype: NEW [PDTransDrive]];
CreateNDTransPorts[];
[] ← RoseCreate.RegisterCellClass[className: "NDTrans",
expandProc: NIL,
ioCreator: CreateNDTransIO, initializer: InitializeNDTrans,
evals: [PropQ: NDTransPropQ, PropUD: NDTransPropUD, FindVicinity: NDTransFindVicinity],
blackBox: NIL, stateToo: NIL,
ports: NDTransPorts,
drivePrototype: NEW [NDTransDrive]];
CreatePassTransistorPorts[];
[] ← RoseCreate.RegisterCellClass[className: "PassTransistor",
expandProc: NIL,
ioCreator: CreatePassTransistorIO, initializer: InitializePassTransistor,
evals: [ValsChanged: PassTransistorValsChanged, PropQ: PassTransistorPropQ, PropUD: PassTransistorPropUD, FindVicinity: PassTransistorFindVicinity],
blackBox: NIL, stateToo: NIL,
ports: PassTransistorPorts,
drivePrototype: NEW [PassTransistorDrive]];
CreatePullupTransistorPorts[];
[] ← RoseCreate.RegisterCellClass[className: "PullupTransistor",
expandProc: NIL,
ioCreator: CreatePullupTransistorIO, initializer: InitializePullupTransistor,
evals: [PropQ: PullupTransistorPropQ, PropUD: PullupTransistorPropUD, FindVicinity: PullupTransistorFindVicinity],
blackBox: NIL, stateToo: NIL,
ports: PullupTransistorPorts,
drivePrototype: NEW [PullupTransistorDrive]];
END;
--explicitly requested CEDAR:
Conductance: TYPE = {Off, Indeterminate, On};
NState: ARRAY Level OF Conductance = [Off, Indeterminate, On];
PState: ARRAY Level OF Conductance = [On, Indeterminate, Off];
CreateNETransPorts: PROC = {NETransPorts ← RoseCreate.PortsFromFile["Transistors.NETrans.rosePorts"]};
NETransIORef: TYPE = REF NETransIORec;
NETransIORec: TYPE = MACHINE DEPENDENT RECORD [
gate(0:0..15): SwitchTypes.SwitchVal,
ch1(1:0..15): SwitchTypes.SwitchVal,
ch2(2:0..15): SwitchTypes.SwitchVal];
-- port indices:
NETransGatePortIndex: CARDINAL = 0;
NETransCh1PortIndex: CARDINAL = 1;
NETransCh2PortIndex: CARDINAL = 2;
NETransDrive: TYPE = MACHINE DEPENDENT RECORD [
fill0(0:0..14): [0 .. 32768),
gate(0:15..15): BOOLEAN,
fill1(1:0..14): [0 .. 32768),
ch1(1:15..15): BOOLEAN,
fill2(2:0..14): [0 .. 32768),
ch2(2:15..15): BOOLEAN];
NETransStateRef: TYPE = REF NETransStateRec;
NETransStateRec: TYPE = RECORD [
strength: Strength ← drive,
conductance: Conductance ← Indeterminate
];
CreateNETransIO: IOCreator = {
cell.realCellStuff.switchIO ← NEW [NETransIORec];
cell.realCellStuff.newIO ← NEW [NETransIORec];
cell.realCellStuff.oldIO ← NEW [NETransIORec];
};
InitializeNETrans: Initializer = {
IF leafily THEN
BEGIN
ioRec: NETransIORef ← NARROW[cell.realCellStuff.newIO];
state: NETransStateRef ← NEW [NETransStateRec ← []];
cell.realCellStuff.state ← state;
BEGIN OPEN ioRec, state;
rs: REF Strength ← NARROW[initData];
IF rs # NIL THEN strength ← rs^;
END;
END;
};
NETransValsChanged: CellProc =
BEGIN
sw: NETransIORef ← NARROW[cell.realCellStuff.switchIO];
newIO: NETransIORef ← NARROW[cell.realCellStuff.newIO];
state: NETransStateRef ← NARROW[cell.realCellStuff.state];
BEGIN OPEN sw, state;
IF NState[gate.val] # conductance THEN
{conductance ← NState[gate.val]; PerturbPort[cell, 1]; PerturbPort[cell, 2]};
END;
END;
NETransPropQ: CellProc =
BEGIN
sw: NETransIORef ← NARROW[cell.realCellStuff.switchIO];
newIO: NETransIORef ← NARROW[cell.realCellStuff.newIO];
state: NETransStateRef ← NARROW[cell.realCellStuff.state];
BEGIN OPEN sw, state;
IF conductance = On THEN {
ch1.s[q] ← MAX[ch1.s[q], MIN[strength, ch2.s[q]]];
ch2.s[q] ← MAX[ch2.s[q], MIN[strength, ch1.s[q]]];
};
END;
END;
NETransPropUD: CellProc =
BEGIN
sw: NETransIORef ← NARROW[cell.realCellStuff.switchIO];
newIO: NETransIORef ← NARROW[cell.realCellStuff.newIO];
state: NETransStateRef ← NARROW[cell.realCellStuff.state];
BEGIN OPEN sw, state;
IF conductance # Off THEN
BEGIN
ch1.s[u] ← MAX[ch1.s[u], MIN[strength, ch2.s[u]]];
ch2.s[u] ← MAX[ch2.s[u], MIN[strength, ch1.s[u]]];
ch1.s[d] ← MAX[ch1.s[d], MIN[strength, ch2.s[d]]];
ch2.s[d] ← MAX[ch2.s[d], MIN[strength, ch1.s[d]]];
END;
END;
END;
NETransFindVicinity: PROC [cell: Cell, index: CARDINAL] =
BEGIN
sw: NETransIORef ← NARROW[cell.realCellStuff.switchIO];
newIO: NETransIORef ← NARROW[cell.realCellStuff.newIO];
state: NETransStateRef ← NARROW[cell.realCellStuff.state];
BEGIN OPEN state;
SELECT index FROM
0 => NULL;
1, 2 => IF conductance # Off THEN FindExteriorVicinity[cell, 3-index];
ENDCASE => ERROR;
END;
END;
NETransPorts: Ports ← NEW [PortsRep[3]];
CreatePETransPorts: PROC = {PETransPorts ← RoseCreate.PortsFromFile["Transistors.PETrans.rosePorts"]};
PETransIORef: TYPE = REF PETransIORec;
PETransIORec: TYPE = MACHINE DEPENDENT RECORD [
gate(0:0..15): SwitchTypes.SwitchVal,
ch1(1:0..15): SwitchTypes.SwitchVal,
ch2(2:0..15): SwitchTypes.SwitchVal];
-- port indices:
PETransGatePortIndex: CARDINAL = 0;
PETransCh1PortIndex: CARDINAL = 1;
PETransCh2PortIndex: CARDINAL = 2;
PETransDrive: TYPE = MACHINE DEPENDENT RECORD [
fill0(0:0..14): [0 .. 32768),
gate(0:15..15): BOOLEAN,
fill1(1:0..14): [0 .. 32768),
ch1(1:15..15): BOOLEAN,
fill2(2:0..14): [0 .. 32768),
ch2(2:15..15): BOOLEAN];
PETransStateRef: TYPE = REF PETransStateRec;
PETransStateRec: TYPE = RECORD [
strength: Strength ← drive,
conductance: Conductance ← Indeterminate
];
CreatePETransIO: IOCreator = {
cell.realCellStuff.switchIO ← NEW [PETransIORec];
cell.realCellStuff.newIO ← NEW [PETransIORec];
cell.realCellStuff.oldIO ← NEW [PETransIORec];
};
InitializePETrans: Initializer = {
IF leafily THEN
BEGIN
ioRec: PETransIORef ← NARROW[cell.realCellStuff.newIO];
state: PETransStateRef ← NEW [PETransStateRec ← []];
cell.realCellStuff.state ← state;
BEGIN OPEN ioRec, state;
rs: REF Strength ← NARROW[initData];
IF rs # NIL THEN strength ← rs^;
END;
END;
};
PETransValsChanged: CellProc =
BEGIN
sw: PETransIORef ← NARROW[cell.realCellStuff.switchIO];
newIO: PETransIORef ← NARROW[cell.realCellStuff.newIO];
state: PETransStateRef ← NARROW[cell.realCellStuff.state];
BEGIN OPEN sw, state;
IF PState[gate.val] # conductance THEN
{conductance ← PState[gate.val]; PerturbPort[cell, 1]; PerturbPort[cell, 2]};
END;
END;
PETransPropQ: CellProc =
BEGIN
sw: PETransIORef ← NARROW[cell.realCellStuff.switchIO];
newIO: PETransIORef ← NARROW[cell.realCellStuff.newIO];
state: PETransStateRef ← NARROW[cell.realCellStuff.state];
BEGIN OPEN sw, state;
IF conductance = On THEN {
ch1.s[q] ← MAX[ch1.s[q], MIN[strength, ch2.s[q]]];
ch2.s[q] ← MAX[ch2.s[q], MIN[strength, ch1.s[q]]];
};
END;
END;
PETransPropUD: CellProc =
BEGIN
sw: PETransIORef ← NARROW[cell.realCellStuff.switchIO];
newIO: PETransIORef ← NARROW[cell.realCellStuff.newIO];
state: PETransStateRef ← NARROW[cell.realCellStuff.state];
BEGIN OPEN sw, state;
IF conductance # Off THEN
BEGIN
ch1.s[u] ← MAX[ch1.s[u], MIN[strength, ch2.s[u]]];
ch2.s[u] ← MAX[ch2.s[u], MIN[strength, ch1.s[u]]];
ch1.s[d] ← MAX[ch1.s[d], MIN[strength, ch2.s[d]]];
ch2.s[d] ← MAX[ch2.s[d], MIN[strength, ch1.s[d]]];
END;
END;
END;
PETransFindVicinity: PROC [cell: Cell, index: CARDINAL] =
BEGIN
sw: PETransIORef ← NARROW[cell.realCellStuff.switchIO];
newIO: PETransIORef ← NARROW[cell.realCellStuff.newIO];
state: PETransStateRef ← NARROW[cell.realCellStuff.state];
BEGIN OPEN state;
SELECT index FROM
0 => NULL;
1, 2 => IF conductance # Off THEN FindExteriorVicinity[cell, 3-index];
ENDCASE => ERROR;
END;
END;
PETransPorts: Ports ← NEW [PortsRep[3]];
CreatePDTransPorts: PROC = {PDTransPorts ← RoseCreate.PortsFromFile["Transistors.PDTrans.rosePorts"]};
PDTransIORef: TYPE = REF PDTransIORec;
PDTransIORec: TYPE = MACHINE DEPENDENT RECORD [
gate(0:0..15): SwitchTypes.SwitchVal,
ch1(1:0..15): SwitchTypes.SwitchVal,
ch2(2:0..15): SwitchTypes.SwitchVal];
-- port indices:
PDTransGatePortIndex: CARDINAL = 0;
PDTransCh1PortIndex: CARDINAL = 1;
PDTransCh2PortIndex: CARDINAL = 2;
PDTransDrive: TYPE = MACHINE DEPENDENT RECORD [
fill0(0:0..14): [0 .. 32768),
gate(0:15..15): BOOLEAN,
fill1(1:0..14): [0 .. 32768),
ch1(1:15..15): BOOLEAN,
fill2(2:0..14): [0 .. 32768),
ch2(2:15..15): BOOLEAN];
PDTransStateRef: TYPE = REF PDTransStateRec;
PDTransStateRec: TYPE = RECORD [
strength: Strength ← drive,
conductance: Conductance ← On
];
CreatePDTransIO: IOCreator = {
cell.realCellStuff.switchIO ← NEW [PDTransIORec];
cell.realCellStuff.newIO ← NEW [PDTransIORec];
cell.realCellStuff.oldIO ← NEW [PDTransIORec];
};
InitializePDTrans: Initializer = {
IF leafily THEN
BEGIN
ioRec: PDTransIORef ← NARROW[cell.realCellStuff.newIO];
state: PDTransStateRef ← NEW [PDTransStateRec ← []];
cell.realCellStuff.state ← state;
BEGIN OPEN ioRec, state;
rs: REF Strength ← NARROW[initData];
IF rs # NIL THEN strength ← rs^;
END;
END;
};
PDTransPropQ: CellProc =
BEGIN
sw: PDTransIORef ← NARROW[cell.realCellStuff.switchIO];
newIO: PDTransIORef ← NARROW[cell.realCellStuff.newIO];
state: PDTransStateRef ← NARROW[cell.realCellStuff.state];
BEGIN OPEN sw, state;
IF conductance = On THEN {
ch1.s[q] ← MAX[ch1.s[q], MIN[strength, ch2.s[q]]];
ch2.s[q] ← MAX[ch2.s[q], MIN[strength, ch1.s[q]]];
};
END;
END;
PDTransPropUD: CellProc =
BEGIN
sw: PDTransIORef ← NARROW[cell.realCellStuff.switchIO];
newIO: PDTransIORef ← NARROW[cell.realCellStuff.newIO];
state: PDTransStateRef ← NARROW[cell.realCellStuff.state];
BEGIN OPEN sw, state;
IF conductance # Off THEN
BEGIN
ch1.s[u] ← MAX[ch1.s[u], MIN[strength, ch2.s[u]]];
ch2.s[u] ← MAX[ch2.s[u], MIN[strength, ch1.s[u]]];
ch1.s[d] ← MAX[ch1.s[d], MIN[strength, ch2.s[d]]];
ch2.s[d] ← MAX[ch2.s[d], MIN[strength, ch1.s[d]]];
END;
END;
END;
PDTransFindVicinity: PROC [cell: Cell, index: CARDINAL] =
BEGIN
sw: PDTransIORef ← NARROW[cell.realCellStuff.switchIO];
newIO: PDTransIORef ← NARROW[cell.realCellStuff.newIO];
state: PDTransStateRef ← NARROW[cell.realCellStuff.state];
BEGIN OPEN state;
SELECT index FROM
0 => NULL;
1, 2 => IF conductance # Off THEN FindExteriorVicinity[cell, 3-index];
ENDCASE => ERROR;
END;
END;
PDTransPorts: Ports ← NEW [PortsRep[3]];
CreateNDTransPorts: PROC = {NDTransPorts ← RoseCreate.PortsFromFile["Transistors.NDTrans.rosePorts"]};
NDTransIORef: TYPE = REF NDTransIORec;
NDTransIORec: TYPE = MACHINE DEPENDENT RECORD [
gate(0:0..15): SwitchTypes.SwitchVal,
ch1(1:0..15): SwitchTypes.SwitchVal,
ch2(2:0..15): SwitchTypes.SwitchVal];
-- port indices:
NDTransGatePortIndex: CARDINAL = 0;
NDTransCh1PortIndex: CARDINAL = 1;
NDTransCh2PortIndex: CARDINAL = 2;
NDTransDrive: TYPE = MACHINE DEPENDENT RECORD [
fill0(0:0..14): [0 .. 32768),
gate(0:15..15): BOOLEAN,
fill1(1:0..14): [0 .. 32768),
ch1(1:15..15): BOOLEAN,
fill2(2:0..14): [0 .. 32768),
ch2(2:15..15): BOOLEAN];
NDTransStateRef: TYPE = REF NDTransStateRec;
NDTransStateRec: TYPE = RECORD [
strength: Strength ← drive,
conductance: Conductance ← On
];
CreateNDTransIO: IOCreator = {
cell.realCellStuff.switchIO ← NEW [NDTransIORec];
cell.realCellStuff.newIO ← NEW [NDTransIORec];
cell.realCellStuff.oldIO ← NEW [NDTransIORec];
};
InitializeNDTrans: Initializer = {
IF leafily THEN
BEGIN
ioRec: NDTransIORef ← NARROW[cell.realCellStuff.newIO];
state: NDTransStateRef ← NEW [NDTransStateRec ← []];
cell.realCellStuff.state ← state;
BEGIN OPEN ioRec, state;
rs: REF Strength ← NARROW[initData];
IF rs # NIL THEN strength ← rs^;
END;
END;
};
NDTransPropQ: CellProc =
BEGIN
sw: NDTransIORef ← NARROW[cell.realCellStuff.switchIO];
newIO: NDTransIORef ← NARROW[cell.realCellStuff.newIO];
state: NDTransStateRef ← NARROW[cell.realCellStuff.state];
BEGIN OPEN sw, state;
IF conductance = On THEN {
ch1.s[q] ← MAX[ch1.s[q], MIN[strength, ch2.s[q]]];
ch2.s[q] ← MAX[ch2.s[q], MIN[strength, ch1.s[q]]];
};
END;
END;
NDTransPropUD: CellProc =
BEGIN
sw: NDTransIORef ← NARROW[cell.realCellStuff.switchIO];
newIO: NDTransIORef ← NARROW[cell.realCellStuff.newIO];
state: NDTransStateRef ← NARROW[cell.realCellStuff.state];
BEGIN OPEN sw, state;
IF conductance # Off THEN
BEGIN
ch1.s[u] ← MAX[ch1.s[u], MIN[strength, ch2.s[u]]];
ch2.s[u] ← MAX[ch2.s[u], MIN[strength, ch1.s[u]]];
ch1.s[d] ← MAX[ch1.s[d], MIN[strength, ch2.s[d]]];
ch2.s[d] ← MAX[ch2.s[d], MIN[strength, ch1.s[d]]];
END;
END;
END;
NDTransFindVicinity: PROC [cell: Cell, index: CARDINAL] =
BEGIN
sw: NDTransIORef ← NARROW[cell.realCellStuff.switchIO];
newIO: NDTransIORef ← NARROW[cell.realCellStuff.newIO];
state: NDTransStateRef ← NARROW[cell.realCellStuff.state];
BEGIN OPEN state;
SELECT index FROM
0 => NULL;
1, 2 => IF conductance # Off THEN FindExteriorVicinity[cell, 3-index];
ENDCASE => ERROR;
END;
END;
NDTransPorts: Ports ← NEW [PortsRep[3]];
CreatePassTransistorPorts: PROC = {PassTransistorPorts ← RoseCreate.PortsFromFile["Transistors.PassTransistor.rosePorts"]};
PassTransistorIORef: TYPE = REF PassTransistorIORec;
PassTransistorIORec: TYPE = MACHINE DEPENDENT RECORD [
gate(0:0..15): SwitchTypes.SwitchVal,
in(1:0..15): SwitchTypes.SwitchVal,
out(2:0..15): SwitchTypes.SwitchVal];
-- port indices:
PassTransistorGatePortIndex: CARDINAL = 0;
PassTransistorInPortIndex: CARDINAL = 1;
PassTransistorOutPortIndex: CARDINAL = 2;
PassTransistorDrive: TYPE = MACHINE DEPENDENT RECORD [
fill0(0:0..14): [0 .. 32768),
gate(0:15..15): BOOLEAN,
fill1(1:0..14): [0 .. 32768),
in(1:15..15): BOOLEAN,
fill2(2:0..14): [0 .. 32768),
out(2:15..15): BOOLEAN];
PassTransistorStateRef: TYPE = REF PassTransistorStateRec;
PassTransistorStateRec: TYPE = RECORD [
strength: Strength ← drive,
conductance: Conductance ← Indeterminate
];
CreatePassTransistorIO: IOCreator = {
cell.realCellStuff.switchIO ← NEW [PassTransistorIORec];
cell.realCellStuff.newIO ← NEW [PassTransistorIORec];
cell.realCellStuff.oldIO ← NEW [PassTransistorIORec];
};
InitializePassTransistor: Initializer = {
IF leafily THEN
BEGIN
ioRec: PassTransistorIORef ← NARROW[cell.realCellStuff.newIO];
state: PassTransistorStateRef ← NEW [PassTransistorStateRec ← []];
cell.realCellStuff.state ← state;
BEGIN OPEN ioRec, state;
rs: REF Strength ← NARROW[initData];
IF rs # NIL THEN strength ← rs^;
END;
END;
};
PassTransistorValsChanged: CellProc =
BEGIN
sw: PassTransistorIORef ← NARROW[cell.realCellStuff.switchIO];
newIO: PassTransistorIORef ← NARROW[cell.realCellStuff.newIO];
state: PassTransistorStateRef ← NARROW[cell.realCellStuff.state];
BEGIN OPEN sw, state;
IF NState[gate.val] # conductance THEN
{conductance ← NState[gate.val]; PerturbPort[cell, 2]};
END;
END;
PassTransistorPropQ: CellProc =
BEGIN
sw: PassTransistorIORef ← NARROW[cell.realCellStuff.switchIO];
newIO: PassTransistorIORef ← NARROW[cell.realCellStuff.newIO];
state: PassTransistorStateRef ← NARROW[cell.realCellStuff.state];
BEGIN OPEN sw, state;
IF conductance = On THEN {
IF in.s[q] < MIN[strength, out.s[q]] THEN
ERROR Error["Backward flow across unidirectional transistor!", cell];
out.s[q] ← MAX[out.s[q], MIN[strength, in.s[q]]];
};
END;
END;
PassTransistorPropUD: CellProc =
BEGIN
sw: PassTransistorIORef ← NARROW[cell.realCellStuff.switchIO];
newIO: PassTransistorIORef ← NARROW[cell.realCellStuff.newIO];
state: PassTransistorStateRef ← NARROW[cell.realCellStuff.state];
BEGIN OPEN sw, state;
IF conductance # Off THEN
BEGIN
IF in.s[u] < Block[MIN[strength, out.s[u]], in.s[q]] THEN
ERROR Error["Backward flow across unidirectional transistor!", cell];
out.s[u] ← MAX[out.s[u], MIN[strength, in.s[u]]];
IF in.s[d] < Block[MIN[strength, out.s[d]], in.s[q]] THEN
ERROR Error["Backward flow across unidirectional transistor!", cell];
out.s[d] ← MAX[out.s[d], MIN[strength, in.s[d]]];
END;
END;
END;
PassTransistorFindVicinity: PROC [cell: Cell, index: CARDINAL] =
BEGIN
sw: PassTransistorIORef ← NARROW[cell.realCellStuff.switchIO];
newIO: PassTransistorIORef ← NARROW[cell.realCellStuff.newIO];
state: PassTransistorStateRef ← NARROW[cell.realCellStuff.state];
BEGIN OPEN state;
SELECT index FROM
0 => NULL;
1 => IF state.conductance # Off THEN FindExteriorVicinity[cell, 3-index];
2 => ERROR;
ENDCASE => ERROR;
END;
END;
PassTransistorPorts: Ports ← NEW [PortsRep[3]];
CreatePullupTransistorPorts: PROC = {PullupTransistorPorts ← RoseCreate.PortsFromFile["Transistors.PullupTransistor.rosePorts"]};
PullupTransistorIORef: TYPE = REF PullupTransistorIORec;
PullupTransistorIORec: TYPE = MACHINE DEPENDENT RECORD [
gate(0:0..15): SwitchTypes.SwitchVal,
in(1:0..15): SwitchTypes.SwitchVal,
out(2:0..15): SwitchTypes.SwitchVal];
-- port indices:
PullupTransistorGatePortIndex: CARDINAL = 0;
PullupTransistorInPortIndex: CARDINAL = 1;
PullupTransistorOutPortIndex: CARDINAL = 2;
PullupTransistorDrive: TYPE = MACHINE DEPENDENT RECORD [
fill0(0:0..14): [0 .. 32768),
gate(0:15..15): BOOLEAN,
fill1(1:0..14): [0 .. 32768),
in(1:15..15): BOOLEAN,
fill2(2:0..14): [0 .. 32768),
out(2:15..15): BOOLEAN];
PullupTransistorStateRef: TYPE = REF PullupTransistorStateRec;
PullupTransistorStateRec: TYPE = RECORD [
strength: Strength ← driveWeak,
conductance: Conductance ← Indeterminate
];
CreatePullupTransistorIO: IOCreator = {
cell.realCellStuff.switchIO ← NEW [PullupTransistorIORec];
cell.realCellStuff.newIO ← NEW [PullupTransistorIORec];
cell.realCellStuff.oldIO ← NEW [PullupTransistorIORec];
};
InitializePullupTransistor: Initializer = {
IF leafily THEN
BEGIN
ioRec: PullupTransistorIORef ← NARROW[cell.realCellStuff.newIO];
state: PullupTransistorStateRef ← NEW [PullupTransistorStateRec ← []];
cell.realCellStuff.state ← state;
BEGIN OPEN ioRec, state;
rs: REF Strength ← NARROW[initData];
IF rs # NIL THEN strength ← rs^;
END;
END;
};
PullupTransistorPropQ: CellProc =
BEGIN
sw: PullupTransistorIORef ← NARROW[cell.realCellStuff.switchIO];
newIO: PullupTransistorIORef ← NARROW[cell.realCellStuff.newIO];
state: PullupTransistorStateRef ← NARROW[cell.realCellStuff.state];
BEGIN OPEN sw, state;
IF conductance = On THEN {
IF in.s[q] < MIN[strength, out.s[q]] THEN
ERROR Error["Backward flow across unidirectional transistor!", cell];
out.s[q] ← MAX[out.s[q], MIN[strength, in.s[q]]];
};
END;
END;
PullupTransistorPropUD: CellProc =
BEGIN
sw: PullupTransistorIORef ← NARROW[cell.realCellStuff.switchIO];
newIO: PullupTransistorIORef ← NARROW[cell.realCellStuff.newIO];
state: PullupTransistorStateRef ← NARROW[cell.realCellStuff.state];
BEGIN OPEN sw, state;
IF conductance # Off THEN
BEGIN
IF in.s[u] < Block[MIN[strength, out.s[u]], in.s[q]] THEN
ERROR Error["Backward flow across unidirectional transistor!", cell];
out.s[u] ← MAX[out.s[u], MIN[strength, in.s[u]]];
IF in.s[d] < Block[MIN[strength, out.s[d]], in.s[q]] THEN
ERROR Error["Backward flow across unidirectional transistor!", cell];
out.s[d] ← MAX[out.s[d], MIN[strength, in.s[d]]];
END;
END;
END;
PullupTransistorFindVicinity: PROC [cell: Cell, index: CARDINAL] =
BEGIN
sw: PullupTransistorIORef ← NARROW[cell.realCellStuff.switchIO];
newIO: PullupTransistorIORef ← NARROW[cell.realCellStuff.newIO];
state: PullupTransistorStateRef ← NARROW[cell.realCellStuff.state];
BEGIN OPEN state;
SELECT index FROM
0 => NULL;
1 => IF state.conductance # Off THEN FindExteriorVicinity[cell, 3-index];
2 => ERROR;
ENDCASE => ERROR;
END;
END;
PullupTransistorPorts: Ports ← NEW [PortsRep[3]];
RegisterCells[];
END.