Coverage for pyEDAA/CLITool/GHDL.py: 92%
158 statements
« prev ^ index » next coverage.py v7.4.0, created at 2024-01-12 01:00 +0000
« prev ^ index » next coverage.py v7.4.0, created at 2024-01-12 01:00 +0000
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 typing import Union, Iterable
35from pyTooling.Decorators import export
36from pyVHDLModel import VHDLVersion
38from pyTooling.CLIAbstraction import CLIArgument, Executable
39from pyTooling.CLIAbstraction.Argument import PathListArgument, StringArgument
40from pyTooling.CLIAbstraction.Command import CommandArgument
41from pyTooling.CLIAbstraction.Flag import ShortFlag, LongFlag
42from pyTooling.CLIAbstraction.BooleanFlag import LongBooleanFlag
43from pyTooling.CLIAbstraction.ValuedFlag import ShortValuedFlag, LongValuedFlag
44from pyTooling.CLIAbstraction.KeyValueFlag import ShortKeyValueFlag
47@export
48class GHDL(Executable):
49 _executableNames = {
50 "Darwin": "ghdl",
51 "Linux": "ghdl",
52 "Windows": "ghdl.exe"
53 }
55 # XXX: overwrite __init__ and get backend variant
56 # XXX: check for compatible backends
58 @CLIArgument()
59 class CommandHelp(CommandArgument, name="help"):
60 """Print help page(s)."""
62 @CLIArgument()
63 class CommandVersion(CommandArgument, name="version"):
64 """Print version information."""
66 @CLIArgument()
67 class CommandSyntax(CommandArgument, name="syntax"):
68 """Check syntax."""
70 @CLIArgument()
71 class CommandElaborationOrder(CommandArgument, name="elab-order"):
72 """Display (elaboration) ordered source files."""
74 @CLIArgument()
75 class CommandAnalyze(CommandArgument, name="analyze"):
76 """Analyze VHDL source file(s)."""
78 @CLIArgument()
79 class CommandElaborate(CommandArgument, name="elaborate"):
80 """Elaborate design."""
82 @CLIArgument()
83 class CommandElaborationAndRun(CommandArgument, name="elab-run"):
84 """Elaborate and simulate design."""
86 @CLIArgument()
87 class CommandRun(CommandArgument, name="run"):
88 """Simulate design."""
90 @CLIArgument()
91 class CommandBind(CommandArgument, name="bind"):
92 """Bind design unit."""
94 @CLIArgument()
95 class CommandLink(CommandArgument, name="link"):
96 """Link design unit."""
98 @CLIArgument()
99 class CommandListLink(CommandArgument, name="list-link"):
100 """List objects file to link a design unit."""
102 @CLIArgument()
103 class CommandCompile(CommandArgument, name="compile"):
104 """Generate whole sequence to elaborate design from files."""
106 @CLIArgument()
107 class CommandGenerateDependencies(CommandArgument, name="gen-depends"):
108 """Generate dependencies of design."""
110 @CLIArgument()
111 class CommandSynthesize(CommandArgument, name="synth"):
112 """Synthesis from design unit."""
114 @CLIArgument()
115 class FlagVerbose(ShortFlag, name="v"):
116 """Run in verbose mode (print more messages)."""
118 # Analyze and elaborate options
119 @CLIArgument()
120 class FlagVHDLStandard(LongValuedFlag, name="std"):
121 """Set the used VHDL standard version."""
122 _value: VHDLVersion
124 def __init__(self, value: VHDLVersion):
125 if value is None: 125 ↛ 126line 125 didn't jump to line 126, because the condition on line 125 was never true
126 raise ValueError(f"") # XXX: add message
128 self._value = value
130 @property
131 def Value(self) -> VHDLVersion:
132 return self._value
134 @Value.setter
135 def Value(self, value: VHDLVersion) -> None:
136 if value is None:
137 raise ValueError(f"") # XXX: add message
139 self._value = value
141 def AsArgument(self) -> Union[str, Iterable[str]]:
142 if self._name is None: 142 ↛ 143line 142 didn't jump to line 143, because the condition on line 142 was never true
143 raise ValueError(f"") # XXX: add message
145 return self._pattern.format(self._name, str(self._value)[-2:])
147 @CLIArgument()
148 class FlagIEEEFlavor(LongValuedFlag, name="ieee"):
149 """Set the used VHDL flavor."""
151 @CLIArgument()
152 class FlagSynopsys(ShortFlag, name="fsynopsys"):
153 """Set used VHDL flavor to *Synopsys* and make Synopsys packages visible in library ``ìeee``."""
155 @CLIArgument()
156 class FlagRelaxed(ShortFlag, name="frelaxed"):
157 """Relax some LRM rules."""
159 @CLIArgument()
160 class FlagExplicit(ShortFlag, name="fexplicit"): ...
162 @CLIArgument()
163 class FlagLibrary(LongValuedFlag, name="work"):
164 """Set working library."""
166 @CLIArgument()
167 class FlagWorkingDirectory(LongValuedFlag, name="workdir"):
168 """Set working directory."""
170 @CLIArgument()
171 class FlagMultiByteComments(LongFlag, name="mb-comments"):
172 """Allow multi-byte comments."""
174 @CLIArgument()
175 class FlagSyntesisBindingRule(LongFlag, name="syn-binding"):
176 """Enable synthesis binding rule."""
178 @CLIArgument()
179 class FlagSearchPath(ShortValuedFlag, name="P", pattern="-{0}{1}"):
180 """Add search path."""
182 @CLIArgument()
183 class FlagTimeResolution(LongValuedFlag, name="time-resolution"):
184 """Set base time resolution.
186 Allowed values are ``auto`` (default), ``fs``, ``ps``, ``ns``, ``us``, ``ms`` or ``sec``.
187 """
189 @CLIArgument()
190 class FlagVitalChecks(LongBooleanFlag, name="vital-checks", pattern="-{0}", falsePattern="--no-{0}"):
191 """Check VITAL restrictions."""
193 @CLIArgument()
194 class FlagWarnUnboundComponents(ShortFlag, name="binding", pattern="-W{0}"):
195 """Warns for unbound components."""
197 @CLIArgument()
198 class FlagWarnReservedWords(ShortFlag, name="reserved", pattern="-W{0}"):
199 """Warns if VHDL'93 reserved words are used in VHDL'87."""
201 @CLIArgument()
202 class FlagWarnRedefinedDesignUnits(ShortFlag, name="library", pattern="-W{0}"):
203 """Warns for redefined design unit."""
205 @CLIArgument()
206 class FlagWarnNonVitalGenericNames(ShortFlag, name="vital-generic", pattern="-W{0}"):
207 """Warns of non-vital generic names."""
209 @CLIArgument()
210 class FlagWarnElaborationChecks(ShortFlag, name="delayed-checks", pattern="-W{0}"):
211 """Warns for checks performed at elaboration."""
213 @CLIArgument()
214 class FlagWarnUnnecessaryPackageBody(ShortFlag, name="body", pattern="-W{0}"):
215 """Warns for unnecessary package body."""
217 @CLIArgument()
218 class FlagWarnOthersSpecifications(ShortFlag, name="specs", pattern="-W{0}"):
219 """Warns if an all/others specification does not apply."""
221 @CLIArgument()
222 class FlagSyntesisBindingRule(ShortFlag, name="unused", pattern="-W{0}"):
223 """Warns for unused subprograms."""
225 @CLIArgument()
226 class FlagSyntesisBindingRule(ShortFlag, name="error", pattern="-W{0}"):
227 """Turns warnings into errors."""
229 @CLIArgument()
230 class OptionPath(PathListArgument):
231 """Add VHDL file to analyze."""
233 @CLIArgument()
234 class OptionTopLevel(StringArgument):
235 """Specify the toplevel design unit."""
237 @CLIArgument()
238 class OptionArchitecture(StringArgument):
239 """Specify the architecture name, if the toplevel design unit is an entity."""
241 @CLIArgument()
242 class FlagGenerics(ShortKeyValueFlag, pattern="-{0}{1}={2}"):
243 """Set a generic value."""
245 @CLIArgument()
246 class FlagAsserts(ShortValuedFlag, name="asserts"):
247 """Select how assertions are handled.
249 It can be ``enable`` (the default), ``disable`` which disables all assertions and ``disable-at-0`` which disables
250 only at the start of simulation.
251 """
253 @CLIArgument()
254 class FlagIEEEAsserts(ShortValuedFlag, name="ieee-asserts"):
255 """Select how assertions are handled.
257 It can be ``enable`` (the default), ``disable`` which disables all assertions and ``disable-at-0`` which disables
258 only at the start of simulation.
259 """
261 @CLIArgument()
262 class FlagStopTime(ShortValuedFlag, name="stop-time"):
263 """Stop the simulation after a given simulation time.
265 The time is expressed as a time value, without any spaces. The time is the simulation time, not the real execution time.
266 """
268 @CLIArgument()
269 class FlagMaxDeltaCycles(ShortValuedFlag, name="stop-delta"):
270 """Stop the simulation after N delta cycles in the same current time."""
272 @CLIArgument()
273 class FlagDisplayDeltaCycles(ShortValuedFlag, name="disp-time"):
274 """Display the time and delta cycle number as simulation advances."""
276 @CLIArgument()
277 class FlagUnbufferedIO(ShortValuedFlag, name="unbuffered"):
278 """Disable buffering on STDOUT, STDERR and files opened in write or append mode (TEXTIO)."""
280 @CLIArgument()
281 class FlagReadWaveformOptionsFile(ShortValuedFlag, name="read-wave-opt"):
282 """Filter signals to be dumped to the waveform file according to the wavefile option file provided."""
284 @CLIArgument()
285 class FlagWriteWaveformOptionsFile(ShortValuedFlag, name="write-wave-opt"):
286 """If the wavefile option file doesn’t exist, creates it with all the signals of the design.
287 Otherwise, it throws an error, because it won’t erase an existing file.
288 """
290 @CLIArgument()
291 class FlagGHWWaveformFile(ShortValuedFlag, name="wave"):
292 """Write the waveforms into a GHDL Waveform (``*.ghw``) file.
294 Contrary to VCD files, any VHDL type can be dumped into a GHW file.
295 """
297 def _CopyParameters(self, tool: "GHDL") -> None:
298 for key in self.__cliParameters__:
299 if self._NeedsParameterInitialization(key):
300 value = self.__cliParameters__[key].Value
301 tool.__cliParameters__[key] = key(value)
302 else:
303 tool.__cliParameters__[key] = key()
305 def _SetParameters(self, tool: "GHDL", std: VHDLVersion = None, ieee: str = None):
306 if std is not None: 306 ↛ 307line 306 didn't jump to line 307, because the condition on line 306 was never true
307 tool[self.FlagVHDLStandard] = str(std)
309 if ieee is not None: 309 ↛ 310line 309 didn't jump to line 310, because the condition on line 309 was never true
310 tool[self.FlagVHDLStandard] = ieee
312 def GetGHDLAsAnalyzer(self, std: VHDLVersion = None, ieee: str = None):
313 tool = GHDL(executablePath=self._executablePath)
315 tool[tool.CommandAnalyze] = True
316 self._CopyParameters(tool)
317 self._SetParameters(tool, std, ieee)
319 return tool
321 def GetGHDLAsElaborator(self, std: VHDLVersion = None, ieee: str = None):
322 tool = GHDL(executablePath=self._executablePath)
324 tool[tool.CommandElaborate] = True
325 self._CopyParameters(tool)
326 self._SetParameters(tool, std, ieee)
328 return tool
330 def GetGHDLAsSimulator(self, std: VHDLVersion = None, ieee: str = None):
331 tool = GHDL(executablePath=self._executablePath)
333 tool[tool.CommandRun] = True
334 self._CopyParameters(tool)
335 self._SetParameters(tool, std, ieee)
337 return tool