#!/bin/bash

# Script which loops thru boom/boog/loon and chooses the fastest
# result according to the criteria:
# 1/ Smallest critical path with 6fF wireload
# 2/ Then smallest critical path with 0fF wireload
# 3/ Then smallest area

# Script includes a forced exit for LOON if it locks up.

export VASY=vasy
export FLATBEH=flatbeh
export BOOM=boom
export BOOG=boog
export LOON=loon
export ASIMUT=asimut
export LVX=lvx
export X2Y=x2y
export FLATLO=flatlo
export CRIT_PATH=find_crit_path
export BOOG_CHECK=boog_check
export LOON_CHECK=loon_check

export BOOG_TARGET_LIB=/usr/share/pharosc/alliance/cells/vsclib013_6_min
export TARGET_LIB_6=/usr/share/pharosc/alliance/cells/vsclib013_6
export TARGET_LIB=/usr/share/pharosc/alliance/cells/vtclib013
export TARGET_NETLIST=/usr/share/pharosc/alliance/cells/vsclib_netlist

export RDS_TECHNO_200=/usr/share/pharosc/etc/vtc200.rds
export MBK_SPI_MODEL=/usr/share/pharosc/etc/spimodel.cfg
export DREAL_TECHNO_NAME=/usr/share/pharosc/etc/t200.dreal
export GRAAL_TECHNO_NAME=/usr/share/pharosc/etc/t.graal

export RDS_TECHNO_NAME=$RDS_TECHNO_200
export MBK_TARGET_LIB=$TARGET_LIB
export MBK_WORK_LIB=.
export MBK_IN_LO=vst
export MBK_OUT_LO=vst
export MBK_CATA_LIB=.:$MBK_TARGET_LIB:$TARGET_NETLIST
CATAL_NAME=VSCLIB013

cp $MBK_TARGET_LIB/$CATAL_NAME .
export MBK_CATAL_NAME=$CATAL_NAME

cell=adder4
track_pitch=8
row_height=72

min_path_delay=9999
all_path_delay=9999
vasy_netlists=99
max_netlists=9999
boom_duration=100
boog_timeout=3
loon_duration=4000
loon_timeout=10
short_sleep=0.5

# loop1 vasy with ripple carry option
# loop1 vasy with carry look ahead option
# loop1 boom to make set of different VBE files for synthesis
#   loop2 boom with opt levels 0-3
# loop1 boog thru boom netlists to get initial min drive strength VST netlists
#   loop2 boog with opt levels 0-4
# sort boog netlists numbering fastest first
# loop1 loon thru boog netlists
#   loop2 loon 6fF wireload using optimisation modes 0 and 1 (no buffer insertion)
#     loop3 loon 0fF
#       loop4 loon 0fF wireload timing
#         loop5 loon 6fF wireload timing and loon with 0fF and -m 1 for 0fF timing

kill_loon ()
{
  kill_loop=0
  while [ "$(ps -a | grep ' loon$' | tail -1 | sed 's/^ *//' | tr -s ' ' ' ' | cut -f1 -d' ')" != "" ]
  do
    kill -9 $(ps -a | grep ' loon$' | tail -1 | sed 's/^ *//' | tr -s ' ' ' ' | cut -f1 -d' ') 2>/dev/null
    if [ "$kill_loop" -gt 10 ]
    then
      break
    fi
    let "kill_loop=kill_loop+1"
  done
}
kill_boog_check ()
{
  if [ "$(ps -a | grep ' boog_check$' | tail -1 | sed 's/^ *//' | tr -s ' ' ' ' | cut -f1 -d' ')" != "" ]
  then
    kill -9 $(ps -a | grep ' boog_check$' | tail -1 | sed 's/^ *//' | tr -s ' ' ' ' | cut -f1 -d' ') 2>/dev/null
  fi
}
kill_loon_check ()
{
  if [ "$(ps -a | grep ' loon_check$' | tail -1 | sed 's/^ *//' | tr -s ' ' ' ' | cut -f1 -d' ')" != "" ]
  then
    kill -9 $(ps -a | grep ' loon_check$' | tail -1 | sed 's/^ *//' | tr -s ' ' ' ' | cut -f1 -d' ') 2>/dev/null
  fi
}
get_path_delay ()
{
  path_delay=$(cat $$loon_out | \
    grep 'Critical' | cut -f4 -d' ' | tr -s '.' '.' | cut -f2 -d'.')
  cell_gates=$(echo $[($(grep 'Area on file' $$loon_out | \
    sed -n '2 p' | cut -f4 -d' ' | tr -s . | cut -f3 -d'.') \
    +$track_pitch*$row_heig/usr/share/pharosc/$track_pitch/$row_height])
  rm -f $$loon_out
  case $path_delay in
  [0-9]|[0-9][0-9]|[0-9][0-9][0-9]|[0-9][0-9][0-9][0-9]|[0-9][0-9][0-9][0-9][0-9])
# complicated way to ignore path_delay unless it is positive integer less than 100000
    ;;
  *)
    continue
    ;;
  esac
}
check_or_continue ()
{
  if test ! -f "$1"
  then # ignore this loon if no xsc output file
    rm -f $$loon_out
    continue
  fi
  if test ! -f $$loon_out
  then # check it before using it to make sure
    continue
  fi
}
write_path_delay ()
#                $stage_loop $path_delay $min_path_delayx
{
  if [ "$3" = "" ]
  then
#   Use this path_delay
    let file_length=$(wc -l all_path_delay.log | cut -f1 -d' ')
    if [ "$file_length" -lt "$1" ]
    then echo $2 >> all_path_delay.log
    else sed -i "$1 s|^.*$|$2|" all_path_delay.log
    fi
  elif [ "$2" -lt "$3" ]
  then sed -i "$1 s|^.*$|$2|" all_path_delay.log
  fi
}

all=1
if [ "$all" -eq 1 ]
then
##### VASY LOOP #####
loop1=0; loop2=0
while [ "$loop1" -lt "$vasy_netlists" ]
do
  $VASY -a -B -o -p -I vhdl ${cell} >/dev/null
  netlist_exists=0
  loop3=0
  while [ "$loop3" -lt "$loop2" ]
  do
    if [ "$(diff -biq ${cell}.vbe ${cell}_a_${loop3}.vbe)" = "" ]
    then
      netlist_exists=1
      break
    fi
    let "loop3=loop3+1"
  done
  if [ "$netlist_exists" -eq 0 ]
  then
    mv ${cell}.vbe ${cell}_a_${loop2}.vbe
    let "loop2=loop2+1"
  fi
  let "loop1=loop1+1"
done

loop1=$loop2
while [ "$loop1" -lt "$vasy_netlists" ]
do
  $VASY -a -B -o -p -C 4 -I vhdl ${cell} >/dev/null
  netlist_exists=0
  loop3=0
  while [ "$loop3" -lt "$loop2" ]
  do
    if [ "$(diff -biq ${cell}.vbe ${cell}_a_${loop3}.vbe)" = "" ]
    then
      netlist_exists=1
      break
    fi
    let "loop3=loop3+1"
  done
  if [ "$netlist_exists" -eq 0 ]
  then
    mv ${cell}.vbe ${cell}_a_${loop2}.vbe
    let "loop2=loop2+1"
  fi
  let "loop1=loop1+1"
done

loop1=$loop2
while [ "$loop1" -lt "$vasy_netlists" ]
do
  $VASY -a -B -o -p -E 4 -I vhdl ${cell} >/dev/null
  netlist_exists=0
  loop3=0
  while [ "$loop3" -lt "$loop2" ]
  do
    if [ "$(diff -biq ${cell}.vbe ${cell}_a_${loop3}.vbe)" = "" ]
    then
      netlist_exists=1
      break
    fi
    let "loop3=loop3+1"
  done
  if [ "$netlist_exists" -eq 0 ]
  then
    mv ${cell}.vbe ${cell}_a_${loop2}.vbe
    let "loop2=loop2+1"
  fi
  let "loop1=loop1+1"
done

loop1=$loop2
while [ "$loop1" -lt "$vasy_netlists" ]
do
  $VASY -a -B -o -p -C 4 -E 4 -I vhdl ${cell} >/dev/null
  netlist_exists=0
  loop3=0
  while [ "$loop3" -lt "$loop2" ]
  do
    if [ "$(diff -biq ${cell}.vbe ${cell}_a_${loop3}.vbe)" = "" ]
    then
      netlist_exists=1
      break
    fi
    let "loop3=loop3+1"
  done
  if [ "$netlist_exists" -eq 0 ]
  then
    mv ${cell}.vbe ${cell}_a_${loop2}.vbe
    let "loop2=loop2+1"
  fi
  let "loop1=loop1+1"
done
let "vasy_netlists=loop2+1"

##### BOOM LOOP #####
loop1=0; loop2=0
while [ "$loop1" -lt "$vasy_netlists" ]
do
  if test -f "${cell}_a_${loop1}.vbe"
  then
    cp -p ${cell}_a_${loop1}.vbe ${cell}.vbe
  else
    break
  fi
  start_time=$(date '+%s')
  while [ "$loop2" -lt "$max_netlists" ]
  do
    run_time=$(date '+%s')
    let "elapsed_time=run_time-start_time"
    if [ "$elapsed_time" -ge "$boom_duration" ]
    then
      break
    fi
    for order in N Y
    do
      for level in 0 1 2 3
      do
        for delay in 0 25 50 75 100
        do
          export MBK_TARGET_LIB=$BOOG_TARGET_LIB
          if [ "$order" = N ]
          then
            $BOOM -APs -l $level -d $delay $cell ${cell}_b > /dev/null 2>/dev/null
          else
            $BOOM -AOPs -l $level -d $delay $cell ${cell}_b > /dev/null 2>/dev/null
          fi
          mv -f ${cell}_b.vbe ${cell}_b_${loop2}.vbe 2>/dev/null
          echo "${cell}_a_${loop1}" > ${cell}_b_${loop2}.log
          egrep -v '^--|^ *$' ${cell}_b_${loop2}.vbe > ${cell}_c_${loop2}.vbe

          prev_loop=0; netlist_exists=0
          while [ "$prev_loop" -lt "$loop2" ]
          do
            if [ "$(diff -biq ${cell}_c_${prev_loop}.vbe ${cell}_c_${loop2}.vbe)" = "" ]
            then
              netlist_exists=1
              break
            fi
            let "prev_loop=prev_loop+1"
          done
          if [ "$netlist_exists" -eq 1 ]
          then continue
          else
            if [ "$[$loop2%10]" -eq 0 ]
            then echo "# Netlist "${cell}_b_${loop2}".vbe from "${cell}_a_${loop1}".vbe"
            fi
            let "loop2=loop2+1"
          fi
        done
      done
    done
  done
  let "loop1=loop1+1"
done
let "boom_netlists=loop2+1"

echo "# "$boom_netlists" BOOM netlists written"
rm -f ${cell}_c_[0-9]*.vbe

##### BOOG LOOP #####
boog_loop=0
loop1=0
while [ "$loop1" -lt "$boom_netlists" ]
do 
  if test -f "${cell}_b_${loop1}.vbe"
  then
    cp -p ${cell}_b_${loop1}.vbe ${cell}_b.vbe
  else
    break
  fi
  for loop2 in 0 1 2 3 4
  do
    rm -f ${cell}_c_${boog_loop}.xsc
    export MBK_WORK_LIB=.
    export MBK_IN_LO=vst
    export MBK_OUT_LO=vst
    export MBK_TARGET_LIB=$BOOG_TARGET_LIB
    nice -10 $BOOG_CHECK ${cell}_c_${boog_loop}.xsc $short_sleep $boog_timeout &
    nice -10 $BOOG -l ../boog${loop2} ${cell}_b ${cell}_c_${boog_loop} >/dev/null
    kill_boog_check
    if test ! -f "${cell}_c_${boog_loop}.xsc"
    then continue
    fi

    if test ! -f "${cell}_c_${boog_loop}.vst"
    then
      continue
    fi
    rm -f ${cell}_a.vst
    path_delay=$($LOON -x 0 -l ../loon0 ${cell}_c_${boog_loop} ${cell}_a | \
      grep 'Critical' | \
      cut -f4 -d' ' | \
      tr -s '.' '.' | \
      cut -f2 -d'.')
    if test ! -f "${cell}_a.vst"
    then
      continue
    fi
    if [ "$path_delay" -lt "$min_path_delay" ]
    then
      min_path_delay=$path_delay
      echo "# BOOG loop "$boog_loop" Critical path ..."$min_path_delay" ps from "${cell}"_b_"${loop1}".vbe prio="$loop2
    fi
    mv -f ${cell}_a.vst ${cell}_d_${boog_loop}.vst 2>/dev/null
    mv -f ${cell}_a.xsc ${cell}_d_${boog_loop}.xsc 2>/dev/null

    prev_loop=0; netlist_exists=0
    while [ "$prev_loop" -lt "$boog_loop" ]
    do
#     If instances compare OK then assume netlists are the same
      if [ ! -f "${cell}_d_${prev_loop}" -o ! -f "${cell}_d_${boog_loop}" ]
      then
        let "prev_loop=prev_loop+1"
        continue
      fi
      inst_compare=$($LVX vst vst ${cell}_d_${prev_loop} ${cell}_d_${boog_loop} | \
        sed -n '/Compare Instances/,+1 p' | \
        tail -1 | \
        tr -s '\t' ' ' | \
        cut -f2 -d' ')
      if [ "$inst_compare" = "O.K." ]
      then
        netlist_exists=1
        break
      fi
      let "prev_loop=prev_loop+1"
    done
    if [ "$netlist_exists" -eq 1 ]
    then
#      echo "# BOOG loop "$boog_loop" opt level "$loop2" = loop "$prev_loop
      continue
    else
      echo ${cell}"_b_"${loop1}" "${cell}"_d_"${boog_loop}" "$path_delay > ${cell}_d_${boog_loop}.log
      if [ "$[$boog_loop%10]" -eq 0 ]
      then
        echo "# Netlist "${cell}_a_${boog_loop}".vst"
      fi
      let "boog_loop=boog_loop+1"
    fi
    if [ "$boog_loop" -ge "$max_netlists" ]
    then
      break
    fi
  done
  if test ! -f "${cell}_b_${loop1}.vbe"
  then
    break
  fi
  let "loop1=loop1+1"
done

if test -f "${cell}_b_0.vbe"
then
# sort according to delay and remove delay duplicates
  boog_loop=0
  cat ${cell}_d_[0-9]*.log | sort -b -n -u +2 2>/dev/null | \
  while read boog_field
  do
    boom_netlist=$(echo $boog_field | tr -s ' ' ' ' | cut -f1 -d' ')
    boog_netlist=$(echo $boog_field | tr -s ' ' ' ' | cut -f2 -d' ')
    cp -p ${boog_netlist}.vst ${cell}_a_${boog_loop}.vst
    cp -p ${boog_netlist}.xsc ${cell}_a_${boog_loop}.xsc
    echo ${boom_netlist} > ${cell}_a_${boog_loop}.log
    let "boog_loop=boog_loop+1"
    echo $boog_loop > $$temp1
  done

  boog_netlists=$(cat $$temp1)
  echo "# "$boog_netlists" BOOG netlists written"
  rm -f $$temp $$temp1

  rm -f ${cell}_[c-d]_[0-9]*.vst
  rm -f ${cell}_[c-d]_[0-9]*.xsc
  rm -f ${cell}_d_[0-9]*.log
fi
else
boog_netlists=$(ls ${cell}_a_[0-9]*.vst | grep -c '^')
fi
##### LOON LOOP #####
echo $all_path_delay > all_path_delay.log
error_out=0
max_loon_loop=0
loon_loop=0; out_loop=0
start_time=$(date '+%s')
loop1=0
while [ "$loop1" -lt "$boog_netlists" ]
do
  run_time=$(date '+%s')
  let "elapsed_time=run_time-start_time"
  if [ "$elapsed_time" -ge "$loon_duration" ]
  then
    break
  fi
  while  [ "$loop1" -lt "$boog_netlists" ]
  do
    if test -f "${cell}_a_${loop1}.vst"
    then
      cp ${cell}_a_${loop1}.vst ${cell}_a.vst
      break
    else
      let "loop1=loop1+1"
    fi
  done
  if [ "$loop1" -eq "$boog_netlists" ]
  then
    break
  fi
  echo "# BOOG netlist "$loop1
  first_loop2=1
  for loop2 in 0 1
  do
    stage_loop=1
    loon_loop=0
    prev_loon_loop=0
    min_path_delay=9999
    loop_seq=$loop2
#    if [ "$first_loop2" = 1 ]
#    then
#      first_loop2=0
#      echo $all_path_delay > all_path_delay.log
#    fi
    rm -f ${cell}_tmp.xsc
    export MBK_TARGET_LIB=$TARGET_LIB_6
    nice -10 $LOON_CHECK ${cell}_tmp.xsc $short_sleep $loon_timeout &
    nice -10 $LOON -x 0 -l ../loon${loop2} ${cell}_a ${cell}_tmp 2>/dev/null > $$loon_out
    kill_loon_check
    check_or_continue ${cell}_tmp.xsc
    rm -f ${cell}_b.xsc
    nice -10 $LOON_CHECK ${cell}_b.xsc $short_sleep $loon_timeout &
    nice -10 $LOON -x 0 -l ../loon0 ${cell}_tmp ${cell}_b 2>/dev/null > $$loon_out
    kill_loon_check
    check_or_continue ${cell}_b.xsc

    get_path_delay # gets $path_delay, $cell_gates and removes $$loon_out
    cur_path_delay=$(sed -n "$stage_loop p" all_path_delay.log)
    if [ "$path_delay" -lt "$cur_path_delay" ]
    then
      sed -i "$stage_loop s|^.*$|$path_delay|" all_path_delay.log
    fi
#echo "loop2="$loop2", stage_loop="$stage_loop", path_delay="$path_delay", min_path_delay="$min_path_delay

    while [ "$loon_loop" -ge 0 ]
    do
      first_loop3=1
      for loop3 in 0 1 2 4
      do
        if [ "$first_loop3" = 1 ]
        then
          let "stage_loop=stage_loop+1"
          first_loop3=0
        fi
        rm -f ${cell}_tmp.xsc
        export MBK_TARGET_LIB=$TARGET_LIB
        export MBK_CATA_LIB=.:$MBK_TARGET_LIB:$TARGET_NETLIST
        nice -10 $LOON_CHECK ${cell}_tmp.xsc $short_sleep $loon_timeout &
        nice -10 $LOON -x 0 -l ../loon${loop3} ${cell}_b ${cell}_tmp 2>/dev/null > $$loon_out
        kill_loon_check
        check_or_continue ${cell}_tmp.xsc # continue if ${cell}_tmp.xsc doesn't exist
        rm -f ${cell}_c.xsc
        nice -10 $LOON_CHECK ${cell}_c.xsc $short_sleep $loon_timeout &
        nice -10 $LOON -x 0 -l ../loon0 ${cell}_tmp ${cell}_c 2>/dev/null > $$loon_out
        kill_loon_check
        check_or_continue ${cell}_c.xsc

        get_path_delay # gets $path_delay, $cell_gates and removes $$loon_out
        cur_path_delay=$(sed -n "$stage_loop p" all_path_delay.log)
        write_path_delay $stage_loop $path_delay $cur_path_delay
#echo "loop3="$loop3", stage_loop="$stage_loop", path_delay="$path_delay", min_path_delay="$min_path_delay

        first_loop4=1
        for loop4 in 0 1 2 4
        do
          if [ "$first_loop4" = 1 ]
          then
            let "stage_loop=stage_loop+1"
            first_loop4=0
          fi
          rm -f ${cell}_tmp.xsc
          export MBK_TARGET_LIB=$TARGET_LIB_6
          export MBK_CATA_LIB=.:$MBK_TARGET_LIB:$TARGET_NETLIST
          nice -10 $LOON_CHECK ${cell}_tmp.xsc $short_sleep $loon_timeout &
          nice -10 $LOON -x 0 -l ../loon${loop4} ${cell}_c ${cell}_tmp 2>/dev/null > $$loon_out
          kill_loon_check
          check_or_continue ${cell}_tmp.xsc # continue if ${cell}_tmp.xsc doesn't exist
          rm -f ${cell}_d.xsc
          nice -10 $LOON_CHECK ${cell}_d.xsc $short_sleep $loon_timeout &
          nice -10 $LOON -x 0 -l ../loon0 ${cell}_tmp ${cell}_d 2>/dev/null > $$loon_out
          kill_loon_check
          check_or_continue ${cell}_d.xsc

          get_path_delay # gets $path_delay, $cell_gates and removes $$loon_out
          cur_path_delay=$(sed -n "$stage_loop p" all_path_delay.log)
          write_path_delay $stage_loop $path_delay $cur_path_delay
#echo "loop4="$loop4", stage_loop="$stage_loop", path_delay="$path_delay", min_path_delay="$min_path_delay

          first_loop5=1
          for loop5 in 0 1 2 4
          do
            if [ "$first_loop5" = 1 ]
            then
              let "stage_loop=stage_loop+1"
              first_loop5=0
            fi
            rm -f ${cell}_tmp.xsc
            export MBK_TARGET_LIB=$TARGET_LIB
            export MBK_CATA_LIB=.:$MBK_TARGET_LIB:$TARGET_NETLIST
            nice -10 $LOON_CHECK ${cell}_tmp.xsc $short_sleep $loon_timeout &
            nice -10 $LOON -x 0 -l ../loon${loop5} ${cell}_d ${cell}_tmp 2>/dev/null > $$loon_out
            kill_loon_check
            check_or_continue ${cell}_tmp.xsc # continue if ${cell}_tmp.xsc doesn't exist
            rm -f ${cell}_e.xsc
            nice -10 $LOON_CHECK ${cell}_e.xsc $short_sleep $loon_timeout &
            nice -10 $LOON -x 0 -l ../loon0 ${cell}_tmp ${cell}_e 2>/dev/null > $$loon_out
            kill_loon_check
            check_or_continue ${cell}_e.xsc

            get_path_delay # gets $path_delay, $cell_gates and removes $$loon_out
            cur_path_delay=$(sed -n "$stage_loop p" all_path_delay.log)
            write_path_delay $stage_loop $path_delay $cur_path_delay
#echo "loop5="$loop5", stage_loop="$stage_loop", path_delay="$path_delay", min_path_delay="$min_path_delay

            first_loop6=1
            for loop6 in 0 1 2 4
            do
              if [ "$first_loop6" = 1 ]
              then
                let "stage_loop=stage_loop+1"
                first_loop6=0
              fi
              rm -f ${cell}_tmp.xsc
              export MBK_TARGET_LIB=$TARGET_LIB_6
              export MBK_CATA_LIB=.:$MBK_TARGET_LIB:$TARGET_NETLIST
              nice -10 $LOON_CHECK ${cell}_tmp.xsc $short_sleep $loon_timeout &
              nice -10 $LOON -x 0 -l ../loon${loop6} ${cell}_e ${cell}_tmp 2>/dev/null > $$loon_out
              kill_loon_check
              check_or_continue ${cell}_tmp.xsc # continue if ${cell}_tmp.xsc doesn't exist
              rm -f ${cell}_f.xsc
              nice -10 $LOON_CHECK ${cell}_f.xsc $short_sleep $loon_timeout &
              nice -10 $LOON -x 0 -l ../loon0 ${cell}_tmp ${cell}_f 2>/dev/null > $$loon_out
              kill_loon_check
              check_or_continue ${cell}_f.xsc

              update=0
              cp -p $$loon_out ${cell}_f.loonout
              get_path_delay # gets $path_delay, $cell_gates and removes $$loon_out
              min_path_delay=$(sed -n "$stage_loop p" all_path_delay.log)
              write_path_delay $stage_loop $path_delay $min_path_delay
#echo "loop6="$loop6", stage_loop="$stage_loop", path_delay="$path_delay", min_path_delay="$min_path_delay
              if [ "$min_path_delay" = "" ]
              then
#             Use this path_delay
                min_path_delay=$path_delay
                let "file_length=$(wc -l all_path_delay.log | cut -f1 -d' ')+1"
                if [ "$file_length" -lt "$stage_loop" ]
                then
                  error_out=1
                  echo "#? Error: No delay in all_path_delay.log at stage_loop="$stage_loop", loon_loop="$loon_loop". STOP."
                  break
                elif [ "$file_length" -eq "$stage_loop" ]
                then
                  echo $min_path_delay >> all_path_delay.log
                else
                  sed -i "$stage_loop s|^.*$|$path_delay|" all_path_delay.log
                fi
                min_cell_gates=$cell_gates
                update=1
              elif [ "$path_delay" -lt "$min_path_delay" ]
#             This path delay is the fastest to this stage so far
              then
                min_path_delay=$path_delay
                sed -i "$stage_loop s|^.*$|$path_delay|" all_path_delay.log
                min_cell_gates=$cell_gates
                update=1
              elif [ "$path_delay" -eq "$min_path_delay" -a "$cell_gates" -lt "$min_cell_gates" ]
              then
#             Same delay as before but with fewer gates
                min_cell_gates=$cell_gates
                update=1
              fi
              if [ "$update" -eq 1 -a "$min_path_delay" -lt "$all_path_delay" ]
              then
                let "loon_loop=loon_loop+1"
                loop_init=${loop3}${loop4}
              else
                if [ "$min_path_delay" -lt "$all_path_delay" ]
                then echo "#? update=0 but min_path_delay "$min_path_delay" is less than all_path_delay "$all_path_delay"."
                fi
              fi
              if [ "$min_path_delay" -lt "$all_path_delay" ]
              then
                let "out_loop=out_loop+1"
                all_path_delay=$min_path_delay
                cp -p ${cell}_f.vst ${cell}_f_${out_loop}.vst
                cp -p ${cell}_f.xsc ${cell}_f_${out_loop}.xsc
                cp -p ${cell}_e.vst ${cell}_e_${out_loop}.vst
                cp -p ${cell}_e.xsc ${cell}_e_${out_loop}.xsc
                cp -p ${cell}_d.vst ${cell}_d_${out_loop}.vst
                cp -p ${cell}_d.xsc ${cell}_d_${out_loop}.xsc
                cp -p ${cell}_f.loonout ${cell}_f_${out_loop}.loonout
                echo "${cell}_a_${loop1}" > ${cell}_f_${out_loop}.log
                write_path_delay $stage_loop $path_delay $min_path_delay
                loop_init=${loop3}${loop4}
                echo "# BOOG netlist "$loop1", LOON loop "$loon_loop" Critical path ..."$all_path_delay" ps, Area ..."$min_cell_gates" tracks, sequence "${loop_seq}" "${loop3}${loop4}${loop5}${loop6}
              fi
            done #loop6
            if [ "$error_out" -eq 1 ]
            then
              break
            fi
            let "stage_loop=stage_loop-1"
          done #loop5
#         Make sure no loon processes still hanging
          kill_loon
          if [ "$error_out" -eq 1 ]
          then
            break
          fi
          let "stage_loop=stage_loop-1"
        done #loop4
        if [ "$error_out" -eq 1 ]
        then
          break
        fi
        let "stage_loop=stage_loop-1"
      done #loop3
      if [ "$error_out" -eq 1 ]
      then
        break
      fi
      if [ "$loon_loop" -eq "$prev_loon_loop" ]
      then # No improvement so break the while loop. Only way out.
        break
      fi
#     Use netlist from loop4 for next iteration
      let "stage_loop=stage_loop+1"
      cp ${cell}_d_${loon_loop}.vst ${cell}_b.vst
      loop_seq=${loop_seq}${loop_init}
      prev_loon_loop=$loon_loop
    done #loon_loop
    if [ "$error_out" -eq 1 ]; then break; fi
  done #loop2
  if [ "$error_out" -eq 1 ]
  then
    break
  fi
  let "loop1=loop1+1"
done #loop1

$FLATLO -r ${cell}_f_${out_loop} ${cell}_f
min_path_delay=9999
for loop7 in 0 1 2 4
do
  rm -f ${cell}_g.xsc
  export MBK_TARGET_LIB=$TARGET_LIB
  export MBK_CATA_LIB=.:$MBK_TARGET_LIB:$TARGET_NETLIST
  nice -10 $LOON_CHECK ${cell}_g.xsc $short_sleep $loon_timeout &
  nice -10 $LOON -x 0 -l ../loon${loop7} ${cell}_f ${cell}_g 2>/dev/null > $$loon_out
  kill_loon_check
  check_or_continue ${cell}_g.xsc # continue if ${cell}_g.xsc doesn't exist
  cp -p $$loon_out loon_out_0
#echo "loop7="$loop7", stage_loop="$stage_loop

  export MBK_TARGET_LIB=$TARGET_LIB_6
  export MBK_CATA_LIB=.:$MBK_TARGET_LIB:$TARGET_NETLIST
  for loop8 in 0 1 2 4
  do
    rm -f ${cell}_h.xsc
    nice -10 $LOON_CHECK ${cell}_h.xsc $short_sleep $loon_timeout &
    nice -10 $LOON -x 0 -l ../loon${loop8} ${cell}_g ${cell}_h 2>/dev/null > $$loon_out
    kill_loon_check
    check_or_continue ${cell}_h.xsc # continue if ${cell}_h.xsc doesn't exist
    cp -p $$loon_out loon_out_6

    get_path_delay # defines $path_delay and $cell_gates
#echo "loop8="$loop8", stage_loop="$stage_loop", path_delay="$path_delay", min_path_delay="$min_path_delay

    if [ "$path_delay" -lt "$min_path_delay" ]
    then
      min_path_delay=$path_delay
      min_cell_gates=$cell_gates
      cp -p loon_out_0 ${cell}_0.loonout
      cp -p loon_out_6 ${cell}_6.loonout
      cp -p ${cell}_g.xsc ${cell}_0.xsc
      cp -p ${cell}_g.vst ${cell}_0.vst
      cp -p ${cell}_h.xsc ${cell}.xsc
      cp -p ${cell}_h.vst ${cell}.vst
    elif [ "$path_delay" -eq "$min_path_delay" ]
    then
      if [ "$cell_gates" -le "$min_cell_gates" ]
      then
        min_cell_gates=$cell_gates
        cp -p loon_out_0 ${cell}_0.loonout
        cp -p loon_out_6 ${cell}_6.loonout
        cp -p ${cell}_g.xsc ${cell}_0.xsc
        cp -p ${cell}_g.vst ${cell}_0.vst
        cp -p ${cell}_h.xsc ${cell}.xsc
        cp -p ${cell}_h.vst ${cell}.vst
      fi
    fi
  done
done

boog_file=$(tail -1 ${cell}_f_${out_loop}.log)
cp -p ${boog_file}.vst ${cell}_o.vst 2>/dev/null

boom_file=$(tail -1 ${boog_file}.log)
cp -p ${boom_file}.vbe ${cell}_o.vbe 2>/dev/null

vasy_file=$(tail -1 ${boom_file}.log)
cp -p ${vasy_file}.vbe ${cell}.vbe 2>/dev/null

cat ${cell}_0.loonout
cat ${cell}_6.loonout

# HAVE TO USE X2Y TO REMOVE 1 BIT VECTORS WHICH MAKE THE LVS FAIL LATER

$X2Y vst vst ${cell}_0 ${cell}_0a
$X2Y vst vst ${cell} ${cell}_a
export MBK_TARGET_LIB=$TARGET_LIB
$LOON -x 0 -l ../loon0 ${cell}_0a ${cell}_0 2>/dev/null >/dev/null
export MBK_TARGET_LIB=$TARGET_LIB_6
$LOON -x 0 -l ../loon0 ${cell}_a ${cell} 2>/dev/null >/dev/null
rm -f ${cell}_0a.vst ${cell}_a.vst

$CRIT_PATH ${cell}_0 | tee ${cell}_0.path
$CRIT_PATH ${cell} | tee ${cell}_6.path

rm -f ${cell}_[a-f]_*.vst
rm -f ${cell}_[a-f]_*.xsc
rm -f ${cell}_[a-f]_*.log
rm -f ${cell}_[a-b]_*.vbe
rm -f ${cell}_[a-h].vst
rm -f ${cell}_[a-h].xsc
rm -f ${cell}_b.vbe
rm -f ${cell}_tmp.*

rm -f ${cell}_f*.loonout
rm -f all_path_delay.log
rm -f loon_out*
