graph axes in engineering notation (20u, 10p, 3k), fix an issue in graph panning with button1 mouse; ngspice:: get_current, get_voltage, get_diff_voltage, get_node embedded into xschem.tcl, to_eng tcl procedure to convert number to engineering form.
This commit is contained in:
parent
9d9a4826fc
commit
ae4b74f2d8
|
|
@ -314,7 +314,6 @@ static void backannotate_at_cursor_b_pos(xRect *r, Graph_ctx *gr)
|
||||||
static int waves_callback(int event, int mx, int my, KeySym key, int button, int aux, int state)
|
static int waves_callback(int event, int mx, int my, KeySym key, int button, int aux, int state)
|
||||||
{
|
{
|
||||||
Graph_ctx *gr;
|
Graph_ctx *gr;
|
||||||
const char *val;
|
|
||||||
int i, redraw_all_at_end = 0, need_all_redraw = 0, need_redraw = 0, dataset = 0;
|
int i, redraw_all_at_end = 0, need_all_redraw = 0, need_redraw = 0, dataset = 0;
|
||||||
double xx1, xx2, yy1, yy2;
|
double xx1, xx2, yy1, yy2;
|
||||||
double delta_threshold = 0.25;
|
double delta_threshold = 0.25;
|
||||||
|
|
@ -337,6 +336,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
||||||
/* check if this is the master graph (the one containing the mouse pointer) */
|
/* check if this is the master graph (the one containing the mouse pointer) */
|
||||||
/* determine if mouse pointer is below xaxis or left of yaxis in some graph */
|
/* determine if mouse pointer is below xaxis or left of yaxis in some graph */
|
||||||
if( POINTINSIDE(xctx->mousex, xctx->mousey, r->x1, r->y1, r->x2, r->y2)) {
|
if( POINTINSIDE(xctx->mousex, xctx->mousey, r->x1, r->y1, r->x2, r->y2)) {
|
||||||
|
dbg(1, "mouse inside: %d\n", i);
|
||||||
setup_graph_data(i, xctx->graph_flags, 0, gr);
|
setup_graph_data(i, xctx->graph_flags, 0, gr);
|
||||||
|
|
||||||
/* move cursor1 */
|
/* move cursor1 */
|
||||||
|
|
@ -354,6 +354,10 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
||||||
}
|
}
|
||||||
else need_redraw = 1;
|
else need_redraw = 1;
|
||||||
}
|
}
|
||||||
|
gr->master_gx1 = gr->gx1;
|
||||||
|
gr->master_gx2 = gr->gx2;
|
||||||
|
gr->master_gw = gr->gw;
|
||||||
|
gr->master_cx = gr->cx;
|
||||||
if(xctx->ui_state & GRAPHPAN) break; /* After GRAPHPAN only need to check Motion events for cursors */
|
if(xctx->ui_state & GRAPHPAN) break; /* After GRAPHPAN only need to check Motion events for cursors */
|
||||||
if(xctx->mousey_snap < W_Y(gr->gy2)) {
|
if(xctx->mousey_snap < W_Y(gr->gy2)) {
|
||||||
xctx->graph_top = 1;
|
xctx->graph_top = 1;
|
||||||
|
|
@ -437,6 +441,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
||||||
break;
|
break;
|
||||||
} /* if( POINTINSIDE(...) */
|
} /* if( POINTINSIDE(...) */
|
||||||
} /* for(i=0; i < xctx->rects[GRIDLAYER]; i++) */
|
} /* for(i=0; i < xctx->rects[GRIDLAYER]; i++) */
|
||||||
|
dbg(1, "out of 1st loop: i=%d\n", i);
|
||||||
|
|
||||||
/* check if user clicked on a wave label -> draw wave in bold */
|
/* check if user clicked on a wave label -> draw wave in bold */
|
||||||
if(event == ButtonPress && button == Button3 &&
|
if(event == ButtonPress && button == Button3 &&
|
||||||
|
|
@ -454,17 +459,11 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
||||||
!xctx->graph_top /* && !xctx->graph_bottom */
|
!xctx->graph_top /* && !xctx->graph_bottom */
|
||||||
) {
|
) {
|
||||||
xctx->ui_state |= GRAPHPAN;
|
xctx->ui_state |= GRAPHPAN;
|
||||||
|
dbg(1, "save mouse\n");
|
||||||
if(!xctx->graph_left) xctx->mx_double_save = xctx->mousex_snap;
|
if(!xctx->graph_left) xctx->mx_double_save = xctx->mousex_snap;
|
||||||
if(xctx->graph_left) xctx->my_double_save = xctx->mousey_snap;
|
if(xctx->graph_left) xctx->my_double_save = xctx->mousey_snap;
|
||||||
}
|
}
|
||||||
gr->master_gx1 = 0;
|
dbg(1, "graph_master=%d\n", xctx->graph_master);
|
||||||
gr->master_gx2 = 1e-6;
|
|
||||||
val = get_tok_value(xctx->rect[GRIDLAYER][xctx->graph_master].prop_ptr,"x1",0);
|
|
||||||
if(val[0]) gr->master_gx1 = atof_spice(val);
|
|
||||||
val = get_tok_value(xctx->rect[GRIDLAYER][xctx->graph_master].prop_ptr,"x2",0);
|
|
||||||
if(val[0]) gr->master_gx2 = atof_spice(val);
|
|
||||||
if(gr->master_gx1 == gr->master_gx2) gr->master_gx2 += 1e-6;
|
|
||||||
gr->master_gw = gr->master_gx2 - gr->master_gx1;
|
|
||||||
|
|
||||||
/* parameters for absolute positioning by mouse drag in bottom graph area */
|
/* parameters for absolute positioning by mouse drag in bottom graph area */
|
||||||
if( event == MotionNotify && (state & Button1Mask) && xctx->graph_bottom ) {
|
if( event == MotionNotify && (state & Button1Mask) && xctx->graph_bottom ) {
|
||||||
|
|
@ -547,8 +546,8 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
||||||
} else {
|
} else {
|
||||||
tcleval("graph_show_measure stop");
|
tcleval("graph_show_measure stop");
|
||||||
}
|
}
|
||||||
}
|
} /* if(xctx->graph_flags & 64) */
|
||||||
}
|
} /* if(i == xctx->graph_master) */
|
||||||
dbg(1, "%g %g %g %g - %d %d\n", gr->gx1, gr->gy1, gr->gx2, gr->gy2, gr->divx, gr->divy);
|
dbg(1, "%g %g %g %g - %d %d\n", gr->gx1, gr->gy1, gr->gx2, gr->gy2, gr->divx, gr->divy);
|
||||||
if( event == KeyPress || event == ButtonPress || event == MotionNotify ) {
|
if( event == KeyPress || event == ButtonPress || event == MotionNotify ) {
|
||||||
/* move cursor1 */
|
/* move cursor1 */
|
||||||
|
|
@ -597,6 +596,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
||||||
delta_threshold = 0.01;
|
delta_threshold = 0.01;
|
||||||
/* selected or locked or master */
|
/* selected or locked or master */
|
||||||
if( r->sel || !(r->flags & 2) || i == xctx->graph_master) {
|
if( r->sel || !(r->flags & 2) || i == xctx->graph_master) {
|
||||||
|
dbg(1, "moving waves: %d\n", i);
|
||||||
if(fabs(xctx->mx_double_save - xctx->mousex_snap) > fabs(gr->cx * delta) * delta_threshold) {
|
if(fabs(xctx->mx_double_save - xctx->mousex_snap) > fabs(gr->cx * delta) * delta_threshold) {
|
||||||
xx1 = gr->gx1 + (xctx->mx_double_save - xctx->mousex_snap) / gr->cx;
|
xx1 = gr->gx1 + (xctx->mx_double_save - xctx->mousex_snap) / gr->cx;
|
||||||
xx2 = gr->gx2 + (xctx->mx_double_save - xctx->mousex_snap) / gr->cx;
|
xx2 = gr->gx2 + (xctx->mx_double_save - xctx->mousex_snap) / gr->cx;
|
||||||
|
|
@ -1024,10 +1024,12 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
||||||
}
|
}
|
||||||
if(clear_graphpan_at_end) xctx->ui_state &= ~GRAPHPAN;
|
if(clear_graphpan_at_end) xctx->ui_state &= ~GRAPHPAN;
|
||||||
/* update saved mouse position after processing all graphs */
|
/* update saved mouse position after processing all graphs */
|
||||||
if(save_mouse_at_end &&
|
if(save_mouse_at_end) {
|
||||||
fabs(xctx->mx_double_save - xctx->mousex_snap) > fabs(gr->cx * gr->gw) * delta_threshold) {
|
if( fabs(xctx->mx_double_save - xctx->mousex_snap) > fabs(gr->master_cx * gr->master_gw) * delta_threshold) {
|
||||||
xctx->mx_double_save = xctx->mousex_snap;
|
dbg(1, "save mose pos\n");
|
||||||
xctx->my_double_save = xctx->mousey_snap;
|
xctx->mx_double_save = xctx->mousex_snap;
|
||||||
|
xctx->my_double_save = xctx->mousey_snap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
13
src/draw.c
13
src/draw.c
|
|
@ -1978,10 +1978,10 @@ static void draw_graph_grid(Graph_ctx *gr, void *ct)
|
||||||
drawline(GRIDLAYER, ADD, W_X(wx), W_Y(gr->gy1), W_X(wx), W_Y(gr->gy1) + mark_size, 0, ct); /* axis marks */
|
drawline(GRIDLAYER, ADD, W_X(wx), W_Y(gr->gy1), W_X(wx), W_Y(gr->gy1) + mark_size, 0, ct); /* axis marks */
|
||||||
/* X-axis labels */
|
/* X-axis labels */
|
||||||
if(gr->logx)
|
if(gr->logx)
|
||||||
draw_string(3, NOW, dtoa(pow(10, wx) * gr->unitx), 0, 0, 1, 0, W_X(wx), gr->y2 + mark_size + 5 * gr->txtsizex,
|
draw_string(3, NOW, dtoa_eng(pow(10, wx) * gr->unitx), 0, 0, 1, 0, W_X(wx),
|
||||||
gr->txtsizex, gr->txtsizex);
|
gr->y2 + mark_size + 5 * gr->txtsizex, gr->txtsizex, gr->txtsizex);
|
||||||
else
|
else
|
||||||
draw_string(3, NOW, dtoa(wx * gr->unitx), 0, 0, 1, 0, W_X(wx), gr->y2 + mark_size + 5 * gr->txtsizex,
|
draw_string(3, NOW, dtoa_eng(wx * gr->unitx), 0, 0, 1, 0, W_X(wx), gr->y2 + mark_size + 5 * gr->txtsizex,
|
||||||
gr->txtsizex, gr->txtsizex);
|
gr->txtsizex, gr->txtsizex);
|
||||||
}
|
}
|
||||||
/* first and last vertical box delimiters */
|
/* first and last vertical box delimiters */
|
||||||
|
|
@ -2009,10 +2009,10 @@ static void draw_graph_grid(Graph_ctx *gr, void *ct)
|
||||||
drawline(GRIDLAYER, ADD, W_X(gr->gx1) - mark_size, W_Y(wy), W_X(gr->gx1), W_Y(wy), 0, ct); /* axis marks */
|
drawline(GRIDLAYER, ADD, W_X(gr->gx1) - mark_size, W_Y(wy), W_X(gr->gx1), W_Y(wy), 0, ct); /* axis marks */
|
||||||
/* Y-axis labels */
|
/* Y-axis labels */
|
||||||
if(gr->logy)
|
if(gr->logy)
|
||||||
draw_string(3, NOW, dtoa(pow(10, wy) * gr->unity), 0, 1, 0, 1, gr->x1 - mark_size - 5 * gr->txtsizey, W_Y(wy),
|
draw_string(3, NOW, dtoa_eng(pow(10, wy) * gr->unity), 0, 1, 0, 1,
|
||||||
gr->txtsizey, gr->txtsizey);
|
gr->x1 - mark_size - 5 * gr->txtsizey, W_Y(wy), gr->txtsizey, gr->txtsizey);
|
||||||
else
|
else
|
||||||
draw_string(3, NOW, dtoa(wy * gr->unity), 0, 1, 0, 1, gr->x1 - mark_size - 5 * gr->txtsizey, W_Y(wy),
|
draw_string(3, NOW, dtoa_eng(wy * gr->unity), 0, 1, 0, 1, gr->x1 - mark_size - 5 * gr->txtsizey, W_Y(wy),
|
||||||
gr->txtsizey, gr->txtsizey);
|
gr->txtsizey, gr->txtsizey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2036,6 +2036,7 @@ void setup_graph_data(int i, const int flags, int skip, Graph_ctx *gr)
|
||||||
const char *val;
|
const char *val;
|
||||||
xRect *r = &xctx->rect[GRIDLAYER][i];
|
xRect *r = &xctx->rect[GRIDLAYER][i];
|
||||||
|
|
||||||
|
dbg(1, "setup_graph_data: i=%d\n", i);
|
||||||
/* default values */
|
/* default values */
|
||||||
gr->divx = gr->divy = 5;
|
gr->divx = gr->divy = 5;
|
||||||
gr->subdivx = gr->subdivy = 0;
|
gr->subdivx = gr->subdivy = 0;
|
||||||
|
|
|
||||||
|
|
@ -340,6 +340,35 @@ char *dtoa(double i)
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *dtoa_eng(double i)
|
||||||
|
{
|
||||||
|
static char s[70];
|
||||||
|
size_t n;
|
||||||
|
int suffix = 0;
|
||||||
|
double absi = fabs(i);
|
||||||
|
|
||||||
|
if (absi == 0.0) { suffix = 0;}
|
||||||
|
else if(absi >=1e12) { i /= 1e12; suffix = 'T';}
|
||||||
|
else if(absi >=1e9) { i /= 1e9 ; suffix = 'G';}
|
||||||
|
else if(absi >=1e6) { i /= 1e6 ; suffix = 'M';}
|
||||||
|
else if(absi >=1e3) { i /= 1e3 ; suffix = 'k';}
|
||||||
|
else if(absi >=0.1) { suffix = 0;}
|
||||||
|
else if(absi >=1e-3) { i *= 1e3 ; suffix = 'm';}
|
||||||
|
else if(absi >=1e-6) { i *= 1e6 ; suffix = 'u';}
|
||||||
|
else if(absi >=1e-9) { i *= 1e9 ; suffix = 'n';}
|
||||||
|
else if(absi >=1e-12) { i *= 1e12; suffix = 'p';}
|
||||||
|
else if(absi >=1e-15) { i *= 1e15; suffix = 'f';}
|
||||||
|
else { i *= 1e18; suffix = 'a';}
|
||||||
|
if(suffix) {
|
||||||
|
n = my_snprintf(s, S(s), "%.5g%c", i, suffix);
|
||||||
|
} else {
|
||||||
|
n = my_snprintf(s, S(s), "%.5g", i);
|
||||||
|
}
|
||||||
|
if(xctx) xctx->tok_size = n;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
char *dtoa_prec(double i)
|
char *dtoa_prec(double i)
|
||||||
{
|
{
|
||||||
static char s[70];
|
static char s[70];
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,6 @@
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
|
||||||
namespace eval ngspice {
|
|
||||||
# Create a variable inside the namespace
|
|
||||||
variable ngspice_data
|
|
||||||
variable op_point_read
|
|
||||||
}
|
|
||||||
|
|
||||||
proc ngspice::read_raw_dataset {arr fp} {
|
proc ngspice::read_raw_dataset {arr fp} {
|
||||||
upvar $arr var
|
upvar $arr var
|
||||||
|
|
||||||
|
|
@ -99,141 +93,4 @@ proc ngspice::read_raw {{f {}}} {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
proc ngspice::get_current {n} {
|
|
||||||
global path graph_raw_level
|
|
||||||
set path [string range [xschem get sch_path] 1 end]
|
|
||||||
# skip hierarchy components above the level where raw file has been loaded.
|
|
||||||
# node path names to look up in raw file begin from there.
|
|
||||||
set skip 0
|
|
||||||
while { $skip < $graph_raw_level } {
|
|
||||||
regsub {^[^.]*\.} $path {} path
|
|
||||||
incr skip
|
|
||||||
}
|
|
||||||
set n [string tolower $n]
|
|
||||||
set prefix [string range $n 0 0]
|
|
||||||
#puts "ngspice::get_current: path=$path n=$n"
|
|
||||||
set n $path$n
|
|
||||||
if { ![sim_is_xyce] } {
|
|
||||||
if {$path ne {} } {
|
|
||||||
set n $prefix.$n
|
|
||||||
}
|
|
||||||
if { ![regexp $prefix {[ve]}] } {
|
|
||||||
set n @$n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set n i($n)
|
|
||||||
#puts "ngspice::get_current --> $n"
|
|
||||||
set err [catch {set ngspice::ngspice_data($n)} res]
|
|
||||||
if { $err } {
|
|
||||||
set res {?}
|
|
||||||
} else {
|
|
||||||
if { abs($res) <1e-3 && $res != 0.0} {
|
|
||||||
set res [ format %.4e $res ]
|
|
||||||
} else {
|
|
||||||
set res [ format %.4g $res ]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
# puts "$n --> $res"
|
|
||||||
return $res
|
|
||||||
}
|
|
||||||
|
|
||||||
proc ngspice::get_diff_voltage {n m} {
|
|
||||||
global path graph_raw_level
|
|
||||||
set path [string range [xschem get sch_path] 1 end]
|
|
||||||
# skip hierarchy components above the level where raw file has been loaded.
|
|
||||||
# node path names to look up in raw file begin from there.
|
|
||||||
set skip 0
|
|
||||||
while { $skip < $graph_raw_level } {
|
|
||||||
regsub {^[^.]*\.} $path {} path
|
|
||||||
incr skip
|
|
||||||
}
|
|
||||||
set n [string tolower $n]
|
|
||||||
set m [string tolower $m]
|
|
||||||
set nn $path$n
|
|
||||||
set mm $path$m
|
|
||||||
set errn [catch {set ngspice::ngspice_data($nn)} resn]
|
|
||||||
if {$errn} {
|
|
||||||
set nn v(${path}${n})
|
|
||||||
set errn [catch {set ngspice::ngspice_data($nn)} resn]
|
|
||||||
}
|
|
||||||
set errm [catch {set ngspice::ngspice_data($mm)} resm]
|
|
||||||
if {$errm} {
|
|
||||||
set mm v(${path}${m})
|
|
||||||
set errm [catch {set ngspice::ngspice_data($mm)} resm]
|
|
||||||
}
|
|
||||||
if { $errn || $errm} {
|
|
||||||
set res {?}
|
|
||||||
} else {
|
|
||||||
set res [expr {$resn - $resm}]
|
|
||||||
if { abs($res) <1e-5} {
|
|
||||||
set res 0
|
|
||||||
} elseif { abs($res) <1e-3 && $res != 0.0} {
|
|
||||||
set res [ format %.4e $res ]
|
|
||||||
} else {
|
|
||||||
set res [ format %.4g $res ]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $res
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
proc ngspice::get_voltage {n} {
|
|
||||||
global path graph_raw_level
|
|
||||||
set path [string range [xschem get sch_path] 1 end]
|
|
||||||
# skip hierarchy components above the level where raw file has been loaded.
|
|
||||||
# node path names to look up in raw file begin from there.
|
|
||||||
set skip 0
|
|
||||||
while { $skip < $graph_raw_level } {
|
|
||||||
regsub {^[^.]*\.} $path {} path
|
|
||||||
incr skip
|
|
||||||
}
|
|
||||||
set n [string tolower $n]
|
|
||||||
# puts "ngspice::get_voltage: path=$path n=$n"
|
|
||||||
set node $path$n
|
|
||||||
set err [catch {set ngspice::ngspice_data($node)} res]
|
|
||||||
if {$err} {
|
|
||||||
set node v(${path}${n})
|
|
||||||
# puts "ngspice::get_voltage: trying $node"
|
|
||||||
set err [catch {set ngspice::ngspice_data($node)} res]
|
|
||||||
}
|
|
||||||
if { $err } {
|
|
||||||
set res {?}
|
|
||||||
} else {
|
|
||||||
if { abs($res) <1e-5} {
|
|
||||||
set res 0
|
|
||||||
} elseif { abs($res) <1e-3 && $res != 0.0} {
|
|
||||||
set res [ format %.4e $res ]
|
|
||||||
} else {
|
|
||||||
set res [ format %.4g $res ]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $res
|
|
||||||
}
|
|
||||||
|
|
||||||
proc ngspice::get_node {n} {
|
|
||||||
global path graph_raw_level
|
|
||||||
set path [string range [xschem get sch_path] 1 end]
|
|
||||||
# skip hierarchy components above the level where raw file has been loaded.
|
|
||||||
# node path names to look up in raw file begin from there.
|
|
||||||
set skip 0
|
|
||||||
while { $skip < $graph_raw_level } {
|
|
||||||
regsub {^[^.]*\.} $path {} path
|
|
||||||
incr skip
|
|
||||||
}
|
|
||||||
set n [string tolower $n]
|
|
||||||
# n may contain $path, so substitute its value
|
|
||||||
set n [ subst -nocommand $n ]
|
|
||||||
set err [catch {set ngspice::ngspice_data($n)} res]
|
|
||||||
if { $err } {
|
|
||||||
set res {?}
|
|
||||||
} else {
|
|
||||||
if { abs($res) <1e-3 && $res != 0.0} {
|
|
||||||
set res [ format %.4e $res ]
|
|
||||||
} else {
|
|
||||||
set res [ format %.4g $res ]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $res
|
|
||||||
}
|
|
||||||
|
|
||||||
# if { [info exists ::has_x] } {bind .drw <Alt-a> {puts {Annotating...}; ngspice::annotate} }
|
# if { [info exists ::has_x] } {bind .drw <Alt-a> {puts {Annotating...}; ngspice::annotate} }
|
||||||
|
|
|
||||||
40
src/token.c
40
src/token.c
|
|
@ -3029,7 +3029,7 @@ const char *translate(int inst, const char* s)
|
||||||
size_t len;
|
size_t len;
|
||||||
int idx;
|
int idx;
|
||||||
double val;
|
double val;
|
||||||
char valstr[120];
|
const char *valstr;
|
||||||
if(path) {
|
if(path) {
|
||||||
int skip = 0;
|
int skip = 0;
|
||||||
/* skip path components that are above the level where raw file was loaded */
|
/* skip path components that are above the level where raw file was loaded */
|
||||||
|
|
@ -3050,15 +3050,13 @@ const char *translate(int inst, const char* s)
|
||||||
val = xctx->graph_values[idx][xctx->graph_annotate_p];
|
val = xctx->graph_values[idx][xctx->graph_annotate_p];
|
||||||
}
|
}
|
||||||
if(idx < 0) {
|
if(idx < 0) {
|
||||||
my_snprintf(valstr, S(valstr), "");
|
valstr = "";
|
||||||
} else if( fabs(val) < 1.0e-5) {
|
xctx->tok_size = 0;
|
||||||
my_snprintf(valstr, S(valstr), "0");
|
len = 0;
|
||||||
} else if( fabs(val) < 1.0e-3 && val != 0.0) {
|
|
||||||
my_snprintf(valstr, S(valstr), "%.4e", val);
|
|
||||||
} else {
|
} else {
|
||||||
my_snprintf(valstr, S(valstr), "%.4g", val);
|
valstr = dtoa_eng(val);
|
||||||
|
len = xctx->tok_size;
|
||||||
}
|
}
|
||||||
len = strlen(valstr);
|
|
||||||
if(len) {
|
if(len) {
|
||||||
STR_ALLOC(&result, len + result_pos, &size);
|
STR_ALLOC(&result, len + result_pos, &size);
|
||||||
memcpy(result+result_pos, valstr, len+1);
|
memcpy(result+result_pos, valstr, len+1);
|
||||||
|
|
@ -3083,7 +3081,7 @@ const char *translate(int inst, const char* s)
|
||||||
size_t len;
|
size_t len;
|
||||||
int idx1, idx2;
|
int idx1, idx2;
|
||||||
double val = 0.0, val1 = 0.0, val2 = 0.0;
|
double val = 0.0, val1 = 0.0, val2 = 0.0;
|
||||||
char valstr[120];
|
const char *valstr;
|
||||||
if(path) {
|
if(path) {
|
||||||
int skip = 0;
|
int skip = 0;
|
||||||
/* skip path components that are above the level where raw file was loaded */
|
/* skip path components that are above the level where raw file was loaded */
|
||||||
|
|
@ -3116,15 +3114,13 @@ const char *translate(int inst, const char* s)
|
||||||
}
|
}
|
||||||
val = val1 - val2;
|
val = val1 - val2;
|
||||||
if(idx1 < 0 || idx2 < 0) {
|
if(idx1 < 0 || idx2 < 0) {
|
||||||
my_snprintf(valstr, S(valstr), "");
|
valstr = "";
|
||||||
} else if( fabs(val) < 1.0e-5) {
|
xctx->tok_size = 0;
|
||||||
my_snprintf(valstr, S(valstr), "0");
|
len = 0;
|
||||||
} else if( fabs(val) < 1.0e-3 && val != 0.0) {
|
|
||||||
my_snprintf(valstr, S(valstr), "%.4e", val);
|
|
||||||
} else {
|
} else {
|
||||||
my_snprintf(valstr, S(valstr), "%.4g", val);
|
valstr = dtoa_eng(val);
|
||||||
|
len = xctx->tok_size;
|
||||||
}
|
}
|
||||||
len = strlen(valstr);
|
|
||||||
if(len) {
|
if(len) {
|
||||||
STR_ALLOC(&result, len + result_pos, &size);
|
STR_ALLOC(&result, len + result_pos, &size);
|
||||||
memcpy(result+result_pos, valstr, len+1);
|
memcpy(result+result_pos, valstr, len+1);
|
||||||
|
|
@ -3148,7 +3144,7 @@ const char *translate(int inst, const char* s)
|
||||||
size_t len;
|
size_t len;
|
||||||
int idx;
|
int idx;
|
||||||
double val;
|
double val;
|
||||||
char valstr[120];
|
const char *valstr;
|
||||||
if(path) {
|
if(path) {
|
||||||
int skip = 0;
|
int skip = 0;
|
||||||
/* skip path components that are above the level where raw file was loaded */
|
/* skip path components that are above the level where raw file was loaded */
|
||||||
|
|
@ -3181,13 +3177,13 @@ const char *translate(int inst, const char* s)
|
||||||
val = xctx->graph_values[idx][xctx->graph_annotate_p];
|
val = xctx->graph_values[idx][xctx->graph_annotate_p];
|
||||||
}
|
}
|
||||||
if(idx < 0) {
|
if(idx < 0) {
|
||||||
my_snprintf(valstr, S(valstr), "");
|
valstr = "";
|
||||||
} else if( fabs(val) < 1.0e-3 && val != 0.0) {
|
xctx->tok_size = 0;
|
||||||
my_snprintf(valstr, S(valstr), "%.4e", val);
|
len = 0;
|
||||||
} else {
|
} else {
|
||||||
my_snprintf(valstr, S(valstr), "%.4g", val);
|
valstr = dtoa_eng(val);
|
||||||
|
len = xctx->tok_size;
|
||||||
}
|
}
|
||||||
len = strlen(valstr);
|
|
||||||
if(len) {
|
if(len) {
|
||||||
STR_ALLOC(&result, len + result_pos, &size);
|
STR_ALLOC(&result, len + result_pos, &size);
|
||||||
memcpy(result+result_pos, valstr, len+1);
|
memcpy(result+result_pos, valstr, len+1);
|
||||||
|
|
|
||||||
|
|
@ -690,7 +690,7 @@ typedef struct {
|
||||||
/* graph box (smaller than rect container due to margins) */
|
/* graph box (smaller than rect container due to margins) */
|
||||||
double x1, y1, x2, y2, w, h;
|
double x1, y1, x2, y2, w, h;
|
||||||
double gx1, gy1, gx2, gy2, gw, gh;
|
double gx1, gy1, gx2, gy2, gw, gh;
|
||||||
double master_gx1, master_gx2, master_gw;
|
double master_gx1, master_gx2, master_gw, master_cx;
|
||||||
/* y area range for digital graphs */
|
/* y area range for digital graphs */
|
||||||
double ypos1, ypos2, posh;
|
double ypos1, ypos2, posh;
|
||||||
double marginx; /* will be recalculated later */
|
double marginx; /* will be recalculated later */
|
||||||
|
|
@ -1317,6 +1317,7 @@ extern size_t my_mstrcat(int id, char **str, const char *append_str, ...);
|
||||||
extern char *my_itoa(int i);
|
extern char *my_itoa(int i);
|
||||||
extern double atof_spice(const char *s);
|
extern double atof_spice(const char *s);
|
||||||
extern char *dtoa(double i);
|
extern char *dtoa(double i);
|
||||||
|
extern char *dtoa_eng(double i);
|
||||||
extern char *dtoa_prec(double i);
|
extern char *dtoa_prec(double i);
|
||||||
extern double my_round(double a);
|
extern double my_round(double a);
|
||||||
extern double round_to_n_digits(double x, int n);
|
extern double round_to_n_digits(double x, int n);
|
||||||
|
|
|
||||||
147
src/xschem.tcl
147
src/xschem.tcl
|
|
@ -266,7 +266,6 @@ proc execute_fileevent {id} {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
proc execute_wait {status args} {
|
proc execute_wait {status args} {
|
||||||
global execute
|
global execute
|
||||||
set id [eval execute $status $args]
|
set id [eval execute $status $args]
|
||||||
|
|
@ -347,6 +346,33 @@ proc sframe {container} {
|
||||||
}
|
}
|
||||||
#### /Scrollable frame
|
#### /Scrollable frame
|
||||||
|
|
||||||
|
|
||||||
|
## convert number to engineering form
|
||||||
|
proc to_eng {i} {
|
||||||
|
set suffix {}
|
||||||
|
set absi [expr {abs($i)}]
|
||||||
|
|
||||||
|
if {$absi == 0.0} { set mult 1 ; set suffix {}
|
||||||
|
} elseif {$absi >=1e12} { set mult 1e-12; set suffix T
|
||||||
|
} elseif {$absi >=1e9} { set mult 1e-9 ; set suffix G
|
||||||
|
} elseif {$absi >=1e6} { set mult 1e-6 ; set suffix M
|
||||||
|
} elseif {$absi >=1e3} { set mult 1e-3 ; set suffix k
|
||||||
|
} elseif {$absi >=0.1} { set mult 1 ; set suffix {}
|
||||||
|
} elseif {$absi >=1e-3} { set mult 1e3 ; set suffix m
|
||||||
|
} elseif {$absi >=1e-6} { set mult 1e6 ; set suffix u
|
||||||
|
} elseif {$absi >=1e-9} { set mult 1e9 ; set suffix n
|
||||||
|
} elseif {$absi >=1e-12} { set mult 1e12 ; set suffix p
|
||||||
|
} elseif {$absi >=1e-15} { set mult 1e15 ; set suffix f
|
||||||
|
} else { set mult 1e18 ; set suffix a}
|
||||||
|
if {$suffix ne {}} {
|
||||||
|
set i [expr {$i * $mult}]
|
||||||
|
set s [format {%.5g%s} $i $suffix]
|
||||||
|
} else {
|
||||||
|
set s [format {%.5g} $i]
|
||||||
|
}
|
||||||
|
return $s
|
||||||
|
}
|
||||||
|
|
||||||
## evaluate expression. if expression has errors or does not evaluate return expression as is
|
## evaluate expression. if expression has errors or does not evaluate return expression as is
|
||||||
proc ev {s} {
|
proc ev {s} {
|
||||||
if {![catch {expr $s} res]} {
|
if {![catch {expr $s} res]} {
|
||||||
|
|
@ -668,6 +694,125 @@ proc setup_recent_menu { {in_new_window 0} { topwin {} } } {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## ngspice:: raw file access functions
|
||||||
|
namespace eval ngspice {
|
||||||
|
# Create a variable inside the namespace
|
||||||
|
variable ngspice_data
|
||||||
|
variable op_point_read
|
||||||
|
}
|
||||||
|
|
||||||
|
proc ngspice::get_current {n} {
|
||||||
|
global path graph_raw_level
|
||||||
|
set path [string range [xschem get sch_path] 1 end]
|
||||||
|
# skip hierarchy components above the level where raw file has been loaded.
|
||||||
|
# node path names to look up in raw file begin from there.
|
||||||
|
set skip 0
|
||||||
|
while { $skip < $graph_raw_level } {
|
||||||
|
regsub {^[^.]*\.} $path {} path
|
||||||
|
incr skip
|
||||||
|
}
|
||||||
|
set n [string tolower $n]
|
||||||
|
set prefix [string range $n 0 0]
|
||||||
|
#puts "ngspice::get_current: path=$path n=$n"
|
||||||
|
set n $path$n
|
||||||
|
if { ![sim_is_xyce] } {
|
||||||
|
if {$path ne {} } {
|
||||||
|
set n $prefix.$n
|
||||||
|
}
|
||||||
|
if { ![regexp $prefix {[ve]}] } {
|
||||||
|
set n @$n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set n i($n)
|
||||||
|
#puts "ngspice::get_current --> $n"
|
||||||
|
set err [catch {set ngspice::ngspice_data($n)} res]
|
||||||
|
if { $err } {
|
||||||
|
set res {?}
|
||||||
|
}
|
||||||
|
# puts "$n --> $res"
|
||||||
|
return $res
|
||||||
|
}
|
||||||
|
|
||||||
|
proc ngspice::get_diff_voltage {n m} {
|
||||||
|
global path graph_raw_level
|
||||||
|
set path [string range [xschem get sch_path] 1 end]
|
||||||
|
# skip hierarchy components above the level where raw file has been loaded.
|
||||||
|
# node path names to look up in raw file begin from there.
|
||||||
|
set skip 0
|
||||||
|
while { $skip < $graph_raw_level } {
|
||||||
|
regsub {^[^.]*\.} $path {} path
|
||||||
|
incr skip
|
||||||
|
}
|
||||||
|
set n [string tolower $n]
|
||||||
|
set m [string tolower $m]
|
||||||
|
set nn $path$n
|
||||||
|
set mm $path$m
|
||||||
|
set errn [catch {set ngspice::ngspice_data($nn)} resn]
|
||||||
|
if {$errn} {
|
||||||
|
set nn v(${path}${n})
|
||||||
|
set errn [catch {set ngspice::ngspice_data($nn)} resn]
|
||||||
|
}
|
||||||
|
set errm [catch {set ngspice::ngspice_data($mm)} resm]
|
||||||
|
if {$errm} {
|
||||||
|
set mm v(${path}${m})
|
||||||
|
set errm [catch {set ngspice::ngspice_data($mm)} resm]
|
||||||
|
}
|
||||||
|
if { $errn || $errm} {
|
||||||
|
set res {?}
|
||||||
|
}
|
||||||
|
return $res
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
proc ngspice::get_voltage {n} {
|
||||||
|
global path graph_raw_level
|
||||||
|
set path [string range [xschem get sch_path] 1 end]
|
||||||
|
# skip hierarchy components above the level where raw file has been loaded.
|
||||||
|
# node path names to look up in raw file begin from there.
|
||||||
|
set skip 0
|
||||||
|
while { $skip < $graph_raw_level } {
|
||||||
|
regsub {^[^.]*\.} $path {} path
|
||||||
|
incr skip
|
||||||
|
}
|
||||||
|
set n [string tolower $n]
|
||||||
|
# puts "ngspice::get_voltage: path=$path n=$n"
|
||||||
|
set node $path$n
|
||||||
|
set err [catch {set ngspice::ngspice_data($node)} res]
|
||||||
|
if {$err} {
|
||||||
|
set node v(${path}${n})
|
||||||
|
# puts "ngspice::get_voltage: trying $node"
|
||||||
|
set err [catch {set ngspice::ngspice_data($node)} res]
|
||||||
|
}
|
||||||
|
if { $err } {
|
||||||
|
set res {?}
|
||||||
|
}
|
||||||
|
return $res
|
||||||
|
}
|
||||||
|
|
||||||
|
proc ngspice::get_node {n} {
|
||||||
|
global path graph_raw_level
|
||||||
|
set path [string range [xschem get sch_path] 1 end]
|
||||||
|
# skip hierarchy components above the level where raw file has been loaded.
|
||||||
|
# node path names to look up in raw file begin from there.
|
||||||
|
set skip 0
|
||||||
|
while { $skip < $graph_raw_level } {
|
||||||
|
regsub {^[^.]*\.} $path {} path
|
||||||
|
incr skip
|
||||||
|
}
|
||||||
|
set n [string tolower $n]
|
||||||
|
# n may contain $path, so substitute its value
|
||||||
|
set n [ subst -nocommand $n ]
|
||||||
|
set err [catch {set ngspice::ngspice_data($n)} res]
|
||||||
|
if { $err } {
|
||||||
|
set res {?}
|
||||||
|
}
|
||||||
|
return $res
|
||||||
|
}
|
||||||
|
|
||||||
|
## end ngspice:: functions
|
||||||
|
|
||||||
proc sim_is_ngspice {} {
|
proc sim_is_ngspice {} {
|
||||||
global sim
|
global sim
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -323,7 +323,7 @@ C {ngspice_get_expr.sym} 330 -900 0 1 {name=r17
|
||||||
node="[ngspice::get_current v2]"
|
node="[ngspice::get_current v2]"
|
||||||
descr = current
|
descr = current
|
||||||
}
|
}
|
||||||
C {ngspice_get_expr.sym} 360 -1040 0 0 {name=r18
|
C {ngspice_get_expr.sym} 380 -1030 0 0 {name=r18
|
||||||
node="[ngspice::get_current \{r2[i]\}]"
|
node="[ngspice::get_current \{r2[i]\}]"
|
||||||
descr = current
|
descr = current
|
||||||
}
|
}
|
||||||
|
|
@ -356,7 +356,7 @@ node="[format %.4g [expr ([ngspice::get_voltage e11] - [ngspice::get_voltage ga]
|
||||||
descr = power
|
descr = power
|
||||||
}
|
}
|
||||||
C {ngspice_get_expr.sym} 1000 -710 0 0 {name=r20
|
C {ngspice_get_expr.sym} 1000 -710 0 0 {name=r20
|
||||||
node="[ngspice::get_current \{r0[i]\}]"
|
node="[to_eng [ngspice::get_current \{r0[i]\}]]"
|
||||||
descr = current
|
descr = current
|
||||||
}
|
}
|
||||||
C {ngspice_get_expr.sym} 280 -200 2 1 {name=r3
|
C {ngspice_get_expr.sym} 280 -200 2 1 {name=r3
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ subdivx=1
|
||||||
node=s_vec
|
node=s_vec
|
||||||
color=4
|
color=4
|
||||||
dataset=0
|
dataset=0
|
||||||
unitx=u
|
unitx=1
|
||||||
logx=0
|
logx=0
|
||||||
logy=0
|
logy=0
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue