From 68cf318134342d3f2adf9e0430f7c69579b0728d Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Mon, 24 Apr 2023 23:56:56 +0200 Subject: [PATCH] load_sym_def(): removed embedded parameter, recognize generator names and pipe in data from generator instead of loading from file. No more set flags for generated symbols to EMBEDDED --- src/actions.c | 16 ++-- src/netlist.c | 2 +- src/save.c | 68 +++++++------- src/spice_netlist.c | 2 +- src/token.c | 26 +----- src/verilog_netlist.c | 2 +- src/vhdl_netlist.c | 2 +- src/xschem.h | 2 +- xschem_library/examples/0_examples_top.sch | 1 + xschem_library/generators/my_inv.sym | 3 +- xschem_library/generators/symbolgen | 2 - xschem_library/generators/test_symbolgen.sch | 98 ++++++++++++-------- 12 files changed, 114 insertions(+), 110 deletions(-) diff --git a/src/actions.c b/src/actions.c index c731cb56..b51808ac 100644 --- a/src/actions.c +++ b/src/actions.c @@ -1404,19 +1404,20 @@ 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] && is_generator(str_tmp)) { /* generator: return as is */ - my_strncpy(filename, str_tmp, PATH_MAX); - } else if(str_tmp[0]) { + if(str_tmp[0]) { /* @symname in schematic attribute will be replaced with symbol name */ - my_strdup(_ALLOC_ID_, &sch, str_replace(str_tmp, "@symname", skip_dir(sym->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_free(_ALLOC_ID_, &sch); - } else { + } else { /* no schematic attribute from instance or symbol */ if(is_generator(sym->name)) my_strncpy(filename, sym->name, PATH_MAX); else if(tclgetboolvar("search_schematic")) { /* for schematics referenced from web symbols do not build absolute path */ @@ -1433,6 +1434,7 @@ void get_sch_from_sym(char *filename, xSymbol *sym, int inst) } } } + if(sch) my_free(_ALLOC_ID_, &sch); /* if( strstr(xctx->current_dirname, "http://") == xctx->current_dirname || * strstr(xctx->current_dirname, "https://") == xctx->current_dirname) { @@ -1601,7 +1603,7 @@ void go_back(int confirm) /* 20171006 add confirm */ /* when returning after editing an embedded symbol * load immediately symbol definition before going back (.xschem_embedded... file will be lost) */ - load_sym_def(xctx->sch[xctx->currsch], NULL, 0); + load_sym_def(xctx->sch[xctx->currsch], NULL); from_embedded_sym=1; } my_strncpy(xctx->sch[xctx->currsch] , "", S(xctx->sch[xctx->currsch])); diff --git a/src/netlist.c b/src/netlist.c index 2db26eda..51277665 100644 --- a/src/netlist.c +++ b/src/netlist.c @@ -1407,7 +1407,7 @@ int sym_vs_sch_pins() } break; case '[': - load_sym_def(name, fd, 1); + load_sym_def(name, fd); break; case ']': read_line(fd, 0); diff --git a/src/save.c b/src/save.c index bbdb72d7..a1eb4708 100644 --- a/src/save.c +++ b/src/save.c @@ -1641,18 +1641,12 @@ static void save_inst(FILE *fd, int select_only) } fprintf(fd, " %.16g %.16g %hd %hd ",inst[i].x0, inst[i].y0, inst[i].rot, inst[i].flip ); save_ascii_string(inst[i].prop_ptr,fd, 1); - if(embedded_saved && !embedded_saved[inst[i].ptr]) { - if(is_generator(inst[i].name)) { - embedded_saved[inst[i].ptr] = 1; - xctx->sym[inst[i].ptr].flags |= EMBEDDED; - dbg(1, "save_inst(): setting symbol %d to embedded\n", inst[i].ptr); - } else if(inst[i].embed) { - embedded_saved[inst[i].ptr] = 1; - fprintf(fd, "[\n"); - save_embedded_symbol( xctx->sym+inst[i].ptr, fd); - fprintf(fd, "]\n"); - xctx->sym[inst[i].ptr].flags |= EMBEDDED; - } + if(embedded_saved && !embedded_saved[inst[i].ptr] && inst[i].embed) { + embedded_saved[inst[i].ptr] = 1; + fprintf(fd, "[\n"); + save_embedded_symbol( xctx->sym+inst[i].ptr, fd); + fprintf(fd, "]\n"); + xctx->sym[inst[i].ptr].flags |= EMBEDDED; } } my_free(_ALLOC_ID_, &embedded_saved); @@ -2194,7 +2188,7 @@ static void read_xschem_file(FILE *fd) } read_line(fd, 0); /* skip garbage after '[' */ if(!found) { - load_sym_def(xctx->inst[xctx->instances-1].name, fd, 1); + load_sym_def(xctx->inst[xctx->instances-1].name, fd); found = 2; } } @@ -2432,7 +2426,7 @@ void load_schematic(int load_symbols, const char *fname, int reset_undo, int ale else xctx->prev_set_modify = 0; /* will prevent set_modify(0) from setting window title */ if(fname && fname[0]) { int generator = 0; - if(is_generator(fname) && !strstr(fname, ".xschem_embedded_")) generator = 1; + if(is_generator(fname)) generator = 1; my_strncpy(name, fname, S(name)); /* remote web object specified */ @@ -3105,8 +3099,6 @@ void sort_symbol_pins(xRect *pin_array, int npins, const char *name) /* load_sym_def(): load a symbol definition looking up 'name' in the search paths. * if 'embed_fd' FILE pointer is given read from there instead of searching 'name' - * 'embedded' parameter: set to 1 if loading an embedded symbol (embed_fd FILE pointer is given) - * set to 0 if loading a symbol that is not embedded from the given FILE pointer. * Global (or static global) variables used: * cadlayers * errfp @@ -3115,7 +3107,7 @@ void sort_symbol_pins(xRect *pin_array, int npins, const char *name) * xctx->symbols * has_x */ -int load_sym_def(const char *name, FILE *embed_fd, int embedded) +int load_sym_def(const char *name, FILE *embed_fd) { static int recursion_counter=0; /* safe to keep even with multiple schematics, operation not interruptable */ Lcc *lcc; /* size = level */ @@ -3153,7 +3145,7 @@ int load_sym_def(const char *name, FILE *embed_fd, int embedded) char *skip_line; const char *dash; xSymbol * symbol; - int symbols, sym_n_pins=0; + int symbols, sym_n_pins=0, generator; check_symbol_storage(); symbol = xctx->sym; @@ -3164,7 +3156,17 @@ int load_sym_def(const char *name, FILE *embed_fd, int embedded) lcc=NULL; my_realloc(_ALLOC_ID_, &lcc, (level + 1) * sizeof(Lcc)); max_level = level + 1; - if(!embed_fd) { /* regular symbol: open file */ + + generator = is_generator(name); + if(generator) { + char * cmd = get_generator_command(name); + 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); + } else { + lcc[level].fd = NULL; + } + } else if(!embed_fd) { /* regular symbol: open file */ if(!strcmp(xctx->file_version,"1.0")) { my_strncpy(sympath, abs_sym_path(name, ".sym"), S(sympath)); } else { @@ -3179,21 +3181,21 @@ int load_sym_def(const char *name, FILE *embed_fd, int embedded) lcc[level].fd=fopen(sympath,fopen_read_mode); } } - if(lcc[level].fd==NULL) { - /* issue warning only on top level symbol loading */ - if(recursion_counter == 1) dbg(0, "l_s_d(): Symbol not found: %s\n",sympath); - my_snprintf(sympath, S(sympath), "%s/%s", tclgetvar("XSCHEM_SHAREDIR"), "systemlib/missing.sym"); - if((lcc[level].fd=fopen(sympath, fopen_read_mode))==NULL) - { - fprintf(errfp, "l_s_d(): systemlib/missing.sym missing, I give up\n"); - tcleval("exit"); - } - } dbg(1, "l_s_d(): fopen1(%s), level=%d, fd=%p\n",sympath, level, lcc[level].fd); } else { /* embedded symbol (defined after instantiation within [...] ) */ dbg(1, "l_s_d(): getting embed_fd, level=%d\n", level); lcc[level].fd = embed_fd; } + if(lcc[level].fd==NULL) { + /* issue warning only on top level symbol loading */ + if(recursion_counter == 1) dbg(0, "l_s_d(): Symbol not found: %s\n",sympath); + my_snprintf(sympath, S(sympath), "%s/%s", tclgetvar("XSCHEM_SHAREDIR"), "systemlib/missing.sym"); + if((lcc[level].fd=fopen(sympath, fopen_read_mode))==NULL) + { + fprintf(errfp, "l_s_d(): systemlib/missing.sym missing, I give up\n"); + tcleval("exit"); + } + } endfile=0; /* initialize data for loading a new symbol */ for(c=0;csym[i].name)); - fprintf(fd, "** sch_path: %s\n", filename); + 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); diff --git a/src/token.c b/src/token.c index f2ab0a54..c3948d56 100644 --- a/src/token.c +++ b/src/token.c @@ -235,11 +235,9 @@ char *get_generator_command(const char *str) int match_symbol(const char *name) /* never returns -1, if symbol not found load systemlib/missing.sym */ { - int i,found, is_sym_generator; + int i,found; found=0; - is_sym_generator = is_generator(name); - for(i=0;isymbols; ++i) { /* dbg(1, "match_symbol(): name=%s, sym[i].name=%s\n",name, xctx->sym[i].name);*/ if(xctx->x_strcmp(name, xctx->sym[i].name) == 0) @@ -249,26 +247,8 @@ int match_symbol(const char *name) /* never returns -1, if symbol not found loa } } if(!found) { - dbg(1, "match_symbol(): matching symbol not found: loading\n"); - if(is_sym_generator) { - FILE *fp; - char *cmd; - - cmd = get_generator_command(name); - if(cmd) { - fp = popen(cmd, "r"); /* execute ss="/path/to/xxx par1 par2 ..." and pipe in the stdout */ - my_free(_ALLOC_ID_, &cmd); - load_sym_def(name, fp, 1); /* append another symbol to the xctx->sym[] array */ - dbg(1, "match_symbol(): generator symbol name=%s\n", xctx->sym[xctx->symbols - 1].name); - pclose(fp); - } else { - i = xctx->symbols; /* not found */ - } - } else { - dbg(1, "match_symbol(): symbol=%s\n",name); - load_sym_def(name, NULL, 0); /* append another symbol to the xctx->sym[] array */ - dbg(1, "match_symbol(): symbol name=%s\n", xctx->sym[xctx->symbols - 1].name); - } + dbg(1, "match_symbol(): matching symbol not found: loading %s\n", name); + load_sym_def(name, NULL); /* append another symbol to the xctx->sym[] array */ } dbg(1, "match_symbol(): returning %d\n",i); return i; diff --git a/src/verilog_netlist.c b/src/verilog_netlist.c index c6fe7a34..6e497991 100644 --- a/src/verilog_netlist.c +++ b/src/verilog_netlist.c @@ -215,7 +215,7 @@ int global_verilog_netlist(int global) /* netlister driver */ /* 20071006 print top level params if defined in symbol */ str_tmp = add_ext(xctx->sch[xctx->currsch], ".sym"); if(!stat(str_tmp, &buf)) { - load_sym_def(str_tmp, NULL, 0); + load_sym_def(str_tmp, NULL); print_verilog_param(fd,xctx->symbols-1); /* added print top level params */ remove_symbol(xctx->symbols - 1); } diff --git a/src/vhdl_netlist.c b/src/vhdl_netlist.c index ee536108..c1a8b5d1 100644 --- a/src/vhdl_netlist.c +++ b/src/vhdl_netlist.c @@ -212,7 +212,7 @@ int global_vhdl_netlist(int global) /* netlister driver */ /* 20071009 print top level generics if defined in symbol */ str_tmp = add_ext(xctx->sch[xctx->currsch], ".sym"); if(!stat(str_tmp, &buf)) { - load_sym_def(str_tmp, NULL, 0); + load_sym_def(str_tmp, NULL); print_generic(fd,"entity", xctx->symbols-1); /* added print top level params */ remove_symbol(xctx->symbols - 1); } else { diff --git a/src/xschem.h b/src/xschem.h index adb01412..b5a8b64b 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1275,7 +1275,7 @@ extern int spice_block_netlist(FILE *fd, int i); extern void remove_symbols(void); extern void remove_symbol(int i); extern void clear_drawing(void); -extern int load_sym_def(const char name[], FILE *embed_fd, int embedded); +extern int load_sym_def(const char name[], FILE *embed_fd); extern void descend_symbol(void); extern int place_symbol(int pos, const char *symbol_name, double x, double y, short rot, short flip, const char *inst_props, int draw_sym, int first_call, int to_push_undo); diff --git a/xschem_library/examples/0_examples_top.sch b/xschem_library/examples/0_examples_top.sch index cedc66a9..674bd73d 100644 --- a/xschem_library/examples/0_examples_top.sch +++ b/xschem_library/examples/0_examples_top.sch @@ -1468,3 +1468,4 @@ C {test_extracted_netlist.sym} 160 -130 0 0 {name=x23 tclcommand="xschem descend"} C {poweramp_lcc.sym} 480 -650 0 0 {name=x16 tclcommand="xschem descend"} +C {test_symbolgen.sym} 480 -530 0 0 {name=x18} diff --git a/xschem_library/generators/my_inv.sym b/xschem_library/generators/my_inv.sym index aaf3be29..2b0e976b 100644 --- a/xschem_library/generators/my_inv.sym +++ b/xschem_library/generators/my_inv.sym @@ -13,9 +13,10 @@ L 4 -20 -20 20 0 {} 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 } -A 4 25 -0 5 180 360 {} +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 {} diff --git a/xschem_library/generators/symbolgen b/xschem_library/generators/symbolgen index 874565b4..768a8690 100755 --- a/xschem_library/generators/symbolgen +++ b/xschem_library/generators/symbolgen @@ -25,7 +25,6 @@ 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 {ROUT=@ROUT} -25 -42 0 0 0.2 0.2 {} } } else { puts {v {xschem version=3.1.0 file_version=1.2} @@ -48,6 +47,5 @@ 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 {ROUT=@ROUT} -25 -42 0 0 0.2 0.2 {} } } diff --git a/xschem_library/generators/test_symbolgen.sch b/xschem_library/generators/test_symbolgen.sch index 8f784f50..4d931792 100644 --- a/xschem_library/generators/test_symbolgen.sch +++ b/xschem_library/generators/test_symbolgen.sch @@ -5,16 +5,16 @@ K {} V {} S {} E {} -B 2 560 -400 1170 -150 {flags=graph +B 2 20 -380 660 -110 {flags=graph y1=0 y2=3 -ypos1=0.157569 -ypos2=1.98753 +ypos1=0.0732701 +ypos2=1.90323 divy=5 subdivy=1 unity=1 -x1=1e-11 -x2=3e-07 +x1=-5.76971e-09 +x2=2.9422e-07 divx=5 subdivx=1 node="in @@ -28,43 +28,58 @@ unitx=1 logx=0 logy=0 digital=1} -T {The two below symbols are created by a 'symbolgen' script -that takes a 'buf' or 'inv' argument.} 200 -640 0 0 0.6 0.6 {} +T {The two below symbols are +created by a 'symbolgen' script +that takes a 'buf' or 'inv' +argument. Schematic also +created by a 'schematicgen' +script.} 30 -830 0 0 0.5 0.5 {} T {Click on symbol with Control key -pressed to see the generator script} 130 -340 0 0 0.3 0.3 {} -N 70 -250 70 -180 { +pressed to see the generator script} 90 -620 0 0 0.3 0.3 {} +T {The two below symbols have a +schematic created by a +'schematicgen' script +that takes a 'buf' or 'inv' +argument.} 830 -830 0 0 0.5 0.5 {} +T {Click on symbol with Control key +pressed to see the generator script} 900 -620 0 0 0.3 0.3 {} +N 30 -560 30 -520 { lab=IN} -N 70 -250 150 -250 { +N 30 -560 110 -560 { lab=IN} -N 70 -180 70 -120 { +N 30 -520 30 -460 { lab=IN} -N 70 -120 150 -120 { +N 30 -460 110 -460 { lab=IN} -N 230 -250 350 -250 { +N 190 -560 310 -560 { lab=IN_BUF} -N 230 -120 350 -120 { +N 190 -460 310 -460 { lab=IN_INV} -N 600 -470 630 -470 { -lab=IN} -N 710 -470 740 -470 { +N 1000 -460 1120 -460 { lab=IN_INV2} -N 890 -470 920 -470 { -lab=IN} -N 1000 -470 1030 -470 { +N 1000 -560 1120 -560 { lab=IN_BUF2} -N 500 -310 500 -280 { +N 620 -470 620 -440 { lab=VCC} -C {symbolgen(inv)} 190 -120 0 0 {name=x1 +N 840 -560 840 -520 { +lab=IN} +N 840 -560 920 -560 { +lab=IN} +N 840 -520 840 -460 { +lab=IN} +N 840 -460 920 -460 { +lab=IN} +C {symbolgen(inv)} 150 -460 0 0 {name=x1 tclcommand="edit_file [abs_sym_path symbolgen]" ROUT=1200} -C {lab_pin.sym} 70 -180 0 0 {name=p1 lab=IN} -C {symbolgen(buf)} 190 -250 0 0 {name=x3 +C {lab_pin.sym} 30 -520 0 0 {name=p1 lab=IN} +C {symbolgen(buf)} 150 -560 0 0 {name=x3 tclcommand="edit_file [abs_sym_path symbolgen]" ROUT=1200} -C {lab_pin.sym} 350 -250 0 1 {name=p2 lab=IN_BUF} -C {lab_pin.sym} 350 -120 0 1 {name=p3 lab=IN_INV} +C {lab_pin.sym} 310 -560 0 1 {name=p2 lab=IN_BUF} +C {lab_pin.sym} 310 -460 0 1 {name=p3 lab=IN_INV} C {title.sym} 160 -30 0 0 {name=l1 author="Stefan Schippers"} -C {code_shown.sym} 40 -540 0 0 {name=CONTROL +C {code_shown.sym} 730 -370 0 0 {name=CONTROL tclcommand="xschem edit_vi_prop" xxplace=end value=".include models_rom8k.txt @@ -77,19 +92,22 @@ Vin in 0 pwl 0 0 100n 0 100.1n 3 200n 3 200.1n 0 write test_symbolgen.raw .endc "} -C {parax_cap.sym} 280 -240 0 0 {name=C1 gnd=0 value=100f m=1} -C {parax_cap.sym} 280 -110 0 0 {name=C2 gnd=0 value=100f m=1} -C {launcher.sym} 620 -130 0 0 {name=h5 +C {parax_cap.sym} 240 -550 0 0 {name=C1 gnd=0 value=100f m=1} +C {parax_cap.sym} 240 -450 0 0 {name=C2 gnd=0 value=100f m=1} +C {launcher.sym} 80 -80 0 0 {name=h5 descr="load waves" tclcommand="xschem raw_read $netlist_dir/test_symbolgen.raw tran" } -C {my_inv.sym} 670 -470 0 0 {name=x2 ROUT=1000 -schematic=schematicgen(inv)} -C {lab_pin.sym} 600 -470 0 0 {name=p4 lab=IN} -C {lab_pin.sym} 740 -470 0 1 {name=p5 lab=IN_INV2} -C {my_inv.sym} 960 -470 0 0 {name=x4 ROUT=1000 -schematic=schematicgen(buf)} -C {lab_pin.sym} 890 -470 0 0 {name=p6 lab=IN} -C {lab_pin.sym} 1030 -470 0 1 {name=p7 lab=IN_BUF2} -C {vdd.sym} 500 -310 0 0 {name=l2 lab=VCC} -C {lab_pin.sym} 500 -280 0 1 {name=p8 lab=VCC} +C {my_inv.sym} 960 -460 0 0 {name=x2 ROUT=1000 +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) +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} +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}