From 794df4dfc3cc57d1ce7e11a6872244c59ddb7b16 Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Thu, 2 Nov 2023 19:07:15 +0100 Subject: [PATCH] add make_sym_from_spice.awk, cut down from make_sch_from_spice.awk --- src/Makefile.in | 2 +- src/make_sch_from_spice.awk | 124 ++++----- src/make_sym_from_spice.awk | 509 ++++++++++++++++++++++++++++++++++++ src/scheduler.c | 2 +- 4 files changed, 566 insertions(+), 71 deletions(-) create mode 100755 src/make_sym_from_spice.awk diff --git a/src/Makefile.in b/src/Makefile.in index 411fb39a..28e66b22 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -16,7 +16,7 @@ put /local/install_shares { vhdl.awk hspice_backannotate.tcl add_custom_menu.tcl create_graph.tcl add_custom_button.tcl change_index.tcl icon.xpm resources.tcl xschemrc ngspice_backannotate.tcl gschemtoxschem.awk traversal.tcl mouse_bindings.tcl - place_sym_pins.tcl place_pins.tcl + place_sym_pins.tcl place_pins.tcl make_sch_from_spice.awk make_sym_from_spice.awk } # generate a list of objects from the list of source files diff --git a/src/make_sch_from_spice.awk b/src/make_sch_from_spice.awk index 3df7c235..6e6f3354 100755 --- a/src/make_sch_from_spice.awk +++ b/src/make_sch_from_spice.awk @@ -2,89 +2,68 @@ gawk ' BEGIN{ -# ar["a", 1] = "A[3]" -# ar["a", 2] = "A[3]" -# ar["a", 3] = "A[3]" -# ar["a", 4] = "A[4]" -# ar["a", 5] = "A[5]" -# ar["a", 6] = "A[6]" -# ar["a", 7] = "A[6]" -# ar["a", 8] = "A[6]" -# ar["a", 9] = "A[6]" -# ar["a",10] = "A[8]" -# ar["a",11] = "A[7]" -# ar["a",12] = "A[7]" -# ar["a",13] = "A[9]" -# ar["a",14] = "A[11]" -# ar["a",15] = "A[13]" -# -# print compact_label("a",ar, 1,15) -# exit - - ## 20161225 avoid_brakets=0 ## set to 1 if you want to avoid [] in inst names: x12[3] --> x12_3_ ## this is needed for VHDl since [] are not allowed in inst names error_missing=0 ## flag to terminate or continue in case of missing subckt definitions in netlist ## 20161118 - # list of cmos_t9 symbol pin coordinates, generated with build_cmoslib.awk - while ( "ls $HOME/.xschem/xschem_library/xschem_sky130/sky130_stdcells/*.sym"|getline sym ) { insert_symbol(sym, "sky130_stdcells") } -# while ( "ls $HOME/xschem/library/devices/*.sym"|getline sym ) -# { -# insert_symbol(sym, "devices") -# } + # while ( "ls $HOME/share/xschem/xschem_library/devices/*.sym"|getline sym ) + # { + # insert_symbol(sym, "devices") + # } - inherited_pin["VGND"]=1 - inherited_pin["VPWR"]=1 - inherited_pin["VNB"]=1 - inherited_pin["VPB"]=1 + devices_prefix = "devices/" #for sky130 + # devices_prefix = "" + + 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 + 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="" + all_signals="" ########################## JOIN ########################## - netlist_lines=0 - first=1 - while(err= (getline l) >0) { - gsub(//,"]",l) - if(first) { - $0=l - first=0 - } - else if(l !~/^\+/) { - netlist[netlist_lines++]=$0 - $0=l - } - else $0 = $0 " " substr(l,2) - } - netlist[netlist_lines++]=$0 + netlist_lines=0 + first=1 + while(err= (getline l) >0) { + gsub(//,"]",l) + if(first) { + $0=l + first=0 + } + else if(l !~/^\+/) { + netlist[netlist_lines++]=$0 + $0=l + } + else $0 = $0 " " substr(l,2) + } + netlist[netlist_lines++]=$0 ########################## END JOIN ########################## - skip=0 - for(i=0;i print_sch called for: " schname - print "V {}\nG {}\nS {" subckt_netlist "}" > schname # 20111009 added subckt_components + print "V {}\nG {}\nS {" escape_brackets(subckt_netlist) "}" > schname # 20111009 added subckt_components n_pin = dir["n"] ip=op=0 @@ -543,21 +522,21 @@ function print_sch(schname, dir, pin, if(pin_dir=="I") { iii++ - printf "C {devices/ipin} " (x+sch_x_offset) " " (y+iii*space) " 0 0 " \ + printf "C {" devices_prefix "ipin.sym} " (x+sch_x_offset) " " (y+iii*space) " 0 0 " \ " {name=p" p_pin++ " lab=" pin[i] " " >schname printf "}\n" >schname } if(pin_dir=="O") { ooo++ - printf "C {devices/opin} " (-x+sch_x_offset) " " (y+ooo*space) " 0 0 " \ + printf "C {" devices_prefix "opin.sym} " (-x+sch_x_offset) " " (y+ooo*space) " 0 0 " \ " {name=p" p_pin++ " lab=" pin[i] " " >schname printf "}\n" >schname } if(pin_dir=="B") { ooo++ - printf "C {devices/iopin} " (-x+sch_x_offset) " " (y+ooo*space) " 0 0 " \ + printf "C {" devices_prefix "iopin.sym} " (-x+sch_x_offset) " " (y+ooo*space) " 0 0 " \ " {name=p" p_pin++ " lab=" pin[i] " " >schname printf "}\n" >schname } @@ -629,21 +608,21 @@ function print_signals( inst_name, component_name, param, pin,dir,net, if(curr_dir=="I") { - all_signals = all_signals "C {devices/lab_pin} " xpin " " ypin " 0 0 " \ + all_signals = all_signals "C {" devices_prefix "lab_pin.sym} " xpin " " ypin " 0 0 " \ " {name=p" p_pin++ " lab=" net[i] " " all_signals = all_signals "}\n" } if(curr_dir=="O") { - all_signals = all_signals "C {devices/lab_pin} " xpin " " ypin " 0 1 " \ + all_signals = all_signals "C {" devices_prefix "lab_pin.sym} " xpin " " ypin " 0 1 " \ " {name=p" p_pin++ " lab=" net[i] " " all_signals = all_signals "}\n" } if(curr_dir=="B") { - all_signals = all_signals "C {devices/lab_pin} " xpin " " ypin " 0 1 " \ + all_signals = all_signals "C {" devices_prefix "lab_pin.sym} " xpin " " ypin " 0 1 " \ " {name=p" p_pin++ " lab=" net[i] " " all_signals = all_signals "}\n" } @@ -774,6 +753,13 @@ function print_sym(sym, template, format, subckt_name, sym_type, extra, dir, pin #------------------------------ +function escape_brackets(s , ss) +{ + ss = s + gsub(/[{}]/, "\\\\&", ss) + return ss +} + function abs(a) { return a>0 ? a: -a diff --git a/src/make_sym_from_spice.awk b/src/make_sym_from_spice.awk new file mode 100755 index 00000000..cf00d6b6 --- /dev/null +++ b/src/make_sym_from_spice.awk @@ -0,0 +1,509 @@ +#!/bin/sh +gawk ' + +BEGIN{ + sym_type = "subcircuit" # or "primitive" +########################## JOIN ########################## + netlist_lines=0 + first=1 + while(err= (getline l) >0) { + gsub(//,"]",l) + if(first) { + $0=l + first=0 + } + else if(l !~/^\+/) { + netlist[netlist_lines++]=$0 + $0=l + } + else $0 = $0 " " substr(l,2) + } + netlist[netlist_lines++]=$0 +########################## END JOIN ########################## + + skip=0 + for(i=0;i " $0 ; exit} + } + } + else if(toupper($1) ~ /^\*\.(I|O|IO)PIN/) { + if($1 ~ /^\*\.ipin/) { pin_ar[curr_subckt, "dir", $2] = "I" } + else if($1 ~ /^\*\.opin/) { pin_ar[curr_subckt, "dir", $2] = "O" } + else if($1 ~ /^\*\.iopin/) { pin_ar[curr_subckt, "dir", $2] = "B" } + } +} + +function get_template(t, templ, i) +{ + templ="" + if(t) for(i=t;i<=NF;i++) { + templ = templ $i " " + } + pin_ar[curr_subckt,"template"] = pin_ar[curr_subckt,"template"] " " templ +} + + + +function process( i,name,param) +{ + 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) + if(curr_subckt in cell) {print "process(): skipping " curr_subckt ; skip=1; return } + space=20 + width=150 + lwidth=20 + textdist=5 + labsize=0.2 + titlesize=0.3 + text_voffset=20 + xoffset=1300 + yoffset=0 + prev_size=0 + lab_voffset=4 + sp=ip=op=n_pin=0 + all_signals="" + delete net_ar + subckt_netlist = "" # 20111009 all netlist lines except component instances (X) + + } + else if(toupper($1) ~ /^.ENDS/) { + + + compact_pinlist( "" , curr_subckt) + + 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) + } +} + +function get_param(i, param,j) +{ + param="" + if(i) for(j=i;j<=NF;j++) { + param = param $j " " + } + return param +} + +function compact_pinlist(inst,inst_sub , prevgroup, group,i,ii,base,curr,curr_n,np) +{ + delete pin_ret + delete net_ret + delete dir_ret + + np=pin_ar[inst_sub,"n"] + # print " compact_pinlist: inst=" inst " np= " np " inst_sub=" inst_sub + if(np) { + ii=1 + for(i=1;i<=np;i++) { + group=0 + # print "compact_pinlist: i=" i " inst_sub=" inst_sub " pin_ar[inst_sub,i]=" pin_ar[inst_sub,i] + # print "compact_pinlist: net_ar[inst,i]=" net_ar[inst,i] + if(net_ar[inst,i] ~/,/) group=1 + + base =lab_name( pin_ar[inst_sub,i] ) + if(i==1) {prevgroup=group; curr=base; curr_n=i} + else { + if(prevgroup || base != curr) { + if(prevgroup) pin_ret[ii] = pin_ar[inst_sub,i-1] + else pin_ret[ii] = compact_label(inst_sub,pin_ar,curr_n,i-1) + if(inst) { + if(prevgroup) net_ret[ii] = compact_label_str(net_ar[inst,i-1]) + else net_ret[ii] = compact_label(inst,net_ar,curr_n,i-1) + } + dir_ret[ii] = pin_ar[inst_sub,"dir",pin_ar[inst_sub,i-1] ] + if(dir_ret[ii] == "") dir_ret[ii] = "B" + ii++ + curr=base;curr_n=i + prevgroup=group + } + } + } + } + pin_ret[ii] = compact_label(inst_sub, pin_ar,curr_n,np) + if(inst) { + if(group) net_ret[ii] = compact_label_str(net_ar[inst, np]) + else net_ret[ii] = compact_label(inst, net_ar,curr_n,np) + } + + dir_ret[ii] = pin_ar[inst_sub,"dir",pin_ar[inst_sub,np] ] + if(dir_ret[ii] == "") dir_ret[ii] = "B" + pin_ret["n"] = dir_ret["n"] = ii + if(inst) net_ret["n"] = ii +} +# 1 2 3 4 5 6 7 8 9 10 11 12 +# PP A[3] A[2] A[1] B C K[10] K[9] K[5] K[4] K[3] K[1] +function compact_label_str(str, a, b, ar, ret,start,i) +{ + # print "compact_label_str(): str=" str + a=1 + b=split(str, ar,",") + ret="" + for(i=a;i<=b;i++) { + if(i==a) {start=a} + else { + if(ar[i-1] !~ /\[/) { + if(ar[i-1] != ar[i]) { + if(start < i-1) { ret = ret (i-start) "*" ar[i-1] ","; start=i } + else {ret = ret ar[i-1] ","; start=i } + } + } + else if(lab_name(ar[i])!=lab_name(ar[i-1])) { # lab basename changed + if(start sym + iii = format_translate(template, extra) + if(iii) iii = " " iii + + # 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 + for(i=1; i<=n_pin; i++) { + if(dir[i] ~ /[OB]/) { + op++ + } + else if(dir[i] ~ /I/) ip++ + else {print "ERROR: print_sym(): undefined dir[] i=" i " inst=" inst " sub=" component_name ; exit} + } + + n=ip;if(op>n) n=op + if(n==0) n=1 + m=(n-1)/2 + y=-m*space + x=-width + print "T {@name}",-x-lwidth+5, y-space/2-8-lab_voffset,0,0,labsize, labsize,"{}" >sym + print "L 4 " (x+lwidth) ,y-space/2,(-x-lwidth) , y-space/2,"{}" >sym + print "L 4 " (x+lwidth) ,y+n*space-space/2,(-x-lwidth) , y+n*space-space/2,"{}" >sym + print "L 4 " (x+lwidth) ,y-space/2,(x+lwidth) , y+n*space-space/2,"{}" >sym + print "L 4 " (-x-lwidth) ,y-space/2,(-x-lwidth) , y+n*space-space/2,"{}" >sym + iii=ooo=0 + for(i=1;i<=n_pin;i++) + { + pin_dir=dir[i] + + if(pin_dir=="I") + { + printf "B 5 " (x-size) " " (y+iii*space-size) " " (x+size) " " (y+iii*space+size) \ + " {name=" pin[i] " dir=in " >sym + printf "}\n" >sym + print "L 4 " x,y+iii*space,x+lwidth, y+iii*space,"{}" >sym + print "T {" pin[i] "}",x+lwidth+textdist,y+iii*space-lab_voffset,0,0,labsize, labsize, "{}" >sym + iii++ + } + if(pin_dir=="O") + { + printf "B 5 " (-x-size) " " (y+ooo*space-size) " " (-x+size) " " (y+ooo*space+size) \ + " {name=" pin[i] " dir=out " >sym + printf "}\n" >sym + print "L 4 " (-x-lwidth),(y+ooo*space),(-x), (y+ooo*space),"{}" >sym + print "T {" pin[i] "}",-x-lwidth-textdist,y+ooo*space-lab_voffset,0,1,labsize, labsize, "{}" >sym + ooo++ + } + if(pin_dir=="B") + { + printf "B 5 " (-x-size) " " (y+ooo*space-size) " " (-x+size) " " (y+ooo*space+size) \ + " {name=" pin[i] " dir=inout " >sym + printf "}\n" >sym + print "L 7 " (-x-lwidth),(y+ooo*space),(-x), (y+ooo*space),"{}" >sym + print "T {" pin[i] "}",-x-lwidth-textdist,y+ooo*space-lab_voffset,0,1,labsize, labsize, "{}" >sym + ooo++ + } + } + close(sym) +} + + +#------------------------------ + +function escape_brackets(s , ss) +{ + ss = s + gsub(/[{}]/, "\\\\&", ss) + return ss +} + +function abs(a) +{ + return a>0 ? a: -a +} + +function format_translate(s, extra, n_extra, extra_arr, extra_hash, c,quote,str,n,i,ss,sss) +{ + + # 20140321 + str="" + quote=0 + for(i=1; i< length(s); i++) { + c = substr(s,i,1) + if(c == "\"") quote=!quote + if(quote && c==" ") str = str SUBSEP + else str = str c + } + s = str + # /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]) + if(ss[i] ~ /[^=]+=[^=]+/) { + split(ss[i],sss,"=") + if(!(sss[1] in extra_hash)) ss[i] = sss[1] "=@" sss[1] + else ss[i] = "" + } + str = str ss[i] + if(i