diff --git a/src/netlist.c b/src/netlist.c index fce9dc97..824db088 100644 --- a/src/netlist.c +++ b/src/netlist.c @@ -526,12 +526,19 @@ static void wirecheck(int k) /* recursive routine */ void set_tcl_netlist_type(void) { - if(xctx->netlist_type == CAD_SPICE_NETLIST) tclsetvar("netlist_type", "spice"); - else if(xctx->netlist_type == CAD_VERILOG_NETLIST) tclsetvar("netlist_type", "verilog"); - else if(xctx->netlist_type == CAD_VHDL_NETLIST) tclsetvar("netlist_type", "vhdl"); - else if(xctx->netlist_type == CAD_TEDAX_NETLIST) tclsetvar("netlist_type", "tedax"); - else if(xctx->netlist_type == CAD_SYMBOL_ATTRS) tclsetvar("netlist_type", "symbol"); - else tclsetvar("netlist_type", "unknown"); + if(xctx->netlist_type == CAD_SPICE_NETLIST) { + tclsetvar("netlist_type", "spice"); + } else if(xctx->netlist_type == CAD_VERILOG_NETLIST) { + tclsetvar("netlist_type", "verilog"); + } else if(xctx->netlist_type == CAD_VHDL_NETLIST) { + tclsetvar("netlist_type", "vhdl"); + } else if(xctx->netlist_type == CAD_TEDAX_NETLIST) { + tclsetvar("netlist_type", "tedax"); + } else if(xctx->netlist_type == CAD_SYMBOL_ATTRS) { + tclsetvar("netlist_type", "symbol"); + } else { + tclsetvar("netlist_type", "unknown"); + } } /* what==0 -> initialize */ diff --git a/src/scheduler.c b/src/scheduler.c index f78a9602..c94f3af5 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -883,6 +883,12 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg else Tcl_SetResult(interp, "0",TCL_STATIC); } + else if(!strcmp(argv[2],"format")) { + if( !xctx->format ) + Tcl_SetResult(interp, "",TCL_STATIC); + else + Tcl_SetResult(interp, xctx->format,TCL_VOLATILE); + } else if(!strcmp(argv[2],"graph_lastsel")) { Tcl_SetResult(interp, my_itoa(xctx->graph_lastsel),TCL_VOLATILE); } @@ -2509,6 +2515,9 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg else if(!strcmp(argv[2],"flat_netlist")) { xctx->flat_netlist=atoi(argv[3]); } + else if(!strcmp(argv[2],"format")) { + my_strdup(1542, &xctx->format, argv[3]); + } else if(!strcmp(argv[2],"hide_symbols")) { xctx->hide_symbols=atoi(argv[3]); } @@ -2520,27 +2529,23 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg if(argc > 3) { if(!strcmp(argv[3],"spice")){ xctx->netlist_type=CAD_SPICE_NETLIST; - tclsetvar("netlist_type", "spice"); } else if(!strcmp(argv[3],"vhdl")) { xctx->netlist_type=CAD_VHDL_NETLIST; - tclsetvar("netlist_type", "vhdl"); } else if(!strcmp(argv[3],"verilog")) { xctx->netlist_type=CAD_VERILOG_NETLIST; - tclsetvar("netlist_type", "verilog"); } else if(!strcmp(argv[3],"tedax")) { xctx->netlist_type=CAD_TEDAX_NETLIST; - tclsetvar("netlist_type", "tedax"); } else if(!strcmp(argv[3],"symbol")) { xctx->netlist_type=CAD_SYMBOL_ATTRS; - tclsetvar("netlist_type", "symbol"); } else { - tclsetvar("netlist_type", "unknown"); + dbg(0, "Warning: undefined netlist format: %s\n", argv[3]); } + set_tcl_netlist_type(); } } else if(!strcmp(argv[2],"no_draw")) { diff --git a/src/token.c b/src/token.c index 6b296c58..25b1da80 100644 --- a/src/token.c +++ b/src/token.c @@ -115,11 +115,13 @@ void hash_all_names(int n) { int i; char *upinst = NULL, *type = NULL, *format = NULL; + const char *fmt_attr = NULL; inst_hash_free(); + fmt_attr = xctx->format ? xctx->format : "format"; for(i=0; iinstances; i++) { if(xctx->inst[i].instname && xctx->inst[i].instname[0]) { my_strdup(1519, &type,(xctx->inst[i].ptr+ xctx->sym)->type); - my_strdup(1520, &format, get_tok_value((xctx->inst[i].ptr + xctx->sym)->prop_ptr,"format",2)); + my_strdup(1520, &format, get_tok_value((xctx->inst[i].ptr + xctx->sym)->prop_ptr, fmt_attr,2)); if(!type || !format || IS_LABEL_SH_OR_PIN(type) ) continue; my_strdup(1254, &upinst, xctx->inst[i].instname); strtoupper(upinst); @@ -169,6 +171,7 @@ void check_unique_names(int rename) Inst_hashentry *entry; int big = xctx->wires> 2000 || xctx->instances > 2000; char *upinst = NULL, *type = NULL, *format = NULL; + const char *fmt_attr = NULL; /* int save_draw; */ if(xctx->hilight_nets) { @@ -187,10 +190,11 @@ void check_unique_names(int rename) } inst_hash_free(); first = 1; + fmt_attr = xctx->format ? xctx->format : "format"; for(i=0;iinstances;i++) { if(xctx->inst[i].instname && xctx->inst[i].instname[0]) { my_strdup(1261, &type,(xctx->inst[i].ptr+ xctx->sym)->type); - my_strdup(1262, &format, get_tok_value((xctx->inst[i].ptr + xctx->sym)->prop_ptr,"format",2)); + my_strdup(1262, &format, get_tok_value((xctx->inst[i].ptr + xctx->sym)->prop_ptr, fmt_attr,2)); if(!type || !format || IS_LABEL_SH_OR_PIN(type) ) continue; my_strdup(1246, &upinst, xctx->inst[i].instname); strtoupper(upinst); @@ -774,15 +778,17 @@ static void print_vhdl_primitive(FILE *fd, int inst) /* netlist primitives, 200 int escape=0; int no_of_pins=0; /* Inst_hashentry *ptr; */ + char *fmt_attr = NULL; my_strdup(513, &template, (xctx->inst[inst].ptr + xctx->sym)->templ); my_strdup(514, &name, xctx->inst[inst].instname); + fmt_attr = xctx->format ? xctx->format : "vhdl_format"; if(!name) my_strdup(50, &name, get_tok_value(template, "name", 0)); /* allow format string override in instance */ - my_strdup(1000, &format, get_tok_value(xctx->inst[inst].prop_ptr,"vhdl_format",2)); + my_strdup(1000, &format, get_tok_value(xctx->inst[inst].prop_ptr, fmt_attr, 2)); if(!format || !format[0]) - my_strdup(516, &format, get_tok_value((xctx->inst[inst].ptr + xctx->sym)->prop_ptr,"vhdl_format",2)); + my_strdup(516, &format, get_tok_value((xctx->inst[inst].ptr + xctx->sym)->prop_ptr, fmt_attr, 2)); if((name==NULL) || (format==NULL) ) { my_free(1047, &template); my_free(1048, &name); @@ -1192,8 +1198,10 @@ void print_vhdl_element(FILE *fd, int inst) int quote=0; int escape=0; xRect *pinptr; + const char *fmt_attr = NULL; - if(get_tok_value((xctx->inst[inst].ptr + xctx->sym)->prop_ptr,"vhdl_format", 2)[0] != '\0') { + fmt_attr = xctx->format ? xctx->format : "vhdl_format"; + if(get_tok_value((xctx->inst[inst].ptr + xctx->sym)->prop_ptr, fmt_attr, 2)[0] != '\0') { print_vhdl_primitive(fd, inst); return; } @@ -1544,8 +1552,10 @@ void print_tedax_subckt(FILE *fd, int symbol) size_t token_pos=0; int escape=0; int no_of_pins=0; + char *fmt_attr = NULL; - my_strdup(460, &format, get_tok_value(xctx->sym[symbol].prop_ptr,"format",2)); + fmt_attr = xctx->format ? xctx->format : "format"; + my_strdup(460, &format, get_tok_value(xctx->sym[symbol].prop_ptr, fmt_attr, 2)); if( format==NULL ) { my_free(473, &format); return; /* no format */ @@ -1653,20 +1663,21 @@ void print_spice_subckt(FILE *fd, int symbol) size_t token_pos=0; int escape=0; int no_of_pins=0; - const char *tclres; + const char *tclres, *fmt_attr = NULL; - my_strdup(103, &format1, get_tok_value(xctx->sym[symbol].prop_ptr,"format",2)); + fmt_attr = xctx->format ? xctx->format : "format"; + my_strdup(103, &format1, get_tok_value(xctx->sym[symbol].prop_ptr, fmt_attr, 2)); dbg(1, "print_spice_subckt(): format1=%s\n", format1); - if(strstr(format1, "tcleval(") == format1) { + if(format1 && strstr(format1, "tcleval(") == format1) { tclres = tcl_hook2(&format1); if(!strcmp(tclres, "?\n")) my_strdup(1529, &format, format1 + 8); else my_strdup(455, &format, tclres); } else { my_strdup(1530, &format, format1); } + if(format1) my_free(1544, &format1); dbg(1, "print_spice_subckt(): format=%s\n", format); if( format==NULL ) { - my_free(1012, &format); return; /* no format */ } no_of_pins= xctx->sym[symbol].rects[PINLAYER]; @@ -1781,7 +1792,8 @@ int print_spice_element(FILE *fd, int inst) char *result = NULL; size_t result_pos = 0; size_t size = 0; - char *spiceprefixtag = NULL; + char *spiceprefixtag = NULL; + const char *fmt_attr = NULL; size = CADCHUNKALLOC; my_realloc(1211, &result, size); @@ -1792,9 +1804,10 @@ int print_spice_element(FILE *fd, int inst) if (!name) my_strdup(43, &name, get_tok_value(template, "name", 0)); /* allow format string override in instance */ - my_strdup(470, &format, get_tok_value(xctx->inst[inst].prop_ptr,"format",2)); + fmt_attr = xctx->format ? xctx->format : "format"; + my_strdup(470, &format, get_tok_value(xctx->inst[inst].prop_ptr, fmt_attr, 2)); if(!format || !format[0]) - my_strdup(486, &format, get_tok_value((xctx->inst[inst].ptr + xctx->sym)->prop_ptr,"format",2)); + my_strdup(486, &format, get_tok_value((xctx->inst[inst].ptr + xctx->sym)->prop_ptr, fmt_attr, 2)); if ((name==NULL) || (format==NULL)) { my_free(1015, &template); @@ -2397,6 +2410,7 @@ static void print_verilog_primitive(FILE *fd, int inst) /* netlist switch level int escape=0; int no_of_pins=0; /* Inst_hashentry *ptr; */ + const char *fmt_attr = NULL; my_strdup(519, &template, (xctx->inst[inst].ptr + xctx->sym)->templ); @@ -2404,10 +2418,11 @@ static void print_verilog_primitive(FILE *fd, int inst) /* netlist switch level my_strdup(520, &name,xctx->inst[inst].instname); if(!name) my_strdup(4, &name, get_tok_value(template, "name", 0)); + fmt_attr = xctx->format ? xctx->format : "verilog_format"; /* allow format string override in instance */ - my_strdup(1186, &format, get_tok_value(xctx->inst[inst].prop_ptr,"verilog_format",2)); + my_strdup(1186, &format, get_tok_value(xctx->inst[inst].prop_ptr, fmt_attr, 2)); if(!format || !format[0]) - my_strdup(522, &format, get_tok_value((xctx->inst[inst].ptr + xctx->sym)->prop_ptr,"verilog_format",2)); + my_strdup(522, &format, get_tok_value((xctx->inst[inst].ptr + xctx->sym)->prop_ptr, fmt_attr, 2)); if((name==NULL) || (format==NULL) ) { my_free(1054, &template); my_free(1055, &name); @@ -2597,8 +2612,10 @@ void print_verilog_element(FILE *fd, int inst) size_t sizetok=0, sizeval=0; size_t token_pos=0, value_pos=0; int quote=0; + const char *fmt_attr = NULL; - if(get_tok_value((xctx->inst[inst].ptr + xctx->sym)->prop_ptr,"verilog_format",2)[0] != '\0') { + fmt_attr = xctx->format ? xctx->format : "verilog_format"; + if(get_tok_value((xctx->inst[inst].ptr + xctx->sym)->prop_ptr, fmt_attr, 2)[0] != '\0') { print_verilog_primitive(fd, inst); return; } diff --git a/src/verilog_netlist.c b/src/verilog_netlist.c index d14018ac..385fed69 100644 --- a/src/verilog_netlist.c +++ b/src/verilog_netlist.c @@ -90,6 +90,7 @@ void global_verilog_netlist(int global) /* netlister driver */ char *subckt_name; char *abs_path = NULL; int split_f; + const char *fmt_attr = NULL; split_f = tclgetboolvar("split_files"); xctx->push_undo(); @@ -120,6 +121,7 @@ void global_verilog_netlist(int global) /* netlister driver */ /* print verilog timescale 10102004 */ + fmt_attr = xctx->format ? xctx->format : "verilog_format"; for(i=0;iinstances;i++) { if( strcmp(get_tok_value(xctx->inst[i].prop_ptr,"verilog_ignore",0),"true")==0 ) continue; @@ -130,7 +132,7 @@ void global_verilog_netlist(int global) /* netlister driver */ my_strdup(105, &type,(xctx->inst[i].ptr+ xctx->sym)->type); if( type && (strcmp(type,"timescale")==0 || strcmp(type,"verilog_preprocessor")==0) ) { - str_tmp = get_tok_value( (xctx->inst[i].ptr+ xctx->sym)->prop_ptr ,"verilog_format",2); + str_tmp = get_tok_value( (xctx->inst[i].ptr+ xctx->sym)->prop_ptr , fmt_attr, 2); my_strdup(106, &tmp_string, str_tmp); fprintf(fd, "%s\n", str_tmp ? translate(i, tmp_string) : "(NULL)"); } @@ -419,7 +421,7 @@ void verilog_block_netlist(FILE *fd, int i) char netl_filename[PATH_MAX]; char tcl_cmd_netlist[PATH_MAX + 100]; char cellname[PATH_MAX]; - const char *str_tmp; + const char *str_tmp, *fmt_attr = NULL; int split_f; split_f = tclgetboolvar("split_files"); @@ -445,6 +447,7 @@ void verilog_block_netlist(FILE *fd, int i) verilog_stop? load_schematic(0,filename, 0) : load_schematic(1,filename, 0); /* print verilog timescale and preprocessor directives 10102004 */ + fmt_attr = xctx->format ? xctx->format : "verilog_format"; for(j=0;jinstances;j++) { if( strcmp(get_tok_value(xctx->inst[j].prop_ptr,"verilog_ignore",0),"true")==0 ) continue; @@ -455,7 +458,7 @@ void verilog_block_netlist(FILE *fd, int i) my_strdup(544, &type,(xctx->inst[j].ptr+ xctx->sym)->type); if( type && ( strcmp(type,"timescale")==0 || strcmp(type,"verilog_preprocessor")==0) ) { - str_tmp = get_tok_value( (xctx->inst[j].ptr+ xctx->sym)->prop_ptr ,"verilog_format",2); + str_tmp = get_tok_value( (xctx->inst[j].ptr+ xctx->sym)->prop_ptr, fmt_attr, 2); my_strdup(545, &tmp_string, str_tmp); fprintf(fd, "%s\n", str_tmp ? translate(j, tmp_string) : "(NULL)"); } diff --git a/src/xinit.c b/src/xinit.c index fe5660d9..39d6ee20 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -377,6 +377,7 @@ static void free_xschem_data() my_free(1295, &xctx->top_path); my_free(1463, &xctx->current_win_path); my_free(1120, &xctx->fill_type); + my_free(1543, &xctx->format); if(xctx->inst_redraw_table) my_free(604, &xctx->inst_redraw_table); my_free(269, &xctx); } @@ -620,6 +621,8 @@ static void alloc_xschem_data(const char *top_path, const char *win_path) xctx->active_layer=my_calloc(563, cadlayers, sizeof(int)); xctx->hide_symbols = 0; xctx->netlist_type = CAD_SPICE_NETLIST; + xctx->format = NULL; /* custom format string for netlist, otherwise use + * "format", "verilog_format", "vhdl_format", "tedax_format" */ xctx->top_path = NULL; xctx->current_win_path = NULL; my_strdup2(1296, &xctx->top_path, top_path); diff --git a/src/xschem.h b/src/xschem.h index aa4c4d75..29c8bfbf 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -928,6 +928,7 @@ typedef struct { int netlist_count; /* netlist counter incremented at any cell being netlisted */ int hide_symbols; int netlist_type; + char *format; /* "format", "verilog_format", "vhdl_format" or "tedax_format" */ char *top_path; /* top_path is the path prefix of drawing canvas (current_win_path): *