#!/bin/bash
# Script which changes a 2-AND with fanout of 1 followed by
# an inverter type iv1 with a fanout less than or equal to
# the value of argument_2 (or 1 if omitted) from netlist
# argument_1 to a 2-NAND.
# ONLY WORKS AFTER ANY VECTORED SIGNALS ( eg not(x(7) )
# HAVE BEEN CONVERTED TO NON-VECTORED WITH x2y.
if [ "$#" -eq 0 ]
then
echo "# Usage: lgc_an2iv1 [-r] netlist [fanout]" 1>&2
echo "#" 1>&2
echo "# will change a 2-AND with fanout 1" 1>&2
echo "# followed by an inverter type iv1 with a fanout" 1>&2
echo "# less than or equal to the value of argument_2 (or 1" 1>&2
echo "# if omitted) from netlist argument_1 to a 2-NAND." 1>&2
echo "# eg lgc_an2iv1 multi8 2" 1>&2
echo "# will change all 2-AND gates with FO=1 followed by" 1>&2
echo "# an inverter with FO<=2 with a 2-NAND." 1>&2
exit 1
fi
if [ "$1" = "-r" ]
then
shift
readonly=1
else
readonly=0
fi
if test -f $1.vst
then
netlist=$1.vst
else
echo "# Usage: lgc_an2iv1 [-r] netlist [fanout]" 1>&2
echo "#" 1>&2
echo "# The netlist supplied "$1".vst does not exist. Please check." 1>&2
exit 1
fi
if [ "$#" -eq 1 ]
then
fanout=2
else
fanout=$2
fi
ident1=an2
pin1_in1=a
pin1_in2=b
pin1_out=z
ident2=iv1
pin2_in1=a
pin2_out=z
ident3=nd2
pin3_in1=a
pin3_in2=b
pin3_out=z
grep '=>' $netlist | \
grep -v 'vdd *=>' | \
grep -v 'vss *=>' > netlist_nets
# Get instance name of all 2-AND cells
inst_names=$(grep "^ *[^ ][^ ]* *: *${ident1}v[^ ][^ ]* *$" $netlist | \
sed "s/ *\([^ ][^ ]*\) *: *${ident1}v[^ ][^ ]* *$/\1/")
if [ "$inst_names" = "" ]
then
echo "# No 2-AND gates plus inverter can be replaced with 2-NAND"
exit
fi
#echo "# Write 2-AND instance descriptions to a temp file"
for inst_name in $inst_names
do
sed -n "/^ *$inst_name *:/,/^[^)][^)]*) *; *$/ p" $netlist > $$inst
inst=$(head -1 $$inst | \
sed 's/^ *\([^ ][^ ]*\) *:.*$/\1/')
net1_in1=$(grep "^ *$pin1_in1 *=>" $$inst | \
sed "s/^ *$pin1_in1 *=> *\([^ ][^ ]*\) *,* *$/\1/" | \
sed 's/,$//')
net1_in2=$(grep "^ *$pin1_in2 *=>" $$inst | \
sed "s/^ *$pin1_in2 *=> *\([^ ][^ ]*\) *,* *$/\1/" | \
sed 's/,$//')
net1_out=$(grep "^ *$pin1_out *=>" $$inst | \
sed "s/^ *$pin1_out *=> *\([^ ][^ ]*\) *,* *$/\1/" | \
sed 's/,$//')
let "comp1_fanout=$(grep -c "=> *$net1_out *," netlist_nets)-1"
if [ "$comp1_fanout" -eq 1 ]
then
echo "$inst $net1_in1 $net1_in2 $net1_out $comp1_fanout" >> $$comp1_insts
fi
done
rm -f $$inst
if test ! -s $$comp1_insts
then
echo "# No 2-AND gates plus inverter can be replaced with 2-NAND"
exit 0
fi
inst_names=$(grep "^ *[^ ][^ ]* *: *${ident2}v[^ ][^ ]* *$" $netlist | \
sed "s/ *\([^ ][^ ]*\) *: *${ident2}v[^ ][^ ]* *$/\1/")
if [ "$inst_names" = "" ]
then
echo "# No 2-AND gates plus inverter can be replaced with 2-NAND"
exit
fi
#echo "# Write inverter instance descriptions to a temp file"
for inst_name in $inst_names
do
sed -n "/^ *$inst_name *:/,/^[^)][^)]*) *; *$/ p" $netlist > $$inst
inst=$(head -1 $$inst | \
sed 's/^ *\([^ ][^ ]*\) *:.*$/\1/')
net2_in1=$(grep "^ *$pin2_in1 *=>" $$inst | \
sed "s/^ *$pin2_in1 *=> *\([^ ][^ ]*\) *,* *$/\1/" | \
sed 's/,$//')
net2_out=$(grep "^ *$pin2_out *=>" $$inst | \
sed "s/^ *$pin2_out *=> *\([^ ][^ ]*\) *,* *$/\1/" | \
sed 's/,$//')
let "comp2_fanout=$(grep -c "=> *$net2_out *," netlist_nets)-1"
if [ "$comp2_fanout" -le "$fanout" -a "$comp2_fanout" -gt 0 ]
then
echo "$inst $net2_in1 $net2_out $comp2_fanout" >> $$comp2_insts
fi
done
rm -f $$inst
#echo "# Select those 2-AND outputs connected to the input pin of an inverter with FO<=spec"
cat $$comp1_insts | \
while read line
do
net2_in=$(echo $line | cut -f4 -d' ')
grep "^ *[^ ][^ ]* *$net2_in *[^ ][^ ]* *[^ ][^ ]* *$" $$comp2_insts > $$comp3_insts
cat $$comp3_insts | \
while read line2
do
net2_out=$(echo $line2 | cut -f3 -d' ')
comp2_fanout=$(echo $line2 | cut -f4 -d' ')
if [ "$comp2_fanout" -le "$fanout" -a "$comp2_fanout" -gt 0 ]
then
inst2=$(echo $line2 | cut -f1 -d' ')
echo "$line $inst2 $net2_out $comp2_fanout" >> $$in2_names
fi
done
done
rm -f $$comp1_insts $$comp2_insts $$comp3_insts
# File $$in2_names has fields which are:
# inst1 net1_in1 net1_in2 net1_out fanout1 inst2 net2_out fanout2 (net2_in=net1_out)
# inst1 is a 2-AND; inst2 is an inverter with FO<= spec
# Now need to:
# - remove the instance in field 6 of in2_names from the netlist
# - change the inst1 comp from an2 to nd2
# - remove net name in field 7 of in2_names from signal list
# - change net name in field 7 of in2_names to the net name in field 4
if test -e $$in2_names
then
echo "# List of 2-AND instances with FO=1 followed by an inverter"
echo "# ---------------------------------------------------------"
cp $netlist ${netlist}_tmp
cat $$in2_names | \
while read line
do
inst1=$(echo $line | cut -f1 -d' ')
inst2=$(echo $line | cut -f6 -d' ')
net1_in1=$(echo $line | cut -f2 -d' ')
net1_in2=$(echo $line | cut -f3 -d' ')
net1_out=$(echo $line | cut -f4 -d' ')
net2_out=$(echo $line | cut -f7 -d' ')
comp_name=$(sed -n "s/^ *${inst1}\( *: *\)\([^ ][^ ]*\)\(v[0-9]x[0-9][0-9]*\) *$/${ident3}\3/ p" ${netlist}_tmp)
comp1_fanout=$(echo $line | cut -f5 -d' ')
comp2_fanout=$(echo $line | cut -f8 -d' ')
sed "/^ *$inst2 *:/,/^[^)][^)]*) *; *$/ d" ${netlist}_tmp | \
sed "s/^ *\($inst1 *: *\)\(${ident1}\)v/\1${ident3}v/" | \
grep -v "^ *signal *$net2_out " | \
sed "s/=> *$net2_out *,/=> $net1_out,/" > ${netlist}_out
echo "# $inst1 $comp1_fanout $inst2 $comp2_fanout"
comp_exists=$(grep -i "^ *component *$comp_name" ${netlist}_out | \
grep -c '^' )
if [ "$comp_exists" -eq 0 ]
then
sed -i "/^ *architecture / a\
Component $comp_name\\
port (\\
$pin3_in1 : in bit;\\
$pin3_in2 : in bit;\\
$pin3_out : out bit;\\
vdd : in bit;\\
vss : in bit\\
);\\
end component;" ${netlist}_out
fi
mv ${netlist}_out ${netlist}_tmp
done
if [ "$readonly" -eq 0 ]
then
mv -f ${netlist}_tmp ${netlist}
else
rm -f ${netlist}_tmp
fi
rm $$in2_names
else
echo "# No 2-AND gates plus inverter can be replaced with 2-NAND"
fi
rm -f netlist_nets |