Transistors.Rose
Last Edited by: Spreitzer, October 6, 1984 7:16:41 pm PDT
Last Edited by: Gasbarro, August 17, 1984 11:22:10 am PDT
Imports Asserting, BiasTypes, RoseCreate, RoseRun, RoseTypes, SwitchTypes;
Open SwitchTypes, RoseRun, RoseCreate, RoseTypes;
CEDAR
Mode: PUBLIC TYPE = {Enhancement, Depletion};
Conductance: TYPE = {Off, On, Indeterminate};
ComputeState: ARRAY Mode OF ARRAY BOOL--positive-- OF ARRAY Level OF Conductance = [
Enhancement: [[On, Off, Indeterminate], [Off, On, Indeterminate]],
Depletion: [ALL[On], ALL[On]]];
Gate: TYPE = RECORD [variant: SELECT COMPUTED BOOL--biased-- FROM
FALSE => [switch: SwitchVal],
TRUE => [bh: BiasTypes.BiasHolder],
ENDCASE];
SG: TYPE = Gate[FALSE];
BG: TYPE = Gate[TRUE];
TransIORef: TYPE = REF TransIORec;
TransIORec: TYPE = MACHINE DEPENDENT RECORD [
gate(0:0..15): Gate,
fill1(1:0..15-bitsPerSwitchVal): [0 .. TwoToThe[16-bitsPerSwitchVal]),
ch1(1:16-bitsPerSwitchVal..15): SwitchVal,
fill2(2:0..15-bitsPerSwitchVal): [0 .. TwoToThe[16-bitsPerSwitchVal]),
ch2(2:16-bitsPerSwitchVal..15): SwitchVal];
BiasToLevel: ARRAY BiasTypes.Bias OF Level = [H, L];
classes: ARRAY --positive--BOOL OF ARRAY Mode OF ROPE ← [
FALSE: [Enhancement: "pE", Depletion: "pD"],
TRUE: [Enhancement: "nE", Depletion: "nD"]];
;
Transistor:
LAMBDA [
strength: |Strength ← drive|,
positive: |BOOLTRUE|,
mode: |Mode ← Enhancement|,
unidirectional: |BOOLFALSE|,
biased: |BOOLFALSE|,
offStrength: |Strength ← none|]
RETURN CELLTYPE AutoName
PortsProc
ports ← NEW [PortsRep[3]];
ports[0] ← [0, 1, "gate", IF biased THEN BiasTypes.biasType ELSE bitType, TRUE, FALSE];
IF unidirectional
THEN {
ports[1] ← [1, 1, "ch1", bitType, TRUE, FALSE];
ports[2] ← [2, 1, "ch2", bitType, FALSE, TRUE];
}
ELSE {
ports[1] ← [1, 1, "ch1", bitType, TRUE, TRUE];
ports[2] ← [2, 1, "ch2", bitType, TRUE, TRUE];
ports[1].other ← Asserting.Assert[reln: $EC, terms: LIST[NARROW["Structure", ROPE], NARROW["ch", ROPE]], inAdditionTo: ports[1].other];
ports[2].other ← Asserting.Assert[reln: $EC, terms: LIST[NARROW["Structure", ROPE], NARROW["ch", ROPE]], inAdditionTo: ports[2].other];
};
InitCTProps
other ← Asserting.Assert[reln: $EC, terms: LIST[NARROW["Structure", ROPE], classes[positive][mode]], inAdditionTo: other];
IOCreator
cell.realCellStuff.newIO ← NEW [TransIORec];
cell.realCellStuff.oldIO ← NEW [TransIORec];
cell.realCellStuff.switchIO ← NEW [TransIORec];
IORefTypeName TransIORef
State
conductance: Conductance
Initializer
conductance ← SELECT mode FROM Enhancement => Indeterminate, Depletion => On, ENDCASE => ERROR;
conductance ← ComputeState[mode][positive][WITH g: gate SELECT biased FROM FALSE => g.switch.val, TRUE => BiasToLevel[g.bh.bias], ENDCASE => ERROR];
EvalSimple
IF mode = Enhancement AND biased THEN {
new: Conductance ← ComputeState[mode][positive][WITH g: gate SELECT biased FROM FALSE => g.switch.val, TRUE => BiasToLevel[g.bh.bias], ENDCASE => ERROR];
IF new # conductance THEN {
conductance ← new;
IF NOT unidirectional THEN PerturbPort[cell, 1];
PerturbPort[cell, 2];
}
};
ValsChanged
IF mode = Enhancement AND NOT biased THEN {
new: Conductance ← ComputeState[mode][positive][WITH g: gate SELECT biased FROM FALSE => g.switch.val, TRUE => BiasToLevel[g.bh.bias], ENDCASE => ERROR];
IF new # conductance THEN {
conductance ← new;
IF NOT unidirectional THEN PerturbPort[cell, 1];
PerturbPort[cell, 2];
}
};
FindVicinity
NotOff: PROC RETURNS [no: BOOL] = INLINE {
no ← SELECT conductance FROM
On, Indeterminate => TRUE,
Off => offStrength > none,
ENDCASE => ERROR};
SELECT portIndex FROM
0 => NULL;
1 => IF NotOff[] THEN FindExteriorVicinity[cell, 3-portIndex];
2 => IF unidirectional THEN ERROR
ELSE IF NotOff[] THEN FindExteriorVicinity[cell, 3-portIndex];
ENDCASE => ERROR;
PropQ
cs: Strength = SELECT conductance FROM
On => strength,
Off, Indeterminate => offStrength,
ENDCASE => ERROR;
IF cs > none THEN {
IF unidirectional THEN NULL ELSE
ch1.s[q] ← MAX[ch1.s[q], MIN[cs, ch2.s[q]]];
ch2.s[q] ← MAX[ch2.s[q], MIN[cs, ch1.s[q]]];
};
InitUD
cs: Strength = SELECT conductance FROM
On => strength,
Off, Indeterminate => offStrength,
ENDCASE => ERROR;
IF unidirectional AND ch1.s[q] < MIN[cs, ch2.s[q]] THEN
ERROR Error["Backward flow across unidirectional transistor!", cell];
PropUD
cs: Strength = SELECT conductance FROM
On, Indeterminate => strength,
Off => offStrength,
ENDCASE => ERROR;
IF cs > none THEN {
IF unidirectional THEN NULL
ELSE {
ch1.s[u] ← MAX[ch1.s[u], MIN[cs, ch2.s[u]]];
ch1.s[d] ← MAX[ch1.s[d], MIN[cs, ch2.s[d]]];
};
ch2.s[u] ← MAX[ch2.s[u], MIN[cs, ch1.s[u]]];
ch2.s[d] ← MAX[ch2.s[d], MIN[cs, ch1.s[d]]];
};
FinalUD
cs: Strength = SELECT conductance FROM
On, Indeterminate => strength,
Off => offStrength,
ENDCASE => ERROR;
IF cs > none AND unidirectional THEN {
IF ch1.s[u] < Block[MIN[cs, ch2.s[u]], ch1.s[q]] THEN
ERROR Error["Backward flow across unidirectional transistor!", cell];
IF ch1.s[d] < Block[MIN[cs, ch2.s[d]], ch1.s[q]] THEN
ERROR Error["Backward flow across unidirectional transistor!", cell];
};
ENDCELLTYPE;
nE: Transistor[];
nD: Transistor[mode: Depletion, strength: driveWeak];
pE: Transistor[positive: FALSE];
unE: Transistor[unidirectional: TRUE];
unD: Transistor[mode: Depletion, strength: driveWeak, unidirectional: TRUE];
upE: Transistor[positive: FALSE, unidirectional: TRUE];
wpu: Transistor[strength: driveWeak, positive: FALSE, unidirectional: TRUE];
wpd: Transistor[offStrength: driveWeak, unidirectional: TRUE, biased: TRUE]