#!/bin/sh
#
#   @(#)men2xnf8	9.3  7/11/95
#
###################################################################
#
# program: men2xnf8
# purpose: Extract Xilinx Netlist Format (XNF) from Mentor Design
# input: <design>
# output: <design>.xnf
# authors: Robert Maul, Rajesh Trivedi, Dale Walter, David Tseitlin
# Copyright (c) Xilinx 1992, All Rights Reserved
#
# 10/13/94 djt  version changed to 5.1.0
# 10/17/94 djt  version changed to 6.1.0; Added XC5200 
# 11/02/94 djt  calls external script 'find_cpu_type.sh'
#
# 12/08/94 djt  disabled message about machine type (bita 20443); 
#		version changed to pre5.1.1a (bita 20426)
#
# 01/19/95 djt  Because in 8.4 $invoke_tool can send space as an argument
#               (see pld_men2xnf8.qual), men2xnf8 has to deal with it.
#		This fixes bita 21137.
#		Also, calls 'version.sh'
#
# 03/22/95 djt  created a function edif2xnf_run; lcanet version changed to 6 (from 5)
#               - see bita 20444
#
# 03/22/95 djt  created function set_tech and fixed bita 22699
#
# 05/16/95 djt  created enwrite_run, rm_run, create_config_file; 
#		changed enwrite.cfg. This is part of the fix for bita 23973.
#
# 05/18/95 djt  created memgen_run, memgen_run_2; added check for existence
#		of *.mem files to fix bita 24083.
#
# 05/26/95 djt  Modified set_tech to handle JONATHAN (4000e)
#
# 07/10/95 djt  Added no_mem_file_exist to fix bita 25061; updated Copyright
#
###################################################################

  version=`version.sh`

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

this_cpu=`find_cpu_type.sh`

if [ "${this_cpu}" = "Unknown" ] ; then
   echo ""
   echo " Warning: cannot determine the type of this machine. "
#else 
   #echo " This machine was determined to be of type '${this_cpu}'. "
fi

if [ "${this_cpu}" = "apollo" ] ; then
   echo Changing path now...
   PATH=/bin:/usr/bin:/bsd4.3/usr/ucb:/sys5.3/usr/bin:$PATH
fi

#################################################################
# function: help
###################################################################

help() {
  cat <<EOF

This program extracts the Xilinx Netlist Format (XNF)
file from a Mentor V8 design (System V Bourne Shell)

Usage: men2xnf8 <design> -p <part_type> [ -m -verbose -help ]

  where <design> is the name of your mentor design directory
    -p <part_type> - Xilinx part type

    -m             - Run only memgen on *.mem files.
                     This option should be used when xblox has
                     generated skeleton *.mem files.

    -verbose       - Run the script in verbose mode.
                     All output messages will be  shown on monitor
                     as well as piped to men2xnf8.log file.

    -help          - Displays this message

Note:

    Your XACT environment variable must be set to the location
    of the installed Xilinx software.


Examples: men2xnf8 mydesign -p 4005pc84
          men2xnf8 mydesign -p 4005pc84 -verbose
          men2xnf8 mydesign -p 4005pc84 -m
          men2xnf8 mydesign -p 4005pc84 -m -verbose
          men2xnf8 mydesign -help

EOF

help_ret=1
return_code
}

#################################################################
# function: return_code
#################################################################

return_code() {

  if [ $ret -ne 0 ]; then
    if [ $program = "none" ] ; then
        echo "Errors found."
	echo "Check men2xnf8.log file and men2xnf8.sh file."
    else
        echo "Errors found while running $program."
	echo "Check men2xnf8.log file and men2xnf8.sh file."
    fi
  fi

  if [ $tail_flag = "true" ]; then
  	KillTailProcess
  fi

  #if [ $help_ret = 1 ]; then
  #fi

  rm -f $mmgc_wd/.retcode
  echo $ret > $mmgc_wd/.retcode
  MGC_WD=$old_mgc_wd
  export MGC_WD
  echo "Men2xnf8 ended with return code " $ret
  echo "Done."
  exit $ret
}


#################################################################
# function: KillTailProcess
#################################################################

KillTailProcess() {
        echo "The following message about killing the tail process"
	echo "is to be expected.  Do not be alarmed by it."
	echo "Killing tail -f men2xnf8.log process: $!"
	echo "Killing tail -f men2xnf8.log process: $!" >> $log_file 2>&1
	kill $!
}

#################################################################
no_mem_file_exist_fnc() {
	ls *.mem >/dev/null 2>/dev/null
	no_mem_file_exist=$?
}

#################################################################
# function: run memgen on *.mem files which are more recent
#           than the corresponding *.xnf files.
# input: *.mem files
# output: *.xnf files
#################################################################

memgen_run() {

    program="memgen"

    for mem in `ls *.mem`
      do
        run_memgen="false"
        fn=`basename $mem .mem`
  
        if [ -f $fn.xnf ]; then
          both_files=`ls -c $fn.mem $fn.xnf`
          young_one=`echo $both_files | cut -f1 -d" "`
          if [ $young_one = $fn.mem ]; then
            run_memgen="true"
          fi
        else
          run_memgen="true"
        fi
  
        if [ $run_memgen = "true" ]; then
          echo "memgen $fn.mem"
          echo "memgen $fn.mem" >> $sh_file 2>&1
          echo "memgen $fn.mem" >> $log_file 2>&1
          memgen $fn.mem >> $log_file 2>&1
          ret=$?
          if [ $ret -ne 0 ]; then
            return_code
          fi
        fi

      done

    ret=0
    return_code

}

#################################################################
# function: run memgen on *.mem files which are more recent
#           than the corresponding *.xnf files.
# input: *.mem files
# output: *.xnf files
#################################################################

memgen_run_2() {

    program="memgen"

    for mem in `ls *.mem`
      do
        run_memgen="false"
        fn=`basename $mem .mem`
  
        if [ -f $fn.xnf ]; then
          both_files=`ls -c $fn.mem $fn.xnf`
          young_one=`echo $both_files | cut -f1 -d" "`
          if [ $young_one = $fn.mem ]; then
            run_memgen="true"
          fi
        else
          run_memgen="true"
        fi
  
        if [ $run_memgen = "true" ]; then
          if [ -f $design.ulf ] ; then
            echo "memgen $fn.mem"
            echo "memgen $fn.mem" >> $sh_file 2>&1
            echo "memgen $fn.mem" >> $log_file 2>&1
            memgen $fn.mem >> $log_file 2>&1
          else
            echo "memgen $fn.mem old_library=true"
            echo "memgen $fn.mem old_library=true" >> $sh_file 2>&1
            echo "memgen $fn.mem old_library=true" >> $log_file 2>&1
            memgen $fn.mem old_library=true >> $log_file 2>&1
          fi
          ret=$?
          if [ $ret -ne 0 ]; then
            return_code
          fi
        fi
      done
}

#################################################################
# function: edif2xnf_run
# input: $design.edif
# output: $design.xnf
###################################################################

edif2xnf_run() {

  program="edif2xnf"
  lcanet_ver="6"

  if [ -f $design.ulf ]; then
     cmd="edif2xnf $design.edif -l $LCA/data/unified/$edif_data -lcanet $lcanet_ver -n -p $part -f -od $head -of $leaf.xnf"
  else
     cmd="edif2xnf $design.edif -lcanet $lcanet_ver -n -p $part -f -od $head -of $leaf.xnf"
  fi

  echo "$cmd"
  echo "$cmd" >> $sh_file 2>&1
  echo "$cmd" >> $log_file 2>&1
  $cmd >> $log_file 2>&1

  ret=$?
  if [ $ret -ne 0 ]; then
    return_code
  fi
}


###################################################################

create_config_file_5200() {

cat > enwrite.cfg <<!
     SET PR M -E
     SET SCOPE "$LCA/$tech" "osc5"
     IGN PROP "DIVIDE1_BY"
     IGN PROP "DIVIDE2_BY"
     SET SCOPE "$LCA/$tech" "ck_div"
     IGN PROP "DIVIDE1_BY"
     IGN PROP "DIVIDE2_BY"
!

}

###################################################################

create_config_file() {

  rm_run enwrite.cfg

  if [ $tech = "xc5200" ]; then
    create_config_file_5200
  else
    echo "SET PR M -E" > enwrite.cfg
  fi

}

###################################################################

rm_run() {

  program="rm"
  cmd="rm -f $1"

  echo "$cmd"
  echo "$cmd" >> $sh_file 2>&1
  echo "$cmd" >> $log_file 2>&1
  $cmd >> $log_file 2>&1

  ret=$?
  if [ $ret -ne 0 ]; then
    return_code
  fi

}

###################################################################

enwrite_run() {

  create_config_file

  program="enwrite"
  cmd="$MGC_HOME/bin/enwrite $design/xnf -wef $design.edif -rcf enwrite.cfg"

  echo "$cmd"
  echo "$cmd" >> $sh_file 2>&1
  echo "$cmd" >> $log_file 2>&1
  $cmd >> $log_file 2>&1

  ret=$?
  if [ $ret -ne 0 ]; then
    ret=1
    return_code
  fi

  grep "Error:" $log_file | grep "//" > /dev/null
  ret=$?
  if [ $ret -eq 0 ]; then
    ret=1
    return_code
  fi

}

#################################################################
# function: set_tech
# sets technology and family
###################################################################

set_tech() {

xc=`echo $part | cut -c-2 | tr "[a-z]" "[A-Z]"`

if [ $xc = "XC" ] ; then
  family=`echo $part | cut -c3`
  part=`echo $part | cut -c3-`
else 
  family=`echo $part | cut -c1`
fi 

echo "Family = $family"
echo Part = $part

end=\000

if [ $family = "5" ]; then
  end=\200
elif [ $family = "4" ]; then
  suff=`echo $part | cut -c5 | tr "[a-z]" "[A-Z]"`
  if [ \( $suff = "E" \) -o \( $suff = "L" \) ] ; then
     end=\000e  # JONATHAN
  fi
fi

tech=xc$family$end
edif_data=edif$family$end

echo "Technology = $tech"

}

#################################################################
# start main shell
#################################################################

cat <<EOS

               MEN2XNF8 Version $version
             Copyright (c) Xilinx 1994-1995, All Rights Reserved

                     UNPUBLISHED, LICENSED SOFTWARE.
          CONFIDENTIAL AND PROPRIETARY INFORMATION WHICH IS THE
                  PROPERTY OF XILINX OR ITS LICENSORS.


EOS

#################################################################
# init parameters
#################################################################

# Begin Variables

xblox_opt="true"
memgen_only="false"
verbose_opt="false"
tail_flag="false"
help_ret=0
ret=0
err_ret=0
err_opt=" "

# End Variables

if [ $# -lt 1 ] ; then
  help_ret=1
fi


#################################################################
# scan off command line arguments
#################################################################

while [ $# -gt 0 ]; do

  if [ null$1 = "null" ]; then
    shift
  elif [ $1 = "-p" ]; then
    shift
    if [ ! $# -gt 0 ]; then
      err_msg="Error: -p requires part type as an argument"
      #echo "Error: -p requires part type as an argument"
      #echo "Error: -p requires part type as an argument" >> $log_file 2>&1
      err_ret=1
      #help
    else
      part=$1
      shift
    fi
  elif [ $1 = "-P" ]; then
    shift
    if [ ! $# -gt 0 ]; then
      err_msg="Error: -p requires part type as an argument"
      #echo "Error: -p requires part type as an argument"
      #echo "Error: -p requires part type as an argument" >> $log_file 2>&1
      err_ret=1
      #help
    else
      part=$1
      shift
    fi
  elif [ $1 = "-m" ]; then
    memgen_only="true"
    shift
  elif [ $1 = "-M" ]; then
    memgen_only="true"
    shift
  elif [ $1 = "-verbose" ]; then
    verbose_opt="true"
    shift
  elif [ $1 = "-VERBOSE" ]; then
    verbose_opt="true"
    shift
  elif [ $1 = "-h" ]; then
    help_ret=1
    shift
  elif [ $1 = "-H" ]; then
    help_ret=1
    shift
  elif [ $1 = "-help" ]; then
    help_ret=1
    shift
  elif [ $1 = "-HELP" ]; then
    help_ret=1
    shift
  elif [ `echo $1 | cut -c1` = "-" ]; then
  	err_msg="Error: Illegal option specified on the command line:  "
	err_opt=$1
#  	echo "Error: illegal option $1 specified on the command line"
#  	echo "Error: illegal option $1 specified on the command line" >> $log_file 2>&1
        err_ret=1
	#help
        shift
  else
    design=$1
    shift
  fi

done


#################################################################
# strip off leading directory hierarchy for edifi2xnf -od argument
# use leaf for -of argument
#################################################################

tmp_design=`echo $design | sed -e 's|\(.*\)/\(.*\)|\1:\2|'`
head=`echo $tmp_design | cut -d: -f1`
leaf=`echo $tmp_design | cut -d: -f2`
if [ $head = $leaf ]; then
  head=`pwd | sed -e "s./tmp_mnt.."`
fi
if [ null$head = "null" ]; then
  head=`pwd | sed -e "s./tmp_mnt.."`
fi

###################################################################
# Reset MGC_WD to directory containing design...
###################################################################

old_mgc_wd=${MGC_WD}
MGC_WD=$head
export MGC_WD
mmgc_wd=`$MGC_HOME/bin/get_hard_name -s $MGC_WD`
echo "MGC_WD = " $MGC_WD
log_file=$mmgc_wd/men2xnf8.log
sh_file=$mmgc_wd/men2xnf8.sh

###################################################################
# create log file men2xnf8.log...
###################################################################

program="rm"
rm -f $log_file
ret=$?
if [ ! $ret -eq 0 ]; then
  return_code
fi

program="touch"
touch $log_file
ret=$?
if [ ! $ret -eq 0 ]; then
  return_code
fi


###################################################################
# create commands file men2xnf8.sh...
###################################################################

program="rm"
rm -f $sh_file
ret=$?
if [ ! $ret -eq 0 ]; then
  return_code
fi

program="touch"
touch $sh_file
ret=$?
if [ ! $ret -eq 0 ]; then
  return_code
fi
program="none"

echo "#!/bin/sh" >> $sh_file 2>&1
echo "" >> $sh_file 2>&1


if [ $help_ret -ne 0 ] ; then
  ret=0
  help
fi

if [ $err_ret -ne 0 ] ; then
  echo $err_msg $err_opt
  echo $err_msg $err_opt >> $log_file 2>&1
  ret=1
  help
fi

#################################################################
# check env variables
#################################################################

if [ null$XACT = "null" ]; then
  echo "Error: XACT variable needs to be set to location of Xilinx software"
  echo "Error: XACT variable needs to be set to location of Xilinx software" \
		>> $log_file 2>&1
  ret=1
  help
fi


if [ null$LCA = "null" ]; then
  echo "Error: LCA variable needs to be set to location of Xilinx/Mentor Kit"
  echo "Error: LCA variable needs to be set to location of Xilinx/Mentor Kit" \
		>> $log_file 2>&1
  ret=1
  help
fi


if [ ! -d $LCA ]; then
  echo "Error: LCA = $LCA , directory not found."
  echo "Error: LCA = $LCA , directory not found." >> $log_file 2>&1
  ret=1
  help
fi


if [ null$MGC_WD = "null" ]; then
  echo "Error: MGC_WD variable needs to be set to design directory"
  echo "Error: MGC_WD variable needs to be set to design directory" >> $log_file 2>&1
  ret=1
  help
fi


if [ ! -d $mmgc_wd ]; then
  echo "Error: MGC_WD = $mmgc_wd , directory not found."
  echo "Error: MGC_WD = $mmgc_wd , directory not found." >> $log_file 2>&1
  ret=1
  help
fi

if [ null$MGC_HOME = "null" ]; then
  echo "Error: MGC_HOME needs to be set to the MGC_HOME tree."
  echo "Error: MGC_HOME needs to be set to the MGC_HOME tree." >> $log_file 2>&1
  echo ""
  ret=1
  help
fi

if [ ! -d $MGC_HOME ]; then
  echo "Error: MGC_HOME = $MGC_HOME , directory not found!"
  echo "Error: MGC_HOME = $MGC_HOME , directory not found!" >> $log_file 2>&1
  echo ""
  ret=1
  help
fi



#################################################################
# check command line options and arguments
#################################################################

if [ null$design = "null" ]; then
  echo "Error: <design> not specified on command line"
  echo "Error: <design> not specified on command line" >> $log_file 2>&1
  ret=1
  help
fi

if [ ! -d $design ]; then
  echo "Error: <design> = $design , directory not found!"
  echo "Error: <design> = $design , directory not found!" >> $log_file 2>&1
  echo ""
  ret=1
  help
fi

if [ null$part = "null" ]; then
	echo "Error: -p <part_type> not specifed on command line."
	echo "Error: -p <part_type> not specifed on command line." >> $log_file 2>&1
        ret=1
	help
fi

set_tech

if [ $memgen_only != "true" ]; then
	if [ ! \( \( $family = "2" \) -o \( $family = "3" \) -o \( $family = "4" \) \) ]; then

		if [ ! \( \( $family = "5" \) -o \( $family = "7" \) -o \( $family = "8" \) \) ]; then
	 		echo "Error: -p $part , part_type must start with 2, 3, 4, 5, 7, or 8"
			echo "Error: -p $part , part_type must start with 2, 3, 4, 5, 7, or 8" >> \
			  $log_file 2>&1
                	ret=1
		 	help
		fi
	fi
fi



###################################################################
# function: if verbose option is specified then start the tail
#           process.
# input: men2xnf8.log
# output:
###################################################################

if [ $verbose_opt = "true" ]; then

	echo "tail -f " $log_file " &" >> $log_file 2>&1
	tail -f $log_file &

	trap return_code 2
	tail_flag="true"
fi


########################  Invoke Point Tools  #####################




########################  Main Design Flow ########################


########################  pld_dve  ################################


###################################################################
# function: run pld_dve on $design
# condition: pld_dve needs to be run only once.
#            If $design/xnf.Eddm_design_viewpoint.attr file exists,
#            then don't run pld_dve.
# input: $design
# output: $design/xnf.Eddm_design_viewpoint.attr
###################################################################

if [ \( ! -f $design/xnf.Eddm_design_viewpoint.attr \) ]; then

  program="pld_dve"
  echo "pld_dve $design $tech"
  echo "pld_dve $design $tech" >> $sh_file 2>&1
  echo "pld_dve $design $tech" >> $log_file 2>&1
  pld_dve $design  $tech >> $log_file 2>&1
  ret=$?
  if [ $ret -ne 0 ]; then
    return_code
  fi

  grep "Error:" $log_file | grep "//" > /dev/null
  ret=$?
  if [ $ret -eq 0 ] ; then
    ret=1
    return_code
  fi

fi


#

###################################################################
# remove $design.edif file
###################################################################
program="rm"
echo "rm -f $design.edif"
echo "rm -f $design.edif" >> $sh_file 2>&1
echo "rm -f $design.edif" >> $log_file 2>&1
rm -f $design.edif >> $log_file 2>&1
ret=$?
if [ $ret -ne 0 ]; then
  return_code
fi


#######################  enwrite  ################################

enwrite_run


###################################################################
# function: clean up flag files
# They are used by funcsim.sh to see if XBLOX or PPR JUSTFLATTEN
# is needed. EDIF2XNF will create them when external file references,
# FILE=<fn>[.xnf]), XBLOX primitives, {DEF=BLOX}, or hard macros,
# {DEF=HM}, are found while translating.
# $design.fil flag file is created if there are any FILE= references
# in $design.xnf file.
###################################################################

program="rm"
echo "rm -f $design.flt"
echo "rm -f $design.flt" >> $sh_file 2>&1
echo "rm -f $design.flt" >> $log_file 2>&1
rm -f $design.flt >> $log_file 2>&1

echo "rm -f $design.fpf"
echo "rm -f $design.fpf" >> $sh_file 2>&1
echo "rm -f $design.fpf" >> $log_file 2>&1
rm -f $design.fpf >> $log_file 2>&1

echo "rm -f $design.hmf"
echo "rm -f $design.hmf" >> $sh_file 2>&1
echo "rm -f $design.hmf" >> $log_file 2>&1
rm -f $design.hmf >> $log_file 2>&1

echo "rm -f $design.bmf"
echo "rm -f $design.bmf" >> $sh_file 2>&1
echo "rm -f $design.bmf" >> $log_file 2>&1
rm -f $design.bmf >> $log_file 2>&1

# pld file used to indicate presence of DEF=PLD symbol(s).
echo "rm -f $design.pld"
echo "rm -f $design.pld" >> $sh_file 2>&1
echo "rm -f $design.pld" >> $log_file 2>&1
rm -f $design.pld >> $log_file 2>&1

grep -i 'property def' $design.edif | grep -i pld > /dev/null
ret=$?
if [ $ret -eq 0 ] ; then
  program="touch"
  touch $design.pld
  ret=$?
  if [ ! $ret -eq 0 ]; then
    return_code
  fi
fi

# ulf file used to indicate that the Unified Library parts were found in edif.
echo "rm -f $design.ulf"
echo "rm -f $design.ulf" >> $sh_file 2>&1
echo "rm -f $design.ulf" >> $log_file 2>&1
rm -f $design.ulf >> $log_file 2>&1

grep -i libver $design.edif > /dev/null
ret=$?
if [ $ret -eq 0 ] ; then
  program="touch"
  touch $design.ulf
  ret=$?
  if [ ! $ret -eq 0 ]; then
    return_code
  fi
fi

# clb file used to indicate that CLB's/IOB's/EQN's were used in design.
echo "rm -f $design.clb"
echo "rm -f $design.clb" >> $sh_file 2>&1
echo "rm -f $design.clb" >> $log_file 2>&1
rm -f $design.clb >> $log_file 2>&1

grep -i 'property comp' $design.edif | grep -i clb | grep -v -i clbmap > /dev/null
ret=$?
if [ $ret -eq 0 ] ; then
  program="touch"
  touch $design.clb
  ret=$?
  if [ ! $ret -eq 0 ]; then
    return_code
  fi
fi

grep -i 'property comp' $design.edif | grep -i iob | grep -v -i clbmap > /dev/null
ret=$?
if [ $ret -eq 0 ] ; then
  program="touch"
  touch $design.clb
  ret=$?
  if [ ! $ret -eq 0 ]; then
    return_code
  fi
fi

grep -i 'property comp' $design.edif | grep -i eqn > /dev/null
ret=$?
if [ $ret -eq 0 ] ; then
  program="touch"
  touch $design.clb
  ret=$?
  if [ ! $ret -eq 0 ]; then
    return_code
  fi
fi

########################  -m switch  ##############################

if [ $memgen_only = "true" ]; then

  no_mem_file_exist_fnc
  #echo "no_mem_file_exist=" $no_mem_file_exist

  if [ $no_mem_file_exist = 0 ]; then
    memgen_run
  fi

fi

########################  edif2xnf  ###############################

edif2xnf_run


if [ -f $design.bmf ]; then
  if [ \( $family != "4" \) -a \( $family != "5" \) -a \( $family != "3" \) ]; then
    echo "Error: edif2xnf has generated $design.bmf file for a non-3/4/5.2K design."
    echo "Error: edif2xnf has generated $design.bmf file for a non-3/4/5.2K design." \
		 >> $log_file 2>&1
    ret=1
    return_code
  fi
fi

if [ -f $design.hmf ]; then
  if [ $family != "4" ]; then
    echo "Error: 'edif2xnf' has generated $design.hmf file for a non-4K design."
    echo "Error: 'edif2xnf' has generated $design.hmf file for a non-4K design." \
		 >> $log_file 2>&1
    ret=1
    return_code
  fi
fi


########################  memgen  #################################

if [ -f $design.fpf ]; then

  if [ $family = "4" ]; then

    no_mem_file_exist_fnc
    #echo "no_mem_file_exist=" $no_mem_file_exist

    if [ $no_mem_file_exist = 0 ]; then
      memgen_run_2
    fi

  fi

fi

###################################################################
ret=0
return_code
###################################################################
