diff --git a/doc/xschem_man/developer_info.html b/doc/xschem_man/developer_info.html index d988da0f..ee0ddf30 100644 --- a/doc/xschem_man/developer_info.html +++ b/doc/xschem_man/developer_info.html @@ -1165,7 +1165,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns" Push current state on undo stack
what = add | clear | datasets | index | info | loaded | list | new | points | rawfile | del |
- read | set | sim_type | switch | switch_back | table_read | value | values | vars |
+ read | set | sim_type | switch | switch_back | table_read | value | values | pos_at | vars |
xschem raw read filename [type [sweep1 sweep2]]
if sweep1, sweep2 interval is given in 'read' subcommand load only the interval
@@ -1229,6 +1229,13 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
print all simulation values of 'node' for dataset 'dset' (default dset=0)
dset= -1: print all values for all datasets
+ xschem raw pos_at node value [dset] [from_start] [to_end]
+ returns the position, starting from 0 or from_start if given, to the end of dataset
+ or to_end if given of the first point 'p' where node[p] and node[p+1] bracket value.
+ If dset not given assume dset 0 (first one)
+ This is usually done on the sweep (time) variable in transient sims where timestep is
+ not uniform
+
xschem raw points [dset]
print simulation points for dataset 'dset' (default: all dataset points combined)
@@ -1672,6 +1679,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
+
diff --git a/src/draw.c b/src/draw.c
index f373d54e..1a9fc28a 100644
--- a/src/draw.c
+++ b/src/draw.c
@@ -2271,15 +2271,20 @@ static SPICE_DATA **get_bus_idx_array(const char *ntok, int *n_bits)
*/
static void set_thick_waves(int what, int wcnt, int wave_col, Graph_ctx *gr)
{
+ unsigned long valuemask;
+ XGCValues values;
+ valuemask = GCLineWidth;
dbg(1, "set_thick_waves(): what=%d\n", what);
if(what) {
- if(gr->hilight_wave == wcnt)
- XSetLineAttributes (display, xctx->gc[wave_col],
- XLINEWIDTH(2.4 * gr->linewidth_mult * xctx->lw) ,LineSolid, LINECAP , LINEJOIN);
+ if(gr->hilight_wave == wcnt) {
+ values.line_width = XLINEWIDTH(2.4 * gr->linewidth_mult * xctx->lw);
+ XChangeGC(display, xctx->gc[wave_col], valuemask, &values);
+ }
} else {
- if(gr->hilight_wave == wcnt)
- XSetLineAttributes (display, xctx->gc[wave_col],
- XLINEWIDTH(gr->linewidth_mult * xctx->lw) ,LineSolid, LINECAP , LINEJOIN);
+ if(gr->hilight_wave == wcnt) {
+ values.line_width = XLINEWIDTH(gr->linewidth_mult * xctx->lw);
+ XChangeGC(display, xctx->gc[wave_col], valuemask, &values);
+ }
}
}
@@ -2610,9 +2615,8 @@ static void draw_graph_bus_points(const char *ntok, int n_bits, SPICE_DATA **idx
}
for(p=0;pgc[p],
- XLINEWIDTH(gr->linewidth_mult * xctx->lw), LineSolid, LINECAP , LINEJOIN);
+ XLINEWIDTH(gr->linewidth_mult * xctx->lw), LineSolid, LINECAP, LINEJOIN);
}
-
if(gr->logx) {
lx1 = W_X(mylog10(raw->values[sweep_idx][first]));
lx2 = W_X(mylog10(raw->values[sweep_idx][last]));
@@ -2689,8 +2693,13 @@ static void draw_graph_points(int idx, int first, int last,
dbg(1, "draw_graph_points: idx=%d, first=%d, last=%d, wcnt=%d\n", idx, first, last, wcnt);
if(idx == -1) return;
for(p=0;pgc[p],
- XLINEWIDTH(gr->linewidth_mult * xctx->lw), LineSolid, LINECAP , LINEJOIN);
+ if(gr->mode == 1 || gr->mode == 2) { /* Histograms */
+ XSetLineAttributes(display, xctx->gc[p],
+ XLINEWIDTH(gr->linewidth_mult * xctx->lw), LineSolid, xCap , xJoin);
+ } else {
+ XSetLineAttributes(display, xctx->gc[p],
+ XLINEWIDTH(gr->linewidth_mult * xctx->lw), LineSolid, LINECAP , LINEJOIN);
+ }
}
digital = gr->digital;
if(digital) {
diff --git a/src/save.c b/src/save.c
index 02b0b32f..4b711b96 100644
--- a/src/save.c
+++ b/src/save.c
@@ -1538,6 +1538,42 @@ int table_read(const char *f)
return 0;
}
+int raw_get_pos(const char *node, double value, int dset, int from_start, int to_end)
+{
+ int x = -1;
+ Raw *raw = xctx->raw;
+ int idx = -1;
+
+ if(sch_waves_loaded() >= 0) {
+ if(dset >= raw->datasets) dset = raw->datasets - 1;
+ if(dset < 0) dset = 0;
+ idx = get_raw_index(node, NULL);
+ if(idx >= 0) {
+ double vx;
+ int start, end;
+
+ start = from_start >= 0 ? from_start : 0;
+ end = to_end >= 0 ? to_end : raw->npoints[dset] - 1;
+ double vstart = get_raw_value(dset, idx, start);
+ double vend = get_raw_value(dset, idx, end);
+ int sign = (vend > vstart) ? 1 : -1;
+ dbg(0, "%d %d\n", start, end);
+
+ if(start >= end) start = end;
+ if( sign * value >= sign * vstart && sign * value <= sign * vend) {
+ while(1) {
+ x = (start + end ) / 2;
+ vx = get_raw_value(dset, idx, x);
+ if(end - start <= 1) break;
+ if( sign * vx > sign * value) end = x;
+ else start = x;
+ }
+ }
+ }
+ }
+
+ return x;
+}
/* given a node XXyy try XXyy , xxyy, XXYY, v(XXyy), v(xxyy), V(XXYY) */
int get_raw_index(const char *node, Int_hashentry **entry_ret)
{
diff --git a/src/scheduler.c b/src/scheduler.c
index e74b0edc..e2d286c8 100644
--- a/src/scheduler.c
+++ b/src/scheduler.c
@@ -3791,7 +3791,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
/* raw what ...
* what = add | clear | datasets | index | info | loaded | list | new | points | rawfile | del |
- * read | set | sim_type | switch | switch_back | table_read | value | values | vars |
+ * read | set | sim_type | switch | switch_back | table_read | value | values | pos_at | vars |
*
* xschem raw read filename [type [sweep1 sweep2]]
* if sweep1, sweep2 interval is given in 'read' subcommand load only the interval
@@ -3855,6 +3855,13 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
* print all simulation values of 'node' for dataset 'dset' (default dset=0)
* dset= -1: print all values for all datasets
*
+ * xschem raw pos_at node value [dset] [from_start] [to_end]
+ * returns the position, starting from 0 or from_start if given, to the end of dataset
+ * or to_end if given of the first point 'p' where node[p] and node[p+1] bracket value.
+ * If dset not given assume dset 0 (first one)
+ * This is usually done on the sweep (time) variable in transient sims where timestep is
+ * not uniform
+ *
* xschem raw points [dset]
* print simulation points for dataset 'dset' (default: all dataset points combined)
*
@@ -3994,6 +4001,25 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
Tcl_AppendResult(interp, n, " ", NULL);
}
}
+ } else if(argc > 4 && !strcmp(argv[2], "pos_at")) {
+ /* xschem raw pos_at node value [dset] [from_start] [to_end] */
+ int dset = 0;
+ int from_start = -1;
+ int to_end = -1;
+ int pos = -1;
+ double value = 0.0;
+ if(argc > 5) {
+ dset = atoi(argv[5]);
+ }
+ if(argc > 6) {
+ from_start = atoi(argv[6]);
+ }
+ if(argc > 7) {
+ to_end = atoi(argv[7]);
+ }
+ value = atof_spice(argv[4]);
+ pos = raw_get_pos(argv[3], value, dset, from_start, to_end);
+ Tcl_SetResult(interp, my_itoa(pos), TCL_VOLATILE);
} else if(argc > 3 && !strcmp(argv[2], "add")) {
int res = 0;
int sweep_idx = 0;
diff --git a/src/xschem.h b/src/xschem.h
index df46aeee..3f59ee9b 100644
--- a/src/xschem.h
+++ b/src/xschem.h
@@ -1267,6 +1267,7 @@ extern int set_rect_extraptr(int what, xRect *drptr);
extern unsigned char *base64_decode(const char *data, const size_t input_length, size_t *output_length);
extern char *base64_encode(const unsigned char *data, const size_t input_length, size_t *output_length, int brk);
extern unsigned char *ascii85_encode(const unsigned char *data, const size_t input_length, size_t *output_length);
+extern int raw_get_pos(const char *node, double value, int dset, int from_start, int to_end);
extern int get_raw_index(const char *node, Int_hashentry **entry_ret);
extern void free_rawfile(Raw **rawptr, int dr);
extern int update_op();
diff --git a/xschem_library/examples/cmos_example.sch b/xschem_library/examples/cmos_example.sch
index 10360840..be0657d9 100644
--- a/xschem_library/examples/cmos_example.sch
+++ b/xschem_library/examples/cmos_example.sch
@@ -1,4 +1,4 @@
-v {xschem version=3.4.6RC file_version=1.2
+v {xschem version=3.4.6 file_version=1.2
*
* This file is part of XSCHEM,
* a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit
@@ -31,8 +31,8 @@ y1=-160
y2=0
divy=4
subdivy=1
-x1=2.3
-x2=2.7
+x1=2.4
+x2=2.6
divx=6
subdivx=1
node="\\"GAIN @ 2uA;diffout deriv() % 0\\"
@@ -57,8 +57,8 @@ y1=0.875402
y2=5.6754
divy=4
subdivy=1
-x1=2.3
-x2=2.7
+x1=2.4
+x2=2.6
divx=6
subdivx=1
node="diffout@2uA;v(diffout)%0
@@ -144,8 +144,8 @@ y1=2.3
y2=2.7
divy=4
subdivy=1
-x1=2.3088075
-x2=2.7088075
+x1=2.4
+x2=2.6
divx=6
subdivx=1
node="minus;minus%0
@@ -344,7 +344,7 @@ value=".temp 30
settype power power
write cmos_example_ngspice.raw
set appendwrite
- dc vminus 2.3 2.7 0.001
+ dc vminus 2.4 2.6 0.001
write cmos_example_ngspice.raw
tran 0.5n 5u
write cmos_example_ngspice.raw
@@ -366,7 +366,7 @@ value=".temp 30
alterparam IB=100u
reset
save all
- dc vminus 2.3 2.7 0.001
+ dc vminus 2.4 2.6 0.001
write cmos_example_ngspice.raw
tran 0.5n 5u
write cmos_example_ngspice.raw