#!/bin/bash

# Script which converts the original sclib layout cell to
# one that can be used with Alliance version 5 software

# Also fixes cmx2_y.vbe, xr2_y.vbe, nxr2_y.vbe and all area value that are 100X too big
# Adds afeter clause to logic expression in VBE file

comments_on=0
source_dir=/home/cad/alliance-4.0.6/share/cells/sclib

if [ "$#" -eq 0 ]
then
  echo "# Usage: convert_cell cell" 1>&2
  echo "#   eg  convert_cell fred" 1>&2
  exit 1
fi

if test -f ${source_dir}/$1.ap
then
  cell=$1
else
  echo "# Usage: convert_cell cell" 1>&2
  echo "#   eg  convert_cell fred" 1>&2
  exit 1
fi
start_time=$(date '+%s')
metal_width=2
metal_pitch=6
supply_width=6

cp ${source_dir}/${cell}.ap $$_temp1
mbk_scale=$(grep '^H ' $$_temp1 | cut -f4 -d,)
let snap_grid=${mbk_scale}/2
#
#                                        Remove TALU2 and change ALU2 to ALU3
#
grep -v 'TALU2' $$_temp1 | \
  sed 's/ALU3$/ALU4/' | \
  sed 's/ALU2$/ALU3/' | \
  sed 's/CONT_VIA/CONT_VIA2/' > $$_temp
#
#                          Copy ALU1 vdd and vss connectors to 6 lambda wide CALU1 and CALU2
#
for supply in vss vdd
do
  xmin=$(grep "$supply" $$_temp | grep '^C ' | grep WEST | cut -f1 -d, | cut -f2 -d' ')
  xmax=$(grep "$supply" $$_temp | grep '^C ' | grep EAST | cut -f1 -d, | cut -f2 -d' ')
  ycoord=$(grep "$supply" $$_temp | grep '^C ' | grep EAST | cut -f2 -d,)
  width=$(grep "$supply" $$_temp | grep '^C ' | grep EAST | cut -f3 -d,)
  let "new_width=supply_width*mbk_scale"
  if [ "$supply" = vss ]
  then
    let "ynew=ycoord+(width-new_width)/2"
  else
    let "ynew=ycoord-(width-new_width)/2"
  fi
  segment1=$(echo "S ${xmin},${ynew},${xmax},${ynew},${new_width},${supply},RIGHT,CALU1")
  segment2=$(echo "S ${xmin},${ynew},${xmax},${ynew},${new_width},${supply},RIGHT,CALU2")
  sed -i "s/^EOF *$/${segment1}\n${segment2}\nEOF/" $$_temp
done
egrep -v '^C .*,vss|^C .*,vdd' $$_temp > $$_temp1
#
#                                    Change signal connectors to CALU3 connectors
#
pinlist=$(grep '^C ' $$_temp1 | egrep 'NORTH|SOUTH' | cut -f4 -d, | sort -u)
for pin in $pinlist
do
  xcoord=$(grep '^C ' $$_temp1 | grep "$pin" | grep SOUTH | cut -f1 -d, | cut -f2 -d' ')
  ymin=$(grep '^C ' $$_temp1 | grep "$pin" | grep SOUTH | cut -f2 -d,)
  ymax=$(grep '^C ' $$_temp1 | grep "$pin" | grep NORTH | cut -f2 -d,)
  let "width=metal_width*mbk_scale"
# Check whether the via2 to ALU2 is on or off grid. If it's off grid then we
# have to stop horizontal ALU3 connections in case they cause DRC violations
  vias=$(grep '^V .*,CONT_VIA2 *$' $$_temp1 | sed 's/^V  */V,/')
  for via in $vias
  do
    let x_pos=$(echo $via | cut -f2 -d,)
    if [ "$x_pos" -eq "$xcoord" ]
    then
      let y_pos=$(echo $via | cut -f3 -d,)-$ymin
      let "y_rem=(y_pos*1000/mbk_scale)%(metal_pitch*1000)"
      case $y_rem in
        0|500|1000|1500|4500|5000|5500)
          off_grid=0
          ;;
        2000|2500|3000|3500|4000)
          off_grid=1
          ;;
        *)
          echo "#? Error: illegal value for remainder "$y_rem" on via at "$via"." 1>&2
          off_grid=1
          ;;
      esac
      tsegment=$(echo "S ${xcoord},${ymin},${xcoord},${ymax},${width},\*,UP,TALU3")
      if [ "$off_grid" -eq 0 ]
      then
        segment=$(echo "S ${xcoord},${ymin},${xcoord},${ymax},${width},${pin},UP,CALU3")
        sed -i "s/^EOF *$/${tsegment}\n${segment}\nEOF/" $$_temp1
      else
        segment1=$(echo "S ${xcoord},${ymin},${xcoord},${ymin},${width},${pin},UP,CALU3")
        segment2=$(echo "S ${xcoord},${ymax},${xcoord},${ymax},${width},${pin},UP,CALU3")
        sed -i "s/^EOF *$/${tsegment}\n${segment1}\n${segment2}\nEOF/" $$_temp1
      fi
    fi
  done
done
grep -v '^C .*ALU2 *$' $$_temp1 > $$_temp
#
#                          Make TALU2 geometry flush with AB in y and 1 lambda inside in x
#
let "xmin=$(grep '^A ' $$_temp | cut -f 1 -d, | cut -f2 -d' ')+metal_width*mbk_scale"
ymin=$(grep '^A ' $$_temp | cut -f 2 -d,)
let "xmax=$(grep '^A ' $$_temp | cut -f 3 -d,)-metal_width*mbk_scale"
ymax=$(grep '^A ' $$_temp | cut -f 4 -d,)
let "y_coord=(ymin+ymax)/2"
let "width=ymax-ymin+metal_width"
if [ "$cell" != tie_y ]
then
  sed "s/^A  *\([^,][^,]*\),\([^,][^,]*\),\([^,][^,]*\),\([^,][^,]*\) *$/A \1,\2,\3,\4\nS $xmin,$y_coord,$xmax,$y_coord,$width,\*,RIGHT,TALU2/" $$_temp > $$_temp1
else
  cp $$_temp $$_temp1
fi
cp $$_temp1 ${cell}.ap
#
#                                Add blockages where metal-2 is used inside the cells
#
if [ "$cell" = ms2dp2_y ]
then
  ymin=$(grep '^A ' ${cell}.ap | cut -f 2 -d,)
  ymax=$(grep '^A ' ${cell}.ap | cut -f 4 -d,)
  let "width=metal_width*mbk_scale"
  for x in 27 33 51 57 69 87
  do
    let "xcoord=x*mbk_scale"
    segment=$(echo "S ${xcoord},${ymin},${xcoord},${ymax},${width},*,UP,TALU3")
    sed -i "s/^EOF *$/${segment}\nEOF/" ${cell}.ap
  done
fi
if [ "$cell" = ms2dp4_y ]
then
  ymin=$(grep '^A ' ${cell}.ap | cut -f 2 -d,)
  ymax=$(grep '^A ' ${cell}.ap | cut -f 4 -d,)
  let "width=metal_width*mbk_scale"
  for x in 27 33 51 57 69 87
  do
    let "xcoord=x*mbk_scale"
    segment=$(echo "S ${xcoord},${ymin},${xcoord},${ymax},${width},*,UP,TALU3")
    sed -i "s/^EOF *$/${segment}\nEOF/" ${cell}.ap
  done
fi
if [ "$cell" = msdp2_y ]
then
  ymin=$(grep '^A ' ${cell}.ap | cut -f 2 -d,)
  ymax=$(grep '^A ' ${cell}.ap | cut -f 4 -d,)
  let "width=metal_width*mbk_scale"
  for x in 27 33 51 57 69 87
  do
    let "xcoord=x*mbk_scale"
    segment=$(echo "S ${xcoord},${ymin},${xcoord},${ymax},${width},*,UP,TALU3")
    sed -i "s/^EOF *$/${segment}\nEOF/" ${cell}.ap
  done
fi
if [ "$cell" = msdp4_y ]
then
  ymin=$(grep '^A ' ${cell}.ap | cut -f 2 -d,)
  ymax=$(grep '^A ' ${cell}.ap | cut -f 4 -d,)
  let "width=metal_width*mbk_scale"
  for x in 27 33 51 57 69 87
  do
    let "xcoord=x*mbk_scale"
    segment=$(echo "S ${xcoord},${ymin},${xcoord},${ymax},${width},*,UP,TALU3")
    sed -i "s/^EOF *$/${segment}\nEOF/" ${cell}.ap
  done
fi
#
#                                    Remove unnecessary metal-1 from feedthru cell
#
if [ "$cell" = tie_y ]
then
  cp ${cell}.ap $$_temp
  grep -v '^V 800,2900,CONT_BODY_N *$' $$_temp | \
  grep -v '^V 800,3300,CONT_BODY_N *$' | \
  grep -v '^V 800,3700,CONT_BODY_N *$' | \
  grep -v '^V 800,1600,CONT_BODY_P *$' | \
  grep -v '^V 800,1100,CONT_BODY_P *$' | \
  sed 's/S 800,300,800,1600,200,vss,UP,ALU1/S 800,300,800,700,200,vss,UP,ALU1/' | \
  sed 's/S 800,2900,800,4500,200,vdd,UP,ALU1/S 800,4100,800,4500,200,vdd,UP,ALU1/' > ${cell}.ap
fi
#
#                             Remove duplicated lines from three of the sclib VBE files
#
if [ "$cell" = cmx2_y ]
then
  sed '18 s/^ */--/' ${source_dir}/${cell}.vbe  | sed '22 s/^ */--/' > ${cell}.vbe
elif [ "$cell" = xr2_y ]
then
  sed '17 s/^ */--/' ${source_dir}/${cell}.vbe | \
  sed '19 s/^ */--/' | \
  sed '21 s/^\( *\)\(.*\)\(2490\)\(.*\)$/--\2\3\4\n\1\22415\4/' | \
  sed '26 s/^ */--/' | sed '28 s/^ */--/' | \
  sed '30 s/^\( *\)\(.*\)\(2490\)\(.*\)$/--\2\3\4\n\1\22415\4/' > ${cell}.vbe
elif [ "$cell" = nxr2_y ]
then
 sed '15 s/^ */--/' ${source_dir}/${cell}.vbe | \
 sed '17 s/^\( *\)\(.*\)\(2450\)\(.*\)$/--\2\3\4\n\1\22575\4/' | \
 sed '22 s/^ */--/' | sed '24 s/^ */--/' | \
 sed '26 s/^\( *\)\(.*\)\(2450\)\(.*\)$/--\2\3\4\n\1\22575\4/' | \
 sed '29 s/^ */--/' > ${cell}.vbe
else
  cp ${source_dir}/${cell}.vbe .
fi
#
#                                          Correct wrong area values
#
cp ${cell}.vbe $$_temp
sed 's/^\( *CONSTANT  *area *: *NATURAL *:= *[0-9][0-9]*\)\(00\)\( *;.*\)$/\1\3/' $$_temp | \
  sed 's/^ *REPORT  *\(.*\)$/  REPORT \1/' | \
  sed 's/^ *SEVERITY  *\(.*\)$/  SEVERITY \1/' | \
  grep -v '^ *-- *Architecture Declaration' > ${cell}.vbe
#
#                                            Add a simulator delay
#
if [ "$cell" != one_y -a "$cell" != zero_y ]
then
  sed -i 's/^ *\([^ ][^ ]*\)  *<= *\([^;][^;]*\); *$/  \1 <= \2 after 1000ps;/' ${cell}.vbe
fi
#
#                                   Change carry cell's logical expression
#
if [ "$cell" = cry_y ]
then
  sed -i 's/^\(.*\)<=\(.*\)$/--\1<=\2\n\1<= not ((si or (pi and ci)) and (pi or ci)) after 1000ps;/' ${cell}.vbe
fi

rm $$_temp $$_temp1

end_time=$(date '+%s')
let "elapsed_time=end_time-start_time"
echo "# convert_cell $cell in ${elapsed_time}s"