Coverage for pyEDAA/ToolSetup/__init__.py: 68%

154 statements  

« prev     ^ index     » next       coverage.py v7.5.1, created at 2024-05-17 00:56 +0000

1# ==================================================================================================================== # 

2# _____ ____ _ _ ____ __ _ # 

3# _ __ _ _| ____| _ \ / \ / \ / ___|___ _ __ / _(_) __ _ _ _ _ __ ___ # 

4# | '_ \| | | | _| | | | |/ _ \ / _ \ | | / _ \| '_ \| |_| |/ _` | | | | '__/ _ \ # 

5# | |_) | |_| | |___| |_| / ___ \ / ___ \ | |__| (_) | | | | _| | (_| | |_| | | | __/ # 

6# | .__/ \__, |_____|____/_/ \_\/_/ \_(_)____\___/|_| |_|_| |_|\__, |\__,_|_| \___| # 

7# |_| |___/ |___/ # 

8# ==================================================================================================================== # 

9# Authors: # 

10# Patrick Lehmann # 

11# # 

12# License: # 

13# ==================================================================================================================== # 

14# Copyright 2014-2022 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"""Package to support configuring EDA tools for usage with pyEDAA.CLITool.""" 

32__author__ = "Patrick Lehmann" 

33__email__ = "Paebbels@gmail.com" 

34__copyright__ = "2014-2022, Patrick Lehmann" 

35__license__ = "Apache License, Version 2.0" 

36__version__ = "0.3.0" 

37__keywords__ = ["configuration", "eda", "installation", "selection"] 

38 

39 

40from pathlib import Path 

41from typing import Dict, ClassVar, cast 

42 

43from pyTooling.Configuration import Dictionary 

44from pyTooling.Decorators import export 

45from pyTooling.Configuration.YAML import Configuration 

46 

47from .DataModel import ( 

48 Installation as DM_Installation, 

49 Vendor as DM_Vendor, 

50 Tool as DM_Tool, 

51 ToolInstance as DM_ToolInstance 

52) 

53 

54 

55class ConfigurationMixIn: 

56 _config: Dictionary 

57 

58 def __init__(self, config: Dictionary): 

59 self._config = config 

60 

61 

62@export 

63class ToolInstance(DM_ToolInstance, ConfigurationMixIn): 

64 def __init__(self, config: Dictionary, parent: "Tool"): 

65 name = config.Key 

66 installationDirectory = Path(config["InstallationDirectory"]) 

67 binaryDirectory = Path(config["BinaryDirectory"]) 

68 version = config["Version"] 

69 

70 super().__init__(installationDirectory, binaryDirectory, version, parent=parent) 

71 ConfigurationMixIn.__init__(self, config) 

72 

73 

74@export 

75class Tool(DM_Tool, ConfigurationMixIn): 

76 def __init__(self, config: Dictionary, parent: "Vendor"): 

77 name = config.Key 

78 

79 super().__init__(name, parent=parent) 

80 ConfigurationMixIn.__init__(self, config) 

81 

82 @property 

83 def Default(self) -> ToolInstance: 

84 return self._LoadVariant("Default") 

85 

86 def _LoadVariant(self, key: str) -> ToolInstance: 

87 if key not in self._variants: 87 ↛ 91line 87 didn't jump to line 91, because the condition on line 87 was always true

88 instance = self._instanceClass(self._config[key], parent=self) 

89 self._variants[key] = instance 

90 else: 

91 instance = self._variants[key] 

92 

93 return instance 

94 

95 def _LoadAllVariants(self) -> None: 

96 if self._allLoaded: 

97 return 

98 

99 for key in self._config: 

100 if key not in self._variants: 

101 self._variants[key] = ToolInstance(self._config[key], parent=self) 

102 

103 self._allLoaded = True 

104 

105 

106@export 

107class Vendor(DM_Vendor, ConfigurationMixIn): 

108 _toolClasses: ClassVar[Dict[str, Tool]] 

109 

110 def __init__(self, config: Dictionary, parent: "Installations"): 

111 name = config.Key 

112 installationDirectory = config["InstallationDirectory"] 

113 

114 super().__init__(name, installationDirectory, parent=parent) 

115 ConfigurationMixIn.__init__(self, config) 

116 

117 def _LoadTool(self, key: str) -> Tool: 

118 if key not in self._tools: 118 ↛ 123line 118 didn't jump to line 123, because the condition on line 118 was always true

119 cls = self._toolClasses[key] 

120 tool = cls(self._config[key], parent=self) 

121 self._tools[key] = tool 

122 else: 

123 tool = self._tools[key] 

124 

125 return tool 

126 

127 def _LoadAllTools(self) -> None: 

128 if self._allLoaded: 

129 return 

130 

131 for key in self._config: 

132 if key not in self._tools: 

133 cls = self._toolClasses[key] 

134 self._tools[key] = cls(self._config[key], parent=self) 

135 

136 self._allLoaded = True 

137 

138 

139@export 

140class Installations(DM_Installation): 

141 from .Aldec import ActiveHDL, RivieraPRO, Aldec 

142 from .OpenSource.GHDL import GHDL 

143 from .IntelFPGA import Quartus, Altera, IntelFPGA 

144 from .Lattice import Diamond, Lattice 

145 from .OpenSource import OpenSource 

146 from .OpenSource.GTKWave import GTKWave 

147 from .SiemensEDA import ModelSim, QuestaSim, MentorGraphics 

148 from .SystemTools import Git, SystemTools 

149 from .Xilinx import ISE, Vivado, VivadoSDK, Vitis, Xilinx 

150 

151 _config: Configuration 

152 _vendorClasses: Dict[str, Vendor] = { 

153 "Aldec": Aldec, 

154 "Altera": Altera, 

155 "IntelFPGA": IntelFPGA, 

156 "Lattice": Lattice, 

157 "MentorGraphics": MentorGraphics, 

158 "Xilinx": Xilinx, 

159 "SystemTools": SystemTools, 

160 "OpenSource": OpenSource 

161 } 

162 

163 def __init__(self, yamlFile: Path): 

164 super().__init__() 

165 self._config = Configuration(yamlFile) 

166 

167 def _LoadVendor(self, key: str) -> Vendor: 

168 cls = self._vendorClasses[key] 

169 vendor = cls(self._config["Installations"][key], parent=self) 

170 self._vendors[key] = vendor 

171 

172 return vendor 

173 

174 def _LoadAllVendors(self) -> None: 

175 if self._allLoaded: 

176 return 

177 

178 for key in self._config["Installations"]: 

179 if key not in self._vendors: 

180 cls = self._vendorClasses[key] 

181 self._vendors[key] = cls(self._config["Installations"][key], parent=self) 

182 

183 self._allLoaded = True 

184 

185 @property 

186 def Aldec(self) -> Aldec: 

187 from .Aldec import Aldec 

188 return cast(Aldec, self.__getitem__("Aldec")) 

189 

190 @property 

191 def Altera(self) -> Altera: 

192 from .IntelFPGA import Altera 

193 return cast(Altera, self.__getitem__("Altera")) 

194 

195 @property 

196 def IntelFPGA(self) -> IntelFPGA: 

197 from .IntelFPGA import IntelFPGA 

198 return cast(IntelFPGA, self.__getitem__("IntelFPGA")) 

199 

200 @property 

201 def Lattice(self) -> Lattice: 

202 from .Lattice import Lattice 

203 return cast(Lattice, self.__getitem__("Lattice")) 

204 

205 @property 

206 def MentorGraphics(self) -> MentorGraphics: 

207 from .SiemensEDA import MentorGraphics 

208 return cast(MentorGraphics, self.__getitem__("MentorGraphics")) 

209 

210 @property 

211 def OpenSource(self) -> OpenSource: 

212 from .OpenSource import OpenSource 

213 return cast(OpenSource, self.__getitem__("OpenSource")) 

214 

215 @property 

216 def SiemensEDA(self) -> SiemensEDA: 

217 from .SiemensEDA import SiemensEDA 

218 return cast(SiemensEDA, self.__getitem__("SiemensEDA")) 

219 

220 @property 

221 def SystemTools(self) -> SystemTools: 

222 from .SystemTools import SystemTools 

223 return cast(SystemTools, self.__getitem__("SystemTools")) 

224 

225 @property 

226 def Xilinx(self) -> Xilinx: 

227 from .Xilinx import Xilinx 

228 return cast(Xilinx, self.__getitem__("Xilinx")) 

229 

230 @property 

231 def ActiveHDL(self) -> ActiveHDL: 

232 raise NotImplementedError() 

233 

234 @property 

235 def RivieraPRO(self) -> RivieraPRO: 

236 raise NotImplementedError() 

237 

238 @property 

239 def Diamond(self) -> Diamond: 

240 raise NotImplementedError() 

241 

242 @property 

243 def Quartus(self) -> Quartus: 

244 raise NotImplementedError() 

245 

246 @property 

247 def ModelSim(self) -> ModelSim: 

248 raise NotImplementedError() 

249 

250 @property 

251 def QuestaSim(self) -> QuestaSim: 

252 raise NotImplementedError() 

253 

254 @property 

255 def Vivado(self) -> Vivado: 

256 raise NotImplementedError() 

257 

258 @property 

259 def VivadoSDK(self) -> VivadoSDK: 

260 raise NotImplementedError() 

261 

262 @property 

263 def Vitis(self) -> Vitis: 

264 raise NotImplementedError()