__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:
- 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()