more comments

This commit is contained in:
h_vogt 2009-08-08 13:48:06 +00:00
parent 72a5e9754d
commit 0aaab1697d
2 changed files with 83 additions and 22 deletions

View File

@ -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)

View File

@ -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 ) {