Enable multiplier 'm' for behavioral resistor
(R using a B source).
This commit is contained in:
parent
02c87b129f
commit
c6d2c354a4
|
|
@ -182,6 +182,9 @@ static void ltspice_compat_a(struct card *oldcard);
|
||||||
static void inp_repair_dc_ps(struct card* oldcard);
|
static void inp_repair_dc_ps(struct card* oldcard);
|
||||||
static void inp_get_w_l_x(struct card* oldcard);
|
static void inp_get_w_l_x(struct card* oldcard);
|
||||||
|
|
||||||
|
static char* eval_m(char* line, char* tline);
|
||||||
|
static char* eval_tc(char* line, char* tline);
|
||||||
|
|
||||||
#ifndef EXT_ASC
|
#ifndef EXT_ASC
|
||||||
static void utf8_syntax_check(struct card *deck);
|
static void utf8_syntax_check(struct card *deck);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -744,7 +747,7 @@ struct card *inp_readall(FILE *fp, const char *dir_name,
|
||||||
inp_reorder_params(subckt_w_params, cc);
|
inp_reorder_params(subckt_w_params, cc);
|
||||||
|
|
||||||
/* Special handling for large PDKs: We need to know W and L of
|
/* Special handling for large PDKs: We need to know W and L of
|
||||||
transistor subcircuits by checking their x invokcation */
|
transistor subcircuits by checking their x invocation */
|
||||||
inp_get_w_l_x(working);
|
inp_get_w_l_x(working);
|
||||||
|
|
||||||
inp_fix_inst_calls_for_numparam(subckt_w_params, working);
|
inp_fix_inst_calls_for_numparam(subckt_w_params, working);
|
||||||
|
|
@ -4783,6 +4786,49 @@ static char* eval_tc(char* line, char *tline) {
|
||||||
return ret_str;
|
return ret_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* return a string that consists of m evaluated
|
||||||
|
or having a rhs for numparam expansion {...}.
|
||||||
|
The retun string has to be freed by the caller after its usage. */
|
||||||
|
static char* eval_m(char* line, char* tline) {
|
||||||
|
double m;
|
||||||
|
char* str_ptr, * m_ptr, * m_str = NULL;
|
||||||
|
char* cut_line = line;
|
||||||
|
str_ptr = strstr(cut_line, "m=");
|
||||||
|
if (str_ptr) {
|
||||||
|
/* We need to have 'm=something */
|
||||||
|
if (str_ptr[2]) {
|
||||||
|
m_ptr = str_ptr + 2;
|
||||||
|
int error = 0;
|
||||||
|
m = INPevaluate(&m_ptr, &error, 1);
|
||||||
|
/*We have a value and create the tc1 string */
|
||||||
|
if (error == 0) {
|
||||||
|
m_str = tprintf("m=%15.8e", m);
|
||||||
|
}
|
||||||
|
else if (error == 1 && *m_ptr == '{' && m_ptr + 1 && *(m_ptr + 1) != '}') {
|
||||||
|
char* bra = gettok_char(&m_ptr, '}', TRUE, TRUE);
|
||||||
|
if (bra) {
|
||||||
|
m_str = tprintf("m=%s", bra);
|
||||||
|
tfree(bra);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf(stderr, "Warning: Cannot copy m in line\n %s\n ignored\n", tline);
|
||||||
|
m_str = copy(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf(stderr, "Warning: Cannot copy m in line\n %s\n ignored\n", tline);
|
||||||
|
m_str = copy(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_str = copy(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ps compatibility:
|
/* ps compatibility:
|
||||||
Exxx n1 n2 TABLE {0.45*v(1)} = (-1, -0.5) (-0.5, 0) (0, 2) (0.5, 2) (1, 1)
|
Exxx n1 n2 TABLE {0.45*v(1)} = (-1, -0.5) (-0.5, 0) (0, 2) (0.5, 2) (1, 1)
|
||||||
-->
|
-->
|
||||||
|
|
@ -5397,14 +5443,18 @@ static void inp_compat(struct card *card)
|
||||||
/* evauate tc1 and tc2 */
|
/* evauate tc1 and tc2 */
|
||||||
char* tcrstr = eval_tc(cut_line, card->line);
|
char* tcrstr = eval_tc(cut_line, card->line);
|
||||||
|
|
||||||
|
/* evauate m */
|
||||||
|
char* mstr = eval_m(cut_line, card->line);
|
||||||
|
|
||||||
/* white noise model by x2line, x3line, x4line
|
/* white noise model by x2line, x3line, x4line
|
||||||
if instance parameter noisy=1 (or noise=1) is set */
|
if instance parameter noisy=1 (or noise=1) is set */
|
||||||
bool rnoise = FALSE;
|
bool rnoise = FALSE;
|
||||||
if (strstr(cut_line, "noisy=1") || strstr(cut_line, "noise=1"))
|
if (strstr(cut_line, "noisy=1") || strstr(cut_line, "noise=1"))
|
||||||
rnoise = TRUE;
|
rnoise = TRUE;
|
||||||
|
|
||||||
xline = tprintf("b%s %s %s i = v(%s, %s)/(%s) %s reciproctc=1",
|
/* tc1, tc2, and m are enabled */
|
||||||
title_tok, node1, node2, node1, node2, equation, tcrstr);
|
xline = tprintf("b%s %s %s i = v(%s, %s)/(%s) %s %s reciproctc=1 reciprocm=0",
|
||||||
|
title_tok, node1, node2, node1, node2, equation, tcrstr, mstr);
|
||||||
if (rnoise) {
|
if (rnoise) {
|
||||||
x2line = tprintf("b%s_1 %s %s i = i(v%s_3)/sqrt(%s)",
|
x2line = tprintf("b%s_1 %s %s i = i(v%s_3)/sqrt(%s)",
|
||||||
title_tok, node1, node2, title_tok, equation);
|
title_tok, node1, node2, title_tok, equation);
|
||||||
|
|
@ -5414,6 +5464,7 @@ static void inp_compat(struct card *card)
|
||||||
}
|
}
|
||||||
|
|
||||||
tfree(tcrstr);
|
tfree(tcrstr);
|
||||||
|
tfree(mstr);
|
||||||
|
|
||||||
// comment out current old R line
|
// comment out current old R line
|
||||||
*(card->line) = '*';
|
*(card->line) = '*';
|
||||||
|
|
@ -6113,9 +6164,10 @@ static char *inp_modify_exp(/* NOT CONST */ char *expr)
|
||||||
wl->wl_word = copy(buf);
|
wl->wl_word = copy(buf);
|
||||||
}
|
}
|
||||||
else if (cieq(buf, "tc1") || cieq(buf, "tc2") ||
|
else if (cieq(buf, "tc1") || cieq(buf, "tc2") ||
|
||||||
cieq(buf, "reciproctc")) {
|
cieq(buf, "reciproctc") || cieq(buf, "m") || cieq(buf, "reciprocm")) {
|
||||||
s = skip_ws(s);
|
s = skip_ws(s);
|
||||||
/* no {} around tc1 = or tc2 = , these are temp coeffs. */
|
/* no {} around tc1 = or tc2 = , these are temp coeffs.
|
||||||
|
m= is a multiplier*/
|
||||||
if (s[0] == '=' && s[1] != '=') {
|
if (s[0] == '=' && s[1] != '=') {
|
||||||
buf[i++] = '=';
|
buf[i++] = '=';
|
||||||
buf[i] = '\0';
|
buf[i] = '\0';
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue