[Indigo]<Rosemary>2.6>Rosemary.DF=>TransesImpl.Mesa
Last Edited by: Spreitzer, June 22, 1984 3:42:56 pm PDT
DIRECTORY IO, RoseCreate, RoseRun, RoseTypes, SimRead, SwitchTypes, Transes;
TransesImpl: CEDAR PROGRAM
IMPORTS IO, RoseCreate, RoseRun, RoseTypes, SwitchTypes
EXPORTS Transes =
BEGIN OPEN SwitchTypes, RoseRun, RoseCreate, RoseTypes;
invert: ARRAY Level OF Level = [H, X, L];
TransIORef: TYPE = REF TransIORec;
TransIORec: TYPE = MACHINE DEPENDENT RECORD [
fill0(0:0..15-bitsPerSwitchVal): [0 .. TwoToThe[16-bitsPerSwitchVal]),
gate(0:16-bitsPerSwitchVal..15): SwitchVal,
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];
TransStateRef: TYPE = REF TransStateRec;
TransStateRec: TYPE = RECORD [
td: TransDataRep,
conductance: Level];
TransData: TYPE = REF TransDataRep;
TransDataRep: TYPE = RECORD [
strength: Strength,
positive, sensitive, unidirectional: BOOL];
TransIOCreator: IOCreator--PROC [cell: Cell, initData: REF ANY]-- =
BEGIN
cell.realCellStuff.oldIO ← NEW [TransIORec];
cell.realCellStuff.newIO ← NEW [TransIORec];
cell.realCellStuff.switchIO ← NEW [TransIORec];
END;
TransInitializer: PROCEDURE [cell: Cell, leafily: BOOLEAN] --Initializer-- =
BEGIN
IF leafily THEN
BEGIN
td: TransData ← NARROW[cell.type.typeData];
cell.realCellStuff.state ← NEW [TransStateRec ← [td^, X]];
END;
END;
SensitiveTransValsChanged: PROC [cell: Cell] --CellProc-- =
BEGIN
io: TransIORef ← NARROW[cell.realCellStuff.switchIO];
state: TransStateRef ← NARROW[cell.realCellStuff.state];
BEGIN OPEN state, io;
newConductance: Level ← IF td.positive THEN gate.val ELSE invert[gate.val];
IF newConductance # conductance THEN
{conductance ← newConductance;
IF NOT td.unidirectional THEN PerturbPort[cell, 1];
PerturbPort[cell, 2]};
END;
END;
TransFindVicinity: PROC [cell: Cell, index: CARDINAL] =
BEGIN
state: TransStateRef ← NARROW[cell.realCellStuff.state];
SELECT index FROM
0 => NULL;
1, 2 => IF state.conductance # L THEN FindExteriorVicinity[cell, 3-index];
ENDCASE => ERROR;
END;
DirTransFindVicinity: PROC [cell: Cell, index: CARDINAL] =
BEGIN
state: TransStateRef ← NARROW[cell.realCellStuff.state];
SELECT index FROM
0 => NULL;
1 => IF state.conductance # L THEN FindExteriorVicinity[cell, 3-index];
2 => ERROR;
ENDCASE => ERROR;
END;
TransPropQ: CellProc--PROC [cell: Cell]-- =
BEGIN
io: TransIORef ← NARROW[cell.realCellStuff.switchIO];
state: TransStateRef ← NARROW[cell.realCellStuff.state];
BEGIN OPEN state, io;
IF conductance = H THEN {
ch1.s[q] ← MAX[ch1.s[q], MIN[td.strength, ch2.s[q]]];
ch2.s[q] ← MAX[ch2.s[q], MIN[td.strength, ch1.s[q]]];
};
END;
END;
DirTransPropQ: CellProc--PROC [cell: Cell]-- =
BEGIN
io: TransIORef ← NARROW[cell.realCellStuff.switchIO];
state: TransStateRef ← NARROW[cell.realCellStuff.state];
BEGIN OPEN state, io;
IF conductance = H THEN {
IF ch1.s[q] < MIN[td.strength, ch2.s[q]] THEN
ERROR Error["Backward flow across unidirectional transistor!", cell];
ch2.s[q] ← MAX[ch2.s[q], MIN[td.strength, ch1.s[q]]];
};
END;
END;
TransPropUD: CellProc--PROC [cell: Cell]-- =
BEGIN
io: TransIORef ← NARROW[cell.realCellStuff.switchIO];
state: TransStateRef ← NARROW[cell.realCellStuff.state];
BEGIN OPEN state, io;
IF conductance # L THEN
BEGIN
ch1.s[u] ← MAX[ch1.s[u], MIN[td.strength, ch2.s[u]]];
ch2.s[u] ← MAX[ch2.s[u], MIN[td.strength, ch1.s[u]]];
ch1.s[d] ← MAX[ch1.s[d], MIN[td.strength, ch2.s[d]]];
ch2.s[d] ← MAX[ch2.s[d], MIN[td.strength, ch1.s[d]]];
END;
END;
END;
DirTransPropUD: CellProc--PROC [cell: Cell]-- =
BEGIN
io: TransIORef ← NARROW[cell.realCellStuff.switchIO];
state: TransStateRef ← NARROW[cell.realCellStuff.state];
BEGIN OPEN state, io;
IF conductance # L THEN
BEGIN
IF ch1.s[u] < Block[MIN[td.strength, ch2.s[u]], ch1.s[q]] THEN
ERROR Error["Backward flow across unidirectional transistor!", cell];
ch2.s[u] ← MAX[ch2.s[u], MIN[td.strength, ch1.s[u]]];
IF ch1.s[d] < Block[MIN[td.strength, ch2.s[d]], ch1.s[q]] THEN
ERROR Error["Backward flow across unidirectional transistor!", cell];
ch2.s[d] ← MAX[ch2.s[d], MIN[td.strength, ch1.s[d]]];
END;
END;
END;
MakeType: PROC [strength: Strength, positive, sensitive, unidirectional: BOOL] RETURNS [ct: CellType] =
BEGIN
ports: Ports ← NEW [PortsRep[3]];
name: ROPEIO.PutFR["Transistor[%g,%g,%g,%g]", IO.int[ORD[strength]], IO.bool[positive], IO.bool[sensitive], IO.bool[unidirectional]];
td: TransData ← NEW [TransDataRep ← [
strength: strength,
positive: positive,
sensitive: sensitive,
unidirectional: unidirectional]];
ports[0] ← [0, 1, "gate", bitType, TRUE, FALSE];
IF unidirectional
THEN {
ports[1] ← [1, 1, "in", bitType, TRUE, FALSE];
ports[2] ← [2, 1, "out", bitType, FALSE, TRUE];
}
ELSE {
ports[1] ← [1, 1, "ch1", bitType, TRUE, TRUE];
ports[2] ← [2, 1, "ch2", bitType, TRUE, TRUE];
};
ct ← RegisterCellType[
name: name,
ioCreator: TransIOCreator,
initializer: TransInitializer,
evals: [
ValsChanged: IF sensitive THEN SensitiveTransValsChanged ELSE NIL,
FindVicinity: IF unidirectional THEN DirTransFindVicinity ELSE TransFindVicinity,
PropQ: IF unidirectional THEN DirTransPropQ ELSE TransPropQ,
PropUD: IF unidirectional THEN DirTransPropUD ELSE TransPropUD],
ports: ports,
typeData: td];
END;
transTypes: ARRAY Strength OF ARRAY BOOL OF ARRAY BOOL OF ARRAY BOOL OF CellType ← ALL[ALL[ALL[ALL[NIL]]]];
GetTransType: PUBLIC PROC [strength: Strength, positive, sensitive, unidirectional: BOOLFALSE] RETURNS [ct: RoseTypes.CellType] =
{IF (ct ← transTypes[strength][positive][sensitive][unidirectional]) = NIL THEN
transTypes[strength][positive][sensitive][unidirectional] ← ct ← MakeType[strength, positive, sensitive, unidirectional]};
END.