<> <> <> <<>> <<>> DIRECTORY CoreFlat, CoreOps, HashTable, Histograms, Icons, IO, LinearSystem, Mint, PlotGraph, Real, <> Rope, Schedule, TerminalIO, TypeScript, ViewerIO; MintImpl: CEDAR PROGRAM IMPORTS CoreFlat, CoreOps, HashTable, Histograms, Icons, IO, LinearSystem, PlotGraph, <> Schedule, TerminalIO, TypeScript, ViewerIO EXPORTS Mint SHARES Schedule ~ BEGIN OPEN Mint; <> <> <> <> <> <> <> <<];>> Path: TYPE = LIST OF RECORD[node: Node, fet: Fet]; PathList: TYPE = LIST OF Path; Delay: TYPE = REF DelayRec; DelayRec: TYPE = RECORD [tup, tdown: ps]; ExtendedCircuit: TYPE = REF ExtendedCircuitRec; ExtendedCircuitRec: TYPE = RECORD [circuit: Circuit, data: REF ANY]; TimedPlot: TYPE = REF TimedPlotRec; TimedPlotRec: TYPE = RECORD [plot: PlotGraph.Plot _ NIL, oldt: ps _ 0.0]; <> gndName: Rope.ROPE _ "public.Gnd"; vddName: Rope.ROPE _ "public.Vdd"; VddVal: mVolt _ 5000.0; GndVal: mVolt _ 0.0; pVtVal: mVolt _ -0.800; nVtVal: mVolt _ 0.780; threshold: mVolt _ 2500.0; gamma: REAL = 0.4*31.62277; -- 31.62277 = SqRt[1000.0] due to unit = mV phi: mVolt _ 1000.0; sqrtPhi: REAL _ 31.62277; timeSpecs: ps _ 5.0; tInc: ps _ 100.0; approx: REAL _ 1.4; overlapFactor: REAL _ 0.5; matrixCacheSize: CARDINAL _ 100; totalSets: CARDINAL _ 0; separateView: BOOL _ FALSE; StdOut: PUBLIC IO.STREAM _ NIL; debug: PUBLIC BOOL _ FALSE; verbose: PUBLIC BOOL _ FALSE; debugCircuit: Circuit _ NIL; debugNode: Node _ NIL; debugNodeList: NodeList _ NIL; debugHList: LIST OF Schedule.History _ NIL; statsNumberOfSimulations: CARDINAL _ 0; nSimInc: CARDINAL _ 50; <> SimulateSet: PROC [ref: REF ANY, t: ps, data: REF ANY] ~ { circuit: Circuit ~ NARROW[data]; set: Set ~ NARROW[ref]; agenda: Schedule.Agenda ~ circuit.agenda; subsets: SetList; nodeList: NodeList; finished, firstTime: BOOLEAN _ FALSE; inputHistories: LIST OF Schedule.History; timeList: LIST OF ps; tmin, tmax, tmaxmin, tmaxmax: ps; IF set=NIL THEN RETURN; IF set.done THEN RETURN; set.done _ TRUE; IF debug THEN {IO.PutF[StdOut, "\n\n%5d ~~~>",IO.real[t]]; PrintSetType[set.type]; IO.PutF[StdOut, "\nInputs :"];}; nodeList _ ScanHistoriesOfNodeList[set.inList, t, agenda, FALSE]; FOR inode: NodeList _ nodeList, inode.rest UNTIL inode=NIL DO IF verbose THEN IO.PutF[StdOut,"\n Unknown Input: %g ", IO.rope[RopeFromNode[inode.first, circuit]]] ENDLOOP; nodeList _ ScanHistoriesOfNodeList[set.lNodes, t, agenda]; firstTime _ nodeList#NIL; FOR inode: NodeList _ set.inList, inode.rest UNTIL inode=NIL DO IF debug THEN PrintNode[inode.first, circuit]; inputHistories _ CONS[inode.first.history, inputHistories]; ENDLOOP; FOR inode: NodeList _ set.fixedV, inode.rest UNTIL inode=NIL DO IF ~inode.first.input THEN ResetInput[inode.first, set] ENDLOOP; FOR inode: NodeList _ set.lNodes, inode.rest UNTIL inode=NIL DO IF inode.first.input THEN SetInput[inode.first, set] ENDLOOP; IF debug THEN IO.PutF[StdOut, "\nOutputs:"]; timeList _ Schedule.Schedule[inputHistories]; tmin _ t; UNTIL timeList.first>=tmin OR timeList.rest=NIL DO timeList _ timeList.rest; ENDLOOP; tmaxmin _ timeList.first; IF set.type.solve#NIL THEN tmaxmin _ set.type.solve[set, tmin, circuit] ELSE UNTIL finished DO [finished , tmin] _ FlipSwitches[set.lFets, tmin, tmaxmin]; IF firstTime THEN finished _ FALSE; firstTime _ FALSE; IF ~finished THEN { tmaxmax _ tmaxmin; subsets _ ClipSet[set]; FOR isubset: SetList _ subsets, isubset.rest UNTIL isubset=NIL DO tmax _ RCSolve[isubset.first, tmin, circuit]; tmaxmin _ MIN[tmaxmin, tmax]; tmaxmax _ MAX[tmaxmax, tmax]; IF debug AND verbose THEN { IO.PutF[StdOut, "\nsubset between %g and %g", IO.real[tmin], IO.real[tmax]]; PrintNodeList[isubset.first.lNodes, circuit]; }; ENDLOOP; KillSetList[subsets, TRUE]; } ELSE { tmin _ tmaxmin; UNTIL timeList.first>tmin OR timeList.rest=NIL DO timeList _ timeList.rest; ENDLOOP; IF MAX[tmaxmax, timeList.first]> tmaxmin THEN finished _ FALSE; tmaxmin _ IF timeList.first>tmaxmin THEN timeList.first ELSE tmaxmax; }; ENDLOOP; FOR inode: NodeList _ set.lNodes, inode.rest UNTIL inode=NIL DO FOR setList: SetList _ inode.first.setList, setList.rest UNTIL setList=NIL DO Schedule.InsertInAgenda[agenda, setList.first, Schedule.NextTimeOfHistory[inode.first.history, t+1]]; setList.first.done _ FALSE; ENDLOOP; ENDLOOP; circuit.info.nbOfSimulations _ circuit.info.nbOfSimulations+1; IF verbose THEN IF (circuit.info.nbOfSimulations MOD nSimInc) = 0 THEN IO.PutF[StdOut, "\n%5d t : %5d, No of events : %7d", IO.int[circuit.info.nbOfSimulations], IO.real[agenda.list.first.t], IO.int[agenda.nbOfEvents]]; }; ScanHistoriesOfNodeList: PROC [nodeList: NodeList, t: ps, agenda: Schedule.Agenda, cut: BOOLEAN _ TRUE] RETURNS [uninitialized: NodeList] ~ { CutHistory: PROC[node: Node] RETURNS [quit: BOOLEAN _ FALSE] ~ { IF node.history=NIL THEN RETURN; IF node.input THEN RETURN; t1 _ Schedule.NextTimeOfHistory[node.history, t+tInc]; IF t1>t AND Schedule.LastTimeOfHistory[node.history]>t1 THEN { node.history _ Schedule.AddToHistory[node.history, t1, Schedule.VFromHistory[node.history, t1]]; FOR iSetList: SetList _ node.setList, iSetList.rest UNTIL iSetList=NIL DO Schedule.InsertInAgenda[agenda, iSetList.first, t1]; iSetList.first.done _ FALSE; FOR inodeList: NodeList _ iSetList.first.lNodes, inodeList.rest UNTIL inodeList=NIL DO quit _ CutHistory[inodeList.first]; ENDLOOP; ENDLOOP; }; }; t1: ps _ t+tInc; FOR inode: NodeList _ nodeList, inode.rest UNTIL inode=NIL DO <> IF inode.first.history=NIL THEN { uninitialized _ CONS[inode.first, uninitialized]; inode.first.history _ Schedule.CreateHistory[t, GndVal+0.0314159]; } ELSE { IF ~inode.first.watched THEN inode.first.history _ Schedule.ForgetBeginings[inode.first.history, t]; IF cut THEN [] _ CutHistory[inode.first]; }; ENDLOOP; }; <> <> <> <> <> <> <> <> <<};>> <<>> FindInputs2: PROC [set: Set] ~ { found: BOOLEAN; FOR ifet: FetList _ set.lFets, ifet.rest UNTIL ifet=NIL DO found _ FALSE; FOR inode: NodeList _ set.lNodes, inode.rest UNTIL inode=NIL DO IF inode.first=ifet.first.gate THEN { found _ TRUE; EXIT; }; ENDLOOP; IF ~found THEN { found _ FALSE; FOR inode: NodeList _ set.inList, inode.rest UNTIL inode=NIL DO IF inode.first=ifet.first.gate THEN { found _ TRUE; EXIT; }; ENDLOOP; IF ~found THEN set.inList _ CONS[ifet.first.gate, set.inList]; }; ENDLOOP; }; NextFetList2: PROC [set: Set, nodeList: NodeList] RETURNS [fetList: FetList _ NIL] ~ { FOR iNodeList: NodeList _ nodeList, iNodeList.rest UNTIL iNodeList = NIL DO FOR i: NAT IN [0..iNodeList.first.fetSeq.nUsed) DO fet: Fet = iNodeList.first.fetSeq[i]; IF NOT fet.done THEN IF fet.gate # iNodeList.first THEN { fetList _ CONS[fet, fetList]; set.lFets _ CONS[fet, set.lFets]; fet.done _ TRUE; }; ENDLOOP; ENDLOOP; }; --NextFetList2 NextNodeList2: PROC [set: Set, fetList: FetList] RETURNS [nodeList: NodeList _ NIL] ~ { FOR iFetList: FetList _ fetList, iFetList.rest UNTIL iFetList = NIL DO IF NOT iFetList.first.ch1.done THEN { nodeList _ CONS[iFetList.first.ch1, nodeList]; set.lNodes _ CONS[iFetList.first.ch1, set.lNodes]; iFetList.first.ch1.done _ TRUE; }; IF NOT iFetList.first.ch2.done THEN { nodeList _ CONS[iFetList.first.ch2, nodeList]; set.lNodes _ CONS[iFetList.first.ch2, set.lNodes]; iFetList.first.ch2.done _ TRUE; }; ENDLOOP; }; --NextNodeList2 ClipSet: PROC [totalSet: Set, cutNodes: NodeList _ NIL] RETURNS [setList: SetList _ NIL] ~ { set: Set; nodeList: NodeList; fetList: FetList; FOR iFetList: FetList _ totalSet.lFets, iFetList.rest UNTIL iFetList = NIL DO iFetList.first.done _ ~iFetList.first.switch; ENDLOOP; FOR iNodeList: NodeList _ totalSet.lNodes, iNodeList.rest UNTIL iNodeList=NIL DO iNodeList.first.done _ FALSE; ENDLOOP; FOR iNodeList: NodeList _ totalSet.fixedV, iNodeList.rest UNTIL iNodeList=NIL DO iNodeList.first.done _ TRUE; ENDLOOP; FOR iNodeList: NodeList _ cutNodes, iNodeList.rest UNTIL iNodeList=NIL DO iNodeList.first.done _ TRUE; ENDLOOP; FOR inodeList: NodeList _ totalSet.lNodes, inodeList.rest UNTIL inodeList=NIL DO IF inodeList.first.done THEN LOOP; set _ NEW[SetRec]; nodeList _ LIST[inodeList.first]; set.lNodes _ nodeList; inodeList.first.done _ TRUE; UNTIL nodeList=NIL DO fetList _ NextFetList2[set, nodeList]; nodeList _ NextNodeList2[set, fetList]; ENDLOOP; FOR iNodeList: NodeList _ totalSet.fixedV, iNodeList.rest UNTIL iNodeList=NIL DO iNodeList.first.done _ FALSE; ENDLOOP; FOR iFetList: FetList _ set.lFets, iFetList.rest UNTIL iFetList=NIL DO IF iFetList.first.ch1.input THEN IF ~iFetList.first.ch1.done AND iFetList.first.switch THEN { iFetList.first.ch1.done _ TRUE; set.fixedV _ CONS[iFetList.first.ch1, set.fixedV]; }; IF iFetList.first.ch2.input THEN IF ~iFetList.first.ch2.done AND iFetList.first.switch THEN { iFetList.first.ch2.done _ TRUE; set.fixedV _ CONS[iFetList.first.ch2, set.fixedV]; }; ENDLOOP; FOR iNodeList: NodeList _ totalSet.fixedV, iNodeList.rest UNTIL iNodeList=NIL DO iNodeList.first.done _ TRUE; ENDLOOP; setList _ CONS[set, setList]; ENDLOOP; }; <> <> <> <> <> <> <> <> <> <> <> < status _ FALSE;>> <=vDrain => status _ TRUE;>> < {>> <> < vTran);>> <<};>> <<};>> < {>> <> <> <> <> <> <