From 10441ef901a5dd1928cd071752b801caef3e70ca Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Wed, 26 Apr 2023 09:54:35 +0200 Subject: [PATCH] allow tcl procedures to generate generator script and parameters, update vhdl and verilog netlisters to handle generator schematic/symbol references --- src/actions.c | 37 +++++----- src/save.c | 19 ++++-- src/spice_netlist.c | 15 +++-- src/token.c | 71 +++++++++++--------- src/verilog_netlist.c | 19 +++--- src/vhdl_netlist.c | 14 ++-- src/xinit.c | 1 + src/xschem.h | 4 +- xschem_library/generators/my_inv.sym | 8 +-- xschem_library/generators/symbolgen | 16 ++--- xschem_library/generators/test_symbolgen.sch | 5 +- 11 files changed, 118 insertions(+), 91 deletions(-) diff --git a/src/actions.c b/src/actions.c index b51808ac..e1e48116 100644 --- a/src/actions.c +++ b/src/actions.c @@ -1217,11 +1217,11 @@ const char *get_sym_name(int inst, int ext) else sym = skip_dir(add_ext(rel_sym_path(sch), ".sym")); } else if(ext) { - sym = get_cell_w_ext(xctx->inst[inst].name, 0); + sym = get_cell_w_ext(tcl_hook2(xctx->inst[inst].name), 0); } else { - sym = skip_dir(xctx->inst[inst].name); + sym = skip_dir(tcl_hook2(xctx->inst[inst].name)); } - dbg(1, "get_sym_name(): returning sym=%s\n", sym); + dbg(1, "get_sym_name(): inst=%d, ext=%d, returning sym=%s\n", inst, ext, sym); return sym; } @@ -1404,21 +1404,24 @@ void get_sch_from_sym(char *filename, xSymbol *sym, int inst) dbg(1, "get_sch_from_sym(): symbol %s inst=%d\n", sym->name, inst); if(inst >= 0) my_strdup(_ALLOC_ID_, &str_tmp, get_tok_value(xctx->inst[inst].prop_ptr, "schematic", 2)); if(!str_tmp) my_strdup2(_ALLOC_ID_, &str_tmp, get_tok_value(sym->prop_ptr, "schematic", 2)); - if(str_tmp[0]) { + + + + if(str_tmp[0]) { /* schematic attribute in symbol or instance was given */ /* @symname in schematic attribute will be replaced with symbol name */ - my_strdup2(_ALLOC_ID_, &sch, str_replace(str_tmp, "@symname", skip_dir(sym->name), '\\')); - } - if(str_tmp[0] && is_generator(str_tmp)) { /* generator: return as is */ - my_strncpy(filename, sch, PATH_MAX); - } else if(str_tmp[0]) { - dbg(1, "get_sch_from_sym(): sch=%s\n", sch); - my_strdup2(_ALLOC_ID_, &sch, tcl_hook2(&sch)); - dbg(1, "get_sch_from_sym(): after tcl_hook2 sch=%s\n", sch); - /* for schematics referenced from web symbols do not build absolute path */ - if(web_url) my_strncpy(filename, sch, PATH_MAX); - else my_strncpy(filename, abs_sym_path(sch, ""), PATH_MAX); + my_strdup2(_ALLOC_ID_, &sch, tcl_hook2(str_replace(str_tmp, "@symname", sym->name, '\\'))); + if(is_generator(sch)) { /* generator: return as is */ + my_strncpy(filename, sch, PATH_MAX); + 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); + /* for schematics referenced from web symbols do not build absolute path */ + 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 */ - if(is_generator(sym->name)) my_strncpy(filename, sym->name, PATH_MAX); + 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")) { /* for schematics referenced from web symbols do not build absolute path */ if(web_url) my_strncpy(filename, add_ext(sym->name, ".sch"), PATH_MAX); @@ -1439,7 +1442,7 @@ void get_sch_from_sym(char *filename, xSymbol *sym, int inst) /* if( strstr(xctx->current_dirname, "http://") == xctx->current_dirname || * strstr(xctx->current_dirname, "https://") == xctx->current_dirname) { */ - if(web_url) { + if(web_url) { char sympath[PATH_MAX]; /* download item into ${XSCHEM_TMP_DIR}/xschem_web */ tclvareval("try_download_url {", xctx->current_dirname, "} {", filename, "}", NULL); diff --git a/src/save.c b/src/save.c index dbf88481..b419b1f4 100644 --- a/src/save.c +++ b/src/save.c @@ -3146,6 +3146,7 @@ int load_sym_def(const char *name, FILE *embed_fd) const char *dash; xSymbol * symbol; int symbols, sym_n_pins=0, generator; + const char *cmd; check_symbol_storage(); symbol = xctx->sym; @@ -3156,10 +3157,12 @@ int load_sym_def(const char *name, FILE *embed_fd) lcc=NULL; my_realloc(_ALLOC_ID_, &lcc, (level + 1) * sizeof(Lcc)); max_level = level + 1; - - generator = is_generator(name); + cmd = tcl_hook2(name); + dbg(1, "l_s_d(): cmd=%s\n", cmd); + generator = is_generator(cmd); if(generator) { - char * cmd = get_generator_command(name); + cmd = get_generator_command(cmd); + dbg(1, "l_s_d(): cmd=%s\n", cmd); if(cmd) { lcc[level].fd = popen(cmd, "r"); /* execute ss="/path/to/xxx par1 par2 ..." and pipe in the stdout */ my_free(_ALLOC_ID_, &cmd); @@ -4002,8 +4005,9 @@ void descend_symbol(void) /* load_symbol(name_embedded); */ load_schematic(1, name_embedded, 1, 1); } else { - char sympath[PATH_MAX]; - my_strncpy(sympath, abs_sym_path(name, ""), S(sympath)); + char *sympath = NULL; + my_strdup2(_ALLOC_ID_, &sympath, name); + my_strdup2(_ALLOC_ID_, &sympath, abs_sym_path(tcl_hook2(sympath), "")); unselect_all(1); remove_symbols(); /* must follow save (if) embedded */ dbg(1, "name=%s, sympath=%s\n", name, sympath); @@ -4013,11 +4017,14 @@ void descend_symbol(void) (strstr(xctx->current_dirname, "http://") == xctx->current_dirname || strstr(xctx->current_dirname, "https://") == xctx->current_dirname)) { /* symbols have already been downloaded while loading parent schematic: set local file path */ - my_snprintf(sympath, S(sympath), "%s/xschem_web/%s", tclgetvar("XSCHEM_TMP_DIR"), get_cell_w_ext(name, 0)); + my_mstrcat(_ALLOC_ID_, &sympath, tclgetvar("XSCHEM_TMP_DIR"), + "/xschem_web/", get_cell_w_ext(name, 0), NULL); load_schematic(1, sympath, 1, 1); } else { + dbg(1, "descend_symbol(): sympath=%s\n", sympath); load_schematic(1, sympath, 1, 1); } + my_free(_ALLOC_ID_, &sympath); } zoom_full(1, 0, 1, 0.97); } diff --git a/src/spice_netlist.c b/src/spice_netlist.c index daf0409a..7e7b5b3d 100644 --- a/src/spice_netlist.c +++ b/src/spice_netlist.c @@ -534,7 +534,9 @@ int spice_block_netlist(FILE *fd, int i) char *extra=NULL; int split_f; const char *sym_def; + char *name = NULL; + my_strdup(_ALLOC_ID_, &name, tcl_hook2(xctx->sym[i].name)); split_f = tclgetboolvar("split_files"); if(!strcmp( get_tok_value(xctx->sym[i].prop_ptr,"spice_stop",0),"true") ) @@ -545,23 +547,21 @@ int spice_block_netlist(FILE *fd, int i) dbg(1, "spice_block_netlist(): filename=%s\n", filename); if(split_f) { my_snprintf(netl_filename, S(netl_filename), "%s/.%s_%d", - tclgetvar("netlist_dir"), skip_dir(xctx->sym[i].name), getpid()); + tclgetvar("netlist_dir"), skip_dir(name), getpid()); dbg(1, "spice_block_netlist(): split_files: netl_filename=%s\n", netl_filename); fd=fopen(netl_filename, "w"); - my_snprintf(cellname, S(cellname), "%s.spice", skip_dir(xctx->sym[i].name)); + my_snprintf(cellname, S(cellname), "%s.spice", skip_dir(name)); } - fprintf(fd, "\n* expanding symbol: %s # of pins=%d\n", - xctx->sym[i].name,xctx->sym[i].rects[PINLAYER] ); + fprintf(fd, "\n* expanding symbol: %s # of pins=%d\n", name,xctx->sym[i].rects[PINLAYER] ); if(xctx->sym[i].base_name) fprintf(fd, "** sym_path: %s\n", abs_sym_path(xctx->sym[i].base_name, "")); - else fprintf(fd, "** sym_path: %s\n", sanitized_abs_sym_path(xctx->sym[i].name, "")); + else fprintf(fd, "** sym_path: %s\n", sanitized_abs_sym_path(name, "")); sym_def = get_tok_value(xctx->sym[i].prop_ptr,"spice_sym_def",0); if(sym_def[0]) { fprintf(fd, "%s\n", sym_def); } else { - char *s = sanitize(skip_dir(xctx->sym[i].name)); + const char *s = sanitize(skip_dir(name)); fprintf(fd, "** sch_path: %s\n", sanitized_abs_sym_path(filename, "")); fprintf(fd, ".subckt %s ", s); - my_free(_ALLOC_ID_, &s); print_spice_subckt_nodes(fd, i); my_strdup(_ALLOC_ID_, &extra, get_tok_value(xctx->sym[i].prop_ptr,"extra",0) ); @@ -598,6 +598,7 @@ int spice_block_netlist(FILE *fd, int i) if(debug_var==0) xunlink(netl_filename); } xctx->netlist_count++; + my_free(_ALLOC_ID_, &name); return err; } diff --git a/src/token.c b/src/token.c index c3948d56..30ce47fd 100644 --- a/src/token.c +++ b/src/token.c @@ -61,26 +61,28 @@ void hash_all_names(void) my_free(_ALLOC_ID_, &type); } -const char *tcl_hook2(char **res) +/* if cmd is wrapped inside tcleval(...) pass the content to tcl + * for evaluation, return tcl result. If no tcleval(...) found return copy of cmd */ +const char *tcl_hook2(const char *cmd) { static char *result = NULL; static const char *empty=""; char *unescaped_res; - if(res == NULL || *res == NULL) { + if(cmd == NULL) { my_free(_ALLOC_ID_, &result); return empty; } - if(strstr(*res, "tcleval(") == *res) { - unescaped_res = str_replace(*res, "\\}", "}", 0); + if(strstr(cmd, "tcleval(") == cmd) { + unescaped_res = str_replace(cmd, "\\}", "}", 0); tclvareval("tclpropeval2 {", unescaped_res, "}" , NULL); my_strdup2(_ALLOC_ID_, &result, tclresult()); /* dbg(0, "tcl_hook2: return: %s\n", result);*/ - return result; } else { - /* dbg(0, "tcl_hook2: return: %s\n", *res); */ - return *res; + /* dbg(0, "tcl_hook2: return: %s\n", cmd); */ + my_strdup2(_ALLOC_ID_, &result, cmd); } + return result; } /* Missing: @@ -187,11 +189,15 @@ int is_generator(const char *name) #endif } -/* caller must free returned string - * cleanup syntax of symbol generators: xxx(a,b,c) --> xxx_a_b_c */ -char *sanitize(const char *name) +/* cleanup syntax of symbol generators: xxx(a,b,c) --> xxx_a_b_c */ +const char *sanitize(const char *name) { - char *s = NULL; + static char *s = NULL; + static char *empty=""; + if(name == NULL) { + my_free(_ALLOC_ID_, &s); + return empty; + } tclvareval("regsub -all { *[(),] *} {", name, "} _", NULL); tclvareval("regsub {_$} {", tclresult(), "} {}", NULL); my_strdup2(_ALLOC_ID_, &s, tclresult()); @@ -493,7 +499,7 @@ const char *get_tok_value(const char *s,const char *tok, int with_quotes) } else if(state==TOK_END) { result[value_pos]='\0'; if( !cmp ) { - return with_quotes & 2 ? result : tcl_hook2(&result); + return with_quotes & 2 ? result : tcl_hook2(result); } value_pos=0; state=TOK_BEGIN; @@ -502,7 +508,7 @@ const char *get_tok_value(const char *s,const char *tok, int with_quotes) if(c=='\0') { result[0]='\0'; xctx->tok_size = 0; - return with_quotes & 2 ? result : tcl_hook2(&result); + return with_quotes & 2 ? result : tcl_hook2(result); } } } @@ -854,11 +860,13 @@ static void print_vhdl_primitive(FILE *fd, int inst) /* netlist primitives, 200 else if(strcmp(token,"@symname")==0) /* of course symname must not be present */ /* in hash table */ { - fputs(get_sym_name(inst, 0), fd); + const char *s = sanitize(get_sym_name(inst, 0)); + fputs(s, fd); } else if (strcmp(token,"@symname_ext")==0) { - fputs(get_sym_name(inst, 1), fd); + const char *s = sanitize(get_sym_name(inst, 1)); + fputs(s, fd); } else if(strcmp(token,"@schname_ext")==0) /* of course schname must not be present */ /* in hash table */ @@ -1229,9 +1237,9 @@ void print_vhdl_element(FILE *fd, int inst) /* print instance name and subckt */ dbg(2, "print_vhdl_element(): printing inst name & subcircuit name\n"); if( (lab = expandlabel(name, &tmp)) != NULL) - fprintf(fd, "%d %s : %s\n", tmp, lab, get_sym_name(inst, 0) ); + fprintf(fd, "%d %s : %s\n", tmp, lab, sanitize(get_sym_name(inst, 0)) ); else /* name in some strange format, probably an error */ - fprintf(fd, "1 %s : %s\n", name, get_sym_name(inst, 0) ); + fprintf(fd, "1 %s : %s\n", name, sanitize(get_sym_name(inst, 0)) ); dbg(2, "print_vhdl_element(): printing generics passed as properties\n"); @@ -1376,7 +1384,7 @@ void print_generic(FILE *fd, char *ent_or_comp, int symbol) my_strdup(_ALLOC_ID_, &generic_type, get_tok_value(xctx->sym[symbol].prop_ptr,"generic_type",0)); dbg(2, "print_generic(): symbol=%d template=%s \n", symbol, template); - fprintf(fd, "%s %s ",ent_or_comp, skip_dir(xctx->sym[symbol].name)); + fprintf(fd, "%s %s ",ent_or_comp, sanitize(skip_dir(xctx->sym[symbol].name))); if(!strcmp(ent_or_comp,"entity")) fprintf(fd, "is\n"); else @@ -1594,11 +1602,11 @@ void print_spice_subckt_nodes(FILE *fd, int symbol) my_strdup(_ALLOC_ID_, &format1, get_tok_value(xctx->sym[symbol].prop_ptr, "format", 2)); dbg(1, "print_spice_subckt(): format1=%s\n", format1); - /* can not do this, since @symname is used as a marker later */ + /* can not do this, since @symname is used as a token later in format parser */ /* my_strdup(_ALLOC_ID_, &format1, str_replace(format1, "@symname", skip_dir(xctx->sym[symbol].name), '\\')); */ if(format1 && strstr(format1, "tcleval(") == format1) { - tclres = tcl_hook2(&format1); + tclres = tcl_hook2(format1); if(!strcmp(tclres, "?\n")) { char *ptr = strrchr(format1 + 8, ')'); *ptr = '\0'; @@ -1869,17 +1877,16 @@ int print_spice_element(FILE *fd, int inst) } else if (strcmp(token,"@symname")==0) /* of course symname must not be present in attributes */ { - char *s = sanitize(get_sym_name(inst, 0)); + const char *s = sanitize(get_sym_name(inst, 0)); tmp = strlen(s) +100 ; /* always make room for some extra chars * so 1-char writes to result do not need reallocs */ STR_ALLOC(&result, tmp + result_pos, &size); result_pos += my_snprintf(result + result_pos, tmp, "%s", s); - my_free(_ALLOC_ID_, &s); /* fputs(s,fd); */ } else if (strcmp(token,"@symname_ext")==0) /* of course symname must not be present in attributes */ { - const char *s = get_sym_name(inst, 1); + const char *s = sanitize(get_sym_name(inst, 1)); tmp = strlen(s) +100 ; /* always make room for some extra chars * so 1-char writes to result do not need reallocs */ STR_ALLOC(&result, tmp + result_pos, &size); @@ -2237,11 +2244,13 @@ void print_tedax_element(FILE *fd, int inst) else if(strcmp(token,"@symname")==0) /* of course symname must not be present */ /* in hash table */ { - fputs(get_sym_name(inst, 0), fd); + const char *s = sanitize(get_sym_name(inst, 0)); + fputs(s, fd); } else if (strcmp(token,"@symname_ext")==0) { - fputs(get_sym_name(inst, 1), fd); + const char *s = sanitize(get_sym_name(inst, 1)); + fputs(s, fd); } else if(strcmp(token,"@schname_ext")==0) /* of course schname must not be present */ /* in hash table */ @@ -2476,11 +2485,13 @@ static void print_verilog_primitive(FILE *fd, int inst) /* netlist switch level else if(strcmp(token,"@symname")==0) /* of course symname must not be present */ /* in hash table */ { - fputs(get_sym_name(inst, 0), fd); + const char *s = sanitize(get_sym_name(inst, 0)); + fputs(s, fd); } else if (strcmp(token,"@symname_ext")==0) { - fputs(get_sym_name(inst, 1), fd); + const char *s = sanitize(get_sym_name(inst, 1)); + fputs(s, fd); } else if(strcmp(token,"@schname_ext")==0) /* of course schname must not be present */ /* in hash table */ @@ -2635,7 +2646,7 @@ void print_verilog_element(FILE *fd, int inst) s=xctx->inst[inst].prop_ptr; /* print instance subckt */ dbg(2, "print_verilog_element(): printing inst name & subcircuit name\n"); - fprintf(fd, "%s\n", symname); + fprintf(fd, "%s\n", sanitize(symname)); my_free(_ALLOC_ID_, &symname); /* -------- print generics passed as properties */ tmp=0; @@ -3540,7 +3551,7 @@ const char *translate(int inst, const char* s) /* if result is like: 'tcleval(some_string)' pass it thru tcl evaluation so expressions * can be calculated */ - return tcl_hook2(&result); + return tcl_hook2(result); } const char *translate2(Lcc *lcc, int level, char* s) @@ -3668,7 +3679,7 @@ const char *translate2(Lcc *lcc, int level, char* s) my_free(_ALLOC_ID_, &token); my_free(_ALLOC_ID_, &value); dbg(1, "translate2(): result=%s\n", result); - /* return tcl_hook2(&result); */ + /* return tcl_hook2(result); */ return result; } diff --git a/src/verilog_netlist.c b/src/verilog_netlist.c index 6e497991..b15c403b 100644 --- a/src/verilog_netlist.c +++ b/src/verilog_netlist.c @@ -435,8 +435,9 @@ int verilog_block_netlist(FILE *fd, int i) int split_f; const char *sym_def; char *extra_ptr, *saveptr1, *extra_token, *extra = NULL, *extra2=NULL; + char *name = NULL; - + my_strdup(_ALLOC_ID_, &name, tcl_hook2(xctx->sym[i].name)); split_f = tclgetboolvar("split_files"); if(!strcmp( get_tok_value(xctx->sym[i].prop_ptr,"verilog_stop",0),"true") ) verilog_stop=1; @@ -446,17 +447,16 @@ int verilog_block_netlist(FILE *fd, int i) if(split_f) { my_snprintf(netl_filename, S(netl_filename), "%s/.%s_%d", - tclgetvar("netlist_dir"), skip_dir(xctx->sym[i].name), getpid()); + tclgetvar("netlist_dir"), skip_dir(name), getpid()); dbg(1, "global_vhdl_netlist(): split_files: netl_filename=%s\n", netl_filename); fd=fopen(netl_filename, "w"); - my_snprintf(cellname, S(cellname), "%s.v", skip_dir(xctx->sym[i].name) ); + my_snprintf(cellname, S(cellname), "%s.v", skip_dir(name)); } - dbg(1, "verilog_block_netlist(): expanding %s\n", xctx->sym[i].name); - fprintf(fd, "\n// expanding symbol: %s # of pins=%d\n", - xctx->sym[i].name,xctx->sym[i].rects[PINLAYER] ); + dbg(1, "verilog_block_netlist(): expanding %s\n", name); + fprintf(fd, "\n// expanding symbol: %s # of pins=%d\n", name, xctx->sym[i].rects[PINLAYER] ); if(xctx->sym[i].base_name) fprintf(fd, "// sym_path: %s\n", abs_sym_path(xctx->sym[i].base_name, "")); - else fprintf(fd, "// sym_path: %s\n", abs_sym_path(xctx->sym[i].name, "")); + else fprintf(fd, "// sym_path: %s\n", sanitized_abs_sym_path(name, "")); sym_def = get_tok_value(xctx->sym[i].prop_ptr,"verilog_sym_def",0); if(sym_def[0]) { fprintf(fd, "%s\n", sym_def); @@ -465,7 +465,7 @@ int verilog_block_netlist(FILE *fd, int i) int_hash_init(&table, 37); my_strdup(_ALLOC_ID_, &extra, get_tok_value(xctx->sym[i].prop_ptr, "verilog_extra", 0)); my_strdup(_ALLOC_ID_, &extra2, get_tok_value(xctx->sym[i].prop_ptr, "verilog_extra", 0)); - fprintf(fd, "// sch_path: %s\n", filename); + fprintf(fd, "// sch_path: %s\n", sanitized_abs_sym_path(filename, "")); verilog_stop? load_schematic(0,filename, 0, 1) : load_schematic(1,filename, 0, 1); /* print verilog timescale and preprocessor directives 10102004 */ fmt_attr = xctx->format ? xctx->format : "verilog_format"; @@ -500,7 +500,7 @@ int verilog_block_netlist(FILE *fd, int i) - fprintf(fd, "module %s (\n", symname); + fprintf(fd, "module %s (\n", sanitize(symname)); my_free(_ALLOC_ID_, &symname); /*print_generic(fd, "entity", i); */ @@ -615,6 +615,7 @@ int verilog_block_netlist(FILE *fd, int i) if(debug_var==0) xunlink(netl_filename); } xctx->netlist_count++; + my_free(_ALLOC_ID_, &name); return err; } diff --git a/src/vhdl_netlist.c b/src/vhdl_netlist.c index c1a8b5d1..0a198c2f 100644 --- a/src/vhdl_netlist.c +++ b/src/vhdl_netlist.c @@ -331,7 +331,8 @@ int global_vhdl_netlist(int global) /* netlister driver */ fprintf(fd,"end %s ;\n\n", skip_dir( xctx->sch[xctx->currsch]) ); fprintf(fd,"architecture arch_%s of %s is\n\n", - skip_dir( xctx->sch[xctx->currsch]) , skip_dir( xctx->sch[xctx->currsch])); + sanitize(skip_dir( xctx->sch[xctx->currsch])), + sanitize(skip_dir( xctx->sch[xctx->currsch]))); dbg(1, "global_vhdl_netlist(): printing top level used components\n"); /* print all components */ @@ -551,13 +552,13 @@ int vhdl_block_netlist(FILE *fd, int i) fprintf(fd, "\n-- expanding symbol: %s # of pins=%d\n", xctx->sym[i].name,xctx->sym[i].rects[PINLAYER] ); if(xctx->sym[i].base_name) fprintf(fd, "-- sym_path: %s\n", abs_sym_path(xctx->sym[i].base_name, "")); - else fprintf(fd, "-- sym_path: %s\n", abs_sym_path(xctx->sym[i].name, "")); + else fprintf(fd, "-- sym_path: %s\n", sanitized_abs_sym_path(xctx->sym[i].name, "")); sym_def = get_tok_value(xctx->sym[i].prop_ptr,"vhdl_sym_def",0); if(sym_def[0]) { fprintf(fd, "%s\n", sym_def); } else { Int_hashtable table = {NULL, 0}; - fprintf(fd, "-- sch_path: %s\n", filename); + fprintf(fd, "-- sch_path: %s\n", sanitized_abs_sym_path(filename, "")); load_schematic(1,filename, 0, 1); dbg(1, "vhdl_block_netlist(): packages\n"); for(l=0;linstances; ++l) @@ -632,11 +633,12 @@ int vhdl_block_netlist(FILE *fd, int i) if(xctx->inst[l].prop_ptr) fprintf(fd, "%s\n", xctx->inst[l].prop_ptr); } } - fprintf(fd,"end %s ;\n\n", skip_dir(xctx->sym[i].name) ); + fprintf(fd,"end %s ;\n\n", sanitize(skip_dir(xctx->sym[i].name)) ); dbg(1, "vhdl_block_netlist(): architecture\n"); fprintf(fd,"architecture arch_%s of %s is\n\n", - skip_dir(xctx->sym[i].name), skip_dir(xctx->sym[i].name) ); + sanitize(skip_dir(xctx->sym[i].name)), + sanitize(skip_dir(xctx->sym[i].name)) ); /* skip_dir( xctx->sch[xctx->currsch]), skip_dir( xctx->sch[xctx->currsch])); */ /* load current schematic to print used components */ @@ -724,7 +726,7 @@ int vhdl_block_netlist(FILE *fd, int i) } if(xctx->schvhdlprop && xctx->schvhdlprop[0]) fprintf(fd, "%s\n", xctx->schvhdlprop); - fprintf(fd, "end arch_%s ;\n\n", skip_dir(xctx->sym[i].name) ); /* skip_dir( xctx->sch[xctx->currsch]) ); */ + fprintf(fd, "end arch_%s ;\n\n", sanitize(skip_dir(xctx->sym[i].name)) ); my_free(_ALLOC_ID_, &sig_type); my_free(_ALLOC_ID_, &port_value); my_free(_ALLOC_ID_, &type); diff --git a/src/xinit.c b/src/xinit.c index ca4f75ce..1e23d763 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -646,6 +646,7 @@ static void delete_schematic_data(int delete_pixmap) remove_symbols(); str_replace(NULL, NULL, NULL, 0); escape_chars(NULL); + sanitize(NULL); is_generator(NULL); free_rawfile(0); free_xschem_data(); /* delete the xctx struct */ diff --git a/src/xschem.h b/src/xschem.h index b5a8b64b..e68af98d 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1158,7 +1158,7 @@ extern const char *get_cell_w_ext(const char *str, int no_of_dir); extern const char *rel_sym_path(const char *s); extern const char *abs_sym_path(const char *s, const char *ext); extern const char *sanitized_abs_sym_path(const char *s, const char *ext); -extern char *sanitize(const char *name); +extern const char *sanitize(const char *name); extern const char *add_ext(const char *f, const char *ext); extern void make_symbol(void); /* sort based on pinnumber pin attribute if present */ @@ -1346,7 +1346,7 @@ extern void tclsetdoublevar(const char *s, const double value); extern void tclsetboolvar(const char *s, const int value); extern void tclsetintvar(const char *s, const int value); extern int tclvareval(const char *script, ...); -extern const char *tcl_hook2(char **res); +extern const char *tcl_hook2(const char *res); extern void statusmsg(char str[],int n); extern int place_text(int draw_text, double mx, double my); extern void init_inst_iterator(Iterator_ctx *ctx, double x1, double y1, double x2, double y2); diff --git a/xschem_library/generators/my_inv.sym b/xschem_library/generators/my_inv.sym index 2b0e976b..abb62153 100644 --- a/xschem_library/generators/my_inv.sym +++ b/xschem_library/generators/my_inv.sym @@ -14,10 +14,10 @@ L 4 -20 -20 -20 20 {} L 4 -20 20 20 0 {} L 4 30 -0 40 -0 {} L 4 20 0 30 0 {dash=3} -B 5 37.5 -2.5 42.5 2.5 {name=Y dir=out } -B 5 -42.5 -2.5 -37.5 2.5 {name=A dir=in } +B 5 37.5 -2.5 42.5 2.5 {name=y dir=out } +B 5 -42.5 -2.5 -37.5 2.5 {name=a dir=in } A 4 25 -0 5 180 360 {dash=3} T {@symname} -47.5 24 0 0 0.3 0.3 {} T {@name} 25 -22 0 0 0.2 0.2 {} -T {Y} 7.5 -6.5 0 1 0.2 0.2 {} -T {A} -17.5 -6.5 0 0 0.2 0.2 {} +T {y} 7.5 -6.5 0 1 0.2 0.2 {} +T {a} -17.5 -6.5 0 0 0.2 0.2 {} diff --git a/xschem_library/generators/symbolgen b/xschem_library/generators/symbolgen index 768a8690..c3983864 100755 --- a/xschem_library/generators/symbolgen +++ b/xschem_library/generators/symbolgen @@ -6,10 +6,10 @@ set arg1 [lindex $argv 0] if { $arg1 eq {inv}} { puts {v {xschem version=3.1.0 file_version=1.2} K {type=subcircuit -verilog_primitive=true -vhdl_primitive=true -vhdl_format="@@y <= not @@a after 90 ps;" -verilog_format="assign #90 @@y = ~@@a ;" +xvhdl_primitive=true +xverilog_primitive=true +xvhdl_format="@@y <= not @@a after 90 ps;" +xverilog_format="assign #90 @@y = ~@@a ;" format="@name @pinlist @symname wn=@wn lln=@lln wp=@wp lp=@lp" template="name=x1 wn=1u lln=2u wp=4u lp=2u" schematic=schematicgen(inv)} @@ -29,10 +29,10 @@ T {a} -17.5 -6.5 0 0 0.2 0.2 {} } else { puts {v {xschem version=3.1.0 file_version=1.2} K {type=subcircuit -verilog_primitive=true -vhdl_primitive=true -vhdl_format="@@y <= @@a after 90 ps;" -verilog_format="assign #90 @@y = @@a ;" +xvhdl_primitive=true +xverilog_primitive=true +xvhdl_format="@@y <= @@a after 90 ps;" +xverilog_format="assign #90 @@y = @@a ;" format="@name @pinlist @symname wn=@wn lln=@lln wp=@wp lp=@lp" template="name=x1 wn=1u lln=2u wp=4u lp=2u" schematic=schematicgen(buf)} diff --git a/xschem_library/generators/test_symbolgen.sch b/xschem_library/generators/test_symbolgen.sch index 4d931792..e64e368b 100644 --- a/xschem_library/generators/test_symbolgen.sch +++ b/xschem_library/generators/test_symbolgen.sch @@ -73,7 +73,7 @@ C {symbolgen(inv)} 150 -460 0 0 {name=x1 tclcommand="edit_file [abs_sym_path symbolgen]" ROUT=1200} C {lab_pin.sym} 30 -520 0 0 {name=p1 lab=IN} -C {symbolgen(buf)} 150 -560 0 0 {name=x3 +C {symbolgen(buf,2)} 150 -560 0 0 {name=x3 tclcommand="edit_file [abs_sym_path symbolgen]" ROUT=1200} C {lab_pin.sym} 310 -560 0 1 {name=p2 lab=IN_BUF} @@ -103,7 +103,7 @@ schematic=schematicgen(inv) tclcommand="edit_file [abs_sym_path schematicgen]"} C {lab_pin.sym} 1120 -460 0 1 {name=p5 lab=IN_INV2} C {my_inv.sym} 960 -560 0 0 {name=x4 ROUT=1000 -schematic=schematicgen(buf) +schematic="schematicgen(buf,4)" tclcommand="edit_file [abs_sym_path schematicgen]"} C {lab_pin.sym} 1120 -560 0 1 {name=p7 lab=IN_BUF2} C {vdd.sym} 620 -470 0 0 {name=l2 lab=VCC} @@ -111,3 +111,4 @@ C {lab_pin.sym} 620 -440 0 1 {name=p8 lab=VCC} C {lab_pin.sym} 840 -520 0 0 {name=p9 lab=IN} C {parax_cap.sym} 1080 -550 0 0 {name=C3 gnd=0 value=100f m=1} C {parax_cap.sym} 1080 -450 0 0 {name=C4 gnd=0 value=100f m=1} +C {noconn.sym} 840 -560 0 0 {name=l3}