DIRECTORY Globals, IO, Model, Printout, SlopeModel; SlopeModelImpl: CEDAR PROGRAM IMPORTS Globals, IO, Model, Printout EXPORTS SlopeModel = BEGIN OPEN Globals, Model; maxUpRatio: ARRAY[0..maxFetTypes) OF REAL _ ALL[0]; maxDownRatio: ARRAY[0..maxFetTypes) OF REAL _ ALL[0]; SlopeDelay: PUBLIC DelayProc = BEGIN f: Fet; r, c, resVolts, rFactor, rcIntegral, tmp: REAL; rEff, ratio: REF ParmArray; thisC, thisR, tmp2: REAL; esIntegral, es: REAL; isLoad: BOOLEAN; type: TType; i: INT; stage.time _ -1.0; stage.edgeSpeed _ 0; IF (stage.piece1Size = 0) AND (stage.piece2Size <= 1) THEN BEGIN IO.PutRope[StdOut, "Crystal bug: nothing in stage!\n"]; RETURN; END; IF stage.rise THEN BEGIN resVolts _ vdd^ - vinv^; rFactor _ rUpFactor^; END ELSE BEGIN resVolts _ vinv^; rFactor _ rDownFactor^; END; IF (stage.piece1Size = 0) AND (stage.piece2Node[0].always0 OR stage.piece2Node[0].always1) THEN isLoad _ TRUE ELSE isLoad _ FALSE; r _ 0.0; c _ 0.0; es _ 0.0; rcIntegral _ 0.0; esIntegral _ 0.0; FOR i IN [0..stage.piece1Size) DO IF i # 0 THEN BEGIN f _ stage.piece1Fet[i]; type _ TypeTable[f.type]; IF stage.rise THEN BEGIN tmp _ type.upREff[0]; es _ es + type.upOutES[0] * f.aspect; END ELSE BEGIN tmp _ type.downREff[0]; es _ es + type.downOutES[0] * f.aspect; END; IF tmp = 0 THEN RETURN; r _ r + (tmp * f.aspect); END; IF i # (stage.piece1Size - 1) THEN BEGIN tmp _ stage.piece1Node[i].res; r _ r + (tmp * rFactor); es _ es + tmp/(resVolts*1000); END; ENDLOOP; FOR i IN [0..stage.piece2Size) DO IF (i=0) AND isLoad THEN LOOP; IF (i # 0) OR (stage.piece1Size # 0) THEN BEGIN thisR _ stage.piece2Node[i].res; thisC _ stage.piece2Node[i].cap; r _ r + (thisR*rFactor); c _ c + thisC; rcIntegral _ rcIntegral + (r * thisC); es _ es + thisR/(resVolts*1000); esIntegral _ esIntegral + (es * thisC); END; f _ stage.piece2Fet[i]; IF f # NIL THEN BEGIN type _ TypeTable[f.type]; IF stage.rise THEN BEGIN thisR _ type.upREff[0]; es _ es + type.upOutES[0] * f.aspect; END ELSE BEGIN thisR _ type.downREff[0]; es _ es + type.downOutES[0] * f.aspect; END; IF thisR = 0 THEN RETURN; r _ r + thisR*f.aspect; thisC _ f.area * type.cPerArea; c _ c + thisC; rcIntegral _ rcIntegral + (thisC * r); esIntegral _ esIntegral + (thisC * es); END; ENDLOOP; IF stage.piece1Size = 0 THEN BEGIN IF NOT isLoad THEN BEGIN stage.time _ rcIntegral/1000.0 + stage.prev.time; stage.edgeSpeed _ esIntegral; RETURN; END; f _ stage.piece2Fet[0]; END ELSE f _ stage.piece1Fet[0]; type _ TypeTable[f.type]; IF stage.rise THEN BEGIN ratio _ type.upESRatio; rEff _ type.upREff; esIntegral _ esIntegral + (c * type.upOutES[0] * f.aspect); END ELSE BEGIN ratio _ type.downESRatio; rEff _ type.downREff; esIntegral _ esIntegral + (c * type.downOutES[0] * f.aspect); END; IF rEff[0] = 0 THEN RETURN; IF c = 0 THEN BEGIN IO.PutF[StdOut, "Zero capacitance in stage leading to %s!\n", IO.rope[Printout.NodeRope[stage.piece2Node[stage.piece2Size-1], globalVars]]]; stage.time _ stage.prev.time; stage.edgeSpeed _ 0; RETURN; END; tmp _ stage.prev.edgeSpeed/esIntegral; FOR i IN [0..maxSlopePoints-1) DO IF tmp < ratio[i+1] THEN EXIT; IF ratio[i+1] < ratio[i] THEN EXIT; ENDLOOP; IF tmp >= ratio[i+1] THEN BEGIN IF stage.rise THEN BEGIN IF tmp > maxUpRatio[f.type] THEN BEGIN maxUpRatio[f.type] _ tmp; IO.PutF[StdOut, "Warning: ran off end of %s up slope table with\n", IO.rope[type.name]]; IO.PutF[StdOut, " edge speed ratio %f. Maybe you should ", IO.real[tmp]]; IO.PutRope[StdOut, "expand\n the range of the table.\n"]; END; END ELSE BEGIN IF tmp > maxDownRatio[f.type] THEN BEGIN maxDownRatio[f.type] _ tmp; IO.PutF[StdOut, "Warning: ran off end of %s down slope table with\n", IO.rope[type.name]]; IO.PutF[StdOut, " edge speed ratio %f. Maybe you should ", IO.real[tmp]]; IO.PutRope[StdOut, "expand\n the range of the table.\n"]; END; END; i _ i-1; END; tmp _ (tmp - ratio[i])/(ratio[i+1] - ratio[i]); tmp2 _ f.aspect * (rEff[i] + (tmp * (rEff[i+1] - rEff[i]))); rcIntegral _ rcIntegral + tmp2*c; stage.time _ rcIntegral/1000.0 + stage.prev.time; stage.edgeSpeed _ esIntegral; END; END. ¦FILE: SlopeModelImpl.mesa Last edited by Ousterhout, November 29, 1983 2:50 pm Christian LeCocq April 11, 1986 2:27:56 pm PST This file implements the slope model for Xerox Crystal. To understand how the slope model works, see either the Berkeley code or the paper by Ousterhout on the Crystal models. This model uses slopes and the Penfield-Rubinstein model for distributed capacitance. It uses intrinsic rise-times everywhere (the outES tables are not used). The following stuff is used to keep from printing zillions of messages when the tables overflow a lot. Make sure that there is stuff in the stage. Precompute the voltage drop used to compute resistor edge speeds. Figure out if there's a load driving this stage. We know there's a load if there's no piece1 and the first node in piece2 is fixed in value. Go through the two pieces of the path, computing the integral of RdC through the path. There are a couple of hitches in this. First of all, don't count any capacitance in piece1: we assume it's been discharged already. Also, we have to leave out any resistance associated with the trigger transistor for now (it will be interpolated and added later). To add in its value later, we have to remember the total capacitance of the path. Also, leave out the capacitance and resistance of the node that is signal source: it is supposed to have infinite capacitance and zero resistance. The last node in piece1 is the signal source, so don't consider it. When the stage is load-driven, we don't consider the first transistor (it will be interpolated below), or the first node in piece2, since it is the signal source. If no piece1, then first node in piece2 supplies signal so don't use the capacitance or resistance associated with the node. If this stage is a carry-over from a bus (no piece1 and not a load), then we're done; return the RC integral as the delay, and sum the RC integral and the edgeSpeed from the last stage to produce the new edgeSpeed for this stage. If this isn't a bus carryover, then figure out which is the transistor that is to be used for interpolation. Now do linear interpolation in the slope tables to compute the effective resistance of the trigger or load transistor. Zero resistance means this transistor can't drive in this direction, so return immediately. Zero capacitance means the node transits instantly. If we ran off the top of the table, then use the last two values in the table for extrapolation. ΚM˜Jšœ™šœ4™4Icode™.—J˜JšœΡ™ΡJ˜šΟk ˜ J˜Jšœ˜J˜J˜ J˜ —J˜JšΟnœœ˜š˜J˜Jšœ˜J˜J˜—Jšœ ˜Jš˜Jšœ˜J˜Jšœf™fJ˜Jš œ œœœœ˜4Jš œœœœœ˜5J˜J˜šž œœ ˜Jš˜J˜Jšœ*œ˜/Jšœ œ ˜Jšœœ˜Jšœœ˜Jšœœ˜J˜ Jšœœ˜J˜Jšœ+™+J˜J˜J˜šœœ˜:Jš˜Jšœ6˜8Jšœ˜Jšœ˜—J˜JšœA™AJ˜šœ ˜Jš˜J˜J˜Jš˜—š˜Jš˜J˜J˜Jšœ˜—J˜Jšœ™J˜šœ˜Jšœœ˜AJšœ ˜ —Jšœ œ˜J˜JšœΚ™ΚJ˜J˜J˜J˜ J˜J˜šœœ˜!šœ˜ Jš˜J˜J˜šœ ˜Jš˜J˜J˜%Jš˜—š˜Jš˜J˜J˜'Jšœ˜—Jšœ œœ˜J˜Jšœ˜—J˜JšœC™CJ˜šœ˜"Jš˜J˜J˜J˜Jšœ˜—Jšœ˜—J˜šœœ˜!Jšœ’™’J˜Jšœœœœ˜J˜Jšœ|™|J˜šœ œ˜)Jš˜J˜ J˜ J˜J˜J˜&J˜ J˜'Jšœ˜—J˜šœœ˜Jš˜J˜šœ ˜Jš˜J˜J˜%Jš˜—š˜Jš˜J˜J˜'Jšœ˜—Jšœ œœ˜J˜J˜J˜J˜&J˜'Jšœ˜—Jšœ˜J˜—JšœΤ™ΤJ˜šœ˜Jš˜šœœ˜Jš˜J˜1J˜Jšœ˜Jšœ˜—J˜Jš˜—Jšœ˜J˜Jšœv™vJ˜J˜šœ ˜Jš˜J˜J˜J˜;Jš˜—š˜Jš˜J˜J˜J˜=Jšœ˜—J˜Jšœ™J˜Jšœ œœ˜šœ˜ Jš˜Jšœ;œL˜ŒJ˜J˜Jšœ˜Jšœ˜—J˜J˜&J˜šœœ˜!Jšœœœ˜Jšœœœ˜#Jšœ˜—J˜Jšœ`™`J˜šœ˜Jš˜šœ ˜Jš˜šœ˜ Jš˜J˜JšœAœ˜XJšœ<œ ˜MJšœ:˜