attribute default_schematic=ignore: if set in a symbol xschem will not descend into the default schematic associated to symbol. Instances MUST specify a schematic attribute

This commit is contained in:
stefan schippers 2023-12-02 13:17:32 +01:00
parent 5cb5ec9031
commit b2965f4c3d
8 changed files with 85 additions and 15 deletions

View File

@ -192,10 +192,14 @@ type=nmos
<li><kbd>spice_primitive</kbd></li>
<li><kbd>vhdl_primitive</kbd></li>
<li><kbd>verilog_primitive</kbd></li>
<p> same as above <kbd>_stop</kbd> attributes, but in this case the schematic subcircuit is completely ignored,
<p> Same as above <kbd>_stop</kbd> attributes, but in this case the schematic subcircuit is completely ignored,
only the 'format' string is dumped to netlist. No component/entity is generated in vhdl netlist,
no module declaration in verilog, no .subckt in spice, no schematic global attributes are exported to netlist.</p>
<li><kbd>default_schematic</kbd></li>
<p> If set to <kbd>ignore</kbd> xschem will not descend into the symbol associated schematic and will
not complain if this schematic does not exists. To descend into a schematic instances must specify a
<kbd>schematic</kbd> attribute, otherwise no descendng and expansion occurs.</p>
<li><kbd>spice_sym_def</kbd></li>
<li><kbd>verilog_sym_def</kbd></li>

View File

@ -1849,8 +1849,10 @@ void get_additional_symbols(int what)
char *spice_sym_def = NULL;
char *vhdl_sym_def = NULL;
char *verilog_sym_def = NULL;
char *default_schematic = NULL;
char *sch = NULL;
/* copy instance based *_sym_def attributes to symbol */
my_strdup(_ALLOC_ID_, &spice_sym_def, get_tok_value(xctx->inst[i].prop_ptr,"spice_sym_def",0));
my_strdup(_ALLOC_ID_, &verilog_sym_def, get_tok_value(xctx->inst[i].prop_ptr,"verilog_sym_def",0));
my_strdup(_ALLOC_ID_, &vhdl_sym_def, get_tok_value(xctx->inst[i].prop_ptr,"vhdl_sym_def",0));
@ -1858,9 +1860,13 @@ void get_additional_symbols(int what)
str_replace( get_tok_value(xctx->inst[i].prop_ptr,"schematic",2), "@symname",
get_cell(xctx->inst[i].name, 0), '\\')));
dbg(1, "get_additional_symbols(): sch=%s\n", sch);
if(xctx->tok_size) { /* token exists */
if(xctx->tok_size && xctx->inst[i].ptr>= 0) { /* token exists and instance points to valid symbol */
int j;
char *sym = NULL;
int ignore_schematic = 0;
xSymbol *symptr = xctx->inst[i].ptr + xctx->sym;
my_strdup2(_ALLOC_ID_, &default_schematic, get_tok_value(symptr->prop_ptr,"default_schematic",0));
ignore_schematic = !strcmp(default_schematic, "ignore");
dbg(1, "get_additional_symbols(): inst=%d, sch=%s\n", i, sch);
if(is_generator(sch)) {
@ -1870,15 +1876,23 @@ void get_additional_symbols(int what)
my_strdup2(_ALLOC_ID_, &sym, add_ext(rel_sym_path(sch), ".sym"));
}
found = int_hash_lookup(&sym_table, sym, 0, XLOOKUP);
/* if instance symbol has ignore_schematic set to ignore copy the symbol anyway, since
* the base symbol will not be netlisted by *_block_netlist() */
found = ignore_schematic ? NULL : int_hash_lookup(&sym_table, sym, 0, XLOOKUP);
if(!found) {
j = xctx->symbols;
int_hash_lookup(&sym_table, sym, j, XINSERT);
dbg(1, "get_additional_symbols(): adding symbol %s\n", sym);
check_symbol_storage();
copy_symbol(&xctx->sym[j], xctx->inst[i].ptr + xctx->sym);
xctx->sym[j].base_name = (xctx->inst[i].ptr + xctx->sym)->name;
copy_symbol(&xctx->sym[j], symptr);
xctx->sym[j].base_name = symptr->name;
my_strdup(_ALLOC_ID_, &xctx->sym[j].name, sym);
/* the copied symbol will not inherit the default_schematic attribute otherwise it will also
* be skipped */
if(default_schematic) {
my_strdup(_ALLOC_ID_, &xctx->sym[j].prop_ptr,
subst_token(xctx->sym[j].prop_ptr, "default_schematic", NULL)); /* delete attribute */
}
if(spice_sym_def)
my_strdup(_ALLOC_ID_, &xctx->sym[j].prop_ptr,
subst_token(xctx->sym[j].prop_ptr, "spice_sym_def", spice_sym_def));
@ -1893,6 +1907,7 @@ void get_additional_symbols(int what)
j = found->value;
}
my_free(_ALLOC_ID_, &sym);
my_free(_ALLOC_ID_, &default_schematic);
}
my_free(_ALLOC_ID_, &sch);
my_free(_ALLOC_ID_, &spice_sym_def);

View File

@ -93,7 +93,17 @@ void hier_psprint(char **res, int what) /* netlister driver */
get_sch_from_sym(filename, xctx->sym + i, -1);
if (str_hash_lookup(&subckt_table, filename, "", XLOOKUP)==NULL)
{
str_hash_lookup(&subckt_table, filename, "", XINSERT);
const char *default_schematic;
/* do not insert symbols with default_schematic attribute set to ignore in hash since these symbols
* will not be processed by *_block_netlist() */
if(strcmp(get_tok_value(xctx->sym[i].prop_ptr, "default_schematic", 0), "ignore"))
str_hash_lookup(&subckt_table, subckt_name, "", XINSERT);
default_schematic = get_tok_value(xctx->sym[i].prop_ptr, "default_schematic", 0);
if(!strcmp(default_schematic, "ignore")) {
continue;
}
if(is_generator(filename) || !stat(filename, &buf)) {
/* for printing we go down to bottom regardless of spice_stop attribute */
dbg(1, "hier_psprint(): loading file: |%s|\n", filename);
@ -433,7 +443,10 @@ int global_spice_netlist(int global) /* netlister driver */
dbg(1, "global_spice_netlist(): subckt_name=%s\n", subckt_name);
if (str_hash_lookup(&subckt_table, subckt_name, "", XLOOKUP)==NULL)
{
str_hash_lookup(&subckt_table, subckt_name, "", XINSERT);
/* do not insert symbols with default_schematic attribute set to ignore in hash since these symbols
* will not be processed by *_block_netlist() */
if(strcmp(get_tok_value(xctx->sym[i].prop_ptr, "default_schematic", 0), "ignore"))
str_hash_lookup(&subckt_table, subckt_name, "", XINSERT);
if( split_f && strboolcmp(get_tok_value(xctx->sym[i].prop_ptr,"vhdl_netlist",0),"true")==0 )
err |= vhdl_block_netlist(fd, i);
else if(split_f && strboolcmp(get_tok_value(xctx->sym[i].prop_ptr,"verilog_netlist",0),"true")==0 )
@ -559,8 +572,8 @@ int spice_block_netlist(FILE *fd, int i)
int split_f;
const char *sym_def;
char *name = NULL;
const char *default_schematic;
my_strdup(_ALLOC_ID_, &name, tcl_hook2(xctx->sym[i].name));
split_f = tclgetboolvar("split_files");
if(!strboolcmp( get_tok_value(xctx->sym[i].prop_ptr,"spice_stop",0),"true") )
@ -568,6 +581,13 @@ int spice_block_netlist(FILE *fd, int i)
else
spice_stop=0;
get_sch_from_sym(filename, xctx->sym + i, -1);
default_schematic = get_tok_value(xctx->sym[i].prop_ptr, "default_schematic", 0);
if(!strcmp(default_schematic, "ignore")) {
return err;
}
my_strdup(_ALLOC_ID_, &name, tcl_hook2(xctx->sym[i].name));
dbg(1, "spice_block_netlist(): filename=%s\n", filename);
if(split_f) {
my_snprintf(netl_filename, S(netl_filename), "%s/.%s_%d",

View File

@ -75,6 +75,7 @@ static int tedax_block_netlist(FILE *fd, int i)
int tedax_stop=0;
char filename[PATH_MAX];
char *extra=NULL;
const char *default_schematic;
if(!strboolcmp( get_tok_value(xctx->sym[i].prop_ptr,"tedax_stop",0),"true") )
tedax_stop=1;
@ -82,6 +83,11 @@ static int tedax_block_netlist(FILE *fd, int i)
tedax_stop=0;
get_sch_from_sym(filename, xctx->sym + i, -1);
default_schematic = get_tok_value(xctx->sym[i].prop_ptr, "default_schematic", 0);
if(!strcmp(default_schematic, "ignore")) {
return err;
}
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, ""));
@ -220,7 +226,10 @@ int global_tedax_netlist(int global) /* netlister driver */
my_strdup(_ALLOC_ID_, &subckt_name, get_cell(xctx->sym[i].name, 0));
if (str_hash_lookup(&subckt_table, subckt_name, "", XLOOKUP)==NULL)
{
str_hash_lookup(&subckt_table, subckt_name, "", XINSERT);
/* do not insert symbols with default_schematic attribute set to ignore in hash since these symbols
* will not be processed by *_block_netlist() */
if(strcmp(get_tok_value(xctx->sym[i].prop_ptr, "default_schematic", 0), "ignore"))
str_hash_lookup(&subckt_table, subckt_name, "", XINSERT);
err |= tedax_block_netlist(fd, i);
}
}

View File

@ -41,7 +41,8 @@ proc traversal {file} {
proc spaces {n} {
set indent 4
set n [expr {$n * $indent}]
return [format %${n}s {}]
# return [format %${n}s {}]
return [string repeat { } $n]
}
# recursive procedure

View File

@ -343,7 +343,10 @@ int global_verilog_netlist(int global) /* netlister driver */
my_strdup(_ALLOC_ID_, &subckt_name, get_cell(xctx->sym[i].name, 0));
if (str_hash_lookup(&subckt_table, subckt_name, "", XLOOKUP)==NULL)
{
str_hash_lookup(&subckt_table, subckt_name, "", XINSERT);
/* do not insert symbols with default_schematic attribute set to ignore in hash since these symbols
* will not be processed by *_block_netlist() */
if(strcmp(get_tok_value(xctx->sym[i].prop_ptr, "default_schematic", 0), "ignore"))
str_hash_lookup(&subckt_table, subckt_name, "", XINSERT);
if( split_f && strboolcmp(get_tok_value(xctx->sym[i].prop_ptr,"vhdl_netlist",0),"true")==0 )
err |= vhdl_block_netlist(fd, i);
else if(split_f && strboolcmp(get_tok_value(xctx->sym[i].prop_ptr,"spice_netlist",0),"true")==0 )
@ -426,8 +429,8 @@ int verilog_block_netlist(FILE *fd, int i)
char *extra_ptr, *saveptr1, *extra_token, *extra = NULL, *extra2=NULL;
char *name = NULL;
int lvs_ignore = tclgetboolvar("lvs_ignore");
const char *default_schematic;
my_strdup(_ALLOC_ID_, &name, tcl_hook2(xctx->sym[i].name));
split_f = tclgetboolvar("split_files");
if(!strboolcmp( get_tok_value(xctx->sym[i].prop_ptr,"verilog_stop",0),"true") )
verilog_stop=1;
@ -435,6 +438,12 @@ int verilog_block_netlist(FILE *fd, int i)
verilog_stop=0;
get_sch_from_sym(filename, xctx->sym + i, -1);
default_schematic = get_tok_value(xctx->sym[i].prop_ptr, "default_schematic", 0);
if(!strcmp(default_schematic, "ignore")) {
return err;
}
my_strdup(_ALLOC_ID_, &name, tcl_hook2(xctx->sym[i].name));
if(split_f) {
my_snprintf(netl_filename, S(netl_filename), "%s/.%s_%d",
tclgetvar("netlist_dir"), get_cell(name, 0), getpid());

View File

@ -432,7 +432,10 @@ int global_vhdl_netlist(int global) /* netlister driver */
my_strdup(_ALLOC_ID_, &subckt_name, get_cell(xctx->sym[i].name, 0));
if (str_hash_lookup(&subckt_table, subckt_name, "", XLOOKUP)==NULL)
{
str_hash_lookup(&subckt_table, subckt_name, "", XINSERT);
/* do not insert symbols with default_schematic attribute set to ignore in hash since these symbols
* will not be processed by *_block_netlist() */
if(strcmp(get_tok_value(xctx->sym[i].prop_ptr, "default_schematic", 0), "ignore"))
str_hash_lookup(&subckt_table, subckt_name, "", XINSERT);
if( split_f && strboolcmp(get_tok_value(xctx->sym[i].prop_ptr,"verilog_netlist",0),"true")==0 )
err |= verilog_block_netlist(fd, i);
else if( split_f && strboolcmp(get_tok_value(xctx->sym[i].prop_ptr,"spice_netlist",0),"true")==0 )
@ -510,6 +513,7 @@ int vhdl_block_netlist(FILE *fd, int i)
int split_f;
const char *sym_def;
int lvs_ignore = tclgetboolvar("lvs_ignore");
const char *default_schematic;
split_f = tclgetboolvar("split_files");
if(!strboolcmp( get_tok_value(xctx->sym[i].prop_ptr,"vhdl_stop",0),"true") )
@ -518,6 +522,11 @@ int vhdl_block_netlist(FILE *fd, int i)
vhdl_stop=0;
get_sch_from_sym(filename, xctx->sym + i, -1);
default_schematic = get_tok_value(xctx->sym[i].prop_ptr, "default_schematic", 0);
if(!strcmp(default_schematic, "ignore")) {
return err;
}
if(split_f) {
my_snprintf(netl_filename, S(netl_filename), "%s/.%s_%d",
tclgetvar("netlist_dir"), get_cell(xctx->sym[i].name, 0), getpid());
@ -615,7 +624,11 @@ int vhdl_block_netlist(FILE *fd, int i)
get_additional_symbols(1);
for(j=0;j<xctx->symbols; ++j)
{
const char *default_schematic;
if( strboolcmp(get_tok_value(xctx->sym[j].prop_ptr,"vhdl_primitive",0),"true")==0 ) continue;
default_schematic = get_tok_value(xctx->sym[i].prop_ptr, "default_schematic", 0);
if(!strcmp(default_schematic, "ignore")) continue;
if(!xctx->sym[j].type || (strcmp(xctx->sym[j].type,"primitive")!=0 &&
strcmp(xctx->sym[j].type,"subcircuit")!=0))
continue;

View File

@ -194,7 +194,7 @@ proc netlist_test {} {
greycnt.sch verilog 3032956185
autozero_comp.sch spice 751826850
test_generators.sch spice 49312823
inst_sch_select.sch spice 801962545
inst_sch_select.sch spice 2444330953
test_bus_tap.sch spice 181420586
loading.sch vhdl 2975204502
mos_power_ampli.sch spice 125840804
@ -204,7 +204,6 @@ proc netlist_test {} {
test_doublepin.sch spice 4159808692
simulate_ff.sch spice 574849766
test_symbolgen.sch spice 2593807370
inst_sch_select.sch spice 801962545
test_mosgen.sch spice 21996225
} {
xschem set netlist_type $t