vlsitechnology.org /cell_choice /ex0a_syn.html /lgc_an2iv1.html


#!/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