Better axis label placement, smooth waves move/zoom with mouse, compile option to store sim data as floats instead of doubles, option for axis scaling (p,n,u,m,k,M,G), load waveforms command is a toggle (load / free)

This commit is contained in:
Stefan Frederik 2021-12-24 12:17:00 +01:00
parent ddb4c048bd
commit 70adb61410
9 changed files with 454 additions and 322 deletions

View File

@ -25,9 +25,9 @@
#include <sys/wait.h> /* waitpid */
#endif
void here(int i)
void here(double i)
{
fprintf(stderr, "here %d\n", i);
fprintf(stderr, "here %g\n", i);
}
/* super simple 32 bit hashing function for files
@ -1304,6 +1304,10 @@ void calc_drawing_bbox(xRect *boundbox, int selected)
for(i=0;i<xctx->rects[c];i++)
{
if(selected == 1 && !xctx->rect[c][i].sel) continue;
/* skip graph objects if no datafile loaded */
if(c == 2 && xctx->rect[c][i].flags == 1) {
if(!schematic_waves_loaded()) continue;
}
tmp.x1=xctx->rect[c][i].x1;
tmp.x2=xctx->rect[c][i].x2;
tmp.y1=xctx->rect[c][i].y1;
@ -2313,6 +2317,24 @@ double round_to_n_digits(double x, int n)
return my_round(x / scale) * scale;
}
/*
double floor_to_n_digits(double x, int n)
{
double scale;
if(x == 0.0) return x;
scale = pow(10.0, ceil(log10(fabs(x))) - n);
return floor(x / scale) * scale;
}
double ceil_to_n_digits(double x, int n)
{
double scale;
if(x == 0.0) return x;
scale = pow(10.0, ceil(log10(fabs(x))) - n);
return ceil(x / scale) * scale;
}
*/
int place_text(int draw_text, double mx, double my)
{
char *txt;

View File

@ -168,13 +168,14 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
double wy2 = 4;
double x1, y1, x2, y2, marginx, marginy;
double cx;
int divisx = 10;
int divisy = 5;
int divx = 10;
int divy = 5;
const char *val;
char s[30];
int n, c, i;
double xx1, xx2;
int need_redraw = 0;
double delta_threshold = 0.25;
#if HAS_CAIRO==1
cairo_save(xctx->cairo_ctx);
@ -191,9 +192,9 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
if(xctx->rect[c][n].flags != 1) continue;
if(i == 0) {
val = get_tok_value(xctx->rect[c][n].prop_ptr,"divx",0);
if(val[0]) divisx = atoi(val);
if(val[0]) divx = atoi(val);
val = get_tok_value(xctx->rect[c][n].prop_ptr,"divy",0);
if(val[0]) divisy = atoi(val);
if(val[0]) divy = atoi(val);
val = get_tok_value(xctx->rect[c][n].prop_ptr,"x1",0);
if(val[0]) wx1 = atof(val);
val = get_tok_value(xctx->rect[c][n].prop_ptr,"y1",0);
@ -205,23 +206,32 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
calc_graph_area(c, n, &x1, &y1, &x2, &y2, &marginx, &marginy);
/* cache coefficients for faster graph coord transformations */
cx = (x2 - x1) / (wx2 - wx1);
dbg(1, "%g %g %g %g - %d %d\n", wx1, wy1, wx2, wy2, divisx, divisy);
dbg(1, "%g %g %g %g - %d %d\n", wx1, wy1, wx2, wy2, divx, divy);
}
if(event == MotionNotify && state && Button1Mask) {
double delta = (wx2 - wx1) / divisx;
if(event == MotionNotify && (state & Button2Mask)) {
double delta = (wx2 - wx1) / divx;
dbg(1, "waves_callback: Motion: %g %g --> %g %g\n",
xctx->mx_double_save, xctx->my_double_save, xctx->mousex_snap, xctx->mousey_snap);
if(fabs(xctx->mx_double_save - xctx->mousex_snap) > fabs(cx * delta)) {
if( xctx->mousex_snap > xctx->mx_double_save) key = XK_Left;
else key = XK_Right;
xctx->mx_double_save, xctx->my_double_save, xctx->mousex_snap, xctx->mousey_snap);
delta_threshold = 0.10;
if(fabs(xctx->mx_double_save - xctx->mousex_snap) > fabs(cx * delta) * delta_threshold) {
xx1 = wx1 + (xctx->mx_double_save - xctx->mousex_snap) / cx;
xx2 = wx2 + (xctx->mx_double_save - xctx->mousex_snap) / cx;
if(i >= xctx->lastsel -1) { /* update saved mouse position after processing all graphs */
xctx->mx_double_save = xctx->mousex_snap;
xctx->my_double_save = xctx->mousey_snap;
}
}
my_snprintf(s, S(s), "%g", xx1);
my_strdup(1410, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x1", s));
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1411, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
need_redraw = 1;
}
}
if(key == XK_Left || (button == Button5 && state == 0)) {
double delta = (wx2 - wx1) / divisx;
xx1 = round_to_n_digits(wx1 - delta, 4);
xx2 = round_to_n_digits(wx2 - delta, 4);
else if(key == XK_Left || (button == Button5 && state == 0)) {
double delta = (wx2 - wx1) / divx;
delta_threshold = 2.0;
xx1 = wx1 - delta * delta_threshold;
xx2 = wx2 - delta * delta_threshold;
my_snprintf(s, S(s), "%g", xx1);
my_strdup(1395, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x1", s));
my_snprintf(s, S(s), "%g", xx2);
@ -229,9 +239,10 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
need_redraw = 1;
}
else if(key == XK_Right || (button == Button4 && state == 0)) {
double delta = (wx2 - wx1) / divisx;
xx1 = round_to_n_digits(wx1 + delta, 4);
xx2 = round_to_n_digits(wx2 + delta, 4);
double delta = (wx2 - wx1) / divx;
delta_threshold = 2.0;
xx1 = wx1 + delta * delta_threshold;
xx2 = wx2 + delta * delta_threshold;
my_snprintf(s, S(s), "%g", xx1);
my_strdup(1397, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x1", s));
my_snprintf(s, S(s), "%g", xx2);
@ -240,22 +251,16 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
}
else if(key == XK_Down || (button == Button5 && state == ShiftMask)) {
double delta = (wx2 - wx1);
xx2 = round_to_n_digits(wx2 + delta, 2);
xx2 = wx2 + delta * 0.1;
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1399, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
need_redraw = 1;
}
else if(key == XK_Up || (button == Button4 && state == ShiftMask)) {
double delta = (wx2 - wx1)/ 2.0;
double tmp;
if(fabs(wx2) > fabs(wx1) ) tmp = fabs(wx2);
else tmp = fabs(wx1);
if( tmp / fabs(wx2 - wx1) < 1e2) {
xx2 = round_to_n_digits(wx2 - delta, 2);
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1400, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
}
double delta = (wx2 - wx1);
xx2 = wx2 - delta * 0.1;
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1400, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
need_redraw = 1;
}
else if(key == 'f') {
@ -265,11 +270,11 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
my_snprintf(s, S(s), "%g", xx1);
my_strdup(1409, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x1", s));
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1409, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
my_strdup(1412, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
need_redraw = 1;
}
}
else if(event == ButtonPress && button == Button1) {
else if(event == ButtonPress && button == Button2) {
xctx->mx_double_save = xctx->mousex_snap;
xctx->my_double_save = xctx->mousey_snap;
}
@ -1849,6 +1854,10 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
rebuild_selected_array(); /* sets or clears xctx->ui_state SELECTION flag */
}
else if(button==Button2 && (state == 0)) {
if(waves_selected()) {
waves_callback(event, mx, my, key, button, aux, state);
break;
}
pan2(START, mx, my);
xctx->ui_state |= STARTPAN2;
}

View File

@ -1489,9 +1489,9 @@ void read_binary_block(FILE *fd)
double *tmp;
tmp = my_calloc(1405, xctx->nvars, sizeof(double *));
/* allocate storage for binary block */
xctx->values = my_calloc(118, xctx->nvars, sizeof(double *));
xctx->values = my_calloc(118, xctx->nvars, sizeof(RAW_FLOAT *));
for(p = 0 ; p < xctx->nvars; p++) {
xctx->values[p] = my_calloc(372, xctx->npoints, sizeof(double));
xctx->values[p] = my_calloc(372, xctx->npoints, sizeof(RAW_FLOAT));
}
/* read binary block */
for(p = 0; p < xctx->npoints; p++) {
@ -1535,11 +1535,16 @@ int read_dataset(FILE *fd)
char *ptr;
int transient = 0;
int dc = 0;
int done_header = 0;
xctx->datasets = 0;
xctx->npoints = 0;
xctx->nvars = 0;
while((ptr = fgets(line, sizeof(line), fd)) ) {
if(!strncmp(line, "Binary:", 7)) break; /* start of binary block */
if(dc || transient) {
if(!strncmp(line, "Binary:", 7)) {
done_header = 1;
break; /* start of binary block */
}
if((dc || transient) && !done_header) {
if(variables) {
sscanf(line, "%d %s", &i, varname); /* read index and name of saved waveform */
xctx->names[i] = my_malloc(415, strlen(varname) + 1);
@ -1562,9 +1567,11 @@ int read_dataset(FILE *fd)
}
if(!strncmp(line, "Plotname: Transient Analysis", 28)) {
transient = 1;
xctx->datasets++;
}
if(!strncmp(line, "Plotname: DC transfer characteristic", 36)) {
dc = 1;
xctx->datasets++;
}
if(!done_points && !strncmp(line, "No. Points:", 11)) {
sscanf(line, "No. Points: %d", &xctx->npoints);
@ -1598,6 +1605,7 @@ void free_rawfile(void)
my_free(528, &xctx->values);
my_free(968, &xctx->names);
my_free(1393, &xctx->raw_schname);
xctx->datasets = 0;
xctx->npoints = 0;
xctx->nvars = 0;
int_hash_free(xctx->raw_table);
@ -1652,6 +1660,75 @@ void calc_graph_area(int c, int i, double *x1, double *y1,double *x2,double *y2,
*y2 = ry2 - tmp; /* some more space to accomodate x-axis label */
}
/* round to closest 1e-ee. 2e-ee, 5e-ee
* example: delta = 0.234 --> 0.2
* 3.23 --> 5
* 66 --> 100
* 4.3 --> 5
* 13 --> 20
* 112 --> 100
* 6300 --> 10000
*/
static double axis_increment(double delta, int div)
{
double scale;
double sign;
double scaled_delta;
if(div == 1) return delta;
if(delta == 0.0) return delta;
delta /= div;
sign = (delta < 0.0) ? -1.0 : 1.0;
delta = fabs(delta);
scale = pow(10.0, floor(log10(delta)));
scaled_delta = delta / scale; /* 1 <= scaled_delta < 10 */
if(scaled_delta > 5.5) scaled_delta = 10.0;
else if(scaled_delta > 2.2) scaled_delta = 5.0;
else if(scaled_delta > 1.1) scaled_delta = 2.0;
else scaled_delta = 1.0;
return scaled_delta * scale * sign;
}
double axis_start(double n, double delta)
{
if(delta == 0.0) return n;
if(delta < 0.0) return floor(n / delta) * delta;
return ceil(n / delta) * delta;
}
int axis_end(double x, double delta, double b)
{
if(delta == 0.0) return 1; /* guard against infinite loops */
if(delta > 0) return x > b + delta / 100000.0;
return x < b + delta / 100000.0;
}
int axis_within_range(double x, double a, double b)
{
if(a < b) return x >= a;
return x <= a;
}
static double get_unit(const char *val)
{
if(!val) return 1.0;
else if(val[0] == 'p') return 1e12;
else if(val[0] == 'n') return 1e9;
else if(val[0] == 'u') return 1e6;
else if(val[0] == 'm') return 1e3;
else if(val[0] == 'k') return 1e-3;
else if(val[0] == 'M') return 1e-6;
else if(val[0] == 'G') return 1e-9;
return 1.0;
}
int schematic_waves_loaded(void)
{
if(xctx->values && xctx->raw_schname)
if( !strcmp(xctx->raw_schname, get_cell_w_ext(xctx->sch[0], 0)) ||
!strcmp(xctx->raw_schname, xctx->current_name) ) return 1;
return 0;
}
/* fill each graph box with simulation data */
/* #define W_X(x) (x1 + (x2 - x1) / (wx2 - wx1) * ((x) - wx1)) */
/* #define W_Y(y) (y2 - (y2 - y1) / (wy2 - wy1) * ((y) - wy1)) */
@ -1671,11 +1748,21 @@ void draw_graph(int c, int i, int flags)
double marginx = 20; /* will be recalculated later */
double marginy = 20; /* will be recalculated later */
double wx, wy; /* point coordinates in graph */
/* coefficients for graph to container coordinate transformations W_X() and W_Y()*/
double cx, dx, cy, dy;
double dash_sizex, dash_sizey;
int divisx = 10;
int divisy = 5;
int j, wave_color = 5;
int divx = 10;
int divy = 5;
int subdivx = 0;
int subdivy = 0;
double unitx = 1.0;
double unity = 1.0;
int unitx_suffix = ' '; /* 'n' or 'u' or 'M' or 'k' ... */
int unity_suffix = ' ';
/* label start and increments calculated in order to give 'nice' numbers */
double deltax, deltay;
double startx, starty;
int j, k, wave_color = 5;
char lab[30];
const char *val;
char *node = NULL, *color = NULL, *sweep = NULL;
@ -1684,6 +1771,10 @@ void draw_graph(int c, int i, int flags)
int sweep_idx = 0;
int n_nodes; /* number of variables to display in a single graph */
xRect *r = &xctx->rect[c][i];
char tmpstr[200];
char *saven, *savec, *saves, *nptr, *cptr, *sptr, *ntok, *ctok, *stok;
int wcnt = 0;
double *xarr = NULL, *yarr = NULL;
/* container (embedding rectangle) coordinates */
@ -1698,10 +1789,20 @@ void draw_graph(int c, int i, int flags)
w = (x2 - x1);
h = (y2 - y1);
/* get variables to plot, x/y range, grid info etc */
val = get_tok_value(r->prop_ptr,"unitx",0);
unitx_suffix = val[0];
unitx = get_unit(val);;
val = get_tok_value(r->prop_ptr,"unity",0);
unity_suffix = val[0];
unity = get_unit(val);;
val = get_tok_value(r->prop_ptr,"subdivx",0);
if(val[0]) subdivx = atoi(val);
val = get_tok_value(r->prop_ptr,"subdivy",0);
if(val[0]) subdivy = atoi(val);
val = get_tok_value(r->prop_ptr,"divx",0);
if(val[0]) divisx = atoi(val);
if(val[0]) divx = atoi(val);
val = get_tok_value(r->prop_ptr,"divy",0);
if(val[0]) divisy = atoi(val);
if(val[0]) divy = atoi(val);
val = get_tok_value(r->prop_ptr,"x1",0);
if(val[0]) wx1 = atof(val);
val = get_tok_value(r->prop_ptr,"y1",0);
@ -1717,19 +1818,19 @@ void draw_graph(int c, int i, int flags)
dy = y2 - wy1 * cy;
/* calculate dash length for grid lines */
dash_sizex = 800 * xctx->mooz / 300.0;
dash_sizex = 1.5 * xctx->mooz;
dash_sizex = dash_sizex > 127.0 ? 127 : dash_sizex;
if(dash_sizex <= 1) dash_sizex = 1;
dash_sizey = 800 * xctx->mooz / 300.0;
dash_sizey = 1.5 * xctx->mooz;
dash_sizey = dash_sizey > 127.0 ? 127 : dash_sizey;
if(dash_sizey <= 1) dash_sizey = 1;
/* x axis, y axis, label text sizes */
txtsizey = h / divisy / 90 ;
txtsizey = h / divy / 90 ;
tmp = marginx / 200;
if(tmp < txtsizey) txtsizey = tmp;
txtsizex = w / divisx / 300;
txtsizex = w / divx / 300;
tmp = marginy / 110;
if(tmp < txtsizex) txtsizex = tmp;
@ -1740,125 +1841,152 @@ void draw_graph(int c, int i, int flags)
drawrect(c, NOW, rx1, ry1, rx2, ry2, 1);
/* vertical grid lines */
for(j = 0; j <= divisx; j++) {
wx = wx1 + j * (wx2 -wx1) / divisx;
deltax = axis_increment((wx2 - wx1), divx);
startx = axis_start(wx1, deltax);
for(j = -1;; j++) { /* start one interval before to allow sub grids at beginning */
wx = startx + j * deltax;
if(subdivx > 0) for(k = 1; k <=subdivx; k++) {
double subwx = wx + k * deltax / (subdivx + 1);
if(!axis_within_range(subwx, wx1, wx2)) continue;
if(axis_end(subwx, deltax, wx2)) break;
drawline(2, ADD, W_X(subwx), W_Y(wy2), W_X(subwx), W_Y(wy1), dash_sizey);
}
if(!axis_within_range(wx, wx1, wx2)) continue;
if(axis_end(wx, deltax, wx2)) break;
/* swap order of wy1 and wy2 since grap y orientation is opposite to xorg orientation */
drawline(2, NOW, W_X(wx), W_Y(wy2), W_X(wx), W_Y(wy1), dash_sizey);
drawline(2, ADD, W_X(wx), W_Y(wy2), W_X(wx), W_Y(wy1), dash_sizey);
drawline(2, ADD, W_X(wx), W_Y(wy1), W_X(wx), W_Y(wy1) + 4, 0); /* axis marks */
/* X-axis labels */
my_snprintf(lab, S(lab), "%.4g", fabs(wx) < 1e-23 ? 0.0 : wx);
my_snprintf(lab, S(lab), "%.4g", wx * unitx);
draw_string(3, NOW, lab, 0, 0, 1, 0, W_X(wx), y2 + 30 * txtsizex, txtsizex, txtsizex);
}
/* first and last box delimiters */
drawline(2, ADD, W_X(wx1), W_Y(wy2), W_X(wx1), W_Y(wy1), 0);
drawline(2, ADD, W_X(wx2), W_Y(wy2), W_X(wx2), W_Y(wy1), 0);
/* horizontal grid lines */
for(j = 0; j <= divisy; j++) {
wy = wy1 + j * (wy2 -wy1) / divisy;
drawline(2, NOW, W_X(wx1), W_Y(wy), W_X(wx2), W_Y(wy), dash_sizex);
deltay = axis_increment((wy2 - wy1), divy);
starty = axis_start(wy1, deltay);
for(j = -1;; j++) { /* start one interval before to allow sub grids at beginning */
wy = starty + j * deltay;
if(subdivy > 0) for(k = 1; k <=subdivy; k++) {
double subwy = wy + k * deltay / (subdivy + 1);
if(!axis_within_range(subwy, wy1, wy2)) continue;
if(axis_end(subwy, deltay, wy2)) break;
drawline(2, ADD, W_X(wx1), W_Y(subwy), W_X(wx2), W_Y(subwy), dash_sizex);
}
if(!axis_within_range(wy, wy1, wy2)) continue;
if(axis_end(wy, deltay, wy2)) break;
drawline(2, ADD, W_X(wx1), W_Y(wy), W_X(wx2), W_Y(wy), dash_sizex);
drawline(2, ADD, W_X(wx1)-4, W_Y(wy), W_X(wx1), W_Y(wy), 0); /* axis marks */
/* Y-axis labels */
my_snprintf(lab, S(lab), "%.4g", fabs(wy) < 1e-23 ? 0.0 : wy);
draw_string(3, NOW, lab, 0, 1, 0, 1, x1 - 30 * txtsizey, W_Y(wy), txtsizey, txtsizey);
my_snprintf(lab, S(lab), "%.4g", wy * unity);
draw_string(3, NOW, lab, 0, 1, 0, 1, x1 - 2 - 30 * txtsizey, W_Y(wy), txtsizey, txtsizey);
}
/* first and last box delimiters */
drawline(2, ADD, W_X(wx1), W_Y(wy1), W_X(wx2), W_Y(wy1), 0);
drawline(2, ADD, W_X(wx1), W_Y(wy2), W_X(wx2), W_Y(wy2), 0);
/* Horizontal axis (if in viewport) */
if(wy1 <= 0 && wy2 >= 0) drawline(2, NOW, W_X(wx1), W_Y(0), W_X(wx2), W_Y(0), 0);
if(wy1 <= 0 && wy2 >= 0) drawline(2, ADD, W_X(wx1), W_Y(0), W_X(wx2), W_Y(0), 0);
/* Vertical axis (if in viewport)
* swap order of wy1 and wy2 since grap y orientation is opposite to xorg orientation */
if(wx1 <= 0 && wx2 >= 0) drawline(2, NOW, W_X(0), W_Y(wy2), W_X(0), W_Y(wy1), 0);
if(wx1 <= 0 && wx2 >= 0) drawline(2, ADD, W_X(0), W_Y(wy2), W_X(0), W_Y(wy1), 0);
drawline(2, END, 0.0, 0.0, 0.0, 0.0, 0);
/* if simulation data is loaded and matches schematic draw data */
if(xctx->raw_schname && (!strcmp(xctx->raw_schname, get_cell_w_ext(xctx->sch[0], 0)) ||
!strcmp(xctx->raw_schname, xctx->current_name) ) && xctx->values) {
char *saven, *savec, *saves, *nptr, *cptr, *sptr, *ntok, *ctok, *stok;
int wcnt = 0;
double *xarr = NULL, *yarr = NULL;
xarr = my_malloc(1401, xctx->npoints * sizeof(double));
yarr = my_malloc(1402, xctx->npoints * sizeof(double));
my_strdup2(1389, &node, get_tok_value(r->prop_ptr,"node",0));
my_strdup2(1390, &color, get_tok_value(r->prop_ptr,"color",0));
my_strdup2(1407, &sweep, get_tok_value(r->prop_ptr,"sweep",0));
nptr = node;
cptr = color;
sptr = sweep;
n_nodes = count_items(node, " \t\n");
/* process each node given in "node" attribute, get also associated color if any*/
while( (ntok = my_strtok_r(nptr, "\n\t ", &saven)) ) {
ctok = my_strtok_r(cptr, " ", &savec);
stok = my_strtok_r(sptr, " ", &saves);
nptr = cptr = sptr = NULL;
dbg(1, "ntok=%s ctok=%s\n", ntok, ctok? ctok: "NULL");
if(ctok && ctok[0]) wave_color = atoi(ctok);
if(stok && stok[0]) {
entry = int_hash_lookup(xctx->raw_table, stok, 0, XLOOKUP);
if(entry && entry->value) sweep_idx = entry->value;
else sweep_idx = 0;
}
/* draw sweep variable(s) on x-axis */
if(wcnt == 0 || (stok && stok[0])) {
draw_string(wave_color, NOW, xctx->names[sweep_idx], 2, 1, 0, 0,
rx1 + 2 + rw/n_nodes * wcnt, ry2-1, txtsizelab, txtsizelab);
}
/* draw node labels in graph */
draw_string(wave_color, NOW, ntok, 0, 0, 0, 0, rx1 + rw/n_nodes * wcnt, ry1, txtsizelab, txtsizelab);
/* clipping everything outside graph area */
/* quickly find index number of ntok variable to be plotted */
entry = int_hash_lookup(xctx->raw_table, ntok, 0, XLOOKUP);
if(entry) {
int p;
int poly_npoints = 0;
int v = entry->value;
int first = -1, last = 0;
double xx, yy;
double start = (wx1 <= wx2) ? wx1 : wx2;
double end = (wx1 <= wx2) ? wx2 : wx1;
xarr = my_malloc(1401, xctx->npoints * sizeof(double));
yarr = my_malloc(1402, xctx->npoints * sizeof(double));
my_strdup2(1389, &node, get_tok_value(r->prop_ptr,"node",0));
my_strdup2(1390, &color, get_tok_value(r->prop_ptr,"color",0));
my_strdup2(1407, &sweep, get_tok_value(r->prop_ptr,"sweep",0));
nptr = node;
cptr = color;
sptr = sweep;
n_nodes = count_items(node, " \t\n");
/* process each node given in "node" attribute, get also associated color if any*/
while( (ntok = my_strtok_r(nptr, "\n\t ", &saven)) ) {
ctok = my_strtok_r(cptr, " ", &savec);
stok = my_strtok_r(sptr, " ", &saves);
nptr = cptr = sptr = NULL;
dbg(1, "ntok=%s ctok=%s\n", ntok, ctok? ctok: "NULL");
if(ctok && ctok[0]) wave_color = atoi(ctok);
if(stok && stok[0]) {
entry = int_hash_lookup(xctx->raw_table, stok, 0, XLOOKUP);
if(entry && entry->value) sweep_idx = entry->value;
else sweep_idx = 0;
}
/* draw sweep variable(s) on x-axis */
if(wcnt == 0 || (stok && stok[0])) {
if(unitx != 1.0) my_snprintf(tmpstr, S(tmpstr), "%s[%c]", xctx->names[sweep_idx], unitx_suffix);
else my_snprintf(tmpstr, S(tmpstr), "%s", xctx->names[sweep_idx]);
draw_string(wave_color, NOW, tmpstr, 2, 1, 0, 0,
rx1 + 2 + rw/n_nodes * wcnt, ry2-1, txtsizelab, txtsizelab);
}
/* draw node labels in graph */
if(unity != 1.0) my_snprintf(tmpstr, S(tmpstr), "%s[%c]", ntok, unity_suffix);
else my_snprintf(tmpstr, S(tmpstr), "%s", ntok);
draw_string(wave_color, NOW, tmpstr, 0, 0, 0, 0, rx1 + rw/n_nodes * wcnt, ry1, txtsizelab, txtsizelab);
/* clipping everything outside graph area */
/* quickly find index number of ntok variable to be plotted */
entry = int_hash_lookup(xctx->raw_table, ntok, 0, XLOOKUP);
if(entry) {
int p;
int poly_npoints = 0;
int v = entry->value;
int first = -1, last = 0;
double xx, yy;
double start = (wx1 <= wx2) ? wx1 : wx2;
double end = (wx1 <= wx2) ? wx2 : wx1;
bbox(START, 0.0, 0.0, 0.0, 0.0);
bbox(ADD,x1, y1, x2, y2);
bbox(SET, 0.0, 0.0, 0.0, 0.0);
/* skip if nothing in viewport */
if(xctx->values[sweep_idx][xctx->npoints -1] > start) {
/* Process "npoints" simulation items
* p loop split repeated 2 timed (for xx and yy points) to preserve cache locality */
for(p = 0 ; p < xctx->npoints; p++) {
xx = xctx->values[sweep_idx][p];
if(xx > end) {
break;
}
if(xx >= start) {
if(first == -1) first = p;
/* Build poly x array. Translate from graph coordinates to {x1,y1} - {x2, y2} world. */
xarr[poly_npoints] = W_X(xx);
poly_npoints++;
}
bbox(START, 0.0, 0.0, 0.0, 0.0);
bbox(ADD,x1, y1, x2, y2);
bbox(SET, 0.0, 0.0, 0.0, 0.0);
/* skip if nothing in viewport */
if(xctx->values[sweep_idx][xctx->npoints -1] > start) {
/* Process "npoints" simulation items
* p loop split repeated 2 timed (for xx and yy points) to preserve cache locality */
for(p = 0 ; p < xctx->npoints; p++) {
xx = xctx->values[sweep_idx][p];
if(xx > end) {
break;
}
last = p;
if(first != -1) {
poly_npoints = 0;
for(p = first ; p < last; p++) {
yy = xctx->values[v][p];
/* Build poly y array. Translate from graph coordinates to {x1,y1} - {x2, y2} world. */
yarr[poly_npoints] = W_Y(yy);
poly_npoints++;
}
/* plot data */
drawpolygon(wave_color, 0, xarr, yarr, poly_npoints, 0, 0);
if(xx >= start) {
if(first == -1) first = p;
/* Build poly x array. Translate from graph coordinates to {x1,y1} - {x2, y2} world. */
xarr[poly_npoints] = W_X(xx);
poly_npoints++;
}
}
bbox(END, 0.0, 0.0, 0.0, 0.0);
last = p;
if(first != -1) {
poly_npoints = 0;
for(p = first ; p < last; p++) {
yy = xctx->values[v][p];
/* Build poly y array. Translate from graph coordinates to {x1,y1} - {x2, y2} world. */
yarr[poly_npoints] = W_Y(yy);
poly_npoints++;
}
/* plot data */
drawpolygon(wave_color, 0, xarr, yarr, poly_npoints, 0, 0);
}
}
wcnt++;
bbox(END, 0.0, 0.0, 0.0, 0.0);
}
wcnt++;
}
if(flags & 1) {
bbox(START, 0.0, 0.0, 0.0, 0.0);
bbox(ADD, rx1, ry1, rx2, ry2);
bbox(SET, 0.0, 0.0, 0.0, 0.0);
if((flags & 1) && !xctx->draw_window) {
if(!xctx->draw_window) {
XCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gctiled, xctx->xrect[0].x, xctx->xrect[0].y,
xctx->xrect[0].width, xctx->xrect[0].height, xctx->xrect[0].x, xctx->xrect[0].y);
}
bbox(END, 0.0, 0.0, 0.0, 0.0);
my_free(1403, &xarr);
my_free(1404, &yarr);
my_free(1391, &node);
my_free(1392, &color);
my_free(1408, &sweep);
}
my_free(1403, &xarr);
my_free(1404, &yarr);
my_free(1391, &node);
my_free(1392, &color);
my_free(1408, &sweep);
}
/* fill graph boxes with data from ngspice simulations */
@ -1873,41 +2001,43 @@ void draw_waves(int flags)
int bbox_set = 0;
int save_bbx1, save_bby1, save_bbx2, save_bby2;
/* save bbox data, since draw_waves() is called from draw() which may be called after a bbox(SET) */
if(xctx->sem) {
bbox_set = 1;
save_bbx1 = xctx->bbx1;
save_bby1 = xctx->bby1;
save_bbx2 = xctx->bbx2;
save_bby2 = xctx->bby2;
bbox(END, 0.0, 0.0, 0.0, 0.0);
}
#if HAS_CAIRO==1
cairo_save(xctx->cairo_ctx);
cairo_save(xctx->cairo_save_ctx);
cairo_select_font_face(xctx->cairo_ctx, "Sans-Serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_select_font_face(xctx->cairo_save_ctx, "Sans-Serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
#endif
c = 2; /* only rectangles on layer 2 (GRID) can embed graphs */
if(xctx->draw_single_layer==-1 || c == xctx->draw_single_layer) {
if(xctx->enable_layer[c]) for(i = 0; i < xctx->rects[c]; i++) {
xRect *r = &xctx->rect[c][i];
if(r->flags == 1) {
draw_graph(c, i, flags); /* draw data in each graph box */
if(schematic_waves_loaded()) {
if(xctx->sem) {
bbox_set = 1;
save_bbx1 = xctx->bbx1;
save_bby1 = xctx->bby1;
save_bbx2 = xctx->bbx2;
save_bby2 = xctx->bby2;
bbox(END, 0.0, 0.0, 0.0, 0.0);
}
#if HAS_CAIRO==1
cairo_save(xctx->cairo_ctx);
cairo_save(xctx->cairo_save_ctx);
cairo_select_font_face(xctx->cairo_ctx, "Sans-Serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_select_font_face(xctx->cairo_save_ctx, "Sans-Serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
#endif
c = 2; /* only rectangles on layer 2 (GRID) can embed graphs */
if(xctx->draw_single_layer==-1 || c == xctx->draw_single_layer) {
if(xctx->enable_layer[c]) for(i = 0; i < xctx->rects[c]; i++) {
xRect *r = &xctx->rect[c][i];
if(r->flags == 1) {
draw_graph(c, i, flags); /* draw data in each graph box */
}
}
}
}
#if HAS_CAIRO==1
cairo_restore(xctx->cairo_ctx);
cairo_restore(xctx->cairo_save_ctx);
#endif
/* restore previous bbox */
if(bbox_set) {
xctx->bbx1 = save_bbx1;
xctx->bby1 = save_bby1;
xctx->bbx2 = save_bbx2;
xctx->bby2 = save_bby2;
xctx->sem = 1;
bbox(SET, 0.0, 0.0, 0.0, 0.0);
#if HAS_CAIRO==1
cairo_restore(xctx->cairo_ctx);
cairo_restore(xctx->cairo_save_ctx);
#endif
/* restore previous bbox */
if(bbox_set) {
xctx->bbx1 = save_bbx1;
xctx->bby1 = save_bby1;
xctx->bbx2 = save_bbx2;
xctx->bby2 = save_bby2;
xctx->sem = 1;
bbox(SET, 0.0, 0.0, 0.0, 0.0);
}
}
}
@ -1959,11 +2089,10 @@ void draw(void)
}
if(xctx->enable_layer[c]) for(i=0;i<xctx->rects[c];i++) {
xRect *r = &xctx->rect[c][i];
if(c == 2 && r->flags == 1)
drawrect(c, ADD, r->x1, r->y1, r->x2, r->y2, 1);
else
if(c != 2 || r->flags != 1 /* || !schematic_waves_loaded() */) {
drawrect(c, ADD, r->x1, r->y1, r->x2, r->y2, r->dash);
filledrect(c, ADD, r->x1, r->y1, r->x2, r->y2);
filledrect(c, ADD, r->x1, r->y1, r->x2, r->y2);
}
}
if(xctx->enable_layer[c]) for(i=0;i<xctx->arcs[c];i++) {
xArc *a = &xctx->arc[c][i];

View File

@ -2003,8 +2003,14 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
{
cmd_found = 1;
if(argc > 2) {
free_rawfile();
read_rawfile(argv[2]);
if(schematic_waves_loaded()) {
free_rawfile();
} else {
free_rawfile();
read_rawfile(argv[2]);
}
}
Tcl_ResetResult(interp);
}

View File

@ -426,6 +426,7 @@ void alloc_xschem_data(const char *top_path)
xctx->values = NULL;
xctx->nvars = 0;
xctx->npoints = 0;
xctx->datasets = 0;
xctx->raw_schname = NULL;
xctx->wires = 0;
xctx->instances = 0;

View File

@ -330,6 +330,10 @@ do { \
#define INT_WIDTH(x) ( (int)(x) == 0 ? 1 : (int)(x) )
#define INT_BUS_WIDTH(x) ( (int)( (BUS_WIDTH) * (x) ) == 0 ? 1 : (int)( (BUS_WIDTH) * (x) ) )
/* set do double if you need more precision at the expense of memory */
#define RAW_FLOAT float
typedef struct
{
unsigned short type;
@ -688,9 +692,10 @@ typedef struct {
int undo_initialized;
/* read raw files (draw.c) */
char **names;
double **values;
RAW_FLOAT **values;
int nvars;
int npoints;
int datasets;
struct int_hashentry **raw_table;
char *raw_schname;
/* */
@ -889,6 +894,7 @@ extern char cli_opt_netlist_dir[PATH_MAX];
extern Xschem_ctx *xctx;
/* FUNCTIONS */
extern int schematic_waves_loaded(void);
extern void calc_graph_area(int c, int i, double *x1, double *y1,double *x2, double *y2,
double *marginx,double *marginy);
extern void draw_graph(int c, int i, int flags);
@ -903,7 +909,7 @@ extern void create_plot_cmd(void);
extern void set_modify(int mod);
extern void dbg(int level, char *fmt, ...);
extern unsigned int hash_file(const char *f, int skip_path_lines);
extern void here(int i);
extern void here(double i);
extern void print_version(void);
extern int set_netlist_dir(int force, char *dir);
extern void netlist_options(int i);

View File

@ -14,7 +14,7 @@ L 18 900 -580 910 -580 {}
L 18 880 -530 900 -580 {}
L 18 880 -530 880 -450 {}
L 18 900 -580 900 -400 {}
B 2 1040 -770 1510 -570 {flags=1
B 2 1200 -860 1880 -550 {flags=1
y1 = -60
y2 = 60
divy = 12
@ -22,8 +22,8 @@ x1=0
x2=0.03
divx=10
node="v(outp) v(outm) v(vpp) v(vnn) v(x1.vboost) v(x0.vboost)"
color="4 5 6 12 8 10"}
B 2 1040 -550 1510 -360 {flags=1
color="4 5 6 12 8 10" unitx=m}
B 2 1200 -530 1880 -340 {flags=1
y1 = 0
y2 = 12
divy = 6
@ -31,7 +31,16 @@ x1=0
x2=0.03
divx=10
node="i(v.x1.vu) i(v.x0.vu) i(v.x1.vd) i(v.x0.vd)"
color="11 12 13 14"}
color="11 12 13 14" unitx=m}
B 2 1200 -330 1880 -140 {flags=1
y1 = 0
y2 = .05
divy = 5
x1=0
x2=0.03
divx=10
node="i(v.x1.v3)"
color="11 12 13 14" unitx=m unity=m}
T {actual value
50u} 400 -820 0 0 0.4 0.4 {}
T {actual value
@ -57,7 +66,7 @@ each with different bias points these
annotator dinamically show the correct
data.} 780 -830 0 0 0.2 0.2 {layer=4}
T {Select one or more graphs (and no other objects)
and use arrow keys to zoom / pan waveforms} 1060 -830 0 0 0.3 0.3 {}
and use arrow keys to zoom / pan waveforms} 1060 -940 0 0 0.3 0.3 {}
N 150 -1220 150 -1200 {lab=#net1}
N 150 -1080 150 -1060 {lab=#net2}
N 360 -1140 370 -1140 {lab=VSS}
@ -309,7 +318,7 @@ tclcommand="textwindow $netlist_dir/[file tail [file rootname [ xschem get schna
}
C {spice_probe.sym} 360 -1220 0 0 {name=p45 analysis=tran voltage=0.0000e+00}
C {spice_probe.sym} 360 -1060 0 0 {name=p46 analysis=tran voltage=0.0000e+00}
C {launcher.sym} 1115 -875 0 0 {name=h5
C {launcher.sym} 1115 -985 0 0 {name=h5
descr="Ctrl-Left-Click on arrow
to load waveforms"
tclcommand="xschem raw_read $netlist_dir/[file rootname [xschem get current_name]].raw"}

View File

@ -42,27 +42,27 @@ B 2 1110 -950 1530 -800 {flags=1
y1 = 0
y2 = 20
divy = 10
x1=3.388e-21
x1=0
x2=0.0002
divx=8
divx=9
node="v(led) v(sw)"
color="11 18"}
color="11 18" unitx=m subdivx=4}
B 2 1110 -790 1530 -660 {flags=1
y1 = 0
y2 = 20
divy = 10
x1=3.388e-21
x1=0
x2=0.0002
divx=8
node="v(panel)"}
node="v(panel)" unitx=m}
B 2 1110 -650 1530 -520 {flags=1
y1 = 0
y2 = 4
divy = 8
x1=3.388e-21
x1=0
x2=0.0002
divx=8
node="i(vsw)" color=12}
node="i(vsw)" color=12 unitx=m}
B 18 45 -850 300 -665 {}
A 5 300 -850 5.590169943749475 243.434948822922 360 {fill=true}
P 7 6 375 -665 320 -821.25 315 -835 302.5 -850 290 -855 45 -865 {}

View File

@ -27,186 +27,136 @@ L 8 1150 -160 1180 -160 {}
L 8 1180 -160 1180 -120 {}
L 8 1180 -120 1300 -120 {}
L 8 820 -120 950 -120 {}
B 2 1870 -810 2380 -710 {flags=1
y1 = 0
y2 = 2
divy = 4
x1=2.05e-07
x2=2.55e-07
divx=10
node="v(ldcp) v(ldprech)"
color="3 11"}
B 2 1870 -700 2380 -600 {flags=1
y1 = 0
y2 = 2
divy = 4
x1=2.05e-07
x2=2.55e-07 divx=10
node="v(lden)"
color=12}
B 2 1870 -370 2380 -270 {flags=1
y1 = 0
y2 = 2
divy = 4
x1=2.05e-07
x2=2.55e-07
divx=10
node="v(ldq[11])"}
B 2 1870 -590 2380 -490 {flags=1
y1 = 0
y2 = 2
divy = 4
x1=2.05e-07
x2=2.55e-07
divx=10
node="v(ldsal)"
color=8}
B 2 1870 -480 2380 -380 {flags=1
y1 = 0
y2 = 2
divy = 4
x1=2.05e-07
x2=2.55e-07
divx=10
node="v(ldq[12])"}
B 2 1870 -1010 2380 -820 {flags=1
y1 = 0
y2 = 2
divy = 5
x1=2.05e-07
x2=2.55e-07
divx=10
node="v(ldyms[6]) v(ldyms[9]) v(ldcp)"
color="4 7 12"}
B 2 2490 -1240 3640 -1160 {flags=1
B 2 1860 -1180 3010 -1100 {flags=1
y1 = 0
y2 = 1
divy = 1
x1=0
x2=4.8e-07 divx=10
x1=1.26503e-07
x2=1.66157e-07 divx=10
node="
v(ldbl[0]) v(ldbl[16]) v(ldbl[32])
v(ldbl[1]) v(ldbl[17]) v(ldbl[33])
v(ldbl[2]) v(ldbl[18]) v(ldbl[34])
"
color="8 9 10 11 12 13 14 15 16 17 18"}
B 2 2490 -1150 3640 -1070 {flags=1
color="8 9 10 11 12 13 14 15 16 17 18" unitx=n}
B 2 1860 -1090 3010 -1010 {flags=1
y1 = 0
y2 = 2
y2 = 1.5
divy = 1
x1=0
x2=4.8e-07 divx=10
x1=1.26503e-07
x2=1.66157e-07 divx=10
node="
v(ldl1x[0]) v(ldl1x[1]) v(ldl1x[2]) v(ldl1x[3])
"
color="6 7 8 9 10 11 12 13"}
B 2 2490 -1060 3640 -980 {flags=1
color="6 7 8 9 10 11 12 13" unitx=n}
B 2 1860 -1000 3010 -920 {flags=1
y1 = 0
y2 = 2
y2 = 1.5
divy = 1
x1=0
x2=4.8e-07 divx=10
x1=1.26503e-07
x2=1.66157e-07 divx=10
node="v(lda[3])"
color=12}
B 2 2490 -1550 3640 -1340 {flags=1
color=12 unitx=n subdivy=2}
B 2 1860 -1490 3010 -1280 {flags=1
y1 = 0
y2 = 2
divy = 4
x1=-6.617e-24
x2=4.8e-07 divx=10
x1=1.26503e-07
x2=1.66157e-07 divx=10
node="v(ldcp) v(ldyms[4]) v(ldyms[5]) v(ldyms[6]) v(ldyms[7])"
color=6\\ 12\\ 13\\ 14\\ 15}
B 2 2490 -970 3640 -890 {flags=1
color=6\\ 12\\ 13\\ 14\\ 15 unitx=n}
B 2 1860 -910 3010 -830 {flags=1
y1 = 0
y2 = 2
y2 = 1.5
subdivy=2
divy = 1
x1=0
x2=4.8e-07 divx=10
x1=1.26503e-07
x2=1.66157e-07 divx=10
node="v(ldl1x[0])"
color=4}
B 2 2490 -790 3640 -710 {flags=1
y1 = 0
y2 = 2
color=4 unitx=n}
B 2 1860 -730 3010 -650 {flags=1
y1 = -0.4
y2 = 1.5
divy = 1
x1=0
x2=4.8e-07 divx=10
x1=1.26503e-07
x2=1.66157e-07 divx=10
node="v(ldprech)"
color=4}
B 2 2490 -700 3640 -620 {flags=1
color=4 unitx=n subdivy=2}
B 2 1860 -640 3010 -560 {flags=1
y1 = 0
y2 = 2
y2 = 1.5
divy = 1
x1=0
x2=4.8e-07 divx=10
x1=1.26503e-07
x2=1.66157e-07 divx=10
node="v(lden) v(ldcp)"
color=12\\ 18}
B 2 2490 -610 3640 -530 {flags=1
color=12\\ 18 unitx=n subdivy=2}
B 2 1860 -550 3010 -470 {flags=1
y1 = 0
y2 = 2
y2 = 1.5
divy = 1
x1=0
x2=4.8e-07 divx=10
x1=1.26503e-07
x2=1.66157e-07 divx=10
node="
v(ldwl[0]) v(ldwl[1]) v(ldwl[2]) v(ldwl[3])
v(ldwl[4]) v(ldwl[5]) v(ldwl[6]) v(ldwl[8])
v(ldwl[7])"
color=12\\ 15\\ 16\\ 17\\ 18\\ 19\\ 11\\ 7\\ 4}
B 2 2490 -520 3640 -440 {flags=1
color=12\\ 15\\ 16\\ 17\\ 18\\ 19\\ 11\\ 7\\ 4 unitx=n subdivy=2}
B 2 1860 -460 3010 -380 {flags=1
y1 = 0
y2 = 2
y2 = 1
divy = 1
x1=0
x2=4.8e-07 divx=10
x1=1.26503e-07
x2=1.66157e-07 divx=10
node="v(ldymsref)"
color=3}
B 2 2490 -430 3640 -350 {flags=1
color=3 unitx=n subdivy=4}
B 2 1860 -370 3010 -290 {flags=1
y1 = 0
y2 = 2
y2 = 1.5
divy = 1
x1=0
x2=4.8e-07 divx=10
x1=1.26503e-07
x2=1.66157e-07 divx=10
node="v(ldoe)"
color=4}
B 2 2490 -340 3640 -260 {flags=1
color=4 unitx=n subdivy=2}
B 2 1860 -280 3010 -200 {flags=1
y1 = 0
y2 = 2
y2 = 1.5
divy = 1
x1=0
x2=4.8e-07 divx=10
x1=1.26503e-07
x2=1.66157e-07 divx=10
node="v(lden)"
color=4}
B 2 2490 -250 3640 -170 {flags=1
color=4 unitx=n subdivy=2}
B 2 1860 -190 3010 -110 {flags=1
y1 = 0
y2 = 2
y2 = 1.5
divy = 1
x1=0
x2=4.8e-07 divx=10
x1=1.26503e-07
x2=1.66157e-07 divx=10
node="v(lden) v(ldprech)"
color=12\\ 16}
B 2 2490 -160 3640 -80 {flags=1
color=12\\ 16 unitx=n subdivy=2}
B 2 1860 -100 3010 -20 {flags=1
y1 = 0
y2 = 2
y2 = 1.5
divy = 1
x1=0
x2=4.8e-07 divx=10
x1=1.26503e-07
x2=1.66157e-07 divx=10
node="v(lden) v(ldcp)"
color=12\\ 5}
B 2 2490 -880 3640 -800 {flags=1
color=12\\ 5 unitx=n subdivy=2}
B 2 1860 -820 3010 -740 {flags=1
y1 = 0
y2 = 2
y2 = 1.5
divy = 1
x1=0
x2=4.8e-07 divx=10
x1=1.26503e-07
x2=1.66157e-07 divx=10
node="v(ldl1x[1])"
color=4}
B 2 2490 -1330 3640 -1250 {flags=1
color=4 unitx=n subdivy=2}
B 2 1860 -1270 3010 -1190 {flags=1
y1 = 0
y2 = 2
y2 = 1.5
divy = 1
x1=0
x2=4.8e-07 divx=10
x1=1.26503e-07
x2=1.66157e-07 divx=10
node="v(lden) v(ldprech)"
color=4\\ 6}
color=4\\ 6 unitx=n}
B 7 950 -250 980 -80 {}
B 7 1150 -250 1180 -80 {}
B 21 10 -970 240 -750 {}
@ -218,7 +168,7 @@ T {was: vss} 880 -980 0 0 0.4 0.4 {}
T {16KB ROM Macrocell
16 bit Data I/O x 8KWords} 210 -1120 0 0 0.7 0.7 {}
T {Select one or more graphs (and no other objects)
and use arrow keys to zoom / pan waveforms} 1880 -1080 0 0 0.3 0.3 {}
and use arrow keys to zoom / pan waveforms} 1460 -1100 0 0 0.3 0.3 {}
N 150 -580 150 -560 {lab=vss}
N 150 -420 150 -400 {lab=vss}
N 10 -270 10 -250 {lab=vss}
@ -409,7 +359,7 @@ C {lab_pin.sym} 1670 -740 0 0 {name=l2 lab=LDWL[16:0]}
C {spice_probe.sym} 1670 -740 0 0 {name=p46 analysis=tran}
C {lab_pin.sym} 1670 -790 0 0 {name=l4 lab=LDBL[0,16,32,1,17,33,2,18,34]}
C {spice_probe.sym} 1670 -790 0 0 {name=p91 analysis=tran}
C {launcher.sym} 1925 -1115 0 0 {name=h5
C {launcher.sym} 1565 -1135 0 0 {name=h5
descr="Ctrl-Left-Click on arrow
to load waveforms"
tclcommand="xschem raw_read $netlist_dir/[file rootname [xschem get current_name]].raw"}