From a088a6e0e659d82b16ba3b1df36ca7e1937deda0 Mon Sep 17 00:00:00 2001 From: rlar Date: Sun, 22 Dec 2013 15:17:41 +0100 Subject: [PATCH] subckt.c, fix .model processing (scope) --- configure.ac | 1 + src/frontend/subckt.c | 27 ++++-- tests/regression/Makefile.am | 2 +- .../regression/subckt-processing/Makefile.am | 12 +++ .../subckt-processing/model-scope-5.cir | 84 +++++++++++++++++++ .../subckt-processing/model-scope-5.out | 9 ++ 6 files changed, 127 insertions(+), 8 deletions(-) create mode 100644 tests/regression/subckt-processing/Makefile.am create mode 100644 tests/regression/subckt-processing/model-scope-5.cir create mode 100644 tests/regression/subckt-processing/model-scope-5.out diff --git a/configure.ac b/configure.ac index f33f9b3d0..2dce77097 100644 --- a/configure.ac +++ b/configure.ac @@ -1191,6 +1191,7 @@ AC_CONFIG_FILES([Makefile tests/mos6/Makefile tests/polezero/Makefile tests/regression/Makefile + tests/regression/subckt-processing/Makefile tests/regression/lib-processing/Makefile tests/regression/parser/Makefile tests/sensitivity/Makefile diff --git a/src/frontend/subckt.c b/src/frontend/subckt.c index ea2c7076a..86b47280d 100644 --- a/src/frontend/subckt.c +++ b/src/frontend/subckt.c @@ -212,12 +212,24 @@ inp_subcktexpand(struct line *deck) { /* Get all the model names so we can deal with BJTs, etc. * Stick all the model names into the doubly-linked wordlist modnames. */ - for (c = deck; c; c = c->li_next) - if (ciprefix(model, c->li_line)) { - s = c->li_line; - txfree(gettok(&s)); /* discard the model keyword */ - modnames = wl_cons(gettok(&s), modnames); - } /* model name finding routine */ + { + int nest = 0; + for (c = deck; c; c = c->li_next) { + + if (ciprefix(".subckt", c->li_line)) + nest++; + else if (ciprefix(".ends", c->li_line)) + nest--; + else if (nest > 0) + continue; + + if (ciprefix(model, c->li_line)) { + s = c->li_line; + txfree(gettok(&s)); /* discard the model keyword */ + modnames = wl_cons(gettok(&s), modnames); + } /* model name finding routine */ + } + } #ifdef TRACE { @@ -595,8 +607,10 @@ doit(struct line *deck, wordlist *modnames) { lcc = inp_deckcopy(sss->su_def); /* Change the names of .models found in .subckts . . . */ + submod = NULL; if (modtranslate(lcc, scname, &submod, &modnames)) /* this translates the model name in the .model line */ devmodtranslate(lcc, scname, submod); /* This translates the model name on all components in the deck */ + wl_free(submod); { char *s = sss->su_args; @@ -664,7 +678,6 @@ doit(struct line *deck, wordlist *modnames) { #endif wl_delete_slice(modnames, xmodnames); - wl_free(submod); if (error) return NULL; /* error message already reported; should free() */ diff --git a/tests/regression/Makefile.am b/tests/regression/Makefile.am index ac64b0e00..9fd1a3d71 100644 --- a/tests/regression/Makefile.am +++ b/tests/regression/Makefile.am @@ -1,5 +1,5 @@ ## Process this file with automake to produce Makefile.in -SUBDIRS = lib-processing parser +SUBDIRS = lib-processing parser subckt-processing MAINTAINERCLEANFILES = Makefile.in diff --git a/tests/regression/subckt-processing/Makefile.am b/tests/regression/subckt-processing/Makefile.am new file mode 100644 index 000000000..4bef8024e --- /dev/null +++ b/tests/regression/subckt-processing/Makefile.am @@ -0,0 +1,12 @@ +## Process this file with automake to produce Makefile.in + + +TESTS = model-scope-5.cir + +TESTS_ENVIRONMENT = ngspice_vpath=$(srcdir) $(SHELL) $(top_srcdir)/tests/bin/check.sh $(top_builddir)/src/ngspice + +EXTRA_DIST = \ + $(TESTS) \ + $(TESTS:.cir=.out) + +MAINTAINERCLEANFILES = Makefile.in diff --git a/tests/regression/subckt-processing/model-scope-5.cir b/tests/regression/subckt-processing/model-scope-5.cir new file mode 100644 index 000000000..1baf1081b --- /dev/null +++ b/tests/regression/subckt-processing/model-scope-5.cir @@ -0,0 +1,84 @@ +check scoping of nested .model definitions + +* (exec-spice "ngspice -b %s") +* (tests-aux-renumber) + + +i1 n1001_t 0 dc=-1 +i2 n1002_t 0 dc=-1 +i3 n1003_t 0 dc=-1 +i4 n1004_t 0 dc=-1 +i5 n1005_t 0 dc=-1 +i6 n1006_t 0 dc=-1 +i7 n1007_t 0 dc=-1 + +x1 n1001_t sub1 +v1_g n1001_g 0 2k + +x2 n1002_t n1003_t n1004_t n1005_t n1006_t n1007_t sub2 +v2_g n1002_g 0 4k +v3_g n1003_g 0 1k +v4_g n1004_g 0 8k +v5_g n1005_g 0 1k +v6_g n1006_g 0 8k +v7_g n1007_g 0 43 + +.subckt sub1 2 + .model my r r=2k + r1 2 0 my +.ends + +.subckt sub2 3 41a 41b 42a 42b 5 + r2 3 0 my + + x31 41a 41b sub3 + x32 42a 42b sub3 + + .subckt sub3 4 5 + .model my r r=8k + .model any r r=42 + r5 4 0 1k + r6 5 0 my + .ends + + .model just r r=43 + r5 5 0 just +.ends + +.model my r r=4k + + +.control + +define mismatch(a,b,err) abs(a-b)>err + +op + +let total_count = 0 +let fail_count = 0 + +let tests = 1001 + vector(7) + +foreach n $&tests + set n_test = "n{$n}_t" + set n_gold = "n{$n}_g" + if mismatch(v($n_test), v($n_gold), 1e-9) + let v_test = v($n_test) + let v_gold = v($n_gold) + echo "ERROR, test failure, v($n_test) = $&v_test but should be $&v_gold" + let fail_count = fail_count + 1 + end + let total_count = total_count + 1 +end + +if fail_count > 0 + echo "ERROR: $&fail_count of $&total_count tests failed" + quit 1 +else + echo "INFO: $&fail_count of $&total_count tests failed" + quit 0 +end + +.endc + +.end diff --git a/tests/regression/subckt-processing/model-scope-5.out b/tests/regression/subckt-processing/model-scope-5.out new file mode 100644 index 000000000..feba998ad --- /dev/null +++ b/tests/regression/subckt-processing/model-scope-5.out @@ -0,0 +1,9 @@ + +Circuit: check scoping of nested .model definitions + +Doing analysis at TEMP = 27.000000 and TNOM = 27.000000 + + +No. of Data Rows : 1 +INFO: 0 of 7 tests failed +ngspice-25 done