spice netlist postprocessing will not break ".include " lines as ngspice does not like these. make_sch_from_spice.awk adapted to import sky130 standard cells, spice netlister will print extra nodes (inherited connections or pins-by-attribute) in the order specified by the format string, instead of dumping the "extra" attribute after all "real" pins, this allows to mix attribute pins with the other pins.

This commit is contained in:
Stefan Schippers 2020-10-21 18:18:53 +02:00
parent 65b7e318a9
commit 1536e77b62
6 changed files with 98 additions and 41 deletions

View File

@ -29,6 +29,10 @@ BEGIN{ quote=0 }
pos=0
if(NF==0) { print ""; next }
first = substr($0,1,1)
# dont break .include lines as ngspice chokes on these.
if(tolower($1) ~ /include/) include = 1
else include = 0
# 20151203 faster executionif no {}' present
if($0 ~/[{}']/ || quote) {
l = length($0)
@ -36,7 +40,7 @@ BEGIN{ quote=0 }
pos++
c = substr($0,i,1)
if(c ~/[{}']/) quote=!quote
if(pos> 100 && !quote && (c ~/[ \t]/)) {
if(!include && pos> 100 && !quote && (c ~/[ \t]/)) {
if(first=="*")
c = "\n*+" c
else
@ -50,7 +54,7 @@ BEGIN{ quote=0 }
split($0, a, /[^ \t]+/)
for(i=1;i<=NF;i++) {
pos += length($i)+length(a[i])
if(pos>100) {
if(!include && pos>100) {
if(first=="*") {
printf "%s", "\n*+"
} else {

View File

@ -30,9 +30,9 @@ BEGIN{
# list of cmos_t9 symbol pin coordinates, generated with build_cmoslib.awk
while ( "ls $HOME/xschem/library/TECHLIB/*.sym"|getline sym )
while ( "ls $HOME/.xschem/xschem_library/sky130_symbols/*.sym"|getline sym )
{
insert_symbol(sym, "TECHLIB")
insert_symbol(sym, "sky130_symbols")
}
@ -42,13 +42,17 @@ BEGIN{
# }
$0=""
inherited_pin["VGND"]=1
inherited_pin["VPWR"]=1
inherited_pin["VNB"]=1
inherited_pin["VPB"]=1
skip_symbol_prefix= "sky130_fd_sc_hd__"
# sym_type = "subcircuit"
sym_type = "primitive" # do not use schematics although they will be generated
all_signals=""
$0=""
########################## JOIN ##########################
netlist_lines=0
@ -123,22 +127,40 @@ function insert_symbol(sym, lib, n,cellname, name, dir, tmp)
}
function process_subckts( i,name)
function process_subckts( j, i,name)
{
if(skip==1 && toupper($1) ==".ENDS") { skip=0; return }
if(skip==1) return
if(toupper($1) ==".SUBCKT") {
curr_subckt=$2
sub(skip_symbol_prefix, "", curr_subckt)
pin_ar[curr_subckt, "name"] = $2
print " process_subckt(): curr_subckt=|" curr_subckt "|"
if(curr_subckt in cell) {print " process_subckt(); skipping " curr_subckt ; skip=1; return }
subckt[curr_subckt]=1
template=0
j = 1
for(i=3;i<=NF;i++) {
if($i~ /=/) { template=i; break}
pin_ar[curr_subckt,i-2]=$i
if(!($i in inherited_pin)) {
pin_ar[curr_subckt,j]=$i
pin_ar[curr_subckt,"format"]=pin_ar[curr_subckt,"format"] " @@" $i
j++
} else {
if(pin_ar[curr_subckt,"extra"])
pin_ar[curr_subckt,"extra"] = pin_ar[curr_subckt,"extra"] " " $i
else
pin_ar[curr_subckt,"extra"] = $i
pin_ar[curr_subckt,"template"] = pin_ar[curr_subckt,"template"] " " $i "=" $i
pin_ar[curr_subckt,"format"]=pin_ar[curr_subckt,"format"] " @" $i
}
}
pin_ar[curr_subckt,"n"]=i-3
pin_ar[curr_subckt,"template"] = get_template(template)
pin_ar[curr_subckt,"n"]=j-1
if(skip_symbol_prefix) pin_ar[curr_subckt,"template"] = pin_ar[curr_subckt,"template"] " prefix=" skip_symbol_prefix
get_template(template)
if(skip_symbol_prefix) pin_ar[curr_subckt,"extra"] = pin_ar[curr_subckt,"extra"] " prefix"
print "\n\n\n process_subckt() : " curr_subckt "--> "
for(i=1; i<= pin_ar[curr_subckt,"n"]; i++) printf "%s ", pin_ar[curr_subckt,i]; printf "\n"
}
@ -164,7 +186,7 @@ function get_template(t, templ, i)
if(t) for(i=t;i<=NF;i++) {
templ = templ $i " "
}
return templ
pin_ar[curr_subckt,"template"] = pin_ar[curr_subckt,"template"] " " templ
}
@ -176,6 +198,7 @@ function process( i,name,param)
if(skip==1) return
if(toupper($1) ==".SUBCKT") {
curr_subckt=$2
sub(skip_symbol_prefix, "", curr_subckt)
if(curr_subckt in cell) {print "process(): skipping " curr_subckt ; skip=1; return }
space=20
width=150
@ -206,7 +229,9 @@ function process( i,name,param)
print "\n\n"
print_sch(curr_subckt, dir_ret, pin_ret)
print_sym(curr_subckt, pin_ar[curr_subckt,"template"], dir_ret, pin_ret)
print_sym(curr_subckt, pin_ar[curr_subckt,"template"], \
pin_ar[curr_subckt,"format"], pin_ar[curr_subckt,"name"], \
sym_type, pin_ar[curr_subckt,"extra"], dir_ret, pin_ret)
print "----------------------------------------------------------"
@ -640,7 +665,7 @@ function print_signals( inst_name, component_name, param, pin,dir,net,
#------------------------------
function print_sym(sym, template, dir, pin,
function print_sym(sym, template, format, subckt_name, sym_type, extra, dir, pin,
size,space,width,lwidth,textdist,labsize,titlesize,
i,name,text_voffset,lab_voffset,ip,op,n_pin ,m,x,y,n,
iii,ooo)
@ -667,13 +692,23 @@ function print_sym(sym, template, dir, pin,
print "start print symbol: " sym
print "v {xschem version=2.9.8 file_version=1.2}"
print "K {type=" sym_type > sym
# print "format=\"@name @pinlist @symname " format_translate(template) "\"" > sym
iii = format_translate(template, extra)
if(iii) iii = " " iii
print "G {type=subcircuit" > sym
print "format=\"@name @pinlist @symname " format_translate(template) "\"" > sym
print "template=\"name=x1 " template "\"}" > sym
print "T {@symname}" ,-length(name)/2*titlesize*30, -text_voffset*titlesize,0,0,
titlesize, titlesize, "{}" >sym
# since awk strings use backslash escapes and sub also uses backslash escapes (example for \& substitution)
# there are 2 levels of escape substitutions, we need \\\\ to generate one \.
# in the xschem file \\\\ is reduced to \\ in the format string and finally format contains one \
if(skip_symbol_prefix) sub(skip_symbol_prefix, "@prefix\\\\\\\\\\\\\\\\", subckt_name)
print "format=\"@name" format " " subckt_name iii "\"" > sym
print "template=\"name=x1" template "\"" > sym
print "extra=\"" extra "\"}" > sym
# print "T {@symname}" ,-length(name)/2*titlesize*30, -text_voffset*titlesize,0,0,
# titlesize, titlesize, "{}" >sym
print "T {@symname}" ,0, -text_voffset*titlesize,0,0,
titlesize, titlesize, "{hcenter=true}" >sym
n_pin=pin["n"]
ip=op=0
@ -742,7 +777,7 @@ function abs(a)
return a>0 ? a: -a
}
function format_translate(s, c,quote,str,n,i,ss,sss)
function format_translate(s, extra, n_extra, extra_arr, extra_hash, c,quote,str,n,i,ss,sss)
{
# 20140321
@ -758,17 +793,23 @@ function format_translate(s, c,quote,str,n,i,ss,sss)
# /20140321
str=""
n_extra = split(extra, extra_arr)
for(i = 1; i <= n_extra; i++) extra_hash[ extra_arr[i] ] = 1
n=split(s,ss)
for(i=1;i<=n;i++) {
gsub(SUBSEP," ", ss[i])
print "subckt params: " ss[i]
if(ss[i] ~ /[^=]+=[^=]+/) {
split(ss[i],sss,"=")
ss[i] = sss[1] "=@" sss[1]
if(!(sss[1] in extra_hash)) ss[i] = sss[1] "=@" sss[1]
else ss[i] = ""
}
str = str ss[i]
if(i<n) str=str " "
if(i<n && ss[i] ) str=str " "
}
delete extra_hash
return str
}

View File

@ -321,8 +321,11 @@ void spice_block_netlist(FILE *fd, int i)
print_spice_subckt(fd, i);
my_strdup(387, &extra, get_tok_value(xctx->sym[i].prop_ptr,"extra",0) );
fprintf(fd, "%s ", extra ? extra : "" );
/* this is now done in print_spice_subckt */
/*
* fprintf(fd, "%s ", extra ? extra : "" );
*/
/* 20081206 new get_sym_template does not return token=value pairs where token listed in extra */
fprintf(fd, "%s", get_sym_template(xctx->sym[i].templ, extra));
my_free(950, &extra);

View File

@ -1394,6 +1394,12 @@ void print_spice_subckt(FILE *fd, int symbol)
}
}
}
/* this will print the other @parameters, usually "extra" nodes so they will be in the order
* specified by the format string. The 'extra' attribute is no more used to print extra nodes
* in spice_block_netlist(). */
else if(token[0] == '@') { /* given previous if() conditions not followed by @ or # */
fprintf(fd, "%s ", token + 1);
}
if(c!='$' && c!='@' && c!='\0' ) fputc(c,fd);
if(c == '@' || c =='$') s--;
state=XBEGIN;
@ -1646,7 +1652,9 @@ void print_spice_element(FILE *fd, int inst)
/* do one level of substitutions to resolve @params and equations*/
if(result && strstr(result, "tcleval(")== result) {
dbg(1, "print_spice_element(): before translate()result=%s\n", result);
my_strdup(22, &result, translate(inst, result));
dbg(1, "print_spice_element(): after translate()result=%s\n", result);
}
fprintf(fd, "%s", result);

View File

@ -1865,7 +1865,8 @@ proc tclpropeval {s instname symname} {
# this hook is called in translate() if whole string is contained in a tcleval(...) construct
proc tclpropeval2 {s} {
# puts "tclpropeval2: $s $instname $symname"
global tcl_debug
if {$tcl_debug <=-1} {puts "tclpropeval2: $s"}
set path [string range [xschem get sch_path] 1 end]
regsub {^tcleval\(} $s {} s
regsub {\)([ \n\t]*)$} $s {\1} s

View File

@ -125,8 +125,8 @@ C {lab_pin.sym} 340 -970 0 1 {name=p23 lab=E2}
C {lab_pin.sym} 560 -970 0 1 {name=p28 lab=E6}
C {lab_pin.sym} 840 -1000 0 0 {name=p29 lab=E4}
C {lab_pin.sym} 180 -1120 0 0 {name=p34 lab=VBOOST}
C {ammeter.sym} 1110 -540 0 0 {name=vd net_name=true current=0.1944}
C {ammeter.sym} 1110 -640 0 0 {name=vu net_name=true current=0.216}
C {ammeter.sym} 1110 -540 0 0 {name=vd net_name=true current=0.2069}
C {ammeter.sym} 1110 -640 0 0 {name=vu net_name=true current=0.2005}
C {lab_pin.sym} 60 -1180 0 0 {name=p27 lab=VPP}
C {pnp.sym} 200 -950 0 1 {name=Q1 model=q2n2907p area=1 net_name=true}
C {pnp.sym} 360 -790 0 1 {name=Q2 model=q2n2907p area=1 net_name=true}
@ -209,18 +209,18 @@ C {lab_pin.sym} 180 -690 0 0 {name=p8 lab=C7}
C {lab_pin.sym} 340 -710 0 1 {name=p31 lab=C2}
C {title.sym} 160 -30 0 0 {name=l2 author="Stefan Schippers"}
C {lab_pin.sym} 860 -700 0 0 {name=p32 lab=SA}
C {ammeter.sym} 1110 -350 0 0 {name=v0 net_name=true current=0.2138}
C {ammeter.sym} 1110 -350 0 0 {name=v0 net_name=true current=0.2263}
C {lab_pin.sym} 860 -380 0 0 {name=p35 lab=SB}
C {ammeter.sym} 560 -890 0 0 {name=v1 net_name=true current=0.01954}
C {ammeter.sym} 340 -890 0 0 {name=v2 net_name=true current=0.01944}
C {ammeter.sym} 260 -310 0 0 {name=v3 net_name=true current=0.03919}
C {ammeter.sym} 700 -440 3 0 {name=v4 net_name=true current=0.01939}
C {ammeter.sym} 690 -680 0 0 {name=v5 net_name=true current=0.006273}
C {ammeter.sym} 180 -870 0 1 {name=v6 net_name=true current=0.01952}
C {ammeter.sym} 840 -890 0 0 {name=v7 net_name=true current=0.01947}
C {spice_probe_vdiff.sym} 860 -410 0 0 {name=p37 analysis=tran voltage=3.684}
C {spice_probe_vdiff.sym} 860 -730 0 0 {name=p38 analysis=tran voltage=3.685}
C {ammeter.sym} 1300 -590 3 0 {name=v8 net_name=true current=0.02782}
C {ammeter.sym} 560 -890 0 0 {name=v1 net_name=true current=0.01956}
C {ammeter.sym} 340 -890 0 0 {name=v2 net_name=true current=0.01947}
C {ammeter.sym} 260 -310 0 0 {name=v3 net_name=true current=0.03918}
C {ammeter.sym} 700 -440 3 0 {name=v4 net_name=true current=0.01941}
C {ammeter.sym} 690 -680 0 0 {name=v5 net_name=true current=0.006184}
C {ammeter.sym} 180 -870 0 1 {name=v6 net_name=true current=0.01949}
C {ammeter.sym} 840 -890 0 0 {name=v7 net_name=true current=0.01944}
C {spice_probe_vdiff.sym} 860 -410 0 0 {name=p37 analysis=tran voltage=3.688}
C {spice_probe_vdiff.sym} 860 -730 0 0 {name=p38 analysis=tran voltage=3.68}
C {ammeter.sym} 1300 -590 3 0 {name=v8 net_name=true current=-2.1216e-04}
C {opin.sym} 600 -130 0 0 {name=p5 lab=OUT}
C {ipin.sym} 530 -180 0 0 {name=p1 lab=MINUS}
C {ipin.sym} 530 -140 0 0 {name=p4 lab=VSS}