From 1cbbed77bafaf078e71cca64f86f3e914caccbd0 Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Fri, 9 Feb 2024 17:00:56 +0100 Subject: [PATCH] first commit for parametric models in subckts --DO NOT USE-- --- src/actions.c | 44 +++++++++++++++++++++++++++++++++++-------- src/callback.c | 4 ++-- src/in_memory_undo.c | 1 + src/netlist.c | 2 +- src/psprint.c | 2 +- src/save.c | 1 + src/scheduler.c | 6 +++--- src/spice_netlist.c | 20 ++++++++++---------- src/tedax_netlist.c | 2 +- src/token.c | 8 +++++++- src/verilog_netlist.c | 2 +- src/vhdl_netlist.c | 2 +- src/xschem.h | 5 +++-- 13 files changed, 68 insertions(+), 31 deletions(-) diff --git a/src/actions.c b/src/actions.c index 485606b8..bf2ace20 100644 --- a/src/actions.c +++ b/src/actions.c @@ -638,6 +638,7 @@ void remove_symbol(int j) dbg(1,"clearing symbol %d: %s\n", j, xctx->sym[j].name); my_free(_ALLOC_ID_, &xctx->sym[j].prop_ptr); my_free(_ALLOC_ID_, &xctx->sym[j].templ); + my_free(_ALLOC_ID_, &xctx->sym[j].parent_prop_ptr); my_free(_ALLOC_ID_, &xctx->sym[j].type); my_free(_ALLOC_ID_, &xctx->sym[j].name); /* /20150409 */ @@ -1698,7 +1699,7 @@ int schematic_in_new_window(int new_process, int dr, int force) "primitive" ) ) return 0; - get_sch_from_sym(filename, xctx->inst[xctx->sel_array[0].n].ptr+ xctx->sym, xctx->sel_array[0].n); + get_sch_from_sym(filename, xctx->inst[xctx->sel_array[0].n].ptr+ xctx->sym, xctx->sel_array[0].n, 0); if(force || !check_loaded(filename, win_path)) { if(new_process) new_xschem_process(filename, 0); else new_schematic("create", "noalert", filename, dr); @@ -1775,9 +1776,11 @@ void copy_symbol(xSymbol *dest_sym, xSymbol *src_sym) dest_sym->prop_ptr = NULL; dest_sym->type = NULL; dest_sym->templ = NULL; + dest_sym->parent_prop_ptr = NULL; my_strdup2(_ALLOC_ID_, &dest_sym->name, src_sym->name); my_strdup2(_ALLOC_ID_, &dest_sym->type, src_sym->type); my_strdup2(_ALLOC_ID_, &dest_sym->templ, src_sym->templ); + my_strdup(_ALLOC_ID_, &dest_sym->parent_prop_ptr, src_sym->parent_prop_ptr); my_strdup2(_ALLOC_ID_, &dest_sym->prop_ptr, src_sym->prop_ptr); dest_sym->line = my_calloc(_ALLOC_ID_, cadlayers, sizeof(xLine *)); @@ -1917,6 +1920,7 @@ void get_additional_symbols(int what) xctx->sym[j].base_name = symptr->name; my_strdup(_ALLOC_ID_, &xctx->sym[j].name, sym); + my_strdup(_ALLOC_ID_, &xctx->sym[j].parent_prop_ptr, xctx->inst[i].prop_ptr); /* the copied symbol will not inherit the default_schematic attribute otherwise it will also * be skipped */ if(default_schematic) { @@ -1960,13 +1964,17 @@ void get_additional_symbols(int what) xctx->symbols = num_syms; } } - -void get_sch_from_sym(char *filename, xSymbol *sym, int inst) +/* fallback = 1: if schematic attribute is set but file not existing fallback + * to defaut symbol schematic (symname.sym -> symname.sch) */ +void get_sch_from_sym(char *filename, xSymbol *sym, int inst, int fallback) { char *sch = NULL; char *str_tmp = NULL; int web_url = 0; struct stat buf; + int file_exists=0; + int cancel = 0; + int is_gen = 0; /* get sch/sym name from parent schematic downloaded from web */ if(is_from_web(xctx->current_dirname)) { @@ -1982,6 +1990,7 @@ void get_sch_from_sym(char *filename, xSymbol *sym, int inst) get_cell(sym->name, 0), '\\'))); if(is_generator(sch)) { /* generator: return as is */ my_strncpy(filename, sch, PATH_MAX); + is_gen = 1; dbg(1, "get_sch_from_sym(): filename=%s\n", filename); } else { /* not generator */ dbg(1, "get_sch_from_sym(): after tcl_hook2 sch=%s\n", sch); @@ -1989,7 +1998,23 @@ void get_sch_from_sym(char *filename, xSymbol *sym, int inst) if(web_url) my_strncpy(filename, sch, PATH_MAX); else my_strncpy(filename, abs_sym_path(sch, ""), PATH_MAX); } - } else { /* no schematic attribute from instance or symbol */ + } else { + my_strncpy(filename, "", PATH_MAX); + } + + if(!is_gen && filename[0]) file_exists = !stat(filename, &buf); + dbg(1, "get_sch_from_sym(): fallback=%d, file_exists=%d\n", fallback, file_exists); + if(!is_gen && filename[0] && !file_exists && fallback && has_x) { + tclvareval("ask_save {Schematic ", filename, "\ndoes not exist.\nDescend into base schematic?}", NULL); + if(strcmp(tclresult(), "yes") ) fallback = 0; + if(!strcmp(tclresult(), "") ) { + my_strncpy(filename, "", PATH_MAX); + cancel = 1; + } + } + + /* no schematic attr from instance or symbol */ + if(!cancel && (!str_tmp[0] || (!is_gen && filename[0] && !file_exists && fallback))) { const char *symname_tcl = tcl_hook2(sym->name); if(is_generator(symname_tcl)) my_strncpy(filename, symname_tcl, PATH_MAX); else if(tclgetboolvar("search_schematic")) { @@ -2009,7 +2034,7 @@ void get_sch_from_sym(char *filename, xSymbol *sym, int inst) } if(sch) my_free(_ALLOC_ID_, &sch); - if(web_url) { + if(web_url && filename[0]) { char sympath[PATH_MAX]; /* build local cached filename of web_url */ @@ -2028,7 +2053,8 @@ void get_sch_from_sym(char *filename, xSymbol *sym, int inst) dbg(1, "get_sch_from_sym(): sym->name=%s, filename=%s\n", sym->name, filename); } -int descend_schematic(int instnumber) +/* fallback = 1: if schematic=.. attr is set but file not existing descend into symbol base schematic */ +int descend_schematic(int instnumber, int fallback, int alert) { char *str = NULL; char filename[PATH_MAX]; @@ -2059,6 +2085,9 @@ int descend_schematic(int instnumber) if(save_ok==0) return 0; } n = xctx->sel_array[0].n; + get_sch_from_sym(filename, xctx->inst[n].ptr+ xctx->sym, n, fallback); + + if(!filename[0]) return 0; /* no filename returned from get_sch_from_sym() --> abort */ dbg(1, "descend_schematic(): selected:%s\n", xctx->inst[n].name); dbg(1, "descend_schematic(): inst type: %s\n", (xctx->inst[n].ptr+ xctx->sym)->type); if( /* do not descend if not subcircuit */ @@ -2176,11 +2205,10 @@ int descend_schematic(int instnumber) xctx->currsch++; hilight_child_pins(); unselect_all(1); - get_sch_from_sym(filename, xctx->inst[n].ptr+ xctx->sym, n); dbg(1, "descend_schematic(): filename=%s\n", filename); /* we are descending from a parent schematic downloaded from the web */ remove_symbols(); - load_schematic(1, filename, 1, 1); + load_schematic(1, filename, 1, alert); if(xctx->hilight_nets) { prepare_netlist_structs(0); propagate_hilights(1, 0, XINSERT_NOREPLACE); diff --git a/src/callback.c b/src/callback.c index f1e3d30b..18e79820 100644 --- a/src/callback.c +++ b/src/callback.c @@ -1872,7 +1872,7 @@ int rstate; /* (reduced state, without ShiftMask) */ if(key=='e' && rstate == 0) /* descend to schematic */ { if(xctx->semaphore >= 2) break; - descend_schematic(0);break; + descend_schematic(0, 1, 1);break; } if(key=='e' && EQUAL_MODMASK) /* edit schematic in new window */ { @@ -2846,7 +2846,7 @@ int rstate; /* (reduced state, without ShiftMask) */ edit_property(1); break; case 12: - descend_schematic(0); + descend_schematic(0, 1, 1); break; case 13: descend_symbol(); diff --git a/src/in_memory_undo.c b/src/in_memory_undo.c index 38595b21..07497d74 100644 --- a/src/in_memory_undo.c +++ b/src/in_memory_undo.c @@ -129,6 +129,7 @@ static void free_undo_symbols(int slot) my_free(_ALLOC_ID_, &sym->prop_ptr); my_free(_ALLOC_ID_, &sym->type); my_free(_ALLOC_ID_, &sym->templ); + my_free(_ALLOC_ID_, &sym->parent_prop_ptr); for(c = 0;cpolygons[c]; ++j) { diff --git a/src/netlist.c b/src/netlist.c index 14b44f43..a48dfa2d 100644 --- a/src/netlist.c +++ b/src/netlist.c @@ -1612,7 +1612,7 @@ int sym_vs_sch_pins() int_hash_free(&pin_table); /* pass through symbols, duplicated pins: do not check with schematic */ if(rects > unique_pins) continue; - get_sch_from_sym(filename, xctx->sym + i, -1); + get_sch_from_sym(filename, xctx->sym + i, -1, 0); if(!stat(filename, &buf)) { fd = fopen(filename, "r"); pin_cnt = 0; diff --git a/src/psprint.c b/src/psprint.c index 4f253bbb..1b266f5e 100644 --- a/src/psprint.c +++ b/src/psprint.c @@ -812,7 +812,7 @@ static void ps_draw_symbol(int n,int layer, int what, short tmp_flip, short rot, if(what != 7) { char fname[PATH_MAX]; if(!strcmp(xctx->sym[xctx->inst[n].ptr].type, "subcircuit")) { - get_sch_from_sym(fname, xctx->inst[n].ptr+ xctx->sym, n); + get_sch_from_sym(fname, xctx->inst[n].ptr+ xctx->sym, n, 0); fprintf(fd, "[ " "/Rect [ %g %g %g %g ] " diff --git a/src/save.c b/src/save.c index 6c834bbe..5b250442 100644 --- a/src/save.c +++ b/src/save.c @@ -3632,6 +3632,7 @@ int load_sym_def(const char *name, FILE *embed_fd) symbol[symbols].prop_ptr = NULL; symbol[symbols].type = NULL; symbol[symbols].templ = NULL; + symbol[symbols].parent_prop_ptr = NULL; symbol[symbols].base_name=NULL; symbol[symbols].name=NULL; diff --git a/src/scheduler.c b/src/scheduler.c index 2d06cfcd..69766b3c 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -655,9 +655,9 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg if(xctx->semaphore == 0) { if(argc > 2) { int n = atoi(argv[2]); - ret = descend_schematic(n); + ret = descend_schematic(n, 0, 0); } else { - ret = descend_schematic(0); + ret = descend_schematic(0, 0, 0); } } Tcl_SetResult(interp, dtoa(ret), TCL_VOLATILE); @@ -1698,7 +1698,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg return TCL_ERROR; } else { if( xctx->inst[inst].ptr >= 0 ) { - get_sch_from_sym(filename, xctx->inst[inst].ptr+ xctx->sym, inst); + get_sch_from_sym(filename, xctx->inst[inst].ptr+ xctx->sym, inst, 0); } } } diff --git a/src/spice_netlist.c b/src/spice_netlist.c index 5875783c..b1b87f30 100644 --- a/src/spice_netlist.c +++ b/src/spice_netlist.c @@ -90,7 +90,7 @@ void hier_psprint(char **res, int what) /* netlister driver */ { /* xctx->sym can be SCH or SYM, use hash to avoid writing duplicate subckt */ my_strdup(_ALLOC_ID_, &subckt_name, get_cell(xctx->sym[i].name, 0)); - get_sch_from_sym(filename, xctx->sym + i, -1); + get_sch_from_sym(filename, xctx->sym + i, -1, 0); if (str_hash_lookup(&subckt_table, filename, "", XLOOKUP)==NULL) { const char *default_schematic; @@ -434,17 +434,14 @@ 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) + /* store parent symbol template attr (before descending into it) and parent instance prop_ptr * 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)); + tcl_hook2(xctx->sym[i].templ)); + my_strdup(_ALLOC_ID_, &xctx->hier_attr[xctx->currsch - 1].prop_ptr, + tcl_hook2(xctx->sym[i].parent_prop_ptr)); 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)) { @@ -470,8 +467,11 @@ 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); } + if(xctx->hier_attr[xctx->currsch - 1].templ) + my_free(_ALLOC_ID_, &xctx->hier_attr[xctx->currsch - 1].templ); + if(xctx->hier_attr[xctx->currsch - 1].prop_ptr) + my_free(_ALLOC_ID_, &xctx->hier_attr[xctx->currsch - 1].prop_ptr); my_free(_ALLOC_ID_, &abs_path); /* get_additional_symbols(0); */ my_free(_ALLOC_ID_, &subckt_name); @@ -599,7 +599,7 @@ int spice_block_netlist(FILE *fd, int i) if(!strcmp(get_tok_value(xctx->sym[i].prop_ptr, "format", 0), "")) { return err; } - get_sch_from_sym(filename, xctx->sym + i, -1); + get_sch_from_sym(filename, xctx->sym + i, -1, 0); default_schematic = get_tok_value(xctx->sym[i].prop_ptr, "default_schematic", 0); if(!strcmp(default_schematic, "ignore")) { return err; diff --git a/src/tedax_netlist.c b/src/tedax_netlist.c index e4ab931f..ceb0e521 100644 --- a/src/tedax_netlist.c +++ b/src/tedax_netlist.c @@ -81,7 +81,7 @@ static int tedax_block_netlist(FILE *fd, int i) tedax_stop=1; else tedax_stop=0; - get_sch_from_sym(filename, xctx->sym + i, -1); + get_sch_from_sym(filename, xctx->sym + i, -1, 0); default_schematic = get_tok_value(xctx->sym[i].prop_ptr, "default_schematic", 0); if(!strcmp(default_schematic, "ignore")) { diff --git a/src/token.c b/src/token.c index 6aecefcb..872ecdd6 100644 --- a/src/token.c +++ b/src/token.c @@ -2166,6 +2166,9 @@ int print_spice_element(FILE *fd, int inst) dbg(1, "model: instance=%s ,val=%s, tok=%s, value=%s template=%s\n", xctx->inst[inst].instname, val, token, value, xctx->hier_attr[xctx->currsch - 1].templ); + if(value[0] == '\0') { + value=get_tok_value(xctx->hier_attr[xctx->currsch - 1].prop_ptr, val+1, 0); + } if(value[0] == '\0') { value=get_tok_value(xctx->hier_attr[xctx->currsch - 1].templ, val+1, 0); } @@ -2175,6 +2178,9 @@ int print_spice_element(FILE *fd, int inst) value = get_tok_value(xctx->inst[inst].prop_ptr, val + 1, 0); dbg(1, "val=%s, tok=%s, value=%s template=%s", val, token, value, xctx->hier_attr[xctx->currsch - 1].templ); + if(value[0] == '\0') { + value=get_tok_value(xctx->hier_attr[xctx->currsch - 1].prop_ptr, val+1, 0); + } if(value[0] == '\0') { value=get_tok_value(xctx->hier_attr[xctx->currsch - 1].templ, val+1, 0); } @@ -3735,7 +3741,7 @@ const char *translate(int inst, const char* s) } } else if(strcmp(token,"@sch_last_modified")==0 && xctx->inst[inst].ptr >= 0) { - get_sch_from_sym(file_name, xctx->inst[inst].ptr + xctx->sym, inst); + get_sch_from_sym(file_name, xctx->inst[inst].ptr + xctx->sym, inst, 0); if(!stat(file_name , &time_buf)) { tm=localtime(&(time_buf.st_mtime) ); tmp=strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", tm); diff --git a/src/verilog_netlist.c b/src/verilog_netlist.c index f254535a..cddaa7d8 100644 --- a/src/verilog_netlist.c +++ b/src/verilog_netlist.c @@ -437,7 +437,7 @@ int verilog_block_netlist(FILE *fd, int i) verilog_stop=1; else verilog_stop=0; - get_sch_from_sym(filename, xctx->sym + i, -1); + get_sch_from_sym(filename, xctx->sym + i, -1, 0); default_schematic = get_tok_value(xctx->sym[i].prop_ptr, "default_schematic", 0); if(!strcmp(default_schematic, "ignore")) { diff --git a/src/vhdl_netlist.c b/src/vhdl_netlist.c index 21c05a40..114d8660 100644 --- a/src/vhdl_netlist.c +++ b/src/vhdl_netlist.c @@ -521,7 +521,7 @@ int vhdl_block_netlist(FILE *fd, int i) vhdl_stop=1; else vhdl_stop=0; - get_sch_from_sym(filename, xctx->sym + i, -1); + get_sch_from_sym(filename, xctx->sym + i, -1, 0); default_schematic = get_tok_value(xctx->sym[i].prop_ptr, "default_schematic", 0); if(!strcmp(default_schematic, "ignore")) { diff --git a/src/xschem.h b/src/xschem.h index 8838668b..37d94d30 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -560,6 +560,7 @@ typedef struct char *prop_ptr; char *type; char *templ; + char *parent_prop_ptr; int flags; /* bit 0: embedded flag * bit 1: **free** * bit 2: HILIGHT_CONN, highlight if connected net/label is highlighted @@ -1478,10 +1479,10 @@ extern void load_ascii_string(char **ptr, FILE *fd); extern char *read_line(FILE *fp, int dbg_level); extern void read_record(int firstchar, FILE *fp, int dbg_level); extern void create_sch_from_sym(void); -extern void get_sch_from_sym(char *filename, xSymbol *sym, int inst); +extern void get_sch_from_sym(char *filename, xSymbol *sym, int inst, int fallback); extern const char *get_sym_name(int inst, int ndir, int ext); extern void get_additional_symbols(int what); -extern int descend_schematic(int instnumber); +extern int descend_schematic(int instnumber, int fallback, int alert); extern void go_back(int confirm); extern void clear_schematic(int cancel, int symbol); extern void view_unzoom(double z);