diff --git a/doc/xschem_man/developer_info.html b/doc/xschem_man/developer_info.html index 4961ea54..9a847521 100644 --- a/doc/xschem_man/developer_info.html +++ b/doc/xschem_man/developer_info.html @@ -1517,6 +1517,11 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns" if rep not preceeded by an 'escape' character
  • subst_tok str tok newval
  •     Return string 'str' with 'tok' attribute value replaced with 'newval' 
    +
  • symbol_base_name n
  • +   Return the base_name field of a symbol with name or number `n`
    +   Normally this is empty. It is set for overloaded symbols, that is symbols
    +   derived from the base symbol due to instance based implementation selection
    +   (the instance "schematic" attribute) 
  • symbol_in_new_window [new_process]
  •     When a symbol is selected edit it in a new tab/window if not already open.
        If nothing selected open another window of the second schematic (issues a warning).
    diff --git a/doc/xschem_man/symbol_property_syntax.html b/doc/xschem_man/symbol_property_syntax.html
    index d0ca082c..9aa02448 100644
    --- a/doc/xschem_man/symbol_property_syntax.html
    +++ b/doc/xschem_man/symbol_property_syntax.html
    @@ -619,6 +619,29 @@ verilog_format="xnor #(@risedel , @falldel ) @name ( @@Z , @@A , @@B );"
         sequence number n, extracted from simulation raw file (operating point or 
         cursor b position)

    +
  • @spice_get_voltage
  • +

    This attribute will be replaced by the voltage of the net attached to the first pin (pin number 0) + of the symbol

    + +
  • @spice_get_current
  • +

    This attribute will be replaced by the current through the first pin of the primitive symbol + according to the SPICE syntax. This can be used for elementary devices like voltage sources, + resistors, mosfets, bjts and so on. For example @spice_get_current will display the + drain current of a mosfet if this attribute is placed inside a MOS symbol.

    + +
  • @spice_get_current_param
  • +

    This will specify in param the current to display, for example:
    + @spice_get_current_ibs to get the body-source current in a Mosfet, + @spice_get_current_ie to get the emitter current in a Bjt.

    + +
  • @spice_get_modelvoltage_param
  • +

    This will specify in param the voltage to display, for example:
    + @spice_get_modelvoltage_vth to get the Vth in a Mosfet

    + +
  • @spice_get_modelparam_param
  • +

    This will specify in param the model parameter to display, for example:
    + @spice_get_modelparam_gm to get the transconductance in a Mosfet

    +
  • @spice_get_node spice_node
  • spice_node Will be replaced with the Spice simulated value for that node.
    diff --git a/src/callback.c b/src/callback.c index 3b2f10f9..c0e65b64 100644 --- a/src/callback.c +++ b/src/callback.c @@ -467,12 +467,6 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int tcleval("graph_show_measure"); } /* if(xctx->graph_flags & 64) */ - - - - - - gr->master_gx1 = gr->gx1; gr->master_gx2 = gr->gx2; gr->master_gw = gr->gw; @@ -497,11 +491,41 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int need_redraw_master = 1; } + /* move cursor1 */ + /* set cursor position from master graph x-axis */ + else if(event == MotionNotify && (state & Button1Mask) && (xctx->graph_flags & 16 )) { + double c; + c = G_X(xctx->mousex); + if(gr->logx) c = pow(10, c); + if(r->flags & 4) { /* private_cursor */ + my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "cursor1_x", dtoa(c))); + } else { + xctx->graph_cursor1_x = c; + } + need_all_redraw = 1; + } + /* move cursor2 */ + /* set cursor position from master graph x-axis */ + else if(event == MotionNotify && (state & Button1Mask) && (xctx->graph_flags & 32 )) { + double c; + int floaters = there_are_floaters(); - - - + c = G_X(xctx->mousex); + if(gr->logx) c = pow(10, c); + if(r->flags & 4) { /* private_cursor */ + my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "cursor2_x", dtoa(c))); + } else { + xctx->graph_cursor2_x = c; + } + if(tclgetboolvar("live_cursor2_backannotate")) { + backannotate_at_cursor_b_pos(r, gr); + if(floaters) set_modify(-2); /* update floater caches to reflect actual backannotation */ + need_fullredraw = 1; + } else { + need_all_redraw = 1; + } + } if(xctx->ui_state & GRAPHPAN) goto finish; /* After GRAPHPAN only need to check Motion events for cursors */ if(xctx->mousey_snap < W_Y(gr->gy2)) { @@ -925,53 +949,6 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int } } - - - /* move cursor1 */ - /* set cursor position from master graph x-axis */ - else if(event == MotionNotify && (state & Button1Mask) && (xctx->graph_flags & 16 )) { - double c; - - /* selected or locked or master */ - if( r->sel || !(r->flags & 2) || i == xctx->graph_master) { - c = G_X(xctx->mousex); - if(gr->logx) c = pow(10, c); - if(r->flags & 4) { /* private_cursor */ - my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "cursor1_x", dtoa(c))); - } else { - xctx->graph_cursor1_x = c; - } - need_all_redraw = 1; - } - } - /* move cursor2 */ - /* set cursor position from master graph x-axis */ - else if(event == MotionNotify && (state & Button1Mask) && (xctx->graph_flags & 32 )) { - double c; - int floaters = there_are_floaters(); - - /* selected or locked or master */ - if( r->sel || !(r->flags & 2) || i == xctx->graph_master) { - c = G_X(xctx->mousex); - if(gr->logx) c = pow(10, c); - if(r->flags & 4) { /* private_cursor */ - my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "cursor2_x", dtoa(c))); - } else { - xctx->graph_cursor2_x = c; - } - if(tclgetboolvar("live_cursor2_backannotate")) { - backannotate_at_cursor_b_pos(r, gr); - if(floaters) set_modify(-2); /* update floater caches to reflect actual backannotation */ - need_fullredraw = 1; - } else { - need_all_redraw = 1; - } - } - } - - - - else if(event == ButtonPress && button == Button5 && !(state & ShiftMask)) { double delta; /* vertical move of waveforms with mouse wheel */ @@ -2024,9 +2001,10 @@ static int handle_mouse_wheel(int event, int mx, int my, KeySym key, int button, return 0; } -static void end_shape_point_edit() +static void end_shape_point_edit(double c_snap) { int save = xctx->modified; + double sx, sy; dbg(1, "%g %g %g %g\n", xctx->mx_double_save, xctx->my_double_save, xctx->mousex_snap, xctx->mousey_snap); if(xctx->lastsel == 1 && xctx->sel_array[0].type==POLYGON) { @@ -2072,7 +2050,10 @@ static void end_shape_point_edit() xctx->shape_point_selected = 0; xctx->need_reb_sel_arr=1; } - if(xctx->mx_double_save == xctx->mousex_snap && xctx->my_double_save == xctx->mousey_snap) { + sx = my_round(xctx->mx_double_save / c_snap) * c_snap; + sy = my_round(xctx->my_double_save / c_snap) * c_snap; + + if(sx == xctx->mousex_snap && sy == xctx->mousey_snap) { set_modify(save); } } @@ -4169,7 +4150,7 @@ int rstate; /* (reduced state, without ShiftMask) */ /* if a polygon/bezier/rectangle control point was clicked, end point move operation * and set polygon state back to SELECTED from SELECTED1 */ else if((xctx->ui_state & (STARTMOVE | SELECTION)) && xctx->shape_point_selected) { - end_shape_point_edit(); + end_shape_point_edit(c_snap); } if(xctx->ui_state & STARTPAN) { diff --git a/src/draw.c b/src/draw.c index df693b78..2066be3d 100644 --- a/src/draw.c +++ b/src/draw.c @@ -561,7 +561,6 @@ void draw_symbol(int what,int c, int n,int layer,short tmp_flip, short rot, disabled = 1; } - if( (layer != PINLAYER && !xctx->enable_layer[layer]) ) return; if(!has_x) return; if( (xctx->inst[n].flags & HIDE_INST) || (xctx->hide_symbols==1 && (xctx->inst[n].ptr+ xctx->sym)->prop_ptr && @@ -620,6 +619,9 @@ void draw_symbol(int what,int c, int n,int layer,short tmp_flip, short rot, x0=xctx->inst[n].x0 + xoffset; y0=xctx->inst[n].y0 + yoffset; symptr = (xctx->inst[n].ptr+ xctx->sym); + + if( (layer != PINLAYER && !xctx->enable_layer[layer]) ) goto draw_texts; + if(!hide) { for(j=0;j< symptr->lines[layer]; ++j) { @@ -713,6 +715,9 @@ void draw_symbol(int what,int c, int n,int layer,short tmp_flip, short rot, } } } + + draw_texts: + if( !(xctx->inst[n].flags & HIDE_SYMBOL_TEXTS) && ( diff --git a/src/save.c b/src/save.c index 83a6edcf..c19593e5 100644 --- a/src/save.c +++ b/src/save.c @@ -4629,10 +4629,12 @@ int load_sym_def(const char *name, FILE *embed_fd) my_free(_ALLOC_ID_, &path); dbg(1, " --> tt[i].txt_ptr=%s\n", tt[i].txt_ptr); } - if(!strcmp(tt[i].txt_ptr, "@spice_get_current")) { + /* @spice_get_current or @spice_get_current */ + if(!strncmp(tt[i].txt_ptr, "@spice_get_current", 18)) { /* prop_ptr is the attribute string of last loaded LCC component */ const char *dev; size_t new_size = 0; + char *txt_ptr = NULL; char *path = NULL; if(level > 1) { /* add parent LCC instance names (X1, Xinv etc) */ int i; @@ -4644,11 +4646,13 @@ int load_sym_def(const char *name, FILE *embed_fd) } if(path) new_size += strlen(path); dev = get_tok_value(prop_ptr, "name", 0); - new_size += strlen(dev) + 21; /* @spice_get_current() */ - my_realloc(_ALLOC_ID_, &tt[i].txt_ptr, new_size); - my_snprintf(tt[i].txt_ptr, new_size, "@spice_get_current(%s%s)", path ? path : "", dev); + new_size += strlen(tt[i].txt_ptr) + strlen(dev) + 2 + 1; /* tok() */ + my_realloc(_ALLOC_ID_, &txt_ptr, new_size); + my_snprintf(txt_ptr, new_size, "%s(%s%s)", tt[i].txt_ptr, path ? path : "", dev); + my_free(_ALLOC_ID_, &tt[i].txt_ptr); + tt[i].txt_ptr = txt_ptr; my_free(_ALLOC_ID_, &path); - dbg(1, " --> tt[i].txt_ptr=%s\n", tt[i].txt_ptr); + dbg(1, "--> tt[i].txt_ptr=%s\n", tt[i].txt_ptr); } ROTATION(rot, flip, 0.0, 0.0, tt[i].x0, tt[i].y0, rx1, ry1); tt[i].x0 = lcc[level].x0 + rx1; tt[i].y0 = lcc[level].y0 + ry1; diff --git a/src/scheduler.c b/src/scheduler.c index 799a01e4..b2e99256 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -5591,6 +5591,29 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg Tcl_SetResult(interp, s, TCL_VOLATILE); my_free(_ALLOC_ID_, &s); } + /* symbol_base_name n + * Return the base_name field of a symbol with name or number `n` + * Normally this is empty. It is set for overloaded symbols, that is symbols + * derived from the base symbol due to instance based implementation selection + * (the instance "schematic" attribute) */ + else if(!strcmp(argv[1], "symbol_base_name")) + { + int i = -1, found = 0; + if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;} + if(argc > 2 && argv[2][0]) { + i = get_symbol(argv[2]); + if(i >=0) { + found = 1; + } + } + if(found) { + Tcl_AppendResult(interp, xctx->sym[i].base_name, NULL); + } else { + Tcl_SetResult(interp, "Missing arguments or symbol not found", TCL_STATIC); + return TCL_ERROR; + } + } + /* symbol_in_new_window [new_process] * When a symbol is selected edit it in a new tab/window if not already open. diff --git a/src/token.c b/src/token.c index 31c0b2cb..145c8e63 100644 --- a/src/token.c +++ b/src/token.c @@ -3723,6 +3723,7 @@ const char *spice_get_node(const char *token) /* if s==NULL return emty string */ const char *translate(int inst, const char* s) { + static regex_t *get_sp_cur = NULL; static const char *empty=""; static char *translated_tok = NULL; static char *result=NULL; /* safe to keep even with multiple schematics */ @@ -3746,10 +3747,20 @@ const char *translate(int inst, const char* s) int sim_is_xyce; char *instname = NULL; + if(!get_sp_cur) { + get_sp_cur = my_malloc(_ALLOC_ID_, sizeof(regex_t)); + /* @spice_get_current_param(...) or @spice_get_modelparam_param(...) */ + /* @spice_get_current(...) or @spice_get_modelparam(...) */ + /* @spice_get_modelvoltage(...) or @spice_get_modelvoltage_param(...) */ + regcomp(get_sp_cur, + "^@spice_get_(current|modelparam|modelvoltage)(_[a-zA-Z][a-zA-Z0-9_]*)*\\(", REG_NOSUB | REG_EXTENDED); + } + sp_prefix = tclgetboolvar("spiceprefix"); if(!s || !xctx || !xctx->inst) { my_free(_ALLOC_ID_, &result); my_free(_ALLOC_ID_, &translated_tok); + regfree(get_sp_cur); return empty; } if(inst >= xctx->instances) { @@ -3770,6 +3781,7 @@ const char *translate(int inst, const char* s) while(1) { + c=*s++; if(c=='\\') { escape=1; @@ -4074,16 +4086,22 @@ const char *translate(int inst, const char* s) } } } - else if(strncmp(token,"@spice_get_current(", 19)==0 ) + /* @spice_get_current(...) or @spice_get_current_param(...) + * @spice_get_modelparam(...) or @spice_get_modelparam_param(...) + * @spice_get_modelvoltage(...) or @spice_get_modelvoltage_param(...) + * + * Only @spice_get_current(...) and @spice_get_current_param(...) are processed + * the other types are ignored */ + else if(!regexec(get_sp_cur, token, 0 , NULL, 0) ) { int start_level; /* hierarchy level where waves were loaded */ int live = tclgetboolvar("live_cursor2_backannotate"); if(live && (start_level = sch_waves_loaded()) >= 0 && xctx->raw->annot_p>=0) { char *fqdev = NULL; const char *path = xctx->sch_path[xctx->currsch] + 1; - char *dev = NULL; + char *dev = NULL, *param = NULL; size_t len; - int idx, n; + int idx, n = 0; double val = 0.0; const char *valstr; tmp = strlen(token) + 1; @@ -4095,8 +4113,18 @@ const char *translate(int inst, const char* s) ++path; } dev = my_malloc(_ALLOC_ID_, tmp); - n = sscanf(token + 19, "%[^)]", dev); - if(n == 1) { + dbg(1, "%s\n", token); + if(!strncmp(token, "@spice_get_current(", 19)) { + n = sscanf(token + 19, "%[^)]", dev); + } else { + param = my_malloc(_ALLOC_ID_, tmp); + n = sscanf(token, "@spice_get_current_%s(%[^)]", param, dev); + if(n < 2) { + my_free(_ALLOC_ID_, ¶m); + n = sscanf(token, "@spice_get_current[^(](%[^)]", dev); + } + } + if(n >= 1) { strtolower(dev); len = strlen(path) + strlen(instname) + strlen(dev) + 21; /* some extra chars for i(..) wrapper */ @@ -4109,14 +4137,17 @@ const char *translate(int inst, const char* s) else prefix=dev[0]; dbg(1, "prefix=%c, path=%s\n", prefix, path); vsource = (prefix == 'v') || (prefix == 'e'); - if(vsource) my_snprintf(fqdev, len, "i(%c.%s%s.%s)", prefix, path, instname, dev); - else if(prefix == 'q') - my_snprintf(fqdev, len, "i(@%c.%s%s.%s[ic])", prefix, path, instname, dev); - else if(prefix == 'd' || prefix == 'm') - my_snprintf(fqdev, len, "i(@%c.%s%s.%s[id])", prefix, path, instname, dev); - else if(prefix == 'i') + if(vsource) { + my_snprintf(fqdev, len, "i(%c.%s%s.%s)", prefix, path, instname, dev); + } else if(prefix == 'q') { + my_snprintf(fqdev, len, "i(@%c.%s%s.%s[%s])", prefix, path, instname, dev, param ? param : "ic"); + } else if(prefix == 'd' || prefix == 'm') { + my_snprintf(fqdev, len, "i(@%c.%s%s.%s[%s])", prefix, path, instname, dev, param ? param : "id"); + } else if(prefix == 'i') { my_snprintf(fqdev, len, "i(@%c.%s%s.%s[current])", prefix, path, instname, dev); - else my_snprintf(fqdev, len, "i(@%c.%s%s.%s[i])", prefix, path, instname, dev); + } else { + my_snprintf(fqdev, len, "i(@%c.%s%s.%s[i])", prefix, path, instname, dev); + } } else { my_snprintf(fqdev, len, "i(%s%s.%s)", path, instname, dev); } @@ -4144,6 +4175,7 @@ const char *translate(int inst, const char* s) dbg(1, "instname %s, dev=%s, fqdev=%s idx=%d valstr=%s\n", instname, dev, fqdev, idx, valstr); my_free(_ALLOC_ID_, &fqdev); } /* if(n == 1) */ + if(param) my_free(_ALLOC_ID_, ¶m); my_free(_ALLOC_ID_, &dev); } /* if(path) */ } /* if((start_level = sch_waves_loaded()) >= 0 && xctx->raw->annot_p>=0) */ @@ -4214,16 +4246,22 @@ const char *translate(int inst, const char* s) } } } - else if(strcmp(token,"@spice_get_current")==0 ) + else if( + strncmp(token,"@spice_get_current", 18)==0 || + strncmp(token,"@spice_get_modelparam", 21)==0 || + strncmp(token,"@spice_get_modelvoltage", 23)==0 + ) { int start_level; /* hierarchy level where waves were loaded */ int live = tclgetboolvar("live_cursor2_backannotate"); if(live && (start_level = sch_waves_loaded()) >= 0 && xctx->raw->annot_p>=0) { char *fqdev = NULL; const char *path = xctx->sch_path[xctx->currsch] + 1; - char *dev = NULL; + char *dev = NULL, *param = NULL; + int modelparam = 0; /* 0: current, 1: modelparam, 2: modelvoltage */ size_t len; int idx; + int error = 0; double val = 0.0; const char *valstr; if(path) { @@ -4233,54 +4271,94 @@ const char *translate(int inst, const char* s) if(*path == '.') skip++; ++path; } - my_strdup2(_ALLOC_ID_, &dev, instname); - strtolower(dev); - len = strlen(path) + strlen(dev) + 21; /* some extra chars for i(..) wrapper */ - dbg(1, "dev=%s\n", dev); - fqdev = my_malloc(_ALLOC_ID_, len); - if(!sim_is_xyce) { - int prefix=dev[0]; - int vsource = (prefix == 'v') || (prefix == 'e'); - if(path[0]) { - if(vsource) my_snprintf(fqdev, len, "i(%c.%s%s)", prefix, path, dev); - else if(prefix=='q') my_snprintf(fqdev, len, "i(@%c.%s%s[ic])", prefix, path, dev); - else if(prefix=='d' || prefix == 'm') my_snprintf(fqdev, len, "i(@%c.%s%s[id])", prefix, path, dev); - else if(prefix=='i') my_snprintf(fqdev, len, "i(@%c.%s%s[current])", prefix, path, dev); - else my_snprintf(fqdev, len, "i(@%c.%s%s[i])", prefix, path, dev); - } else { - if(vsource) my_snprintf(fqdev, len, "i(%s)", dev); - else if(prefix == 'q') my_snprintf(fqdev, len, "i(@%s[ic])", dev); - else if(prefix == 'd' || prefix == 'm') my_snprintf(fqdev, len, "i(@%s[id])", dev); - else if(prefix == 'i') my_snprintf(fqdev, len, "i(@%s[current])", dev); - else my_snprintf(fqdev, len, "i(@%s[i])", dev); + /* token contans _param after @spice_get_current or @spice_get_modelparam + * or @spice_get_modelvoltage */ + if(strcmp(token, "@spice_get_current") && + strcmp(token, "@spice_get_modelparam") && + strcmp(token, "@spice_get_modelvoltage")) { + int n = 0; + param = my_malloc(_ALLOC_ID_, strlen(token) + 1); + n = sscanf(token, "@spice_get_current_%s", param); + if(n == 0) { + n = sscanf(token, "@spice_get_modelparam_%s", param); + modelparam = 1; + } + if(n == 0) { + n = sscanf(token, "@spice_get_modelvoltage_%s", param); + modelparam = 2; + } + if(n == 0) { + my_free(_ALLOC_ID_, ¶m); + error = 1; } - } else { - my_snprintf(fqdev, len, "i(%s%s)", path, dev); } - dbg(1, "fqdev=%s\n", fqdev); - strtolower(fqdev); - idx = get_raw_index(fqdev, NULL); - if(idx >= 0) { - val = xctx->raw->cursor_b_val[idx]; - } - if(idx < 0) { - valstr = "-"; - xctx->tok_size = 1; - len = 1; - } else { - valstr = engineering ? dtoa_eng(val) : dtoa(val); - len = xctx->tok_size; - } - if(len) { - STR_ALLOC(&result, len + result_pos, &size); - memcpy(result+result_pos, valstr, len+1); - result_pos += len; - } - dbg(1, "instname %s, dev=%s, fqdev=%s idx=%d valstr=%s\n", instname, dev, fqdev, idx, valstr); - my_free(_ALLOC_ID_, &fqdev); - my_free(_ALLOC_ID_, &dev); - } - } + if(!error) { + char *iprefix = modelparam == 0 ? "i(" : modelparam == 1 ? "" : "v("; + char *ipostfix = modelparam == 1 ? "" : ")"; + my_strdup2(_ALLOC_ID_, &dev, instname); + strtolower(dev); + len = strlen(path) + strlen(dev) + 40; /* some extra chars for i(..) wrapper */ + dbg(1, "token=%s, dev=%s param=%s\n", token, dev, param ? param : ""); + fqdev = my_malloc(_ALLOC_ID_, len); + if(!sim_is_xyce) { + int prefix=dev[0]; + int vsource = (prefix == 'v') || (prefix == 'e'); + if(path[0]) { + if(vsource) { + my_snprintf(fqdev, len, "i(%c.%s%s)", prefix, path, dev); + } else if(prefix=='q') { + my_snprintf(fqdev, len, "%s@%c.%s%s[%s]%s", + iprefix, prefix, path, dev, param ? param : "ic", ipostfix); + } else if(prefix=='d' || prefix == 'm') { + my_snprintf(fqdev, len, "%s@%c.%s%s[%s]%s", + iprefix, prefix, path, dev, param ? param : "id", ipostfix); + } else if(prefix=='i') { + my_snprintf(fqdev, len, "i(@%c.%s%s[current])", prefix, path, dev); + } else { + my_snprintf(fqdev, len, "i(@%c.%s%s[i])", prefix, path, dev); + } + } else { + if(vsource) { + my_snprintf(fqdev, len, "i(%s)", dev); + } else if(prefix == 'q') { + my_snprintf(fqdev, len, "%s@%s[%s]%s", iprefix, dev, param ? param : "ic", ipostfix); + } else if(prefix == 'd' || prefix == 'm') { + my_snprintf(fqdev, len, "%s@%s[%s]%s", iprefix, dev, param ? param : "id", ipostfix); + } else if(prefix == 'i') { + my_snprintf(fqdev, len, "i(@%s[current])", dev); + } else { + my_snprintf(fqdev, len, "i(@%s[i])", dev); + } + } + } else { + my_snprintf(fqdev, len, "i(%s%s)", path, dev); + } + if(param) my_free(_ALLOC_ID_, ¶m); + dbg(1, "fqdev=%s\n", fqdev); + strtolower(fqdev); + idx = get_raw_index(fqdev, NULL); + if(idx >= 0) { + val = xctx->raw->cursor_b_val[idx]; + } + if(idx < 0) { + valstr = "-"; + xctx->tok_size = 1; + len = 1; + } else { + valstr = engineering ? dtoa_eng(val) : dtoa(val); + len = xctx->tok_size; + } + if(len) { + STR_ALLOC(&result, len + result_pos, &size); + memcpy(result+result_pos, valstr, len+1); + result_pos += len; + } + dbg(1, "instname %s, dev=%s, fqdev=%s idx=%d valstr=%s\n", instname, dev, fqdev, idx, valstr); + my_free(_ALLOC_ID_, &fqdev); + my_free(_ALLOC_ID_, &dev); + } /* if(!error) */ + } /* if(path) */ + } /* (live && (start_level = sch_waves_loaded()) >= 0 && xctx->raw->annot_p>=0) */ } else if(strcmp(token,"@schvhdlprop")==0 && xctx->schvhdlprop) { diff --git a/src/xinit.c b/src/xinit.c index 1fbc00a1..e3d48898 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -1990,6 +1990,7 @@ static void destroy_all_tabs(int *window_count, int force) xctx = savectx; /* restore previous schematic or main if old is destroyed */ tclvareval("restore_ctx ", xctx->current_win_path, " ; housekeeping_ctx", NULL); set_modify(-1); /* sets window title */ + draw(); } } diff --git a/src/xschem.tcl b/src/xschem.tcl index 18ac45d9..24b5da01 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -1770,29 +1770,31 @@ proc simconf_add {tool} { ############ cellview # proc cellview prints symbol bindings (default binding or "schematic" attr in symbol) # of all symbols used in current and sub schematics. -proc cellview_setlabels {w symbol sym_sch default_sch sym_spice_sym_def} { +proc cellview_setlabels {w symbol sym_sch sym_spice_sym_def derived_symbol} { global dark_gui_colorscheme if {$dark_gui_colorscheme} { + set instfg orange1 set symfg SeaGreen1 set symbg SeaGreen4 set missingbg IndianRed4 } else { + set instfg orange4 set symfg SeaGreen4 set symbg SeaGreen1 set missingbg IndianRed1 } $w configure -fg [option get . foreground {}] $w configure -bg [option get . background {}] - if { $sym_spice_sym_def ne {}} { + if { $derived_symbol} { + $w configure -fg $instfg + } elseif {$sym_spice_sym_def ne {} } { $w configure -fg $symfg - } else { - if {[$w get] eq $default_sch} { - puts "$symbol: need to clear schematic attr in symbol" - } elseif {[$w get] eq $sym_sch} { - $w configure -bg $symbg - } else { - puts "need to update:[$w get] --> $sym_sch" - } + } + puts =============== + puts sym_sch=$sym_sch + puts symbol=$symbol + + if { $sym_spice_sym_def eq {}} { if { ![file exists [abs_sym_path [$w get]]] } { $w configure -bg $missingbg } @@ -1811,8 +1813,31 @@ proc cellview_edit_item {w sym_spice_sym_def} { } } +proc cellview_edit_sym {w} { + set sym [$w cget -text] + set res [catch {xschem symbol_base_name $sym} base_name] + if {$res == 0} { + if {$base_name ne {}} { + set sym $base_name + } + } + xschem load_new_window $sym +} + proc cellview {{derived_symbols {}}} { - global keep_symbols nolist_libs + global keep_symbols nolist_libs dark_gui_colorscheme + + if {$dark_gui_colorscheme} { + set instfg orange1 + set symfg SeaGreen1 + set symbg SeaGreen4 + set missingbg IndianRed4 + } else { + set instfg orange4 + set symfg SeaGreen4 + set symbg SeaGreen1 + set missingbg IndianRed1 + } if {[info tclversion] >= 8.5} { set font {TkDefaultFont 10 bold} ;# Monospace @@ -1820,6 +1845,7 @@ proc cellview {{derived_symbols {}}} { set font fixed } toplevel .cv + xschem reload_symbols ;# purge unused symbols set save_keep $keep_symbols set keep_symbols 1 ;# keep all symbols when doing a hierarchic netlist xschem netlist ;# traverse the hierarchy and retain all encountered symbols @@ -1830,7 +1856,7 @@ proc cellview {{derived_symbols {}}} { frame .cv.top label .cv.top.sym -text { SYMBOL} -width 30 -bg grey60 -anchor w -padx 4 -font $font label .cv.top.sch -text SCHEMATIC -width 45 -bg grey60 -anchor w -padx 4 -font $font - label .cv.top.pad -text { } -width 1 -bg grey60 -font $font + label .cv.top.pad -text { } -width 4 -bg grey60 -font $font pack .cv.top.sym .cv.top.sch -side left -fill x -expand 1 pack .cv.top.pad -side left -fill x frame .cv.center @@ -1838,9 +1864,17 @@ proc cellview {{derived_symbols {}}} { # puts sf=$sf set syms [join [lsort -index 1 [xschem symbols $derived_symbols]]] foreach {i symbol} $syms { + set base_name [xschem symbol_base_name $symbol] + set derived_symbol 0 + if {$base_name ne {}} { + set derived_symbol 1 + } set abs_sch [xschem get_sch_from_sym -1 $symbol] - set abs_sym [abs_sym_path $symbol] - set default_sch [add_ext $symbol .sch] + if {$derived_symbol} { + set abs_sym [abs_sym_path $base_name] + } else { + set abs_sym [abs_sym_path $symbol] + } set skip 0 foreach j $nolist_libs { if {[regexp $j $abs_sym]} { @@ -1851,28 +1885,53 @@ proc cellview {{derived_symbols {}}} { if {$skip} { continue } set sym_sch [rel_sym_path $abs_sch] set type [xschem getprop symbol $symbol type] - set sym_spice_sym_def [xschem getprop symbol $symbol spice_sym_def] + set sym_spice_sym_def [xschem getprop symbol $symbol spice_sym_def 2] if {$type eq {subcircuit}} { frame $sf.f$i pack $sf.f$i -side top -fill x label $sf.f$i.l -text $symbol -width 30 -anchor w -padx 4 -borderwidth 1 \ -relief sunken -pady 1 -font $font + if {$derived_symbol} { + $sf.f$i.l configure -fg $instfg + } # puts $sf.f$i.s entry $sf.f$i.s -width 45 -borderwidth 1 -relief sunken -font $font - balloon $sf.f$i.s $abs_sch - button $sf.f$i.b -text Sch -padx 4 -borderwidth 1 -pady 0 -font $font \ + button $sf.f$i.sym -text Sym -padx 4 -borderwidth 1 -pady 0 -font $font \ + -command "cellview_edit_sym $sf.f$i.l" + button $sf.f$i.sch -text Sch -padx 4 -borderwidth 1 -pady 0 -font $font \ -command "cellview_edit_item $sf.f$i.s [list $sym_spice_sym_def]" if {$sym_spice_sym_def eq {}} { $sf.f$i.s insert 0 $sym_sch } else { - $sf.f$i.s insert 0 {defined in symbol spice_sym_def} + if {$derived_symbol} { + $sf.f$i.s insert 0 {defined in instance spice_sym_def} + } else { + $sf.f$i.s insert 0 {defined in symbol spice_sym_def} + } } + if {[xschem is_generator [ $sf.f$i.s get]]} { + set f [ $sf.f$i.s get] + regsub {\(.*} $f {} f + } elseif { $sym_spice_sym_def eq {}} { + set f [abs_sym_path [$sf.f$i.s get]] + } else { + set ff [split $sym_spice_sym_def \n] + puts ff=$ff + if {[llength $ff] > 5} { + set ff [lrange $ff 0 4] + lappend ff ... + } + set f [join $ff \n] + puts f=$f + } + balloon $sf.f$i.s $f + bind $sf.f$i.s " - cellview_setlabels %W [list $symbol] [list $sym_sch] [list $default_sch] [list $sym_spice_sym_def] + cellview_setlabels %W [list $symbol] [list $sym_sch] [list $sym_spice_sym_def] $derived_symbol " - cellview_setlabels $sf.f$i.s $symbol $sym_sch $default_sch $sym_spice_sym_def + cellview_setlabels $sf.f$i.s $symbol $sym_sch $sym_spice_sym_def $derived_symbol pack $sf.f$i.l $sf.f$i.s -side left -fill x -expand 1 - pack $sf.f$i.b -side left + pack $sf.f$i.sch $sf.f$i.sym -side left } } frame .cv.bottom @@ -1888,7 +1947,6 @@ proc cellview {{derived_symbols {}}} { bind .cv { sframeyview .cv.center scroll -0.1} bind .cv { sframeyview .cv.center scroll 0.1} bind .cv {destroy .cv} - xschem reload_symbols ;# purge all symbols used in below hierarchies } ############ /cellview @@ -5071,7 +5129,7 @@ proc tclcmd {} { proc select_layers {} { global dark_colorscheme enable_layer - xschem set semaphore [expr {[xschem get semaphore] +1}] + # xschem set semaphore [expr {[xschem get semaphore] +1}] toplevel .sl -class Dialog wm transient .sl [xschem get topwindow] if { $dark_colorscheme == 1 } { @@ -5124,6 +5182,7 @@ proc select_layers {} { -selectcolor $ind_bg -anchor w -foreground $layfg -background $i -activebackground $i \ -command { xschem enable_layers + xschem redraw } pack .sl.f0.f$f.cb$j -side top -fill x incr j @@ -5133,8 +5192,8 @@ proc select_layers {} { pack .sl.f0.f$f -side left -fill y } } - tkwait window .sl - xschem set semaphore [expr {[xschem get semaphore] -1}] + # tkwait window .sl + # xschem set semaphore [expr {[xschem get semaphore] -1}] } proc color_dim {} { diff --git a/xschem_library/ngspice/diode_ngspice.sym b/xschem_library/ngspice/diode_ngspice.sym index 002e17fe..76f5bd95 100644 --- a/xschem_library/ngspice/diode_ngspice.sym +++ b/xschem_library/ngspice/diode_ngspice.sym @@ -1,4 +1,4 @@ -v {xschem version=3.4.4 file_version=1.2 +v {xschem version=3.4.6 file_version=1.2 * * This file is part of XSCHEM, * a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit @@ -37,5 +37,7 @@ B 5 -2.5 -32.5 2.5 -27.5 {name=plus dir=inout pinnumber=1 propag=1 goto=1} B 5 -2.5 27.5 2.5 32.5 {name=minus dir=inout pinnumber=2 goto=0} P 4 4 -0 5 -10 -5 10 -5 0 5 {fill=true} T {@name} 15 -18.75 0 0 0.2 0.2 {} -T {@#0:net_name} 10 -28.75 0 0 0.15 0.15 {layer=15} -T {@#1:net_name} 10 20 0 0 0.15 0.15 {layer=15} +T {@#0:net_name} 10 -28.75 0 0 0.15 0.15 {layer=15 +hide=instance} +T {@#1:net_name} 10 20 0 0 0.15 0.15 {layer=15 +hide=instance} diff --git a/xschem_library/ngspice/solar_panel.sch b/xschem_library/ngspice/solar_panel.sch index 8cd6c87a..046ef49c 100644 --- a/xschem_library/ngspice/solar_panel.sch +++ b/xschem_library/ngspice/solar_panel.sch @@ -295,7 +295,7 @@ lab=0} C {title.sym} 160 -40 0 0 {name=l1 author="Stefan Schippers"} C {code_shown.sym} 170 -310 0 0 {name=CONTROL value="tcleval( -.option savecurrents +.probe alli .control * example of tcl evaluation of code blocks: * current path: $path