-- File: JaMSimMOS.mesa -- Written by Martin Newell January 1980 -- Last edited: August 19, 1981 10:30 AM -- JaM interface for running SimMOSFns.mesa DIRECTORY IODefs: FROM "IODefs" USING [GetOutputStream, SetOutputStream, WriteChar, WriteString, WriteLine, CR], SegmentDefs: FROM "SegmentDefs" USING [FileNameError, FileAccessError], SimMOSDefs: FROM "SimMOSDefs" USING [SimReset, CircuitReset, ETrans, DTrans, H, L, X, SH, SL, InitHi, InitLo, GetNodeValue, SimSolve, MicroStep, SimNode, EnumerateETrans, EnumerateDTrans, EnumerateNodes, RedefineETrans, RedefineDTrans,Node, Transistor, NodeNames, NodeAttributes, SetStorage], SimMOSUtilitiesDefs: FROM "SimMOSUtilitiesDefs" USING [SimMOSUtilities], SimParserDefs: FROM "SimParserDefs" USING [SimRead, SimWrite], StreamDefs: FROM "StreamDefs" USING [NewByteStream, StreamHandle, Read, Write, Append], StringDefs: FROM "StringDefs" USING [EquivalentString, AppendString], JaMFnsDefs: FROM "JaMFnsDefs" USING [Register, PopString, PushString, PopBoolean, PushInteger, PopInteger, GetJaMBreak]; JaMSimMOS: PROGRAM IMPORTS IODefs, SegmentDefs, SimMOSDefs, SimMOSUtilitiesDefs, SimParserDefs, StreamDefs, StringDefs, JaMFnsDefs = BEGIN OPEN IODefs, SegmentDefs, SimMOSDefs, SimMOSUtilitiesDefs, SimParserDefs, StreamDefs, StringDefs, JaMFnsDefs; CallSimReset: PROCEDURE = BEGIN --expects nothing SimReset[]; END; CallCircuitReset: PROCEDURE = BEGIN --expects (value) (STRING 0,1,X) value: STRING _ [50]; PopString[value]; CircuitReset[value[0]]; END; CallETrans: PROCEDURE = BEGIN --expects (STRINGs) gate: STRING _ [50]; source: STRING _ [50]; drain: STRING _ [50]; PopString[drain]; PopString[source]; PopString[gate]; [] _ ETrans[gate,source,drain]; END; CallDTrans: PROCEDURE = BEGIN --expects (STRINGs) gate: STRING _ [50]; source: STRING _ [50]; drain: STRING _ [50]; PopString[drain]; PopString[source]; PopString[gate]; [] _ DTrans[gate,source,drain]; END; CallH: PROCEDURE = BEGIN --expects (STRING) nodename: STRING _ [50]; PopString[nodename]; H[nodename]; END; CallL: PROCEDURE = BEGIN --expects (STRING) nodename: STRING _ [50]; PopString[nodename]; L[nodename]; END; CallX: PROCEDURE = BEGIN --expects (STRING) nodename: STRING _ [50]; PopString[nodename]; X[nodename]; END; CallSH: PROCEDURE = BEGIN --expects (STRING) nodename: STRING _ [50]; PopString[nodename]; SH[nodename]; END; CallSL: PROCEDURE = BEGIN --expects (STRING) nodename: STRING _ [50]; PopString[nodename]; SL[nodename]; END; CallInitHi: PROCEDURE = BEGIN --expects (STRING) nodename: STRING _ [50]; PopString[nodename]; InitHi[nodename]; END; CallInitLo: PROCEDURE = BEGIN --expects (STRING) nodename: STRING _ [50]; PopString[nodename]; InitLo[nodename]; END; CallGetNodeValue: PROCEDURE = BEGIN --expects (STRING) returns (CHARACTER (1,0,X)) nodename: STRING _ [50]; value: STRING _ [1]; PopString[nodename]; value[0] _ GetNodeValue[nodename]; value.length _ 1; PushString[value]; END; CallSimSolve: PROCEDURE = BEGIN --expects nothing, returns #iterations (0 = circuit already settled) microSteps: CARDINAL _ 0; AbortSimSolve: PROCEDURE RETURNS[BOOLEAN] = BEGIN microSteps _ microSteps+1; IF microSteps >= MaxMicroSteps THEN BEGIN WriteLine["Max microSteps exhausted"]; RETURN[TRUE]; END; IF GetJaMBreak[] THEN BEGIN WriteLine["SimSolve aborted"]; RETURN[TRUE]; END; RETURN[FALSE]; END; SimSolve[AbortSimSolve]; PushInteger[microSteps]; END; MaxMicroSteps: CARDINAL _ 100; SetMaxMicroSteps: PROCEDURE = BEGIN --expects (INTEGER) --applies only to SimSolve MaxMicroSteps _ PopInteger[]; END; CallMicroStep: PROCEDURE = BEGIN --expects nothing, returns BOOLEAN PushInteger[MicroStep[ReportChanges,ReportShorts].changed]; END; ReportChanges: BOOLEAN _ FALSE; ReportShorts: BOOLEAN _ TRUE; SetReportChanges: PROCEDURE = BEGIN --expects (BOOLEAN) --applies only to MicroStep ReportChanges _ PopBoolean[]; END; SetReportShorts: PROCEDURE = BEGIN --expects (BOOLEAN) --applies only to MicroStep ReportShorts _ PopBoolean[]; END; CallSimNode: PROCEDURE = BEGIN --expects (STRING) nodename: STRING _ [50]; PopString[nodename]; [] _ SimNode[nodename, FALSE]; END; CallSimRead: PROCEDURE = BEGIN --expects (STRING) filename: STRING _ [50]; stream: StreamHandle; BEGIN ENABLE BEGIN FileNameError => BEGIN WriteString[filename];WriteLine[": invalid file name"]; CONTINUE; END; FileAccessError => BEGIN WriteString[filename];WriteLine[": invalid file access"]; CONTINUE; END; END; PopString[filename]; IF ~DotInName[filename] THEN AppendString[filename,".sim"]; stream _ NewByteStream[filename,Read]; [] _ SimRead[stream]; stream.destroy[stream]; END; END; CallSimWrite: PROCEDURE = BEGIN --expects (STRING) filename: STRING _ [50]; stream: StreamHandle; PopString[filename]; IF ~DotInName[filename] THEN AppendString[filename,".sim"]; stream _ NewByteStream[filename,Write+Append]; SimWrite[stream]; stream.destroy[stream]; END; CallWriteState: PROCEDURE = --write state of entire circuit in JaM to enable restoring same BEGIN --expects (STRING) filename: STRING _ [50]; stream: StreamHandle; savestream: StreamHandle _ GetOutputStream[]; WriteNode: PROCEDURE[n: Node] RETURNS[BOOLEAN] = BEGIN name: STRING _ [50]; value: CHARACTER; input,storage: BOOLEAN; [value, input, storage] _ NodeAttributes[n,name]; WriteString[" ("]; WriteString[name]; WriteChar[')]; WriteLine[ IF value#'X THEN SELECT TRUE FROM input => (IF value = '0 THEN "lo" ELSE "hi"), storage => (IF value = '0 THEN "chlo" ELSE "chhi"), ENDCASE => (IF value = '0 THEN "initlo" ELSE "inithi") ELSE "x"]; RETURN[FALSE]; END; PopString[filename]; IF ~DotInName[filename] THEN AppendString[filename,".state"]; stream _ NewByteStream[filename,Write+Append]; SetOutputStream[stream]; [] _ EnumerateNodes[WriteNode]; WriteChar[CR]; SetOutputStream[savestream]; stream.destroy[stream]; END; DoListETrans: PROCEDURE = -- List enhancement mode transistors that have given terminal nodes. -- Wild card is null string BEGIN --expects (STRINGs) gate: STRING _ [50]; term1: STRING _ [50]; term2: STRING _ [50]; PopString[term2]; PopString[term1]; PopString[gate]; ListTrans1[gate,term1,term2,TRUE]; END; DoListDTrans: PROCEDURE = -- List enhancement mode transistors that have given terminal nodes. -- Wild card is null string BEGIN --expects (STRINGs) gate: STRING _ [50]; term1: STRING _ [50]; term2: STRING _ [50]; PopString[term2]; PopString[term1]; PopString[gate]; ListTrans1[gate,term1,term2,FALSE]; END; ListTrans1: PROCEDURE[gate,term1,term2: STRING, enh: BOOLEAN] = -- List transistors that have given terminal nodes. -- Wild card is null string -- enh = (TRUE,FALSE) for (enhancement,depletion) mode transistors BEGIN type: STRING; PrintTrans: PROCEDURE[t: Transistor] RETURNS[BOOLEAN] = BEGIN g: STRING _ [50]; s: STRING _ [50]; d: STRING _ [50]; NodeNames[t,g,s,d]; IF MatchTransistor[t, gate,term1,term2,g,s,d] THEN BEGIN WriteString[" ("]; WriteString[g]; WriteString[")("]; WriteString[s]; WriteString[")("]; WriteString[d]; WriteString[")"]; WriteString[type]; END; RETURN[FALSE]; END; IF enh THEN BEGIN type _ "etrans"; [] _ EnumerateETrans[PrintTrans]; END ELSE BEGIN type _ "dtrans"; [] _ EnumerateDTrans[PrintTrans]; END; WriteChar[CR]; END; CallRedefineTrans: PROCEDURE = --Redefine the transistor having given terminal nodes. Wild card is null string BEGIN --expects (STRINGs) newdrain: STRING _ [50]; newsource: STRING _ [50]; newgate: STRING _ [50]; term2: STRING _ [50]; term1: STRING _ [50]; gate: STRING _ [50]; type: STRING _ "etrans"; trans: Transistor _ NIL; FindTrans: PROCEDURE[t: Transistor] RETURNS[BOOLEAN] = BEGIN g: STRING _ [50]; s: STRING _ [50]; d: STRING _ [50]; NodeNames[t,g,s,d]; IF MatchTransistor[t, gate,term1,term2,g,s,d] THEN BEGIN IF trans=NIL THEN BEGIN trans _ t; RETURN[FALSE]; END ELSE BEGIN WriteChar['(]; WriteString[gate];WriteString[")("]; WriteString[term1];WriteString[")("]; WriteString[term2]; WriteString[") is not unique - will redefine ("]; NodeNames[trans,g,s,d]; WriteString[g];WriteString[")("]; WriteString[s];WriteString[")("]; WriteString[d];WriteChar[')]; WriteLine[type]; RETURN[TRUE]; END; END; RETURN[FALSE]; END; PopString[newdrain]; PopString[newsource]; PopString[newgate]; PopString[term2]; PopString[term1]; PopString[gate]; [] _ EnumerateETrans[FindTrans]; IF trans#NIL THEN BEGIN --matches at least one etrans - redefine first one found [] _ EnumerateDTrans[FindTrans]; --to provoke reporting ambiguity with dtrans RedefineETrans[trans, newgate,newsource,newdrain]; --do it END ELSE BEGIN --no match with etrans type _ "dtrans"; [] _ EnumerateDTrans[FindTrans]; --try dtrans IF trans#NIL THEN RedefineDTrans[trans, newgate,newsource,newdrain]; END; END; MatchTransistor: PROCEDURE[trans: Transistor, gate,term1,term2,g,s,d: STRING] RETURNS[BOOLEAN] = BEGIN RETURN[(gate.length=0 OR EquivalentString[g,gate]) AND (((term1.length=0 OR EquivalentString[s,term1]) AND (term2.length=0 OR EquivalentString[d,term2])) OR ((term1.length=0 OR EquivalentString[d,term1]) AND (term2.length=0 OR EquivalentString[s,term2])))]; END; CallSetStorage: PROCEDURE = BEGIN --expects (BOOLEAN) SetStorage[PopBoolean[]]; END; DotInName: PROCEDURE[name: STRING] RETURNS[BOOLEAN] = BEGIN FOR i:CARDINAL IN [0..name.length) DO IF name[i]='. THEN RETURN[TRUE]; ENDLOOP; RETURN[FALSE]; END; Register["simreset",CallSimReset]; Register["circuitreset",CallCircuitReset]; Register["etrans",CallETrans]; Register["dtrans",CallDTrans]; Register["hi",CallH]; Register["lo",CallL]; Register["x",CallX]; Register["chhi",CallSH]; Register["chlo",CallSL]; Register["inithi",CallInitHi]; Register["initlo",CallInitLo]; Register["getnodevalue",CallGetNodeValue]; Register["simsolve",CallSimSolve]; Register["maxmicrosteps",SetMaxMicroSteps]; Register["microstep",CallMicroStep]; Register["reportchanges",SetReportChanges]; Register["reportshorts",SetReportShorts]; Register["simnode",CallSimNode]; Register["simread",CallSimRead]; Register["simwrite",CallSimWrite]; Register["writestate",CallWriteState]; Register["listetrans",DoListETrans]; Register["listdtrans",DoListDTrans]; Register["redefinetrans",CallRedefineTrans]; Register["gatestorage",CallSetStorage]; START SimMOSUtilities; --to initialize globals - yuk SimReset[] END. (635)\1053b9B241b12B59b16B128b10B227b10B227b5B120b5B120b5B120b6B121b6B121b10B125b10B125b16B239b12B118b13B389b16B122b13B197b16B119b15B118b11B138b11B550b12B282b14B972b12B324b12B325b10B803b17B1667b15B374b14B87b9B