diff --git a/src/actions.c b/src/actions.c index 2ee18e76..a4b3df33 100644 --- a/src/actions.c +++ b/src/actions.c @@ -648,10 +648,10 @@ void attach_labels_to_inst(int interactive) /* offloaded from callback.c 201710 xRect *rct; char *labname=NULL; char *prop=NULL; /* 20161122 overflow safe */ - const char symname_pin[] = "devices/lab_pin.sym"; - const char symname_wire[] = "devices/lab_wire.sym"; - const char symname_pin2[] = "lab_pin.sym"; - const char symname_wire2[] = "lab_wire.sym"; + const char *symname_pin = "devices/lab_pin.sym"; + const char *symname_wire = "devices/lab_wire.sym"; + const char *symname_pin2 = "lab_pin.sym"; + const char *symname_wire2 = "lab_wire.sym"; char *type=NULL; int dir; int k,ii, skip; @@ -1479,8 +1479,8 @@ void set_viewport_size(int w, int h, double lw) { xctx->xrect[0].x = 0; xctx->xrect[0].y = 0; - xctx->xschem_w = xctx->xrect[0].width = w; - xctx->xschem_h = xctx->xrect[0].height = h; + xctx->xrect[0].width = w; + xctx->xrect[0].height = h; xctx->areax2 = w+2*INT_WIDTH(lw); xctx->areay2 = h+2*INT_WIDTH(lw); xctx->areax1 = -2*INT_WIDTH(lw); @@ -1496,8 +1496,8 @@ void save_restore_zoom(int save) static double savexor, saveyor, savezoom, savelw; /* safe to keep even with multiple schematics */ if(save) { - savew = xctx->xschem_w; - saveh = xctx->xschem_h; + savew = xctx->xrect[0].width; + saveh = xctx->xrect[0].height; savelw = xctx->lw; savexor = xctx->xorigin; saveyor = xctx->yorigin; @@ -1505,8 +1505,8 @@ void save_restore_zoom(int save) } else { xctx->xrect[0].x = 0; xctx->xrect[0].y = 0; - xctx->xschem_w = xctx->xrect[0].width = savew; - xctx->xschem_h = xctx->xrect[0].height = saveh; + xctx->xrect[0].width = savew; + xctx->xrect[0].height = saveh; xctx->areax2 = savew+2*INT_WIDTH(savelw); xctx->areay2 = saveh+2*INT_WIDTH(savelw); xctx->areax1 = -2*INT_WIDTH(savelw); @@ -2305,6 +2305,14 @@ double my_round(double a) return (a > 0.0) ? floor(a + 0.5) : (a < 0.0) ? ceil(a - 0.5) : a; } +double round_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 my_round(x / scale) * scale; +} + int place_text(int draw_text, double mx, double my) { char *txt; diff --git a/src/callback.c b/src/callback.c index 2655020b..1d2b9a79 100644 --- a/src/callback.c +++ b/src/callback.c @@ -21,6 +21,20 @@ */ #include "xschem.h" +static int waves_selected() +{ + int n, c, i; + rebuild_selected_array(); + if(xctx->ui_state != SELECTION || !xctx->lastsel) return 0; + for(i=0; ilastsel; i++) { + c = xctx->sel_array[i].col; + if(xctx->sel_array[i].type == xRECT && c == 2) { + n = xctx->sel_array[i].n; + if(xctx->rect[c][n].flags != 1) return 0; + } else return 0; + } + return 1; +} void redraw_w_a_l_r_p_rubbers(void) { @@ -136,6 +150,115 @@ void start_wire(double mx, double my) new_wire(PLACE,xctx->mousex_snap, xctx->mousey_snap); } + +/* process user input (arrow keys for now) when only graphs are selected */ +static int waves_callback(int event, int mx, int my, KeySym key, int button, int aux, int state) +{ + double wx1 = -2e-6; + double wy1 = -1; + double wx2 = 8e-6; + double wy2 = 4; + int divisx = 10; + int divisy = 5; + const char *val; + xRect bb; + int n, c, i; + for(i=0; ilastsel; i++) { + c = xctx->sel_array[i].col; + /* process only graph boxes */ + if(xctx->sel_array[i].type == xRECT && c == 2) { + n = xctx->sel_array[i].n; + 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); + val = get_tok_value(xctx->rect[c][n].prop_ptr,"divy",0); + if(val[0]) divisy = 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); + if(val[0]) wy1 = atof(val); + val = get_tok_value(xctx->rect[c][n].prop_ptr,"x2",0); + if(val[0]) wx2 = atof(val); + val = get_tok_value(xctx->rect[c][n].prop_ptr,"y2",0); + if(val[0]) wy2 = atof(val); + dbg(1, "%g %g %g %g - %d %d\n", wx1, wy1, wx2, wy2, divisx, divisy); + } + if(key == XK_Left) { + char s[30]; + double delta = (wx2 - wx1) / divisx; + double x1, x2; + x1 = wx1 - delta; + x2 = wx2 - delta; + my_snprintf(s, S(s), "%g", x1); + 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", x2); + my_strdup(1396, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s)); + } + if(key == XK_Right) { + char s[30]; + double delta = (wx2 - wx1) / divisx; + double x1, x2; + x1 = wx1 + delta; + x2 = wx2 + delta; + my_snprintf(s, S(s), "%g", x1); + 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", x2); + my_strdup(1398, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s)); + } + if(key == XK_Down) { + char s[30]; + double delta = (wx2 - wx1); + double x2; + x2 = wx2 + delta; + my_snprintf(s, S(s), "%g", x2); + my_strdup(1399, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s)); + } + if(key == XK_Up) { + char s[30]; + double delta = (wx2 - wx1)/ 2.0; + double x2; + if(wx2 - delta != wx1) { + x2 = wx2 - delta; + my_snprintf(s, S(s), "%g", x2); + my_strdup(1400, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s)); + } + } + } + } + + calc_drawing_bbox(&bb, 1); /* selection bbox */ + bbox(START, 0.0 , 0.0 , 0.0 , 0.0); + bbox(ADD, bb.x1, bb.y1, bb.x2, bb.y2); + bbox(SET , 0.0 , 0.0 , 0.0 , 0.0); + if(xctx->draw_pixmap) + XFillRectangle(display, xctx->save_pixmap, xctx->gc[BACKLAYER], xctx->areax1, xctx->areay1, + xctx->areaw, xctx->areah); + if(xctx->draw_window) + XFillRectangle(display, xctx->window, xctx->gc[BACKLAYER], xctx->areax1, xctx->areay1, + xctx->areaw, xctx->areah); + drawgrid(); + draw_waves(); + for(i=0; ilastsel; i++) { + c = xctx->sel_array[i].col; + /* repaint graph borders */ + if(xctx->sel_array[i].type == xRECT && c == 2) { + xRect *r; + n = xctx->sel_array[i].n; + r = &xctx->rect[c][n]; + if(c == 2 && r->flags == 1) + drawrect(c, ADD, r->x1, r->y1, r->x2, r->y2, 1); + } + } + 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); + draw_selection(xctx->gc[SELLAYER], 0); + return 0; +} + /* main window callback */ /* mx and my are set to the mouse coord. relative to window */ int callback(const char *winpath, int event, int mx, int my, KeySym key, @@ -704,6 +827,10 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key, } if(key==XK_Right) /* left */ { + if(waves_selected()) { + waves_callback(event, mx, my, key, button, aux, state); + break; + } xctx->xorigin+=-CADMOVESTEP*xctx->zoom; draw(); redraw_w_a_l_r_p_rubbers(); @@ -711,6 +838,10 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key, } if(key==XK_Left) /* right */ { + if(waves_selected()) { + waves_callback(event, mx, my, key, button, aux, state); + break; + } xctx->xorigin-=-CADMOVESTEP*xctx->zoom; draw(); redraw_w_a_l_r_p_rubbers(); @@ -718,6 +849,10 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key, } if(key==XK_Down) /* down */ { + if(waves_selected()) { + waves_callback(event, mx, my, key, button, aux, state); + break; + } xctx->yorigin+=-CADMOVESTEP*xctx->zoom; draw(); redraw_w_a_l_r_p_rubbers(); @@ -725,6 +860,10 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key, } if(key==XK_Up) /* up */ { + if(waves_selected()) { + waves_callback(event, mx, my, key, button, aux, state); + break; + } xctx->yorigin-=-CADMOVESTEP*xctx->zoom; draw(); redraw_w_a_l_r_p_rubbers(); @@ -1464,7 +1603,10 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key, } if(key=='f' && state == 0 ) /* full zoom */ { - zoom_full(1, 0, 1, 0.97); + if(xctx->ui_state == SELECTION) + zoom_full(1, 1, 3, 0.97); + else + zoom_full(1, 0, 1, 0.97); break; } if((key=='z' && state==ControlMask)) /* zoom out */ diff --git a/src/clip.c b/src/clip.c index 5c545b4e..397e9d92 100644 --- a/src/clip.c +++ b/src/clip.c @@ -28,13 +28,13 @@ #define DOWN 4 #define RIGHT 2 #define LEFT 1 -static int outcode(double x,double y) +static int outcode(double x,double y, double sx1, double sy1, double sx2, double sy2) { register int code=0; - if(y > xctx->xschem_h) code = UP; - else if(y < 0) code = DOWN; - if(x > xctx->xschem_w) code |= RIGHT; - else if(x < 0) code |= LEFT; + if(y > sy2) code = UP; + else if(y < sy1) code = DOWN; + if(x > sx2) code |= RIGHT; + else if(x < sx1) code |= LEFT; return code; } @@ -42,9 +42,14 @@ int clip( double *xa,double *ya,double *xb,double *yb) { int outa, outb,outpoint; double x,y; + double sx1, sy1, sx2, sy2; - outa=outcode(*xa, *ya); - outb=outcode(*xb, *yb); + sx1 = xctx->xrect[0].x; + sy1 = xctx->xrect[0].y; + sx2 = sx1 + xctx->xrect[0].width; + sy2 = sy1 + xctx->xrect[0].height; + outa=outcode(*xa, *ya, sx1, sy1, sx2, sy2); + outb=outcode(*xb, *yb, sx1, sy1, sx2, sy2); while(1) { if(!(outa | outb)) return 1; /* line is all inside! */ @@ -53,18 +58,18 @@ int clip( double *xa,double *ya,double *xb,double *yb) { outpoint=outa? outa:outb; if(UP & outpoint) - {x= *xa + (*xb-*xa) * (xctx->xschem_h - *ya) / (*yb - *ya); y = xctx->xschem_h;} + {x= *xa + (*xb-*xa) * (sy2 - *ya) / (*yb - *ya); y = sy2;} else if(DOWN & outpoint) - {x= *xa + (*xb-*xa) * (0 - *ya) / (*yb - *ya); y = 0;} + {x= *xa + (*xb-*xa) * (sy1 - *ya) / (*yb - *ya); y = sy1;} else if(RIGHT & outpoint) - {y= *ya + (*yb-*ya) * (xctx->xschem_w - *xa) / (*xb - *xa); x = xctx->xschem_w;} + {y= *ya + (*yb-*ya) * (sx2 - *xa) / (*xb - *xa); x = sx2;} /* else if(LEFT & outpoint) */ else - {y= *ya + (*yb-*ya) * (0 - *xa) / (*xb - *xa); x = 0;} + {y= *ya + (*yb-*ya) * (sx1 - *xa) / (*xb - *xa); x = sx1;} if(outpoint == outa) - {*xa=x; *ya=y; outa=outcode(*xa, *ya);} + {*xa=x; *ya=y; outa=outcode(*xa, *ya, sx1, sy1, sx2, sy2);} else - {*xb=x; *yb=y; outb=outcode(*xb, *yb);} + {*xb=x; *yb=y; outb=outcode(*xb, *yb, sx1, sy1, sx2, sy2);} } } } diff --git a/src/draw.c b/src/draw.c index 1d0cbf0f..afaa7d81 100644 --- a/src/draw.c +++ b/src/draw.c @@ -669,13 +669,15 @@ void drawgrid() delta=tclgetdoublevar("cadgrid")*xctx->mooz; while(delta < CADGRIDTHRESHOLD) delta*=CADGRIDMULTIPLY; /* <-- to be improved,but works */ x = xctx->xorigin*xctx->mooz; y = xctx->yorigin*xctx->mooz; - if(y>xctx->areay1 && y < xctx->areay2) { - if(xctx->draw_window) XDrawLine(display, xctx->window, xctx->gc[GRIDLAYER],xctx->areax1+1,(int)y, xctx->areax2-1, (int)y); + if(y > xctx->areay1 && y < xctx->areay2) { + if(xctx->draw_window) + XDrawLine(display, xctx->window, xctx->gc[GRIDLAYER],xctx->areax1+1,(int)y, xctx->areax2-1, (int)y); if(xctx->draw_pixmap) XDrawLine(display, xctx->save_pixmap, xctx->gc[GRIDLAYER],xctx->areax1+1,(int)y, xctx->areax2-1, (int)y); } - if(x>xctx->areax1 && x < xctx->areax2) { - if(xctx->draw_window) XDrawLine(display, xctx->window, xctx->gc[GRIDLAYER],(int)x,xctx->areay1+1, (int)x, xctx->areay2-1); + if(x > xctx->areax1 && x < xctx->areax2) { + if(xctx->draw_window) + XDrawLine(display, xctx->window, xctx->gc[GRIDLAYER],(int)x,xctx->areay1+1, (int)x, xctx->areay2-1); if(xctx->draw_pixmap) XDrawLine(display, xctx->save_pixmap, xctx->gc[GRIDLAYER],(int)x,xctx->areay1+1, (int)x, xctx->areay2-1); } @@ -1470,55 +1472,393 @@ void drawtemprect(GC gc, int what, double rectx1,double recty1,double rectx2,dou } } -/* boiler plate code for future draw waves in xschem */ -void draw_waves(int c, int i) +/* read the binary portion of a ngspice raw simulation file + * data layout in memory arranged to maximize cache locality + * when looking up data + */ +void read_binary_block(FILE *fd) { - double x1, y1, x2, y2, w, h; - double txtsize; - double txtx, txty; - char dash_arr[2] = {3, 3}; - double dash_size; - const double margin = 0.05; + int p, v; + double *tmp; + tmp = my_calloc(1405, xctx->nvars, sizeof(double *)); + /* allocate storage for binary block */ + xctx->values = my_calloc(118, xctx->nvars, sizeof(double *)); + for(p = 0 ; p < xctx->nvars; p++) { + xctx->values[p] = my_calloc(372, xctx->npoints, sizeof(double)); + } + /* read binary block */ + for(p = 0; p < xctx->npoints; p++) { + if(fread(tmp, sizeof(double), xctx->nvars, fd) != xctx->nvars) { + dbg(0, "Warning: binary block is not of correct size\n"); + } + for(v = 0; v < xctx->nvars; v++) { + xctx->values[v][p] = tmp[v]; + } + } + my_free(1406, &tmp); +} - x1 = xctx->rect[c][i].x1; - y1 = xctx->rect[c][i].y1; - x2 = xctx->rect[c][i].x2; - y2 = xctx->rect[c][i].y2; +/* parse ascii raw header section: + * returns: 1 if dataset and variables were read. + * 0 if transient sim dataset not found + * -1 on EOF + * Typical ascii header of raw file looks like: + * + * Title: **.subckt poweramp + * Date: Thu Nov 21 18:36:25 2019 + * Plotname: Transient Analysis + * Flags: real + * No. Variables: 158 + * No. Points: 90267 + * Variables: + * 0 time time + * 1 v(net1) voltage + * 2 v(vss) voltage + * ... + * ... + * 155 i(v.x1.vd) current + * 156 i(v0) current + * 157 i(v1) current + * Binary: + */ +int read_dataset(FILE *fd) +{ + int variables = 0, i, done_points = 0; + char line[PATH_MAX], varname[PATH_MAX]; + char *ptr; + int transient = 0; + int dc = 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(variables) { + sscanf(line, "%d %s", &i, varname); /* read index and name of saved waveform */ + xctx->names[i] = my_malloc(415, strlen(varname) + 1); + strcpy(xctx->names[i], varname); + /* use hash table to store index number of variables */ + int_hash_lookup(xctx->raw_table, xctx->names[i], i, XINSERT_NOREPLACE); + dbg(1, "names[%d] = %s\n", i, xctx->names[i]); + } + if(!strncmp(line, "Variables:", 10)) { + variables = 1; + xctx->names = my_calloc(426, xctx->nvars, sizeof(char *)); + } + } + if(!strncmp(line, "No. of Data Rows :", 18)) { + sscanf(line, "No. of Data Rows : %d", &xctx->npoints); + done_points = 1; + } + if(!strncmp(line, "No. Variables:", 14)) { + sscanf(line, "No. Variables: %d", &xctx->nvars); + } + if(!strncmp(line, "Plotname: Transient Analysis", 28)) { + transient = 1; + } + if(!strncmp(line, "Plotname: DC transfer characteristic", 36)) { + dc = 1; + } + if(!done_points && !strncmp(line, "No. Points:", 11)) { + sscanf(line, "No. Points: %d", &xctx->npoints); + } + } + if(!ptr) { + dbg(1, "EOF found\n"); + variables = -1; /* EOF */ + } + dbg(1, "npoints=%d, nvars=%d\n", xctx->npoints, xctx->nvars); + if(variables == 1) { + read_binary_block(fd); + } else if(variables == 0) { + dbg(1, "seeking past binary block\n"); + fseek(fd, xctx->nvars * xctx->npoints * sizeof(double), SEEK_CUR); /* skip binary block */ + } + return variables; +} + +void free_rawfile(void) +{ + int i; + + if(!xctx->values) return; + for(i = 0 ; i < xctx->nvars; i++) { + my_free(510, &xctx->names[i]); + } + for(i = 0 ; i < xctx->nvars; i++) { + my_free(512, &xctx->values[i]); + } + my_free(528, &xctx->values); + my_free(968, &xctx->names); + my_free(1393, &xctx->raw_schname); + xctx->npoints = 0; + xctx->nvars = 0; + int_hash_free(xctx->raw_table); + draw(); +} + +/* read a ngspice raw file (with data portion in binary format) */ +int read_rawfile(const char *f) +{ + int res; + FILE *fd; + fd = fopen(f, "r"); + if(fd) for(;;) { + if((res = read_dataset(fd)) == 1) { + break; + } else if(res == -1) { /* EOF */ + dbg(0, "read_rawfile(): dataset not found in raw file\n"); + return EXIT_FAILURE; + } + } else { + dbg(0, "read_rawfile(): failed to open file for reading\n"); + return EXIT_FAILURE; + } + if(fd) fclose(fd); + dbg(0, "Raw file data read\n"); + my_strdup2(1394, &xctx->raw_schname, xctx->current_name); + draw(); + return EXIT_SUCCESS; +} + + +/* 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)) */ +#define W_X(x) (cx * (x) + dx) +#define W_Y(y) (cy * (y) + dy) +void draw_graph(int c, int i) +{ + /* container box */ + double rx1, ry1, rx2, ry2, rw, rh; + /* graph box (smaller due to margins) */ + double x1, y1, x2, y2, w, h; + /* graph coordinate, some defaults */ + double wx1 = -2e-6; + double wy1 = -1; + double wx2 = 8e-6; + double wy2 = 4; + double marginx = 20; /* will be recalculated later */ + double marginy = 20; /* will be recalculated later */ + double wx, wy; /* point coordinates in graph */ + double cx, dx, cy, dy; + double dash_sizex, dash_sizey; + int divisx = 10; + int divisy = 5; + int j, wave_color = 5; + char lab[30]; + const char *val; + char *node = NULL, *color = NULL; + double txtsizelab, txtsizey, txtsizex, tmp; + struct int_hashentry *entry; + + /* container ( ebnedding rectangle) coordinates */ + rx1 = xctx->rect[c][i].x1; + ry1 = xctx->rect[c][i].y1; + rx2 = xctx->rect[c][i].x2; + ry2 = xctx->rect[c][i].y2; + rw = (rx2 - rx1); + rh = (ry2 - ry1); + + /* set margins */ + tmp = rw * 0.05; + marginx = tmp < 50 ? 50 : tmp; + tmp = rh * 0.1; + marginy = tmp < 20 ? 20 : tmp; + + /* calculate graph bounding box (container - margin) + * This is the box where plot is done */ + x1 = rx1 + marginx; + x2 = rx2 - marginx/1.3; + y1 = ry1 + marginy; + y2 = ry2 - marginy; w = (x2 - x1); h = (y2 - y1); - /* set a margin */ - x1 += w * margin; - x2 -= w * margin; - y1 += h * margin; - y2 -= h * margin; - w = (x2 - x1); - h = (y2 - y1); - - dash_size = (x2 - x1) * xctx->mooz / 80.0; - dash_arr[0] = dash_arr[1] = dash_size > 127.0 ? 127 : dash_size; - txtx = (x2 + x1) / 2; - txty = (y2 + y1) / 2; - txtsize = (x2 - x1) / 400; + + /* get variables to plot, x/y range, grid info etc */ + val = get_tok_value(xctx->rect[c][i].prop_ptr,"divx",0); + if(val[0]) divisx = atoi(val); + val = get_tok_value(xctx->rect[c][i].prop_ptr,"divy",0); + if(val[0]) divisy = atoi(val); + val = get_tok_value(xctx->rect[c][i].prop_ptr,"x1",0); + if(val[0]) wx1 = atof(val); + val = get_tok_value(xctx->rect[c][i].prop_ptr,"y1",0); + if(val[0]) wy1 = atof(val); + val = get_tok_value(xctx->rect[c][i].prop_ptr,"x2",0); + if(val[0]) wx2 = atof(val); + val = get_tok_value(xctx->rect[c][i].prop_ptr,"y2",0); + if(val[0]) wy2 = atof(val); + + /* cache coefficients for faster graph coord transformations */ + cx = (x2 - x1) / (wx2 - wx1); + dx = x1 - wx1 * cx; + cy = (y1 - y2) / (wy2 - wy1); + dy = y2 - wy1 * cy; + + /* calculate dash length for grid lines */ + dash_sizex = 800 * xctx->mooz / 300.0; + 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 = 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 ; + tmp = marginx / 200; + if(tmp < txtsizey) txtsizey = tmp; + + txtsizex = w / divisx / 300; + tmp = marginy / 110; + if(tmp < txtsizex) txtsizex = tmp; + + txtsizelab = marginy / 100; + + /* background */ + filledrect(0, NOW, x1, y1, x2, y2); + /* vertical grid lines */ + for(j = 0; j <= divisx; j++) { + wx = wx1 + j * (wx2 -wx1) / divisx; + /* 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); + /* X-axis labels */ + my_snprintf(lab, S(lab), "%.4g", fabs(wx) < 1e-23 ? 0.0 : wx); + draw_string(3, NOW, lab, 0, 0, 1, 0, W_X(wx), y2 + 30 * txtsizex, txtsizex, txtsizex); + } + /* 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); + /* 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); + } + /* 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); + /* 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 simulation data is loaded and matches schematic draw data */ + if(xctx->raw_schname && !strcmp(xctx->raw_schname, xctx->current_name) && xctx->values) { + char *saven, *savec, *nptr, *cptr, *ntok, *ctok; + 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(xctx->rect[c][i].prop_ptr,"node",0)); + my_strdup2(1390, &color, get_tok_value(xctx->rect[c][i].prop_ptr,"color",0)); + nptr = node; + cptr = color; + /* process each node given in "node" attribute, get also associated color if any*/ + while( (ntok = my_strtok_r(nptr, " ", &saven)) ) { + ctok = my_strtok_r(cptr, " ", &savec); + nptr = cptr = NULL; + dbg(1, "ntok=%s ctok=%s\n", ntok, ctok? ctok: "NULL"); + if(ctok && ctok[0]) wave_color = atoi(ctok); + draw_string(wave_color, NOW, ntok, 0, 0, 0, 0, rx1 + rw/6 * wcnt, ry1, txtsizelab, txtsizex); + /* clipping everything outside graph area */ + bbox(START, 0.0, 0.0, 0.0, 0.0); + bbox(ADD,x1, y1, x2, y2); + dbg(1, "draw_graph(ADD): %g %g %g %g\n", x1, y1, x2, y2); + bbox(SET, 0.0, 0.0, 0.0, 0.0); + /* 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; + + /* 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[0][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++; + } + } + 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, NOW, xarr, yarr, poly_npoints, 0, 0); + } + } + bbox(END, 0.0, 0.0, 0.0, 0.0); + wcnt++; + } + my_free(1403, &xarr); + my_free(1404, &yarr); + my_free(1391, &node); + my_free(1392, &color); + } +} + +/* fill graph boxes with data from ngspice simulations */ +void draw_waves(void) +{ + int c, i; + int bbox_set = 0; + double save_lw; + int save_bbx1, save_bby1, save_bbx2, save_bby2; + save_lw = xctx->lw; + xctx->lw = 0; + /* 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); + } /* thin / dashed lines (axis etc) */ - XSetDashes(display, xctx->gc[7], 0, dash_arr, 2); - XSetLineAttributes (display, xctx->gc[7], 0, xDashType, CapButt, JoinBevel); - XSetLineAttributes (display, xctx->gc[9], 0, LineSolid, CapRound , JoinRound); - drawline(7, NOW, x1, y1, x2, y2, 0); - drawline(9, NOW, x1, y2, x2, y1, 0); - + XSetLineAttributes(display, xctx->gc[2], 0, LineSolid, CapRound, JoinRound); #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 - draw_string(10, NOW, "Hello World!", 0, 0, 1, 1, txtx, txty, txtsize, txtsize); + 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); /* draw data in each graph box */ + } + } + } #if HAS_CAIRO==1 cairo_restore(xctx->cairo_ctx); cairo_restore(xctx->cairo_save_ctx); #endif - XSetLineAttributes (display, xctx->gc[7], INT_WIDTH(xctx->lw), LineSolid, CapRound , JoinRound); - XSetLineAttributes (display, xctx->gc[9], INT_WIDTH(xctx->lw), LineSolid, CapRound , JoinRound); + xctx->lw = save_lw; + XSetLineAttributes(display, xctx->gc[2], INT_WIDTH(xctx->lw), LineSolid, CapRound , JoinRound); + /* 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); + } } void draw(void) @@ -1546,6 +1886,7 @@ void draw(void) xctx->areaw, xctx->areah); dbg(1, "draw(): window: %d %d %d %d\n",xctx->areax1, xctx->areay1, xctx->areax2, xctx->areay2); drawgrid(); + draw_waves(); x1 = X_TO_XSCHEM(xctx->areax1); y1 = Y_TO_XSCHEM(xctx->areay1); x2 = X_TO_XSCHEM(xctx->areax2); @@ -1567,16 +1908,11 @@ void draw(void) else drawline(c, ADD, l->x1, l->y1, l->x2, l->y2, l->dash); } if(xctx->enable_layer[c]) for(i=0;irects[c];i++) { - xRect *r = &xctx->rect[c][i]; - drawrect(c, ADD, r->x1, r->y1, r->x2, r->y2, r->dash); - if(r->flags == 1) { - /* flush pending data... */ - filledrect(c, END, 0.0, 0.0, 0.0, 0.0); - drawarc(c, END, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 0); - drawrect(c, END, 0.0, 0.0, 0.0, 0.0, 0); - drawline(c, END, 0.0, 0.0, 0.0, 0.0, 0); - draw_waves(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 + drawrect(c, ADD, r->x1, r->y1, r->x2, r->y2, r->dash); filledrect(c, ADD, r->x1, r->y1, r->x2, r->y2); } if(xctx->enable_layer[c]) for(i=0;iarcs[c];i++) { diff --git a/src/editprop.c b/src/editprop.c index 1afebe39..69ce0eb2 100644 --- a/src/editprop.c +++ b/src/editprop.c @@ -180,7 +180,7 @@ int my_snprintf(char *string, int size, const char *format, ...) format_spec = 0; prev = f + 1; } - else if(format_spec && *f == 'g') { + else if(format_spec && (*f == 'g' || *f == 'e' || *f == 'f')) { char nfmt[50], nstr[50]; double i; int nlen; @@ -393,14 +393,13 @@ void set_inst_prop(int i) void edit_rect_property(void) { - int i, c, n, old_dash; - unsigned short old_flags; + int i, c, n; int drw = 0; const char *dash, *flags; int preserve; char *oldprop=NULL; - if(xctx->rect[xctx->sel_array[0].col][xctx->sel_array[0].n].prop_ptr!=NULL) { - my_strdup(67, &oldprop, xctx->rect[xctx->sel_array[0].col][xctx->sel_array[0].n].prop_ptr); + my_strdup(67, &oldprop, xctx->rect[xctx->sel_array[0].col][xctx->sel_array[0].n].prop_ptr); + if(oldprop && oldprop[0]) { tclsetvar("retval",oldprop); } else { tclsetvar("retval",""); @@ -416,7 +415,7 @@ void edit_rect_property(void) if(xctx->sel_array[i].type != xRECT) continue; c = xctx->sel_array[i].col; n = xctx->sel_array[i].n; - if(preserve == 1) { + if(oldprop && preserve == 1) { set_different_token(&xctx->rect[c][n].prop_ptr, (char *) tclgetvar("retval"), oldprop, 0, 0); } else { @@ -424,7 +423,6 @@ void edit_rect_property(void) (char *) tclgetvar("retval")); } - old_flags = xctx->rect[c][n].flags; flags = get_tok_value(xctx->rect[c][n].prop_ptr,"flags",0); if( strcmp(flags, "") ) { int d = atoi(flags); @@ -432,14 +430,14 @@ void edit_rect_property(void) } else xctx->rect[c][n].flags = 0; - old_dash = xctx->rect[c][n].dash; dash = get_tok_value(xctx->rect[c][n].prop_ptr,"dash",0); if( strcmp(dash, "") ) { int d = atoi(dash); xctx->rect[c][n].dash = d >= 0? d : 0; } else xctx->rect[c][n].dash = 0; - if(old_dash != xctx->rect[c][n].dash || old_flags != xctx->rect[c][n].flags) { + if( (oldprop && xctx->rect[c][n].prop_ptr && strcmp(oldprop, xctx->rect[c][n].prop_ptr)) || + (!oldprop && xctx->rect[c][n].prop_ptr) ) { if(!drw) { bbox(START,0.0,0.0,0.0,0.0); drw = 1; @@ -463,8 +461,8 @@ void edit_line_property(void) const char *dash; int preserve; char *oldprop=NULL; - if(xctx->line[xctx->sel_array[0].col][xctx->sel_array[0].n].prop_ptr!=NULL) { - my_strdup(46, &oldprop, xctx->line[xctx->sel_array[0].col][xctx->sel_array[0].n].prop_ptr); + my_strdup(46, &oldprop, xctx->line[xctx->sel_array[0].col][xctx->sel_array[0].n].prop_ptr); + if(oldprop && oldprop[0]) { tclsetvar("retval", oldprop); } else { tclsetvar("retval",""); @@ -481,7 +479,7 @@ void edit_line_property(void) if(xctx->sel_array[i].type != LINE) continue; c = xctx->sel_array[i].col; n = xctx->sel_array[i].n; - if(preserve == 1) { + if(oldprop && preserve == 1) { set_different_token(&xctx->line[c][n].prop_ptr, (char *) tclgetvar("retval"), oldprop, 0, 0); } else { @@ -517,8 +515,8 @@ void edit_wire_property(void) char *oldprop=NULL; const char *bus_ptr; - if(xctx->wire[xctx->sel_array[0].n].prop_ptr!=NULL) { - my_strdup(47, &oldprop, xctx->wire[xctx->sel_array[0].n].prop_ptr); + my_strdup(47, &oldprop, xctx->wire[xctx->sel_array[0].n].prop_ptr); + if(oldprop && oldprop[0]) { tclsetvar("retval", oldprop); } else { tclsetvar("retval",""); @@ -539,7 +537,7 @@ void edit_wire_property(void) * xctx->prep_net_structs=0; * xctx->prep_hi_structs=0; */ oldbus = xctx->wire[k].bus; - if(preserve == 1) { + if(oldprop && preserve == 1) { set_different_token(&xctx->wire[k].prop_ptr, (char *) tclgetvar("retval"), oldprop, 0, 0); } else { @@ -580,8 +578,8 @@ void edit_arc_property(void) const char *dash; int preserve; - if(xctx->arc[xctx->sel_array[0].col][xctx->sel_array[0].n].prop_ptr!=NULL) { - my_strdup(98, &oldprop, xctx->arc[xctx->sel_array[0].col][xctx->sel_array[0].n].prop_ptr); + my_strdup(98, &oldprop, xctx->arc[xctx->sel_array[0].col][xctx->sel_array[0].n].prop_ptr); + if(oldprop && oldprop[0]) { tclsetvar("retval", oldprop); } else { tclsetvar("retval",""); @@ -598,7 +596,7 @@ void edit_arc_property(void) i = xctx->sel_array[ii].n; c = xctx->sel_array[ii].col; - if(preserve == 1) { + if(oldprop && preserve == 1) { set_different_token(&xctx->arc[c][i].prop_ptr, (char *) tclgetvar("retval"), oldprop, 0, 0); } else { @@ -647,8 +645,8 @@ void edit_polygon_property(void) int preserve; dbg(1, "edit_property(): input property:\n"); - if(xctx->poly[xctx->sel_array[0].col][xctx->sel_array[0].n].prop_ptr!=NULL) { - my_strdup(112, &oldprop, xctx->poly[xctx->sel_array[0].col][xctx->sel_array[0].n].prop_ptr); + my_strdup(112, &oldprop, xctx->poly[xctx->sel_array[0].col][xctx->sel_array[0].n].prop_ptr); + if(oldprop && oldprop[0]) { tclsetvar("retval", oldprop); } else { tclsetvar("retval",""); @@ -665,9 +663,8 @@ void edit_polygon_property(void) i = xctx->sel_array[ii].n; c = xctx->sel_array[ii].col; - if(preserve == 1) { + if(oldprop && preserve == 1) { set_different_token(&xctx->poly[c][i].prop_ptr, (char *) tclgetvar("retval"), oldprop, 0, 0); - } else { my_strdup(113, &xctx->poly[c][i].prop_ptr, (char *) tclgetvar("retval")); } @@ -724,7 +721,7 @@ void edit_text_property(int x) dbg(1, "edit_text_property(): entering\n"); sel = xctx->sel_array[0].n; my_strdup(656, &oldprop, xctx->text[sel].prop_ptr); - if(xctx->text[sel].prop_ptr !=NULL) + if(oldprop && oldprop[0]) tclsetvar("props",xctx->text[sel].prop_ptr); else tclsetvar("props",""); @@ -816,8 +813,8 @@ void edit_text_property(int x) my_strdup(74, &xctx->text[sel].txt_ptr, (char *) tclgetvar("retval")); } if(x==0) { - if(preserve) - set_different_token(&xctx->text[sel].prop_ptr, (char *) tclgetvar("props"), oldprop, 0, 0); + if(oldprop && preserve) + set_different_token(&xctx->text[sel].prop_ptr, (char *) tclgetvar("props"), oldprop, 0, 0); else my_strdup(75, &xctx->text[sel].prop_ptr,(char *) tclgetvar("props")); my_strdup(76, &xctx->text[sel].font, get_tok_value(xctx->text[sel].prop_ptr, "font", 0)); diff --git a/src/hilight.c b/src/hilight.c index d0620899..c76df5a4 100644 --- a/src/hilight.c +++ b/src/hilight.c @@ -563,7 +563,7 @@ int search(const char *tok, const char *val, int sub, int sel) const char *str; char *type; int has_token; - const char empty_string[] = ""; + const char *empty_string = ""; char *tmpname=NULL; int found = 0; xRect boundbox; @@ -1797,9 +1797,9 @@ void print_hilight_net(int show) char cmd[2*PATH_MAX]; /* 20161122 overflow safe */ char cmd2[2*PATH_MAX]; /* 20161122 overflow safe */ char cmd3[2*PATH_MAX]; /* 20161122 overflow safe */ - char a[] = "create_pins"; - char b[] = "add_lab_prefix"; - char b1[] = "add_lab_no_prefix"; + char *a = "create_pins"; + char *b = "add_lab_prefix"; + char *b1 = "add_lab_no_prefix"; char *filetmp1 = NULL; char *filetmp2 = NULL; char *filename_ptr; diff --git a/src/save.c b/src/save.c index 728874fc..5af0503d 100644 --- a/src/save.c +++ b/src/save.c @@ -87,7 +87,7 @@ char *read_line(FILE *fp, int dbg_level) */ const char *random_string(const char *prefix) { - static const char charset[]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + static const char *charset="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; static const int random_size=10; static char str[PATH_MAX]; /* safe even with multiple schematics, if immediately copied */ int prefix_size; diff --git a/src/scheduler.c b/src/scheduler.c index 83574ead..0b26942f 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -746,6 +746,9 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg else if(!strcmp(argv[2],"current_dirname")) { Tcl_SetResult(interp, xctx->current_dirname, TCL_VOLATILE); } + else if(!strcmp(argv[2],"current_name")) { + Tcl_SetResult(interp, xctx->current_name, TCL_VOLATILE); + } else if(!strcmp(argv[2],"currsch")) { char s[30]; /* overflow safe 20161122 */ my_snprintf(s, S(s), "%d",xctx->currsch); @@ -1081,6 +1084,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg my_snprintf(res, S(res), "color_ps=%d\n", color_ps); Tcl_AppendResult(interp, res, NULL); my_snprintf(res, S(res), "hilight_nets=%d\n", xctx->hilight_nets); Tcl_AppendResult(interp, res, NULL); my_snprintf(res, S(res), "semaphore=%d\n", xctx->semaphore); Tcl_AppendResult(interp, res, NULL); + my_snprintf(res, S(res), "ui_state=%d\n", xctx->ui_state); Tcl_AppendResult(interp, res, NULL); my_snprintf(res, S(res), "prep_net_structs=%d\n", xctx->prep_net_structs); Tcl_AppendResult(interp, res, NULL); my_snprintf(res, S(res), "prep_hi_structs=%d\n", xctx->prep_hi_structs); Tcl_AppendResult(interp, res, NULL); my_snprintf(res, S(res), "prep_hash_inst=%d\n", xctx->prep_hash_inst); Tcl_AppendResult(interp, res, NULL); @@ -1929,6 +1933,82 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg } else if(argv[1][0] == 'r') { + if(!strcmp(argv[1], "raw_clear")) + { + cmd_found = 1; + free_rawfile(); + Tcl_ResetResult(interp); + } + + if(!strcmp(argv[1], "raw_query")) + { + int i; + char s[30]; + cmd_found = 1; + Tcl_ResetResult(interp); + if(xctx->values) { + if(argc > 4) { + /* xschem rawfile_query value v(ldcp) 123 */ + if(!strcmp(argv[2], "value")) { + struct int_hashentry *entry; + int point = atoi(argv[4]); + const char *node = argv[3]; + int idx = -1; + if(point >= 0 && point < xctx->npoints) { + if(isonlydigit(node)) { + int i = atoi(node); + if(i >= 0 && i < xctx->nvars) { + idx = i; + } + } else { + entry = int_hash_lookup(xctx->raw_table, node, 0, XLOOKUP); + if(entry) { + idx = entry->value; + } + } + if(idx >= 0) { + double val = xctx->values[point][idx]; + my_snprintf(s, S(s), "%g", val); + Tcl_AppendResult(interp, s, NULL); + } + } + } + } else if(argc > 3) { + /* xschem rawfile_query index v(ldxp) */ + if(!strcmp(argv[2], "index")) { + struct int_hashentry *entry; + int idx; + entry = int_hash_lookup(xctx->raw_table, argv[3], 0, XLOOKUP); + idx = entry ? entry->value : -1; + my_snprintf(s, S(s), "%d", idx); + Tcl_AppendResult(interp, s, NULL); + } + } else if(argc > 2) { + if(!strcmp(argv[2], "points")) { + my_snprintf(s, S(s), "%d", xctx->npoints); + Tcl_AppendResult(interp, s, NULL); + } else if(!strcmp(argv[2], "vars")) { + my_snprintf(s, S(s), "%d", xctx->nvars); + Tcl_AppendResult(interp, s, NULL); + } else if(!strcmp(argv[2], "list")) { + for(i = 0 ; i < xctx->nvars; i++) { + Tcl_AppendResult(interp, xctx->names[i], "\n", NULL); + } + } + } + } + } + + if(!strcmp(argv[1], "raw_read")) + { + cmd_found = 1; + if(argc > 2) { + free_rawfile(); + read_rawfile(argv[2]); + } + Tcl_ResetResult(interp); + } + if(!strcmp(argv[1], "rebuild_connectivity")) { cmd_found = 1; @@ -2499,21 +2579,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg if(!strcmp(argv[1],"test")) { cmd_found = 1; - /* { - xRect boundbox; - rebuild_selected_array(); - calc_drawing_bbox(&boundbox, 1); - xctx->movelastsel = xctx->lastsel; - xctx->x1=boundbox.x1; - xctx->y_1=boundbox.y1; - xctx->rotatelocal=0; - xctx->move_flip = 1; - xctx->move_rot = 0; - xctx->ui_state|=STARTCOPY; - xctx->deltax = 5000.0; - xctx->deltay = 5000.0; - copy_objects(END); - } */ + Tcl_ResetResult(interp); } else if(!strcmp(argv[1],"toggle_colorscheme")) diff --git a/src/select.c b/src/select.c index d8d8534f..d7f23467 100644 --- a/src/select.c +++ b/src/select.c @@ -464,7 +464,7 @@ void delete_only_rect_line_arc_poly(void) void bbox(int what,double x1,double y1, double x2, double y2) { - /* fprintf(errfp, "bbox: what=%d\n", what); */ + dbg(1, "bbox: what=%d\n", what); switch(what) { case START: @@ -482,6 +482,7 @@ void bbox(int what,double x1,double y1, double x2, double y2) xctx->savey2 = xctx->areay2; xctx->savew = xctx->areaw; xctx->saveh = xctx->areah; + xctx->savexrect = xctx->xrect[0]; xctx->sem=1; break; case ADD: @@ -489,7 +490,7 @@ void bbox(int what,double x1,double y1, double x2, double y2) fprintf(errfp, "ERROR: bbox(ADD) call before bbox(START)\n"); tcleval("alert_ {ERROR: bbox(ADD) call before bbox(START)} {}"); } - dbg(1, " bbox(ADD,...): %.16g %.16g %.16g %.16g\n", x1, y1, x2, y2); + dbg(2, "bbox(ADD): %.16g %.16g %.16g %.16g\n", x1, y1, x2, y2); x1=X_TO_SCREEN(x1); y1=Y_TO_SCREEN(y1); x2=X_TO_SCREEN(x2); @@ -506,21 +507,21 @@ void bbox(int what,double x1,double y1, double x2, double y2) if(y1 > xctx->bby2) xctx->bby2 = (int) y1; break; case END: - xctx->areax1 = xctx->savex1; - xctx->areax2 = xctx->savex2; - xctx->areay1 = xctx->savey1; - xctx->areay2 = xctx->savey2; - xctx->areaw = xctx->savew; - xctx->areah = xctx->saveh; - xctx->xrect[0].x = 0; - xctx->xrect[0].y = 0; - xctx->xrect[0].width = xctx->areaw-4*INT_WIDTH(xctx->lw); - xctx->xrect[0].height = xctx->areah-4*INT_WIDTH(xctx->lw); - - if(has_x) { - set_clip_mask(END); + if(xctx->sem) { + xctx->areax1 = xctx->savex1; + xctx->areax2 = xctx->savex2; + xctx->areay1 = xctx->savey1; + xctx->areay2 = xctx->savey2; + xctx->areaw = xctx->savew; + xctx->areah = xctx->saveh; + xctx->xrect[0] = xctx->savexrect; + if(has_x) { + dbg(2, "bbox(END): resetting clip area: %d %d %d %d\n", + xctx->xrect[0].x, xctx->xrect[0].y, xctx->xrect[0].width, xctx->xrect[0].height); + set_clip_mask(END); + } + xctx->sem=0; } - xctx->sem=0; break; case SET: if(xctx->sem==0) { @@ -540,7 +541,8 @@ void bbox(int what,double x1,double y1, double x2, double y2) xctx->xrect[0].height = xctx->bby2-xctx->bby1+2*INT_WIDTH(xctx->lw); if(has_x) { set_clip_mask(SET); - dbg(1, "bbox(): bbox= %d %d %d %d\n",xctx->areax1,xctx->areay1,xctx->areax2,xctx->areay2); + dbg(2, "bbox(SET): setting clip area: %d %d %d %d\n", + xctx->xrect[0].x, xctx->xrect[0].y, xctx->xrect[0].width, xctx->xrect[0].height); } break; default: diff --git a/src/spice_netlist.c b/src/spice_netlist.c index b9482e35..3b34fd75 100644 --- a/src/spice_netlist.c +++ b/src/spice_netlist.c @@ -86,6 +86,7 @@ void hier_psprint(void) /* netlister driver */ unselect_all(); /* load_schematic(1, xctx->sch[xctx->currsch], 0); */ xctx->pop_undo(0, 0); + my_strncpy(xctx->current_name, rel_sym_path(xctx->sch[xctx->currsch]), S(xctx->current_name)); ps_draw(4); /* trailer */ zoom_full(0, 0, 1, 0.97); draw(); @@ -300,6 +301,7 @@ void global_spice_netlist(int global) /* netlister driver */ /* remove_symbols(); */ /* load_schematic(1, xctx->sch[xctx->currsch], 0); */ xctx->pop_undo(0, 0); + my_strncpy(xctx->current_name, rel_sym_path(xctx->sch[xctx->currsch]), S(xctx->current_name)); prepare_netlist_structs(1); /* so 'lab=...' attributes for unnamed nets are set */ /* symbol vs schematic pin check, we do it here since now we have ALL symbols loaded */ sym_vs_sch_pins(); diff --git a/src/svgdraw.c b/src/svgdraw.c index 837687a3..7903f932 100644 --- a/src/svgdraw.c +++ b/src/svgdraw.c @@ -583,8 +583,8 @@ void svg_draw(void) fill_svg_colors(); old_grid=tclgetboolvar("draw_grid"); tclsetvar("draw_grid", "0"); - dx=xctx->xschem_w; - dy=xctx->xschem_h; + dx=xctx->xrect[0].width; + dy=xctx->xrect[0].height; dbg(1, "svg_draw(): dx=%g dy=%g\n", dx, dy); if(xctx->plotfile[0]) { diff --git a/src/tedax_netlist.c b/src/tedax_netlist.c index 9c4e51f5..d651d3cb 100644 --- a/src/tedax_netlist.c +++ b/src/tedax_netlist.c @@ -116,6 +116,7 @@ void global_tedax_netlist(int global) /* netlister driver */ /* remove_symbols(); */ /* load_schematic(1, xctx->sch[xctx->currsch], 0); */ xctx->pop_undo(0, 0); + my_strncpy(xctx->current_name, rel_sym_path(xctx->sch[xctx->currsch]), S(xctx->current_name)); prepare_netlist_structs(1); /* so 'lab=...' attributes for unnamed nets are set */ /* symbol vs schematic pin check, we do it here since now we have ALL symbols loaded */ diff --git a/src/token.c b/src/token.c index 90728bd3..cfee3aac 100644 --- a/src/token.c +++ b/src/token.c @@ -141,7 +141,7 @@ void hash_all_names(int n) const char *tcl_hook2(char **res) { static char *result = NULL; - static const char empty[]=""; + static const char *empty=""; if(res == NULL || *res == NULL) { my_free(1285, &result); @@ -2695,7 +2695,7 @@ const char *find_nth(const char *str, char sep, int n) { static char *result=NULL; /* safe to keep even with multiple schematic windows */ static int result_size = 0; /* safe to keep even with multiple schematic windows */ - static const char empty[]=""; + static const char *empty=""; int i, len; char *ptr; int count; @@ -2730,7 +2730,7 @@ const char *find_nth(const char *str, char sep, int n) /* if s==NULL return emty string */ const char *translate(int inst, const char* s) { - static const char empty[]=""; + static const char *empty=""; static char *result=NULL; /* safe to keep even with multiple schematics */ int size=0, tmp; register int c, state=TOK_BEGIN, space; @@ -3019,7 +3019,7 @@ const char *translate(int inst, const char* s) const char *translate2(struct Lcc *lcc, int level, char* s) { - static const char empty[]=""; + static const char *empty=""; static char *result = NULL; int i, size = 0, tmp, save_tok_size; register int c, state = TOK_BEGIN, space; diff --git a/src/verilog_netlist.c b/src/verilog_netlist.c index e6cf07af..1625bdf8 100644 --- a/src/verilog_netlist.c +++ b/src/verilog_netlist.c @@ -323,6 +323,7 @@ void global_verilog_netlist(int global) /* netlister driver */ /* remove_symbols(); */ /* load_schematic(1,xctx->sch[xctx->currsch], 0); */ xctx->pop_undo(0, 0); + my_strncpy(xctx->current_name, rel_sym_path(xctx->sch[xctx->currsch]), S(xctx->current_name)); prepare_netlist_structs(1); /* so 'lab=...' attributes for unnamed nets are set */ /* symbol vs schematic pin check, we do it here since now we have ALL symbols loaded */ sym_vs_sch_pins(); diff --git a/src/vhdl_netlist.c b/src/vhdl_netlist.c index 72ef1c5b..56109d2a 100644 --- a/src/vhdl_netlist.c +++ b/src/vhdl_netlist.c @@ -381,6 +381,7 @@ void global_vhdl_netlist(int global) /* netlister driver */ /* remove_symbols(); */ /* load_schematic(1, xctx->sch[xctx->currsch], 0); */ xctx->pop_undo(0, 0); + my_strncpy(xctx->current_name, rel_sym_path(xctx->sch[xctx->currsch]), S(xctx->current_name)); prepare_netlist_structs(1); /* so 'lab=...' attributes for unnamed nets are set */ /* symbol vs schematic pin check, we do it here since now we have ALL symbols loaded */ sym_vs_sch_pins(); diff --git a/src/xinit.c b/src/xinit.c index ab50a942..95bca161 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -323,6 +323,13 @@ void free_xschem_data() int i; xctx->delete_undo(); free_simdata(); + + my_free(970, &xctx->node_table); + my_free(1385, &xctx->inst_table); + my_free(1386, &xctx->node_redraw_table); + my_free(1387, &xctx->hilight_table); + my_free(1388, &xctx->raw_table); + my_free(1098, &xctx->wire); my_free(1100, &xctx->text); my_free(1107, &xctx->inst); @@ -415,6 +422,11 @@ void alloc_xschem_data(const char *top_path) xctx->mooz=1/CADINITIALZOOM; xctx->xorigin=CADINITIALX; xctx->yorigin=CADINITIALY; + xctx->names = NULL; + xctx->values = NULL; + xctx->nvars = 0; + xctx->npoints = 0; + xctx->raw_schname = NULL; xctx->wires = 0; xctx->instances = 0; xctx->symbols = 0; @@ -453,15 +465,16 @@ void alloc_xschem_data(const char *top_path) xctx->inst_spatial_table[i][j] = NULL; } } - memset(xctx->inst_table, 0, HASHSIZE * sizeof(struct inst_hashentry *)); - memset(xctx->node_table, 0, HASHSIZE * sizeof(struct node_hashentry *)); - memset(xctx->hilight_table, 0, HASHSIZE *sizeof(struct hilight_hashentry *)); - memset(xctx->node_redraw_table, 0, HASHSIZE * sizeof(struct int_hashentry *)); + xctx->node_table = my_calloc(517, HASHSIZE, sizeof(struct node_hashentry *)); + xctx->node_redraw_table = my_calloc(973, HASHSIZE, sizeof(struct int_hashentry *)); + xctx->inst_table = my_calloc(1382, HASHSIZE, sizeof(struct inst_hashentry *)); + xctx->hilight_table = my_calloc(1383, HASHSIZE, sizeof(struct hilight_hashentry *)); + xctx->raw_table = my_calloc(1384, HASHSIZE, sizeof(struct int_hashentry *)); + xctx->inst_redraw_table = NULL; xctx->inst_redraw_table_size = 0; xctx->window = xctx->save_pixmap = 0; xctx->xrect[0].width = xctx->xrect[0].height = xctx->xrect[0].x = xctx->xrect[0].y = 0; - xctx->xschem_w = xctx->xschem_h = 0; #if HAS_CAIRO==1 xctx->cairo_ctx = xctx->cairo_save_ctx = NULL; xctx->cairo_sfc = xctx->cairo_save_sfc = NULL; @@ -604,6 +617,7 @@ void delete_schematic_data(void) * inst & wire .node fields, instance name hash */ clear_drawing(); remove_symbols(); + free_rawfile(); free_xschem_data(); /* delete the xctx struct */ } @@ -1116,14 +1130,14 @@ void resetcairo(int create, int clear, int force_or_resize) #if HAS_XRENDER==1 #if HAS_XCB==1 xctx->cairo_save_sfc = cairo_xcb_surface_create_with_xrender_format(xcbconn, screen_xcb, xctx->save_pixmap, - &format_rgb, xctx->xschem_w, xctx->xschem_h); + &format_rgb, xctx->xrect[0].width, xctx->xrect[0].height); #else xctx->cairo_save_sfc = cairo_xlib_surface_create_with_xrender_format(display, xctx->save_pixmap, - DefaultScreenOfDisplay(display), render_format, xctx->xschem_w, xctx->xschem_h); + DefaultScreenOfDisplay(display), render_format, xctx->xrect[0].width, xctx->xrect[0].height); #endif /* HAS_XCB */ #else xctx->cairo_save_sfc = - cairo_xlib_surface_create(display, xctx->save_pixmap, visual, xctx->xschem_w, xctx->xschem_h); + cairo_xlib_surface_create(display, xctx->save_pixmap, visual, xctx->xrect[0].width, xctx->xrect[0].height); #endif /* HAS_XRENDER */ if(cairo_surface_status(xctx->cairo_save_sfc)!=CAIRO_STATUS_SUCCESS) { fprintf(errfp, "ERROR: invalid cairo xcb surface\n"); @@ -1138,15 +1152,17 @@ void resetcairo(int create, int clear, int force_or_resize) /***** Create Cairo main drawing window structures *****/ #if HAS_XRENDER==1 #if HAS_XCB==1 - dbg(1, "create_cairo_surface: w=%d, h=%d\n", xctx->xschem_w, xctx->xschem_h); + dbg(1, "create_cairo_surface: w=%d, h=%d\n", xctx->xrect[0].width, xctx->xrect[0].height); xctx->cairo_sfc = cairo_xcb_surface_create_with_xrender_format(xcbconn, - screen_xcb, xctx->window, &format_rgb, xctx->xschem_w, xctx->xschem_h); + screen_xcb, xctx->window, &format_rgb, xctx->xrect[0].width, xctx->xrect[0].height); #else xctx->cairo_sfc = cairo_xlib_surface_create_with_xrender_format (display, - xctx->window, DefaultScreenOfDisplay(display), render_format, xctx->xschem_w, xctx->xschem_h); + xctx->window, DefaultScreenOfDisplay(display), render_format, + xctx->xrect[0].width, xctx->xrect[0].height); #endif /* HAS_XCB */ #else - xctx->cairo_sfc = cairo_xlib_surface_create(display, xctx->window, visual, xctx->xschem_w, xctx->xschem_h); + xctx->cairo_sfc = cairo_xlib_surface_create(display, xctx->window, visual, + xctx->xrect[0].width, xctx->xrect[0].height); #endif /* HAS_XRENDER */ if(cairo_surface_status(xctx->cairo_sfc)!=CAIRO_STATUS_SUCCESS) { fprintf(errfp, "ERROR: invalid cairo surface\n"); @@ -1160,9 +1176,9 @@ void resetcairo(int create, int clear, int force_or_resize) cairo_set_line_cap(xctx->cairo_ctx, CAIRO_LINE_CAP_ROUND); #if 0 * #if HAS_XCB==1 && HAS_XRENDER==1 - * cairo_xcb_surface_set_size(xctx->cairo_sfc, xctx->xschem_w, xctx->xschem_h); + * cairo_xcb_surface_set_size(xctx->cairo_sfc, xctx->xrect[0].width, xctx->xrect[0].height); * #else - * cairo_xlib_surface_set_size(xctx->cairo_sfc, xctx->xschem_w, xctx->xschem_h); + * cairo_xlib_surface_set_size(xctx->cairo_sfc, xctx->xrect[0].width, xctx->xrect[0].height); * #endif /* HAS_XCB && HAS_XRENDER */ #endif } @@ -1202,23 +1218,21 @@ void resetwin(int create_pixmap, int clear_pixmap, int force, int w, int h) } if(status) { /* if(wattr.map_state==IsUnmapped) return; */ - xctx->xschem_w=width; - xctx->xschem_h=height; - xctx->areax2 = xctx->xschem_w+2*INT_WIDTH(xctx->lw); - xctx->areay2 = xctx->xschem_h+2*INT_WIDTH(xctx->lw); - xctx->areax1 = -2*INT_WIDTH(xctx->lw); - xctx->areay1 = -2*INT_WIDTH(xctx->lw); - xctx->areaw = xctx->areax2-xctx->areax1; - xctx->areah = xctx->areay2-xctx->areay1; + xctx->areax2 = width + 2 * INT_WIDTH(xctx->lw); + xctx->areay2 = height + 2 * INT_WIDTH(xctx->lw); + xctx->areax1 = -2 * INT_WIDTH(xctx->lw); + xctx->areay1 = -2 * INT_WIDTH(xctx->lw); + xctx->areaw = xctx->areax2 - xctx->areax1; + xctx->areah = xctx->areay2 - xctx->areay1; /* if no force avoid unnecessary work if no resize */ - if( force || xctx->xschem_w !=xctx->xrect[0].width || xctx->xschem_h !=xctx->xrect[0].height) { - dbg(1, "resetwin(): create: %d, clear: %d, force: %d, xschem_w=%d xschem_h=%d\n", - create_pixmap, clear_pixmap, force, xctx->xschem_w,xctx->xschem_h); + if( force || width != xctx->xrect[0].width || height != xctx->xrect[0].height) { + dbg(1, "resetwin(): create: %d, clear: %d, force: %d, w=%d h=%d\n", + create_pixmap, clear_pixmap, force, width, height); dbg(1, "resetwin(): changing size\n\n"); xctx->xrect[0].x = 0; xctx->xrect[0].y = 0; - xctx->xrect[0].width = xctx->xschem_w; - xctx->xrect[0].height = xctx->xschem_h; + xctx->xrect[0].width = width; + xctx->xrect[0].height = height; if(clear_pixmap) { resetcairo(0, 1, 1); /* create, clear, force */ #ifdef __unix__ @@ -1230,9 +1244,11 @@ void resetwin(int create_pixmap, int clear_pixmap, int force, int w, int h) } if(create_pixmap) { #ifdef __unix__ - xctx->save_pixmap = XCreatePixmap(display, xctx->window, xctx->xschem_w, xctx->xschem_h, screendepth); + xctx->save_pixmap = XCreatePixmap(display, xctx->window, + xctx->xrect[0].width, xctx->xrect[0].height, screendepth); #else - xctx->save_pixmap = Tk_GetPixmap(display, xctx->window, xctx->xschem_w, xctx->xschem_h, screendepth); + xctx->save_pixmap = Tk_GetPixmap(display, xctx->window, + xctx->xrect[0].width, xctx->xrect[0].height, screendepth); #endif xctx->gctiled = XCreateGC(display,xctx->window,0L, NULL); XSetTile(display,xctx->gctiled, xctx->save_pixmap); @@ -1613,8 +1629,6 @@ int Tcl_AppInit(Tcl_Interp *inter) tclsetvar("flat_netlist","1"); xctx->flat_netlist = 1; } - xctx->xschem_w = CADWIDTH; - xctx->xschem_h = CADHEIGHT; xctx->areaw = CADWIDTH+4*INT_WIDTH(xctx->lw); /* clip area extends 1 pixel beyond physical xctx->window area */ xctx->areah = CADHEIGHT+4*INT_WIDTH(xctx->lw); /* to avoid drawing clipped rectangle borders at xctx->window edges */ xctx->areax1 = -2*INT_WIDTH(xctx->lw); @@ -1876,8 +1890,8 @@ int Tcl_AppInit(Tcl_Interp *inter) xctx->xrect[0].x = 0; xctx->xrect[0].y = 0; - xctx->xschem_w = xctx->xrect[0].width = 842; - xctx->xschem_h = xctx->xrect[0].height = 595; + xctx->xrect[0].width = 842; + xctx->xrect[0].height = 595; xctx->areax2 = 842+2; xctx->areay2 = 595+2; xctx->areax1 = -2; diff --git a/src/xschem.h b/src/xschem.h index fbcf3d99..a6a734b6 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -160,7 +160,7 @@ extern char win_temp_dir[PATH_MAX]; #define CADMAXGRIDPOINTS 512 #define CADMAXHIER 80 #define CADCHUNKALLOC 512 /* was 256 20102004 */ -#define CADDRAWBUFFERSIZE 128 +#define CADDRAWBUFFERSIZE 512 /* when x-width of drawing area s below this threshold use spatial */ /* hash table for drawing wires and instances (for faster lookup) instead of */ @@ -301,7 +301,7 @@ extern char win_temp_dir[PATH_MAX]; #define LINE_OUTSIDE(xa,ya,xb,yb,x1,y1,x2,y2) \ (xa>=x2 || xb<=x1 || ( (ya=y2 || yb<=y1) : (yb>=y2 || ya<=y1) ) ) -#define CLIP(x,a,b) ((x) < a ? (a) : (x) > b ? (b) : (x)) +#define CLIP(x,a,b) (((x) < (a)) ? (a) : ((x) > (b)) ? (b) : (x)) #define MINOR(a,b) ( (a) <= (b) ? (a) : (b) ) @@ -578,7 +578,6 @@ typedef struct { double mousex_snap,mousey_snap; /* mouse coord. snapped to grid */ double mx_double_save, my_double_save; int areax1,areay1,areax2,areay2,areaw,areah; /* window corners / size, line width beyond screen edges */ - int xschem_h, xschem_w; /* true window size from XGetWindowAttributes */ int need_reb_sel_arr; int lastsel; int maxsel; @@ -619,9 +618,10 @@ typedef struct { int cur_undo_ptr; int tail_undo_ptr; int head_undo_ptr; - struct inst_hashentry *inst_table[HASHSIZE]; - struct node_hashentry *node_table[HASHSIZE]; - struct hilight_hashentry *hilight_table[HASHSIZE]; + struct inst_hashentry **inst_table; + struct node_hashentry **node_table; + struct hilight_hashentry **hilight_table; + int hilight_nets; int hilight_color; int hilight_time; /* timestamp for sims */ @@ -636,7 +636,7 @@ typedef struct { int onetime; /* move.c */ /* list of nodes, instances attached to these need redraw */ - struct int_hashentry *node_redraw_table[HASHSIZE]; + struct int_hashentry **node_redraw_table; /* list of instances, collected using previous table, that need redraw */ unsigned char *inst_redraw_table; int inst_redraw_table_size; @@ -676,6 +676,7 @@ typedef struct { int bbx1, bbx2, bby1, bby2; int savew, saveh, savex1, savex2, savey1, savey2; int sem; + XRectangle savexrect; /* new_prop_string */ char prefix; /* edit_symbol_property, update_symbol */ @@ -685,6 +686,13 @@ typedef struct { /* in_memory_undo */ Undo_slot uslot[MAX_UNDO]; int undo_initialized; + /* read raw files (draw.c) */ + char **names; + double **values; + int nvars; + int npoints; + struct int_hashentry **raw_table; + char *raw_schname; /* */ int nl_sel, nl_sem; XSegment *biggridpoint; @@ -881,6 +889,9 @@ extern char cli_opt_netlist_dir[PATH_MAX]; extern Xschem_ctx *xctx; /* FUNCTIONS */ +extern void draw_waves(void); +extern void free_rawfile(void); +extern int read_rawfile(const char *f); extern double timer(int start); extern void enable_layers(void); extern void set_snap(double); @@ -1163,6 +1174,7 @@ extern void *my_calloc(int id, size_t nmemb, size_t size); extern void my_free(int id, void *ptr); extern size_t my_strcat(int id, char **, const char *); extern double my_round(double a); +extern double round_to_n_digits(double x, int n); extern const char *subst_token(const char *s, const char *tok, const char *new_val); extern void new_prop_string(int i, const char *old_prop,int fast, int dis_uniq_names); extern void hash_name(char *token, int remove); diff --git a/tests/xschemtest.tcl b/tests/xschemtest.tcl index 2123beef..6b1b9c42 100644 --- a/tests/xschemtest.tcl +++ b/tests/xschemtest.tcl @@ -26,8 +26,9 @@ proc draw_test {filelist} { xschem hilight ;# hilight all selected nets and labels xschem unselect_all set increment 5.0 + set n 30.0 set a [time { - for { set i 0 } { $i < 100 } { incr i} { + for { set i 0 } { $i < $n } { incr i} { set x [xschem get xorigin] set y [xschem get yorigin] set x [expr {$x +$increment}] @@ -37,7 +38,7 @@ proc draw_test {filelist} { } }] set a [lindex $a 0] - set fps [expr {100.0 / $a * 1e6} ] ;# calculate drawing frames per second + set fps [expr {$n / $a * 1e6} ] ;# calculate drawing frames per second puts "$f: draw speed: $fps fps" } set show_pin_net_names 0 diff --git a/xschem_library/examples/LCC_instances.sch b/xschem_library/examples/LCC_instances.sch index aad58488..feee864e 100644 --- a/xschem_library/examples/LCC_instances.sch +++ b/xschem_library/examples/LCC_instances.sch @@ -20,6 +20,15 @@ L 4 1400 -290 1420 -310 {dash=3} L 4 1400 -330 1400 -290 {dash=3} L 4 1400 -330 1420 -310 {dash=3} L 4 1240 -310 1400 -310 {dash=3} +B 2 30 -940 500 -730 {flags=1 +y1 = 0 +y2 = 3 +divy = 6 +x1=0 +x2=3 +divx=6 +node="v(aa) v(z) v(zz)" +color="11 7 13"} P 4 7 530 -860 1130 -860 1130 -690 1390 -690 1390 -580 530 -580 530 -860 {dash=3} T {These 2 instances are equivalent} 290 -320 0 0 0.4 0.4 {} T {Example of using a schematic as a @@ -32,6 +41,8 @@ in the schematic instance.} 550 -840 0 0 0.6 0.6 {} T {LCC schematics can be nested If only .sch is used there is no need for a .sym file at all} 910 -430 0 0 0.6 0.6 {} +T {Select one or more graphs (and no other objects) +and use arrow keys to zoom / pan waveforms} 40 -990 0 0 0.3 0.3 {} N 410 -140 410 -120 {lab=HALF} N 410 -230 430 -230 {lab=ZZ} N 410 -230 410 -200 {lab=ZZ} @@ -49,8 +60,8 @@ C {code_shown.sym} 580 -150 0 0 {name=STIMULI only_toplevel=true tclcommand="xschem edit_vi_prop" value=" - -.tran 10n 10u uic +.dc v1 0 3 0.01 +* .tran 10n 10u uic .save all "} C {code.sym} 760 -170 0 0 {name=MODEL @@ -133,3 +144,7 @@ C {cmos_inv.sch} 140 -300 0 0 {name=Xinv WN=15u WP=45u LLN=3u LLP=3u} C {cmos_inv.sym} 280 -230 0 0 {name=Xinv2 WN=15u WP=45u LLN=3u LLP=3u} C {bus_keeper.sch} 1200 60 0 0 {name=Xkeeper WN_FB=3u WP_FB=5u} C {lab_pin.sym} 700 -530 0 1 {name=p1 lab=Z} +C {launcher.sym} 85 -1025 0 0 {name=h5 +descr="Select arrow and +Ctrl-Right-Click to load waveforms" +tclcommand="xschem raw_read $netlist_dir/[file rootname [xschem get current_name]].raw"} diff --git a/xschem_library/examples/poweramp.sch b/xschem_library/examples/poweramp.sch index 0b306e1e..9e810d0b 100644 --- a/xschem_library/examples/poweramp.sch +++ b/xschem_library/examples/poweramp.sch @@ -1,4 +1,4 @@ -v {xschem version=2.9.9 file_version=1.2 } +v {xschem version=3.0.0 file_version=1.2 } G {} K {} V {} @@ -14,6 +14,24 @@ 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 +y1 = -60 +y2 = 60 +divy = 12 +x1=0.00 +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 +y1 = 0 +y2 = 12 +divy = 6 +x1=0.00 +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"} T {actual value 50u} 400 -820 0 0 0.4 0.4 {} T {actual value @@ -38,6 +56,8 @@ however when used in multiple instances 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 -820 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} @@ -287,3 +307,9 @@ C {launcher.sym} 1000 -310 0 0 {name=h4 descr="View Raw file" tclcommand="textwindow $netlist_dir/[file tail [file rootname [ xschem get schname 0 ] ] ].raw" } +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} 1105 -865 0 0 {name=h5 +descr="Select arrow and +Ctrl-Right-Click to load waveforms" +tclcommand="xschem raw_read $netlist_dir/[file rootname [xschem get current_name]].raw"} diff --git a/xschem_library/ngspice/solar_panel.sch b/xschem_library/ngspice/solar_panel.sch index cdcd08f4..235468f7 100644 --- a/xschem_library/ngspice/solar_panel.sch +++ b/xschem_library/ngspice/solar_panel.sch @@ -1,4 +1,4 @@ -v {xschem version=2.9.9 file_version=1.2 } +v {xschem version=3.0.0 file_version=1.2 } G {} K {} V {} @@ -38,6 +38,31 @@ L 8 790 -530 790 -510 {} L 8 770 -610 790 -610 {} L 8 790 -610 807.5 -620 {} L 8 810 -610 830 -610 {} +B 2 1110 -950 1530 -800 {flags=1 +y1 = 0 +y2 = 20 +divy = 10 +x1=0 +x2=200e-6 +divx=8 +node="v(led) v(sw)" +color="11 18"} +B 2 1110 -790 1530 -660 {flags=1 +y1 = 0 +y2 = 20 +divy = 10 +x1=0 +x2=200e-6 +divx=8 +node="v(panel)"} +B 2 1110 -650 1530 -520 {flags=1 +y1 = 0 +y2 = 4 +divy = 8 +x1=0 +x2=200e-6 +divx=8 +node="i(vsw)" color=12} 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 {} @@ -63,6 +88,8 @@ T {Maximum Power} 287.5 -870 0 0 0.2 0.2 {layer=8} T {2x10 1W white LED} 1230 -340 0 0 0.4 0.4 {layer=8} T {IDEAL Diode} 690 -470 0 0 0.4 0.4 {layer=8} T {2xseries 1W white LEDs} 1250 -230 0 0 0.4 0.4 {} +T {Select one or more graphs (and no other objects) +and use arrow keys to zoom / pan waveforms} 1120 -990 0 0 0.3 0.3 {} N 80 -450 80 -430 {lab=SRC} N 1050 -250 1140 -250 {lab=0} N 1140 -290 1140 -250 {lab=0} @@ -98,7 +125,7 @@ C {code_shown.sym} 245 -245 0 0 {name=CONTROL value="* .control * .endc .option savecurrents *.save all -.tran 5n 200u uic +.tran 20n 200u uic * .dc VP 0 21 0.01 " net_name=true} C {code.sym} 15 -225 0 0 {name=MODELS value=".MODEL DIODE D(IS=1.139e-08 RS=0.99 CJO=9.3e-12 VJ=1.6 M=0.411 BV=30 EG=0.7 ) @@ -190,3 +217,7 @@ C {spice_probe.sym} 1160 -480 0 0 {name=p1 analysis=tran} C {spice_probe.sym} 360 -450 0 0 {name=p2 analysis=tran} C {spice_probe.sym} 860 -550 0 1 {name=p3 analysis=tran} C {spice_probe.sym} 100 -450 0 1 {name=p4 analysis=tran} +C {launcher.sym} 1165 -1025 0 0 {name=h3 +descr="Select arrow and +Ctrl-Right-Click to load waveforms" +tclcommand="xschem raw_read $netlist_dir/[file rootname [xschem get current_name]].raw"} diff --git a/xschem_library/rom8k/rom8k.sch b/xschem_library/rom8k/rom8k.sch index f7837258..3d5d38f3 100644 --- a/xschem_library/rom8k/rom8k.sch +++ b/xschem_library/rom8k/rom8k.sch @@ -1,4 +1,4 @@ -v {xschem version=2.9.9 file_version=1.2 } +v {xschem version=3.0.0 file_version=1.2 } G {} K {} V {} @@ -27,6 +27,57 @@ 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=0 +x2=480e-9 +divx=12 +node="v(ldcp) v(ldprech)" +color="3 11"} +B 2 1870 -700 2380 -600 {flags=1 +y1 = 0 +y2 = 2 +divy = 4 +x1=0 +x2=480e-9 divx=12 +node="v(lden)" +color=12} +B 2 1870 -370 2380 -270 {flags=1 +y1 = 0 +y2 = 2 +divy = 4 +x1=0 +x2=480e-9 +divx=12 +node="v(ldq[11])"} +B 2 1870 -590 2380 -490 {flags=1 +y1 = 0 +y2 = 2 +divy = 4 +x1=0 +x2=480e-9 +divx=12 +node="v(ldsal)" +color=8} +B 2 1870 -480 2380 -380 {flags=1 +y1 = 0 +y2 = 2 +divy = 4 +x1=0 +x2=480e-9 +divx=12 +node="v(ldq[12])"} +B 2 1870 -1010 2380 -820 {flags=1 +y1 = 0 +y2 = 2 +divy = 5 +x1=0 +x2=480e-9 +divx=12 +node="v(ldyms[6]) v(ldyms[9]) v(ldcp)" +color="4 7 12"} B 7 950 -250 980 -80 {} B 7 1150 -250 1180 -80 {} B 21 10 -970 240 -750 {} @@ -37,6 +88,8 @@ monitors} 30 -1030 0 0 0.4 0.4 {} 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 -1050 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} @@ -227,3 +280,7 @@ C {lab_pin.sym} 1670 -740 0 0 {name=l2 lab=LDWL[8: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} 1935 -1085 0 0 {name=h2 +descr="Select arrow and +Ctrl-Right-Click to load waveforms" +tclcommand="xschem raw_read $netlist_dir/[file rootname [xschem get current_name]].raw"}