symbol generators may now take attributes like: "mosgen( @model )", with @model expanded to instance (or symbol template) value. update_symbol() updated to reflect this change.

This commit is contained in:
stefan schippers 2023-05-02 17:49:44 +02:00
parent eb50f9c26a
commit 4b9f61612b
5 changed files with 194 additions and 59 deletions

View File

@ -1248,9 +1248,9 @@ static void update_symbol(const char *result, int x)
int copy_cell=0;
int prefix=0, old_prefix = 0;
char *name = NULL, *ptr = NULL, *new_prop = NULL;
char symbol[PATH_MAX];
char symbol[PATH_MAX], *translated_sym = NULL, *old_translated_sym = NULL;
char *type;
int cond;
int cond, changed_symbol = 0;
int pushed=0;
int *ii = &xctx->edit_sym_i; /* static var */
int *netl_com = &xctx->netlist_commands; /* static var */
@ -1288,19 +1288,9 @@ static void update_symbol(const char *result, int x)
remove_symbols();
link_symbols_to_instances(-1);
}
/* symbol reference changed? --> sym_number >=0, set prefix to 1st char
to use for inst name (from symbol template) */
old_prefix = prefix = 0;
sym_number = -1;
/* User edited the Symbol textbox */
if(strcmp(symbol, xctx->inst[*ii].name)) {
char *sym = NULL;
set_modify(1);
my_strdup2(_ALLOC_ID_, &sym, tcl_hook2(symbol));
sym_number=match_symbol(sym); /* check if exist */
my_free(_ALLOC_ID_, &sym);
if(sym_number>=0) {
prefix=(get_tok_value((xctx->sym+sym_number)->templ, "name",0))[0]; /* get new symbol prefix */
}
changed_symbol = 1;
}
for(k=0;k<xctx->lastsel; ++k) {
dbg(1, "update_symbol(): for k loop: k=%d\n", k);
@ -1310,17 +1300,9 @@ static void update_symbol(const char *result, int x)
/* 20171220 calculate bbox before changes to correctly redraw areas */
/* must be recalculated as cairo text extents vary with zoom factor. */
symbol_bbox(*ii, &xctx->inst[*ii].x1, &xctx->inst[*ii].y1, &xctx->inst[*ii].x2, &xctx->inst[*ii].y2);
if(sym_number>=0) /* changing symbol ! */
{
if(!pushed) { xctx->push_undo(); pushed=1;}
delete_inst_node(*ii); /* 20180208 fix crashing bug: delete node info if changing symbol */
/* if number of pins is different we must delete these data *before* */
/* changing ysmbol, otherwise *ii might end up deleting non allocated data. */
my_strdup2(_ALLOC_ID_, &xctx->inst[*ii].name, rel_sym_path(symbol));
xctx->inst[*ii].ptr=sym_number; /* update instance to point to new symbol */
}
bbox(ADD, xctx->inst[*ii].x1, xctx->inst[*ii].y1,
xctx->inst[*ii].x2, xctx->inst[*ii].y2);
bbox(ADD, xctx->inst[*ii].x1, xctx->inst[*ii].y1, xctx->inst[*ii].x2, xctx->inst[*ii].y2);
my_strdup2(_ALLOC_ID_, &old_translated_sym, translate(*ii, xctx->inst[*ii].name));
/* update property string from tcl dialog */
if(!no_change_props)
@ -1340,6 +1322,7 @@ static void update_symbol(const char *result, int x)
dbg(1, "update_symbol(): changing prop: |%s| -> |%s|\n",
xctx->inst[*ii].prop_ptr, new_prop);
if(!pushed) { xctx->push_undo(); pushed=1; set_modify(1);}
dbg(1, "update_symbol(): *ii=%d, new_prop=%s\n", *ii, new_prop ? new_prop : "NULL");
my_strdup(_ALLOC_ID_, &xctx->inst[*ii].prop_ptr, new_prop);
}
} else {
@ -1349,6 +1332,31 @@ static void update_symbol(const char *result, int x)
}
}
/* symbol reference changed? --> sym_number >=0, set prefix to 1st char
* to use for inst name (from symbol template) */
prefix = 0;
sym_number = -1;
my_strdup2(_ALLOC_ID_, &translated_sym, translate(*ii, symbol));
dbg(1, "update_symbol: %s -- %s\n", translated_sym, old_translated_sym);
if(changed_symbol ||
( !strcmp(symbol, xctx->inst[*ii].name) && strcmp(translated_sym, old_translated_sym) ) ) {
sym_number=match_symbol(translated_sym); /* check if exist */
if(sym_number>=0) {
prefix=(get_tok_value((xctx->sym+sym_number)->templ, "name",0))[0]; /* get new symbol prefix */
}
}
if(sym_number>=0) /* changing symbol ! */
{
if(!pushed) { xctx->push_undo(); pushed=1; set_modify(1);}
delete_inst_node(*ii); /* 20180208 fix crashing bug: delete node info if changing symbol */
/* if number of pins is different we must delete these data *before* */
/* changing ysmbol, otherwise *ii might end up deleting non allocated data. */
my_strdup2(_ALLOC_ID_, &xctx->inst[*ii].name, rel_sym_path(symbol));
xctx->inst[*ii].ptr=sym_number; /* update instance to point to new symbol */
}
my_free(_ALLOC_ID_, &translated_sym);
my_free(_ALLOC_ID_, &old_translated_sym);
/* if symbol changed ensure instance name (with new prefix char) is unique */
/* preserve backslashes in name ---------0---------------------------------->. */
@ -1356,7 +1364,12 @@ static void update_symbol(const char *result, int x)
if(name && name[0] ) {
dbg(1, "update_symbol(): prefix!='\\0', name=%s\n", name);
/* change prefix if changing symbol type; */
if(prefix && old_prefix && old_prefix != prefix) name[0]=(char)prefix;
if(prefix && old_prefix && old_prefix != prefix) {
name[0]=(char)prefix;
my_strdup(_ALLOC_ID_, &ptr, subst_token(xctx->inst[*ii].prop_ptr, "name", name) );
} else {
my_strdup(_ALLOC_ID_, &ptr, xctx->inst[*ii].prop_ptr);
}
/* set unique name of current inst */
if(!pushed) { xctx->push_undo(); pushed=1;}
if(!k) hash_all_names();
@ -1365,7 +1378,6 @@ static void update_symbol(const char *result, int x)
my_strdup2(_ALLOC_ID_, &xctx->inst[*ii].instname, "");
}
/* set cached flags in instances */
type=xctx->sym[xctx->inst[*ii].ptr].type;
cond= !type || !IS_LABEL_SH_OR_PIN(type);
@ -1385,8 +1397,6 @@ static void update_symbol(const char *result, int x)
} /* end for(k=0;k<xctx->lastsel; ++k) */
/* new symbol bbox after prop changes (may change due to text length) */
if(xctx->modified) {
xctx->prep_hash_inst=0;

View File

@ -1559,14 +1559,17 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
else if(!strcmp(argv[1], "instance_list"))
{
int i;
char *s = NULL;
for(i = 0; i < xctx->instances; ++i) {
char *name = xctx->inst[i].name ? xctx->inst[i].name : "";
const char *name = xctx->inst[i].name ? translate(i, xctx->inst[i].name) : "";
char *instname = xctx->inst[i].instname ? xctx->inst[i].instname : "";
char *type = (xctx->inst[i].ptr + xctx->sym)->type;
type = type ? type : "";
if(i > 0) Tcl_AppendResult(interp, " ", NULL);
Tcl_AppendResult(interp, "{", instname, "} {", name, "} {", type, "}", NULL);
if(i > 0) my_mstrcat(_ALLOC_ID_, &s, " ", NULL);
my_mstrcat(_ALLOC_ID_, &s, "{", instname, "} {", name, "} {", type, "}", NULL);
}
Tcl_SetResult(interp, (char *)s, TCL_VOLATILE);
my_free(_ALLOC_ID_, &s);
}
/* instance_net inst pin
* Return the name of the net attached to pin 'pin' of instance 'inst'

View File

@ -110,6 +110,112 @@ hide=true}
T {tcleval(id=[to_eng [ngspice::get_node [subst -nocommand \{i(\\@m.$\{path\}@spiceprefix@name\\.msky130_fd_pr__@model\\[id])\}]]] )} 32.5 -30 0 0 0.15 0.15 {layer=15
hide=true}
}
} elseif {$model eq {pfet_g5v0d10v5}} {
puts {v {xschem version=3.1.0 file_version=1.2}
G {}
K {type=pmos
lvs_format="@spiceprefix@name @pinlist sky130_fd_pr__@model L=@L W=@W nf=@nf m=@mult"
format="@spiceprefix@name @pinlist sky130_fd_pr__@model L=@L W=@W
+ nf=@nf ad=@ad as=@as pd=@pd ps=@ps
+ nrd=@nrd nrs=@nrs sa=@sa sb=@sb sd=@sd
+ mult=@mult m=@mult"
template="name=M1
L=0.5
W=1
nf=1
mult=1
ad=\\"'int((nf+1)/2) * W/nf * 0.29'\\"
pd=\\"'2*int((nf+1)/2) * (W/nf + 0.29)'\\"
as=\\"'int((nf+2)/2) * W/nf * 0.29'\\"
ps=\\"'2*int((nf+2)/2) * (W/nf + 0.29)'\\"
nrd=\\"'0.29 / W'\\" nrs=\\"'0.29 / W'\\"
sa=0 sb=0 sd=0
model=pfet_g5v0d10v5
spiceprefix=X
"}
V {}
S {}
E {}
L 4 20 -30 20 -17.5 {}
L 4 20 17.5 20 30 {}
L 4 7.5 17.5 20 17.5 {}
L 4 12.5 -17.5 20 -17.5 {}
L 4 -20 0 -12.5 0 {}
L 4 7.5 -22.5 7.5 22.5 {}
B 5 17.5 27.5 22.5 32.5 {name=D dir=inout}
B 5 -22.5 -2.5 -17.5 2.5 {name=G dir=in}
B 5 17.5 -32.5 22.5 -27.5 {name=S dir=inout}
B 5 19.921875 -0.078125 20.078125 0.078125 {name=B dir=in}
A 4 -7.5 0 5 180 360 {}
P 4 4 12.5 -20 7.5 -17.5 12.5 -15 12.5 -20 {fill=true}
P 4 5 -2.5 15 -2.5 -15 2.5 -15 2.5 15 -2.5 15 {}
P 5 4 15 -2.5 20 0 15 2.5 15 -2.5 {fill=true}
T {@name} 5 -30 0 1 0.2 0.2 {}
T {D} 22.5 17.5 0 0 0.15 0.15 {layer=7}
T {S} 22.5 -17.5 2 1 0.15 0.15 {layer=7}
T {B} 20 -10 0 0 0.15 0.15 {layer=7}
T {G} -11.875 -10 0 1 0.15 0.15 {layer=7}
T {@model} 30 -8.75 2 1 0.2 0.2 {}
T {@mult x @W / @L} 31.25 13.75 0 0 0.2 0.2 { layer=13}
T {nf=@nf} 31.25 1.25 0 0 0.2 0.2 { layer=13}
T {tcleval(gm=[to_eng [ngspice::get_node [subst -nocommand \{\\@m.$\{path\}@spiceprefix@name\\.msky130_fd_pr__@model\\[gm]\}]]] )} 32.5 -8.75 0 0 0.15 0.15 {layer=15
hide=true}
T {tcleval(id=[to_eng [ngspice::get_node [subst -nocommand \{i(\\@m.$\{path\}@spiceprefix@name\\.msky130_fd_pr__@model\\[id])\}]]] )} 32.5 -30 0 0 0.15 0.15 {layer=15
hide=true}
}
} elseif {$model eq {pfet_01v8}} {
puts {v {xschem version=3.1.0 file_version=1.2}
G {}
K {type=pmos
lvs_format="@spiceprefix@name @pinlist sky130_fd_pr__@model L=@L W=@W nf=@nf m=@mult"
format="@spiceprefix@name @pinlist sky130_fd_pr__@model L=@L W=@W
+ nf=@nf ad=@ad as=@as pd=@pd ps=@ps
+ nrd=@nrd nrs=@nrs sa=@sa sb=@sb sd=@sd
+ mult=@mult m=@mult"
template="name=M1
L=0.15
W=1
nf=1
mult=1
ad=\\"'int((nf+1)/2) * W/nf * 0.29'\\"
pd=\\"'2*int((nf+1)/2) * (W/nf + 0.29)'\\"
as=\\"'int((nf+2)/2) * W/nf * 0.29'\\"
ps=\\"'2*int((nf+2)/2) * (W/nf + 0.29)'\\"
nrd=\\"'0.29 / W'\\" nrs=\\"'0.29 / W'\\"
sa=0 sb=0 sd=0
model=pfet_01v8
spiceprefix=X
"}
V {}
S {}
E {}
L 4 7.5 -22.5 7.5 22.5 {}
L 4 20 -30 20 -17.5 {}
L 4 20 17.5 20 30 {}
L 4 2.5 -15 2.5 15 {}
L 4 7.5 17.5 20 17.5 {}
L 4 12.5 -17.5 20 -17.5 {}
L 4 -20 0 -7.5 0 {}
B 5 17.5 27.5 22.5 32.5 {name=D dir=inout}
B 5 -22.5 -2.5 -17.5 2.5 {name=G dir=in}
B 5 17.5 -32.5 22.5 -27.5 {name=S dir=inout}
B 5 19.921875 -0.078125 20.078125 0.078125 {name=B dir=in}
A 4 -2.5 0 5 180 360 {}
P 4 4 12.5 -20 7.5 -17.5 12.5 -15 12.5 -20 {fill=true}
P 5 4 15 -2.5 20 0 15 2.5 15 -2.5 {fill=true}
T {@name} 5 -30 0 1 0.2 0.2 {}
T {D} 22.5 17.5 0 0 0.15 0.15 {layer=7}
T {S} 22.5 -17.5 2 1 0.15 0.15 {layer=7}
T {B} 20 -10 0 0 0.15 0.15 {layer=7}
T {G} -10 -10 0 1 0.15 0.15 {layer=7}
T {@model} 30 -8.75 2 1 0.2 0.2 {}
T {@mult x @W / @L} 31.25 13.75 0 0 0.2 0.2 { layer=13}
T {nf=@nf} 31.25 1.25 0 0 0.2 0.2 { layer=13}
T {tcleval(gm=[to_eng [ngspice::get_node [subst -nocommand \{\\@m.$\{path\}@spiceprefix@name\\.msky130_fd_pr__@model\\[gm]\}]]] )} 32.5 -8.75 0 0 0.15 0.15 {layer=15
hide=true}
T {tcleval(id=[to_eng [ngspice::get_node [subst -nocommand \{i(\\@m.$\{path\}@spiceprefix@name\\.msky130_fd_pr__@model\\[id])\}]]] )} 32.5 -30 0 0 0.15 0.15 {layer=15
hide=true}
}
} else {
puts {
G {type=missing

View File

@ -0,0 +1,43 @@
v {xschem version=3.1.0 file_version=1.2
}
G {}
K {}
V {}
S {}
E {}
N 500 -140 610 -140 {
lab=#net1}
N 500 -230 500 -170 {
lab=#net2}
N 390 -140 460 -140 {
lab=#net3}
N 500 -110 500 -50 {
lab=#net4}
N 790 -140 900 -140 {
lab=#net5}
N 790 -230 790 -170 {
lab=#net6}
N 680 -140 750 -140 {
lab=#net7}
N 790 -110 790 -50 {
lab=#net8}
N 500 -260 610 -260 {
lab=#net9}
N 390 -260 460 -260 {
lab=#net10}
N 790 -260 900 -260 {
lab=#net11}
N 680 -260 750 -260 {
lab=#net12}
N 500 -350 500 -290 {
lab=#net13}
N 790 -350 790 -290 {
lab=#net14}
C {mosgen( @model )} 480 -140 0 0 {name=x1
model=nfet_01v8}
C {mosgen( @model )} 770 -140 0 0 {name=x2
model=nfet_g5v0d10v5}
C {mosgen( @model )} 480 -260 0 0 {name=x3
model=pfet_01v8}
C {mosgen( @model )} 770 -260 0 0 {name=x4
model=pfet_g5v0d10v5}

View File

@ -1,27 +0,0 @@
v {xschem version=3.1.0 file_version=1.2
}
G {}
K {}
V {}
S {}
E {}
N 500 -140 610 -140 {
lab=#net1}
N 500 -230 500 -170 {
lab=#net2}
N 390 -140 460 -140 {
lab=#net3}
N 500 -110 500 -50 {
lab=#net4}
N 790 -140 900 -140 {
lab=#net5}
N 790 -230 790 -170 {
lab=#net6}
N 680 -140 750 -140 {
lab=#net7}
N 790 -110 790 -50 {
lab=#net8}
C {nmosgen( @model )} 480 -140 0 0 {name=x1
model=nfet_g5v0d10v5}
C {nmosgen( @model )} 770 -140 0 0 {name=x2
model=nfet_g5v0d10v5}