more comments
This commit is contained in:
parent
72a5e9754d
commit
0aaab1697d
|
|
@ -1,3 +1,8 @@
|
|||
2009-08-08 Holger Vogt
|
||||
* measure.c: add more comments
|
||||
* example/func_cap.sp, inverter.sp, inverter2.sp: hint to
|
||||
start examples only in interactive mode.
|
||||
|
||||
2009-08-05 Holger Vogt
|
||||
* measure.c: add comments (not yet complete)
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Entry point is function do_measure(), called by fcn dosim()
|
||||
from runcoms.c:335, after simulation is finished.
|
||||
|
||||
$Id&
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -19,11 +19,13 @@
|
|||
void winmessage(char* new_msg);
|
||||
#endif
|
||||
|
||||
static bool measure_valid[20000];
|
||||
static bool just_chk_meas;
|
||||
static bool measures_passed;
|
||||
static bool measure_valid[20000];/* TRUE: if measurement no. [xxx] has been done successfully
|
||||
(not used anywhere)*/
|
||||
static bool just_chk_meas; /* TRUE: only check if measurement can be done successfully,
|
||||
no output generated (if option autostop is set)*/
|
||||
static bool measures_passed; /* TRUE: stop simulation (if option autostop is set)*/
|
||||
|
||||
/** return precision (either 5 or environment variable NGSPICE_MEAS_PRECISION) */
|
||||
/** return precision (either 5 or value of environment variable NGSPICE_MEAS_PRECISION) */
|
||||
static int
|
||||
get_measure_precision()
|
||||
{
|
||||
|
|
@ -37,8 +39,17 @@ get_measure_precision()
|
|||
return precision;
|
||||
}
|
||||
|
||||
/* returns interpolated time point (char x_or_y='x') or interpolated data value */
|
||||
static double
|
||||
interpolate( struct dvec *time, struct dvec *values, int i, int j, double var_value, char x_or_y ) {
|
||||
interpolate(
|
||||
struct dvec *time, /*in: vector of time points */
|
||||
struct dvec *values, /*in: vector of corresponding data points */
|
||||
int i, /*in: index to first time/data couple */
|
||||
int j, /*in: index to second time/data couple, i nad j setting the interval */
|
||||
double var_value, /*in: either time or data value */
|
||||
char x_or_y /*in: set to 'x': requires var_value to be data point, returns time;
|
||||
otherwise expects var_value to be time, returns data value */
|
||||
) {
|
||||
double slope = (values->v_realdata[j] - values->v_realdata[i])/(time->v_realdata[j] - time->v_realdata[i]);
|
||||
double yint = values->v_realdata[i] - slope*time->v_realdata[i];
|
||||
double result;
|
||||
|
|
@ -49,22 +60,36 @@ interpolate( struct dvec *time, struct dvec *values, int i, int j, double var_va
|
|||
return result;
|
||||
}
|
||||
|
||||
/* Takes a data value and returns corresponding time, but only after the number of
|
||||
data crossings given by e.g. 'rise=3' have passed. */
|
||||
static double
|
||||
get_volt_time( struct dvec *time, struct dvec *values, double value, char polarity, int mindex, bool *failed )
|
||||
{
|
||||
get_volt_time(
|
||||
struct dvec *time, /*in: vector of time points */
|
||||
struct dvec *values, /*in: vector of corresponding data points */
|
||||
double value, /*in: data value, for which time is sought */
|
||||
char polarity, /*in: 'r' (rise) or 'f' (fall) */
|
||||
int mindex, /*in: no. of times the data sequence has to cross 'value', before measurement commences */
|
||||
bool *failed /*out: TRUE if syntax error or time point not found */
|
||||
) {
|
||||
int i = 0, count = 0;
|
||||
double comp_time = 0;
|
||||
|
||||
for ( i = 0; i < values->v_length-1; i++ ) {
|
||||
if ( polarity == 'r' ) {
|
||||
if ( values->v_realdata[i] < value && value <= values->v_realdata[i+1] ) {
|
||||
count++;
|
||||
/* increase 'count' if rising slope data cross 'value' */
|
||||
count++;
|
||||
/* return interpolated time value only after the data sequence has crossed
|
||||
'value' mindex times*/
|
||||
if ( count == mindex ) comp_time = interpolate( time, values, i, i+1, value, 'x' );
|
||||
}
|
||||
}
|
||||
else if ( polarity == 'f' ) {
|
||||
if ( values->v_realdata[i] >= value && value > values->v_realdata[i+1] ) {
|
||||
count++;
|
||||
/* increase 'count' if falling slope data cross 'value' */
|
||||
count++;
|
||||
/* return interpolated time value only after the data sequence has crossed
|
||||
'value' mindex times*/
|
||||
if ( count == mindex ) comp_time = interpolate( time, values, i, i+1, value, 'x' );
|
||||
}
|
||||
}
|
||||
|
|
@ -84,7 +109,7 @@ get_volt_time( struct dvec *time, struct dvec *values, double value, char polari
|
|||
static bool
|
||||
measure(
|
||||
char *trig_name, /*in: name (e.g. in) of vector (e.g. v(in)) following trig parameter */
|
||||
double trig_value, /*in: i or v level following trig parameter */
|
||||
double trig_value, /*in: i or v value following trig parameter */
|
||||
char trig_polarity, /*in: r for rising slope, f for falling slope */
|
||||
int trig_index, /*in: time is measured only after this number of rising (
|
||||
falling) slopes with trigvalue has been detected*/
|
||||
|
|
@ -113,14 +138,26 @@ measure(
|
|||
return failed;
|
||||
}
|
||||
|
||||
/*
|
||||
/*Do any other measurements:
|
||||
avg: (average) calculates the area under the out_var divided by the periods of interest
|
||||
rms: (root mean squared) calculates the square root of the area under the out_var^2 curve
|
||||
divided by the period of interest
|
||||
integral: calculate the integral
|
||||
integ(ral): calculate the integral in period of interest
|
||||
min|max: find min or max value in period of interest
|
||||
when: get time when an vetor reaches a value.
|
||||
Called by fcn do_other_measurement().
|
||||
Returns FALSE if successful.
|
||||
*/
|
||||
static bool
|
||||
measure2( char *meas_type, char *vec_name, char vec_type, double from, double to, double *result, double *result_time ) {
|
||||
measure2(
|
||||
char *meas_type, /* one of avg|rms|integ(ral)|min|max|when*/
|
||||
char *vec_name, /*in: name (e.g. 'v0') of vector (e.g. i(v0) )*/
|
||||
char vec_type, /*in: type (e.g. 'i') of vector (e.g. i(v0) ), may be 'v' or 'i'*/
|
||||
double from, /*in: start value (e.g. of time) defining region of interest */
|
||||
double to, /*in: stop value */
|
||||
double *result, /*out: measurement result */
|
||||
double *result_time /*out: time value where *result occurs (not valid for avg, rms, integ) */
|
||||
) {
|
||||
struct dvec *time = vec_get("time");
|
||||
struct dvec *vec;
|
||||
int xy_size = 0;
|
||||
|
|
@ -214,6 +251,7 @@ measure2( char *meas_type, char *vec_name, char vec_type, double from, double to
|
|||
}
|
||||
else if ( strcmp( meas_type, "when" ) == 0 ){
|
||||
init_val = vec->v_realdata[0] ;
|
||||
/* 'from' is used as input value */
|
||||
if ( AlmostEqualUlps( init_val, from, 100 ) ){
|
||||
/* match right out of the gate. */
|
||||
*result = vec->v_realdata[0];
|
||||
|
|
@ -266,8 +304,15 @@ chkAnalysisType( char *an_type ) {
|
|||
else return TRUE;
|
||||
}
|
||||
|
||||
/* Gets pointer to integer value after 'xxx=' and advances pointer of *line.
|
||||
On error returns FALSE. */
|
||||
static bool
|
||||
get_int_value( char **line, char *name, int *value ) {
|
||||
get_int_value(
|
||||
char **line, /*in|out: pointer to line to be parsed */
|
||||
char *name, /*in: xxx e.g. 'fall' from example 'fall=2' */
|
||||
int *value /*out: return value (e.g. 2 from 'fall=2' */
|
||||
) {
|
||||
/*get token (e.g. 'fall=1' and advance pointer*/
|
||||
char *token = gettok(line);
|
||||
bool return_val = TRUE;
|
||||
char *equal_ptr;
|
||||
|
|
@ -295,12 +340,19 @@ get_int_value( char **line, char *name, int *value ) {
|
|||
return return_val;
|
||||
}
|
||||
|
||||
|
||||
/* Gets pointer to double value after 'xxx=' and advances pointer of *line.
|
||||
On error returns FALSE. */
|
||||
static bool
|
||||
get_double_value( char **line, char *name, double *value ) {
|
||||
get_double_value(
|
||||
char **line, /*in|out: pointer to line to be parsed */
|
||||
char *name, /*in: xxx e.g. 'val' from 'val=0.5' */
|
||||
double *value /*out: return value (e.g. 0.5) from 'val=0.5'*/
|
||||
) {
|
||||
char *token = gettok(line);
|
||||
bool return_val = TRUE;
|
||||
char *equal_ptr, *junk;
|
||||
int err;
|
||||
int err=0;
|
||||
|
||||
if ( name && ( strncmp( token, name, strlen(name) ) != 0 ) ) {
|
||||
if ( just_chk_meas != TRUE ) fprintf( cp_err, "Error: syntax error for measure statement; expecting next field to be '%s'.\n", name );
|
||||
|
|
@ -391,8 +443,10 @@ do_delay_measurement(
|
|||
char *out_line, /*out: output for printing */
|
||||
char *line, /*in: .meas card, first four parameters stripped */
|
||||
char *o_line, /*in: .meas card, complete */
|
||||
int meas_index, /*in: number of measurements */
|
||||
int meas_index, /*in: number of actual measurement */
|
||||
double *result /*out: delay value returned by measure() */
|
||||
/*global variable measures_passed
|
||||
out: set to FALSE if measurement failed (used with autostop)*/
|
||||
) {
|
||||
char *trig_name, *targ_name, *token;
|
||||
char trig_type, targ_type, trig_polarity, targ_polarity;
|
||||
|
|
@ -565,8 +619,8 @@ void
|
|||
do_measure(
|
||||
char *what, /*in: analysis type*/
|
||||
bool chk_only /*in: TRUE if checking for "autostop", FALSE otherwise*/
|
||||
/*global variable measure_type
|
||||
out: */
|
||||
/*global variable measures_passed
|
||||
out: set to FALSE if .meas syntax is violated (used with autostop)*/
|
||||
) {
|
||||
struct line *meas_card, *meas_results = NULL, *end = NULL, *newcard;
|
||||
char *line, *an_name, *an_type, *resname, *meastype, *str_ptr, out_line[1000];
|
||||
|
|
@ -743,9 +797,11 @@ do_measure(
|
|||
}
|
||||
|
||||
|
||||
/* called from dctran.c:470, if TRUE is returned, transient simulation is stopped.
|
||||
/* called from dctran.c:470, if timepoint is accepted.
|
||||
Returns TRUE if measurement (just a check, no output) has been successful.
|
||||
If TRUE is returned, transient simulation is stopped.
|
||||
Returns TRUE if "autostop" has been set as an option and if measures_passed not
|
||||
set to FALSE during calling do_measure. what is set to "tran".*/
|
||||
set to FALSE during calling do_measure. 'what' is set to "tran".*/
|
||||
|
||||
bool
|
||||
check_autostop( char* what ) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue