From 0aaab1697db9e3ae2c105d7668fd32e71be28daa Mon Sep 17 00:00:00 2001 From: h_vogt Date: Sat, 8 Aug 2009 13:48:06 +0000 Subject: [PATCH] more comments --- ChangeLog | 5 +++ src/frontend/measure.c | 100 ++++++++++++++++++++++++++++++++--------- 2 files changed, 83 insertions(+), 22 deletions(-) diff --git a/ChangeLog b/ChangeLog index af3f55a04..0fc2dfcc1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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) diff --git a/src/frontend/measure.c b/src/frontend/measure.c index b01652ffe..285472472 100644 --- a/src/frontend/measure.c +++ b/src/frontend/measure.c @@ -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 ) {