xschem/src/tedax.awk

180 lines
4.8 KiB
Awk
Executable File

#!/usr/bin/awk -f
#
# File: tedax.awk
#
# This file is part of XSCHEM,
# a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit
# simulation.
# Copyright (C) 1998-2024 Stefan Frederik Schippers
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
BEGIN{
}
##1 2 3 4 5 6
## inst net pin pinnumber pinindex
# conn U1:2 INPUT_A A 1:4:9:12 1
/^[ \t]*#/{ print; next}
/^begin netlist/{
print
next
}
/^begin_inst .* numslots/{
reparse()
numslots=$4;
if(numslots ==0) numslots = 1
next
}
$1=="device"||$1=="footprint"{
reparse()
arg1=$1; arg2=$2; $1=$2=""; $0=$0
gsub(/^[ \t]*/,"")
gsub(/[\\]? +/,"\\ ")
$0=arg1 " " arg2 " " $0
current_name=arg2
}
/^footprint/{
if(NF>=3) {
reparse()
fp=""
nn=split($2, inst_arr, ":")
inst_name=inst_arr[1]
for(i=3; i<=NF;i++) {
fp = ((i==3) ? $i : fp " " $i)
}
if(!(inst_name in footprint)) footprint_num[footprint_n++] = inst_name
footprint[inst_name] = fp
}
next
}
/^device/{
if(NF>=3) {
reparse()
dev=""
nn=split($2, inst_arr, ":")
inst_name=inst_arr[1]
for(i=3; i<=NF;i++) {
dev = ((i==3) ? $i : dev " " $i)
}
if(!(inst_name in device)) device_num[device_n++] = inst_name
device[inst_name] = dev
}
next
}
# conn U1 Tx2In Tx2\ In 10 10
/^conn/{
reparse()
nn=split($2, inst_arr, ":")
inst_name=inst_arr[1]
slot = (nn==2) ? inst_arr[2]+0 : 1
nn = split($5, pinlist_arr, ":")
pin_number= (nn>1) ? pinlist_arr[slot] : pinlist_arr[1]
pin_index = $6
pin_name = $4
net_name=$3
slotted=nn>1? 1:0
# even for unused slots initialize the arr[] array.
# conn lines need not to be printed but pinslot and pinidx lines do.
for(i=1; i<=numslots;i++) {
curr_pin = (nn>1) ? pinlist_arr[i]: pinlist_arr[1]
if(!((inst_name,curr_pin) in arr)) arr_num[arr_n++] = (inst_name SUBSEP curr_pin)
if(!((inst_name,curr_pin) in arr) || arr[inst_name,curr_pin]=="" || arr[inst_name,curr_pin] ~/^--UNCONN--/) {
if(curr_pin == pin_number) {
arr[inst_name,curr_pin]=net_name SUBSEP pin_index SUBSEP pin_name SUBSEP i SUBSEP slotted
} else {
arr[inst_name,curr_pin]="--UNCONN--" SUBSEP pin_index SUBSEP pin_name SUBSEP i SUBSEP slotted
}
# hidden connections (VCC, VSS on slotted devices, usually) specified on instance have higher
# precedence w.r.t. default specified in symbol.
} else if($0 ~ /# instance_based/ && curr_pin==pin_number) {
# overwrite with instance specified net name.
arr[inst_name,curr_pin]=net_name SUBSEP pin_index SUBSEP pin_name SUBSEP i SUBSEP slotted
}
}
next
}
/^(__subcircuit__|__map__|tEDAx v1|__GLOBAL__|__HIERSEP__)/ {
print
next
}
/^end_inst/{
next
}
/^end netlist/{
for(ii = 0; ii < arr_n; ii++) { # used to preserve ordering
i = arr_num[ii]
if(arr[i]) {
split(i, i_arr, SUBSEP)
split(arr[i], n_arr, SUBSEP)
slotted = n_arr[5]+0
# print "slotted=" slotted ">> " $0 > "/dev/stderr"
if(n_arr[1] !~/--UNCONN--/) print "conn", n_arr[1], i_arr[1], i_arr[2]
if(slotted) {
print "pinslot", i_arr[1], i_arr[2], n_arr[4]
print "pinidx", i_arr[1], i_arr[2], n_arr[2]
}
print "pinname", i_arr[1], i_arr[2], n_arr[3]
}
}
for(ii = 0; ii < footprint_n; ii++) { # used to preserve ordering
i = footprint_num[ii]
print "footprint", i, footprint[i]
}
for(ii = 0; ii < device_n; ii++) { # used to preserve ordering
i = device_num[ii]
print "device", i, device[i]
}
print $0
delete arr
delete arr_num # used to preserve ordering
arr_n = 0
delete footprint
delete footprint_num # used to preserve ordering
footprint_n = 0
delete device
delete device_num # used to preserve ordering
device_n = 0
next
}
$1 ~ /^(comptag|spicedev|spiceval|value)$/ {
if($1 == "comptag") for(i = 3; i<=NF; i+=2) print "comptag", $2, $i, $(i+1)
else if(NF > 2) print $0
next
}
# avoid considering escaped 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)
}
}