<> <> <> 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): Gate, ch1(1): SwitchVal, ch2(2): 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: |BOOL _ TRUE|, mode: |Mode _ Enhancement|, unidirectional: |BOOL _ FALSE|, biased: |BOOL _ FALSE|, 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]; IOAux RecType TransIORec <> State conductance: Conductance Initializer < 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, 2 => 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]