From 10991e662c62b0d0559417c2cea3a95e4d7c5782 Mon Sep 17 00:00:00 2001
From: stefan schippers
Date: Wed, 15 Jan 2025 00:44:39 +0100
Subject: [PATCH 1/9] added `xschem symbol_base_name` command to get the base
symbol a symbol defined by instance `schematic` attribute comes from; updated
`celview` procedure
---
doc/xschem_man/developer_info.html | 5 ++
src/scheduler.c | 23 +++++++
src/xschem.tcl | 102 ++++++++++++++++++++++-------
3 files changed, 108 insertions(+), 22 deletions(-)
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/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/xschem.tcl b/src/xschem.tcl
index 11244c90..7edac6b3 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
From 7d6c3f47642ccbbb39f155518af4438138e41cb0 Mon Sep 17 00:00:00 2001
From: stefan schippers
Date: Wed, 15 Jan 2025 03:11:12 +0100
Subject: [PATCH 2/9] destroy_all_tabs() do a final redraw to avoid
inconsistent screen after some tab removals
---
src/xinit.c | 1 +
xschem_library/ngspice/diode_ngspice.sym | 8 +++++---
2 files changed, 6 insertions(+), 3 deletions(-)
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/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}
From f2b9d0c6f30bb17cb1b813f4118803a826b7c0a1 Mon Sep 17 00:00:00 2001
From: stefan schippers
Date: Wed, 15 Jan 2025 17:39:59 +0100
Subject: [PATCH 3/9] added attribute @spice_get_current for retrieving
current through terminal of primitive device; example:
@spice_get_current2 to get base current of BJT device
---
src/save.c | 14 +++++----
src/token.c | 83 +++++++++++++++++++++++++++++++++++++++--------------
2 files changed, 71 insertions(+), 26 deletions(-)
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/token.c b/src/token.c
index 31c0b2cb..c892b3b4 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,16 @@ 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));
+ regcomp(get_sp_cur, "^@spice_get_current[0-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 +3777,7 @@ const char *translate(int inst, const char* s)
while(1)
{
+
c=*s++;
if(c=='\\') {
escape=1;
@@ -4074,7 +4082,8 @@ const char *translate(int inst, const char* s)
}
}
}
- else if(strncmp(token,"@spice_get_current(", 19)==0 )
+ /* @spice_get_current(...) or @spice_get_current(...) */
+ 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");
@@ -4082,6 +4091,7 @@ const char *translate(int inst, const char* s)
char *fqdev = NULL;
const char *path = xctx->sch_path[xctx->currsch] + 1;
char *dev = NULL;
+ int ncurrent = 1;
size_t len;
int idx, n;
double val = 0.0;
@@ -4095,8 +4105,14 @@ const char *translate(int inst, const char* s)
++path;
}
dev = my_malloc(_ALLOC_ID_, tmp);
- n = sscanf(token + 19, "%[^)]", dev);
- if(n == 1) {
+ dbg(0, "%s\n", token);
+ if(!strncmp(token, "@spice_get_current(", 19)) {
+ n = sscanf(token + 19, "%[^)]", dev);
+ } else {
+ n = sscanf(token, "@spice_get_current%d(%[^)]", &ncurrent, dev);
+ dbg(0, "ncurrent=%d, dev=%s\n", ncurrent, dev);
+ }
+ if(n >= 1) {
strtolower(dev);
len = strlen(path) + strlen(instname) +
strlen(dev) + 21; /* some extra chars for i(..) wrapper */
@@ -4109,14 +4125,19 @@ 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') {
+ const char *current[] = {"ic", "ic", "ib", "ie"};
+ my_snprintf(fqdev, len, "i(@%c.%s%s.%s[%s])", prefix, path, instname, dev, current[ncurrent]);
+ } else if(prefix == 'd' || prefix == 'm') {
+ const char *current[] = {"id", "id", "ig", "is", "ib"};
+ my_snprintf(fqdev, len, "i(@%c.%s%s.%s[%s])", prefix, path, instname, dev, current[ncurrent]);
+ } 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);
}
@@ -4214,7 +4235,7 @@ 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 )
{
int start_level; /* hierarchy level where waves were loaded */
int live = tclgetboolvar("live_cursor2_backannotate");
@@ -4222,6 +4243,7 @@ const char *translate(int inst, const char* s)
char *fqdev = NULL;
const char *path = xctx->sch_path[xctx->currsch] + 1;
char *dev = NULL;
+ int ncurrent = 1;
size_t len;
int idx;
double val = 0.0;
@@ -4233,6 +4255,9 @@ const char *translate(int inst, const char* s)
if(*path == '.') skip++;
++path;
}
+ if(strcmp(token, "@spice_get_current")) {
+ if(sscanf(token, "@spice_get_current%d", &ncurrent) != 1) ncurrent = 1;
+ }
my_strdup2(_ALLOC_ID_, &dev, instname);
strtolower(dev);
len = strlen(path) + strlen(dev) + 21; /* some extra chars for i(..) wrapper */
@@ -4242,17 +4267,33 @@ const char *translate(int inst, const char* s)
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);
+ if(vsource) {
+ my_snprintf(fqdev, len, "i(%c.%s%s)", prefix, path, dev);
+ } else if(prefix=='q') {
+ const char *current[] = {"ic", "ic", "ib", "ie"};
+ my_snprintf(fqdev, len, "i(@%c.%s%s[%s])", prefix, path, dev, current[ncurrent]);
+ } else if(prefix=='d' || prefix == 'm') {
+ const char *current[] = {"id", "id", "ig", "is", "ib"};
+ my_snprintf(fqdev, len, "i(@%c.%s%s[%s])", prefix, path, dev, current[ncurrent]);
+ } 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);
+ if(vsource) {
+ my_snprintf(fqdev, len, "i(%s)", dev);
+ } else if(prefix == 'q') {
+ const char *current[] = {"ic", "ic", "ib", "ie"};
+ my_snprintf(fqdev, len, "i(@%s[%s])", dev, current[ncurrent]);
+ } else if(prefix == 'd' || prefix == 'm') {
+ const char *current[] = {"id", "id", "ig", "is", "ib"};
+ my_snprintf(fqdev, len, "i(@%s[%s])", dev, current[ncurrent]);
+ } else if(prefix == 'i') {
+ my_snprintf(fqdev, len, "i(@%s[current])");
+ } else {
+ my_snprintf(fqdev, len, "i(@%s[i])", dev);
+ }
}
} else {
my_snprintf(fqdev, len, "i(%s%s)", path, dev);
From f79f9ecf1dbdfbaaee463d2f44a4d6aa9ce35b12 Mon Sep 17 00:00:00 2001
From: stefan schippers
Date: Wed, 15 Jan 2025 19:12:30 +0100
Subject: [PATCH 4/9] removed dbg mesages
---
src/token.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/token.c b/src/token.c
index c892b3b4..d70a6ad4 100644
--- a/src/token.c
+++ b/src/token.c
@@ -4105,12 +4105,12 @@ const char *translate(int inst, const char* s)
++path;
}
dev = my_malloc(_ALLOC_ID_, tmp);
- dbg(0, "%s\n", token);
+ dbg(1, "%s\n", token);
if(!strncmp(token, "@spice_get_current(", 19)) {
n = sscanf(token + 19, "%[^)]", dev);
} else {
n = sscanf(token, "@spice_get_current%d(%[^)]", &ncurrent, dev);
- dbg(0, "ncurrent=%d, dev=%s\n", ncurrent, dev);
+ dbg(1, "ncurrent=%d, dev=%s\n", ncurrent, dev);
}
if(n >= 1) {
strtolower(dev);
From 315c5bd600945a596fda9a17a630d08009153476 Mon Sep 17 00:00:00 2001
From: stefan schippers
Date: Thu, 16 Jan 2025 02:52:52 +0100
Subject: [PATCH 5/9] added symbol attributes @spice_get_current_,
@spice_get_modelparam_, @spice_get_modelvoltage_
---
doc/xschem_man/symbol_property_syntax.html | 23 +++
src/token.c | 189 ++++++++++++---------
2 files changed, 136 insertions(+), 76 deletions(-)
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/token.c b/src/token.c
index d70a6ad4..8745aaf6 100644
--- a/src/token.c
+++ b/src/token.c
@@ -3749,7 +3749,11 @@ const char *translate(int inst, const char* s)
if(!get_sp_cur) {
get_sp_cur = my_malloc(_ALLOC_ID_, sizeof(regex_t));
- regcomp(get_sp_cur, "^@spice_get_current[0-9]*\\(", REG_NOSUB | REG_EXTENDED);
+ /* @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");
@@ -4082,7 +4086,12 @@ const char *translate(int inst, const char* s)
}
}
}
- /* @spice_get_current(...) or @spice_get_current(...) */
+ /* @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 */
@@ -4090,10 +4099,9 @@ const char *translate(int inst, const char* s)
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;
- int ncurrent = 1;
+ 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;
@@ -4109,8 +4117,12 @@ const char *translate(int inst, const char* s)
if(!strncmp(token, "@spice_get_current(", 19)) {
n = sscanf(token + 19, "%[^)]", dev);
} else {
- n = sscanf(token, "@spice_get_current%d(%[^)]", &ncurrent, dev);
- dbg(1, "ncurrent=%d, dev=%s\n", ncurrent, dev);
+ 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);
@@ -4128,11 +4140,9 @@ const char *translate(int inst, const char* s)
if(vsource) {
my_snprintf(fqdev, len, "i(%c.%s%s.%s)", prefix, path, instname, dev);
} else if(prefix == 'q') {
- const char *current[] = {"ic", "ic", "ib", "ie"};
- my_snprintf(fqdev, len, "i(@%c.%s%s.%s[%s])", prefix, path, instname, dev, current[ncurrent]);
+ my_snprintf(fqdev, len, "i(@%c.%s%s.%s[%s])", prefix, path, instname, dev, param ? param : "ic");
} else if(prefix == 'd' || prefix == 'm') {
- const char *current[] = {"id", "id", "ig", "is", "ib"};
- my_snprintf(fqdev, len, "i(@%c.%s%s.%s[%s])", prefix, path, instname, dev, current[ncurrent]);
+ 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 {
@@ -4165,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) */
@@ -4235,17 +4246,22 @@ const char *translate(int inst, const char* s)
}
}
}
- else if(strncmp(token,"@spice_get_current", 18)==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;
- int ncurrent = 1;
+ 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) {
@@ -4255,73 +4271,94 @@ const char *translate(int inst, const char* s)
if(*path == '.') skip++;
++path;
}
- if(strcmp(token, "@spice_get_current")) {
- if(sscanf(token, "@spice_get_current%d", &ncurrent) != 1) ncurrent = 1;
+ /* 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;
+ }
}
- 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') {
- const char *current[] = {"ic", "ic", "ib", "ie"};
- my_snprintf(fqdev, len, "i(@%c.%s%s[%s])", prefix, path, dev, current[ncurrent]);
- } else if(prefix=='d' || prefix == 'm') {
- const char *current[] = {"id", "id", "ig", "is", "ib"};
- my_snprintf(fqdev, len, "i(@%c.%s%s[%s])", prefix, path, dev, current[ncurrent]);
- } else if(prefix=='i') {
- my_snprintf(fqdev, len, "i(@%c.%s%s[current])", prefix, path, 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) + 21; /* 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 {
- my_snprintf(fqdev, len, "i(@%c.%s%s[i])", prefix, path, dev);
+ 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])");
+ } else {
+ my_snprintf(fqdev, len, "i(@%s[i])", dev);
+ }
}
} else {
- if(vsource) {
- my_snprintf(fqdev, len, "i(%s)", dev);
- } else if(prefix == 'q') {
- const char *current[] = {"ic", "ic", "ib", "ie"};
- my_snprintf(fqdev, len, "i(@%s[%s])", dev, current[ncurrent]);
- } else if(prefix == 'd' || prefix == 'm') {
- const char *current[] = {"id", "id", "ig", "is", "ib"};
- my_snprintf(fqdev, len, "i(@%s[%s])", dev, current[ncurrent]);
- } else if(prefix == 'i') {
- my_snprintf(fqdev, len, "i(@%s[current])");
- } else {
- my_snprintf(fqdev, len, "i(@%s[i])", dev);
- }
+ my_snprintf(fqdev, len, "i(%s%s)", path, dev);
}
- } 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(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)
{
From bcca65da908ae7483d2175e1b6c9f10754ceefdf Mon Sep 17 00:00:00 2001
From: stefan schippers
Date: Thu, 16 Jan 2025 15:35:11 +0100
Subject: [PATCH 6/9] translate(), @spice_get_current, typo led to missing
argument in printf()
---
src/token.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/token.c b/src/token.c
index 8745aaf6..145c8e63 100644
--- a/src/token.c
+++ b/src/token.c
@@ -4297,7 +4297,7 @@ const char *translate(int inst, const char* s)
char *ipostfix = modelparam == 1 ? "" : ")";
my_strdup2(_ALLOC_ID_, &dev, instname);
strtolower(dev);
- len = strlen(path) + strlen(dev) + 21; /* some extra chars for i(..) wrapper */
+ 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) {
@@ -4325,7 +4325,7 @@ const char *translate(int inst, const char* s)
} 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])");
+ my_snprintf(fqdev, len, "i(@%s[current])", dev);
} else {
my_snprintf(fqdev, len, "i(@%s[i])", dev);
}
From f2225677cc60195463840023868588ea1c05de05 Mon Sep 17 00:00:00 2001
From: stefan schippers
Date: Thu, 16 Jan 2025 16:03:34 +0100
Subject: [PATCH 7/9] fix regression in (V) cursor movement when multiple
side-by-side graphs are present
---
src/callback.c | 89 +++++++++++++++++++-------------------------------
1 file changed, 33 insertions(+), 56 deletions(-)
diff --git a/src/callback.c b/src/callback.c
index 9dfa4532..b4697452 100644
--- a/src/callback.c
+++ b/src/callback.c
@@ -451,12 +451,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;
@@ -481,11 +475,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)) {
@@ -909,53 +933,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 */
From ca6b8fe85b2b55c27a4e6e00b02ed0f42d7a57c4 Mon Sep 17 00:00:00 2001
From: stefan schippers
Date: Thu, 16 Jan 2025 17:19:42 +0100
Subject: [PATCH 8/9] end_shape_point_edit(): fix erroneous set_modify because
comparing unsmapped mouse saved coords with snapped actual mouse coords
---
src/callback.c | 10 +++++++---
xschem_library/ngspice/solar_panel.sch | 2 +-
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/src/callback.c b/src/callback.c
index b4697452..3b0e50ae 100644
--- a/src/callback.c
+++ b/src/callback.c
@@ -1985,9 +1985,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) {
@@ -2033,7 +2034,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);
}
}
@@ -4106,7 +4110,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/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
From c57c49fde8b9bdb03f9f85457ace7ae5d94c5f03 Mon Sep 17 00:00:00 2001
From: stefan schippers
Date: Thu, 16 Jan 2025 20:37:19 +0100
Subject: [PATCH 9/9] Hiding the TEXT layer will disable only symbol texts on
that layer, not all texts, `proc select_layers` make the widget non-modal
---
src/draw.c | 7 ++++++-
src/xschem.tcl | 7 ++++---
2 files changed, 10 insertions(+), 4 deletions(-)
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/xschem.tcl b/src/xschem.tcl
index 7edac6b3..ca81fb4a 100644
--- a/src/xschem.tcl
+++ b/src/xschem.tcl
@@ -5129,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 } {
@@ -5182,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
@@ -5191,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 {} {