From c71c15e96747689192cf826c47f328462ee76db7 Mon Sep 17 00:00:00 2001
From: stefan schippers
Date: Thu, 13 Apr 2023 00:49:38 +0200
Subject: [PATCH] various enhancements around the new instance based
schematic=... attribute, doc updates.
---
doc/xschem_man/component_property_syntax.html | 10 +++++++
src/actions.c | 4 +--
src/spice_netlist.c | 12 ++++++---
src/tedax_netlist.c | 27 ++++++++++++++++---
src/verilog_netlist.c | 9 +++++--
src/vhdl_netlist.c | 10 +++++--
src/xschem.tcl | 3 ++-
7 files changed, 60 insertions(+), 15 deletions(-)
diff --git a/doc/xschem_man/component_property_syntax.html b/doc/xschem_man/component_property_syntax.html
index b3e4aaa6..528a1b02 100644
--- a/doc/xschem_man/component_property_syntax.html
+++ b/doc/xschem_man/component_property_syntax.html
@@ -178,6 +178,16 @@ name="mchanged_name" model=\"nmos\" w="20u" l="3u" m="10"
in the symbol if any.
+ schematic
+
+ This attribute specifies an alternate schematic file to open when descending into the subcircuit.
+ This is done only for the specific instance allowing to differentiate implementation ona specific
+ instance of a given subcircuit.
+ The specified schematic must have the same interface (in/out/inout pins) as the base schematic (that
+ is inferred from the symbol name).
+ Example: schematic=sky130_tests/inv2.sym
+
+
pinnumber(name)
This will override at instance level the value of attribute pinnumber of pin name of the symbol.
This is mainly used for tedax, where by back annotation a connection to a symbol must be changed.
diff --git a/src/actions.c b/src/actions.c
index 6ba7aed1..2c0d41e5 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -1198,8 +1198,8 @@ const char *get_sym_name(int inst, int ext)
/* what = 1: start
- what = 0 : end
-*/
+ * what = 0 : end
+ */
void get_additional_symbols(int what)
{
int i;
diff --git a/src/spice_netlist.c b/src/spice_netlist.c
index 6a4c7d6c..6856d01c 100644
--- a/src/spice_netlist.c
+++ b/src/spice_netlist.c
@@ -399,9 +399,8 @@ int global_spice_netlist(int global) /* netlister driver */
my_strcat(_ALLOC_ID_, &xctx->sch_path[xctx->currsch+1], "->netlisting");
xctx->sch_path_hash[xctx->currsch+1] = 0;
xctx->currsch++;
-
- dbg(1, "global_spice_netlist(): last defined symbol=%d\n",xctx->symbols);
subckt_name=NULL;
+ dbg(2, "global_spice_netlist(): last defined symbol=%d\n",xctx->symbols);
get_additional_symbols(1);
for(i=0;isymbols; ++i)
{
@@ -410,6 +409,8 @@ int global_spice_netlist(int global) /* netlister driver */
my_strdup(_ALLOC_ID_, &abs_path, abs_sym_path(xctx->sym[i].name, ""));
if(strcmp(xctx->sym[i].type,"subcircuit")==0 && check_lib(1, abs_path))
{
+ tclvareval("get_directory ", xctx->sch[xctx->currsch - 1], NULL);
+ my_strncpy(xctx->current_dirname, tclresult(), S(xctx->current_dirname));
/* xctx->sym can be SCH or SYM, use hash to avoid writing duplicate subckt */
my_strdup(_ALLOC_ID_, &subckt_name, get_cell(xctx->sym[i].name, 0));
if (str_hash_lookup(&subckt_table, subckt_name, "", XLOOKUP)==NULL)
@@ -530,7 +531,8 @@ int spice_block_netlist(FILE *fd, int i)
/* int multip; */
char *extra=NULL;
int split_f;
- const char *sym_def;
+ const char *sym_def, *sympath;
+ struct stat buf;
split_f = tclgetboolvar("split_files");
@@ -549,7 +551,9 @@ 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] );
- fprintf(fd, "** sym_path: %s\n", abs_sym_path(xctx->sym[i].name, ""));
+ sympath = abs_sym_path(xctx->sym[i].name, "");
+ if(!stat(sympath, &buf)) fprintf(fd, "** sym_path: %s\n", abs_sym_path(xctx->sym[i].name, ""));
+ else fprintf(fd, "** sym_path: %s\n", xctx->sym[i].name);
sym_def = get_tok_value(xctx->sym[i].prop_ptr,"spice_sym_def",0);
if(sym_def[0]) {
diff --git a/src/tedax_netlist.c b/src/tedax_netlist.c
index da8c76f7..f1ea9671 100644
--- a/src/tedax_netlist.c
+++ b/src/tedax_netlist.c
@@ -81,6 +81,8 @@ static int tedax_block_netlist(FILE *fd, int i)
int tedax_stop=0;
char filename[PATH_MAX];
char *extra=NULL;
+ const char *sympath;
+ struct stat buf;
if(!strcmp( get_tok_value(xctx->sym[i].prop_ptr,"tedax_stop",0),"true") )
tedax_stop=1;
@@ -90,7 +92,9 @@ static int tedax_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] );
- fprintf(fd, "## sym_path: %s\n", abs_sym_path(xctx->sym[i].name, ""));
+ sympath = abs_sym_path(xctx->sym[i].name, "");
+ if(!stat(sympath, &buf)) fprintf(fd, "## sym_path: %s\n", abs_sym_path(xctx->sym[i].name, ""));
+ else fprintf(fd, "## sym_path: %s\n", xctx->sym[i].name);
fprintf(fd, "## sch_path: %s\n", filename);
fprintf(fd, "begin netlist v1 %s\n",skip_dir(xctx->sym[i].name));
@@ -129,10 +133,13 @@ int global_tedax_netlist(int global) /* netlister driver */
char netl_filename[PATH_MAX]; /* overflow safe 20161122 */
char tcl_cmd_netlist[PATH_MAX + 100]; /* 20081211 overflow safe 20161122 */
char cellname[PATH_MAX]; /* 20081211 overflow safe 20161122 */
+ char *subckt_name;
char *abs_path = NULL;
+ Str_hashtable subckt_table = {NULL, 0};
xctx->push_undo();
statusmsg("",2); /* clear infowindow */
+ str_hash_init(&subckt_table, HASHSIZE);
record_global_node(2, NULL, NULL); /* delete list of global nodes */
bus_char[0] = bus_char[1] = '\0';
xctx->hiersep[0]='.'; xctx->hiersep[1]='\0';
@@ -196,8 +203,9 @@ int global_tedax_netlist(int global) /* netlister driver */
my_strcat(_ALLOC_ID_, &xctx->sch_path[xctx->currsch+1], "->netlisting");
xctx->sch_path_hash[xctx->currsch+1] = 0;
xctx->currsch++;
-
- dbg(2, "global_tedax_netlist(): last defined symbol=%d\n",xctx->symbols);
+ subckt_name=NULL;
+ dbg(2, "global_tedax_netlist(): last defined symbol=%d\n",xctx->symbols);
+ get_additional_symbols(1);
for(i=0;isymbols; ++i)
{
if( strcmp(get_tok_value(xctx->sym[i].prop_ptr,"tedax_ignore",0),"true")==0 ) continue;
@@ -205,10 +213,21 @@ int global_tedax_netlist(int global) /* netlister driver */
my_strdup2(_ALLOC_ID_, &abs_path, abs_sym_path(xctx->sym[i].name, ""));
if(strcmp(xctx->sym[i].type,"subcircuit")==0 && check_lib(1, abs_path))
{
- err |= tedax_block_netlist(fd, i);
+ tclvareval("get_directory ", xctx->sch[xctx->currsch - 1], NULL);
+ my_strncpy(xctx->current_dirname, tclresult(), S(xctx->current_dirname));
+ /* xctx->sym can be SCH or SYM, use hash to avoid writing duplicate subckt */
+ 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);
+ err |= tedax_block_netlist(fd, i);
+ }
}
}
my_free(_ALLOC_ID_, &abs_path);
+ get_additional_symbols(0);
+ str_hash_free(&subckt_table);
+ my_free(_ALLOC_ID_, &subckt_name);
/*clear_drawing(); */
my_strncpy(xctx->sch[xctx->currsch] , "", S(xctx->sch[xctx->currsch]));
xctx->currsch--;
diff --git a/src/verilog_netlist.c b/src/verilog_netlist.c
index 2420b4ea..343a2e0f 100644
--- a/src/verilog_netlist.c
+++ b/src/verilog_netlist.c
@@ -358,6 +358,8 @@ int global_verilog_netlist(int global) /* netlister driver */
if(!xctx->sym[i].type) continue;
my_strdup2(_ALLOC_ID_, &abs_path, abs_sym_path(xctx->sym[i].name, ""));
if(strcmp(xctx->sym[i].type,"subcircuit")==0 && check_lib(1, abs_path)) {
+ tclvareval("get_directory ", xctx->sch[xctx->currsch - 1], NULL);
+ my_strncpy(xctx->current_dirname, tclresult(), S(xctx->current_dirname));
/* xctx->sym can be SCH or SYM, use hash to avoid writing duplicate subckt */
my_strdup(_ALLOC_ID_, &subckt_name, get_cell(xctx->sym[i].name, 0));
if (str_hash_lookup(&subckt_table, subckt_name, "", XLOOKUP)==NULL)
@@ -430,7 +432,8 @@ int verilog_block_netlist(FILE *fd, int i)
char cellname[PATH_MAX];
const char *str_tmp, *fmt_attr = NULL;
int split_f;
- const char *sym_def;
+ const char *sym_def, *sympath;
+ struct stat buf;
char *extra_ptr, *saveptr1, *extra_token, *extra = NULL, *extra2=NULL;
@@ -452,7 +455,9 @@ int verilog_block_netlist(FILE *fd, int i)
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] );
- fprintf(fd, "// sym_path: %s\n", abs_sym_path(xctx->sym[i].name, ""));
+ sympath = abs_sym_path(xctx->sym[i].name, "");
+ if(!stat(sympath, &buf)) fprintf(fd, "// sym_path: %s\n", abs_sym_path(xctx->sym[i].name, ""));
+ else fprintf(fd, "// sym_path: %s\n", xctx->sym[i].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);
diff --git a/src/vhdl_netlist.c b/src/vhdl_netlist.c
index f77fd445..9c01f219 100644
--- a/src/vhdl_netlist.c
+++ b/src/vhdl_netlist.c
@@ -458,6 +458,8 @@ int global_vhdl_netlist(int global) /* netlister driver */
my_strdup(_ALLOC_ID_, &abs_path, abs_sym_path(xctx->sym[i].name, ""));
if(strcmp(xctx->sym[i].type,"subcircuit")==0 && check_lib(1, abs_path))
{
+ tclvareval("get_directory ", xctx->sch[xctx->currsch - 1], NULL);
+ my_strncpy(xctx->current_dirname, tclresult(), S(xctx->current_dirname));
/* xctx->sym can be SCH or SYM, use hash to avoid writing duplicate subckt */
my_strdup(_ALLOC_ID_, &subckt_name, get_cell(xctx->sym[i].name, 0));
if (str_hash_lookup(&subckt_table, subckt_name, "", XLOOKUP)==NULL)
@@ -527,7 +529,8 @@ int vhdl_block_netlist(FILE *fd, int i)
char *abs_path = NULL;
const char *str_tmp;
int split_f;
- const char *sym_def;
+ const char *sym_def, *sympath;
+ struct stat buf;
split_f = tclgetboolvar("split_files");
if(!strcmp( get_tok_value(xctx->sym[i].prop_ptr,"vhdl_stop",0),"true") )
@@ -547,7 +550,10 @@ int vhdl_block_netlist(FILE *fd, int i)
dbg(1, "vhdl_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] );
- fprintf(fd, "-- sym_path: %s\n", abs_sym_path(xctx->sym[i].name, ""));
+ sympath = abs_sym_path(xctx->sym[i].name, "");
+ if(!stat(sympath, &buf)) fprintf(fd, "-- sym_path: %s\n", abs_sym_path(xctx->sym[i].name, ""));
+ else fprintf(fd, "-- sym_path: %s\n", 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);
diff --git a/src/xschem.tcl b/src/xschem.tcl
index cf7fa822..138c3ba4 100644
--- a/src/xschem.tcl
+++ b/src/xschem.tcl
@@ -4464,7 +4464,8 @@ proc sub_match_file { f {paths {}} } {
if {$sub_res != {} } {set res [concat $res $sub_res]}
}
} else {
- set fname [file tail $j]
+ # set fname [file tail $j]
+ set fname $j
if {[regexp $f $fname]} {
lappend res $j
}