__init__.py

Summary

Lines:

118 of 157 covered (75.2%)

Excluded lines:

9

Branches:

2 of 22 taken (9.1%), 2 lines partially

Coverage:

67.0%

Directory:

ToolSetup

Missed lines:

97, 104, 109-116, 136, 141-149, 188-196, 205-206, 210-211, 215-216, 220-221, 225-226, 230-231, 235-236, 240-241

Source

pyEDAA/ToolSetup/__init__.pycoveredpartialuncoveredexcludednot executable
1# ==================================================================================================================== #
2#              _____ ____    _        _    _____           _ ____       _                                              #
3#  _ __  _   _| ____|  _ \  / \      / \  |_   _|__   ___ | / ___|  ___| |_ _   _ _ __                                 #
4# | '_ \| | | |  _| | | | |/ _ \    / _ \   | |/ _ \ / _ \| \___ \ / _ \ __| | | | '_ \                                #
5# | |_) | |_| | |___| |_| / ___ \  / ___ \ _| | (_) | (_) | |___) |  __/ |_| |_| | |_) |                               #
6# | .__/ \__, |_____|____/_/   \_\/_/   \_(_)_|\___/ \___/|_|____/ \___|\__|\__,_| .__/                                #
7# |_|    |___/                                                                   |_|                                   #
8# ==================================================================================================================== #
9# Authors:                                                                                                             #
10#   Patrick Lehmann                                                                                                    #
11#                                                                                                                      #
12# License:                                                                                                             #
13# ==================================================================================================================== #
14# Copyright 2021-2026 Electronic Design Automation Abstraction (EDA²)                                                  #
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"""Package to support configuring EDA tools for usage with pyEDAA.CLITool."""
32__author__ =            "Patrick Lehmann"
33__email__ =             "Paebbels@gmail.com"
34__copyright__ =         "2021-2026, Electronic Design Automation Abstraction (EDA²)"
35__license__ =           "Apache License, Version 2.0"
36__version__ =           "0.6.0"
37__keywords__ =          ["configuration", "eda", "installation", "selection"]
38__project_url__ =       "https://github.com/edaa-org/pyEDAA.ToolSetup"
39__documentation_url__ = "https://edaa-org.github.io/pyEDAA.ToolSetup"
40__issue_tracker_url__ = "https://GitHub.com/edaa-org/pyEDAA.ToolSetup/issues"
41
42
43from pathlib import Path
44from typing  import Dict, ClassVar, cast
45
46from pyTooling.Decorators         import export
47from pyTooling.Exceptions         import ExceptionBase
48from pyTooling.Configuration      import Dictionary
49from pyTooling.Configuration.YAML import Configuration
50
51from .DataModel import Installation as DM_Installation, Vendor as DM_Vendor, Tool as DM_Tool, \
52                       ToolInstance as DM_ToolInstance
53
54
55class ToolChainException(ExceptionBase):
56	"""Base-class for all pyEDAA.ToolSetup specific exceptions."""
57
58class ConfigurationException(ExceptionBase):
59	"""``ConfigurationException`` is raise while running configuration or database
60	tasks in pyIPCMI
61	"""
62
63class SkipConfigurationException(ExceptionBase):
64	"""``SkipConfigurationException`` is a :py:exc:`ConfigurationException`,
65	which can be skipped.
66	"""
67
68class ConfigurationMixIn:
69	_config: Dictionary
70
71	def __init__(self, config: Dictionary) -> None:
72		self._config = config
73
74
75@export
76class ToolInstance(DM_ToolInstance, ConfigurationMixIn):
77	def __init__(self, config: Dictionary, parent: "Tool") -> None:
78		name = config.Key
79		installationDirectory = Path(config["InstallationDirectory"])
80		binaryDirectory = Path(config["BinaryDirectory"])
81		version = config["Version"]
82
83		super().__init__(installationDirectory, binaryDirectory, version, parent=parent)
84		ConfigurationMixIn.__init__(self, config)
85
86
87@export
88class Tool(DM_Tool, ConfigurationMixIn):
89	def __init__(self, config: Dictionary, parent: "Vendor") -> None:
90		name = config.Key
91
92		super().__init__(name, parent=parent)
93		ConfigurationMixIn.__init__(self, config)
94
95	@property
96	def Default(self) -> ToolInstance:
97		return self._LoadVariant("Default")
98
99	def _LoadVariant(self, key: str) -> ToolInstance:
100		if key not in self._variants:
101			instance = self._instanceClass(self._config[key], parent=self)
102			self._variants[key] = instance
103		else:
104			instance = self._variants[key]
105
106		return instance
107
108	def _LoadAllVariants(self) -> None:
109		if self._allLoaded:
110			return
111
112		for key in self._config:
113			if key not in self._variants:
114				self._variants[key] = ToolInstance(self._config[key], parent=self)
115
116		self._allLoaded = True
117
118
119@export
120class Vendor(DM_Vendor, ConfigurationMixIn):
121	_toolClasses: ClassVar[Dict[str, Tool]]
122
123	def __init__(self, config: Dictionary, parent: "Installations") -> None:
124		name = config.Key
125		installationDirectory = Path(config["InstallationDirectory"])
126
127		super().__init__(name, installationDirectory, parent=parent)
128		ConfigurationMixIn.__init__(self, config)
129
130	def _LoadTool(self, key: str) -> Tool:
131		if key not in self._tools:
132			cls = self._toolClasses[key]
133			tool = cls(self._config[key], parent=self)
134			self._tools[key] = tool
135		else:
136			tool = self._tools[key]
137
138		return tool
139
140	def _LoadAllTools(self) -> None:
141		if self._allLoaded:
142			return
143
144		for key in self._config:
145			if key not in self._tools:
146				cls = self._toolClasses[key]
147				self._tools[key] = cls(self._config[key], parent=self)
148
149		self._allLoaded = True
150
151
152@export
153class Installations(DM_Installation):
154	from .Aldec import ActiveHDL, RivieraPRO, Aldec
155	from .OpenSource.GHDL import GHDL
156	from .IntelFPGA import Quartus, Altera, IntelFPGA
157	from .Lattice import Diamond, Lattice
158	from .OpenSource import OpenSource
159	from .OpenSource.GTKWave import GTKWave
160	from .SiemensEDA import ModelSim, QuestaSim, MentorGraphics
161	from .SystemTools import Git, SystemTools
162	from .Xilinx import ISE, Vivado, VivadoSDK, Vitis, Xilinx
163
164	_config: Configuration
165	_vendorClasses: Dict[str, Vendor] = {
166		"Aldec": Aldec,
167		"Altera": Altera,
168		"IntelFPGA": IntelFPGA,
169		"Lattice": Lattice,
170		"MentorGraphics": MentorGraphics,
171		"Xilinx": Xilinx,
172		"SystemTools": SystemTools,
173		"OpenSource": OpenSource
174	}
175
176	def __init__(self, yamlFile: Path) -> None:
177		super().__init__()
178		self._config = Configuration(yamlFile)
179
180	def _LoadVendor(self, key: str) -> Vendor:
181		cls = self._vendorClasses[key]
182		vendor = cls(self._config["Installations"][key], parent=self)
183		self._vendors[key] = vendor
184
185		return vendor
186
187	def _LoadAllVendors(self) -> None:
188		if self._allLoaded:
189			return
190
191		for key in self._config["Installations"]:
192			if key not in self._vendors:
193				cls = self._vendorClasses[key]
194				self._vendors[key] = cls(self._config["Installations"][key], parent=self)
195
196		self._allLoaded = True
197
198	@property
199	def Aldec(self) -> Aldec:
200		from .Aldec import Aldec
201		return cast(Aldec, self.__getitem__("Aldec"))
202
203	@property
204	def Altera(self) -> Altera:
205		from .IntelFPGA import Altera
206		return cast(Altera, self.__getitem__("Altera"))
207
208	@property
209	def IntelFPGA(self) -> IntelFPGA:
210		from .IntelFPGA import IntelFPGA
211		return cast(IntelFPGA, self.__getitem__("IntelFPGA"))
212
213	@property
214	def Lattice(self) -> Lattice:
215		from .Lattice import Lattice
216		return cast(Lattice, self.__getitem__("Lattice"))
217
218	@property
219	def MentorGraphics(self) -> MentorGraphics:
220		from .SiemensEDA import MentorGraphics
221		return cast(MentorGraphics, self.__getitem__("MentorGraphics"))
222
223	@property
224	def OpenSource(self) -> OpenSource:
225		from .OpenSource import OpenSource
226		return cast(OpenSource, self.__getitem__("OpenSource"))
227
228	@property
229	def SiemensEDA(self) -> SiemensEDA:
230		from .SiemensEDA import SiemensEDA
231		return cast(SiemensEDA, self.__getitem__("SiemensEDA"))
232
233	@property
234	def SystemTools(self) -> SystemTools:
235		from .SystemTools import SystemTools
236		return cast(SystemTools, self.__getitem__("SystemTools"))
237
238	@property
239	def Xilinx(self) -> Xilinx:
240		from .Xilinx import Xilinx
241		return cast(Xilinx, self.__getitem__("Xilinx"))
242
243	@property
244	def ActiveHDL(self) -> ActiveHDL:
245		raise NotImplementedError()
246
247	@property
248	def RivieraPRO(self) -> RivieraPRO:
249		raise NotImplementedError()
250
251	@property
252	def Diamond(self) -> Diamond:
253		raise NotImplementedError()
254
255	@property
256	def Quartus(self) -> Quartus:
257		raise NotImplementedError()
258
259	@property
260	def ModelSim(self) -> ModelSim:
261		raise NotImplementedError()
262
263	@property
264	def QuestaSim(self) -> QuestaSim:
265		raise NotImplementedError()
266
267	@property
268	def Vivado(self) -> Vivado:
269		raise NotImplementedError()
270
271	@property
272	def VivadoSDK(self) -> VivadoSDK:
273		raise NotImplementedError()
274
275	@property
276	def Vitis(self) -> Vitis:
277		raise NotImplementedError()