Merge branch 'pre-master-43' into bt_dev
This commit is contained in:
commit
b8b861d8d6
|
|
@ -52,14 +52,14 @@ if test "$1" = "d"; then
|
||||||
# You may add --enable-adms to the following command for adding adms generated devices
|
# You may add --enable-adms to the following command for adding adms generated devices
|
||||||
# Builtin readline is not compatible (Big Sur), readline via Homebrew required (in /usr/local/opt)
|
# Builtin readline is not compatible (Big Sur), readline via Homebrew required (in /usr/local/opt)
|
||||||
# Standard clang does not support OpenMP
|
# Standard clang does not support OpenMP
|
||||||
../configure --with-x --enable-xspice --enable-cider --with-readline=/usr/local/opt/readline CFLAGS="-m64 -O0 -g -Wall -I/opt/X11/include/freetype2 -I/usr/local/opt/readline/include" LDFLAGS="-m64 -g -L/usr/local/opt/readline/lib -L/opt/X11/lib"
|
../configure --with-x --enable-xspice --enable-cider --enable-predictor --enable-osdi --enable-klu --with-readline=/usr/local/opt/readline CFLAGS="-m64 -O0 -g -Wall -I/opt/X11/include/freetype2 -I/usr/local/opt/readline/include" LDFLAGS="-m64 -g -L/usr/local/opt/readline/lib -L/opt/X11/lib"
|
||||||
else
|
else
|
||||||
cd release
|
cd release
|
||||||
if [ $? -ne 0 ]; then echo "cd release failed"; exit 1 ; fi
|
if [ $? -ne 0 ]; then echo "cd release failed"; exit 1 ; fi
|
||||||
echo "configuring for 64 bit release"
|
echo "configuring for 64 bit release"
|
||||||
echo
|
echo
|
||||||
# You may add --enable-adms to the following command for adding adms generated devices
|
# You may add --enable-adms to the following command for adding adms generated devices
|
||||||
../configure --with-x --enable-xspice --enable-cider --with-readline=/usr/local/opt/readline --disable-debug CFLAGS="-m64 -O2 -I/opt/X11/include/freetype2 -I/usr/local/opt/readline/include -I/usr/local/opt/ncurses/include" LDFLAGS="-m64 -L/usr/local/opt/readline/lib -L/usr/local/opt/ncurses/lib -L/opt/X11/lib"
|
../configure --with-x --enable-xspice --enable-cider --enable-predictor --enable-osdi --enable-klu --with-readline=/usr/local/opt/readline --disable-debug CFLAGS="-m64 -O2 -I/opt/X11/include/freetype2 -I/usr/local/opt/readline/include -I/usr/local/opt/ncurses/include" LDFLAGS="-m64 -L/usr/local/opt/readline/lib -L/usr/local/opt/ncurses/lib -L/opt/X11/lib"
|
||||||
fi
|
fi
|
||||||
if [ $? -ne 0 ]; then echo "../configure failed"; exit 1 ; fi
|
if [ $? -ne 0 ]; then echo "../configure failed"; exit 1 ; fi
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
* measurement examples with evaluating an expression 0.9*v(2)
|
||||||
|
* transient simulation of two sine signals with different frequencies
|
||||||
|
|
||||||
|
vac1 1 0 DC 0 sin(0 1 1.0k 0 0)
|
||||||
|
vac2 2 0 DC 0 sin(0 1.2 0.9k 0 0)
|
||||||
|
|
||||||
|
.tran 10u 5m
|
||||||
|
|
||||||
|
** evaluate '0.9*v(2)' in dot command
|
||||||
|
.measure tran yeval1 FIND v(2) WHEN v(1)=par('0.9*v(2)')
|
||||||
|
|
||||||
|
.control
|
||||||
|
run
|
||||||
|
** evaluate '0.9*v(2)' in control language command
|
||||||
|
let vint = 0.9*v(2)
|
||||||
|
meas tran yeval2 FIND v(2) WHEN v(1)= vint
|
||||||
|
plot V(1) v(2)
|
||||||
|
.endc
|
||||||
|
|
||||||
|
.end
|
||||||
|
|
@ -226,6 +226,36 @@ com_compose(wordlist *wl)
|
||||||
}
|
}
|
||||||
|
|
||||||
length *= blocksize;
|
length *= blocksize;
|
||||||
|
} else if (eq(wl->wl_word, "device") && resname[0] == '@') {
|
||||||
|
/* Make vector(s) from device parameters; also works with models. */
|
||||||
|
|
||||||
|
result = vec_get(resname);
|
||||||
|
|
||||||
|
/* With @dev[all] a chain of vectors is returned. */
|
||||||
|
|
||||||
|
while (result) {
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
/* Change name so it is not an array reference. */
|
||||||
|
|
||||||
|
for (cp = result->v_name; cp && *cp; ++cp) {
|
||||||
|
if (*cp == '[')
|
||||||
|
*cp = '_';
|
||||||
|
if (*cp == ']') {
|
||||||
|
*cp = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set dimension info */
|
||||||
|
|
||||||
|
result->v_numdims = 1;
|
||||||
|
result->v_dims[0] = length;
|
||||||
|
|
||||||
|
result->v_flags |= VF_PERMANENT;
|
||||||
|
result = result->v_link2;
|
||||||
|
}
|
||||||
|
goto done;
|
||||||
#ifdef XSPICE
|
#ifdef XSPICE
|
||||||
} else if (eq(wl->wl_word, "xspice")) {
|
} else if (eq(wl->wl_word, "xspice")) {
|
||||||
/* Make vectors from an event node. */
|
/* Make vectors from an event node. */
|
||||||
|
|
@ -240,7 +270,6 @@ com_compose(wordlist *wl)
|
||||||
result->v_scale->v_flags |= VF_PERMANENT;
|
result->v_scale->v_flags |= VF_PERMANENT;
|
||||||
vec_new(result->v_scale);
|
vec_new(result->v_scale);
|
||||||
cp_addkword(CT_VECTOR, result->v_scale->v_name);
|
cp_addkword(CT_VECTOR, result->v_scale->v_name);
|
||||||
txfree(resname); // It was copied
|
|
||||||
goto finished;
|
goto finished;
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ void com_fread(wordlist *wl)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fgets(buf, sizeof buf, Open_Files[fd].fp)) {
|
if (fgets(buf, sizeof buf, Open_Files[fd].fp)) {
|
||||||
length = strlen(buf);
|
length = (int)strlen(buf);
|
||||||
if (length > 0 && buf[length - 1] == '\n') {
|
if (length > 0 && buf[length - 1] == '\n') {
|
||||||
--length;
|
--length;
|
||||||
if (length > 0 && buf[length - 1] == '\r') {
|
if (length > 0 && buf[length - 1] == '\r') {
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,24 @@ typedef enum AnalysisType {
|
||||||
static void measure_errMessage(const char *mName, const char *mFunction,
|
static void measure_errMessage(const char *mName, const char *mFunction,
|
||||||
const char *trigTarg, const char *errMsg, int chk_only);
|
const char *trigTarg, const char *errMsg, int chk_only);
|
||||||
|
|
||||||
|
/* like in string.c, here special without () */
|
||||||
|
static bool
|
||||||
|
is_arith_char2(char c)
|
||||||
|
{
|
||||||
|
return c != '\0' && strchr("*/<>?:|&^!%\\", c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
str_has_arith_char2(char* s)
|
||||||
|
{
|
||||||
|
if (*s == '+' || *s == '-')
|
||||||
|
s++;
|
||||||
|
for (; *s; s++)
|
||||||
|
if (is_arith_char2(*s))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/** return precision (either 5 or value of environment variable NGSPICE_MEAS_PRECISION) */
|
/** return precision (either 5 or value of environment variable NGSPICE_MEAS_PRECISION) */
|
||||||
int
|
int
|
||||||
|
|
@ -466,7 +483,7 @@ com_measure_when(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 'dc' is special: it may start at an arbitrary scale value.
|
/* 'dc' is special: it may start at an arbitrary scale value.
|
||||||
Use m_td to store this value, a delay TD does not make sense */
|
Use m_td to store this value, as a delay TD does not make sense */
|
||||||
if (dc_check && (i == 0))
|
if (dc_check && (i == 0))
|
||||||
meas->m_td = scaleValue;
|
meas->m_td = scaleValue;
|
||||||
/* if analysis tran, suppress values below TD */
|
/* if analysis tran, suppress values below TD */
|
||||||
|
|
@ -1480,8 +1497,12 @@ measure_parse_when(
|
||||||
if (cieq("ac", meas->m_analysis) || cieq("sp", meas->m_analysis))
|
if (cieq("ac", meas->m_analysis) || cieq("sp", meas->m_analysis))
|
||||||
correct_vec(meas);
|
correct_vec(meas);
|
||||||
} else {
|
} else {
|
||||||
meas->m_val = INPevaluate(&pVar2, &err, 1);
|
if (str_has_arith_char2(pVar2)) {
|
||||||
if (err) {
|
snprintf(errBuf, 99, "Expressions like %s are not supported.\n", pVar2);
|
||||||
|
return MEASUREMENT_FAILURE;
|
||||||
|
}
|
||||||
|
meas->m_val = INPevaluate2(&pVar2, &err, 0);
|
||||||
|
if (err || (*pVar2 && (!strchr("avfc", *pVar2) || *(pVar2 + 1) != '\0'))) {
|
||||||
snprintf(errBuf, 99, "Cannot evaluate %s \n", pVar2);
|
snprintf(errBuf, 99, "Cannot evaluate %s \n", pVar2);
|
||||||
return MEASUREMENT_FAILURE;
|
return MEASUREMENT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,11 +36,11 @@ void com_strstr(wordlist *wl)
|
||||||
if (*s2) {
|
if (*s2) {
|
||||||
var = strstr(s1, s2); // Search for s2 in s1
|
var = strstr(s1, s2); // Search for s2 in s1
|
||||||
if (var)
|
if (var)
|
||||||
i = var - s1; // Offset to match
|
i = (int)(var - s1); // Offset to match
|
||||||
else
|
else
|
||||||
i = -1;
|
i = -1;
|
||||||
} else {
|
} else {
|
||||||
i = strlen(s1); // Length
|
i = (int)strlen(s1); // Length
|
||||||
}
|
}
|
||||||
tfree(s1);
|
tfree(s1);
|
||||||
tfree(s2);
|
tfree(s2);
|
||||||
|
|
@ -58,7 +58,7 @@ void com_strslice(wordlist *wl)
|
||||||
wl = wl->wl_next;
|
wl = wl->wl_next;
|
||||||
offset = atoi(wl->wl_word);
|
offset = atoi(wl->wl_word);
|
||||||
length = atoi(wl->wl_next->wl_word);
|
length = atoi(wl->wl_next->wl_word);
|
||||||
actual = strlen(s1);
|
actual = (int)strlen(s1);
|
||||||
if (offset < 0)
|
if (offset < 0)
|
||||||
offset = actual + offset;
|
offset = actual + offset;
|
||||||
if (length + offset > actual)
|
if (length + offset > actual)
|
||||||
|
|
|
||||||
|
|
@ -265,63 +265,71 @@ ft_cpinit(void)
|
||||||
wl_free(wl);
|
wl_free(wl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now source the standard startup file spinit or tclspinit. */
|
/* Now source the standard startup file spinit or tclspinit
|
||||||
|
if no_spinit is not set . */
|
||||||
/* jump over leading spaces */
|
if (!cp_getvar("no_spinit", CP_BOOL, NULL, 0)) {
|
||||||
for (copys = s = cp_tildexpand(Lib_Path); copys && *copys; ) {
|
/* jump over leading spaces */
|
||||||
s = skip_ws(s);
|
for (copys = s = cp_tildexpand(Lib_Path); copys && *copys; ) {
|
||||||
/* copy s into buf until end of s, r is the actual position in buf */
|
s = skip_ws(s);
|
||||||
int ii;
|
/* copy s into buf until end of s, r is the actual position in buf */
|
||||||
for (r = buf, ii = 0; *s; r++, s++, ii++) {
|
int ii;
|
||||||
*r = *s;
|
for (r = buf, ii = 0; *s; r++, s++, ii++) {
|
||||||
if (ii > 500) {
|
*r = *s;
|
||||||
fprintf(stderr, "Warning: spinit path is too long.\n");
|
if (ii > 500) {
|
||||||
break;
|
fprintf(stderr, "Warning: spinit path is too long.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
tfree(copys);
|
||||||
tfree(copys);
|
/* add a path separator to buf at actual position */
|
||||||
/* add a path separator to buf at actual position */
|
(void)strcpy(r, DIR_PATHSEP);
|
||||||
(void) strcpy(r, DIR_PATHSEP);
|
|
||||||
#ifdef TCL_MODULE
|
#ifdef TCL_MODULE
|
||||||
/* add "tclspinit" to buf after actual position */
|
/* add "tclspinit" to buf after actual position */
|
||||||
(void) strcat(r, "tclspinit");
|
(void) strcat(r, "tclspinit");
|
||||||
#else
|
#else
|
||||||
/* add "spinit" to buf after actual position */
|
/* add "spinit" to buf after actual position */
|
||||||
(void) strcat(r, "spinit");
|
(void)strcat(r, "spinit");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((fp = fopen(buf, "r")) != NULL) {
|
if ((fp = fopen(buf, "r")) != NULL) {
|
||||||
|
|
||||||
cp_interactive = FALSE;
|
cp_interactive = FALSE;
|
||||||
inp_spsource(fp, TRUE, buf, FALSE);
|
inp_spsource(fp, TRUE, buf, FALSE);
|
||||||
cp_interactive = TRUE;
|
cp_interactive = TRUE;
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if defined(HAS_WINGUI) || defined(__MINGW32__) || defined(_MSC_VER)
|
#if defined(HAS_WINGUI) || defined(__MINGW32__) || defined(_MSC_VER)
|
||||||
/* search in local directory where ngspice.exe resides */
|
/* search in local directory where ngspice.exe resides */
|
||||||
#if defined TCL_MODULE
|
#if defined TCL_MODULE
|
||||||
} else if ((fp = fopen("./tclspinit", "r")) != NULL) {
|
}
|
||||||
|
else if ((fp = fopen("./tclspinit", "r")) != NULL) {
|
||||||
#else
|
#else
|
||||||
} else if ((fp = fopen("./spinit", "r")) != NULL) {
|
}
|
||||||
|
else if ((fp = fopen("./spinit", "r")) != NULL) {
|
||||||
#endif
|
#endif
|
||||||
cp_interactive = FALSE;
|
cp_interactive = FALSE;
|
||||||
inp_spsource(fp, TRUE, buf, FALSE);
|
inp_spsource(fp, TRUE, buf, FALSE);
|
||||||
cp_interactive = TRUE;
|
cp_interactive = TRUE;
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if (ft_controldb) {
|
||||||
|
fprintf(cp_err, "Warning: can't open \"%s\".\n", buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
#if defined TCL_MODULE
|
||||||
|
fprintf(cp_err, "Warning: can't find the initialization file tclspinit.\n");
|
||||||
|
#else
|
||||||
|
fprintf(cp_err, "Warning: can't find the initialization file spinit.\n");
|
||||||
#endif
|
#endif
|
||||||
} else if (ft_controldb) {
|
|
||||||
fprintf(cp_err, "Note: can't open \"%s\".\n", buf);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
if (!found) {
|
fprintf(cp_out, "Note: Start without reading file 'spinit'.\n");
|
||||||
#if defined TCL_MODULE
|
|
||||||
fprintf(cp_err, "Note: can't find the initialization file tclspinit.\n");
|
|
||||||
#else
|
|
||||||
fprintf(cp_err, "Note: can't find the initialization file spinit.\n");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -667,7 +667,7 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile)
|
||||||
with_params = TRUE;
|
with_params = TRUE;
|
||||||
size = sizeof header + 10; // Allow for %u and close.
|
size = sizeof header + 10; // Allow for %u and close.
|
||||||
for (argc = 0; Copy_of_argv[optind + argc]; ++argc)
|
for (argc = 0; Copy_of_argv[optind + argc]; ++argc)
|
||||||
size += strlen(Copy_of_argv[optind + argc]);
|
size += (int)strlen(Copy_of_argv[optind + argc]);
|
||||||
size += 3 * argc; // Spaces and quotes.
|
size += 3 * argc; // Spaces and quotes.
|
||||||
if (size <= sizeof buf)
|
if (size <= sizeof buf)
|
||||||
p_buf_active = buf;
|
p_buf_active = buf;
|
||||||
|
|
|
||||||
|
|
@ -206,7 +206,7 @@ static int inp_poly_2g6_compat(struct card* deck);
|
||||||
static void inp_poly_err(struct card *deck);
|
static void inp_poly_err(struct card *deck);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CIDER
|
#if defined(CIDER) || defined(XSPICE)
|
||||||
static char *keep_case_of_cider_param(char *buffer)
|
static char *keep_case_of_cider_param(char *buffer)
|
||||||
{
|
{
|
||||||
int numq = 0, keep_case = 0;
|
int numq = 0, keep_case = 0;
|
||||||
|
|
@ -240,6 +240,31 @@ static char *keep_case_of_cider_param(char *buffer)
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char* make_lower_case_copy(char* inbuf)
|
||||||
|
{
|
||||||
|
char* s = NULL;
|
||||||
|
char* rets = NULL;
|
||||||
|
size_t lenb = 0;
|
||||||
|
|
||||||
|
if (!inbuf) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
lenb = strlen(inbuf);
|
||||||
|
if (lenb < 1) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
rets = dup_string(inbuf, lenb);
|
||||||
|
if (!rets) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
for (s = rets; *s; s++) {
|
||||||
|
*s = tolower_c(*s);
|
||||||
|
}
|
||||||
|
return rets;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CIDER
|
||||||
static int is_comment_or_blank(char *buffer)
|
static int is_comment_or_blank(char *buffer)
|
||||||
{
|
{
|
||||||
/* Assume line buffers have initial whitespace removed */
|
/* Assume line buffers have initial whitespace removed */
|
||||||
|
|
@ -275,29 +300,6 @@ static int turn_off_case_retention(char *buffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *make_lower_case_copy(char *inbuf)
|
|
||||||
{
|
|
||||||
char *s = NULL;
|
|
||||||
char *rets = NULL;
|
|
||||||
size_t lenb = 0;
|
|
||||||
|
|
||||||
if (!inbuf) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
lenb = strlen(inbuf);
|
|
||||||
if (lenb < 1) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
rets = dup_string(inbuf, lenb);
|
|
||||||
if (!rets) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
for (s = rets; *s; s++) {
|
|
||||||
*s = tolower_c(*s);
|
|
||||||
}
|
|
||||||
return rets;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ignore_line(char *buf)
|
static int ignore_line(char *buf)
|
||||||
{
|
{
|
||||||
/* Can the line in buf be ignored for ic.file checking?
|
/* Can the line in buf be ignored for ic.file checking?
|
||||||
|
|
@ -397,6 +399,31 @@ static int is_cider_model(char *buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef XSPICE
|
||||||
|
static int is_xspice_model(char* buf)
|
||||||
|
{
|
||||||
|
/* Expect filesource, table2d, table3d, d_state, d_source, d_process, d_cosim
|
||||||
|
to be on the same line as the .model.
|
||||||
|
Otherwise it will be missed if on a continuation line.
|
||||||
|
This should be rare.
|
||||||
|
*/
|
||||||
|
char* s;
|
||||||
|
if (!ciprefix(".model", buf)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
s = make_lower_case_copy(buf);
|
||||||
|
if (!s) return 0;
|
||||||
|
if (strstr(s, "filesource") || strstr(s, "table2d") || strstr(s, "table3d") ||
|
||||||
|
strstr(s, "d_state") || strstr(s, "d_source") || strstr(s, "d_process") || strstr(s, "d_cosim")) {
|
||||||
|
tfree(s);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tfree(s);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Insert a new card, just behind the given card.
|
/* Insert a new card, just behind the given card.
|
||||||
* The new card takes ownership of the memory pointed to by "line".
|
* The new card takes ownership of the memory pointed to by "line".
|
||||||
|
|
@ -1213,26 +1240,26 @@ struct card *inp_readall(FILE *fp, const char *dir_name,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name,
|
struct inp_read_t inp_read(FILE* fp, int call_depth, const char* dir_name,
|
||||||
bool comfile, bool intfile)
|
bool comfile, bool intfile)
|
||||||
/* fp: in, pointer to file to be read,
|
/* fp: in, pointer to file to be read,
|
||||||
call_depth: in, nested call to fcn
|
call_depth: in, nested call to fcn
|
||||||
dir_name: in, name of directory of file to be read
|
dir_name: in, name of directory of file to be read
|
||||||
comfile: in, TRUE if command file (e.g. spinit, .spiceinit)
|
comfile: in, TRUE if command file (e.g. spinit, .spiceinit)
|
||||||
intfile: in, TRUE if deck is generated from internal circarray
|
intfile: in, TRUE if deck is generated from internal circarray
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
struct inp_read_t rv;
|
struct inp_read_t rv;
|
||||||
struct card *end = NULL, *cc = NULL;
|
struct card* end = NULL, * cc = NULL;
|
||||||
char *buffer = NULL;
|
char* buffer = NULL;
|
||||||
/* segfault fix */
|
/* segfault fix */
|
||||||
#ifdef XSPICE
|
#ifdef XSPICE
|
||||||
char big_buff[5000];
|
char big_buff[5000];
|
||||||
int line_count = 0;
|
int line_count = 0;
|
||||||
#endif
|
#endif
|
||||||
char *new_title = NULL;
|
char* new_title = NULL;
|
||||||
int line_number = 1;
|
int line_number = 1;
|
||||||
/* sjb - renamed to avoid confusion with struct card */
|
/* sjb - renamed to avoid confusion with struct card */
|
||||||
int line_number_orig = 1;
|
int line_number_orig = 1;
|
||||||
int cirlinecount = 0; /* length of circarray */
|
int cirlinecount = 0; /* length of circarray */
|
||||||
static int is_control = 0; /* We are reading from a .control section */
|
static int is_control = 0; /* We are reading from a .control section */
|
||||||
|
|
@ -1259,8 +1286,8 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name,
|
||||||
/* gtri - modify - 12/12/90 - wbk - read from mailbox if ipc
|
/* gtri - modify - 12/12/90 - wbk - read from mailbox if ipc
|
||||||
* enabled */
|
* enabled */
|
||||||
|
|
||||||
/* If IPC is not enabled, do equivalent of what SPICE did before
|
/* If IPC is not enabled, do equivalent of what SPICE did before
|
||||||
*/
|
*/
|
||||||
if (!g_ipc.enabled) {
|
if (!g_ipc.enabled) {
|
||||||
if (call_depth == 0 && line_count == 0) {
|
if (call_depth == 0 && line_count == 0) {
|
||||||
line_count++;
|
line_count++;
|
||||||
|
|
@ -1280,7 +1307,7 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name,
|
||||||
char ipc_buffer[1025]; /* Had better be big enough */
|
char ipc_buffer[1025]; /* Had better be big enough */
|
||||||
int ipc_len;
|
int ipc_len;
|
||||||
Ipc_Status_t ipc_status =
|
Ipc_Status_t ipc_status =
|
||||||
ipc_get_line(ipc_buffer, &ipc_len, IPC_WAIT);
|
ipc_get_line(ipc_buffer, &ipc_len, IPC_WAIT);
|
||||||
if (ipc_status == IPC_STATUS_END_OF_DECK) {
|
if (ipc_status == IPC_STATUS_END_OF_DECK) {
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
break;
|
break;
|
||||||
|
|
@ -1302,7 +1329,7 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name,
|
||||||
buffer = readline(fp);
|
buffer = readline(fp);
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
@ -1318,7 +1345,7 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name,
|
||||||
|
|
||||||
/* OK -- now we have loaded the next line into 'buffer'. Process it.
|
/* OK -- now we have loaded the next line into 'buffer'. Process it.
|
||||||
*/
|
*/
|
||||||
/* If input line is blank, ignore it & continue looping. */
|
/* If input line is blank, ignore it & continue looping. */
|
||||||
if ((strcmp(buffer, "\n") == 0) || (strcmp(buffer, "\r\n") == 0))
|
if ((strcmp(buffer, "\n") == 0) || (strcmp(buffer, "\r\n") == 0))
|
||||||
if (call_depth != 0 || (call_depth == 0 && cc != NULL)) {
|
if (call_depth != 0 || (call_depth == 0 && cc != NULL)) {
|
||||||
line_number_orig++;
|
line_number_orig++;
|
||||||
|
|
@ -1339,7 +1366,7 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name,
|
||||||
|
|
||||||
/* now handle .title statement */
|
/* now handle .title statement */
|
||||||
if (ciprefix(".title", buffer)) {
|
if (ciprefix(".title", buffer)) {
|
||||||
char *s;
|
char* s;
|
||||||
s = skip_non_ws(buffer); /* skip over .title */
|
s = skip_non_ws(buffer); /* skip over .title */
|
||||||
s = skip_ws(s); /* advance past space chars */
|
s = skip_ws(s); /* advance past space chars */
|
||||||
|
|
||||||
|
|
@ -1362,7 +1389,7 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name,
|
||||||
* so .lib is interpreted as old style .lib <file name> (no lib
|
* so .lib is interpreted as old style .lib <file name> (no lib
|
||||||
* name given, .lib replaced by .include).
|
* name given, .lib replaced by .include).
|
||||||
*/
|
*/
|
||||||
char *s = skip_non_ws(buffer); /* skip over .lib */
|
char* s = skip_non_ws(buffer); /* skip over .lib */
|
||||||
fprintf(cp_err, " File included as: .inc %s\n", s);
|
fprintf(cp_err, " File included as: .inc %s\n", s);
|
||||||
memcpy(buffer, ".inc", 4);
|
memcpy(buffer, ".inc", 4);
|
||||||
}
|
}
|
||||||
|
|
@ -1370,10 +1397,10 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name,
|
||||||
/* now handle .include statements */
|
/* now handle .include statements */
|
||||||
if (ciprefix(".include", buffer) || ciprefix(".inc", buffer)) {
|
if (ciprefix(".include", buffer) || ciprefix(".inc", buffer)) {
|
||||||
|
|
||||||
char *y = NULL;
|
char* y = NULL;
|
||||||
char *s;
|
char* s;
|
||||||
|
|
||||||
struct card *newcard;
|
struct card* newcard;
|
||||||
|
|
||||||
inp_stripcomments_line(buffer, FALSE);
|
inp_stripcomments_line(buffer, FALSE);
|
||||||
|
|
||||||
|
|
@ -1388,13 +1415,13 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name,
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
char *y_resolved = inp_pathresolve_at(y, dir_name);
|
char* y_resolved = inp_pathresolve_at(y, dir_name);
|
||||||
char *y_dir_name;
|
char* y_dir_name;
|
||||||
FILE *newfp;
|
FILE* newfp;
|
||||||
|
|
||||||
if (!y_resolved) {
|
if (!y_resolved) {
|
||||||
fprintf(cp_err, "Error: Could not find include file %s\n",
|
fprintf(cp_err, "Error: Could not find include file %s\n",
|
||||||
y);
|
y);
|
||||||
if (ft_stricterror)
|
if (ft_stricterror)
|
||||||
controlled_exit(EXIT_FAILURE);
|
controlled_exit(EXIT_FAILURE);
|
||||||
rv.line_number = line_number;
|
rv.line_number = line_number;
|
||||||
|
|
@ -1413,14 +1440,14 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name,
|
||||||
y_dir_name = ngdirname(y_resolved);
|
y_dir_name = ngdirname(y_resolved);
|
||||||
|
|
||||||
newcard = inp_read(
|
newcard = inp_read(
|
||||||
newfp, call_depth + 1, y_dir_name, FALSE, FALSE)
|
newfp, call_depth + 1, y_dir_name, FALSE, FALSE)
|
||||||
.cc; /* read stuff in include file into
|
.cc; /* read stuff in include file into
|
||||||
netlist */
|
netlist */
|
||||||
|
|
||||||
tfree(y_dir_name);
|
tfree(y_dir_name);
|
||||||
tfree(y_resolved);
|
tfree(y_resolved);
|
||||||
|
|
||||||
(void) fclose(newfp);
|
(void)fclose(newfp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make the .include a comment */
|
/* Make the .include a comment */
|
||||||
|
|
@ -1429,7 +1456,7 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name,
|
||||||
/* append `buffer' to the (cc, end) chain of decks */
|
/* append `buffer' to the (cc, end) chain of decks */
|
||||||
{
|
{
|
||||||
end = insert_new_line(
|
end = insert_new_line(
|
||||||
end, copy(buffer), line_number, line_number);
|
end, copy(buffer), line_number, line_number);
|
||||||
|
|
||||||
if (!cc)
|
if (!cc)
|
||||||
cc = end;
|
cc = end;
|
||||||
|
|
@ -1447,17 +1474,17 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name,
|
||||||
end->nextcard = newcard;
|
end->nextcard = newcard;
|
||||||
/* Renumber the lines */
|
/* Renumber the lines */
|
||||||
for (end = newcard; end && end->nextcard;
|
for (end = newcard; end && end->nextcard;
|
||||||
end = end->nextcard) {
|
end = end->nextcard) {
|
||||||
end->linenum = line_number++;
|
end->linenum = line_number++;
|
||||||
end->linenum_orig = line_number_inc++;
|
end->linenum_orig = line_number_inc++;
|
||||||
}
|
}
|
||||||
end->linenum = line_number++; /* SJB - renumber last line */
|
end->linenum = line_number++; /* SJB - renumber last line */
|
||||||
end->linenum_orig = line_number_inc++;
|
end->linenum_orig = line_number_inc++;
|
||||||
/* SJB - renumber the last line */
|
/* SJB - renumber the last line */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fix the buffer up a bit. */
|
/* Fix the buffer up a bit. */
|
||||||
(void) memcpy(buffer + 1, "end of: ", 8);
|
(void)memcpy(buffer + 1, "end of: ", 8);
|
||||||
} /* end of .include handling */
|
} /* end of .include handling */
|
||||||
|
|
||||||
/* loop through 'buffer' until end is reached. Make all letters lower
|
/* loop through 'buffer' until end is reached. Make all letters lower
|
||||||
|
|
@ -1468,7 +1495,7 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name,
|
||||||
* double quotes. Single quotes are later on swallowed and disappear,
|
* double quotes. Single quotes are later on swallowed and disappear,
|
||||||
* double quotes are printed. */
|
* double quotes are printed. */
|
||||||
{
|
{
|
||||||
char *s;
|
char* s;
|
||||||
#ifdef CIDER
|
#ifdef CIDER
|
||||||
if (ciprefix(".model", buffer)) {
|
if (ciprefix(".model", buffer)) {
|
||||||
in_cider_model = is_cider_model(buffer);
|
in_cider_model = is_cider_model(buffer);
|
||||||
|
|
@ -1476,16 +1503,16 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name,
|
||||||
printf("Found .model Cider model is %s\n",
|
printf("Found .model Cider model is %s\n",
|
||||||
(in_cider_model ? "ON" : "OFF"));
|
(in_cider_model ? "ON" : "OFF"));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (in_cider_model && turn_off_case_retention(buffer)) {
|
if (in_cider_model && turn_off_case_retention(buffer)) {
|
||||||
in_cider_model = 0;
|
in_cider_model = 0;
|
||||||
#ifdef TRACE
|
#ifdef TRACE
|
||||||
printf("Cider model is OFF\n");
|
printf("Cider model is OFF\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (ciprefix("plot", buffer) || ciprefix("gnuplot", buffer) ||
|
if (ciprefix("plot", buffer) || ciprefix("gnuplot", buffer) ||
|
||||||
ciprefix("hardcopy", buffer)) {
|
ciprefix("hardcopy", buffer)) {
|
||||||
/* lower case excluded for tokens following title, xlabel,
|
/* lower case excluded for tokens following title, xlabel,
|
||||||
* ylabel. tokens may contain spaces, then they have to be
|
* ylabel. tokens may contain spaces, then they have to be
|
||||||
* enclosed in quotes. keywords and tokens have to be
|
* enclosed in quotes. keywords and tokens have to be
|
||||||
|
|
@ -1549,9 +1576,9 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ciprefix("print", buffer) ||
|
else if (ciprefix("print", buffer) ||
|
||||||
ciprefix("eprint", buffer) ||
|
ciprefix("eprint", buffer) ||
|
||||||
ciprefix("eprvcd", buffer) ||
|
ciprefix("eprvcd", buffer) ||
|
||||||
ciprefix("asciiplot", buffer)) {
|
ciprefix("asciiplot", buffer)) {
|
||||||
/* lower case excluded for tokens following output redirection
|
/* lower case excluded for tokens following output redirection
|
||||||
* '>' */
|
* '>' */
|
||||||
bool redir = FALSE;
|
bool redir = FALSE;
|
||||||
|
|
@ -1565,12 +1592,19 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name,
|
||||||
}
|
}
|
||||||
#ifdef CIDER
|
#ifdef CIDER
|
||||||
else if (in_cider_model && !is_comment_or_blank(buffer) &&
|
else if (in_cider_model && !is_comment_or_blank(buffer) &&
|
||||||
(ciprefix(".model", buffer) || buffer[0] == '+')) {
|
(ciprefix(".model", buffer) || buffer[0] == '+')) {
|
||||||
s = keep_case_of_cider_param(buffer);
|
s = keep_case_of_cider_param(buffer);
|
||||||
}
|
}
|
||||||
else if (line_contains_icfile(buffer)) {
|
else if (line_contains_icfile(buffer)) {
|
||||||
s = keep_case_of_cider_param(buffer);
|
s = keep_case_of_cider_param(buffer);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef XSPICE
|
||||||
|
/* lower case excluded for text in quotes for .model of code models
|
||||||
|
filesource, rable2d, table3d, d_state, d_source, d_process, d_cosim */
|
||||||
|
else if (is_xspice_model(buffer)) {
|
||||||
|
s = keep_case_of_cider_param(buffer);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
/* no lower case letters for lines beginning with: */
|
/* no lower case letters for lines beginning with: */
|
||||||
else if (!ciprefix("write", buffer) &&
|
else if (!ciprefix("write", buffer) &&
|
||||||
|
|
@ -6596,11 +6630,13 @@ static void inp_compat(struct card *card)
|
||||||
// skip '='
|
// skip '='
|
||||||
cut_line++;
|
cut_line++;
|
||||||
// copy the replacement without trailing '\0'
|
// copy the replacement without trailing '\0'
|
||||||
for (ii = 0; ii < xlen; ii++)
|
char* loc_ptr = str_ptr - 1;
|
||||||
|
for (ii = 0; ii < xlen; ii++) {
|
||||||
if (*copy_ptr)
|
if (*copy_ptr)
|
||||||
*cut_line++ = *copy_ptr++;
|
*loc_ptr++ = *copy_ptr++;
|
||||||
else
|
else
|
||||||
*cut_line++ = ' ';
|
*loc_ptr++ = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
tfree(del_ptr);
|
tfree(del_ptr);
|
||||||
tfree(exp_ptr);
|
tfree(exp_ptr);
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,8 @@ extern INPmodel *modtab;
|
||||||
extern NGHASHPTR modtabhash;
|
extern NGHASHPTR modtabhash;
|
||||||
extern bool ft_batchmode;
|
extern bool ft_batchmode;
|
||||||
|
|
||||||
static struct variable *parmtovar(IFvalue *pv, IFparm *opt);
|
static struct variable *parmtovar(IFvalue *pv, IFparm *opt,
|
||||||
|
int use_description);
|
||||||
static IFparm *parmlookup(IFdevice *dev, GENinstance **inptr, char *param,
|
static IFparm *parmlookup(IFdevice *dev, GENinstance **inptr, char *param,
|
||||||
int do_model, int inout);
|
int do_model, int inout);
|
||||||
static IFvalue *doask(CKTcircuit *ckt, int typecode, GENinstance *dev, GENmodel *mod,
|
static IFvalue *doask(CKTcircuit *ckt, int typecode, GENinstance *dev, GENmodel *mod,
|
||||||
|
|
@ -688,17 +689,12 @@ spif_getparam_special(CKTcircuit *ckt, char **name, char *param, int ind, int do
|
||||||
continue;
|
continue;
|
||||||
pv = doask(ckt, typecode, dev, mod, opt, ind);
|
pv = doask(ckt, typecode, dev, mod, opt, ind);
|
||||||
if (pv) {
|
if (pv) {
|
||||||
tv = parmtovar(pv, opt);
|
tv = parmtovar(pv, opt, 0);
|
||||||
|
if (tv) {
|
||||||
/* With the following we pack the name and the acronym of the parameter */
|
if (vv)
|
||||||
{
|
tv->va_next = vv;
|
||||||
char *x = tv->va_name;
|
vv = tv;
|
||||||
tv->va_name = tprintf("%s [%s]", tv->va_name, device->instanceParms[i].keyword);
|
|
||||||
tfree(x);
|
|
||||||
}
|
}
|
||||||
if (vv)
|
|
||||||
tv->va_next = vv;
|
|
||||||
vv = tv;
|
|
||||||
} else {
|
} else {
|
||||||
fprintf(cp_err,
|
fprintf(cp_err,
|
||||||
"Internal Error: no parameter '%s' on device '%s'\n",
|
"Internal Error: no parameter '%s' on device '%s'\n",
|
||||||
|
|
@ -725,26 +721,12 @@ spif_getparam_special(CKTcircuit *ckt, char **name, char *param, int ind, int do
|
||||||
continue;
|
continue;
|
||||||
pv = doask(ckt, typecode, dev, mod, opt, ind);
|
pv = doask(ckt, typecode, dev, mod, opt, ind);
|
||||||
if (pv) {
|
if (pv) {
|
||||||
tv = parmtovar(pv, opt);
|
tv = parmtovar(pv, opt, 0);
|
||||||
/* Inside parmtovar:
|
if (tv) {
|
||||||
* 1. tv->va_name = copy(opt->description);
|
if (vv)
|
||||||
* 2. Copy the type of variable of IFparm into a variable (thus parm-to-var)
|
tv->va_next = vv;
|
||||||
* vv->va_type = opt->dataType
|
vv = tv;
|
||||||
* The long description of the parameter:
|
|
||||||
* IFparm MOS_SGTmPTable[] = { // model parameters //
|
|
||||||
* OP("type", MOS_SGT_MOD_TYPE, IF_STRING, "N-channel or P-channel MOS")
|
|
||||||
* goes into tv->va_name to put braces around the parameter of the model
|
|
||||||
* tv->va_name += device->modelParms[i].keyword;
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
char *x = tv->va_name;
|
|
||||||
tv->va_name = tprintf("%s [%s]", tv->va_name, device->modelParms[i].keyword);
|
|
||||||
tfree(x);
|
|
||||||
}
|
}
|
||||||
/* tv->va_string = device->modelParms[i].keyword; Put the name of the variable */
|
|
||||||
if (vv)
|
|
||||||
tv->va_next = vv;
|
|
||||||
vv = tv;
|
|
||||||
} else {
|
} else {
|
||||||
fprintf(cp_err,
|
fprintf(cp_err,
|
||||||
"Internal Error: no parameter '%s' on device '%s'\n",
|
"Internal Error: no parameter '%s' on device '%s'\n",
|
||||||
|
|
@ -768,7 +750,7 @@ spif_getparam_special(CKTcircuit *ckt, char **name, char *param, int ind, int do
|
||||||
}
|
}
|
||||||
pv = doask(ckt, typecode, dev, mod, opt, ind);
|
pv = doask(ckt, typecode, dev, mod, opt, ind);
|
||||||
if (pv)
|
if (pv)
|
||||||
vv = parmtovar(pv, opt);
|
vv = parmtovar(pv, opt, 0);
|
||||||
return (vv);
|
return (vv);
|
||||||
} else {
|
} else {
|
||||||
return (if_getstat(ckt, *name));
|
return (if_getstat(ckt, *name));
|
||||||
|
|
@ -814,10 +796,12 @@ spif_getparam(CKTcircuit *ckt, char **name, char *param, int ind, int do_model)
|
||||||
continue;
|
continue;
|
||||||
pv = doask(ckt, typecode, dev, mod, opt, ind);
|
pv = doask(ckt, typecode, dev, mod, opt, ind);
|
||||||
if (pv) {
|
if (pv) {
|
||||||
tv = parmtovar(pv, opt);
|
tv = parmtovar(pv, opt, 0);
|
||||||
if (vv)
|
if (tv) {
|
||||||
tv->va_next = vv;
|
if (vv)
|
||||||
vv = tv;
|
tv->va_next = vv;
|
||||||
|
vv = tv;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf(cp_err,
|
fprintf(cp_err,
|
||||||
"Internal Error: no parameter '%s' on device '%s'\n",
|
"Internal Error: no parameter '%s' on device '%s'\n",
|
||||||
|
|
@ -843,7 +827,7 @@ spif_getparam(CKTcircuit *ckt, char **name, char *param, int ind, int do_model)
|
||||||
}
|
}
|
||||||
pv = doask(ckt, typecode, dev, mod, opt, ind);
|
pv = doask(ckt, typecode, dev, mod, opt, ind);
|
||||||
if (pv)
|
if (pv)
|
||||||
vv = parmtovar(pv, opt);
|
vv = parmtovar(pv, opt, 0);
|
||||||
return (vv);
|
return (vv);
|
||||||
} else {
|
} else {
|
||||||
return (if_getstat(ckt, *name));
|
return (if_getstat(ckt, *name));
|
||||||
|
|
@ -991,49 +975,90 @@ if_setparam(CKTcircuit *ckt, char **name, char *param, struct dvec *val, int do_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Make a linked list where the first node is a CP_LIST variable
|
||||||
|
* pointing to the different values of the vector variables.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* In the case of Vin_sin 1 0 sin (0 2 2000)
|
||||||
|
* and of print @vin_sin[sin]
|
||||||
|
*
|
||||||
|
* vv->va_V.vV_list->va_V.vV_real = 2000
|
||||||
|
* vv->va_V.vV_list->va_next->va_V.vV_real = 2
|
||||||
|
* vv->va_V.vV_list->va_next->va_next->va_V.vV_real = 0
|
||||||
|
* So the list is starting from behind, but no problem
|
||||||
|
* This works fine
|
||||||
|
*/
|
||||||
|
|
||||||
static struct variable *
|
static struct variable *
|
||||||
parmtovar(IFvalue *pv, IFparm *opt)
|
parmtolist(IFvalue *pv, IFparm *opt, char *name)
|
||||||
{
|
{
|
||||||
/* It is not clear whether we want to name the variable
|
struct variable *list = NULL;
|
||||||
* by `keyword' or by `description' */
|
int i;
|
||||||
|
|
||||||
|
for (i = pv->v.numValue; --i >= 0;) {
|
||||||
|
switch (opt->dataType & (IF_VARTYPES & ~IF_VECTOR)) {
|
||||||
|
case IF_INTEGER:
|
||||||
|
list = var_alloc_num(NULL, pv->v.vec.iVec[i], list);
|
||||||
|
break;
|
||||||
|
case IF_REAL:
|
||||||
|
case IF_COMPLEX:
|
||||||
|
list = var_alloc_real(NULL, pv->v.vec.rVec[i], list);
|
||||||
|
break;
|
||||||
|
case IF_STRING:
|
||||||
|
list = var_alloc_string(NULL, copy(pv->v.vec.sVec[i]), list);
|
||||||
|
break;
|
||||||
|
case IF_FLAG:
|
||||||
|
list = var_alloc_bool(NULL, pv->v.vec.iVec[i] ? TRUE : FALSE,
|
||||||
|
list);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(cp_err,
|
||||||
|
"parmtolist: Internal Error: bad PARM type "
|
||||||
|
"%#x for %s (%s).\n",
|
||||||
|
opt->dataType, opt->keyword, opt->description);
|
||||||
|
if (name)
|
||||||
|
free(name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i || pv->v.numValue == 0)
|
||||||
|
list = var_alloc_vlist(name, list, NULL);
|
||||||
|
if (pv->v.vec.iVec) { // All the union members are pointers
|
||||||
|
free(pv->v.vec.iVec);
|
||||||
|
pv->v.vec.iVec = NULL;
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct variable *
|
||||||
|
parmtovar(IFvalue *pv, IFparm *opt, int use_description)
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
name = use_description ? opt->description : opt->keyword;
|
||||||
|
if (name)
|
||||||
|
name = copy(name);
|
||||||
|
if (opt->dataType & IF_VECTOR)
|
||||||
|
return parmtolist(pv, opt, name);
|
||||||
|
|
||||||
switch (opt->dataType & IF_VARTYPES) {
|
switch (opt->dataType & IF_VARTYPES) {
|
||||||
case IF_INTEGER:
|
case IF_INTEGER:
|
||||||
return var_alloc_num(copy(opt->description), pv->iValue, NULL);
|
return var_alloc_num(name, pv->iValue, NULL);
|
||||||
case IF_REAL:
|
case IF_REAL:
|
||||||
case IF_COMPLEX:
|
case IF_COMPLEX:
|
||||||
return var_alloc_real(copy(opt->description), pv->rValue, NULL);
|
return var_alloc_real(name, pv->rValue, NULL);
|
||||||
case IF_STRING:
|
case IF_STRING:
|
||||||
return var_alloc_string(copy(opt->description), pv->sValue, NULL);
|
return var_alloc_string(name, copy(pv->sValue), NULL);
|
||||||
case IF_FLAG:
|
case IF_FLAG:
|
||||||
return var_alloc_bool(copy(opt->description), pv->iValue ? TRUE : FALSE, NULL);
|
return var_alloc_bool(name, pv->iValue ? TRUE : FALSE,
|
||||||
case IF_REALVEC: {
|
NULL);
|
||||||
struct variable *list = NULL;
|
|
||||||
int i;
|
|
||||||
for (i = pv->v.numValue; --i >= 0;)
|
|
||||||
list = var_alloc_real(NULL, pv->v.vec.rVec[i], list);
|
|
||||||
return var_alloc_vlist(copy(opt->description), list, NULL);
|
|
||||||
/* It is a linked list where the first node is a variable
|
|
||||||
* pointing to the different values of the variables.
|
|
||||||
*
|
|
||||||
* To access the values of the real variable vector must be
|
|
||||||
* vv->va_V.vV_real = valor node ppal that is of no use.
|
|
||||||
*
|
|
||||||
* In the case of Vin_sin 1 0 sin (0 2 2000)
|
|
||||||
* and of print @vin_sin[sin]
|
|
||||||
*
|
|
||||||
* vv->va_V.vV_list->va_V.vV_real = 2000
|
|
||||||
* vv->va_V.vV_list->va_next->va_V.vV_real = 2
|
|
||||||
* vv->va_V.vV_list->va_next->va_next->va_V.vV_real = 0
|
|
||||||
* So the list is starting from behind, but no problem
|
|
||||||
* This works fine
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
fprintf(cp_err,
|
fprintf(cp_err,
|
||||||
"parmtovar: Internal Error: bad PARM type %d.\n",
|
"parmtovar: Internal Error: bad PARM type %#x for %s (%s).\n",
|
||||||
opt->dataType);
|
opt->dataType, opt->keyword, opt->description);
|
||||||
|
if (name)
|
||||||
|
free(name);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1317,7 +1342,7 @@ if_getstat(CKTcircuit *ckt, char *name)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (parmtovar(&parm, if_parm));
|
return (parmtovar(&parm, if_parm, 1));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
@ -1339,7 +1364,7 @@ if_getstat(CKTcircuit *ckt, char *name)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
*v = parmtovar(&parm, if_parm);
|
*v = parmtovar(&parm, if_parm, 1);
|
||||||
v = &((*v)->va_next);
|
v = &((*v)->va_next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -580,8 +580,8 @@ vec_get(const char *vec_name) {
|
||||||
struct dvec *d, *end = NULL, *newv = NULL;
|
struct dvec *d, *end = NULL, *newv = NULL;
|
||||||
struct plot *pl;
|
struct plot *pl;
|
||||||
char buf[BSIZE_SP], *s, *wd, *word, *whole, *name = NULL, *param;
|
char buf[BSIZE_SP], *s, *wd, *word, *whole, *name = NULL, *param;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
struct variable *vv;
|
struct variable *vv, *v;
|
||||||
|
|
||||||
wd = word = copy(vec_name); /* Gets mangled below... */
|
wd = word = copy(vec_name); /* Gets mangled below... */
|
||||||
|
|
||||||
|
|
@ -638,6 +638,8 @@ vec_get(const char *vec_name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!d && (*word == SPECCHAR)) { /* "@" */
|
if (!d && (*word == SPECCHAR)) { /* "@" */
|
||||||
|
int multiple;
|
||||||
|
|
||||||
/* This is a special quantity... */
|
/* This is a special quantity... */
|
||||||
if (ft_nutmeg) {
|
if (ft_nutmeg) {
|
||||||
fprintf(cp_err,
|
fprintf(cp_err,
|
||||||
|
|
@ -646,6 +648,12 @@ vec_get(const char *vec_name) {
|
||||||
return (NULL); /* va: use NULL */
|
return (NULL); /* va: use NULL */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ft_curckt) {
|
||||||
|
fprintf(cp_err, "Error: No circuit loaded.\n");
|
||||||
|
tfree(wd);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
whole = copy(word);
|
whole = copy(word);
|
||||||
name = ++word;
|
name = ++word;
|
||||||
for (param = name; *param && (*param != '['); param++)
|
for (param = name; *param && (*param != '['); param++)
|
||||||
|
|
@ -660,157 +668,131 @@ vec_get(const char *vec_name) {
|
||||||
param = NULL;
|
param = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is what is done in case of "alter r1 resistance = 1234"
|
||||||
|
* r1 resistance, 0
|
||||||
|
* if_setparam(ft_curckt->ci_ckt, &dev, param, dv, do_model);
|
||||||
|
*/
|
||||||
|
|
||||||
if (ft_curckt) {
|
vv = if_getparam(ft_curckt->ci_ckt, &name, param, 0, 0);
|
||||||
/*
|
if (!vv) {
|
||||||
* This is what is done in case of "alter r1 resistance = 1234"
|
|
||||||
* r1 resistance, 0
|
|
||||||
* if_setparam(ft_curckt->ci_ckt, &dev, param, dv, do_model);
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* vv = if_getparam (ft_curckt->ci_ckt, &name, param, 0, 0); */
|
|
||||||
vv = if_getparam(ft_curckt->ci_ckt, &name, param, 0, 0);
|
|
||||||
if (!vv) {
|
|
||||||
tfree(whole);
|
|
||||||
tfree(wd);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fprintf(cp_err, "Error: No circuit loaded.\n");
|
|
||||||
tfree(whole);
|
tfree(whole);
|
||||||
tfree(wd);
|
tfree(wd);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
d = dvec_alloc(copy(whole), /* MW. The same as word before */
|
/* If vec_name was "@dev", "@model", "@dev[all]" or @model[all]",
|
||||||
SV_NOTYPE,
|
* if_getparam() returns a list.
|
||||||
VF_REAL, /* No complex values yet... */
|
|
||||||
1, NULL);
|
|
||||||
|
|
||||||
/* In case the represented variable is a REAL vector this takes
|
|
||||||
* the actual value of the first element of the linked list which
|
|
||||||
* does not make sense.
|
|
||||||
* This is an error.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* This will copy the contents of the structure vv in another structure
|
multiple = (vv->va_next != NULL);
|
||||||
* dvec (FTEDATA.H) that do not have INTEGER so that those parameters
|
if (multiple && param)
|
||||||
* defined as IF_INTEGER are not given their value when using
|
*--param = '\0';
|
||||||
* print @pot[pos_node]
|
|
||||||
* To fix this, it is necessary to define:
|
|
||||||
* OPU( "pos_node", POT_QUEST_POS_NODE, IF_REAL,"Positive node of potenciometer"),
|
|
||||||
* int POTnegNode; // number of negative node of potenciometer (Nodo_3)
|
|
||||||
* case POT_QUEST_POS_NODE:
|
|
||||||
* value->rValue = (double)fast->POTposNode;
|
|
||||||
* return (OK);
|
|
||||||
* Works but with the format 1.00000E0
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* We must make a change in format between the data that carries a variable to
|
for (v = vv; v; v = v->va_next) {
|
||||||
* put in a dvec.
|
struct dvec *nd;
|
||||||
*/
|
char *new_vec_name, new_name[256];
|
||||||
|
|
||||||
/*
|
if (multiple) {
|
||||||
* #define va_bool va_V.vV_bool
|
snprintf(new_name, sizeof new_name, "@%s[%s]",
|
||||||
* #define va_num va_V.vV_num
|
name, v->va_name);
|
||||||
* #define va_real va_V.vV_real
|
new_vec_name = new_name;
|
||||||
* #define va_string va_V.vV_string
|
} else {
|
||||||
* #define va_vlist va_V.vV_list
|
new_vec_name = whole;
|
||||||
* enum cp_types {
|
|
||||||
* CP_BOOL,
|
|
||||||
* CP_NUM,
|
|
||||||
* CP_REAL,
|
|
||||||
* CP_STRING,
|
|
||||||
* CP_LIST
|
|
||||||
° };
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* The variable is a vector */
|
|
||||||
if (vv->va_type == CP_LIST) {
|
|
||||||
/* Compute the length of the vector,
|
|
||||||
* used with the parameters of isrc and vsrc
|
|
||||||
*/
|
|
||||||
struct variable *nv;
|
|
||||||
|
|
||||||
/* Count the number of nodes in the list */
|
|
||||||
i = 0;
|
|
||||||
for (nv = vv->va_vlist; nv; nv = nv->va_next) {
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
|
nd = dvec_alloc(copy(new_vec_name),
|
||||||
|
SV_NOTYPE,
|
||||||
|
VF_REAL, /* No complex values yet... */
|
||||||
|
1, NULL);
|
||||||
|
|
||||||
dvec_realloc(d, i, NULL); /* Resize to # nodes */
|
switch (v->va_type) {
|
||||||
|
case CP_BOOL:
|
||||||
|
*nd->v_realdata = (double)v->va_bool;
|
||||||
|
break;
|
||||||
|
case CP_NUM:
|
||||||
|
*nd->v_realdata = (double)v->va_num;
|
||||||
|
break;
|
||||||
|
case CP_REAL:
|
||||||
|
*nd->v_realdata = v->va_real;
|
||||||
|
break;
|
||||||
|
case CP_STRING:
|
||||||
|
fprintf(stderr,
|
||||||
|
"ERROR: can not handle string value "
|
||||||
|
"of '%s' in vec_get(%s)\nIgnoring...\n",
|
||||||
|
v->va_name, new_vec_name);
|
||||||
|
dvec_free(nd);
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
case CP_LIST:
|
||||||
|
{
|
||||||
|
struct variable *nv;
|
||||||
|
enum cp_types ft;
|
||||||
|
|
||||||
/* Step through the list again, setting values this time */
|
/* Array values are presented as a list.
|
||||||
i = 0;
|
* Compute the length of the vector, and check that
|
||||||
for (nv = vv->va_vlist; nv; nv = nv->va_next) {
|
* it is homogenous:
|
||||||
d->v_realdata[i++] = nv->va_real;
|
* used with the parameters of isrc and vsrc
|
||||||
}
|
*/
|
||||||
|
|
||||||
/* To be able to identify the vector to represent
|
|
||||||
* belongs to a special "conunto" and should be printed in a
|
|
||||||
* special way.
|
|
||||||
*/
|
|
||||||
d->v_dims[1] = 1;
|
|
||||||
}
|
|
||||||
else if (vv->va_type == CP_NUM) { /* Variable is an integer */
|
|
||||||
*d->v_realdata = (double) vv->va_num;
|
|
||||||
}
|
|
||||||
else if (vv->va_type == CP_REAL) { /* Variable is a real */
|
|
||||||
if (!(vv->va_next)) {
|
|
||||||
/* Only a real data
|
|
||||||
* usually normal
|
|
||||||
*/
|
|
||||||
*d->v_realdata = vv->va_real;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* Real data set
|
|
||||||
* When you print a model @ [all]
|
|
||||||
* Just print numerical values, not the string
|
|
||||||
*/
|
|
||||||
struct variable *nv;
|
|
||||||
/* We go to print the list of values
|
|
||||||
* nv->va_name = Parameter description
|
|
||||||
* nv->va_string = Parameter
|
|
||||||
* nv->va_real= Value
|
|
||||||
*/
|
|
||||||
nv = vv;
|
|
||||||
for (i = 1; ; i++) {
|
|
||||||
switch (nv->va_type) {
|
|
||||||
case CP_REAL:
|
|
||||||
fprintf(stdout, "%s=%g\n", nv->va_name, nv->va_real);
|
|
||||||
break;
|
|
||||||
case CP_STRING:
|
|
||||||
fprintf(stdout, "%s=%s\n", nv->va_name, nv->va_string);
|
|
||||||
break;
|
|
||||||
case CP_NUM:
|
|
||||||
fprintf(stdout, "%s=%d\n", nv->va_name, nv->va_num);
|
|
||||||
break;
|
|
||||||
case CP_BOOL:
|
|
||||||
fprintf(stdout, "%s=%d\n", nv->va_name, nv->va_bool);
|
|
||||||
break;
|
|
||||||
default: {
|
|
||||||
fprintf(stderr, "ERROR: enumeration value `CP_LIST' not handled in vec_get\nIgnoring...\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nv = nv->va_next;
|
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
nv = v->va_vlist;
|
||||||
if (!nv) {
|
if (!nv) {
|
||||||
break;
|
dvec_free(nd);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ft = nv->va_type;
|
||||||
|
for (; nv; nv = nv->va_next) {
|
||||||
|
/* Count the number of nodes in the list */
|
||||||
|
|
||||||
|
i++;
|
||||||
|
if (nv->va_type != ft)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (nv || ft == CP_STRING || ft == CP_LIST) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"ERROR: can not handle mixed, string or list "
|
||||||
|
"value of '%s' in vec_get(%s)\nIgnoring...\n",
|
||||||
|
v->va_name, new_vec_name);
|
||||||
|
dvec_free(nd);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
dvec_realloc(nd, i, NULL); /* Resize to # nodes */
|
||||||
|
|
||||||
|
/* Step through the list again, setting values this time */
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
for (nv = v->va_vlist; nv; nv = nv->va_next) {
|
||||||
|
switch (ft) {
|
||||||
|
case CP_BOOL:
|
||||||
|
nd->v_realdata[i++] = (double)nv->va_bool;
|
||||||
|
break;
|
||||||
|
case CP_NUM:
|
||||||
|
nd->v_realdata[i++] = (double)nv->va_num;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
case CP_REAL:
|
||||||
|
nd->v_realdata[i++] = nv->va_real;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* To be able to identify the vector to represent
|
||||||
|
* belongs to a special "conunto" and should be printed
|
||||||
|
* in a special way.
|
||||||
|
*/
|
||||||
|
nd->v_dims[1] = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
/* To distinguish those does not take anything for print screen to
|
|
||||||
* make a print or M1 @ @ M1 [all] leaving only the correct data
|
|
||||||
* and not the last
|
|
||||||
*/
|
|
||||||
d->v_rlength = 1;
|
|
||||||
}
|
}
|
||||||
|
/* Chain it on. */
|
||||||
|
|
||||||
|
vec_new(nd);
|
||||||
|
nd->v_link2 = d;
|
||||||
|
d = nd;
|
||||||
}
|
}
|
||||||
|
|
||||||
free_struct_variable(vv);
|
free_struct_variable(vv);
|
||||||
tfree(wd);
|
tfree(wd);
|
||||||
vec_new(d);
|
|
||||||
tfree(whole);
|
tfree(whole);
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -378,7 +378,7 @@ int WPRINT_DrawLine(int x1, int y1, int x2, int y2, bool isgrid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int WPRINT_Arc(int x0, int y0, int radius, double theta, double delta_theta)
|
int WPRINT_Arc(int x0, int y0, int radius, double theta, double delta_theta, bool isgrid)
|
||||||
/*
|
/*
|
||||||
* Notes:
|
* Notes:
|
||||||
* Draws an arc of <radius> and center at (x0,y0) beginning at
|
* Draws an arc of <radius> and center at (x0,y0) beginning at
|
||||||
|
|
@ -397,6 +397,8 @@ int WPRINT_Arc(int x0, int y0, int radius, double theta, double delta_theta)
|
||||||
double dx0;
|
double dx0;
|
||||||
double dy0;
|
double dy0;
|
||||||
|
|
||||||
|
NG_IGNORE(isgrid);
|
||||||
|
|
||||||
if (!currentgraph) return 0;
|
if (!currentgraph) return 0;
|
||||||
pd = pPrintData(currentgraph);
|
pd = pPrintData(currentgraph);
|
||||||
if (!pd) return 0;
|
if (!pd) return 0;
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ int WPRINT_NewViewport( GRAPH * graph);
|
||||||
int WPRINT_Close(void);
|
int WPRINT_Close(void);
|
||||||
int WPRINT_Clear(void);
|
int WPRINT_Clear(void);
|
||||||
int WPRINT_DrawLine(int x1, int y1, int x2, int y2, bool isgrid);
|
int WPRINT_DrawLine(int x1, int y1, int x2, int y2, bool isgrid);
|
||||||
int WPRINT_Arc(int x0, int y0, int radius, double theta, double delta_theta);
|
int WPRINT_Arc(int x0, int y0, int radius, double theta, double delta_theta, bool isgrid);
|
||||||
int WPRINT_Text( char * text, int x, int y, int degrees);
|
int WPRINT_Text( char * text, int x, int y, int degrees);
|
||||||
int WPRINT_DefineColor(int colorid, double red, double green, double blue);
|
int WPRINT_DefineColor(int colorid, double red, double green, double blue);
|
||||||
int WPRINT_DefineLinestyle(int num, int mask);
|
int WPRINT_DefineLinestyle(int num, int mask);
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,20 @@
|
||||||
#ifndef ngspice_BOOL_H
|
#ifndef ngspice_BOOL_H
|
||||||
#define ngspice_BOOL_H
|
#define ngspice_BOOL_H
|
||||||
|
|
||||||
//typedef unsigned char bool;
|
#if defined (__MINGW32__) || defined (_MSC_VER)
|
||||||
#ifndef __cplusplus
|
#ifndef __cplusplus
|
||||||
typedef int bool;
|
typedef int bool;
|
||||||
#endif
|
#endif
|
||||||
|
#else
|
||||||
|
#include <stdbool.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef int BOOL;
|
typedef int BOOL;
|
||||||
|
|
||||||
|
|
||||||
#define BOOLEAN int
|
#define BOOLEAN int
|
||||||
#define TRUE 1
|
#define TRUE 1
|
||||||
#define FALSE 0
|
#define FALSE 0
|
||||||
#define NO 0
|
#define NO 0
|
||||||
#define YES 1
|
#define YES 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,9 @@ typedef struct SPICEdev {
|
||||||
/* noise routine */
|
/* noise routine */
|
||||||
int (*DEVsoaCheck)(CKTcircuit*,GENmodel*);
|
int (*DEVsoaCheck)(CKTcircuit*,GENmodel*);
|
||||||
/* subroutine to call on soa check */
|
/* subroutine to call on soa check */
|
||||||
|
int *DEVinstSize; /* size of an instance */
|
||||||
|
int *DEVmodSize; /* size of a model */
|
||||||
|
|
||||||
#ifdef CIDER
|
#ifdef CIDER
|
||||||
void (*DEVdump)(GENmodel *, CKTcircuit *);
|
void (*DEVdump)(GENmodel *, CKTcircuit *);
|
||||||
void (*DEVacct)(GENmodel *, CKTcircuit *, FILE *);
|
void (*DEVacct)(GENmodel *, CKTcircuit *, FILE *);
|
||||||
|
|
@ -114,8 +117,6 @@ typedef struct SPICEdev {
|
||||||
* now used only by cider numerical devices
|
* now used only by cider numerical devices
|
||||||
*/
|
*/
|
||||||
#endif
|
#endif
|
||||||
int *DEVinstSize; /* size of an instance */
|
|
||||||
int *DEVmodSize; /* size of a model */
|
|
||||||
|
|
||||||
#ifdef KLU
|
#ifdef KLU
|
||||||
int (*DEVbindCSC)(GENmodel *, CKTcircuit *);
|
int (*DEVbindCSC)(GENmodel *, CKTcircuit *);
|
||||||
|
|
|
||||||
|
|
@ -282,6 +282,8 @@ struct IFdevice {
|
||||||
int *numModelParms; /* number of model parameter descriptors */
|
int *numModelParms; /* number of model parameter descriptors */
|
||||||
IFparm *modelParms; /* array of model parameter descriptors */
|
IFparm *modelParms; /* array of model parameter descriptors */
|
||||||
|
|
||||||
|
int flags; /* DEV_ */
|
||||||
|
|
||||||
/* gtri - modify - wbk - 10/11/90 - add entries to hold data required */
|
/* gtri - modify - wbk - 10/11/90 - add entries to hold data required */
|
||||||
/* by new parser */
|
/* by new parser */
|
||||||
#ifdef XSPICE
|
#ifdef XSPICE
|
||||||
|
|
@ -298,8 +300,6 @@ struct IFdevice {
|
||||||
/* gtri - end - wbk - 10/11/90 */
|
/* gtri - end - wbk - 10/11/90 */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int flags; /* DEV_ */
|
|
||||||
|
|
||||||
#ifdef OSDI
|
#ifdef OSDI
|
||||||
const void *registry_entry;
|
const void *registry_entry;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,7 @@ char *INPerrCat(char *, char *);
|
||||||
char *INPstrCat(char *, char, char *);
|
char *INPstrCat(char *, char, char *);
|
||||||
char *INPerror(int);
|
char *INPerror(int);
|
||||||
double INPevaluate(char **, int *, int);
|
double INPevaluate(char **, int *, int);
|
||||||
|
double INPevaluate2(char **, int *, int);
|
||||||
double INPevaluateRKM_R(char **, int *, int);
|
double INPevaluateRKM_R(char **, int *, int);
|
||||||
double INPevaluateRKM_C(char **, int *, int);
|
double INPevaluateRKM_C(char **, int *, int);
|
||||||
double INPevaluateRKM_L(char **, int *, int);
|
double INPevaluateRKM_L(char **, int *, int);
|
||||||
|
|
|
||||||
|
|
@ -47,21 +47,14 @@ NON-STANDARD FEATURES
|
||||||
#include "ngspice/miftypes.h"
|
#include "ngspice/miftypes.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/* Values of different types used by the parser. */
|
||||||
* Values of different types used by the parser. Note that this is a structure
|
|
||||||
* instead of a union because we need to do initializations in the ifspec.c files for
|
|
||||||
* the models and unions cannot be initialized in any useful way in C
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct Mif_Parse_Value {
|
|
||||||
|
|
||||||
|
union Mif_Parse_Value {
|
||||||
Mif_Boolean_t bvalue; /* For boolean values */
|
Mif_Boolean_t bvalue; /* For boolean values */
|
||||||
int ivalue; /* For integer values */
|
int ivalue; /* For integer values */
|
||||||
double rvalue; /* For real values */
|
double rvalue; /* For real values */
|
||||||
Mif_Complex_t cvalue; /* For complex values */
|
Mif_Complex_t cvalue; /* For complex values */
|
||||||
char *svalue; /* For string values */
|
char *svalue; /* For string values */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -101,8 +94,8 @@ struct Mif_Param_Info {
|
||||||
char *name; /* Name of this parameter */
|
char *name; /* Name of this parameter */
|
||||||
char *description; /* Description of this parameter */
|
char *description; /* Description of this parameter */
|
||||||
Mif_Data_Type_t type; /* Is this a real, boolean, string, ... */
|
Mif_Data_Type_t type; /* Is this a real, boolean, string, ... */
|
||||||
Mif_Boolean_t has_default; /* True if there is a default value */
|
int default_value_siz;/* Size of default_values array. */
|
||||||
Mif_Parse_Value_t default_value; /* The default value */
|
Mif_Parse_Value_t *default_values; /* The default values (array). */
|
||||||
Mif_Boolean_t has_lower_limit; /* True if there is a lower limit */
|
Mif_Boolean_t has_lower_limit; /* True if there is a lower limit */
|
||||||
Mif_Parse_Value_t lower_limit; /* The lower limit for this parameter */
|
Mif_Parse_Value_t lower_limit; /* The lower limit for this parameter */
|
||||||
Mif_Boolean_t has_upper_limit; /* True if there is a upper limit */
|
Mif_Boolean_t has_upper_limit; /* True if there is a upper limit */
|
||||||
|
|
|
||||||
|
|
@ -205,19 +205,19 @@ typedef struct Mif_Complex {
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
|
|
||||||
Mif_Boolean_t bvalue; /* For digital node value */
|
Mif_Boolean_t bvalue; /* For boolean parameters */
|
||||||
int ivalue; /* For integer parameters */
|
int ivalue; /* For integer parameters */
|
||||||
double rvalue; /* For spice node values and real parameters */
|
double rvalue; /* For spice node values and real parameters */
|
||||||
Mif_Complex_t cvalue; /* For complex parameters */
|
Mif_Complex_t cvalue; /* For complex parameters */
|
||||||
char *svalue; /* For string parameters */
|
char *svalue; /* For string parameters */
|
||||||
void *pvalue; /* For user defined nodes */
|
void *pvalue; /* For Digital and user defined nodes */
|
||||||
|
|
||||||
} Mif_Value_t;
|
} Mif_Value_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* types from mifparse.h */
|
/* types from mifparse.h */
|
||||||
typedef struct Mif_Parse_Value Mif_Parse_Value_t;
|
typedef union Mif_Parse_Value Mif_Parse_Value_t;
|
||||||
typedef struct Mif_Conn_Info Mif_Conn_Info_t;
|
typedef struct Mif_Conn_Info Mif_Conn_Info_t;
|
||||||
typedef struct Mif_Param_Info Mif_Param_Info_t;
|
typedef struct Mif_Param_Info Mif_Param_Info_t;
|
||||||
typedef struct Mif_Inst_Var_Info Mif_Inst_Var_Info_t;
|
typedef struct Mif_Inst_Var_Info Mif_Inst_Var_Info_t;
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,13 @@
|
||||||
/* header file for shared ngspice */
|
/* header file for shared ngspice */
|
||||||
/* Copyright 2021 Holger Vogt */
|
/* Copyright 2021-2024 Holger Vogt */
|
||||||
/* Modified BSD license */
|
/* Modified BSD license */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Interface between a calling program (caller) and ngspice.dll (ngspice.so)
|
Interface between a calling program (caller) and ngspice.dll (ngspice.so)
|
||||||
|
**
|
||||||
|
ngSpice_nospinit(void)
|
||||||
|
Set variable no_spinit, if reading the initialization file 'spinit' is not wanted.
|
||||||
|
To be called before ngSpice_Init()
|
||||||
|
|
||||||
**
|
**
|
||||||
ngSpice_Init(SendChar*, SendStat*, ControlledExit*,
|
ngSpice_Init(SendChar*, SendStat*, ControlledExit*,
|
||||||
|
|
@ -441,6 +445,9 @@ NG_BOOL ngSpice_running(void);
|
||||||
IMPEXP
|
IMPEXP
|
||||||
NG_BOOL ngSpice_SetBkpt(double time);
|
NG_BOOL ngSpice_SetBkpt(double time);
|
||||||
|
|
||||||
|
/* Set variable no_spinit, if reading 'spinit' is not wanted. */
|
||||||
|
IMPEXP
|
||||||
|
int ngSpice_nospinit(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -788,6 +788,15 @@ ngSpice_running (void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Set variable no_spinit, if reading 'spinit' is not wanted. */
|
||||||
|
IMPEXP
|
||||||
|
int
|
||||||
|
ngSpice_nospinit(void)
|
||||||
|
{
|
||||||
|
bool t = TRUE;
|
||||||
|
cp_vset("no_spinit", CP_BOOL, &t);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialise external voltage source and synchronization */
|
/* Initialise external voltage source and synchronization */
|
||||||
IMPEXP
|
IMPEXP
|
||||||
|
|
|
||||||
|
|
@ -31,15 +31,15 @@ Nintegrate (double noizDens, double lnNdens, double lnNlstDens, Ndata *data)
|
||||||
|
|
||||||
exponent = (lnNdens - lnNlstDens) / data->delLnFreq;
|
exponent = (lnNdens - lnNlstDens) / data->delLnFreq;
|
||||||
if ( fabs(exponent) < N_INTFTHRESH ) {
|
if ( fabs(exponent) < N_INTFTHRESH ) {
|
||||||
return (noizDens * data->delFreq);
|
return (noizDens * data->delFreq);
|
||||||
} else {
|
} else {
|
||||||
a = limexp(lnNdens - exponent*data->lnFreq);
|
a = limexp(lnNdens - exponent*data->lnFreq);
|
||||||
exponent += 1.0;
|
exponent += 1.0;
|
||||||
if (fabs(exponent) < N_INTUSELOG) {
|
if (fabs(exponent) < N_INTUSELOG) {
|
||||||
return (a * (data->lnFreq - data->lnLastFreq));
|
return (a * (data->lnFreq - data->lnLastFreq));
|
||||||
} else {
|
} else {
|
||||||
return (a * ((exp(exponent * data->lnFreq) - exp(exponent * data->lnLastFreq)) /
|
return (a * ((limexp(exponent * data->lnFreq) - limexp(exponent * data->lnLastFreq)) /
|
||||||
exponent));
|
exponent));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -161,7 +161,8 @@ void com_optran(wordlist* wl) {
|
||||||
wltmp = wltmp->wl_next;
|
wltmp = wltmp->wl_next;
|
||||||
stpstr = wltmp->wl_word;
|
stpstr = wltmp->wl_word;
|
||||||
opramptime = INPevaluate(&stpstr, &err, 1);
|
opramptime = INPevaluate(&stpstr, &err, 1);
|
||||||
if (err || (*stpstr != '\0'))
|
/* optran with uic reads initial conditions */
|
||||||
|
if (err || ((*stpstr != '\0') && !strstr(stpstr, "uic")))
|
||||||
goto bugquit;
|
goto bugquit;
|
||||||
if (opstepsize > opfinaltime) {
|
if (opstepsize > opfinaltime) {
|
||||||
fprintf(stderr, "Error: Optran step size larger than final time.\n");
|
fprintf(stderr, "Error: Optran step size larger than final time.\n");
|
||||||
|
|
|
||||||
|
|
@ -89,8 +89,8 @@ CKTinit(CKTcircuit **ckt) /* new circuit to create */
|
||||||
sckt->CKTabsDv = 0.5;
|
sckt->CKTabsDv = 0.5;
|
||||||
sckt->CKTrelDv = 2.0;
|
sckt->CKTrelDv = 2.0;
|
||||||
sckt->CKTvarHertz = 0;
|
sckt->CKTvarHertz = 0;
|
||||||
sckt->DEVnameHash = nghash_init_pointer(100);
|
sckt->DEVnameHash = nghash_init(100);
|
||||||
sckt->MODnameHash = nghash_init_pointer(100);
|
sckt->MODnameHash = nghash_init(100);
|
||||||
sckt->CKTepsmin = 1e-28;
|
sckt->CKTepsmin = 1e-28;
|
||||||
|
|
||||||
#ifdef XSPICE
|
#ifdef XSPICE
|
||||||
|
|
|
||||||
|
|
@ -24,12 +24,18 @@ CPLask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value, IFvalue *s
|
||||||
NG_IGNORE(select);
|
NG_IGNORE(select);
|
||||||
|
|
||||||
switch(which) {
|
switch(which) {
|
||||||
|
/* String tables are expected to be freed, but not the strings. */
|
||||||
|
|
||||||
case CPL_POS_NODE:
|
case CPL_POS_NODE:
|
||||||
value->v.vec.sVec = here->in_node_names;
|
value->v.vec.sVec = TMALLOC(char *, here->dimension);
|
||||||
|
memcpy(value->v.vec.sVec, here->in_node_names,
|
||||||
|
here->dimension * sizeof (char *));
|
||||||
value->v.numValue = here->dimension;
|
value->v.numValue = here->dimension;
|
||||||
return(OK);
|
return(OK);
|
||||||
case CPL_NEG_NODE:
|
case CPL_NEG_NODE:
|
||||||
value->v.vec.sVec = here->out_node_names;
|
value->v.vec.sVec = TMALLOC(char *, here->dimension);
|
||||||
|
memcpy(value->v.vec.sVec, here->out_node_names,
|
||||||
|
here->dimension * sizeof (char *));
|
||||||
value->v.numValue = here->dimension;
|
value->v.numValue = here->dimension;
|
||||||
return(OK);
|
return(OK);
|
||||||
case CPL_DIM:
|
case CPL_DIM:
|
||||||
|
|
|
||||||
|
|
@ -686,7 +686,7 @@ INPevaluateRKM_C(char** line, int* error, int gobble)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In addition to fcn INPevaluate() above, allow values like 4k7,
|
/* In addition to fcn INPevaluate() above, allow values like 4k7,
|
||||||
similar to the RKM code (used by inp2r) */
|
similar to the RKM code (used by inp2l) */
|
||||||
double
|
double
|
||||||
INPevaluateRKM_L(char** line, int* error, int gobble)
|
INPevaluateRKM_L(char** line, int* error, int gobble)
|
||||||
/* gobble: non-zero to gobble rest of token, zero to leave it alone */
|
/* gobble: non-zero to gobble rest of token, zero to leave it alone */
|
||||||
|
|
@ -923,3 +923,217 @@ INPevaluateRKM_L(char** line, int* error, int gobble)
|
||||||
pow(10.0, (double)(expo1 + expsgn * expo2)));
|
pow(10.0, (double)(expo1 + expsgn * expo2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This version will move past the scale factor for the rest of the token */
|
||||||
|
double
|
||||||
|
INPevaluate2(char** line, int* error, int gobble)
|
||||||
|
/* gobble: non-zero to gobble rest of token, zero to leave it alone */
|
||||||
|
{
|
||||||
|
char* token;
|
||||||
|
char* here;
|
||||||
|
double mantis;
|
||||||
|
int expo1;
|
||||||
|
int expo2;
|
||||||
|
int sign;
|
||||||
|
int expsgn;
|
||||||
|
char* tmpline;
|
||||||
|
|
||||||
|
/* setup */
|
||||||
|
tmpline = *line;
|
||||||
|
|
||||||
|
if (gobble) {
|
||||||
|
/* MW. INPgetUTok should be called with gobble=0 or it make
|
||||||
|
* errors in v(1,2) exp */
|
||||||
|
*error = INPgetUTok(line, &token, 0);
|
||||||
|
if (*error)
|
||||||
|
return (0.0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
token = *line;
|
||||||
|
*error = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mantis = 0;
|
||||||
|
expo1 = 0;
|
||||||
|
expo2 = 0;
|
||||||
|
sign = 1;
|
||||||
|
expsgn = 1;
|
||||||
|
|
||||||
|
/* loop through all of the input token */
|
||||||
|
here = token;
|
||||||
|
|
||||||
|
if (*here == '+')
|
||||||
|
here++; /* plus, so do nothing except skip it */
|
||||||
|
else if (*here == '-') { /* minus, so skip it, and change sign */
|
||||||
|
here++;
|
||||||
|
sign = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((*here == '\0') || ((!(isdigit_c(*here))) && (*here != '.'))) {
|
||||||
|
/* number looks like just a sign! */
|
||||||
|
*error = 1;
|
||||||
|
if (gobble) {
|
||||||
|
FREE(token);
|
||||||
|
/* back out the 'gettok' operation */
|
||||||
|
*line = tmpline;
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (isdigit_c(*here)) {
|
||||||
|
/* digit, so accumulate it. */
|
||||||
|
mantis = 10 * mantis + *here - '0';
|
||||||
|
here++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*here == '\0') {
|
||||||
|
/* reached the end of token - done. */
|
||||||
|
if (gobble) {
|
||||||
|
FREE(token);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*line = here;
|
||||||
|
}
|
||||||
|
return ((double)mantis * sign);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*here == ':') {
|
||||||
|
/* ':' is no longer used for subcircuit node numbering
|
||||||
|
but is part of ternary function a?b:c
|
||||||
|
FIXME : subcircuit models still use ':' for model numbering
|
||||||
|
Will this hurt somewhere? */
|
||||||
|
if (gobble) {
|
||||||
|
FREE(token);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*line = here;
|
||||||
|
}
|
||||||
|
return ((double)mantis * sign);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* after decimal point! */
|
||||||
|
if (*here == '.') {
|
||||||
|
/* found a decimal point! */
|
||||||
|
here++; /* skip to next character */
|
||||||
|
|
||||||
|
if (*here == '\0') {
|
||||||
|
/* number ends in the decimal point */
|
||||||
|
if (gobble) {
|
||||||
|
FREE(token);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*line = here;
|
||||||
|
}
|
||||||
|
return ((double)mantis * sign);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (isdigit_c(*here)) {
|
||||||
|
/* digit, so accumulate it. */
|
||||||
|
mantis = 10 * mantis + *here - '0';
|
||||||
|
expo1 = expo1 - 1;
|
||||||
|
here++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now look for "E","e",etc to indicate an exponent */
|
||||||
|
if ((*here == 'E') || (*here == 'e') || (*here == 'D') || (*here == 'd')) {
|
||||||
|
|
||||||
|
/* have an exponent, so skip the e */
|
||||||
|
here++;
|
||||||
|
|
||||||
|
/* now look for exponent sign */
|
||||||
|
if (*here == '+')
|
||||||
|
here++; /* just skip + */
|
||||||
|
else if (*here == '-') {
|
||||||
|
here++; /* skip over minus sign */
|
||||||
|
expsgn = -1; /* and make a negative exponent */
|
||||||
|
/* now look for the digits of the exponent */
|
||||||
|
}
|
||||||
|
|
||||||
|
while (isdigit_c(*here)) {
|
||||||
|
expo2 = 10 * expo2 + *here - '0';
|
||||||
|
here++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now we have all of the numeric part of the number, time to
|
||||||
|
* look for the scale factor (alphabetic)
|
||||||
|
*/
|
||||||
|
switch (*here) {
|
||||||
|
case 't':
|
||||||
|
case 'T':
|
||||||
|
expo1 = expo1 + 12;
|
||||||
|
here++;
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
case 'G':
|
||||||
|
expo1 = expo1 + 9;
|
||||||
|
here++;
|
||||||
|
break;
|
||||||
|
case 'k':
|
||||||
|
case 'K':
|
||||||
|
expo1 = expo1 + 3;
|
||||||
|
here++;
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
case 'U':
|
||||||
|
expo1 = expo1 - 6;
|
||||||
|
here++;
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
case 'N':
|
||||||
|
expo1 = expo1 - 9;
|
||||||
|
here++;
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
case 'P':
|
||||||
|
expo1 = expo1 - 12;
|
||||||
|
here++;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
case 'F':
|
||||||
|
expo1 = expo1 - 15;
|
||||||
|
here++;
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
case 'A':
|
||||||
|
expo1 = expo1 - 18;
|
||||||
|
here++;
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
case 'M':
|
||||||
|
if (((here[1] == 'E') || (here[1] == 'e')) &&
|
||||||
|
((here[2] == 'G') || (here[2] == 'g')))
|
||||||
|
{
|
||||||
|
expo1 = expo1 + 6; /* Meg */
|
||||||
|
here += 3;
|
||||||
|
}
|
||||||
|
else if (((here[1] == 'I') || (here[1] == 'i')) &&
|
||||||
|
((here[2] == 'L') || (here[2] == 'l')))
|
||||||
|
{
|
||||||
|
expo1 = expo1 - 6;
|
||||||
|
mantis *= 25.4; /* Mil */
|
||||||
|
here += 3;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
expo1 = expo1 - 3; /* m, milli */
|
||||||
|
here++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gobble) {
|
||||||
|
FREE(token);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*line = here;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (sign * mantis *
|
||||||
|
pow(10.0, (double)(expo1 + expsgn * expo2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ set x11lineararcs
|
||||||
*set askquit
|
*set askquit
|
||||||
** set the number of threads in openmp
|
** set the number of threads in openmp
|
||||||
** default (if compiled with --enable-openmp) is: 2
|
** default (if compiled with --enable-openmp) is: 2
|
||||||
*set num_threads=4
|
set num_threads=8
|
||||||
|
|
||||||
* comment out if central osdi management is set up
|
* comment out if central osdi management is set up
|
||||||
unset osdi_enabled
|
unset osdi_enabled
|
||||||
|
|
|
||||||
|
|
@ -208,8 +208,8 @@ typedef struct {
|
||||||
char *name; /* Name of this parameter */
|
char *name; /* Name of this parameter */
|
||||||
char *description; /* Description of this parameter */
|
char *description; /* Description of this parameter */
|
||||||
Data_Type_t type; /* Data type, e.g. REAL, INTEGER, ... */
|
Data_Type_t type; /* Data type, e.g. REAL, INTEGER, ... */
|
||||||
bool has_default; /* True if there is a default value */
|
int default_value_idx;/* Start of default_values.. */
|
||||||
Value_t default_value; /* The default value */
|
int default_value_cnt;/* Number of default_values.. */
|
||||||
bool has_lower_limit; /* True if there is a lower limit */
|
bool has_lower_limit; /* True if there is a lower limit */
|
||||||
Value_t lower_limit; /* The lower limit for this parameter */
|
Value_t lower_limit; /* The lower limit for this parameter */
|
||||||
bool has_upper_limit; /* True if there is a upper limit */
|
bool has_upper_limit; /* True if there is a upper limit */
|
||||||
|
|
@ -239,7 +239,14 @@ typedef struct {
|
||||||
|
|
||||||
} Inst_Var_Info_t;
|
} Inst_Var_Info_t;
|
||||||
|
|
||||||
|
/* Structure used when parsing default values from the IFS file, used below. */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool has_value;
|
||||||
|
bool advance; // Used for vector default values.
|
||||||
|
Data_Type_t kind;
|
||||||
|
Value_t u; // Union holding the value.
|
||||||
|
} My_Value_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The all encompassing structure for the ifs table information
|
* The all encompassing structure for the ifs table information
|
||||||
|
|
@ -254,7 +261,8 @@ typedef struct {
|
||||||
Param_Info_t *param; /* Array of parameter info structs */
|
Param_Info_t *param; /* Array of parameter info structs */
|
||||||
int num_inst_var; /* Number of entries in the instance var table(s) */
|
int num_inst_var; /* Number of entries in the instance var table(s) */
|
||||||
Inst_Var_Info_t *inst_var; /* Array of instance variable info structs */
|
Inst_Var_Info_t *inst_var; /* Array of instance variable info structs */
|
||||||
|
int num_default_values;
|
||||||
|
My_Value_t *defaults_var; /* Array of annotated values. */
|
||||||
} Ifs_Table_t;
|
} Ifs_Table_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -115,16 +115,14 @@ Ifs_Table_t *parser_ifs_table;
|
||||||
|
|
||||||
int ifs_num_errors;
|
int ifs_num_errors;
|
||||||
|
|
||||||
static size_t alloced_size [4];
|
/* Allocated and initial sizes of tables for parse results. */
|
||||||
|
|
||||||
/*
|
static size_t alloced_size [5];
|
||||||
* !!!!! Make sure these are large enough so that they never get realloced
|
|
||||||
* !!!!! since that will cause garbage uninitialized data...
|
#define DEFAULT_SIZE_CONN 10
|
||||||
* !!!!! (FIX THIS!)
|
#define DEFAULT_SIZE_PARAM 10
|
||||||
*/
|
#define DEFAULT_SIZE_INST_VAR 10
|
||||||
#define DEFAULT_SIZE_CONN 100
|
#define DEFAULT_SIZE_DEFAULTS 100
|
||||||
#define DEFAULT_SIZE_PARAM 100
|
|
||||||
#define DEFAULT_SIZE_INST_VAR 100
|
|
||||||
#define GROW_SIZE 10
|
#define GROW_SIZE 10
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
@ -132,6 +130,7 @@ typedef enum {
|
||||||
TBL_PORT,
|
TBL_PORT,
|
||||||
TBL_PARAMETER,
|
TBL_PARAMETER,
|
||||||
TBL_STATIC_VAR,
|
TBL_STATIC_VAR,
|
||||||
|
TBL_DEFAULTS,
|
||||||
} Table_t;
|
} Table_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -368,15 +367,19 @@ assign_limits (Data_Type_t type, Param_Info_t *param, Range_t range)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Advance the item variable, checking for table overflow. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
check_item_num (void)
|
check_item_num (void)
|
||||||
{
|
{
|
||||||
|
item++;
|
||||||
if (item-item_offset >= ITEM_BUFFER_SIZE) {
|
if (item-item_offset >= ITEM_BUFFER_SIZE) {
|
||||||
fatal ("Too many items in table - split into sub-tables");
|
fatal("Too many items in table - split into sub-tables");
|
||||||
}
|
}
|
||||||
if (item > (int) alloced_size [context.table] ) {
|
if (item >= (int) alloced_size [context.table] ) {
|
||||||
switch (context.table) {
|
switch (context.table) {
|
||||||
case TBL_NAME:
|
case TBL_NAME: // Fixed size.
|
||||||
|
case TBL_DEFAULTS: // Handled in store_default_value().
|
||||||
break;
|
break;
|
||||||
case TBL_PORT:
|
case TBL_PORT:
|
||||||
alloced_size[context.table] += GROW_SIZE;
|
alloced_size[context.table] += GROW_SIZE;
|
||||||
|
|
@ -407,7 +410,6 @@ check_item_num (void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
item++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
@ -429,6 +431,7 @@ check_end_item_num (void)
|
||||||
num_items_fixed = true;
|
num_items_fixed = true;
|
||||||
switch (context.table) {
|
switch (context.table) {
|
||||||
case TBL_NAME:
|
case TBL_NAME:
|
||||||
|
case TBL_DEFAULTS:
|
||||||
break;
|
break;
|
||||||
case TBL_PORT:
|
case TBL_PORT:
|
||||||
TBL->num_conn = num_items;
|
TBL->num_conn = num_items;
|
||||||
|
|
@ -445,11 +448,38 @@ check_end_item_num (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define INIT(n) item = (n); item_offset = (n); num_items = (n); num_items_fixed = false
|
#define INIT(n) item = (n); item_offset = (n); num_items = (n); num_items_fixed = false
|
||||||
#define ITEM check_item_num()
|
#define ITEM check_item_num() // Advances the item_buffer index.
|
||||||
#define END check_end_item_num()
|
#define END check_end_item_num() // Check for excessive values in later row.
|
||||||
|
|
||||||
|
/* Store a default value for a parameter. */
|
||||||
|
|
||||||
|
static void store_default_value(My_Value_t *vp)
|
||||||
|
{
|
||||||
|
if (TBL->num_default_values >= alloced_size[TBL_DEFAULTS]) {
|
||||||
|
/* Expand table. */
|
||||||
|
|
||||||
|
alloced_size [TBL_DEFAULTS] += GROW_SIZE * 5;
|
||||||
|
TBL->defaults_var = (My_Value_t *) realloc(TBL->defaults_var,
|
||||||
|
alloced_size[TBL_DEFAULTS] * sizeof (My_Value_t));
|
||||||
|
if (!TBL->defaults_var) {
|
||||||
|
fatal ("Error allocating memory for default parameter values");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TBL->defaults_var[TBL->num_default_values++] = *vp;
|
||||||
|
if (vp->advance)
|
||||||
|
ITEM; // Count another parameter sub-table.
|
||||||
|
}
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
/* The parser perfoms a double scan for each row (labelled line), with the
|
||||||
|
* row spanning multiple sub-tables (individual connection definitions etc.).
|
||||||
|
* Values and other information are copied into the item_buffer[]
|
||||||
|
* array as they are recognised and then moved to their destination stucture
|
||||||
|
* TBL->xxxx[index] when the whole row has been parsed. Default parameter
|
||||||
|
* values are hndled differently and copied directly to TBL->defaults_var.
|
||||||
|
*/
|
||||||
|
|
||||||
%token TOK_ALLOWED_TYPES
|
%token TOK_ALLOWED_TYPES
|
||||||
%token TOK_ARRAY
|
%token TOK_ARRAY
|
||||||
%token TOK_ARRAY_BOUNDS
|
%token TOK_ARRAY_BOUNDS
|
||||||
|
|
@ -501,6 +531,10 @@ check_end_item_num (void)
|
||||||
%token TOK_SPICE_MODEL_NAME
|
%token TOK_SPICE_MODEL_NAME
|
||||||
%token TOK_STRING_LITERAL
|
%token TOK_STRING_LITERAL
|
||||||
|
|
||||||
|
/* This declares the type of Bison's "semantic values" (the value associated
|
||||||
|
* with an instance of a symbol of the grammer, $$), defining YYSTYPE.
|
||||||
|
*/
|
||||||
|
|
||||||
%union {
|
%union {
|
||||||
Ctype_List_t *ctype_list;
|
Ctype_List_t *ctype_list;
|
||||||
Dir_t dir;
|
Dir_t dir;
|
||||||
|
|
@ -549,6 +583,7 @@ YYSTYPE item_buffer [ITEM_BUFFER_SIZE];
|
||||||
ifs_file : {TBL->num_conn = 0;
|
ifs_file : {TBL->num_conn = 0;
|
||||||
TBL->num_param = 0;
|
TBL->num_param = 0;
|
||||||
TBL->num_inst_var = 0;
|
TBL->num_inst_var = 0;
|
||||||
|
TBL->num_default_values = 0;
|
||||||
|
|
||||||
saw_function_name = false;
|
saw_function_name = false;
|
||||||
saw_model_name = false;
|
saw_model_name = false;
|
||||||
|
|
@ -556,14 +591,18 @@ ifs_file : {TBL->num_conn = 0;
|
||||||
alloced_size [TBL_PORT] = DEFAULT_SIZE_CONN;
|
alloced_size [TBL_PORT] = DEFAULT_SIZE_CONN;
|
||||||
alloced_size [TBL_PARAMETER] = DEFAULT_SIZE_PARAM;
|
alloced_size [TBL_PARAMETER] = DEFAULT_SIZE_PARAM;
|
||||||
alloced_size [TBL_STATIC_VAR] = DEFAULT_SIZE_INST_VAR;
|
alloced_size [TBL_STATIC_VAR] = DEFAULT_SIZE_INST_VAR;
|
||||||
|
alloced_size [TBL_DEFAULTS] = DEFAULT_SIZE_DEFAULTS;
|
||||||
|
|
||||||
TBL->conn = (Conn_Info_t*)
|
TBL->conn = (Conn_Info_t*)
|
||||||
calloc(DEFAULT_SIZE_CONN, sizeof (Conn_Info_t));
|
calloc(DEFAULT_SIZE_CONN, sizeof (Conn_Info_t));
|
||||||
TBL->param = (Param_Info_t*)
|
TBL->param = (Param_Info_t*)
|
||||||
calloc (DEFAULT_SIZE_PARAM, sizeof (Param_Info_t));
|
calloc (DEFAULT_SIZE_PARAM, sizeof (Param_Info_t));
|
||||||
TBL->inst_var = (Inst_Var_Info_t*)
|
TBL->inst_var = (Inst_Var_Info_t*)
|
||||||
calloc (DEFAULT_SIZE_INST_VAR, sizeof (Inst_Var_Info_t));
|
calloc (DEFAULT_SIZE_INST_VAR, sizeof (Inst_Var_Info_t));
|
||||||
if (! (TBL->conn && TBL->param && TBL->inst_var) ) {
|
TBL->defaults_var = (My_Value_t *)
|
||||||
|
calloc(DEFAULT_SIZE_DEFAULTS, sizeof (My_Value_t));
|
||||||
|
if (! (TBL->conn && TBL->param &&
|
||||||
|
TBL->inst_var && TBL->defaults_var) ) {
|
||||||
fatal ("Could not allocate enough memory");
|
fatal ("Could not allocate enough memory");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -701,18 +740,8 @@ parameter_table_item : TOK_PARAMETER_NAME list_of_ids
|
||||||
check_dtype_not_pointer (ITEM_BUF(i).dtype);
|
check_dtype_not_pointer (ITEM_BUF(i).dtype);
|
||||||
TBL->param[i].type = ITEM_BUF(i).dtype;
|
TBL->param[i].type = ITEM_BUF(i).dtype;
|
||||||
}}
|
}}
|
||||||
| TOK_DEFAULT_VALUE list_of_values
|
| TOK_DEFAULT_VALUE list_of_default_values
|
||||||
{int i;
|
{END; } // Check against current sub-table count.
|
||||||
END;
|
|
||||||
FOR_ITEM (i) {
|
|
||||||
TBL->param[i].has_default =
|
|
||||||
ITEM_BUF(i).value.has_value;
|
|
||||||
if (TBL->param[i].has_default) {
|
|
||||||
assign_value (TBL->param[i].type,
|
|
||||||
&TBL->param[i].default_value,
|
|
||||||
ITEM_BUF(i).value);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
| TOK_LIMITS list_of_ranges
|
| TOK_LIMITS list_of_ranges
|
||||||
{int i;
|
{int i;
|
||||||
END;
|
END;
|
||||||
|
|
@ -870,15 +899,22 @@ number_or_dash : TOK_DASH {$$.has_bound = false;}
|
||||||
$$.bound = $1;}
|
$$.bound = $1;}
|
||||||
;
|
;
|
||||||
|
|
||||||
list_of_values : /* empty */
|
list_of_pure_values : value { $1.advance = 1; store_default_value(&$1); }
|
||||||
| list_of_values value_or_dash {ITEM; BUF.value = $2;}
|
| list_of_pure_values value
|
||||||
|
{ $2.advance = 0; store_default_value(&$2); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
list_of_default_values : /* empty */
|
||||||
|
| list_of_default_values value_or_dash
|
||||||
|
{ $2.advance = 1; store_default_value(&$2); }
|
||||||
|
| list_of_default_values
|
||||||
|
TOK_LBRACKET list_of_pure_values TOK_RBRACKET
|
||||||
|
|
||||||
value_or_dash : TOK_DASH {$$.has_value = false;}
|
value_or_dash : TOK_DASH {$$.has_value = false;}
|
||||||
| value
|
| value
|
||||||
;
|
;
|
||||||
|
|
||||||
value : string {$$.has_value = true;
|
value : string {$$.has_value = true;
|
||||||
$$.kind = CMPP_STRING;
|
$$.kind = CMPP_STRING;
|
||||||
$$.u.svalue = $1;}
|
$$.u.svalue = $1;}
|
||||||
| btype {$$.has_value = true;
|
| btype {$$.has_value = true;
|
||||||
|
|
|
||||||
|
|
@ -39,18 +39,6 @@ NON-STANDARD FEATURES
|
||||||
|
|
||||||
#include "cmpp.h"
|
#include "cmpp.h"
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
bool has_value;
|
|
||||||
Data_Type_t kind;
|
|
||||||
union {
|
|
||||||
bool bvalue;
|
|
||||||
int ivalue;
|
|
||||||
double rvalue;
|
|
||||||
Complex_t cvalue;
|
|
||||||
char *svalue;
|
|
||||||
} u;
|
|
||||||
} My_Value_t;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool has_bound;
|
bool has_bound;
|
||||||
My_Value_t bound;
|
My_Value_t bound;
|
||||||
|
|
|
||||||
|
|
@ -250,7 +250,8 @@ int output_paths_from_lst_file(const char *filename)
|
||||||
|
|
||||||
bool f_have_path = false; /* do not have a path to store */
|
bool f_have_path = false; /* do not have a path to store */
|
||||||
FBTYPE fbtype;
|
FBTYPE fbtype;
|
||||||
FBOBJ fbobj;
|
FBOBJ fbobj = { .dbl_value = 0.0}; // Placate MS compiler.
|
||||||
|
|
||||||
for ( ; ; ) { /* Read items until end of file */
|
for ( ; ; ) { /* Read items until end of file */
|
||||||
/* Get the next path if not found yet */
|
/* Get the next path if not found yet */
|
||||||
if (!f_have_path) {
|
if (!f_have_path) {
|
||||||
|
|
@ -378,7 +379,8 @@ static int read_modpath(
|
||||||
|
|
||||||
bool f_have_path = false; /* do not have a path to store */
|
bool f_have_path = false; /* do not have a path to store */
|
||||||
FBTYPE fbtype;
|
FBTYPE fbtype;
|
||||||
FBOBJ fbobj;
|
FBOBJ fbobj = { .dbl_value = 0.0};
|
||||||
|
|
||||||
for ( ; ; ) { /* Read items until end of file */
|
for ( ; ; ) { /* Read items until end of file */
|
||||||
/* Get the next path if not found yet */
|
/* Get the next path if not found yet */
|
||||||
if (!f_have_path) {
|
if (!f_have_path) {
|
||||||
|
|
@ -553,7 +555,7 @@ static int read_udnpath(
|
||||||
|
|
||||||
bool f_have_path = false; /* do not have a path to store */
|
bool f_have_path = false; /* do not have a path to store */
|
||||||
FBTYPE fbtype;
|
FBTYPE fbtype;
|
||||||
FBOBJ fbobj;
|
FBOBJ fbobj = { .dbl_value = 0.0};
|
||||||
|
|
||||||
for ( ; ; ) { /* Read items until end of file */
|
for ( ; ; ) { /* Read items until end of file */
|
||||||
/* Get the next path if not found yet */
|
/* Get the next path if not found yet */
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,10 @@ NON-STANDARD FEATURES
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "cmpp.h"
|
#include "cmpp.h"
|
||||||
|
|
||||||
/* Local function prototypes */
|
/* Local function prototypes */
|
||||||
|
|
@ -183,6 +187,8 @@ EXITPOINT:
|
||||||
filename, strerror(errno));
|
filename, strerror(errno));
|
||||||
xrc = -1;
|
xrc = -1;
|
||||||
}
|
}
|
||||||
|
if (xrc < 0 && filename)
|
||||||
|
unlink(filename); // So "make" will not see it.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filename != (char *) NULL) {
|
if (filename != (char *) NULL) {
|
||||||
|
|
@ -680,29 +686,101 @@ static int write_param_info(
|
||||||
FILE *fp, /* File to write to */
|
FILE *fp, /* File to write to */
|
||||||
Ifs_Table_t *ifs_table) /* Table of Interface Specification data */
|
Ifs_Table_t *ifs_table) /* Table of Interface Specification data */
|
||||||
{
|
{
|
||||||
int xrc = 0;
|
Param_Info_t * const param = ifs_table->param;
|
||||||
int i;
|
const int num_param = ifs_table->num_param;
|
||||||
const char *str;
|
int rc, xrc = 0;
|
||||||
|
int i, dv_idx;
|
||||||
|
const char *str;
|
||||||
|
|
||||||
/* Only write the paramTable if there is something to put in it. */
|
/* Only write the paramTable if there is something to put in it. */
|
||||||
/* Otherwise, we will put NULL in the SPICEdev structure in its slot */
|
/* Otherwise, we will put NULL in the SPICEdev structure in its slot */
|
||||||
|
|
||||||
if (ifs_table->num_param == 0) {
|
if (num_param <= 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Write the default values for each parameter. */
|
||||||
|
|
||||||
/* Write the structure beginning */
|
for (i = 0, dv_idx = 0, rc = 0; i < num_param; i++) {
|
||||||
int rc = 0;
|
Param_Info_t * p_param_cur = param + i;
|
||||||
|
My_Value_t * p_val = ifs_table->defaults_var + dv_idx;
|
||||||
|
int start_index = dv_idx;
|
||||||
|
|
||||||
|
if (dv_idx >= ifs_table->num_default_values) {
|
||||||
|
fprintf(stderr, "Not enough default values for parameter: %s.\n",
|
||||||
|
p_param_cur->name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!p_val->has_value) {
|
||||||
|
/* Dummy entry, no default values. */
|
||||||
|
|
||||||
|
++dv_idx;
|
||||||
|
p_param_cur->default_value_cnt = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!p_param_cur->null_allowed) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Default value given for parameter %s but "
|
||||||
|
"the user must set instance value (Null_Allowed: no).",
|
||||||
|
p_param_cur->name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc |= fprintf(fp,
|
||||||
|
"static union Mif_Parse_Value %s_default[] = {\n",
|
||||||
|
p_param_cur->name);
|
||||||
|
|
||||||
|
do { // Write the default values for this parameter.
|
||||||
|
if (!p_val->advance && !p_param_cur->is_array) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Vector initialisation of default values "
|
||||||
|
"for non-vector parameter: %s.\n",
|
||||||
|
p_param_cur->name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_val->kind != p_param_cur->type) {
|
||||||
|
if (p_val->kind == CMPP_INTEGER &&
|
||||||
|
p_param_cur->type == CMPP_REAL) {
|
||||||
|
/* Promote it. */
|
||||||
|
|
||||||
|
p_val->u.rvalue = p_val->u.ivalue;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Data type of default value does not match for "
|
||||||
|
"parameter: %s.\n",
|
||||||
|
p_param_cur->name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
str = value_to_str(p_param_cur->type, p_val->u);
|
||||||
|
rc |= fprintf(fp, " %s,\n", str);
|
||||||
|
++dv_idx; ++p_val;
|
||||||
|
} while (dv_idx < ifs_table->num_default_values && !p_val->advance);
|
||||||
|
|
||||||
|
rc |= fprintf(fp, "};\n\n");
|
||||||
|
p_param_cur->default_value_cnt = dv_idx - start_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check outputs */
|
||||||
|
|
||||||
|
if (rc < 0) {
|
||||||
|
print_error("Writing of default param values failed.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write the main parameter structure beginning. */
|
||||||
|
|
||||||
|
rc = 0;
|
||||||
rc |= fprintf(fp,
|
rc |= fprintf(fp,
|
||||||
"\n"
|
"\n"
|
||||||
"static Mif_Param_Info_t MIFparamTable[] = {\n");
|
"static Mif_Param_Info_t MIFparamTable[] = {\n");
|
||||||
|
|
||||||
|
|
||||||
/* Write out an entry for each parameter in the table */
|
/* Write out an entry for each parameter in the table */
|
||||||
const Param_Info_t * const param = ifs_table->param;
|
|
||||||
const int num_param = ifs_table->num_param;
|
|
||||||
for (i = 0; i < num_param; i++) {
|
for (i = 0; i < num_param; i++) {
|
||||||
const Param_Info_t * const p_param_cur = param + i;
|
const Param_Info_t * const p_param_cur = param + i;
|
||||||
|
|
||||||
|
|
@ -713,14 +791,11 @@ static int write_param_info(
|
||||||
rc |= fprintf(fp, " %s,\n",
|
rc |= fprintf(fp, " %s,\n",
|
||||||
data_type_to_str(p_param_cur->type));
|
data_type_to_str(p_param_cur->type));
|
||||||
|
|
||||||
str = boolean_to_str(p_param_cur->has_default);
|
rc |= fprintf(fp, " %d,\n", p_param_cur->default_value_cnt);
|
||||||
rc |= fprintf(fp, " %s,\n", str);
|
if (p_param_cur->default_value_cnt)
|
||||||
|
rc |= fprintf(fp, " %s_default,\n", p_param_cur->name);
|
||||||
if (p_param_cur->has_default == true)
|
|
||||||
str = value_to_str(p_param_cur->type, p_param_cur->default_value);
|
|
||||||
else
|
else
|
||||||
str = no_value_to_str();
|
rc |= fprintf(fp, " NULL,\n");
|
||||||
rc |= fprintf(fp, " %s,\n", str);
|
|
||||||
|
|
||||||
str = boolean_to_str(p_param_cur->has_lower_limit);
|
str = boolean_to_str(p_param_cur->has_lower_limit);
|
||||||
rc |= fprintf(fp, " %s,\n", str);
|
rc |= fprintf(fp, " %s,\n", str);
|
||||||
|
|
@ -1205,20 +1280,20 @@ static char *value_to_str(Data_Type_t type, Value_t value)
|
||||||
|
|
||||||
case CMPP_BOOLEAN:
|
case CMPP_BOOLEAN:
|
||||||
bool_str = boolean_to_str(value.bvalue);
|
bool_str = boolean_to_str(value.bvalue);
|
||||||
sprintf(str, "{%s, 0, 0.0, {0.0, 0.0}, NULL}", bool_str);
|
sprintf(str, "{ .bvalue=%s }", bool_str);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMPP_INTEGER:
|
case CMPP_INTEGER:
|
||||||
sprintf(str, "{MIF_FALSE, %d, 0.0, {0.0, 0.0}, NULL}", value.ivalue);
|
sprintf(str, "{ .ivalue=%d }", value.ivalue);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMPP_REAL:
|
case CMPP_REAL:
|
||||||
sprintf(str, "{MIF_FALSE, 0, %e, {0.0, 0.0}, NULL}", value.rvalue);
|
sprintf(str, "{ .rvalue=%e }", value.rvalue);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMPP_COMPLEX:
|
case CMPP_COMPLEX:
|
||||||
sprintf(str, "{MIF_FALSE, 0, 0.0, {%e, %e}, NULL}",
|
sprintf(str, "{ .cvalue={%e, %e} }",
|
||||||
value.cvalue.real, value.cvalue.imag);
|
value.cvalue.real, value.cvalue.imag);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMPP_STRING:
|
case CMPP_STRING:
|
||||||
|
|
@ -1238,7 +1313,7 @@ static char *value_to_str(Data_Type_t type, Value_t value)
|
||||||
max_len += str_len;
|
max_len += str_len;
|
||||||
} /* end of resize */
|
} /* end of resize */
|
||||||
|
|
||||||
sprintf(str, "{MIF_FALSE, 0, 0.0, {0.0, 0.0}, \"%s\"}", value.svalue);
|
sprintf(str, "{ .svalue=\"%s\" }", value.svalue);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -1273,8 +1348,5 @@ static char *integer_to_str(int value)
|
||||||
|
|
||||||
static const char *no_value_to_str(void)
|
static const char *no_value_to_str(void)
|
||||||
{
|
{
|
||||||
return "{MIF_FALSE, 0, 0.0, {0.0, 0.0}, NULL}";
|
return "{ .bvalue=MIF_FALSE }";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,6 @@ int EVTload_with_event(
|
||||||
Evt_Node_Data_t *node_data;
|
Evt_Node_Data_t *node_data;
|
||||||
|
|
||||||
Mif_Private_t cm_data;
|
Mif_Private_t cm_data;
|
||||||
void *value_ptr;
|
|
||||||
|
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
/* Prepare the code model inputs */
|
/* Prepare the code model inputs */
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ PARAMETER_TABLE:
|
||||||
Parameter_Name: x y model
|
Parameter_Name: x y model
|
||||||
Description: "x array" "y array" "model type"
|
Description: "x array" "y array" "model type"
|
||||||
Data_Type: real real string
|
Data_Type: real real string
|
||||||
Default_Value: 0.0 0.0 "and"
|
Default_Value: - - "and"
|
||||||
Limits: - - -
|
Limits: - - -
|
||||||
Vector: yes yes no
|
Vector: yes yes no
|
||||||
Vector_Bounds: [2 -] [2 -] -
|
Vector_Bounds: [2 -] [2 -] -
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,8 @@ Description: "clock input" "input"
|
||||||
Direction: in in
|
Direction: in in
|
||||||
Default_Type: v v
|
Default_Type: v v
|
||||||
Allowed_Types: [v,vd,vnam,i,id] [v,vnam,vd,i,id]
|
Allowed_Types: [v,vd,vnam,i,id] [v,vnam,vd,i,id]
|
||||||
Vector: no no
|
Vector: no no
|
||||||
Vector_Bounds: - -
|
Vector_Bounds: - -
|
||||||
Null_Allowed: no yes
|
Null_Allowed: no yes
|
||||||
|
|
||||||
PORT_TABLE:
|
PORT_TABLE:
|
||||||
|
|
@ -44,8 +44,8 @@ Description: "clear signal" "output"
|
||||||
Direction: in out
|
Direction: in out
|
||||||
Default_Type: v v
|
Default_Type: v v
|
||||||
Allowed_Types: [v,vd,vnam,i,id] [v,vd,i,id]
|
Allowed_Types: [v,vd,vnam,i,id] [v,vd,i,id]
|
||||||
Vector: no no
|
Vector: no no
|
||||||
Vector_Bounds: - -
|
Vector_Bounds: - -
|
||||||
Null_Allowed: yes no
|
Null_Allowed: yes no
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
@ -53,11 +53,11 @@ PARAMETER_TABLE:
|
||||||
Parameter_Name: cntl_array pw_array
|
Parameter_Name: cntl_array pw_array
|
||||||
Description: "control in array" "pulse width array"
|
Description: "control in array" "pulse width array"
|
||||||
Data_Type: real real
|
Data_Type: real real
|
||||||
Default_Value: 0.0 1.0e-6
|
Default_Value: [0.0 1.0] [1.0e-6 0.9999999]
|
||||||
Limits: - [0 -]
|
Limits: - [0 -]
|
||||||
Vector: yes yes
|
Vector: yes yes
|
||||||
Vector_Bounds: [2 -] [2 -]
|
Vector_Bounds: [2 -] [2 -]
|
||||||
Null_Allowed: no no
|
Null_Allowed: yes yes
|
||||||
|
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
@ -67,9 +67,9 @@ Description: "clock trigger value" "pos/neg edge trigger switch"
|
||||||
Data_Type: real boolean
|
Data_Type: real boolean
|
||||||
Default_Value: 0.5 TRUE
|
Default_Value: 0.5 TRUE
|
||||||
Limits: - -
|
Limits: - -
|
||||||
Vector: no no
|
Vector: no no
|
||||||
Vector_Bounds: - -
|
Vector_Bounds: - -
|
||||||
Null_Allowed: no no
|
Null_Allowed: yes yes
|
||||||
|
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
@ -78,9 +78,9 @@ Parameter_Name: out_low out_high
|
||||||
Description: "output low value" "output high value"
|
Description: "output low value" "output high value"
|
||||||
Data_Type: real real
|
Data_Type: real real
|
||||||
Default_Value: 0.0 1.0
|
Default_Value: 0.0 1.0
|
||||||
Limits: - -
|
Limits: - -
|
||||||
Vector: no no
|
Vector: no no
|
||||||
Vector_Bounds: - -
|
Vector_Bounds: - -
|
||||||
Null_Allowed: yes yes
|
Null_Allowed: yes yes
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
@ -90,8 +90,8 @@ Description: "output rise time"
|
||||||
Data_Type: real
|
Data_Type: real
|
||||||
Default_Value: 1.0e-9
|
Default_Value: 1.0e-9
|
||||||
Limits: -
|
Limits: -
|
||||||
Vector: no
|
Vector: no
|
||||||
Vector_Bounds: -
|
Vector_Bounds: -
|
||||||
Null_Allowed: yes
|
Null_Allowed: yes
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
@ -101,8 +101,8 @@ Description: "output delay from trigger" "output delay from pw"
|
||||||
Data_Type: real real
|
Data_Type: real real
|
||||||
Default_Value: 1.0e-9 1.0e-9
|
Default_Value: 1.0e-9 1.0e-9
|
||||||
Limits: - -
|
Limits: - -
|
||||||
Vector: no no
|
Vector: no no
|
||||||
Vector_Bounds: - -
|
Vector_Bounds: - -
|
||||||
Null_Allowed: yes yes
|
Null_Allowed: yes yes
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
@ -112,8 +112,8 @@ Description: "output rise time" "retrigger switch"
|
||||||
Data_Type: real boolean
|
Data_Type: real boolean
|
||||||
Default_Value: 1.0e-9 FALSE
|
Default_Value: 1.0e-9 FALSE
|
||||||
Limits: - -
|
Limits: - -
|
||||||
Vector: no no
|
Vector: no no
|
||||||
Vector_Bounds: - -
|
Vector_Bounds: - -
|
||||||
Null_Allowed: yes yes
|
Null_Allowed: yes yes
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,8 @@ Description: "input" "output"
|
||||||
Direction: in out
|
Direction: in out
|
||||||
Default_Type: v v
|
Default_Type: v v
|
||||||
Allowed_Types: [v,vd,i,id,vnam] [v,vd,i,id]
|
Allowed_Types: [v,vd,i,id,vnam] [v,vd,i,id]
|
||||||
Vector: no no
|
Vector: no no
|
||||||
Vector_Bounds: - -
|
Vector_Bounds: - -
|
||||||
Null_Allowed: no no
|
Null_Allowed: no no
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
@ -42,11 +42,11 @@ PARAMETER_TABLE:
|
||||||
Parameter_Name: cntl_array freq_array
|
Parameter_Name: cntl_array freq_array
|
||||||
Description: "control in array" "frequency array"
|
Description: "control in array" "frequency array"
|
||||||
Data_Type: real real
|
Data_Type: real real
|
||||||
Default_Value: 0.0 1.0e3
|
Default_Value: [0.0 1.0] [1.0e3 2.0e3]
|
||||||
Limits: - [0 -]
|
Limits: - [0 -]
|
||||||
Vector: yes yes
|
Vector: yes yes
|
||||||
Vector_Bounds: [2 -] [2 -]
|
Vector_Bounds: [2 -] [2 -]
|
||||||
Null_Allowed: no no
|
Null_Allowed: yes yes
|
||||||
|
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
@ -56,7 +56,6 @@ Description: "output low value" "output high value"
|
||||||
Data_Type: real real
|
Data_Type: real real
|
||||||
Default_Value: -1.0 1.0
|
Default_Value: -1.0 1.0
|
||||||
Limits: - -
|
Limits: - -
|
||||||
Vector: no no
|
Vector: no no
|
||||||
Vector_Bounds: - -
|
Vector_Bounds: - -
|
||||||
Null_Allowed: yes yes
|
Null_Allowed: yes yes
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,8 @@ Description: "input" "output"
|
||||||
Direction: in out
|
Direction: in out
|
||||||
Default_Type: v v
|
Default_Type: v v
|
||||||
Allowed_Types: [v,vd,i,id,vnam] [v,vd,i,id]
|
Allowed_Types: [v,vd,i,id,vnam] [v,vd,i,id]
|
||||||
Vector: no no
|
Vector: no no
|
||||||
Vector_Bounds: - -
|
Vector_Bounds: - -
|
||||||
Null_Allowed: no no
|
Null_Allowed: no no
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
@ -42,11 +42,11 @@ PARAMETER_TABLE:
|
||||||
Parameter_Name: cntl_array freq_array
|
Parameter_Name: cntl_array freq_array
|
||||||
Description: "control in array" "frequency array"
|
Description: "control in array" "frequency array"
|
||||||
Data_Type: real real
|
Data_Type: real real
|
||||||
Default_Value: 0.0 1.0e3
|
Default_Value: [0.0 1.0] [1.0e3 2.0e3]
|
||||||
Limits: - [0 -]
|
Limits: - [0 -]
|
||||||
Vector: yes yes
|
Vector: yes yes
|
||||||
Vector_Bounds: [2 -] [2 -]
|
Vector_Bounds: [2 -] [2 -]
|
||||||
Null_Allowed: no no
|
Null_Allowed: yes yes
|
||||||
|
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
@ -56,8 +56,8 @@ Description: "output low value" "output high value"
|
||||||
Data_Type: real real
|
Data_Type: real real
|
||||||
Default_Value: -1.0 1.0
|
Default_Value: -1.0 1.0
|
||||||
Limits: - -
|
Limits: - -
|
||||||
Vector: no no
|
Vector: no no
|
||||||
Vector_Bounds: - -
|
Vector_Bounds: - -
|
||||||
Null_Allowed: yes yes
|
Null_Allowed: yes yes
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
@ -67,8 +67,8 @@ Description: "duty cycle" "rise time"
|
||||||
Data_Type: real real
|
Data_Type: real real
|
||||||
Default_Value: 0.5 1.0e-9
|
Default_Value: 0.5 1.0e-9
|
||||||
Limits: [1e-6 .999999] -
|
Limits: [1e-6 .999999] -
|
||||||
Vector: no no
|
Vector: no no
|
||||||
Vector_Bounds: - -
|
Vector_Bounds: - -
|
||||||
Null_Allowed: yes yes
|
Null_Allowed: yes yes
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
@ -78,8 +78,8 @@ Description: "fall time"
|
||||||
Data_Type: real
|
Data_Type: real
|
||||||
Default_Value: 1.0e-9
|
Default_Value: 1.0e-9
|
||||||
Limits: -
|
Limits: -
|
||||||
Vector: no
|
Vector: no
|
||||||
Vector_Bounds: -
|
Vector_Bounds: -
|
||||||
Null_Allowed: yes
|
Null_Allowed: yes
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,25 +28,25 @@ Description: "controlled triangle wave oscillator"
|
||||||
|
|
||||||
PORT_TABLE:
|
PORT_TABLE:
|
||||||
|
|
||||||
Port_Name: cntl_in out
|
Port_Name: cntl_in out
|
||||||
Description: "input" "output"
|
Description: "input" "output"
|
||||||
Direction: in out
|
Direction: in out
|
||||||
Default_Type: v v
|
Default_Type: v v
|
||||||
Allowed_Types: [v,vd,i,id,vnam] [v,vd,i,id]
|
Allowed_Types: [v,vd,i,id,vnam] [v,vd,i,id]
|
||||||
Vector: no no
|
Vector: no no
|
||||||
Vector_Bounds: - -
|
Vector_Bounds: - -
|
||||||
Null_Allowed: no no
|
Null_Allowed: no no
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
||||||
Parameter_Name: cntl_array freq_array
|
Parameter_Name: cntl_array freq_array
|
||||||
Description: "control in array" "frequency array"
|
Description: "control in array" "frequency array"
|
||||||
Data_Type: real real
|
Data_Type: real real
|
||||||
Default_Value: 0.0 1.0e3
|
Default_Value: [0.0 1.0] [1.0e3 2.0e3]
|
||||||
Limits: - [0 -]
|
Limits: - [0 -]
|
||||||
Vector: yes yes
|
Vector: yes yes
|
||||||
Vector_Bounds: [2 -] [2 -]
|
Vector_Bounds: [2 -] [2 -]
|
||||||
Null_Allowed: no no
|
Null_Allowed: yes yes
|
||||||
|
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,7 @@ void cm_bidi_bridge(ARGS)
|
||||||
out = 0.0; /* AtoD, no analogue output. */
|
out = 0.0; /* AtoD, no analogue output. */
|
||||||
svoc = 0.5;
|
svoc = 0.5;
|
||||||
} else {
|
} else {
|
||||||
double target, iota, interval[2], range, partial;
|
double target, iota, interval[2], range, partial = 0.0;
|
||||||
int step, step_count;
|
int step, step_count;
|
||||||
Digital_t drive, *dp;
|
Digital_t drive, *dp;
|
||||||
|
|
||||||
|
|
@ -274,7 +274,6 @@ void cm_bidi_bridge(ARGS)
|
||||||
|
|
||||||
voc = out_low + (out_high - out_low) * voc;
|
voc = out_low + (out_high - out_low) * voc;
|
||||||
target = 0.0;
|
target = 0.0;
|
||||||
partial = 0.0;
|
|
||||||
|
|
||||||
/* Calculate new value for output current. */
|
/* Calculate new value for output current. */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -140,9 +140,9 @@ void accept_output(struct co_info *pinfo, unsigned int bit_num, Digital_t *val)
|
||||||
|
|
||||||
static void output(struct instance *ip, ARGS)
|
static void output(struct instance *ip, ARGS)
|
||||||
{
|
{
|
||||||
double delay;
|
double delay;
|
||||||
Digital_t *out_vals; // XSPICE rotating memory
|
Digital_t *out_vals; // XSPICE rotating memory
|
||||||
int i, j;
|
unsigned int i, j;
|
||||||
|
|
||||||
delay = PARAM(delay) - (TIME - ip->info.vtime);
|
delay = PARAM(delay) - (TIME - ip->info.vtime);
|
||||||
if (delay <= 0) {
|
if (delay <= 0) {
|
||||||
|
|
@ -314,7 +314,7 @@ static bool check_input(struct instance *ip, Digital_t *ovp,
|
||||||
{
|
{
|
||||||
if (ovp->state != rp->what.state ||
|
if (ovp->state != rp->what.state ||
|
||||||
ovp->strength != rp->what.strength) {
|
ovp->strength != rp->what.strength) {
|
||||||
if (++ip->q_index < ip->q_length) {
|
if (++ip->q_index < (int) ip->q_length) {
|
||||||
/* Record this event. */
|
/* Record this event. */
|
||||||
|
|
||||||
ip->q[ip->q_index] = *rp;
|
ip->q[ip->q_index] = *rp;
|
||||||
|
|
@ -345,10 +345,10 @@ void ucm_d_cosim(ARGS)
|
||||||
{
|
{
|
||||||
struct instance *ip;
|
struct instance *ip;
|
||||||
Digital_t *in_vals; // XSPICE rotating memory
|
Digital_t *in_vals; // XSPICE rotating memory
|
||||||
int i, index;
|
unsigned int i, index;
|
||||||
|
|
||||||
if (INIT) {
|
if (INIT) {
|
||||||
int ins, outs, inouts;
|
unsigned int ins, outs, inouts;
|
||||||
unsigned int alloc_size;
|
unsigned int alloc_size;
|
||||||
void *handle;
|
void *handle;
|
||||||
void (*ifp)(struct co_info *);
|
void (*ifp)(struct co_info *);
|
||||||
|
|
@ -380,7 +380,7 @@ void ucm_d_cosim(ARGS)
|
||||||
cm_message_send(dlerror());
|
cm_message_send(dlerror());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ifp = dlsym(handle, "Cosim_setup");
|
ifp = (void (*)(struct co_info *))dlsym(handle, "Cosim_setup");
|
||||||
if (*ifp == NULL) {
|
if (*ifp == NULL) {
|
||||||
cm_message_printf("ERROR: no entry function in %s", fn);
|
cm_message_printf("ERROR: no entry function in %s", fn);
|
||||||
cm_message_send(dlerror());
|
cm_message_send(dlerror());
|
||||||
|
|
@ -468,7 +468,7 @@ void ucm_d_cosim(ARGS)
|
||||||
|
|
||||||
ip = STATIC_VAR(cosim_instance);
|
ip = STATIC_VAR(cosim_instance);
|
||||||
if (!ip) {
|
if (!ip) {
|
||||||
int ports;
|
unsigned int ports;
|
||||||
|
|
||||||
/* Error state. Do nothing at all. */
|
/* Error state. Do nothing at all. */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ PARAMETER_TABLE:
|
||||||
Parameter_Name: table_values
|
Parameter_Name: table_values
|
||||||
Description: "lookup table values"
|
Description: "lookup table values"
|
||||||
Data_Type: string
|
Data_Type: string
|
||||||
Default_Value: "0"
|
Default_Value: -
|
||||||
Limits: -
|
Limits: -
|
||||||
Vector: no
|
Vector: no
|
||||||
Vector_Bounds: -
|
Vector_Bounds: -
|
||||||
|
|
|
||||||
|
|
@ -55,8 +55,8 @@ Description: "input load value (F)"
|
||||||
Data_Type: real
|
Data_Type: real
|
||||||
Default_Value: 1.0e-12
|
Default_Value: 1.0e-12
|
||||||
Limits: -
|
Limits: -
|
||||||
Vector: no
|
Vector: no
|
||||||
Vector_Bounds: -
|
Vector_Bounds: -
|
||||||
Null_Allowed: yes
|
Null_Allowed: yes
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
@ -64,10 +64,10 @@ PARAMETER_TABLE:
|
||||||
Parameter_Name: table_values
|
Parameter_Name: table_values
|
||||||
Description: "lookup table values"
|
Description: "lookup table values"
|
||||||
Data_Type: string
|
Data_Type: string
|
||||||
Default_Value: "0"
|
Default_Value: -
|
||||||
Limits: -
|
Limits: -
|
||||||
Vector: no
|
Vector: no
|
||||||
Vector_Bounds: -
|
Vector_Bounds: -
|
||||||
Null_Allowed: no
|
Null_Allowed: no
|
||||||
|
|
||||||
STATIC_VAR_TABLE:
|
STATIC_VAR_TABLE:
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,6 @@ struct pwl {
|
||||||
|
|
||||||
static void cm_d_osc_callback(ARGS, Mif_Callback_Reason_t reason)
|
static void cm_d_osc_callback(ARGS, Mif_Callback_Reason_t reason)
|
||||||
{
|
{
|
||||||
struct panel_instance *instance;
|
|
||||||
|
|
||||||
if (reason == MIF_CB_DESTROY) {
|
if (reason == MIF_CB_DESTROY) {
|
||||||
struct pwl *table = STATIC_VAR(locdata);
|
struct pwl *table = STATIC_VAR(locdata);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,8 @@ Description: "control input" "output"
|
||||||
Direction: in out
|
Direction: in out
|
||||||
Default_Type: v d
|
Default_Type: v d
|
||||||
Allowed_Types: [v,vd,i,id] [d]
|
Allowed_Types: [v,vd,i,id] [d]
|
||||||
Vector: no no
|
Vector: no no
|
||||||
Vector_Bounds: - -
|
Vector_Bounds: - -
|
||||||
Null_Allowed: no no
|
Null_Allowed: no no
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -43,11 +43,11 @@ PARAMETER_TABLE:
|
||||||
Parameter_Name: cntl_array freq_array
|
Parameter_Name: cntl_array freq_array
|
||||||
Description: "control array" "frequency array"
|
Description: "control array" "frequency array"
|
||||||
Data_Type: real real
|
Data_Type: real real
|
||||||
Default_Value: 0.0 1.0e6
|
Default_Value: [0.0 1.0] [1.0e6 2.0e6]
|
||||||
Limits: - [0 -]
|
Limits: - [0 -]
|
||||||
Vector: yes yes
|
Vector: yes yes
|
||||||
Vector_Bounds: [2 -] [2 -]
|
Vector_Bounds: [2 -] [2 -]
|
||||||
Null_Allowed: no no
|
Null_Allowed: yes yes
|
||||||
|
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ PARAMETER_TABLE:
|
||||||
Parameter_Name: process_file
|
Parameter_Name: process_file
|
||||||
Description: "file name of the executable process"
|
Description: "file name of the executable process"
|
||||||
Data_Type: string
|
Data_Type: string
|
||||||
Default_Value: "process"
|
Default_Value: -
|
||||||
Limits: -
|
Limits: -
|
||||||
Vector: no
|
Vector: no
|
||||||
Vector_Bounds: -
|
Vector_Bounds: -
|
||||||
|
|
@ -100,7 +100,7 @@ Default_Value: 0
|
||||||
Limits: -
|
Limits: -
|
||||||
Vector: no
|
Vector: no
|
||||||
Vector_Bounds: -
|
Vector_Bounds: -
|
||||||
Null_Allowed: no
|
Null_Allowed: yes
|
||||||
|
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
@ -113,7 +113,7 @@ Default_Value: 1.0e-12
|
||||||
Limits: -
|
Limits: -
|
||||||
Vector: no
|
Vector: no
|
||||||
Vector_Bounds: -
|
Vector_Bounds: -
|
||||||
Null_Allowed: no
|
Null_Allowed: yes
|
||||||
|
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
@ -126,7 +126,7 @@ Default_Value: 1.0e-12
|
||||||
Limits: -
|
Limits: -
|
||||||
Vector: no
|
Vector: no
|
||||||
Vector_Bounds: -
|
Vector_Bounds: -
|
||||||
Null_Allowed: no
|
Null_Allowed: yes
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
||||||
|
|
@ -138,7 +138,7 @@ Default_Value: 1.0e-12
|
||||||
Limits: -
|
Limits: -
|
||||||
Vector: no
|
Vector: no
|
||||||
Vector_Bounds: -
|
Vector_Bounds: -
|
||||||
Null_Allowed: no
|
Null_Allowed: yes
|
||||||
|
|
||||||
|
|
||||||
STATIC_VAR_TABLE:
|
STATIC_VAR_TABLE:
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,8 @@ Description: "control input" "output"
|
||||||
Direction: in out
|
Direction: in out
|
||||||
Default_Type: v d
|
Default_Type: v d
|
||||||
Allowed_Types: [v,vd,i,id] [d]
|
Allowed_Types: [v,vd,i,id] [d]
|
||||||
Vector: no no
|
Vector: no no
|
||||||
Vector_Bounds: - -
|
Vector_Bounds: - -
|
||||||
Null_Allowed: no no
|
Null_Allowed: no no
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -45,11 +45,11 @@ PARAMETER_TABLE:
|
||||||
Parameter_Name: cntl_array dc_array
|
Parameter_Name: cntl_array dc_array
|
||||||
Description: "control array" "duty cycle array"
|
Description: "control array" "duty cycle array"
|
||||||
Data_Type: real real
|
Data_Type: real real
|
||||||
Default_Value: 0.0 0.5
|
Default_Value: [-1 1] [0 1]
|
||||||
Limits: - [0 1]
|
Limits: - [0 1]
|
||||||
Vector: yes yes
|
Vector: yes yes
|
||||||
Vector_Bounds: [2 -] [2 -]
|
Vector_Bounds: [2 -] [2 -]
|
||||||
Null_Allowed: no no
|
Null_Allowed: yes yes
|
||||||
|
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
@ -59,8 +59,8 @@ Description: "oscillator frequency" "initial phase of output"
|
||||||
Data_Type: real real
|
Data_Type: real real
|
||||||
Default_Value: 1e6 0
|
Default_Value: 1e6 0
|
||||||
Limits: [1e-6 -] [-180.0 +360.0]
|
Limits: [1e-6 -] [-180.0 +360.0]
|
||||||
Vector: no no
|
Vector: no no
|
||||||
Vector_Bounds: - -
|
Vector_Bounds: - -
|
||||||
Null_Allowed: yes yes
|
Null_Allowed: yes yes
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -71,8 +71,8 @@ Description: "rise delay" "fall delay"
|
||||||
Data_Type: real real
|
Data_Type: real real
|
||||||
Default_Value: 1e-9 1e-9
|
Default_Value: 1e-9 1e-9
|
||||||
Limits: [0 -] [0 -]
|
Limits: [0 -] [0 -]
|
||||||
Vector: no no
|
Vector: no no
|
||||||
Vector_Bounds: - -
|
Vector_Bounds: - -
|
||||||
Null_Allowed: yes yes
|
Null_Allowed: yes yes
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,8 @@ Description: "output"
|
||||||
Direction: out
|
Direction: out
|
||||||
Default_Type: d
|
Default_Type: d
|
||||||
Allowed_Types: [d]
|
Allowed_Types: [d]
|
||||||
Vector: yes
|
Vector: yes
|
||||||
Vector_Bounds: -
|
Vector_Bounds: -
|
||||||
Null_Allowed: no
|
Null_Allowed: no
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -46,9 +46,9 @@ Description: "digital input vector filename"
|
||||||
Data_Type: string
|
Data_Type: string
|
||||||
Default_Value: "source.txt"
|
Default_Value: "source.txt"
|
||||||
Limits: -
|
Limits: -
|
||||||
Vector: no
|
Vector: no
|
||||||
Vector_Bounds: -
|
Vector_Bounds: -
|
||||||
Null_Allowed: no
|
Null_Allowed: yes
|
||||||
|
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
@ -58,9 +58,9 @@ Description: "input loading capacitance (F)"
|
||||||
Data_Type: real
|
Data_Type: real
|
||||||
Default_Value: 1.0e-12
|
Default_Value: 1.0e-12
|
||||||
Limits: -
|
Limits: -
|
||||||
Vector: no
|
Vector: no
|
||||||
Vector_Bounds: -
|
Vector_Bounds: -
|
||||||
Null_Allowed: no
|
Null_Allowed: yes
|
||||||
|
|
||||||
|
|
||||||
STATIC_VAR_TABLE:
|
STATIC_VAR_TABLE:
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,8 @@ Description: "input" "clock"
|
||||||
Direction: in in
|
Direction: in in
|
||||||
Default_Type: d d
|
Default_Type: d d
|
||||||
Allowed_Types: [d] [d]
|
Allowed_Types: [d] [d]
|
||||||
Vector: yes no
|
Vector: yes no
|
||||||
Vector_Bounds: - -
|
Vector_Bounds: - -
|
||||||
Null_Allowed: yes no
|
Null_Allowed: yes no
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -48,8 +48,8 @@ Description: "reset" "output"
|
||||||
Direction: in out
|
Direction: in out
|
||||||
Default_Type: d d
|
Default_Type: d d
|
||||||
Allowed_Types: [d] [d]
|
Allowed_Types: [d] [d]
|
||||||
Vector: no yes
|
Vector: no yes
|
||||||
Vector_Bounds: - [1 -]
|
Vector_Bounds: - [1 -]
|
||||||
Null_Allowed: yes no
|
Null_Allowed: yes no
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -62,8 +62,8 @@ Description: "delay from CLK" "delay from reset"
|
||||||
Data_Type: real real
|
Data_Type: real real
|
||||||
Default_Value: 1.0e-9 1.0e-9
|
Default_Value: 1.0e-9 1.0e-9
|
||||||
Limits: - -
|
Limits: - -
|
||||||
Vector: no no
|
Vector: no no
|
||||||
Vector_Bounds: - -
|
Vector_Bounds: - -
|
||||||
Null_Allowed: yes yes
|
Null_Allowed: yes yes
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -75,9 +75,9 @@ Description: "state transition specification file name"
|
||||||
Data_Type: string
|
Data_Type: string
|
||||||
Default_Value: "state.txt"
|
Default_Value: "state.txt"
|
||||||
Limits: -
|
Limits: -
|
||||||
Vector: no
|
Vector: no
|
||||||
Vector_Bounds: -
|
Vector_Bounds: -
|
||||||
Null_Allowed: no
|
Null_Allowed: yes
|
||||||
|
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
@ -88,9 +88,9 @@ Description: "default state on RESET & at DC"
|
||||||
Data_Type: int
|
Data_Type: int
|
||||||
Default_Value: 0
|
Default_Value: 0
|
||||||
Limits: -
|
Limits: -
|
||||||
Vector: no
|
Vector: no
|
||||||
Vector_Bounds: -
|
Vector_Bounds: -
|
||||||
Null_Allowed: no
|
Null_Allowed: yes
|
||||||
|
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
@ -101,9 +101,9 @@ Description: "input loading capacitance (F)"
|
||||||
Data_Type: real
|
Data_Type: real
|
||||||
Default_Value: 1.0e-12
|
Default_Value: 1.0e-12
|
||||||
Limits: -
|
Limits: -
|
||||||
Vector: no
|
Vector: no
|
||||||
Vector_Bounds: -
|
Vector_Bounds: -
|
||||||
Null_Allowed: no
|
Null_Allowed: yes
|
||||||
|
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
@ -114,9 +114,11 @@ Description: "clock loading capacitance (F)"
|
||||||
Data_Type: real
|
Data_Type: real
|
||||||
Default_Value: 1.0e-12
|
Default_Value: 1.0e-12
|
||||||
Limits: -
|
Limits: -
|
||||||
Vector: no
|
Vector: no
|
||||||
Vector_Bounds: -
|
Vector_Bounds: -
|
||||||
Null_Allowed: no
|
Null_Allowed: yes
|
||||||
|
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -125,9 +127,9 @@ Description: "reset loading capacitance (F)"
|
||||||
Data_Type: real
|
Data_Type: real
|
||||||
Default_Value: 1.0e-12
|
Default_Value: 1.0e-12
|
||||||
Limits: -
|
Limits: -
|
||||||
Vector: no
|
Vector: no
|
||||||
Vector_Bounds: -
|
Vector_Bounds: -
|
||||||
Null_Allowed: no
|
Null_Allowed: yes
|
||||||
|
|
||||||
STATIC_VAR_TABLE:
|
STATIC_VAR_TABLE:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "ngspice/config.h"
|
||||||
#include "ngspice/cpextern.h"
|
#include "ngspice/cpextern.h"
|
||||||
#include "ngspice/devdefs.h"
|
#include "ngspice/devdefs.h"
|
||||||
#include "ngspice/dstring.h"
|
#include "ngspice/dstring.h"
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ FILE table3D/cfunc.mod
|
||||||
The ngspice team
|
The ngspice team
|
||||||
All Rights Reserved
|
All Rights Reserved
|
||||||
GPL
|
GPL
|
||||||
(see COPYING or https://opensource.org/licenses/BSD-3-Clause)
|
(see COPYING or https://opensource.org/licenses/GPL-2.0)
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,8 @@ Description: "capacitor terminals"
|
||||||
Direction: inout
|
Direction: inout
|
||||||
Default_Type: hd
|
Default_Type: hd
|
||||||
Allowed_Types: [hd]
|
Allowed_Types: [hd]
|
||||||
Vector: no
|
Vector: no
|
||||||
Vector_Bounds: -
|
Vector_Bounds: -
|
||||||
Null_Allowed: no
|
Null_Allowed: no
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -63,9 +63,6 @@ Description: "capacitance" "voltage initial condition"
|
||||||
Data_Type: real real
|
Data_Type: real real
|
||||||
Default_Value: - 0.0
|
Default_Value: - 0.0
|
||||||
Limits: - -
|
Limits: - -
|
||||||
Vector: no no
|
Vector: no no
|
||||||
Vector_Bounds: - -
|
Vector_Bounds: - -
|
||||||
Null_Allowed: no no
|
Null_Allowed: no yes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -51,8 +51,8 @@ Description: "inductor terminals"
|
||||||
Direction: inout
|
Direction: inout
|
||||||
Default_Type: gd
|
Default_Type: gd
|
||||||
Allowed_Types: [gd]
|
Allowed_Types: [gd]
|
||||||
Vector: no
|
Vector: no
|
||||||
Vector_Bounds: -
|
Vector_Bounds: -
|
||||||
Null_Allowed: no
|
Null_Allowed: no
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -63,8 +63,8 @@ Description: "inductance" "current initial condition"
|
||||||
Data_Type: real real
|
Data_Type: real real
|
||||||
Default_Value: - 0.0
|
Default_Value: - 0.0
|
||||||
Limits: - -
|
Limits: - -
|
||||||
Vector: no no
|
Vector: no no
|
||||||
Vector_Bounds: - -
|
Vector_Bounds: - -
|
||||||
Null_Allowed: no no
|
Null_Allowed: no yes
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,8 +59,8 @@ Description: "memristor terminals"
|
||||||
Direction: inout
|
Direction: inout
|
||||||
Default_Type: gd
|
Default_Type: gd
|
||||||
Allowed_Types: [gd]
|
Allowed_Types: [gd]
|
||||||
Vector: no
|
Vector: no
|
||||||
Vector_Bounds: -
|
Vector_Bounds: -
|
||||||
Null_Allowed: no
|
Null_Allowed: no
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -71,9 +71,9 @@ Description: "minimum resistance" "maximum resistance" "initial
|
||||||
Data_Type: real real real
|
Data_Type: real real real
|
||||||
Default_Value: 10.0 10000.0 7000.0
|
Default_Value: 10.0 10000.0 7000.0
|
||||||
Limits: - - -
|
Limits: - - -
|
||||||
Vector: no no no
|
Vector: no no no
|
||||||
Vector_Bounds: - - -
|
Vector_Bounds: - - -
|
||||||
Null_Allowed: no no no
|
Null_Allowed: yes yes yes
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
||||||
|
|
@ -84,6 +84,6 @@ Default_Value: 0.0 1.0 0.0
|
||||||
Limits: - - -
|
Limits: - - -
|
||||||
Vector: no no no
|
Vector: no no no
|
||||||
Vector_Bounds: - - -
|
Vector_Bounds: - - -
|
||||||
Null_Allowed: no no no
|
Null_Allowed: yes yes yes
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -177,8 +177,8 @@ void cm_pswitch(ARGS) /* structure holding parms,
|
||||||
r_off = (r_off > 1.0e12) ? 1.0e12 : r_off; /* Set maximum 'OFF' resistance */
|
r_off = (r_off > 1.0e12) ? 1.0e12 : r_off; /* Set maximum 'OFF' resistance */
|
||||||
|
|
||||||
|
|
||||||
if(INIT == 1) { /* first time through, allocate memory, set static parameters */
|
if(INIT == 1) {
|
||||||
char *cntl_error = "\n*****ERROR*****\nPSWITCH: CONTROL voltage delta less than 1.0e-12\n";
|
/* First time through, allocate memory, set static parameters. */
|
||||||
|
|
||||||
cntl_on = PARAM(cntl_on);
|
cntl_on = PARAM(cntl_on);
|
||||||
cntl_off = PARAM(cntl_off);
|
cntl_off = PARAM(cntl_off);
|
||||||
|
|
|
||||||
|
|
@ -36,8 +36,8 @@ Description: "diode port"
|
||||||
Direction: inout
|
Direction: inout
|
||||||
Default_Type: gd
|
Default_Type: gd
|
||||||
Allowed_Types: [gd]
|
Allowed_Types: [gd]
|
||||||
Vector: no
|
Vector: no
|
||||||
Vector_Bounds: -
|
Vector_Bounds: -
|
||||||
Null_Allowed: no
|
Null_Allowed: no
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -49,9 +49,9 @@ Description: "resistance on-state" "resistance off-state"
|
||||||
Data_Type: real real
|
Data_Type: real real
|
||||||
Default_Value: 1 1
|
Default_Value: 1 1
|
||||||
Limits: [1e-6 - ] [1e-12 -]
|
Limits: [1e-6 - ] [1e-12 -]
|
||||||
Vector: no no
|
Vector: no no
|
||||||
Vector_Bounds: - -
|
Vector_Bounds: - -
|
||||||
Null_Allowed: no no
|
Null_Allowed: yes yes
|
||||||
|
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
@ -61,7 +61,7 @@ Description: "forward voltage" "reverse breakdown voltage"
|
||||||
Data_Type: real real
|
Data_Type: real real
|
||||||
Default_Value: 0. 1e30
|
Default_Value: 0. 1e30
|
||||||
Limits: [0. -] [0. -]
|
Limits: [0. -] [0. -]
|
||||||
Vector: no no
|
Vector: no no
|
||||||
Vector_Bounds: - -
|
Vector_Bounds: - -
|
||||||
Null_Allowed: yes yes
|
Null_Allowed: yes yes
|
||||||
|
|
||||||
|
|
@ -74,8 +74,8 @@ Description: "limit of on-current" "limit of breakdown current"
|
||||||
Data_Type: real real
|
Data_Type: real real
|
||||||
Default_Value: 1e30 1e30
|
Default_Value: 1e30 1e30
|
||||||
Limits: [1e-15 -] [1e-15 -]
|
Limits: [1e-15 -] [1e-15 -]
|
||||||
Vector: no no
|
Vector: no no
|
||||||
Vector_Bounds: - -
|
Vector_Bounds: - -
|
||||||
Null_Allowed: yes yes
|
Null_Allowed: yes yes
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -86,8 +86,8 @@ Description: "width quadrat. r 1" "width quadratic region 2"
|
||||||
Data_Type: real real
|
Data_Type: real real
|
||||||
Default_Value: 0. 0.
|
Default_Value: 0. 0.
|
||||||
Limits: [0. -] [0. -]
|
Limits: [0. -] [0. -]
|
||||||
Vector: no no
|
Vector: no no
|
||||||
Vector_Bounds: - -
|
Vector_Bounds: - -
|
||||||
Null_Allowed: yes yes
|
Null_Allowed: yes yes
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -99,8 +99,8 @@ Description: "resistance in breakdown"
|
||||||
Data_Type: real
|
Data_Type: real
|
||||||
Default_Value: 0.
|
Default_Value: 0.
|
||||||
Limits: -
|
Limits: -
|
||||||
Vector: no
|
Vector: no
|
||||||
Vector_Bounds: -
|
Vector_Bounds: -
|
||||||
Null_Allowed: yes
|
Null_Allowed: yes
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -567,28 +567,33 @@ MIF_INP2A (
|
||||||
|
|
||||||
param_info = &(DEVices[type]->DEVpublic.param[i]);
|
param_info = &(DEVices[type]->DEVpublic.param[i]);
|
||||||
|
|
||||||
if(mdfast->param[i]->is_null) {
|
if (mdfast->param[i]->is_null) {
|
||||||
char* emessage;
|
char* emessage = NULL;
|
||||||
|
|
||||||
if(! param_info->has_default) {
|
if (!param_info->null_allowed) {
|
||||||
|
emessage = tprintf("Null not allowed for parameter %s "
|
||||||
|
"on model %s.",
|
||||||
|
param_info->name, mdfast->gen.GENmodName);
|
||||||
|
} else if (param_info->default_value_siz == 0) {
|
||||||
if (param_info->type == MIF_STRING)
|
if (param_info->type == MIF_STRING)
|
||||||
continue; // Allow NULL
|
continue; // Allow NULL
|
||||||
emessage = tprintf("Parameter %s on model %s has no default",
|
emessage = tprintf("Parameter %s on model %s has no default",
|
||||||
param_info->name, mdfast->gen.GENmodName);
|
param_info->name, mdfast->gen.GENmodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (emessage) {
|
||||||
LITERR(emessage);
|
LITERR(emessage);
|
||||||
tfree(emessage);
|
tfree(emessage);
|
||||||
gc_end();
|
gc_end();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
} else if (param_info->is_array && param_info->has_conn_ref &&
|
||||||
if((! mdfast->param[i]->is_null) && (param_info->is_array)) {
|
fast[0]->conn[param_info->conn_ref]->size !=
|
||||||
if(param_info->has_conn_ref) {
|
fast[0]->param[i]->size) {
|
||||||
if(fast[0]->conn[param_info->conn_ref]->size != fast[0]->param[i]->size) {
|
LITERR("Array parameter size on model does not match "
|
||||||
LITERR("Array parameter size on model does not match connection size");
|
"connection size");
|
||||||
gc_end();
|
gc_end();
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gc_end();
|
gc_end();
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,6 @@ MIFsetup(
|
||||||
|
|
||||||
for( ; model != NULL; model = MIFnextModel(model)) {
|
for( ; model != NULL; model = MIFnextModel(model)) {
|
||||||
|
|
||||||
|
|
||||||
/* For each parameter not given explicitly on the .model */
|
/* For each parameter not given explicitly on the .model */
|
||||||
/* card, default it */
|
/* card, default it */
|
||||||
|
|
||||||
|
|
@ -151,42 +150,66 @@ MIFsetup(
|
||||||
model->param[i]->size = 1;
|
model->param[i]->size = 1;
|
||||||
model->param[i]->element = TMALLOC(Mif_Value_t, 1);
|
model->param[i]->element = TMALLOC(Mif_Value_t, 1);
|
||||||
} else { /* parameter is an array */
|
} else { /* parameter is an array */
|
||||||
/* MIF_INP2A() parser assures that there is an associated array connection */
|
/* If there is an associated array connection, take the
|
||||||
/* Since several instances may share this model, we have to create an array */
|
* size from there. Since several instances may share
|
||||||
/* big enough for the instance with the biggest connection array */
|
* this model, create an array big enough for the
|
||||||
max_size = 0;
|
* instance with the biggest connection array.
|
||||||
for(here = MIFinstances(model); here != NULL; here = MIFnextInstance(here)) {
|
* Otherwise, use the size of the default.
|
||||||
size = here->conn[param_info->conn_ref]->size;
|
*/
|
||||||
if(size > max_size)
|
|
||||||
max_size = size;
|
if (param_info->has_conn_ref) {
|
||||||
|
for (here = MIFinstances(model), max_size = 0;
|
||||||
|
here != NULL;
|
||||||
|
here = MIFnextInstance(here)) {
|
||||||
|
size = here->conn[param_info->conn_ref]->size;
|
||||||
|
if (size > max_size)
|
||||||
|
max_size = size;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
max_size = param_info->default_value_siz;
|
||||||
|
if (param_info->has_lower_bound &&
|
||||||
|
param_info->lower_bound > max_size) {
|
||||||
|
max_size = param_info->lower_bound;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
model->param[i]->size = max_size;
|
model->param[i]->size = max_size;
|
||||||
model->param[i]->element = TMALLOC(Mif_Value_t, max_size);
|
model->param[i]->element = TMALLOC(Mif_Value_t, max_size);
|
||||||
} /* end if parameter is an array */
|
} /* end if parameter is an array */
|
||||||
|
|
||||||
/* set the parameter element(s) to default value */
|
if (param_info->default_value_siz == 0)
|
||||||
for(j = 0; j < model->param[i]->size; j++) {
|
continue;
|
||||||
|
|
||||||
|
/* Set the parameter element(s) to default value(s). */
|
||||||
|
|
||||||
|
for(j = 0; j < model->param[i]->size; j++) {
|
||||||
|
Mif_Parse_Value_t *dvp;
|
||||||
|
|
||||||
|
if (j >= param_info->default_value_siz) {
|
||||||
|
dvp = param_info->default_values +
|
||||||
|
param_info->default_value_siz - 1;
|
||||||
|
} else {
|
||||||
|
dvp = param_info->default_values + j;
|
||||||
|
}
|
||||||
switch(param_info->type) {
|
switch(param_info->type) {
|
||||||
|
|
||||||
case MIF_BOOLEAN:
|
case MIF_BOOLEAN:
|
||||||
model->param[i]->element[j].bvalue = param_info->default_value.bvalue;
|
model->param[i]->element[j].bvalue = dvp->bvalue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MIF_INTEGER:
|
case MIF_INTEGER:
|
||||||
model->param[i]->element[j].ivalue = param_info->default_value.ivalue;
|
model->param[i]->element[j].ivalue = dvp->ivalue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MIF_REAL:
|
case MIF_REAL:
|
||||||
model->param[i]->element[j].rvalue = param_info->default_value.rvalue;
|
model->param[i]->element[j].rvalue = dvp->rvalue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MIF_COMPLEX:
|
case MIF_COMPLEX:
|
||||||
model->param[i]->element[j].cvalue = param_info->default_value.cvalue;
|
model->param[i]->element[j].cvalue = dvp->cvalue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MIF_STRING:
|
case MIF_STRING:
|
||||||
model->param[i]->element[j].svalue = param_info->default_value.svalue;
|
model->param[i]->element[j].svalue = dvp->svalue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@ set filetype=ascii
|
||||||
*set askquit
|
*set askquit
|
||||||
** set the number of threads in openmp
|
** set the number of threads in openmp
|
||||||
** default (if compiled with --enable-openmp) is: 2
|
** default (if compiled with --enable-openmp) is: 2
|
||||||
set num_threads=4
|
set num_threads=8
|
||||||
set interactive
|
*set interactive
|
||||||
|
|
||||||
* comment out if central osdi management is set up
|
* comment out if central osdi management is set up
|
||||||
unset osdi_enabled
|
unset osdi_enabled
|
||||||
|
|
@ -38,7 +38,7 @@ if $?osdi_enabled
|
||||||
osdi ../lib/ngspice/BSIMBULK107.osdi
|
osdi ../lib/ngspice/BSIMBULK107.osdi
|
||||||
osdi ../lib/ngspice/BSIMCMG.osdi
|
osdi ../lib/ngspice/BSIMCMG.osdi
|
||||||
osdi ../lib/ngspice/HICUMl0-2.0.osdi
|
osdi ../lib/ngspice/HICUMl0-2.0.osdi
|
||||||
osdi ../lib/ngspice/psp103.osdi
|
osdi ../lib/ngspice/psp103_nqs.osdi
|
||||||
osdi ../lib/ngspice/r2_cmc.osdi
|
osdi ../lib/ngspice/r2_cmc.osdi
|
||||||
osdi ../lib/ngspice/vbic_4T_et_cf.osdi
|
osdi ../lib/ngspice/vbic_4T_et_cf.osdi
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ if $?osdi_enabled
|
||||||
osdi C:/Spiced/lib/ngspice/BSIMBULK107.osdi
|
osdi C:/Spiced/lib/ngspice/BSIMBULK107.osdi
|
||||||
osdi C:/Spiced/lib/ngspice/BSIMCMG.osdi
|
osdi C:/Spiced/lib/ngspice/BSIMCMG.osdi
|
||||||
osdi C:/Spiced/lib/ngspice/HICUMl0-2.0.osdi
|
osdi C:/Spiced/lib/ngspice/HICUMl0-2.0.osdi
|
||||||
osdi C:/Spiced/lib/ngspice/psp103.osdi
|
osdi C:/Spiced/lib/ngspice/psp103_nqs.osdi
|
||||||
osdi C:/Spiced/lib/ngspice/r2_cmc.osdi
|
osdi C:/Spiced/lib/ngspice/r2_cmc.osdi
|
||||||
osdi C:/Spiced/lib/ngspice/vbic_4T_et_cf.osdi
|
osdi C:/Spiced/lib/ngspice/vbic_4T_et_cf.osdi
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@ set filetype=ascii
|
||||||
*set askquit
|
*set askquit
|
||||||
** set the number of threads in openmp
|
** set the number of threads in openmp
|
||||||
** default (if compiled with --enable-openmp) is: 2
|
** default (if compiled with --enable-openmp) is: 2
|
||||||
set num_threads=4
|
set num_threads=8
|
||||||
set interactive
|
*set interactive
|
||||||
|
|
||||||
* comment out if central osdi management is set up
|
* comment out if central osdi management is set up
|
||||||
unset osdi_enabled
|
unset osdi_enabled
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ if $?osdi_enabled
|
||||||
osdi C:/Spice/lib/ngspice/BSIMBULK107.osdi
|
osdi C:/Spice/lib/ngspice/BSIMBULK107.osdi
|
||||||
osdi C:/Spice/lib/ngspice/BSIMCMG.osdi
|
osdi C:/Spice/lib/ngspice/BSIMCMG.osdi
|
||||||
osdi C:/Spice/lib/ngspice/HICUMl0-2.0.osdi
|
osdi C:/Spice/lib/ngspice/HICUMl0-2.0.osdi
|
||||||
osdi C:/Spice/lib/ngspice/psp103.osdi
|
osdi C:/Spice/lib/ngspice/psp103_nqs.osdi
|
||||||
osdi C:/Spice/lib/ngspice/r2_cmc.osdi
|
osdi C:/Spice/lib/ngspice/r2_cmc.osdi
|
||||||
osdi C:/Spice/lib/ngspice/vbic_4T_et_cf.osdi
|
osdi C:/Spice/lib/ngspice/vbic_4T_et_cf.osdi
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ if $?osdi_enabled
|
||||||
osdi C:/Spice64/lib/ngspice/BSIMBULK107.osdi
|
osdi C:/Spice64/lib/ngspice/BSIMBULK107.osdi
|
||||||
osdi C:/Spice64/lib/ngspice/BSIMCMG.osdi
|
osdi C:/Spice64/lib/ngspice/BSIMCMG.osdi
|
||||||
osdi C:/Spice64/lib/ngspice/HICUMl0-2.0.osdi
|
osdi C:/Spice64/lib/ngspice/HICUMl0-2.0.osdi
|
||||||
osdi C:/Spice64/lib/ngspice/psp103.osdi
|
osdi C:/Spice64/lib/ngspice/psp103_nqs.osdi
|
||||||
osdi C:/Spice64/lib/ngspice/r2_cmc.osdi
|
osdi C:/Spice64/lib/ngspice/r2_cmc.osdi
|
||||||
osdi C:/Spice64/lib/ngspice/vbic_4T_et_cf.osdi
|
osdi C:/Spice64/lib/ngspice/vbic_4T_et_cf.osdi
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue