1# ============================================================================== 2# Authors: 3# Patrick Lehmann 4# 5# Bash Script: 6# This is a Bash resource file for sourcing. 7# 8# Description: 9# Provide Bash procedures to easily use GHDL in Bash scripts. 10# 11# ============================================================================== 12# Copyright (C) 2017-2021 Patrick Lehmann - Boetzingen, Germany 13# Copyright (C) 2015-2016 Patrick Lehmann - Dresden, Germany 14# 15# This program is free software: you can redistribute it and/or modify 16# it under the terms of the GNU General Public License as published by 17# the Free Software Foundation, either version 2 of the License, or 18# (at your option) any later version. 19# 20# This program is distributed in the hope that it will be useful, 21# but WITHOUT ANY WARRANTY; without even the implied warranty of 22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23# GNU General Public License for more details. 24# 25# You should have received a copy of the GNU General Public License 26# along with this program. If not, see <gnu.org/licenses>. 27# ============================================================================== 28 29 30# set bash options 31set -o pipefail 32 33if [[ -n "$GHDL" ]]; then 34 if [[ ! -f "$GHDL" ]]; then 35 echo 1>&2 -e "${COLORED_ERROR} Found GHDL environment variable, but '$GHDL' is not a file.${ANSI_NOCOLOR}" 36 exit 1 37 elif [[ ! -x "$GHDL" ]]; then 38 echo 1>&2 -e "${COLORED_ERROR} Found GHDL environment variable, but '$GHDL' is not executable.${ANSI_NOCOLOR}" 39 exit 1 40 fi 41else # fall back to GHDL found via PATH 42 GHDL=$(which ghdl 2>/dev/null) 43 if [[ $? -ne 0 ]]; then 44 echo 1>&2 -e "${COLORED_ERROR} GHDL not found in PATH.${ANSI_NOCOLOR}" 45 echo 1>&2 -e " Use adv. options '--ghdl' to set the GHDL binary directory." 46 exit 1 47 fi 48fi 49 50Analyze_Filter=filter.analyze.sh 51Analyze_Parameters=( 52 --mb-comments 53) 54 55VERBOSE=${VERBOSE:-0} 56DEBUG=${DEBUG:-0} 57CONTINUE_ON_ERROR=${CONTINUE_ON_ERROR:-0} 58 59test $VERBOSE -eq 1 && echo -e " Declaring Bash procedures for GHDL..." 60 61test $DEBUG -eq 1 && echo -e " ${ANSI_DARK_GRAY}procedure SetupDirectories( <Index> <Name> )${ANSI_NOCOLOR}" 62# SetupDirectories 63# -> $Index 64# -> $Name 65# <= $SourceDirectory 66# <= $DestinationDirectory 67SetupDirectories() { 68 local Index=$1 69 local Name=$2 70 71 declare -n Settings="${Index}_Settings" 72 73 # source directory 74 # ---------------------- 75 # If a command line argument ('--source') was passed in, use it, else use the default value 76 # from config.sh 77 if [[ ! -z "$SrcDir" ]]; then 78 SourceDirectory=${SrcDir%/} # remove trailing slashes 79 elif [[ ! -z "$EnvSourceDir" ]]; then 80 SourceDirectory=$EnvSourceDir # fall back to environment variable 81 elif [[ ! -z "${Settings[InstallationDirectory]}" ]]; then 82 SourceDirectory=${Settings[InstallationDirectory]}/${Settings[SourceDirectory]} # fall back to value from config.sh 83 fi 84 # output directory 85 # ---------------------- 86 # If a command line argument ('--output') was passed in, use it, else use the default value 87 # from config.sh 88 if [[ ! -z "$DestDir" ]]; then 89 DestinationDirectory=${DestDir%/} # remove trailing slashes 90 else 91 DestinationDirectory=${Settings[DestinationDirectory]} # fall back to value from config.sh 92 fi 93 94 if [[ -z $SourceDirectory || -z $DestinationDirectory ]]; then 95 echo 1>&2 -e "${COLORED_ERROR} $Name is not configured in '$ScriptDir/config.sh'.${ANSI_NOCOLOR}" 96 echo 1>&2 -e " Use adv. options '--source' and '--output' or configure 'config.sh'." 97 exit 1 98 elif [[ ! -d $SourceDirectory ]]; then 99 echo 1>&2 -e "${COLORED_ERROR} Path '$SourceDirectory' does not exist.${ANSI_NOCOLOR}" 100 exit 1 101 fi 102 103 # Resolve paths to an absolute paths 104 test greadlink --version > /dev/null 2>&1 && READLINK=greadlink || READLINK=readlink 105 SourceDirectory=$($READLINK -f $SourceDirectory) 106 if [[ ! "$DestinationDirectory" = /* ]]; then 107 DestinationDirectory="$WorkingDir/$DestinationDirectory" 108 fi 109} 110 111test $DEBUG -eq 1 && echo -e " ${ANSI_DARK_GRAY}procedure CreateDestinationDirectory( undocumented )${ANSI_NOCOLOR}" 112# CreateDestinationDirectory 113# -> undocumented 114CreateDestinationDirectory() { 115 if [ -d "$DestinationDirectory" ]; then 116 echo -e "${COLORED_WARNING} Vendor directory '$DestinationDirectory' already exists.${ANSI_NOCOLOR}" 117 elif [ -f "$DestinationDirectory" ]; then 118 echo 1>&2 -e "${COLORED_ERROR} Vendor directory '$DestinationDirectory' already exists as a file.${ANSI_NOCOLOR}" 119 exit 1 120 else 121 echo -e "Creating vendor directory: '$DestinationDirectory'.${ANSI_NOCOLOR}" 122 mkdir -p "$DestinationDirectory" 123 fi 124} 125 126test $DEBUG -eq 1 && echo -e " ${ANSI_DARK_GRAY}procedure GHDLSetup( <VHDLStandard> )${ANSI_NOCOLOR}" 127# GHDLSetup 128# -> $VHDLStandard 129# <= $VHDLVersion 130# <= $VHDLStandard 131# <= $VHDLFlavor 132GHDLSetup() { 133 if [ $1 -eq 93 ]; then 134 VHDLVersion="v93" 135 VHDLStandard="93c" 136 VHDLFlavor="synopsys" 137 elif [ $1 -eq 2008 ]; then 138 VHDLVersion="v08" 139 VHDLStandard="08" 140 VHDLFlavor="synopsys" 141 fi 142} 143 144test $DEBUG -eq 1 && echo -e " ${ANSI_DARK_GRAY}procedure CreateVHDLLibrary( <StructName> <LibraryName> <LibraryPath> <VHDLVersion> <Files[*]> )${ANSI_NOCOLOR}" 145# CreateLibraryStruct 146# -> $StructName 147# -> $LibraryName 148# -> $LibraryPath 149# -> $VHDLVersion 150# -> $Files[*] 151CreateLibraryStruct() { 152 local StructName=$1; shift 153 154 declare -g "${StructName}_LibraryName"=$1; shift 155 declare -g "${StructName}_LibraryPath"=$1; shift 156 declare -g "${StructName}_VHDLVersion"=$1; shift 157 158 declare -n FilesRef="${StructName}_Files" 159 FilesRef=( "$*" ) 160} 161 162test $DEBUG -eq 1 && echo -e " ${ANSI_DARK_GRAY}procedure DeleteLibraryStruct( <StructName> )${ANSI_NOCOLOR}" 163# DeleteLibraryStruct 164# -> $StructName 165DeleteLibraryStruct() { 166 local StructName=$1 167 168 unset "${StructName}_VHDLVersion" 169 unset "${StructName}_LibraryName" 170 unset "${StructName}_LibraryPath" 171 unset "${StructName}_Files" 172} 173 174test $DEBUG -eq 1 && echo -e " ${ANSI_DARK_GRAY}procedure PrintLibraryStruct( <StructName> )${ANSI_NOCOLOR}" 175# PrintLibraryStruct 176# -> $StructName 177PrintLibraryStruct() { 178 local StructName=$1 179 local Indentation=${2:-" "} 180 181 local LibraryName="${StructName}_LibraryName"; local LibraryName=${!LibraryName} 182 local Files="${StructName}_Files[*]"; local Files=${!Files} 183 184 echo -e "$Indentation${ANSI_DARK_GRAY}VHDL Library name: $LibraryName${ANSI_NOCOLOR}" 185 for File in ${Files[*]}; do 186 echo -e "$Indentation ${ANSI_DARK_GRAY}$File${ANSI_NOCOLOR}" 187 done 188} 189 190 191declare -A GHDLLibraryMapping 192 193test $DEBUG -eq 1 && echo -e " ${ANSI_DARK_GRAY}procedure CreateVHDLLibrary( <LibraryName> <DirectoryName> <VHDLVersion> )${ANSI_NOCOLOR}" 194# CreateVHDLLibrary 195# -> $LibraryName 196# -> $DirectoryName 197# -> $VHDLVersion 198CreateVHDLLibrary() { 199 local LibraryName=$1 200 local DirectoryName=$2 201 local VHDLVersion=${3:-"v08"} 202 203 echo -e "${ANSI_YELLOW}Creating VHDL Library '$LibraryName'...${ANSI_NOCOLOR}" 204 205 test $DEBUG -eq 1 && echo -e " ${ANSI_DARK_GRAY}mkdir -p \"$DirectoryName/$VHDLVersion\"${ANSI_NOCOLOR}" 206 mkdir -p "$DirectoryName/$VHDLVersion" 207 208 LibraryDir="$(pwd)/$DirectoryName/$VHDLVersion" 209 test $DEBUG -eq 1 && echo -e " ${ANSI_DARK_GRAY}Mapping library $LibraryName to '$LibraryDir'.${ANSI_NOCOLOR}" 210 GHDLLibraryMapping[$LibraryName]=$LibraryDir 211} 212 213test $DEBUG -eq 1 && echo -e " ${ANSI_DARK_GRAY}procedure AnalyzeVHDL( <LibraryName> <SourceDirectory> <LibraryPath> <File> )${ANSI_NOCOLOR}" 214# AnalyzeVHDL 215# -> $LibraryName 216# -> $SourceDirectory 217# -> $LibraryPath 218# -> $File 219AnalyzeVHDL() { 220 local LibraryName=$1 221 local SourceDirectory=$2 222 local LibraryPath=$3 223 local File=$4 224 225 local DestinationDirectory=${GHDLLibraryMapping[$LibraryName]} 226 227 if [[ $DEBUG -eq 1 ]]; then 228 local Parameters=( 229 -v 230 ) 231 local Filter_Parameters=( 232 -d 233 ) 234 local Filter_Indent=" " 235 elif [[ $VERBOSE -eq 1 ]]; then 236 local Parameters=() 237 local Filter_Parameters=( 238 -v 239 ) 240 local Filter_Indent=" " 241 else 242 local Parameters=() 243 local Filter_Parameters=() 244 local Filter_Indent=" " 245 fi 246 247 local SourceFile="$SourceDirectory/$LibraryPath/$File" 248 249 if [[ ! -f "$SourceFile" ]]; then 250 echo 1>&2 -e "${COLORED_ERROR} Source file '$SourceFile' not found.${ANSI_NOCOLOR}" 251 test $CONTINUE_ON_ERROR -eq 0 && exit 1 252 fi 253 254 if [[ $FILTERING -eq 0 ]]; then 255 test $DEBUG -eq 1 && echo -e " ${ANSI_DARK_GRAY}$GHDL -a ${Analyze_Parameters[*]} ${Parameters[*]} --work=$LibraryName \"$SourceFile\"${ANSI_NOCOLOR}" 256 $GHDL -a "${Analyze_Parameters[@]}" "${Parameters[@]}" --work=$LibraryName --workdir=$DestinationDirectory "$SourceFile" 257 ExitCode=$? 258 if [[ $ExitCode -ne 0 ]]; then 259 echo 1>&2 -e "$Filter_Indent${COLORED_ERROR} While analyzing '$File'. ExitCode: $ExitCode${ANSI_NOCOLOR}" 260 test $CONTINUE_ON_ERROR -eq 0 && exit 1 261 fi 262 else 263 test $DEBUG -eq 1 && echo -e " ${ANSI_DARK_GRAY}$GHDL -a ${Analyze_Parameters[*]} ${Parameters[*]} --work=$LibraryName \"$SourceFile\" 2>&1 | \\\\${ANSI_NOCOLOR}" 264 test $DEBUG -eq 1 && echo -e " ${ANSI_DARK_GRAY}$ScriptDir/$Analyze_Filter ${Filter_Parameters[*]} -i \"$Filter_Indent\"${ANSI_NOCOLOR}" 265 $GHDL -a "${Analyze_Parameters[@]}" "${Parameters[@]}" --work=$LibraryName "$SourceFile" 2>&1 | $ScriptDir/$Analyze_Filter "${Filter_Parameters[@]}" -i "$Filter_Indent" 266 local PiplineStatus=("${PIPESTATUS[@]}") 267 if [[ ${PiplineStatus[0]} -ne 0 ]]; then 268 echo 1>&2 -e "$Filter_Indent${COLORED_ERROR} While analyzing '$File'. ExitCode: ${PiplineStatus[0]}${ANSI_NOCOLOR}" 269 test $CONTINUE_ON_ERROR -eq 0 && exit 1 270 elif [[ ${PiplineStatus[1]} -ne 0 ]]; then 271 case $(( ${PiplineStatus[1]} % 4 )) in 272 # TODO: implement CONTINUE_ON_ERROR in cases ... 273 3) echo 1>&2 -e "$Filter_Indent${ANSI_RED}Fatal errors detected by filtering script. ExitCode: ${PiplineStatus[1]}${ANSI_NOCOLOR}"; exit 1 ;; 274 2) echo 1>&2 -e "$Filter_Indent${ANSI_RED}Errors detected by filtering script. ExitCode: ${PiplineStatus[1]}${ANSI_NOCOLOR}"; exit 1 ;; 275 1) echo 1>&2 -e "$Filter_Indent${ANSI_YELLOW}Warnings detected by filtering script.${ANSI_NOCOLOR}" ;; 276 0) test $DEBUG -eq 1 && echo 1>&2 -e "$Filter_Indent${ANSI_YELLOW}Warnings detected by filtering script.${ANSI_NOCOLOR}" ;; 277 esac 278 fi 279 fi 280} 281 282 283test $DEBUG -eq 1 && echo -e " ${ANSI_DARK_GRAY}procedure AnalyzeLibrary( <LibraryName> <SourceDirectory> <LibraryPath> <Files[*]> )${ANSI_NOCOLOR}" 284# AnalyzeLibrary 285# -> LibraryName 286# -> SourceDirectory 287# -> LibraryPath 288# -> Files[*] 289AnalyzeLibrary() { 290 local LibraryName=$1; shift 291 local SourceDirectory=$1; shift 292 local LibraryPath=$1; shift 293 local Files=$@ 294 295 echo -e "${ANSI_YELLOW}Analyzing files into library '$LibraryName'...${ANSI_NOCOLOR}" 296 297 for File in $Files; do 298 test $VERBOSE -eq 1 && echo -e "${ANSI_CYAN} Analyzing '$File'${ANSI_NOCOLOR}" 299 300 AnalyzeVHDL $LibraryName "$SourceDirectory" "$LibraryPath" "$File" 301 done 302} 303 304test $DEBUG -eq 1 && echo -e " ${ANSI_DARK_GRAY}procedure Compile( <SourceDirectory> <Libraries> )${ANSI_NOCOLOR}" 305# Compile 306# -> SourceDirectory 307# -> VHDLLibraries 308Compile() { 309 local SourceDirectory=$1 310 local VHDLLibraries=$2 311 312 for VHDLLibrary in $VHDLLibraries; do 313 local LibraryName="${VHDLLibrary}_LibraryName"; local LibraryName=${!LibraryName} 314 local LibraryPath="${VHDLLibrary}_LibraryPath"; local LibraryPath=${!LibraryPath} 315 local VHDLVersion="${VHDLLibrary}_VHDLVersion"; local VHDLVersion=${!VHDLVersion} 316 local Files="${VHDLLibrary}_Files[*]"; local Files=${!Files} 317 318 echo -e "${ANSI_LIGHT_CYAN}Analyzing library '$LibraryName'...${ANSI_NOCOLOR}" 319 320 CreateVHDLLibrary $LibraryName $LibraryName $VHDLVersion 321 AnalyzeLibrary $LibraryName "$SourceDirectory" "$LibraryPath" "$Files" 322 done 323} 324