From 5517c8b3f0eb34203e67f832ef76880b0970f833 Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Sun, 2 Feb 2025 00:33:55 +0100 Subject: [PATCH] has_included_subcircuit(): fix spice netlisting error when using a symbol with bussed ports and implementation specified via a spice_sym_def attribute. bussed ports must be expanded and resulting total number of bits of symbol (grater than number of I/O pins!!) must be calculated and sent to the tcl has_included_subcircuit proc. --- src/token.c | 77 ++++++++++++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/src/token.c b/src/token.c index f092bb74..e8e3d855 100644 --- a/src/token.c +++ b/src/token.c @@ -1859,6 +1859,11 @@ static int has_included_subcircuit(int inst, int symbol, char **result) char *templ = NULL; char *symname_attr = NULL; int no_of_pins = (xctx->inst[inst].ptr + xctx->sym)->rects[PINLAYER]; + int i; + int exp_no_of_pins = 0; /* number of single bit ports, ie all buses expanded */ + char *net, *net_save; + Str_hashentry *entry; + Str_hashtable table = {NULL, 0}; my_strdup2(_ALLOC_ID_, &templ, get_tok_value(xctx->sym[symbol].prop_ptr, "template", 0)); my_strdup2(_ALLOC_ID_, &symname, get_tok_value(xctx->inst[inst].prop_ptr, "schematic", 0)); @@ -1875,55 +1880,55 @@ static int has_included_subcircuit(int inst, int symbol, char **result) symname_attr); dbg(1, "has_included_subcircuit(): translated_sym_def=%s\n", translated_sym_def); dbg(1, "has_included_subcircuit(): symname=%s\n", symname); + + /* pin list from symbol. Calculate also exp_no_of_pins */ + str_hash_init(&table, 6247); + for(i = 0;i < no_of_pins; ++i) { + char *prop = (xctx->inst[inst].ptr + xctx->sym)->rect[PINLAYER][i].prop_ptr; + int spice_ignore = !strboolcmp(get_tok_value(prop, "spice_ignore", 0), "true"); + const char *name = get_tok_value(prop, "name", 0); + if(!spice_ignore) { + char *pin, *pin_save; + int pin_mult, net_mult; + char *pin_expanded_ptr, *pin_expanded = NULL; + char *net_expanded_ptr, *net_expanded = NULL; + my_strdup2(_ALLOC_ID_, &pin_expanded, expandlabel(name, &pin_mult)); + exp_no_of_pins += pin_mult; + strtolower(pin_expanded); + my_strdup2(_ALLOC_ID_, &net_expanded, net_name(inst, i, &net_mult, 0, 1)); + net_expanded_ptr = net_expanded; + pin_expanded_ptr = pin_expanded; + while((pin = my_strtok_r(pin_expanded_ptr, ",", "", 0, &pin_save))) { + net = my_strtok_r(net_expanded_ptr, ",", "", 0, &net_save); + str_hash_lookup(&table, pin, net ? net : "", XINSERT_NOREPLACE); + dbg(1, "inserting pin: %s, net: %s\n", pin, net ? net : ""); + pin_expanded_ptr = NULL; + net_expanded_ptr = NULL; + } + my_free(_ALLOC_ID_, &pin_expanded); + my_free(_ALLOC_ID_, &net_expanded); + } + } + dbg(1, "exp_no_of_pins=%d\n", exp_no_of_pins); + /* process spice_sym_def spice netlist */ strtolower(symname); tclvareval("has_included_subcircuit {", get_cell(symname, 0), "} {", - translated_sym_def, "} ", my_itoa(no_of_pins), NULL); + translated_sym_def, "} ", my_itoa(exp_no_of_pins), NULL); + my_free(_ALLOC_ID_, &templ); my_free(_ALLOC_ID_, &symname_attr); - if(tclresult()[0]) { + if(tclresult()[0]) { /* a valid spice_sym_def netlist was found */ char *subckt_pin, *pin_save; - char *net, *net_save; char *subckt_pinlist_ptr; char *subckt_pinlist = NULL; char *tmp_result = NULL; - int i; int symbol_pins = 0; int instance_pins = 0; - Str_hashentry *entry; - Str_hashtable table = {NULL, 0}; - str_hash_init(&table, 6247); my_strdup2(_ALLOC_ID_, &subckt_pinlist, tclresult()); dbg(1, "included subcircuit: pinlist=%s\n", subckt_pinlist); - /* pin list from symbol */ - for(i = 0;i < no_of_pins; ++i) { - char *prop = (xctx->inst[inst].ptr + xctx->sym)->rect[PINLAYER][i].prop_ptr; - int spice_ignore = !strboolcmp(get_tok_value(prop, "spice_ignore", 0), "true"); - const char *name = get_tok_value(prop, "name", 0); - if(!spice_ignore) { - char *pin, *pin_save; - int pin_mult, net_mult; - char *pin_expanded_ptr, *pin_expanded = NULL; - char *net_expanded_ptr, *net_expanded = NULL; - my_strdup2(_ALLOC_ID_, &pin_expanded, expandlabel(name, &pin_mult)); - strtolower(pin_expanded); - my_strdup2(_ALLOC_ID_, &net_expanded, net_name(inst, i, &net_mult, 0, 1)); - net_expanded_ptr = net_expanded; - pin_expanded_ptr = pin_expanded; - while((pin = my_strtok_r(pin_expanded_ptr, ",", "", 0, &pin_save))) { - net = my_strtok_r(net_expanded_ptr, ",", "", 0, &net_save); - str_hash_lookup(&table, pin, net ? net : "", XINSERT_NOREPLACE); - dbg(1, "inserting pin: %s, net: %s\n", pin, net ? net : ""); - pin_expanded_ptr = NULL; - net_expanded_ptr = NULL; - } - my_free(_ALLOC_ID_, &pin_expanded); - my_free(_ALLOC_ID_, &net_expanded); - } - } - /* list from subcircuit netlist */ subckt_pinlist_ptr = subckt_pinlist; while( (subckt_pin = my_strtok_r(subckt_pinlist_ptr, " ", "", 0, &pin_save)) ) { @@ -1934,11 +1939,10 @@ static int has_included_subcircuit(int inst, int symbol, char **result) net = entry->value; symbol_pins++; dbg(1, "subckt_pin=%s, net=%s\n", subckt_pin, net); - my_mstrcat(_ALLOC_ID_, &tmp_result, "?1", " ", net, " ", NULL); + my_mstrcat(_ALLOC_ID_, &tmp_result, "?1 ", net, " ", NULL); } subckt_pinlist_ptr = NULL; } - str_hash_free(&table); /* check if they match */ if(instance_pins == symbol_pins) { @@ -1955,6 +1959,7 @@ static int has_included_subcircuit(int inst, int symbol, char **result) my_free(_ALLOC_ID_, &subckt_pinlist); } my_free(_ALLOC_ID_, &symname); + str_hash_free(&table); } my_free(_ALLOC_ID_, &spice_sym_def); return ret;