Merge branch 'StefanSchippers:master' into master

This commit is contained in:
Chayan Deb 2025-01-17 11:37:48 +05:30 committed by GitHub
commit 378c2ea115
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 335 additions and 154 deletions

View File

@ -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 </pre>
<li><kbd> subst_tok str tok newval</kbd></li><pre>
Return string 'str' with 'tok' attribute value replaced with 'newval' </pre>
<li><kbd> symbol_base_name n</kbd></li><pre>
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) </pre>
<li><kbd> symbol_in_new_window [new_process]</kbd></li><pre>
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).

View File

@ -619,6 +619,29 @@ verilog_format="xnor #(@risedel , @falldel ) @name ( @@Z , @@A , @@B );"
sequence number <kbd>n</kbd>, extracted from simulation raw file (operating point or
cursor <kbd>b</kbd> position)</p>
<li><kbd>@spice_get_voltage</kbd></li>
<p> This attribute will be replaced by the voltage of the net attached to the first pin (pin number 0)
of the symbol </p>
<li><kbd>@spice_get_current</kbd></li>
<p> 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 <kbd>@spice_get_current</kbd> will display the
drain current of a mosfet if this attribute is placed inside a MOS symbol.</p>
<li><kbd>@spice_get_current_param</kbd></li>
<p> This will specify in <kbd>param</kbd> the current to display, for example: <br>
<kbd>@spice_get_current_ibs</kbd> to get the body-source current in a Mosfet,
<kbd>@spice_get_current_ie</kbd> to get the emitter current in a Bjt.</p>
<li><kbd>@spice_get_modelvoltage_param</kbd></li>
<p> This will specify in <kbd>param</kbd> the voltage to display, for example: <br>
<kbd>@spice_get_modelvoltage_vth</kbd> to get the Vth in a Mosfet</p>
<li><kbd>@spice_get_modelparam_param</kbd></li>
<p> This will specify in <kbd>param</kbd> the model parameter to display, for example: <br>
<kbd>@spice_get_modelparam_gm</kbd> to get the transconductance in a Mosfet</p>
<li><kbd>@spice_get_node spice_node </kbd></li>
<p>
<kbd>spice_node</kbd> Will be replaced with the Spice simulated value for that node.<br>

View File

@ -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) {

View File

@ -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) &&
(

View File

@ -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<n> */
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(<dev>) */
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(<dev>) */
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;

View File

@ -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.

View File

@ -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_, &param);
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_, &param);
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_, &param);
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 : "<NULL>");
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_, &param);
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)
{

View File

@ -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();
}
}

View File

@ -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 <KeyRelease> "
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 <ButtonPress-4> { sframeyview .cv.center scroll -0.1}
bind .cv <ButtonPress-5> { sframeyview .cv.center scroll 0.1}
bind .cv <Escape> {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 {} {

View File

@ -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}

View File

@ -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