Merge branch 'StefanSchippers:master' into master
This commit is contained in:
commit
378c2ea115
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) &&
|
||||
(
|
||||
|
|
|
|||
14
src/save.c
14
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<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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
198
src/token.c
198
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 : "<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_, ¶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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
109
src/xschem.tcl
109
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 <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 {} {
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue