From 8ec3e52122fe136f732c6c200c310db83521fd91 Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Sat, 3 Feb 2024 13:43:18 +0100 Subject: [PATCH] allow parametric models in subcircuits. Symbol inv.sym contains template="... modp=cmos_p_10 ...", pmos instance in inv.sch contains model=@modp, instance format string contains format="@name @pinlist @model w=@w l=@l, result is: "m2 y a VCCPIN VCCPIN cmos_p_10 w=wp l=lp" --- src/actions.c | 2 ++ src/spice_netlist.c | 12 ++++++++++++ src/token.c | 22 +++++++++++++++++++++- 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/actions.c b/src/actions.c index 5bb2e790..b2ab2192 100644 --- a/src/actions.c +++ b/src/actions.c @@ -2218,6 +2218,8 @@ void go_back(int confirm) /* 20171006 add confirm */ xctx->sch_path_hash[xctx->currsch] = 0; xctx->currsch--; + my_free(_ALLOC_ID_, &xctx->hier_attr[xctx->currsch].prop_ptr); + my_free(_ALLOC_ID_, &xctx->hier_attr[xctx->currsch].templ); save_modified = xctx->modified; /* we propagate modified flag (cleared by load_schematic */ /* by default) to parent schematic if going back from embedded symbol */ diff --git a/src/spice_netlist.c b/src/spice_netlist.c index ca17e364..5875783c 100644 --- a/src/spice_netlist.c +++ b/src/spice_netlist.c @@ -434,6 +434,17 @@ int global_spice_netlist(int global) /* netlister driver */ if(xctx->sym[i].flags & (SPICE_IGNORE | SPICE_SHORT)) continue; if(lvs_ignore && (xctx->sym[i].flags & LVS_IGNORE)) continue; if(!xctx->sym[i].type) continue; + /* normally empty, if not raise a warning... */ + if(xctx->hier_attr[xctx->currsch - 1].templ) { + dbg(0, "xctx->hier_attr[xctx->currsch - 1].templ not empty: %s\n", + xctx->hier_attr[xctx->currsch - 1].templ); + } + /* store parent symbol template attr (before descending into it) + * to resolve subschematic instances with model=@modp in format string, + * modp will be first looked up in instance prop_ptr string, and if not found + * in parent symbol template string */ + my_strdup(_ALLOC_ID_, &xctx->hier_attr[xctx->currsch - 1].templ, + get_tok_value(xctx->sym[i].prop_ptr, "template", 0)); my_strdup(_ALLOC_ID_, &abs_path, abs_sym_path(xctx->sym[i].name, "")); if(strcmp(xctx->sym[i].type,"subcircuit")==0 && check_lib(1, abs_path)) { @@ -459,6 +470,7 @@ int global_spice_netlist(int global) /* netlister driver */ err |= spice_block_netlist(fd, i); } } + my_free(_ALLOC_ID_, &xctx->hier_attr[xctx->currsch - 1].templ); } my_free(_ALLOC_ID_, &abs_path); /* get_additional_symbols(0); */ diff --git a/src/token.c b/src/token.c index 1b19742d..26d8214b 100644 --- a/src/token.c +++ b/src/token.c @@ -2148,16 +2148,36 @@ int print_spice_element(FILE *fd, int inst) value=NULL; } else { size_t tok_val_len; + size_t tok_size; dbg(1, "print_spice_element(): token: |%s|\n", token); my_strdup2(_ALLOC_ID_, &val, get_tok_value(xctx->inst[inst].prop_ptr, token+1, 0)); + tok_size = xctx->tok_size; value = val; - if(!strcmp(token + 1, "model") && strchr(value, '@')) value = translate(inst, val); + if(!strcmp(token + 1, "model") && strchr(value, '@')) { + value = translate(inst, val); + /* Symbol format string contains model=@modp, + * instance attributes does not contain a modp=xxx, + * look up modp in **parent** symbol template attribute */ + if(value[0] == '\0') { + value=get_tok_value(xctx->hier_attr[xctx->currsch - 1].templ, val+1, 0); + } + } + else if(val[0] == '@' && !strpbrk(value + 1, "@ ")) { + /* value = translate(inst, val); */ + value = get_tok_value(xctx->inst[inst].prop_ptr, val + 1, 0); + dbg(1, "val=%s, tok=%s, value=%s template=%s\n", + val, token, value, xctx->hier_attr[xctx->currsch - 1].templ); + if(value[0] == '\0') { + value=get_tok_value(xctx->hier_attr[xctx->currsch - 1].templ, val+1, 0); + } + } tok_val_len = strlen(value); if(!strcmp(token, "@spiceprefix")) { my_realloc(_ALLOC_ID_, &spiceprefixtag, tok_val_len+22); my_snprintf(spiceprefixtag, tok_val_len+22, "**** spice_prefix %s\n", value); value = spiceprefixtag; } + xctx->tok_size = tok_size; /* xctx->tok_size==0 indicates that token(+1) does not exist in instance attributes */ if (!xctx->tok_size) value=get_tok_value(template, token+1, 0);