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

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 

34 

35from pyTooling.Decorators import export 

36from pyVHDLModel import VHDLVersion 

37 

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 

45 

46 

47@export 

48class GHDL(Executable): 

49 _executableNames = { 

50 "Darwin": "ghdl", 

51 "Linux": "ghdl", 

52 "Windows": "ghdl.exe" 

53 } 

54 

55 # XXX: overwrite __init__ and get backend variant 

56 # XXX: check for compatible backends 

57 

58 @CLIArgument() 

59 class CommandHelp(CommandArgument, name="help"): 

60 """Print help page(s).""" 

61 

62 @CLIArgument() 

63 class CommandVersion(CommandArgument, name="version"): 

64 """Print version information.""" 

65 

66 @CLIArgument() 

67 class CommandSyntax(CommandArgument, name="syntax"): 

68 """Check syntax.""" 

69 

70 @CLIArgument() 

71 class CommandElaborationOrder(CommandArgument, name="elab-order"): 

72 """Display (elaboration) ordered source files.""" 

73 

74 @CLIArgument() 

75 class CommandAnalyze(CommandArgument, name="analyze"): 

76 """Analyze VHDL source file(s).""" 

77 

78 @CLIArgument() 

79 class CommandElaborate(CommandArgument, name="elaborate"): 

80 """Elaborate design.""" 

81 

82 @CLIArgument() 

83 class CommandElaborationAndRun(CommandArgument, name="elab-run"): 

84 """Elaborate and simulate design.""" 

85 

86 @CLIArgument() 

87 class CommandRun(CommandArgument, name="run"): 

88 """Simulate design.""" 

89 

90 @CLIArgument() 

91 class CommandBind(CommandArgument, name="bind"): 

92 """Bind design unit.""" 

93 

94 @CLIArgument() 

95 class CommandLink(CommandArgument, name="link"): 

96 """Link design unit.""" 

97 

98 @CLIArgument() 

99 class CommandListLink(CommandArgument, name="list-link"): 

100 """List objects file to link a design unit.""" 

101 

102 @CLIArgument() 

103 class CommandCompile(CommandArgument, name="compile"): 

104 """Generate whole sequence to elaborate design from files.""" 

105 

106 @CLIArgument() 

107 class CommandGenerateDependencies(CommandArgument, name="gen-depends"): 

108 """Generate dependencies of design.""" 

109 

110 @CLIArgument() 

111 class CommandSynthesize(CommandArgument, name="synth"): 

112 """Synthesis from design unit.""" 

113 

114 @CLIArgument() 

115 class FlagVerbose(ShortFlag, name="v"): 

116 """Run in verbose mode (print more messages).""" 

117 

118 # Analyze and elaborate options 

119 @CLIArgument() 

120 class FlagVHDLStandard(LongValuedFlag, name="std"): 

121 """Set the used VHDL standard version.""" 

122 _value: VHDLVersion 

123 

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 

127 

128 self._value = value 

129 

130 @property 

131 def Value(self) -> VHDLVersion: 

132 return self._value 

133 

134 @Value.setter 

135 def Value(self, value: VHDLVersion) -> None: 

136 if value is None: 

137 raise ValueError(f"") # XXX: add message 

138 

139 self._value = value 

140 

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 

144 

145 return self._pattern.format(self._name, str(self._value)[-2:]) 

146 

147 @CLIArgument() 

148 class FlagIEEEFlavor(LongValuedFlag, name="ieee"): 

149 """Set the used VHDL flavor.""" 

150 

151 @CLIArgument() 

152 class FlagSynopsys(ShortFlag, name="fsynopsys"): 

153 """Set used VHDL flavor to *Synopsys* and make Synopsys packages visible in library ``ìeee``.""" 

154 

155 @CLIArgument() 

156 class FlagRelaxed(ShortFlag, name="frelaxed"): 

157 """Relax some LRM rules.""" 

158 

159 @CLIArgument() 

160 class FlagExplicit(ShortFlag, name="fexplicit"): ... 

161 

162 @CLIArgument() 

163 class FlagLibrary(LongValuedFlag, name="work"): 

164 """Set working library.""" 

165 

166 @CLIArgument() 

167 class FlagWorkingDirectory(LongValuedFlag, name="workdir"): 

168 """Set working directory.""" 

169 

170 @CLIArgument() 

171 class FlagMultiByteComments(LongFlag, name="mb-comments"): 

172 """Allow multi-byte comments.""" 

173 

174 @CLIArgument() 

175 class FlagSyntesisBindingRule(LongFlag, name="syn-binding"): 

176 """Enable synthesis binding rule.""" 

177 

178 @CLIArgument() 

179 class FlagSearchPath(ShortValuedFlag, name="P", pattern="-{0}{1}"): 

180 """Add search path.""" 

181 

182 @CLIArgument() 

183 class FlagTimeResolution(LongValuedFlag, name="time-resolution"): 

184 """Set base time resolution. 

185 

186 Allowed values are ``auto`` (default), ``fs``, ``ps``, ``ns``, ``us``, ``ms`` or ``sec``. 

187 """ 

188 

189 @CLIArgument() 

190 class FlagVitalChecks(LongBooleanFlag, name="vital-checks", pattern="-{0}", falsePattern="--no-{0}"): 

191 """Check VITAL restrictions.""" 

192 

193 @CLIArgument() 

194 class FlagWarnUnboundComponents(ShortFlag, name="binding", pattern="-W{0}"): 

195 """Warns for unbound components.""" 

196 

197 @CLIArgument() 

198 class FlagWarnReservedWords(ShortFlag, name="reserved", pattern="-W{0}"): 

199 """Warns if VHDL'93 reserved words are used in VHDL'87.""" 

200 

201 @CLIArgument() 

202 class FlagWarnRedefinedDesignUnits(ShortFlag, name="library", pattern="-W{0}"): 

203 """Warns for redefined design unit.""" 

204 

205 @CLIArgument() 

206 class FlagWarnNonVitalGenericNames(ShortFlag, name="vital-generic", pattern="-W{0}"): 

207 """Warns of non-vital generic names.""" 

208 

209 @CLIArgument() 

210 class FlagWarnElaborationChecks(ShortFlag, name="delayed-checks", pattern="-W{0}"): 

211 """Warns for checks performed at elaboration.""" 

212 

213 @CLIArgument() 

214 class FlagWarnUnnecessaryPackageBody(ShortFlag, name="body", pattern="-W{0}"): 

215 """Warns for unnecessary package body.""" 

216 

217 @CLIArgument() 

218 class FlagWarnOthersSpecifications(ShortFlag, name="specs", pattern="-W{0}"): 

219 """Warns if an all/others specification does not apply.""" 

220 

221 @CLIArgument() 

222 class FlagSyntesisBindingRule(ShortFlag, name="unused", pattern="-W{0}"): 

223 """Warns for unused subprograms.""" 

224 

225 @CLIArgument() 

226 class FlagSyntesisBindingRule(ShortFlag, name="error", pattern="-W{0}"): 

227 """Turns warnings into errors.""" 

228 

229 @CLIArgument() 

230 class OptionPath(PathListArgument): 

231 """Add VHDL file to analyze.""" 

232 

233 @CLIArgument() 

234 class OptionTopLevel(StringArgument): 

235 """Specify the toplevel design unit.""" 

236 

237 @CLIArgument() 

238 class OptionArchitecture(StringArgument): 

239 """Specify the architecture name, if the toplevel design unit is an entity.""" 

240 

241 @CLIArgument() 

242 class FlagGenerics(ShortKeyValueFlag, pattern="-{0}{1}={2}"): 

243 """Set a generic value.""" 

244 

245 @CLIArgument() 

246 class FlagAsserts(ShortValuedFlag, name="asserts"): 

247 """Select how assertions are handled. 

248 

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 """ 

252 

253 @CLIArgument() 

254 class FlagIEEEAsserts(ShortValuedFlag, name="ieee-asserts"): 

255 """Select how assertions are handled. 

256 

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 """ 

260 

261 @CLIArgument() 

262 class FlagStopTime(ShortValuedFlag, name="stop-time"): 

263 """Stop the simulation after a given simulation time. 

264 

265 The time is expressed as a time value, without any spaces. The time is the simulation time, not the real execution time. 

266 """ 

267 

268 @CLIArgument() 

269 class FlagMaxDeltaCycles(ShortValuedFlag, name="stop-delta"): 

270 """Stop the simulation after N delta cycles in the same current time.""" 

271 

272 @CLIArgument() 

273 class FlagDisplayDeltaCycles(ShortValuedFlag, name="disp-time"): 

274 """Display the time and delta cycle number as simulation advances.""" 

275 

276 @CLIArgument() 

277 class FlagUnbufferedIO(ShortValuedFlag, name="unbuffered"): 

278 """Disable buffering on STDOUT, STDERR and files opened in write or append mode (TEXTIO).""" 

279 

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.""" 

283 

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 """ 

289 

290 @CLIArgument() 

291 class FlagGHWWaveformFile(ShortValuedFlag, name="wave"): 

292 """Write the waveforms into a GHDL Waveform (``*.ghw``) file. 

293 

294 Contrary to VCD files, any VHDL type can be dumped into a GHW file. 

295 """ 

296 

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

304 

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) 

308 

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 

311 

312 def GetGHDLAsAnalyzer(self, std: VHDLVersion = None, ieee: str = None): 

313 tool = GHDL(executablePath=self._executablePath) 

314 

315 tool[tool.CommandAnalyze] = True 

316 self._CopyParameters(tool) 

317 self._SetParameters(tool, std, ieee) 

318 

319 return tool 

320 

321 def GetGHDLAsElaborator(self, std: VHDLVersion = None, ieee: str = None): 

322 tool = GHDL(executablePath=self._executablePath) 

323 

324 tool[tool.CommandElaborate] = True 

325 self._CopyParameters(tool) 

326 self._SetParameters(tool, std, ieee) 

327 

328 return tool 

329 

330 def GetGHDLAsSimulator(self, std: VHDLVersion = None, ieee: str = None): 

331 tool = GHDL(executablePath=self._executablePath) 

332 

333 tool[tool.CommandRun] = True 

334 self._CopyParameters(tool) 

335 self._SetParameters(tool, std, ieee) 

336 

337 return tool