update FIND ... WHEN measurements
This commit is contained in:
parent
7880d5bd8e
commit
ebda0af288
|
|
@ -1,3 +1,7 @@
|
||||||
|
2011-02-19 Holger Vogt
|
||||||
|
* ngspice.h: _snprintf for MS Visual Studio
|
||||||
|
* measure.c, com_measure.c: update FIND .. WHEN measurements
|
||||||
|
|
||||||
2011-02-19 Robert Larice
|
2011-02-19 Robert Larice
|
||||||
* configure.ac ,
|
* configure.ac ,
|
||||||
* examples/transient-noise/shot_ng.cir ,
|
* examples/transient-noise/shot_ng.cir ,
|
||||||
|
|
|
||||||
|
|
@ -373,15 +373,20 @@ static void com_measure_when(
|
||||||
int measurement_pending;
|
int measurement_pending;
|
||||||
int init_measured_value;
|
int init_measured_value;
|
||||||
bool ac_check = FALSE, sp_check = FALSE, dc_check = FALSE, tran_check = FALSE ;
|
bool ac_check = FALSE, sp_check = FALSE, dc_check = FALSE, tran_check = FALSE ;
|
||||||
double value, prevValue;
|
bool has_d2 = FALSE;
|
||||||
|
double value, prevValue, value2, prevValue2;
|
||||||
double scaleValue, prevScaleValue;
|
double scaleValue, prevScaleValue;
|
||||||
|
|
||||||
enum ValSide { S_ABOVE_VAL, S_BELOW_VAL };
|
enum ValSide { S_ABOVE_VAL, S_BELOW_VAL };
|
||||||
enum ValEdge { E_RISING, E_FALLING };
|
enum ValEdge { E_RISING, E_FALLING };
|
||||||
|
|
||||||
struct dvec *d, *dScale;
|
struct dvec *d, *d2, *dScale;
|
||||||
|
|
||||||
d = vec_get(meas->m_vec);
|
d = vec_get(meas->m_vec);
|
||||||
|
if (meas->m_vec2) {
|
||||||
|
d2 = vec_get(meas->m_vec2);
|
||||||
|
has_d2 = TRUE;
|
||||||
|
}
|
||||||
dScale = plot_cur->pl_scale;
|
dScale = plot_cur->pl_scale;
|
||||||
|
|
||||||
if (d == NULL) {
|
if (d == NULL) {
|
||||||
|
|
@ -389,13 +394,18 @@ static void com_measure_when(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((has_d2) && (d == NULL)) {
|
||||||
|
fprintf(cp_err, "Error: no such vector as %s.\n", meas->m_vec2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (dScale == NULL) {
|
if (dScale == NULL) {
|
||||||
fprintf(cp_err, "Error: no scale vector.\n");
|
fprintf(cp_err, "Error: no scale vector.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
prevValue =0;
|
prevValue =0.;
|
||||||
prevScaleValue =0;
|
prevValue2 =0.;
|
||||||
|
prevScaleValue =0.;
|
||||||
first =0;
|
first =0;
|
||||||
measurement_pending=0;
|
measurement_pending=0;
|
||||||
init_measured_value=1;
|
init_measured_value=1;
|
||||||
|
|
@ -415,9 +425,6 @@ static void com_measure_when(
|
||||||
|
|
||||||
for (i=0; i < d->v_length; i++) {
|
for (i=0; i < d->v_length; i++) {
|
||||||
|
|
||||||
// value = d->v_realdata[i];
|
|
||||||
// scaleValue = dTime->v_realdata[i];
|
|
||||||
|
|
||||||
if (ac_check) {
|
if (ac_check) {
|
||||||
if (d->v_compdata)
|
if (d->v_compdata)
|
||||||
value = get_value(meas, d, i); //d->v_compdata[i].cx_real;
|
value = get_value(meas, d, i); //d->v_compdata[i].cx_real;
|
||||||
|
|
@ -436,6 +443,24 @@ static void com_measure_when(
|
||||||
value = d->v_realdata[i];
|
value = d->v_realdata[i];
|
||||||
scaleValue = dScale->v_realdata[i];
|
scaleValue = dScale->v_realdata[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (has_d2) {
|
||||||
|
if (ac_check) {
|
||||||
|
if (d2->v_compdata)
|
||||||
|
value2 = get_value(meas, d2, i); //d->v_compdata[i].cx_real;
|
||||||
|
else
|
||||||
|
value2 = d2->v_realdata[i];
|
||||||
|
}
|
||||||
|
else if (sp_check) {
|
||||||
|
if (d2->v_compdata)
|
||||||
|
value2 = get_value(meas, d2, i); //d->v_compdata[i].cx_real;
|
||||||
|
else
|
||||||
|
value2 = d2->v_realdata[i];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
value2 = d2->v_realdata[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
/* 'dc' is special: it may start at an arbitrary scale value.
|
/* 'dc' is special: it may start at an arbitrary scale value.
|
||||||
Use m_td to store this value, a delay TD does not make sense */
|
Use m_td to store this value, a delay TD does not make sense */
|
||||||
if ((dc_check) && (i==0))
|
if ((dc_check) && (i==0))
|
||||||
|
|
@ -451,70 +476,136 @@ static void com_measure_when(
|
||||||
if ((first > 1) && (dc_check && (meas->m_td == scaleValue)))
|
if ((first > 1) && (dc_check && (meas->m_td == scaleValue)))
|
||||||
first = 1;
|
first = 1;
|
||||||
|
|
||||||
if (first == 1) {
|
if (first == 1)
|
||||||
// initialise
|
if (has_d2) {
|
||||||
crossCnt =0;
|
// initialise
|
||||||
if (value < meas->m_val) {
|
crossCnt =0;
|
||||||
section = S_BELOW_VAL;
|
if (value < value2) {
|
||||||
if ( (prevValue <= meas->m_val) && (value >= meas->m_val) ) {
|
section = S_BELOW_VAL;
|
||||||
fallCnt =1;
|
if ( (prevValue <= value2) && (value >= value2) ) {
|
||||||
crossCnt =1;
|
fallCnt =1;
|
||||||
}
|
crossCnt =1;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
section = S_ABOVE_VAL;
|
section = S_ABOVE_VAL;
|
||||||
if ( (prevValue <= meas->m_val) && (value >= meas->m_val) ) {
|
if ( (prevValue <= value2) && (value >= value2) ) {
|
||||||
riseCnt =1;
|
riseCnt =1;
|
||||||
crossCnt =1;
|
crossCnt =1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fflush( stdout ) ;
|
fflush( stdout ) ;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// initialise
|
||||||
|
crossCnt =0;
|
||||||
|
if (value < meas->m_val) {
|
||||||
|
section = S_BELOW_VAL;
|
||||||
|
if ( (prevValue <= meas->m_val) && (value >= meas->m_val) ) {
|
||||||
|
fallCnt =1;
|
||||||
|
crossCnt =1;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
section = S_ABOVE_VAL;
|
||||||
|
if ( (prevValue <= meas->m_val) && (value >= meas->m_val) ) {
|
||||||
|
riseCnt =1;
|
||||||
|
crossCnt =1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fflush( stdout ) ;
|
||||||
|
}
|
||||||
|
|
||||||
if (first > 1) {
|
if (first > 1) {
|
||||||
if ( (section == S_BELOW_VAL) && (value >= meas->m_val) ) {
|
if (has_d2) {
|
||||||
section = S_ABOVE_VAL;
|
if ( (section == S_BELOW_VAL) && (value >= value2) ) {
|
||||||
crossCnt++;
|
section = S_ABOVE_VAL;
|
||||||
riseCnt++;
|
crossCnt++;
|
||||||
if( meas->m_fall != MEASURE_LAST_TRANSITION ){
|
riseCnt++;
|
||||||
/* we can measure rise/cross transition if the user
|
if( meas->m_fall != MEASURE_LAST_TRANSITION ){
|
||||||
* has not requested a last fall transition */
|
/* we can measure rise/cross transition if the user
|
||||||
measurement_pending=1;
|
* has not requested a last fall transition */
|
||||||
}
|
measurement_pending=1;
|
||||||
|
}
|
||||||
|
|
||||||
} else if ( (section == S_ABOVE_VAL) && (value <= meas->m_val) ) {
|
} else if ( (section == S_ABOVE_VAL) && (value <= value2) ) {
|
||||||
section = S_BELOW_VAL;
|
section = S_BELOW_VAL;
|
||||||
crossCnt++;
|
crossCnt++;
|
||||||
fallCnt++;
|
fallCnt++;
|
||||||
if( meas->m_rise != MEASURE_LAST_TRANSITION ){
|
if( meas->m_rise != MEASURE_LAST_TRANSITION ){
|
||||||
/* we can measure fall/cross transition if the user
|
/* we can measure fall/cross transition if the user
|
||||||
* has not requested a last rise transition */
|
* has not requested a last rise transition */
|
||||||
measurement_pending=1;
|
measurement_pending=1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((crossCnt == meas->m_cross) || (riseCnt == meas->m_rise) || (fallCnt == meas->m_fall)) {
|
if ((crossCnt == meas->m_cross) || (riseCnt == meas->m_rise) || (fallCnt == meas->m_fall)) {
|
||||||
/* user requested an exact match of cross, rise, or fall
|
/* user requested an exact match of cross, rise, or fall
|
||||||
* exit when we meet condition */
|
* exit when we meet condition */
|
||||||
meas->m_measured = prevScaleValue + (meas->m_val - prevValue) * (scaleValue - prevScaleValue) / (value - prevValue);
|
// meas->m_measured = prevScaleValue + (value2 - prevValue) * (scaleValue - prevScaleValue) / (value - prevValue);
|
||||||
return;
|
meas->m_measured = prevScaleValue + (prevValue2 - prevValue) * (scaleValue - prevScaleValue) / (value - prevValue - value2 + prevValue2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( measurement_pending ){
|
||||||
|
if( (meas->m_cross == MEASURE_DEFAULT) && (meas->m_rise == MEASURE_DEFAULT) && (meas->m_fall == MEASURE_DEFAULT) ){
|
||||||
|
/* user didn't request any option, return the first possible case */
|
||||||
|
meas->m_measured = prevScaleValue + (prevValue2 - prevValue) * (scaleValue - prevScaleValue) / (value - prevValue - value2 + prevValue2);
|
||||||
|
return;
|
||||||
|
} else if( (meas->m_cross == MEASURE_LAST_TRANSITION) || (meas->m_rise == MEASURE_LAST_TRANSITION) || (meas->m_fall == MEASURE_LAST_TRANSITION) ){
|
||||||
|
meas->m_measured = prevScaleValue + (prevValue2 - prevValue) * (scaleValue - prevScaleValue) / (value - prevValue - value2 + prevValue2);
|
||||||
|
/* no return - look for last */
|
||||||
|
init_measured_value=0;
|
||||||
|
}
|
||||||
|
measurement_pending=0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ( measurement_pending ){
|
else {
|
||||||
if( (meas->m_cross == MEASURE_DEFAULT) && (meas->m_rise == MEASURE_DEFAULT) && (meas->m_fall == MEASURE_DEFAULT) ){
|
if ( (section == S_BELOW_VAL) && (value >= meas->m_val) ) {
|
||||||
/* user didn't request any option, return the first possible case */
|
section = S_ABOVE_VAL;
|
||||||
meas->m_measured = prevScaleValue + (meas->m_val - prevValue) * (scaleValue - prevScaleValue) / (value - prevValue);
|
crossCnt++;
|
||||||
return;
|
riseCnt++;
|
||||||
} else if( (meas->m_cross == MEASURE_LAST_TRANSITION) || (meas->m_rise == MEASURE_LAST_TRANSITION) || (meas->m_fall == MEASURE_LAST_TRANSITION) ){
|
if( meas->m_fall != MEASURE_LAST_TRANSITION ){
|
||||||
meas->m_measured = prevScaleValue + (meas->m_val - prevValue) * (scaleValue - prevScaleValue) / (value - prevValue);
|
/* we can measure rise/cross transition if the user
|
||||||
/* no return - look for last */
|
* has not requested a last fall transition */
|
||||||
init_measured_value=0;
|
measurement_pending=1;
|
||||||
}
|
}
|
||||||
measurement_pending=0;
|
|
||||||
|
} else if ( (section == S_ABOVE_VAL) && (value <= meas->m_val) ) {
|
||||||
|
section = S_BELOW_VAL;
|
||||||
|
crossCnt++;
|
||||||
|
fallCnt++;
|
||||||
|
if( meas->m_rise != MEASURE_LAST_TRANSITION ){
|
||||||
|
/* we can measure fall/cross transition if the user
|
||||||
|
* has not requested a last rise transition */
|
||||||
|
measurement_pending=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((crossCnt == meas->m_cross) || (riseCnt == meas->m_rise) || (fallCnt == meas->m_fall)) {
|
||||||
|
/* user requested an exact match of cross, rise, or fall
|
||||||
|
* exit when we meet condition */
|
||||||
|
meas->m_measured = prevScaleValue + (meas->m_val - prevValue) * (scaleValue - prevScaleValue) / (value - prevValue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( measurement_pending ){
|
||||||
|
if( (meas->m_cross == MEASURE_DEFAULT) && (meas->m_rise == MEASURE_DEFAULT) && (meas->m_fall == MEASURE_DEFAULT) ){
|
||||||
|
/* user didn't request any option, return the first possible case */
|
||||||
|
meas->m_measured = prevScaleValue + (meas->m_val - prevValue) * (scaleValue - prevScaleValue) / (value - prevValue);
|
||||||
|
return;
|
||||||
|
} else if( (meas->m_cross == MEASURE_LAST_TRANSITION) || (meas->m_rise == MEASURE_LAST_TRANSITION) || (meas->m_fall == MEASURE_LAST_TRANSITION) ){
|
||||||
|
meas->m_measured = prevScaleValue + (meas->m_val - prevValue) * (scaleValue - prevScaleValue) / (value - prevValue);
|
||||||
|
/* no return - look for last */
|
||||||
|
init_measured_value=0;
|
||||||
|
}
|
||||||
|
measurement_pending=0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
first ++;
|
first ++;
|
||||||
|
|
||||||
prevValue = value;
|
prevValue = value;
|
||||||
|
if (has_d2)
|
||||||
|
prevValue2 = value2;
|
||||||
prevScaleValue = scaleValue;
|
prevScaleValue = scaleValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1346,7 +1437,7 @@ get_measure2(
|
||||||
|
|
||||||
if (!ciprefix("tran", plot_cur->pl_typename) && !ciprefix("ac", plot_cur->pl_typename) &&
|
if (!ciprefix("tran", plot_cur->pl_typename) && !ciprefix("ac", plot_cur->pl_typename) &&
|
||||||
!ciprefix("dc", plot_cur->pl_typename) && !ciprefix("sp", plot_cur->pl_typename)) {
|
!ciprefix("dc", plot_cur->pl_typename) && !ciprefix("sp", plot_cur->pl_typename)) {
|
||||||
fprintf(cp_err, "Error: measure limited to tran, dc or ac analysis\n");
|
fprintf(cp_err, "Error: measure limited to tran, dc, sp, or ac analysis\n");
|
||||||
return MEASUREMENT_FAILURE;
|
return MEASUREMENT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1529,7 +1620,7 @@ get_measure2(
|
||||||
}
|
}
|
||||||
|
|
||||||
measure_at(meas, measFind->m_measured);
|
measure_at(meas, measFind->m_measured);
|
||||||
meas->m_measured = measFind->m_measured;
|
meas->m_at = measFind->m_measured;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
measure_at(meas, meas->m_at);
|
measure_at(meas, meas->m_at);
|
||||||
|
|
|
||||||
|
|
@ -44,21 +44,27 @@ extern bool rflag;
|
||||||
void
|
void
|
||||||
com_meas(wordlist *wl) {
|
com_meas(wordlist *wl) {
|
||||||
/* wl: in, input line of meas command */
|
/* wl: in, input line of meas command */
|
||||||
char *line_in, *outvar, newvec[1000], *vec_found, *token, *equal_ptr, newval[256];
|
char *line_in, *outvar, newvec[1000];
|
||||||
wordlist * wl_count, *wl_let, *wl_index;
|
wordlist * wl_count, *wl_let;
|
||||||
int fail, err=0;
|
#ifdef not
|
||||||
double result = 0;
|
char *vec_found, *token, *equal_ptr, newval[256];
|
||||||
|
wordlist *wl_index;
|
||||||
struct dvec *d;
|
struct dvec *d;
|
||||||
|
int err=0;
|
||||||
|
#endif
|
||||||
|
int fail;
|
||||||
|
double result = 0;
|
||||||
|
|
||||||
if (!wl) {
|
if (!wl) {
|
||||||
com_display(NULL);
|
com_display(NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
wl_count = wl;
|
wl_count = wl;
|
||||||
|
#ifdef not
|
||||||
/* check each wl entry, if it contain '=' and if the following token is
|
/* check each wl entry, if it contain '=' and if the following token is
|
||||||
a vector. If yes, replace this vector by its value */
|
a vector. If yes, replace this vector by its value */
|
||||||
wl_index = wl;
|
wl_index = wl;
|
||||||
|
|
||||||
while ( wl_index) {
|
while ( wl_index) {
|
||||||
token = wl_index->wl_word;
|
token = wl_index->wl_word;
|
||||||
/* find the vector vec_found, next token after each '=' sign.
|
/* find the vector vec_found, next token after each '=' sign.
|
||||||
|
|
@ -103,7 +109,7 @@ com_meas(wordlist *wl) {
|
||||||
}
|
}
|
||||||
wl_index = wl_index->wl_next;
|
wl_index = wl_index->wl_next;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
line_in = wl_flatten(wl);
|
line_in = wl_flatten(wl);
|
||||||
|
|
||||||
/* get output var name */
|
/* get output var name */
|
||||||
|
|
|
||||||
|
|
@ -171,6 +171,7 @@
|
||||||
#define open _open
|
#define open _open
|
||||||
#define write _write
|
#define write _write
|
||||||
#define strcasecmp _stricmp
|
#define strcasecmp _stricmp
|
||||||
|
#define snprintf _snprintf
|
||||||
#define inline __inline
|
#define inline __inline
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue