From cd41540c5d1d3bd26cf5f7a26b1b44d443c7c08d Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Tue, 19 Aug 2025 08:37:33 +0200 Subject: [PATCH] record_global_node(): handle ground nodes (spectre netlist only); use global=ground for nodes that need to be declared as ground nodes. Ground nodes in Spectre netlist are also considered global --- src/netlist.c | 49 ++++++++++++++++++++++++---------- src/scheduler.c | 3 ++- src/xinit.c | 1 + src/xschem.h | 1 + xschem_library/devices/gnd.sym | 5 ++-- 5 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/netlist.c b/src/netlist.c index 2c161bcf..73eb5952 100644 --- a/src/netlist.c +++ b/src/netlist.c @@ -694,34 +694,48 @@ static void print_wires(void) } #endif -/* store list of global nodes (global=1 set in symbol props) to be printed in netlist 28032003 */ -/* what: */ -/* 0: print list of global nodes and delete list */ -/* 1: add entry */ -/* 2: delete list only, no print */ -/* 3: look if node is a global */ +/* store list of global nodes (global=1 set in symbol props) to be printed in netlist 28032003 + * what: + * 0: print list of global nodes + * 1: add entry + * 4: add ground entry (it is also a global). for Spectre + * 2: delete list only, no print + * 3: look if node is a global + * return value: + * 1: global + * 2: ground (and global) + */ int record_global_node(int what, FILE *fp, const char *node) { int i; - if( what == 1 || what == 3) { + if( what == 1 || what == 3 || what == 4) { if(!node) return 0; - if(!strcmp(node, "0")) return 1; + if(!strcmp(node, "0")) return 2; for(i = 0;i < xctx->max_globals; ++i) { - if( !strcmp(node, xctx->globals[i] )) return 1; /* node is a global */ + if( !strcmp(node, xctx->globals[i] )) { + if(xctx->global_type[i] == 1) return 2; /* node is a ground and global */ + else return 1; /* node is a global */ + } } if(what == 3) return 0; /* node is not a global */ if(xctx->max_globals >= xctx->size_globals) { xctx->size_globals+=CADCHUNKALLOC; my_realloc(_ALLOC_ID_, &xctx->globals, xctx->size_globals*sizeof(char *) ); + my_realloc(_ALLOC_ID_, &xctx->global_type, xctx->size_globals*sizeof(int) ); } - xctx->globals[xctx->max_globals]=NULL; + xctx->globals[xctx->max_globals] = NULL; + if(what == 4) xctx->global_type[xctx->max_globals] = 1; /* ground and global (for Spectre) */ + else xctx->global_type[xctx->max_globals] = 0; /* global */ my_strdup(_ALLOC_ID_, &xctx->globals[xctx->max_globals], node); xctx->max_globals++; } else if(what == 0) { for(i = 0;i < xctx->max_globals; ++i) { if(xctx->netlist_type == CAD_SPICE_NETLIST) fprintf(fp, ".GLOBAL %s\n", xctx->globals[i]); - if(xctx->netlist_type == CAD_SPECTRE_NETLIST) fprintf(fp, "global %s\n", xctx->globals[i]); /*<<<<*/ + if(xctx->netlist_type == CAD_SPECTRE_NETLIST) { + if(xctx->global_type[i] == 1) fprintf(fp, "ground %s\n", xctx->globals[i]); + else fprintf(fp, "global %s\n", xctx->globals[i]); + } if(xctx->netlist_type == CAD_TEDAX_NETLIST) fprintf(fp, "__GLOBAL__ %s\n", xctx->globals[i]); } } else if(what == 2) { @@ -729,6 +743,7 @@ int record_global_node(int what, FILE *fp, const char *node) my_free(_ALLOC_ID_, &xctx->globals[i]); } my_free(_ALLOC_ID_, &xctx->globals); + my_free(_ALLOC_ID_, &xctx->global_type); xctx->size_globals = xctx->max_globals=0; } @@ -1362,9 +1377,15 @@ static int name_nodes_of_pins_labels_and_propagate() inst[i].node[0]); } /* handle global nodes (global=1 set as symbol property) 28032003 */ - if(!strcmp(type,"label") && global_node && !strboolcmp(global_node, "true")) { - dbg(1, "name_nodes_of_pins_labels_and_propagate(): global node: %s\n",inst[i].node[0]); - record_global_node(1,NULL, inst[i].node[0]); + if(!strcmp(type,"label") && global_node) { + if( !strcmp(global_node, "ground")) { + dbg(1, "name_nodes_of_pins_labels_and_propagate(): ground node: %s\n",inst[i].node[0]); + record_global_node(4,NULL, inst[i].node[0]); + } + else if( !strboolcmp(global_node, "true")) { + dbg(1, "name_nodes_of_pins_labels_and_propagate(): global node: %s\n",inst[i].node[0]); + record_global_node(1,NULL, inst[i].node[0]); + } } /* do not count multiple labels/pins with same name */ diff --git a/src/scheduler.c b/src/scheduler.c index ec42c8d6..4c2b252d 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -4533,7 +4533,8 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;} if(argc > 2) { int n = atoi(argv[2]); - if(n == 1 && argc > 3) ret = record_global_node(1,NULL, argv[3]); /* insert node */ + if(n == 4 && argc > 3) ret = record_global_node(4,NULL, argv[3]); /* insert node */ + else if(n == 1 && argc > 3) ret = record_global_node(1,NULL, argv[3]); /* insert node */ else if(n == 0) ret = record_global_node(0, stdout, NULL); else if(n == 2) ret = record_global_node(2, NULL, NULL); else if(n == 3 && argc > 3) ret = record_global_node(3, NULL, argv[3]); /* look up node */ diff --git a/src/xinit.c b/src/xinit.c index 21c39aea..3a8ce74e 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -682,6 +682,7 @@ static void alloc_xschem_data(const char *top_path, const char *win_path) xctx->max_globals = 0; xctx->size_globals = 0; xctx->globals = NULL; + xctx->global_type = NULL; xctx->save_netlist_type = 0; xctx->some_nets_added = 0; xctx->loaded_symbol = 0; diff --git a/src/xschem.h b/src/xschem.h index a0db4b19..908d2ffb 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1079,6 +1079,7 @@ typedef struct { int max_globals; int size_globals; char **globals; + int *global_type; /* global_type[i]: 0:global, 1:ground and global (for Spectre) */ /* load_schematic */ int save_netlist_type; int loaded_symbol; diff --git a/xschem_library/devices/gnd.sym b/xschem_library/devices/gnd.sym index 9a28439e..6ef04a1d 100644 --- a/xschem_library/devices/gnd.sym +++ b/xschem_library/devices/gnd.sym @@ -1,4 +1,4 @@ -v {xschem version=3.4.4 file_version=1.2 +v {xschem version=3.4.8RC file_version=1.3 * * This file is part of XSCHEM, * a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit @@ -22,11 +22,12 @@ v {xschem version=3.4.4 file_version=1.2 G {} K {type=label function0="L" -global=true +global=ground format="*.alias @lab" template="name=l1 lab=GND"} V {} S {} +F {} E {} L 4 0 0 0 12.5 {} L 4 -5 12.5 5 12.5 {}