spice netlisting of schematics with parametrized symbol generators should work

This commit is contained in:
stefan schippers 2023-04-23 00:37:31 +02:00
parent bbb5363da9
commit 3facbf6428
9 changed files with 67 additions and 15 deletions

View File

@ -216,17 +216,23 @@ int set_netlist_dir(int force, char *dir)
}
return 1;
}
/* wrapper to TCL function */
/* remove parameter section of symbol generator before calculating abs path : xxx(a,b) -> xxx */
const char *sanitized_abs_sym_path(const char *s, const char *ext)
{
char c[PATH_MAX+1000];
my_snprintf(c, S(c), "abs_sym_path [regsub {\\(.*} {%s} {}] {%s}", s, ext);
tcleval(c);
return tclresult();
}
/* wrapper to TCL function */
const char *abs_sym_path(const char *s, const char *ext)
{
char c[PATH_MAX+1000];
if(is_symgen(s)) {
my_snprintf(c, S(c), "abs_sym_path [regsub {\\(.*} {%s} {}] {%s}", s, ext);
} else {
my_snprintf(c, S(c), "abs_sym_path {%s} {%s}", s, ext);
}
my_snprintf(c, S(c), "abs_sym_path {%s} {%s}", s, ext);
tcleval(c);
return tclresult();
}
@ -1215,6 +1221,7 @@ const char *get_sym_name(int inst, int ext)
} else {
sym = skip_dir(xctx->inst[inst].name);
}
dbg(1, "get_sym_name(): returning sym=%s\n", sym);
return sym;
}
@ -1559,6 +1566,7 @@ void go_back(int confirm) /* 20171006 add confirm */
int prev_sch_type;
save_ok=1;
dbg(1,"go_back(): sch[xctx->currsch]=%s\n", xctx->sch[xctx->currsch]);
prev_sch_type = xctx->netlist_type; /* if CAD_SYMBOL_ATTRS do not hilight_parent_pins */
if(xctx->currsch>0)
{

View File

@ -1094,6 +1094,25 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
} /* switch */
}
}
/* get_cell cell n_dirs
* return result of get_cell function */
else if(!strcmp(argv[1], "get_cell") )
{
if(argc > 3) {
Tcl_SetResult(interp, (char *)get_cell(argv[2], atoi(argv[3])), TCL_VOLATILE);
}
}
/* get_cell_w_ext cell n_dirs
* return result of get_cell_w_ext function */
else if(!strcmp(argv[1], "get_cell_w_ext") )
{
if(argc > 3) {
Tcl_SetResult(interp, (char *)get_cell_w_ext(argv[2], atoi(argv[3])), TCL_VOLATILE);
}
}
/************ end xschem get subcommands *************/
/* getprop instance|instance_pin|symbol|text ref
*

View File

@ -552,13 +552,15 @@ int spice_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,"spice_sym_def",0);
if(sym_def[0]) {
fprintf(fd, "%s\n", sym_def);
} else {
char *s = sanitize(skip_dir(xctx->sym[i].name));
fprintf(fd, "** sch_path: %s\n", filename);
fprintf(fd, ".subckt %s ",skip_dir(xctx->sym[i].name));
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) );

View File

@ -187,6 +187,17 @@ int is_symgen(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)
{
char *s = NULL;
tclvareval("regsub -all { *[(),] *} {", name, "} _", NULL);
tclvareval("regsub {_$} {", tclresult(), "} {}", NULL);
my_strdup2(_ALLOC_ID_, &s, tclresult());
return s;
}
int match_symbol(const char *name) /* never returns -1, if symbol not found load systemlib/missing.sym */
{
int i,found;
@ -215,25 +226,34 @@ int match_symbol(const char *name) /* never returns -1, if symbol not found loa
const char *s;
char *spc_idx;
struct stat buf;
/* char *symgen_name = NULL; */
dbg(1, "match_symbol(): symgen=%s\n",name);
cmd = str_chars_replace(name, " (),", ' ');
cmd = str_chars_replace(name, " (),", ' '); /* transform name="xxx(a,b,c)" into ss="xxx a b c" */
spc_idx = strchr(cmd, ' ');
if(!spc_idx) goto end;
*spc_idx = '\0';
s = abs_sym_path(cmd, "");
if(stat(s, &buf)) {
if(stat(s, &buf)) { /* symbol generator not found, load 'name' (will probably lead to missing.sym) */
load_sym_def(name, NULL, 0);
goto end;
}
my_strdup(_ALLOC_ID_, &ss, s);
*spc_idx = ' ';
my_strcat(_ALLOC_ID_, &ss, spc_idx);
fp = popen(ss, "r");
fp = popen(ss, "r"); /* execute ss="xxx a b c" and pipe in the output */
dbg(1, "match_symbol(): fp=%p\n", fp);
dbg(1, "match_symbol(): s=%s\n", s);
dbg(1, "match_symbol(): ss=%s\n", ss);
dbg(1, "match_symbol(): is_symgen=%d\n", is_symgen(name));
/*
tclvareval("regsub -all { *[(),] *} {", name, "} _", NULL);
tclvareval("regsub {_$} {", tclresult(), "} {}", NULL);
my_strdup2(_ALLOC_ID_, &symgen_name, tclresult());
load_sym_def(symgen_name, fp, 1);
dbg(1, "match_symbol(): name=%s, regsub=%s\n", name, symgen_name);
my_free(_ALLOC_ID_, &symgen_name);
*/
load_sym_def(name, fp, 1);
dbg(1, "match_symbol(): symbol name%s\n", xctx->sym[xctx->symbols - 1].name);
pclose(fp);
@ -1861,11 +1881,12 @@ int print_spice_element(FILE *fd, int inst)
}
else if (strcmp(token,"@symname")==0) /* of course symname must not be present in attributes */
{
const char *s = get_sym_name(inst, 0);
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 */

View File

@ -1157,6 +1157,8 @@ extern const char *get_cell(const char *str, int no_of_dir);
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 *add_ext(const char *f, const char *ext);
extern void make_symbol(void);
/* sort based on pinnumber pin attribute if present */

View File

@ -19,7 +19,7 @@ C {bsource.sym} 480 -330 0 1 {name=B1 VAR=V FUNC="'VCC/2*(1+tanh((min(V(C1),min(
C {lab_pin.sym} 310 -400 0 0 {name=l2 sig_type=std_logic lab=A1}
C {lab_pin.sym} 480 -250 0 0 {name=l3 sig_type=std_logic lab=0}
C {res.sym} 580 -400 1 0 {name=R1
value=ROUT
value='ROUT'
footprint=1206
device=resistor
m=1}

View File

@ -18,7 +18,7 @@ C {bsource.sym} 480 -330 0 1 {name=B1 VAR=V FUNC="'VCC/2*(1+tanh((min(V(A1),V(B1
C {lab_pin.sym} 330 -400 0 0 {name=l2 sig_type=std_logic lab=A1}
C {lab_pin.sym} 480 -250 0 0 {name=l3 sig_type=std_logic lab=0}
C {res.sym} 580 -400 1 0 {name=R1
value=ROUT
value='ROUT'
footprint=1206
device=resistor
m=1}

View File

@ -18,7 +18,7 @@ C {bsource.sym} 470 -400 0 1 {name=B1 VAR=V FUNC="'VCC/2*(1+tanh((V(A1)-VCC/2)*1
C {lab_pin.sym} 320 -470 0 0 {name=l2 sig_type=std_logic lab=A1}
C {lab_pin.sym} 470 -320 0 0 {name=l3 sig_type=std_logic lab=0}
C {res.sym} 570 -470 1 0 {name=R1
value=ROUT
value='ROUT'
footprint=1206
device=resistor
m=1}

View File

@ -18,7 +18,7 @@ C {bsource.sym} 470 -400 0 1 {name=B1 VAR=V FUNC="'VCC/2*(1-tanh((V(A1)-VCC/2)*1
C {lab_pin.sym} 320 -470 0 0 {name=l2 sig_type=std_logic lab=A1}
C {lab_pin.sym} 470 -320 0 0 {name=l3 sig_type=std_logic lab=0}
C {res.sym} 570 -470 1 0 {name=R1
value=ROUT
value='ROUT'
footprint=1206
device=resistor
m=1}