#!/usr/bin/awk -f BEGIN{ first = 1 hier = 0 debug = 0 hiersep="." } { reparse() } /^begin netlist/{ cell = $4 if(first) { topcell=cell first = 0 } start[cell] = NR } /^end netlist/{ end[cell] = NR } /^__GLOBAL__/{ global[$2] = 1 } /^__HIERSEP__/{ hiersep = $2 } { netlist[NR] = $0 } END{ out("tEDAx v1") out("begin netlist v1 " topcell) expand(topcell, "", "", "") out("end netlist") } function expand(cell, instname, path, maplist, i, j, subpos, subcell, subinst, submaplist) { hier++ for(i = start[cell]+1; i <= end[cell]-1; i++) { $0 = netlist[i] reparse() # __subcircuit__ pcb_voltage_protection x0 # __map__ VOUT -> VOUTXX # __map__ ... -> ... if($1 == "__subcircuit__") { subcell=$2 subinst=$3 subpos = i sub(/__subcircuit__/, "subcircuit", $0) out("#" spaces(hier * 2 - 1) $0) submaplist = "" for(i++; ;i++) { $0 = netlist[i] reparse() if($1 != "__map__") break dbg("expand: $4=" $4) $4 = resolve_node($4, path, maplist) submaplist = submaplist " " $2 " " $4 sub(/__map__/, "map", $0) out("#" spaces(hier * 2 - 1) $0) } expand(subcell, subinst, path subinst hiersep, submaplist) i--; continue; # redo processing of current line } if($1 == "conn") { dbg("conn: $2=" $2) $2 = resolve_node($2, path, maplist) #net name $3 = path $3 #refdes } if($1 ~/^(device|footprint|value|spiceval|spicedev|comptag|pinname|pinslot|pinidx)$/) { $2 = path $2 #refdes } out(spaces(hier * 2) $0) if($0 ~ /^end netlist/) break } hier-- } function spaces(n, s) { n = (n > 0) ? n - 1 : 0 s =" " while(length(s) < n) s = s s return substr(s,1,n) } function out(s) { if(length(s) > 512) print "flatten_tedax: WARNING: >> " s "\n line length > 512 chars, this breaks tEDAx" > "/dev/stderr" print s } function dbg(s) { if(debug) print s > "/dev/stderr" } function resolve_node(node, path, maplist, arr, n, retnode, i) { dbg("resolve_node: node=" node " maplist=" maplist) gsub(/\\ /, SUBSEP "s", maplist) gsub(/\\\t/, SUBSEP "t", maplist) n = split(maplist, arr) for(i = 1; i <= n; i++) { gsub(SUBSEP "s", "\\ ", arr[i]) gsub(SUBSEP "t", "\\\t", arr[i]) } if(node in global) retnode = node else for(i = 1; i <= n; i += 2) { if(node == arr[i]) { retnode = arr[i+1] break } } if(retnode =="") retnode = path node return retnode } # avoid considering escaped white spaces as field separators function reparse( i) { gsub(/\\ /, SUBSEP "s") gsub(/\\\t/, SUBSEP "t") for(i = 1; i <= NF; i++) { gsub(SUBSEP "s", "\\ ", $i) gsub(SUBSEP "t", "\\\t", $i) } }