added symbol attributes @spice_get_current_<param>, @spice_get_modelparam_<param>, @spice_get_modelvoltage_<param>
This commit is contained in:
parent
f79f9ecf1d
commit
315c5bd600
|
|
@ -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>
|
||||
|
|
|
|||
189
src/token.c
189
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<n>(...) */
|
||||
/* @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 : "<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 {
|
||||
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)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue