+ 1# ==================================================================================================================== #
+ 2# _____ ____ _ _ ____ _ ___ _____ _ #
+ 3# _ __ _ _| ____| _ \ / \ / \ / ___| | |_ _|_ _|__ ___ | | #
+ 4# | '_ \| | | | _| | | | |/ _ \ / _ \ | | | | | | | |/ _ \ / _ \| | #
+ 5# | |_) | |_| | |___| |_| / ___ \ / ___ \ | |___| |___ | | | | (_) | (_) | | #
+ 6# | .__/ \__, |_____|____/_/ \_\/_/ \_(_)____|_____|___| |_|\___/ \___/|_| #
+ 7# |_| |___/ #
+ 8# ==================================================================================================================== #
+ 9# Authors: #
+ 10# Patrick Lehmann #
+ 11# #
+ 12# License: #
+ 13# ==================================================================================================================== #
+ 14# Copyright 2017-2023 Patrick Lehmann - Boetzingen, Germany #
+ 15# #
+ 16# Licensed under the Apache License, Version 2.0 (the "License"); #
+ 17# you may not use this file except in compliance with the License. #
+ 18# You may obtain a copy of the License at #
+ 19# #
+ 20# http://www.apache.org/licenses/LICENSE-2.0 #
+ 21# #
+ 22# Unless required by applicable law or agreed to in writing, software #
+ 23# distributed under the License is distributed on an "AS IS" BASIS, #
+ 24# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
+ 25# See the License for the specific language governing permissions and #
+ 26# limitations under the License. #
+ 27# #
+ 28# SPDX-License-Identifier: Apache-2.0 #
+ 29# ==================================================================================================================== #
+ 30#
+ 31"""Unit tests for executable ``ghdl``."""
+ 32from sys import platform as sys_platform
+ 33from os import getenv as os_getenv
+ 34from pathlib import Path
+ 35from unittest import TestCase
+ 36
+ 37from pyEDAA.CLITool.GHDL import GHDL
+ 38from . import Helper
+ 39
+ 40
+ 41class CommonOptions(TestCase, Helper):
+ 42 _binaryDirectoryPath = Path(os_getenv("GHDL_PREFIX", default="/usr/local/lib/ghdl")) / "../../bin"
+ 43
+ 44 @classmethod
+ 45 def setUpClass(cls) -> None:
+ 46 # print(f"\nPlatform: {sys_platform}")
+ 47 if sys_platform in ("linux", "darwin"): 47 ↛ exitline 47 didn't return from function 'setUpClass', because the condition on line 47 was never false
+ 48 ghdlBinaryPath: Path = cls._binaryDirectoryPath / "ghdl"
+ 49 print(f"Creating dummy file '{ghdlBinaryPath}': ", end="")
+ 50 ghdlBinaryPath.touch()
+ 51 print(f"DONE" if ghdlBinaryPath.exists() else f"FAILED")
+ 52
+ 53 def test_Help(self):
+ 54 print()
+ 55
+ 56 tool = GHDL(binaryDirectoryPath=self._binaryDirectoryPath)
+ 57 tool[tool.CommandHelp] = True
+ 58
+ 59 executable = self.getExecutablePath("ghdl", self._binaryDirectoryPath)
+ 60 self.assertEqual(f"[\"{executable}\", \"help\"]", repr(tool))
+ 61
+ 62 helpText = tool.Help()
+ 63 print(helpText)
+ 64
+ 65 def test_Version(self):
+ 66 print()
+ 67
+ 68 tool = GHDL(binaryDirectoryPath=self._binaryDirectoryPath)
+ 69 tool[tool.CommandVersion] = True
+ 70
+ 71 executable = self.getExecutablePath("ghdl", self._binaryDirectoryPath)
+ 72 self.assertEqual(f"[\"{executable}\", \"version\"]", repr(tool))
+ 73
+ 74 version = tool.Version()
+ 75 print(str(version))
+ 76 print(repr(version))
+ 77
+ 78
+ 79class Analyze(TestCase, Helper):
+ 80 _binaryDirectoryPath = Path(os_getenv("GHDL_PREFIX", default="/usr/local/lib/ghdl")) / "../../bin"
+ 81
+ 82 @classmethod
+ 83 def setUpClass(cls) -> None:
+ 84 # print(f"\nPlatform: {sys_platform}")
+ 85 if sys_platform in ("linux", "darwin"): 85 ↛ exitline 85 didn't return from function 'setUpClass', because the condition on line 85 was never false
+ 86 ghdlBinaryPath: Path = cls._binaryDirectoryPath / "ghdl"
+ 87 print(f"Creating dummy file '{ghdlBinaryPath}': ", end="")
+ 88 ghdlBinaryPath.touch()
+ 89 print(f"DONE" if ghdlBinaryPath.exists() else f"FAILED")
+ 90
+ 91 def test_Analyze(self):
+ 92 print()
+ 93
+ 94 tool = GHDL(binaryDirectoryPath=self._binaryDirectoryPath)
+ 95 tool[tool.CommandAnalyze] = True
+ 96 tool[tool.FlagVHDLStandard] = "08"
+ 97 tool[tool.FlagSynopsys] = True
+ 98 tool[tool.FlagRelaxed] = True
+ 99 tool[tool.FlagExplicit] = True
+ 100 tool[tool.FlagMultiByteComments] = True
+ 101 tool[tool.FlagLibrary] = "lib_Test"
+ 102
+ 103 executable = self.getExecutablePath("ghdl", self._binaryDirectoryPath)
+ 104 self.assertEqual(f"[\"{executable}\", \"analyze\", \"--std=08\", \"-fsynopsys\", \"-frelaxed\", \"-fexplicit\", \"--work=lib_Test\", \"--mb-comments\"]", repr(tool))
+ 105
+ 106 tool.StartProcess()
+ 107 for line in tool.GetLineReader():
+ 108 print(line)
+ 109 tool.Terminate()
+ 110 print(tool.ExitCode)
+ 111
+ 112 def test_AnalyzeFile(self):
+ 113 print()
+ 114
+ 115 tool = GHDL(binaryDirectoryPath=self._binaryDirectoryPath)
+ 116 tool[tool.CommandAnalyze] = True
+ 117 tool[tool.FlagVHDLStandard] = "08"
+ 118 tool[tool.FlagSynopsys] = True
+ 119 tool[tool.FlagRelaxed] = True
+ 120 tool[tool.FlagExplicit] = True
+ 121 tool[tool.FlagMultiByteComments] = True
+ 122 tool[tool.FlagLibrary] = "lib_Test"
+ 123 tool[tool.OptionPaths] = (Path("example/file_A1.vhdl"), )
+ 124
+ 125 executable = self.getExecutablePath("ghdl", self._binaryDirectoryPath)
+ 126 self.assertEqual(f"[\"{executable}\", \"analyze\", \"--std=08\", \"-fsynopsys\", \"-frelaxed\", \"-fexplicit\", \"--work=lib_Test\", \"--mb-comments\", \"example\\file_A1.vhdl\"]", repr(tool))
+ 127
+ 128 tool.StartProcess()
+ 129 for line in tool.GetLineReader():
+ 130 print(line)
+ 131 tool.Terminate()
+ 132 print(tool.ExitCode)
+ 133
+ 134 def test_DeriveAnalyzer(self):
+ 135 print()
+ 136
+ 137 tool = GHDL(binaryDirectoryPath=self._binaryDirectoryPath)
+ 138 tool[tool.FlagVHDLStandard] = "08"
+ 139 tool[tool.FlagSynopsys] = True
+ 140 tool[tool.FlagRelaxed] = True
+ 141 tool[tool.FlagExplicit] = True
+ 142 tool[tool.FlagMultiByteComments] = True
+ 143
+ 144 derived = tool.GetGHDLAsAnalyzer()
+ 145 derived[derived.FlagLibrary] = "lib_Test"
+ 146
+ 147 executable = self.getExecutablePath("ghdl", self._binaryDirectoryPath)
+ 148 self.assertEqual(f"[\"{executable}\", \"analyze\", \"--std=08\", \"-fsynopsys\", \"-frelaxed\", \"-fexplicit\", \"--work=lib_Test\", \"--mb-comments\"]", repr(derived))
+ 149
+ 150 derived.StartProcess()
+ 151 for line in derived.GetLineReader():
+ 152 print(line)
+ 153 print(derived.ExitCode)
+
+
+ 1# ==================================================================================================================== #
+ 2# _____ ____ _ _ ____ _ ___ _____ _ #
+ 3# _ __ _ _| ____| _ \ / \ / \ / ___| | |_ _|_ _|__ ___ | | #
+ 4# | '_ \| | | | _| | | | |/ _ \ / _ \ | | | | | | | |/ _ \ / _ \| | #
+ 5# | |_) | |_| | |___| |_| / ___ \ / ___ \ | |___| |___ | | | | (_) | (_) | | #
+ 6# | .__/ \__, |_____|____/_/ \_\/_/ \_(_)____|_____|___| |_|\___/ \___/|_| #
+ 7# |_| |___/ #
+ 8# ==================================================================================================================== #
+ 9# Authors: #
+ 10# Patrick Lehmann #
+ 11# #
+ 12# License: #
+ 13# ==================================================================================================================== #
+ 14# Copyright 2017-2023 Patrick Lehmann - Boetzingen, Germany #
+ 15# Copyright 2014-2016 Technische Universität Dresden - Germany, Chair of VLSI-Design, Diagnostics and Architecture #
+ 16# #
+ 17# Licensed under the Apache License, Version 2.0 (the "License"); #
+ 18# you may not use this file except in compliance with the License. #
+ 19# You may obtain a copy of the License at #
+ 20# #
+ 21# http://www.apache.org/licenses/LICENSE-2.0 #
+ 22# #
+ 23# Unless required by applicable law or agreed to in writing, software #
+ 24# distributed under the License is distributed on an "AS IS" BASIS, #
+ 25# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
+ 26# See the License for the specific language governing permissions and #
+ 27# limitations under the License. #
+ 28# #
+ 29# SPDX-License-Identifier: Apache-2.0 #
+ 30# ==================================================================================================================== #
+ 31#
+ 32"""This module contains the CLI abstraction layer for `GHDL <https://github.com/ghdl/ghdl>`__."""
+ 33from re import search as re_search
+ 34from typing import Union, Iterable, Tuple
+ 35
+ 36from pyTooling.Decorators import export
+ 37from pyVHDLModel import VHDLVersion
+ 38
+ 39from pyTooling.CLIAbstraction import CLIArgument, Executable
+ 40from pyTooling.CLIAbstraction.Argument import PathListArgument, StringArgument
+ 41from pyTooling.CLIAbstraction.Command import CommandArgument
+ 42from pyTooling.CLIAbstraction.Flag import ShortFlag, LongFlag
+ 43from pyTooling.CLIAbstraction.BooleanFlag import LongBooleanFlag
+ 44from pyTooling.CLIAbstraction.ValuedFlag import ShortValuedFlag, LongValuedFlag
+ 45from pyTooling.CLIAbstraction.KeyValueFlag import ShortKeyValueFlag
+ 46
+ 47from pyEDAA.CLITool import CLIToolException
+ 48
+ 49
+ 50@export
+ 51class GHDLVersion:
+ 52 _major: int
+ 53 _minor: int
+ 54 _micro: int
+ 55 _dev: bool
+ 56 _commitsSinceLastTag: int
+ 57 _gitHash: str
+ 58 _dirty: bool
+ 59 _edition: str
+ 60 _gnatCompiler: Tuple[int, int, int]
+ 61 _backend: str
+ 62
+ 63 def __init__(self, versionLine: str, gnatLine: str, backendLine: str):
+ 64 match = re_search(
+ 65 r"GHDL"
+ 66 r"\s(?P<major>\d+)"
+ 67 r"\.(?P<minor>\d+)"
+ 68 r"\.(?P<micro>\d+)"
+ 69 r"(?:-(?P<suffix>dev))?"
+ 70 r"\s\("
+ 71 r"(?P<major2>\d+)"
+ 72 r"\.(?P<minor2>\d+)"
+ 73 r"\.(?P<micro2>\d+)"
+ 74 r"\.(?:r(?P<cslt>\d+))"
+ 75 r"\.(?:g(?P<hash>[0-9a-f]+))"
+ 76 r"(?:\.(?P<dirty>dirty))?"
+ 77 r"\)\s"
+ 78 r"\[(?P<edition>[\w\s]+)\]",
+ 79 versionLine)
+ 80
+ 81 if match is None:
+ 82 raise CLIToolException(f"Unknown first GHDL version string '{versionLine}'.")
+ 83
+ 84 self._major = int(match["major"])
+ 85 self._minor = int(match["minor"])
+ 86 self._micro = int(match["micro"])
+ 87 self._dev = "dev" in match.groups()
+ 88 self._commitsSinceLastTag = int(match["cslt"])
+ 89 self._gitHash = match["hash"]
+ 90 self._dirty = "dirty" in match.groups()
+ 91 self._edition = match["edition"]
+ 92
+ 93 match = re_search(
+ 94 r"\s*[\w\s]+:\s(?P<major>\d+)\.(?P<minor>\d+)\.(?P<micro>\d+)", gnatLine)
+ 95
+ 96 if match is None:
+ 97 raise CLIToolException(f"Unknown second GHDL version string '{gnatLine}'.")
+ 98
+ 99 self._gnatCompiler = (match["major"], match["minor"], match["micro"])
+ 100
+ 101 match = re_search(
+ 102 r"\s*(?P<backend>\w+)\scode\sgenerator", backendLine)
+ 103
+ 104 if match is None:
+ 105 raise CLIToolException(f"Unknown third GHDL version string '{backendLine}'.")
+ 106
+ 107 self._backend = match["backend"]
+ 108
+ 109 @property
+ 110 def Major(self) -> int:
+ 111 return self._major
+ 112
+ 113 @property
+ 114 def Minor(self) -> int:
+ 115 return self._minor
+ 116
+ 117 @property
+ 118 def Micro(self) -> int:
+ 119 return self._micro
+ 120
+ 121 @property
+ 122 def Dev(self) -> bool:
+ 123 return self._dev
+ 124
+ 125 @property
+ 126 def CommitsSinceLastTag(self) -> int:
+ 127 return self._commitsSinceLastTag
+ 128
+ 129 @property
+ 130 def GitHash(self) -> str:
+ 131 return self._gitHash
+ 132
+ 133 @property
+ 134 def Dirty(self) -> bool:
+ 135 return self._dirty
+ 136
+ 137 @property
+ 138 def Edition(self) -> str:
+ 139 return self._edition
+ 140
+ 141 def __str__(self) -> str:
+ 142 dev = f"-dev" if self._dev else ""
+ 143 return f"{self._major}.{self._minor}.{self._micro}{dev}"
+ 144
+ 145 def __repr__(self) -> str:
+ 146 return f"{self.__str__()} (Backend: {self._backend}; Git: {self._gitHash})"
+ 147
+ 148
+ 149@export
+ 150class GHDL(Executable):
+ 151 _executableNames = {
+ 152 "Darwin": "ghdl",
+ 153 "Linux": "ghdl",
+ 154 "Windows": "ghdl.exe"
+ 155 }
+ 156
+ 157 # XXX: overwrite __init__ and get backend variant
+ 158 # XXX: check for compatible backends
+ 159
+ 160 @CLIArgument()
+ 161 class CommandHelp(CommandArgument, name="help"):
+ 162 """Print help page(s)."""
+ 163
+ 164 @CLIArgument()
+ 165 class CommandVersion(CommandArgument, name="version"):
+ 166 """Print version information."""
+ 167
+ 168 @CLIArgument()
+ 169 class CommandSyntax(CommandArgument, name="syntax"):
+ 170 """Check syntax."""
+ 171
+ 172 @CLIArgument()
+ 173 class CommandElaborationOrder(CommandArgument, name="elab-order"):
+ 174 """Display (elaboration) ordered source files."""
+ 175
+ 176 @CLIArgument()
+ 177 class CommandAnalyze(CommandArgument, name="analyze"):
+ 178 """Analyze VHDL source file(s)."""
+ 179
+ 180 @CLIArgument()
+ 181 class CommandElaborate(CommandArgument, name="elaborate"):
+ 182 """Elaborate design."""
+ 183
+ 184 @CLIArgument()
+ 185 class CommandElaborationAndRun(CommandArgument, name="elab-run"):
+ 186 """Elaborate and simulate design."""
+ 187
+ 188 @CLIArgument()
+ 189 class CommandRun(CommandArgument, name="run"):
+ 190 """Simulate design."""
+ 191
+ 192 @CLIArgument()
+ 193 class CommandBind(CommandArgument, name="bind"):
+ 194 """Bind design unit."""
+ 195
+ 196 @CLIArgument()
+ 197 class CommandLink(CommandArgument, name="link"):
+ 198 """Link design unit."""
+ 199
+ 200 @CLIArgument()
+ 201 class CommandListLink(CommandArgument, name="list-link"):
+ 202 """List objects file to link a design unit."""
+ 203
+ 204 @CLIArgument()
+ 205 class CommandCompile(CommandArgument, name="compile"):
+ 206 """Generate whole sequence to elaborate design from files."""
+ 207
+ 208 @CLIArgument()
+ 209 class CommandGenerateDependencies(CommandArgument, name="gen-depends"):
+ 210 """Generate dependencies of design."""
+ 211
+ 212 @CLIArgument()
+ 213 class CommandSynthesize(CommandArgument, name="synth"):
+ 214 """Synthesis from design unit."""
+ 215
+ 216 @CLIArgument()
+ 217 class FlagVerbose(ShortFlag, name="v"):
+ 218 """Run in verbose mode (print more messages)."""
+ 219
+ 220 # Analyze and elaborate options
+ 221 @CLIArgument()
+ 222 class FlagVHDLStandard(LongValuedFlag, name="std"):
+ 223 """Set the used VHDL standard version."""
+ 224 _value: VHDLVersion
+ 225
+ 226 def __init__(self, value: VHDLVersion):
+ 227 if value is None: 227 ↛ 228line 227 didn't jump to line 228, because the condition on line 227 was never true
+ 228 raise ValueError(f"") # XXX: add message
+ 229
+ 230 self._value = value
+ 231
+ 232 @property
+ 233 def Value(self) -> VHDLVersion:
+ 234 return self._value
+ 235
+ 236 @Value.setter
+ 237 def Value(self, value: VHDLVersion) -> None:
+ 238 if value is None:
+ 239 raise ValueError(f"") # XXX: add message
+ 240
+ 241 self._value = value
+ 242
+ 243 def AsArgument(self) -> Union[str, Iterable[str]]:
+ 244 if self._name is None: 244 ↛ 245line 244 didn't jump to line 245, because the condition on line 244 was never true
+ 245 raise ValueError(f"") # XXX: add message
+ 246
+ 247 return self._pattern.format(self._name, str(self._value)[-2:])
+ 248
+ 249 @CLIArgument()
+ 250 class FlagIEEEFlavor(LongValuedFlag, name="ieee"):
+ 251 """Set the used VHDL flavor."""
+ 252
+ 253 @CLIArgument()
+ 254 class FlagSynopsys(ShortFlag, name="fsynopsys"):
+ 255 """Set used VHDL flavor to *Synopsys* and make Synopsys packages visible in library ``ìeee``."""
+ 256
+ 257 @CLIArgument()
+ 258 class FlagRelaxed(ShortFlag, name="frelaxed"):
+ 259 """Relax some LRM rules."""
+ 260
+ 261 @CLIArgument()
+ 262 class FlagExplicit(ShortFlag, name="fexplicit"): ...
+ 263
+ 264 @CLIArgument()
+ 265 class FlagLibrary(LongValuedFlag, name="work"):
+ 266 """Set working library."""
+ 267
+ 268 @CLIArgument()
+ 269 class FlagWorkingDirectory(LongValuedFlag, name="workdir"):
+ 270 """Set working directory."""
+ 271
+ 272 @CLIArgument()
+ 273 class FlagMultiByteComments(LongFlag, name="mb-comments"):
+ 274 """Allow multi-byte comments."""
+ 275
+ 276 @CLIArgument()
+ 277 class FlagSyntesisBindingRule(LongFlag, name="syn-binding"):
+ 278 """Enable synthesis binding rule."""
+ 279
+ 280 @CLIArgument()
+ 281 class FlagSearchPath(ShortValuedFlag, name="P", pattern="-{0}{1}"):
+ 282 """Add search path."""
+ 283
+ 284 @CLIArgument()
+ 285 class FlagTimeResolution(LongValuedFlag, name="time-resolution"):
+ 286 """Set base time resolution.
+ 287
+ 288 Allowed values are ``auto`` (default), ``fs``, ``ps``, ``ns``, ``us``, ``ms`` or ``sec``.
+ 289 """
+ 290
+ 291 @CLIArgument()
+ 292 class FlagVitalChecks(LongBooleanFlag, name="vital-checks", pattern="-{0}", falsePattern="--no-{0}"):
+ 293 """Check VITAL restrictions."""
+ 294
+ 295 @CLIArgument()
+ 296 class FlagWarnUnboundComponents(ShortFlag, name="binding", pattern="-W{0}"):
+ 297 """Warns for unbound components."""
+ 298
+ 299 @CLIArgument()
+ 300 class FlagWarnReservedWords(ShortFlag, name="reserved", pattern="-W{0}"):
+ 301 """Warns if VHDL'93 reserved words are used in VHDL'87."""
+ 302
+ 303 @CLIArgument()
+ 304 class FlagWarnRedefinedDesignUnits(ShortFlag, name="library", pattern="-W{0}"):
+ 305 """Warns for redefined design unit."""
+ 306
+ 307 @CLIArgument()
+ 308 class FlagWarnNonVitalGenericNames(ShortFlag, name="vital-generic", pattern="-W{0}"):
+ 309 """Warns of non-vital generic names."""
+ 310
+ 311 @CLIArgument()
+ 312 class FlagWarnElaborationChecks(ShortFlag, name="delayed-checks", pattern="-W{0}"):
+ 313 """Warns for checks performed at elaboration."""
+ 314
+ 315 @CLIArgument()
+ 316 class FlagWarnUnnecessaryPackageBody(ShortFlag, name="body", pattern="-W{0}"):
+ 317 """Warns for unnecessary package body."""
+ 318
+ 319 @CLIArgument()
+ 320 class FlagWarnOthersSpecifications(ShortFlag, name="specs", pattern="-W{0}"):
+ 321 """Warns if an all/others specification does not apply."""
+ 322
+ 323 @CLIArgument()
+ 324 class FlagSyntesisBindingRule(ShortFlag, name="unused", pattern="-W{0}"):
+ 325 """Warns for unused subprograms."""
+ 326
+ 327 @CLIArgument()
+ 328 class FlagSyntesisBindingRule(ShortFlag, name="error", pattern="-W{0}"):
+ 329 """Turns warnings into errors."""
+ 330
+ 331 @CLIArgument()
+ 332 class OptionPaths(PathListArgument):
+ 333 """Add list of VHDL files to analyze."""
+ 334
+ 335 @CLIArgument()
+ 336 class OptionTopLevel(StringArgument):
+ 337 """Specify the toplevel design unit."""
+ 338
+ 339 @CLIArgument()
+ 340 class OptionArchitecture(StringArgument):
+ 341 """Specify the architecture name, if the toplevel design unit is an entity."""
+ 342
+ 343 @CLIArgument()
+ 344 class FlagGenerics(ShortKeyValueFlag, pattern="-{0}{1}={2}"):
+ 345 """Set a generic value."""
+ 346
+ 347 @CLIArgument()
+ 348 class FlagAsserts(ShortValuedFlag, name="asserts"):
+ 349 """Select how assertions are handled.
+ 350
+ 351 It can be ``enable`` (the default), ``disable`` which disables all assertions and ``disable-at-0`` which disables
+ 352 only at the start of simulation.
+ 353 """
+ 354
+ 355 @CLIArgument()
+ 356 class FlagIEEEAsserts(ShortValuedFlag, name="ieee-asserts"):
+ 357 """Select how assertions are handled.
+ 358
+ 359 It can be ``enable`` (the default), ``disable`` which disables all assertions and ``disable-at-0`` which disables
+ 360 only at the start of simulation.
+ 361 """
+ 362
+ 363 @CLIArgument()
+ 364 class FlagStopTime(ShortValuedFlag, name="stop-time"):
+ 365 """Stop the simulation after a given simulation time.
+ 366
+ 367 The time is expressed as a time value, without any spaces. The time is the simulation time, not the real execution time.
+ 368 """
+ 369
+ 370 @CLIArgument()
+ 371 class FlagMaxDeltaCycles(ShortValuedFlag, name="stop-delta"):
+ 372 """Stop the simulation after N delta cycles in the same current time."""
+ 373
+ 374 @CLIArgument()
+ 375 class FlagDisplayDeltaCycles(ShortValuedFlag, name="disp-time"):
+ 376 """Display the time and delta cycle number as simulation advances."""
+ 377
+ 378 @CLIArgument()
+ 379 class FlagUnbufferedIO(ShortValuedFlag, name="unbuffered"):
+ 380 """Disable buffering on STDOUT, STDERR and files opened in write or append mode (TEXTIO)."""
+ 381
+ 382 @CLIArgument()
+ 383 class FlagReadWaveformOptionsFile(ShortValuedFlag, name="read-wave-opt"):
+ 384 """Filter signals to be dumped to the waveform file according to the wavefile option file provided."""
+ 385
+ 386 @CLIArgument()
+ 387 class FlagWriteWaveformOptionsFile(ShortValuedFlag, name="write-wave-opt"):
+ 388 """If the wavefile option file doesn’t exist, creates it with all the signals of the design.
+ 389 Otherwise, it throws an error, because it won’t erase an existing file.
+ 390 """
+ 391
+ 392 @CLIArgument()
+ 393 class FlagGHWWaveformFile(ShortValuedFlag, name="wave"):
+ 394 """Write the waveforms into a GHDL Waveform (``*.ghw``) file.
+ 395
+ 396 Contrary to VCD files, any VHDL type can be dumped into a GHW file.
+ 397 """
+ 398
+ 399 def _CopyParameters(self, tool: "GHDL") -> None:
+ 400 for key in self.__cliParameters__:
+ 401 if self._NeedsParameterInitialization(key):
+ 402 value = self.__cliParameters__[key].Value
+ 403 tool.__cliParameters__[key] = key(value)
+ 404 else:
+ 405 tool.__cliParameters__[key] = key()
+ 406
+ 407 def _SetParameters(self, tool: "GHDL", std: VHDLVersion = None, ieee: str = None):
+ 408 if std is not None:
+ 409 tool[self.FlagVHDLStandard] = str(std)
+ 410
+ 411 if ieee is not None:
+ 412 tool[self.FlagVHDLStandard] = ieee
+ 413
+ 414 def GetGHDLAsAnalyzer(self, std: VHDLVersion = None, ieee: str = None):
+ 415 tool = GHDL(executablePath=self._executablePath)
+ 416
+ 417 tool[tool.CommandAnalyze] = True
+ 418 self._CopyParameters(tool)
+ 419 self._SetParameters(tool, std, ieee)
+ 420
+ 421 return tool
+ 422
+ 423 def GetGHDLAsElaborator(self, std: VHDLVersion = None, ieee: str = None):
+ 424 tool = GHDL(executablePath=self._executablePath)
+ 425
+ 426 tool[tool.CommandElaborate] = True
+ 427 self._CopyParameters(tool)
+ 428 self._SetParameters(tool, std, ieee)
+ 429
+ 430 return tool
+ 431
+ 432 def GetGHDLAsSimulator(self, std: VHDLVersion = None, ieee: str = None):
+ 433 tool = GHDL(executablePath=self._executablePath)
+ 434
+ 435 tool[tool.CommandRun] = True
+ 436 self._CopyParameters(tool)
+ 437 self._SetParameters(tool, std, ieee)
+ 438
+ 439 return tool
+ 440
+ 441 def Help(self):
+ 442 tool = GHDL(executablePath=self._executablePath)
+ 443
+ 444 tool[tool.CommandHelp] = True
+ 445
+ 446 tool.StartProcess()
+ 447 return "\n".join(tool.GetLineReader())
+ 448
+ 449 def Version(self):
+ 450 tool = GHDL(executablePath=self._executablePath)
+ 451
+ 452 tool[tool.CommandVersion] = True
+ 453
+ 454 tool.StartProcess()
+ 455 iterator = iter(tool.GetLineReader())
+ 456 firstLine = next(iterator)
+ 457 secondLine = next(iterator)
+ 458 thirdLine = next(iterator)
+ 459
+ 460 return GHDLVersion(firstLine, secondLine, thirdLine)
+
+