2.1. pyopus.evaluator.measure — Performance measure extraction

Inheritance diagram of pyopus.evaluator.measure

Performance measure extraction module

All functions in this module do one of the following things:

  • return an object of a Python numeric type (int, float, or complex)
  • return an n-dimensional array (where n can be 0) of int, float or complex type
  • return None to indicate a failure
  • raise an exception to indicate a more severe failure

All signals x(t) are defined in tabular form which means that a signal is fully defined with two 1-dimensional arrays of values of the same size. One array is the scale which represents the values of the scale (t) while the other column represents the values of the signal (x) corresponding to the scale points.

pyopus.evaluator.measure.debug(msg)

Prints a debug message in the log.

pyopus.evaluator.measure.Deg2Rad(degrees)

Converts degrees to radians.

pyopus.evaluator.measure.Rad2Deg(radians)

Converts radians to degrees.

pyopus.evaluator.measure.dB2gain(db, unit='db20')

Converts gain magnitude in decibels to gain as a factor.

unit is the type of decibels to convert from:

  • db and db20 are equivalent and should be used when the conversion of voltage/current gain decibels is required (20dB = gain factor of 10.0).
  • db10 should be used for power gain decibels conversion (10dB = gain factor of 10.0)
pyopus.evaluator.measure.gain2dB(x, unit='db20')

Converts gain as a factor to magnitude in decibels.

unit is the type of decibels to convert to:

  • db and db20 are equivalent and should be used when the conversion to voltage/current gain decibels is required (gain factor of 10.0 = 20dB).
  • db10 should be used for conversion to power gain decibels conversion (gain factor of 10.0 = 10dB)
pyopus.evaluator.measure.XatI(x, i)

Returns the value in 1-dimensional array x corresponding to fractional index i. This operation is equivalent to a table lookup with linear interpolation where the first column of the table represents the index (i) and the second column holds the components of *x.

If i is a 1-dimensional array the return value is an array of the same shape holding the results of table lookups corresponding to fractional indices in array i.

i must satisfy 0 <= i <= x.size-1.

pyopus.evaluator.measure.IatXval(x, val, slope='any')

Returns a 1-dimensional array of fractional indices corresponding places in vector x where the linearly interpolated value is equal to val. These are the crossings of function f(i)=x(i) with g(i)=val. slope specifies what kind of crossings are returned:

  • any - return all crossings
  • rising - return only crossings where the slope of f(i) is positive or zero
  • falling - return only crossings where the slope of f(i) is negative or zero

This function corresponds to a reverse table lookup with linear interpolation where the first folumn of the table contains the index and the second column contains the corresponding values of x. The reverse lookup finds the fractional indices coresponding to val in the second column of the table.

There can be no crossings (empty return array) or more than one crossing (return array size>1).

The fractional indices are returned in an increasing sequence.

pyopus.evaluator.measure.filterI(i, direction='right', start=None, includeStart=False)

Returns a 1-dimensional array of fractional indices obtained by processing fractional indices given in i.

If direction is right i is traversed from lower to higher indices. Only the indices from i that are greater than start are included in the return value.

If direction is left i is traversed from higher to lower indices. Only the indices from i that are less than start are included in the return value.

The filtered indices are returned in the same order as they appear in i.

If includeStart is True the greater than and less than comparison operators are replaced by greater than or equal to and less than or equal to. This includes indices which are equal to start in the return value.

If start is not given, it defaults to i[0] if direction is right and i[-1] if direction is left.

pyopus.evaluator.measure.XatIrange(x, i1, i2=None)

Returns a subvector (1-dimensional array) of a vector given by 1-dimensional array x. The endpoints of the subvector correspond to fractional indices i1 and i2.

If i2 is not given the return value is the same as the return value of XatI(x, i1).

i1 and i2 must satisfy

  • 0 <= i1 <= x.size-1
  • 0 <= i2 <= x.size-1
  • i1 <= i2

If the endpoints do not correspond to integer indices the subvector endpoints are obtained with linear interpolation (see XatI() function).

pyopus.evaluator.measure.dYdI(y)

Returns the derivative of 1-dimensional vector y with respect to its index.

Uses 2nd order polynomial interpolation before the actual derivative is calculated.

pyopus.evaluator.measure.dYdX(y, x)

Derivative of a 1-dimensional vector y with respect to the 1-dimensional vector x. The arrays representing y and x must be of the same size.

pyopus.evaluator.measure.integYdX(y, x)

Integral of a 1-dimensional vector x with respect to its scale given by a 1-dimensional vector x. The arrays representing y and x must be of the same size.

Uses 2nd order polynomial interpolation before the actual integral is calculated.

The lower limit for integration is x[0] while the pints in x define the upper limits. This means that the first point of the result (the one corresponding to x[0]) is 0.

pyopus.evaluator.measure.DCgain(output, input)

Returns the maximal gain (slope) of a nonlinear transfer function output(input).

output and input are 1-dimensional arrays of the same size.

pyopus.evaluator.measure.DCswingAtGain(output, input, relLevel, type='out')

Returns the input or output interval corresponding to the range where the gain (slope) of output(input) is above relLevel times maximal slope. Only rellevel < 1 makes sense in this measurement.

type specifies what to return

  • out - return the output values interval
  • in - return the input values interval

relLevel must satisfy 0 <= relLevel <= 1.

pyopus.evaluator.measure.ACcircle(unit='deg')

Returns the full circle in units specified by unit

  • deg - return 360
  • rad - return 2*``pi``
pyopus.evaluator.measure.ACtf(output, input)

Return the transfer function output/input where output and input are complex vectors of the same size representing the systems response at various frequencies.

pyopus.evaluator.measure.ACmag(tf, unit='db')

Return the magnitude in desired unit of a small signal tranfer function tf.

  • db and db20 stand for voltage/current gain decibels where 20dB = gain factor of 10.0
  • db10 stands for voltage/current gain decibels where 10dB = gain factor of 10.0
  • abs stands for gain factor
pyopus.evaluator.measure.ACphase(tf, unit='deg', unwrapTol=0.5)

Return the phase in desired unit of a transfer function tf

  • deg stands for degrees
  • rad stands for radians

The phase is unwrapped (discontinuities are stiched together to make it continuous). The tolerance of the unwrapping (in radians) is unwrapTol times pi.

pyopus.evaluator.measure.ACgain(tf, unit='db')

Returns the maximal gain magnitude of a transfer function in units given by unit

  • db and db20 stand for voltage/current gain decibels where 20dB = gain factor of 10.0
  • db10 stands for power gain decibels where 10dB = gain factor of 10.0
  • abs stands for gain factor
pyopus.evaluator.measure.ACbandwidth(tf, scl, filter='lp', levelType='db', level=-3.0)

Return the bandwidth of a transfer function tf on frequency scale scl. tf and scl must be 1-dimensional arrays of the same size.

The type of the transfer function is given by filter where

  • lp stands for low-pass (return frequency at level)
  • hp stands for high-pass (return frequency at level)
  • bp stands for band-pass (return bandwidth at level)

levelType gives the units for the level argument. Allowed values for levelType are

  • db and db20 stand for voltage/current gain decibels where 20dB = gain factor of 10.0
  • db10 stands for power gain decibels where 10dB = gain factor of 10.0
  • abs stands for gain factor

level specifies the level at which the bandwidth should be measured. For db, db10, and db20 levelType the level is relative to the maximal gain and is added to the maximal gain. For abs levelType the level is a factor with which the maximal gain factor must be multiplied to obtain the gain factor level at which the bandwidth should be measured.

pyopus.evaluator.measure.ACugbw(tf, scl)

Returns the uniti-gain bandwidth of a transfer function tf on frequency scale scl. 1-dimensional arrays tf and scl must be of the same size.

The return value is the frequency at which the transfer function reaches 1.0 (0dB).

pyopus.evaluator.measure.ACphaseMargin(tf, unit='deg', unwrapTol=0.5)

Returns the phase margin of a transfer function given by 1-dimensional array tf. Uses unwrapTol as the unwrap tolerance for phase (see ACphase()). The phase margin is returned in units given by unit where

  • deg stands for degrees
  • rad stands for radians

The phase margin (in degrees) is the amount the phase at the point where the transfer function magnitude reaches 0dB should be decreased to become equal to -180.

For stable systems the phase margin is >0.

pyopus.evaluator.measure.ACgainMargin(tf, unit='db', unwrapTol=0.5)

Returns the gain margin of a transfer function given by 1-dimensional array tf. Uses unwrapTol as the unwrap tolerance for phase (see ACphase()). The gain margin is returned in units given by unit where

  • db and db20 stand for voltage/current gain decibels where 20dB = gain factor of 10.0
  • db10 stands for power gain decibels where 10dB = gain factor of 10.0
  • abs stands for gain factor

The phase margin (in voltage/current gain decibels) is the amount the gain at the point where phase reaches -180 degrees should be increased to become equal to 0.

For stable systems the gain margin is >0.

pyopus.evaluator.measure.Tdelay(sig1, sig2, scl, lev1type='rel', lev1=0.5, edge1='any', skip1=0, lev2type='rel', lev2=0.5, edge2='any', skip2=0, t1=None, t2=None)

Calculates the delay of signal sig2 with respect to signal sig1. Both signals share a common scale scl. The delay is the difference in scale between the point where sig2 reaches level lev2. edge2 defines the type of crossing between sig2 and lev2

  • rising - the slope of sig2 is positive or zero at the crossing
  • falling - the slope of sig2 is negative or zero at the crossing
  • any - the slope of sig2 does not matter

skip2 specifies how many crossings since the beginning of sig2 are skipped before the crossing that is used as the point in sig2 is reached. 0 means that the first crossing is used as the point in sig2.

Similarly the point in sig1 is defined with lev1, edge1, and skip1.

t1 and t2 are the points on the scale defining the beginning and the end of the part of sig1 and sig2 which is used in the calculation of the delay. skip1 and skip2 are counted from point t1 on the scale. The default values of t1 and t2 are the first and the last value in scl.

If lev1type is abs lev1 specifies the value of the signal at the crossing. If lev1type is rel lev1 specifies the relative value of the signal (between 0.0 and 1.0) where the 0.0 level is defined as the sig1 level at point t1 on the scale while the 1.0 level is defined as the sig1 level at point t2 on the scale. If t1 and t2 are not given the 0.0 and 1.0 relative levels are taken at the beginning and the end of sig2.

Similarly lev2type defines the meaning of lev2 with respect to sig2, t1, and t2.

pyopus.evaluator.measure.Tshoot(measureType, sig, scl, t1=None, t2=None, outputType='rel')

Gets the overshoot or the undershoot of signal sig with scale scl. The over/undershoot is measured on the scale interval between t1 and t2. If t1 and t2 are not given the whole signal sig1 is used in the measurement.

The 0.0 and 1.0 relative levels in the signal are defined as the values of sig at points t1 and t2 on the scale. The default values of t1 and t2 are the first and the last value in scl.

Overshoot is the amount the signal rises above the 1.0 relative level on the observed scale interval defined by t1 and t2. Undershoot is the amount the signal falls below the 0.0 relative level on the observed scale interval.

If measureType is set to over, overshoot is measured and the function expects the signal level at t1 to be lower than the signal level at t2. If measureType is under the opposite must hold.

Over/undershoot can be measured as relative (when outputType is rel) or absolute (when outputType is abs). Abolute values reflect actual signal values while relative values are measured with respect to the 0.0 and 1.0 relative signal level.

pyopus.evaluator.measure.Tovershoot(sig, scl, t1=None, t2=None, outputType='rel')

An alias for Tshoot() with measureType set to over.

pyopus.evaluator.measure.Tundershoot(sig, scl, t1=None, t2=None, outputType='rel')

An alias for Tshoot() with measureType set to under.

pyopus.evaluator.measure.TedgeTime(edgeType, sig, scl, lev1type='rel', lev1=0.1, lev2type='rel', lev2=0.9, t1=None, t2=None)

Measures rise or fall time (scale interval) of signal sig on scale scl. The value of the edgeType parameter determines the type of the measurement

  • rising - measures rise time
  • falling - measures fall time

t1 and t2 specify the scale interval on which the measurement takes place. Their default values correspond to the first and the last value in scl. The values of the signal at *t1 and t2 define the 0.0 and the 1.0 relative signal value.

lev1type and lev specify the point at which the signal rise/fall begins. If lev1type is abs the level specified by lev1 is the actual signal value. If lev1type is rel the value given by lev1 is a relative signal value.

Similarly lev2type and lev2 apply to the point at which the signal rise/fall ends.

lev1type, lev1, lev2type, and lev2 are by default set to measure the 10%..90% rise/fall time.

pyopus.evaluator.measure.TriseTime(sig, scl, lev1type='rel', lev1=0.1, lev2type='rel', lev2=0.9, t1=None, t2=None)

An alias for TedgeTime() with edgeType set to rising.

pyopus.evaluator.measure.TfallTime(sig, scl, lev1type='rel', lev1=0.1, lev2type='rel', lev2=0.9, t1=None, t2=None)

An alias for TedgeTime() with edgeType set to falling.

pyopus.evaluator.measure.TslewRate(edgeType, sig, scl, lev1type='rel', lev1=0.1, lev2type='rel', lev2=0.9, t1=None, t2=None)

Measures the slew rate of a signal. The slew rate is defined as the quotient dx/dt where dx denotes the signal difference between the beginning and the end of signal’s rise/fall, while dt denotes the rise/fall time. Slew rate is always positive.

See TedgeTime() for the explanation of the function’s parameters.

pyopus.evaluator.measure.TsettlingTime(sig, scl, tolType='rel', tol=0.05, t1=None, t2=None)

Measures the time (scale interval on scale scl) in which signal sig settles within some prescribed tolerance of its final value.

t1 and t2 define the scale interval within which the settling time is measured. The default values of t1 and t2 are the first and the last value of scl. The final signal value if the value of the signal corresponding to point t2 on the scale.

The 0.0 and the 1.0 relative signal levels are defined as signal levels at points t1 and t2 on the scale.

If tolType is abs the settling time is measured from t1 to the point at which the signal remains within tol of its final value at t2.

If tolType is rel the settling tolerance is defined as tol times the difference between the signal levels corresponding to the 0.0 and 1.0 relative signal level.

class pyopus.evaluator.measure.Poverdrive(driver1, p1, driver2, p2)

Calculates the difference between the values obtained from two driver functions.

Objects of this class are callable. The calling convention is object(name). When called it returns the difference between the values returned by a call to driver1 with arguments (name, p1) and the value returned by a call to driver2 with arguments (name, p2). The difference is returned as an array. If the size of the array is 1, it is returned as a scalar (0-dimensional array).

Poverdrive can be used for calculating the Vgs-Vth difference of one or more MOS transistors by defining the measurement script in the following way:

obj=m.Poverdrive(p, 'vgs', p, 'vth')
retval=list(map(obj, ['mn2', 'mn3', 'mn9']))
__result=np.array(retval)

The map() Python builtin function calls the Poverdrive object obj 3 times, once for every member of the list ['mn2', 'mn3', 'mn9'] and collects the return values in a list which is then returned by map and stored in retval.

A call to Poverdrive object obj with argument mn2 returns the result of:

p('mn2', 'vgs')-p('mn2', 'vth')

which is actually the difference between the Vgs and the threshold voltage of MOS transistor mn1. So retval is a list holding the values of the difference between Vgs and the threshold voltage of transistors listed in ['mn2', 'mn3', 'mn9'].

Finally the list is converted to an array because the PerformanceEvaluator object can’s handle lists.

The previous measurement script could also be written as a measurement expression:

np.array(list(map(m.Poverdrive(p, 'vgs', p, 'vth'), ['mn2', 'mn3', 'mn9'])))

Note that during measurement evaluation (when a PerformanceEvaluator object is called) the function p() accesses device properties calculated by the simulator while the pyopus.evaluator.measure and numpy modules are available as m and np.