[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

gEDA-cvs: CVS update: gnet_hier_verilog.sh



  User: ahvezda 
  Date: 07/02/10 13:44:05

  Added:       .        gnet_hier_verilog.sh
  Log:
  Added new script for doing non-flatten herarchical Verilog netlist.
  
  Added AM_PROG_CC_C_O to configure.ac to make autoconf happy.
  
  
  
  
  Revision  Changes    Path
  1.1                  eda/geda/gaf/utils/scripts/gnet_hier_verilog.sh
  
  Index: gnet_hier_verilog.sh
  ===================================================================
  #!/bin/bash
  # gEDA - GPL Electronic Design Automation
  # Copyright (C) 2007 Paul Tan (pt75234 at users.sourceforge.net)
  #
  # This program is free software; you can redistribute it and/or modify
  # it under the terms of the GNU General Public License as published by
  # the Free Software Foundation; either version 2 of the License, or
  # (at your option) any later version.
  #
  # This program is distributed in the hope that it will be useful,
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  # GNU General Public License for more details.
  #
  # You should have received a copy of the GNU General Public License
  # along with this program; if not, write to the Free Software
  # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  # ========================================================
  # Description:  
  #   Generate non-flatten hierarchical Verilog netlist
  # gnet_hier_verilog.sh
  # version 0.0.2
  # Usage: 
  #   [path]gnet_hier_verilog.sh [path]FileName.sch
  # Requires gawk and gEDA's gnetlist gnet-verilog.scm
  # Please set tab = 2 for readability
  # Written by Paul Tan
  # ========================================================
  # 1) This is a simple draft bash script to produce a
  #    hierarchical verilog netlist in a single file. 
  #    It gathers hierarchical information from a list of 
  #    unique symbols/schematics originating from the top level
  #    schematic all the way down to the lowest level of the 
  #    design hierarchy. It then successively invokes the
  #    existing gEDA verilog netlister to produce each single 
  #    level netlists, and concatinates all the unique 
  #    module netlists into one single hierarchical netlist 
  #    file. 
  # 2) Currently, it assumes that one or more hierarchical symbol
  #    can be represented by a single schematic file. If needed, 
  #    feature for mutiple schematic files mapped to a single symbol 
  #    can be easily added. In that case, multiple source attrib
  #    are used in that symbol.
  # 3) It checks the follwoing errors while traversing down 
  #    the hierarchy and terminates the netlisting if error 
  #    is found.
  #    a) if a symbol's source attribute indicated schematic can not
  #       be found in the search paths defined by gafrc.
  #    b) if a symbol's device attribute value does not match its
  #       corresponding schematic's module_name attribute value.
  # 4) This script assumes that there are no other errors in the 
  #    entire hierarchy, and that the user has already run the
  #    DRC. Moreover, it assumes that the user has run the single
  #    level verilog netlister on each schematic in the hierarchy
  #    without any error. it also assumes that the hierarchy-traverse
  #    is disabled in gnetlistrc, thus disables flatten hierarchical 
  #    netlist generation.
  # 5) Netlist of modules are listed from top down, can easily be 
  #    changed to do bottom up.
  # 6) Symbol must contain "source=????.sch" attribute to have its
  #    schematic netlisted. Otherwise, symbol is treated just as 
  #    primitive instances in the netlist.
  # 7) It only uses the gafrc file in the folder where the top level 
  #    schematic resides. The search path for the symbols and
  #    schematics should be defined in that gafrc file. The 
  #    current implementation searches from the beginning
  #    of the file, it will be changed to conform to the gEDA
  #    practice of searching from the bottom first.
  # 8) Hierarchy info is output to a report file for reference.
  # 9)This script is optimized for readability only, I hope.
  # 10)Array variables are suffixed with A, e,g,, HLineA[]
  # ========================================================
  #             To do list
  # -------------------------------------------------------
  # 1) Multi-page sch per symbol support
  # 2) Use the "file" attrib to include user defined netlist
  # 3) Include .gnetlistrc and other config files info to search
  # 4) Change search order for sym/sch libs to LIFO (last in fisrt out)
  # 5) Recode the script in C or scheme ?
  # 6) Add CL args to support VHDL and Spice hier netlist
  # 7) Add error checks:
  #     a) add ERC (Electrical_Rule_Check) if not already checked
  #        by gnetlist DRC.
  # ========================================================
  #
  #                   Notes
  #
  # ========================================================
  # First we create a master list in a record array HierListA[].
  # HierListA[] will contain a list of records of all unique symbols
  # under the top schematics and all its underlying schematics.
  # This master record list will be output to a text file
  # for reference.
  # Then we'll invoke the gnetlist program to netlist each of 
  # the schematics representing the symbols on the list,
  # concatinating each netlist into the top level netlist.
  #
  # Each record of HierListA[] has 5 or more fields:
  #  0          1         2          3         4        [5] ...
  #  ItemNum    Flag     Sym_Name   Sch_Dir  Sch_Name  [Sch_Name] ..
  # -------------------------------------------------------
  # Corresponding variables declared in this script
  # $iN         $iFlag    $iSym     $iSchDir $iSch
  # $CurIndex   $CurFlag  $CurSym   $CurDir  $CurSch   ; In master
  # $EndIndex   $Tflag    $Tsym     $TschDir $Tsch     ; To add
  # -------------------------------------------------------
  # The Flag is used to indicate if a schematic needs to 
  # be netlisted.
  #    Flag = 0 means NOT to netlist the schematic.
  #    Flag = 1 means to netlist the schematic.
  #    Flag = 2 means NOT to netlist, since other symbol already
  #             has the same schematic listed.
  # ----------------------------------------------
  # For multiple pages(files) schematic, use more than 5 fields
  # in a record.
  # ========================================================
  #
  #          Script starts here
  #
  # ========================================================
  # Configurable items
  # ---------------------------------------
  # Define the symbol's attribute to be used for its 
  #   associated schematic.
  src_attrib="source"
  # ---------------------------------------
  # version
  ver=0.0.2
  My_Debug=0
  # ========================================================
  my_error=0
  my_ext=""
  echo
  if [ -z $1 ]
  	then my_error=1
  fi
  # ---------------------------------------
  # To be changed: loop thru multiple sch files from CL's args
  if [ $my_error == 0 ]; then
  	TopSchFile=$1
  	my_ext=${TopSchFile#*.}
  	if [ "$my_ext" != "sch" ]; then 
  		my_error=1
  	fi
  fi
  # ---------------------------------------
  if [ $my_error == 1 ]; then
  	echo "Error:"
  	echo -n "Please include a gEDA schematic file"
  	echo " as its argument."
  	echo " Usage:"
  	echo "   [path]gnet_hier_verilog.sh [path]FileName.sch"
  	exit 1
  fi
  # ---------------------------------------
  TopDir=$(dirname $1)
  cd $TopDir
  TopDir=$PWD
  TopBaseFile=$(basename $1 .sch)
  CurSchFile=$1
  TopVFile="${TopBaseFile}.v"
  ReportFile="${TopBaseFile}_Report.txt"
  TemptFile="hier_temp.v"
  # ---------------------------------------
  echo
  echo "Starting Hierarchical Verilog Netlister version ${ver} ....."
  # ===============================================
  if [ $My_Debug == 1 ]
  	then
  		echo 
  		echo '======== Start Debug ==========='
  		echo "TopDir = $TopDir"
  		echo "TopBaseFile = $TopBaseFile"
  		echo "CurSchFile = $CurSchFile"
  		echo "ReportFile = $ReportFile"
  fi
  # ----------------------------------------------
  #
  # Init all indices:
  # Fields position in a record
  iN=0; iFlag=1; iSym=2; iSchDir=3; iSch=4
  # ----------------------------------------------
  # Initialize master list HierListA[]'s first record
  CurIndex=0
  EndIndex=0 
  Tflag=1
  Tsym="${TopBaseFile}.sym" 
  Tsch="${TopBaseFile}.sch" 
  TschDir="."
  # Fields in each row of record
  HLineA[$iN]=$EndIndex
  HLineA[$iSym]=$Tsym
  HLineA[$iSch]=$Tsch
  HLineA[$iSchDir]=$TschDir
  HLineA[$iFlag]=$Tflag
  # First row of record in master list
  HierListA[0]=`echo ${HLineA[@]:0}`
  # ----------------------------------------------
  # Initialize other lists
  # ----------------------------------------------
  # Get gEDA gafrc's symbol and schematic search paths
  # into their respective list arrays
  SymDirListA=( `
  	gawk 'BEGIN {FS="\""}
  		(NF >= 1)&&($1 == "(component-library ") {
  		printf("%s\n",$2);
  	}' gafrc` )
  # ----------------------------------------------
  SrcDirListA=( `
  	gawk 'BEGIN {FS="\""}
  		(NF >= 1)&&($1 == "(source-library ") {
  		printf("%s\n",$2);
  	}' gafrc` )
  
  # ===============================================
  if [ $My_Debug == 1 ]; then
  	echo "---------------------------"
  	echo -n "SymDirList n = "
  	echo ${#SymDirListA[*]}
  	for i in "${SymDirListA[@]}"; do echo "$i"; done
  	echo "---------------------------"
  	echo -n "SrcDirList n = "
  	echo ${#SrcDirListA[*]}
  	for i in "${SrcDirListA[@]}"; do echo "$i"; done
  	echo "---------------------------"
  fi
  # ###############################################
  # Process each record from the master list
  while (("$CurIndex" <= "$EndIndex"))
  do
  	# Get a record from the master list
  	CurA=( ${HierListA[$CurIndex]} )
  	CurFlag=${CurA[$iFlag]}
  	CurSchFile=${CurA[$iSch]}
  	CurSchDir=${CurA[$iSchDir]}
  	if [ "$CurSchDir" == "." ] 
  		then CurSchPath=$CurSchFile
  		else CurSchPath=`echo "$CurSchDir/$CurSchFile"`
  	fi
  	CurSchBase=$(basename $CurSchFile .sch)
  	# --------------------------------
  	# Only Flag=1 entry will get netlisted and processed
  	# down the hierarchy
  	if [ "$CurFlag" != 1 ]; then
  		let "++CurIndex"
  		continue
  	fi
  	# ----------------------------------------------
  	# if needed, this is the place to generate netlist
  	#	for each record. For now, we netlist at the end
  	# after we have generated all the records
  	# ----------------------------------------------
  	# To be changed: loop thru pages of schs
  	# ----------------------------------------------
  	# Get all instances of any symbols from current schematic
  	# into TempSymListA[]
  	TempSymListA=( `
  		gawk '(NF==7)&&($1=="C") {printf("%s\n",$7)}' $CurSchPath 
  	`)
  	# ----------------------------------------------
  	# Make a unique symbol list from it
  	TSymListA[0]=${TempSymListA[0]}
  	found=0
  	let "k = 0"
  	for i in "${TempSymListA[@]}"; do
  		found=0
  		for j in "${TSymListA[@]}"; do
  			if [ "$i" == "$j" ]; then 
  				found=1
  				break
  			fi
  		done # for j
  		if [ $found == 1 ]; then continue
  		fi
  		let "++k"
  		TSymListA[$k]=$i
  	done # for i
  	unset TempSymListA
  	# ===============================================
  	# Check if Tsym already exist in the master list
  	# if not on list, add to the list
  	found=0
  	for Tsym in "${TSymListA[@]}"; do
  		found=0
  		for HLineA in "${HierListA[@]}"; do
  			HierA=( `echo $HLineA` )
  			HierSym=${HierA[$iSym]}
  
  			if [ "$Tsym" == "$HierSym" ]; then
  				found=1
  				break
  			fi
  		done
  
  		if [ $found == 1 ]; then continue
  		fi
  		# ===================================
  		# Find the Symbol file and its folder
  		found=0
  		for i in "${SymDirListA[@]}"; do
  			TsymPath=`echo "$i/$Tsym"`
  			if [ -e $TsymPath ]; then
  				found=1
  				TsymDir=$i
  				break
  			fi 
  		done
  
  		if [ $found == 0 ]; then
  			echo "Error: "
  			echo "  $Tsym file not found. Please check the search path"
  			echo "  defined in the gafrc file."
  			exit 1
  		fi
  		# ---------------------------------
  		# Find the schematic file name for the symbol from:
  		#   1) The "source" attribute in the symbol file of 
  		#      the $TsymDir folder.
  		#   2) If no "source", use the symbol basename as the schematic
  		#      basename?  For now, must use "source". 
  		#   3) Note that the sch file must contain "module_name" 
  		#      attrubute whose value must match the value of the 
  		#      "device" attribute from the sym file. This script
  		#      checks for this condition.
  		# Given the schematic file name, search its folder path in:
  		#   1) Source folders specified in the gEDA rc file
  		# ---------------------------------
  		TsymBase=$(basename $Tsym .sym)
  		TschDir=$TsymDir
  		Tflag=0
  		# ---------------------------------
  		# Get "source" and "device" attributes from sym file
  		# and store them in SymAttribListA[]
  		SymAttribListA=( `
  			gawk -v src=$src_attrib 'BEGIN {FS="="}
  				(NF==2)&&($1 == src) {print $0};
  				(NF==2)&&($1 == "device") {print $0}
  			' $TsymPath` )
  		# ---------------------------------
  		# To be changed: add a list of sources SymSrcList[]
  		#                to support multi-page
  		# ---------------------------------
  		# Check if source exist in SymAttribListA[]
  		Tsch=""
  		for i in "${SymAttribListA[@]}"; do
  			if [ "${i%=*}" == "$src_attrib" ]; then
  				Tsch=${i#*=}; break
  			fi
  		done
  		# ---------------------------------
  		if [ "$Tsch" == "" ]; then 
  				Tsch="None"; Tflag=0
  			else
  				# ---------------------------------
  				# Found sch name, check if already on master list
  				found=0
  				for HLineA in "${HierListA[@]}"; do
  					HierA=( `echo $HLineA` )
  					HierSch=${HierA[$iSch]}
  					if [ "$Tsch" == "$HierSch" ]; then	
  						found=1
  						break
  					fi
  				done
  				# If sch not on master list, need further check
  				if [ $found == 0 ]; then
  					Tflag=2
  				fi
  		fi
  		# ---------------------------------
  		# if sch not on list, search for sch path
  		if [ $Tflag == 2 ]; then
  			found=0		
  			for i in "${SrcDirListA[@]}"; do
  				TschPath=`echo "$i/$Tsch"`
  				if [ -e $TschPath ]; then
  					found=1
  					TschDir=$i
  					break
  				fi 
  			done
  			# if can't find sch path, error and exit
  			if [ $found == 0 ]; then
  				echo -n "Error: $Tsch is the $src_attrib attribute in "
  				echo -n "$Tsym but NOT in the gafrc "
  				echo "source-directory path."
  				Tflag=3
  				exit 1
  			fi
  			# ---------------------------------
  			# Found sch path, check if sch's
  			# sch's module_name attribute = sym's device attribute
  			# ---------------------------------
  			# Get module_name attrib from sch file
  			TModule=""
  			TModule=( `
  				gawk 'BEGIN {FS="="}
  					(NF == 2)&&($1 == "module_name") {
  						printf("%s\n", $2); exit}' $TschPath` )
  			# ---------------------------------
  			# Check if module_name = device from SymAttribListA[]
  			# ---------------------------------	
  			Tdev=""		
  			for i in "${SymAttribListA[@]}"; do
  				if [ "${i%=*}" == "device" ]; then
  					Tdev=${i#*=}; break
  				fi
  			done
  			# ---------------------------------
  			if [[ "$TModule" != "" ]] && [[ "$TModule" == "$Tdev" ]]
  				then Tflag=1
  				else 
  					echo "Error: "
  					echo "  $Tsym Symbol's device attribute $Tdev does not match"
  					echo "  $Tsch schematic's module_name attribute $TModule."
  				exit 1
  			fi
  			# ---------------------------------
  		fi
  		# ===================================
  		# Add a new record into the master list HierListA[]
  		let "++EndIndex"
  		HLineA[$iN]=$EndIndex
  		HLineA[$iFlag]=$Tflag
  		HLineA[$iSym]=$Tsym
  		HLineA[$iSchDir]=$TschDir
  		HLineA[$iSch]=$Tsch
  		HierListA[$EndIndex]=`echo ${HLineA[@]:0}`
  		# ---------------------------------
  		if [ $My_Debug == 3 ]; then
  			echo "Added new record"
  			echo ${HierListA[$EndIndex]}
  			echo
  		fi
  		# ---------------------------------
  	done	# done. for Tsym
  	unset TSymListA
  	# ===============================================
  	let "++CurIndex"
  done	# done generating master list
  #
  # ###############################################
  # Generate a report file
  echo "# Hierarchical netlist report for:" >$ReportFile
  echo "# $TopSchFile" >>$ReportFile
  echo "# ------------------------">>$ReportFile
  # comments fields
  HLineA[$iN]="Index"
  HLineA[$iFlag]="Flag"
  HLineA[$iSym]="Sym"
  HLineA[$iSch]="Sch"
  HLineA[$iSchDir]="Sch_Dir"
  echo "# ${HLineA[@]:0}" >>$ReportFile
  echo "# ------------------------">>$ReportFile
  for i in "${HierListA[@]}"; do
  	echo $i >>$ReportFile
  done
  
  # ###############################################
  # Generate netlist from record in the master list
  # Only Flag=1 record will be netlisted
  # ###############################################
  echo
  echo "Generating hierarchical netlist ...... "
  let "CurIndex=0"
  let "EndIndex=${#HierListA[@]}-1"
  # -----------------------------------
  if [ $My_Debug == 2 ]; then
  	echo
  	echo "CurIndex = $CurIndex"
  	echo "EndIndex = $EndIndex"
  	echo
  fi
  # -----------------------------------
  while (("$CurIndex" <= "$EndIndex"))
  do
  	# Get a record from the master list
  	CurA=( ${HierListA[$CurIndex]} )
  	# Get fields of the selected record
  	CurFlag=${CurA[$iFlag]}
  	CurSchFile=${CurA[$iSch]}
  	CurSchDir=${CurA[$iSchDir]}
  	if [ "$CurSchDir" == "." ]
  		then CurSchPath=$CurSchFile
  		else CurSchPath=`echo "$CurSchDir/$CurSchFile"`
  	fi
  	CurSchBase=$(basename $CurSchFile .sch)
  	# --------------------------------
  	# Only Flag=1 entry will get netlisted
  	if [ $CurFlag != 1 ]; then
  		let "++CurIndex"
  		continue
  	fi
  	# --------------------------------
  	# To be changed: add multi-page netlist
  	# --------------------------------
  	if [ "$CurIndex" -eq 0 ]
  		then 
  			gnetlist -g verilog -o $TopVFile $TopSchFile
  		else
  			gnetlist -g verilog -o $TemptFile $CurSchPath
  			# Skip header portion of each netlist
  			gawk 'BEGIN{found = 0}
  				(NF >= 1)&&($1 == "module")&&(found == 0){
  					found = 1;
  					printf("\n/* --------------------------------- */\n");
  				};
  				(NR > 0)&&(found == 1){
  					print $0;
  				};
  			' $TemptFile >>$TopVFile
  	fi
  	# --------------------------------
  	let "++CurIndex"
  done
  echo
  echo "Hierarchical Verilog netlist successfully completed."
  echo
  
   	  	 
  
  
  


_______________________________________________
geda-cvs mailing list
geda-cvs@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-cvs