SSブログ
シェルスクリプト ブログトップ

サブサーキットの階層表示 [シェルスクリプト]

SPICEネットリストねたをもうひとつ。

SPICEネットリストはサブサーキット(SUBCKT)という回路ブロックが階層構造をとっています。Cプログラムが関数によって構造化されているのと似ています。

SPICEネットリストを一見しただけでは、SUBCKTの階層構造を把握することは困難です。どのSUBCKTがどのSUBCKTを呼んでいるのか、何度もネットリストを読み返さなければなりません。

そこで、階層構造といえば「再帰呼び出し」です! コンピュータのファイルシステムの階層構造などを表示しようとすると再帰呼び出しを使います。ある関数が、その中で自分自身を呼び出す、というものです。

ファイルシステムの場合、何度も同じフォルダの中身をスキャンすることができますが、SPICEネットリストをシェルやawkで取り扱う場合、何度も読み直すことは困難です。

そこで、少し美しくないですが、SUBCKTごとに中身をファイルに書き出しておくことにしました。ファイル名をSUBCKT名にしておくことで、何度でも中身をcatすることとします。

できあがったのが以下です。以前紹介した、継続行処理を前処理として入れています。



#!/bin/sh
# cdltree -- print tree of cdl
# set input cdl file to INPUT variable.
# create SUBCKT_LIST of subckts include input cdl file.
# v1.0 /HORI @2015-07-15

#######################
# VARIABLE DEFINITION #
#######################

INPUT=./input.cdl
SUBCKT_LIST=./subckt_list
LEVEL=1
TOP_CELL_NAME=""

#######################
# FUNCTION DEFINITION #
#######################

# create subckt files
function mksubcktfiles() {
if [ -f $SUBCKT_LIST ]; then
rm -f $SUBCKT_LIST
fi

cat $INPUT | awk '

# de-plus
/^\+ /{
LINE = LINE substr($0, 3)
next
}
{
if (LINE != "") {
print LINE
}
LINE = $0
}
END{
print
}' | awk -v SUBCKT_LIST=$SUBCKT_LIST '

# create all subckt files except for primitive
/^\.SUBCKT/{
flg = 1
file_name = $2
print $2 >> SUBCKT_LIST
}
/\.ENDS/ && flg == 1{
flg = 0
}
flg == 1 && /^XI/{
print $NF > file_name
}'
}

# sort subckt file's contents
function sort_file() {
for FILE in `cat $SUBCKT_LIST`
do
if [ -f $FILE ]; then
cp -f $FILE tmp
cat tmp | sort | uniq > $FILE
fi
done
rm -f tmp
}

# get top cell name
function get_top_cell_name() {
TOP_CELL_NAME=`cat $INPUT | awk '
/^\* Top Cell Name:/{
print $5
}'`
echo "$TOP_CELL_NAME ($(( LEVEL - 1 )))"
}

# search tree
function subckt() {
TARGET=$1
if [ -f $TARGET ]; then
for ELEMENT in `cat $TARGET`
do
# create indent space
COUNT=$LEVEL
while (( COUNT-- ))
do
echo -n " "
if [ $COUNT -le 0 ]; then
break
fi
done
# print
echo "$ELEMENT ($LEVEL)"
LEVEL=$(( LEVEL + 1 ))
subckt $ELEMENT # recursive call
done
# end of list, return upper level
LEVEL=$(( $LEVEL - 1 ))
else
# file not found, that element is primitive, reset level
LEVEL=$(( $LEVEL - 1 ))
fi
}

# post processing
function post() {
for FILE in `cat $SUBCKT_LIST`
do
rm -f $FILE
done
}

################
# MAIN ROUTINE #
################

trap post 0 1 2 3 15 # signal 0 is normal exit
mksubcktfiles
sort_file
get_top_cell_name
subckt $TOP_CELL_NAME

#EOF


SPICEネットリストの折り返し行をくっつける [シェルスクリプト]

SPICEネットリストでは、長い1行には途中に改行を入れて折り返すことができますが、その際、折り返された行の行頭には「+」マークを付けることになっています。

これが、シェルやawkで処理する際に障壁になります。

そこで、前処理として、「+」で始まる行を前の行にくっつけて1行にしてしまうことにします。

シェルやawkが扱える1行の文字数には上限があります(昔のSunOSでは1024文字だったような)が、面倒になるのでここでは無視します。使用上の制約としておきます。

出来上がったawkスクリプトが以下です。attachという名前にしました。なかなかシンプルで気に入っています。もっとシンプルにできるものでしょうか。


#!/bin/awk -f
/^\+ /{
  LINE = LINE substr($0, 3)
  next
}
{
  if (LINE != "") {
    print LINE
  }
  LINE = $0
}
END{
  print
}

シェルスクリプト ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。