Coverage for pyVHDLModel/__init__.py: 74%

1137 statements  

« prev     ^ index     » next       coverage.py v7.14.1, created at 2026-06-05 23:04 +0000

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

2# __ ___ _ ____ _ __ __ _ _ # 

3# _ __ _ \ \ / / | | | _ \| | | \/ | ___ __| | ___| | # 

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

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

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

7# |_| |___/ # 

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

9# Authors: # 

10# Patrick Lehmann # 

11# # 

12# License: # 

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

14# Copyright 2017-2026 Patrick Lehmann - Boetzingen, Germany # 

15# Copyright 2016-2017 Patrick Lehmann - Dresden, Germany # 

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

33**An abstract VHDL language model.** 

34 

35This package provides a unified abstract language model for VHDL. Projects reading from source files can derive own 

36classes and implement additional logic to create a concrete language model for their tools. 

37 

38Projects consuming pre-processed VHDL data (parsed, analyzed or elaborated) can build higher level features and services 

39on such a model, while supporting multiple frontends. 

40 

41.. admonition:: Copyright Information 

42 

43 :copyright: Copyright 2017-2026 Patrick Lehmann - Bötzingen, Germany 

44 :copyright: Copyright 2016-2017 Patrick Lehmann - Dresden, Germany 

45 :license: Apache License, Version 2.0 

46""" 

47__author__ = "Patrick Lehmann" 

48__email__ = "Paebbels@gmail.com" 

49__copyright__ = "2016-2026, Patrick Lehmann" 

50__license__ = "Apache License, Version 2.0" 

51__version__ = "0.34.0" 

52 

53 

54from enum import unique, Enum, Flag, auto 

55from pathlib import Path 

56from sys import version_info 

57 

58from typing import Union, Dict, cast, List, Generator, Optional as Nullable 

59 

60from pyTooling.Common import getFullyQualifiedName 

61from pyTooling.Decorators import export, readonly 

62from pyTooling.Graph import Graph, Vertex, Edge 

63from pyTooling.Warning import WarningCollector 

64 

65from pyVHDLModel.Exception import VHDLModelException, NotImplementedWarning, BlackboxWarning 

66from pyVHDLModel.Exception import LibraryExistsInDesignError, LibraryRegisteredToForeignDesignError, LibraryNotRegisteredError, EntityExistsInLibraryError 

67from pyVHDLModel.Exception import ArchitectureExistsInLibraryError, PackageExistsInLibraryError, PackageBodyExistsError, ConfigurationExistsInLibraryError 

68from pyVHDLModel.Exception import ContextExistsInLibraryError, ReferencedLibraryNotExistingError 

69from pyVHDLModel.Base import ModelEntity, NamedEntityMixin, MultipleNamedEntityMixin, DocumentedEntityMixin 

70from pyVHDLModel.Expression import UnaryExpression, BinaryExpression, TernaryExpression 

71from pyVHDLModel.Namespace import Namespace 

72from pyVHDLModel.Object import Obj, Signal, Constant, DeferredConstant 

73from pyVHDLModel.Symbol import PackageReferenceSymbol, AllPackageMembersReferenceSymbol, PackageMemberReferenceSymbol, SimpleObjectOrFunctionCallSymbol 

74from pyVHDLModel.Common import AllowBlackboxMixin 

75from pyVHDLModel.Regions import ConcurrentDeclarationRegionMixin 

76from pyVHDLModel.Concurrent import EntityInstantiation, ComponentInstantiation, ConfigurationInstantiation 

77from pyVHDLModel.Concurrent import GenerateStatement, IfGenerateStatement, ForGenerateStatement, CaseGenerateStatement 

78from pyVHDLModel.Concurrent import GenerateBranch, ConcurrentStatementsMixin, ConcurrentBlockStatement 

79from pyVHDLModel.DesignUnit import DesignUnit, PrimaryUnit, Architecture, PackageBody, Context, Entity, Configuration, Package, Component 

80from pyVHDLModel.PSLModel import VerificationUnit, VerificationProperty, VerificationMode 

81from pyVHDLModel.Instantiation import PackageInstantiation 

82from pyVHDLModel.Type import IntegerType, PhysicalType, ArrayType, RecordType 

83 

84 

85@export 

86@unique 

87class VHDLVersion(Enum): 

88 """ 

89 An enumeration for all possible version numbers for VHDL and VHDL-AMS. 

90 

91 A version can be given as integer or string and is represented as a unified 

92 enumeration value. 

93 

94 This enumeration supports compare operators. 

95 """ 

96 

97 Any = -1 #: Any 

98 VHDL87 = 87 #: VHDL-1987 

99 VHDL93 = 93 #: VHDL-1993 

100 AMS93 = 1993 #: VHDL-AMS-1993 

101 AMS99 = 1999 #: VHDL-AMS-1999 

102 VHDL2000 = 2000 #: VHDL-2000 

103 VHDL2002 = 2002 #: VHDL-2002 

104 VHDL2008 = 2008 #: VHDL-2008 

105 AMS2017 = 2017 #: VHDL-AMS-2017 

106 VHDL2019 = 2019 #: VHDL-2019 

107 Latest = 10000 #: Latest VHDL (2019) 

108 

109 __VERSION_MAPPINGS__: Dict[Union[int, str], Enum] = { 

110 -1: Any, 

111 87: VHDL87, 

112 93: VHDL93, 

113 # 93: AMS93, 

114 99: AMS99, 

115 0: VHDL2000, 

116 2: VHDL2002, 

117 8: VHDL2008, 

118 17: AMS2017, 

119 19: VHDL2019, 

120 1987: VHDL87, 

121 # 1993: VHDL93, 

122 1993: AMS93, 

123 1999: AMS99, 

124 2000: VHDL2000, 

125 2002: VHDL2002, 

126 2008: VHDL2008, 

127 2017: AMS2017, 

128 2019: VHDL2019, 

129 10000: Latest, 

130 "Any": Any, 

131 "87": VHDL87, 

132 "93": VHDL93, 

133 # "93": AMS93, 

134 "99": AMS99, 

135 "00": VHDL2000, 

136 "02": VHDL2002, 

137 "08": VHDL2008, 

138 "17": AMS2017, 

139 "19": VHDL2019, 

140 "1987": VHDL87, 

141 # "1993": VHDL93, 

142 "1993": AMS93, 

143 "1999": AMS99, 

144 "2000": VHDL2000, 

145 "2002": VHDL2002, 

146 "2008": VHDL2008, 

147 "2017": AMS2017, 

148 "2019": VHDL2019, 

149 "Latest": Latest, 

150 } #: Dictionary of VHDL and VHDL-AMS year codes variants as integer and strings for mapping to unique enum values. 

151 

152 def __init__(self, *_) -> None: 

153 """Patch the embedded MAP dictionary""" 

154 for k, v in self.__class__.__VERSION_MAPPINGS__.items(): 

155 if (not isinstance(v, self.__class__)) and (v == self.value): 

156 self.__class__.__VERSION_MAPPINGS__[k] = self 

157 

158 @classmethod 

159 def Parse(cls, value: Union[int, str]) -> "VHDLVersion": 

160 """ 

161 Parses a VHDL or VHDL-AMS year code as integer or string to an enum value. 

162 

163 :param value: VHDL/VHDL-AMS year code. 

164 :returns: Enumeration value. 

165 :raises ValueError: If the year code is not recognized. 

166 """ 

167 try: 

168 return cls.__VERSION_MAPPINGS__[value] 

169 except KeyError: 

170 raise ValueError(f"Value '{value!s}' cannot be parsed to member of {cls.__name__}.") 

171 

172 def __lt__(self, other: Any) -> bool: 

173 """ 

174 Compare two VHDL/VHDL-AMS versions if the version is less than the second operand. 

175 

176 :param other: Parameter to compare against. 

177 :returns: True if version is less than the second operand. 

178 :raises TypeError: If parameter ``other`` is not of type :class:`VHDLVersion`. 

179 """ 

180 if isinstance(other, VHDLVersion): 

181 return self.value < other.value 

182 else: 

183 raise TypeError("Second operand is not of type 'VHDLVersion'.") 

184 

185 def __le__(self, other: Any) -> bool: 

186 """ 

187 Compare two VHDL/VHDL-AMS versions if the version is less or equal than the second operand. 

188 

189 :param other: Parameter to compare against. 

190 :returns: True if version is less or equal than the second operand. 

191 :raises TypeError: If parameter ``other`` is not of type :class:`VHDLVersion`. 

192 """ 

193 if isinstance(other, VHDLVersion): 

194 return self.value <= other.value 

195 else: 

196 raise TypeError("Second operand is not of type 'VHDLVersion'.") 

197 

198 def __gt__(self, other: Any) -> bool: 

199 """ 

200 Compare two VHDL/VHDL-AMS versions if the version is greater than the second operand. 

201 

202 :param other: Parameter to compare against. 

203 :returns: True if version is greater than the second operand. 

204 :raises TypeError: If parameter ``other`` is not of type :class:`VHDLVersion`. 

205 """ 

206 if isinstance(other, VHDLVersion): 

207 return self.value > other.value 

208 else: 

209 raise TypeError("Second operand is not of type 'VHDLVersion'.") 

210 

211 def __ge__(self, other: Any) -> bool: 

212 """ 

213 Compare two VHDL/VHDL-AMS versions if the version is greater or equal than the second operand. 

214 

215 :param other: Parameter to compare against. 

216 :returns: True if version is greater or equal than the second operand. 

217 :raises TypeError: If parameter ``other`` is not of type :class:`VHDLVersion`. 

218 """ 

219 if isinstance(other, VHDLVersion): 

220 return self.value >= other.value 

221 else: 

222 raise TypeError("Second operand is not of type 'VHDLVersion'.") 

223 

224 def __ne__(self, other: Any) -> bool: 

225 """ 

226 Compare two VHDL/VHDL-AMS versions if the version is unequal to the second operand. 

227 

228 :param other: Parameter to compare against. 

229 :returns: True if version is unequal to the second operand. 

230 :raises TypeError: If parameter ``other`` is not of type :class:`VHDLVersion`. 

231 """ 

232 if isinstance(other, VHDLVersion): 

233 return self.value != other.value 

234 else: 

235 raise TypeError("Second operand is not of type 'VHDLVersion'.") 

236 

237 def __eq__(self, other: Any) -> bool: 

238 """ 

239 Compare two VHDL/VHDL-AMS versions if the version is equal to the second operand. 

240 

241 :param other: Parameter to compare against. 

242 :returns: True if version is equal to the second operand. 

243 :raises TypeError: If parameter ``other`` is not of type :class:`VHDLVersion`. 

244 """ 

245 if isinstance(other, VHDLVersion): 

246 if (self is self.__class__.Any) or (other is self.__class__.Any): 

247 return True 

248 else: 

249 return self.value == other.value 

250 else: 

251 raise TypeError("Second operand is not of type 'VHDLVersion'.") 

252 

253 @readonly 

254 def IsVHDL(self) -> bool: 

255 """ 

256 Checks if the version is a VHDL (not VHDL-AMS) version. 

257 

258 :returns: True if version is a VHDL version. 

259 """ 

260 return self in (self.VHDL87, self.VHDL93, self.VHDL2002, self.VHDL2008, self.VHDL2019) 

261 

262 @readonly 

263 def IsAMS(self) -> bool: 

264 """ 

265 Checks if the version is a VHDL-AMS (not VHDL) version. 

266 

267 :returns: True if version is a VHDL-AMS version. 

268 """ 

269 return self in (self.AMS93, self.AMS99, self.AMS2017) 

270 

271 def __str__(self) -> str: 

272 """ 

273 Formats the VHDL version to pattern ``VHDL'xx`` or in case of VHDL-AMS to ``VHDL-AMS'xx``. 

274 

275 :returns: Formatted VHDL/VHDL-AMS version. 

276 """ 

277 if self.value == self.Any.value: 

278 return "VHDL'Any" 

279 elif self.value == self.Latest.value: 

280 return "VHDL'Latest" 

281 

282 year = str(self.value)[-2:] 

283 if self.IsVHDL: 

284 return f"VHDL'{year}" 

285 else: 

286 return f"VHDL-AMS'{year}" 

287 

288 def __repr__(self) -> str: 

289 """ 

290 Formats the VHDL/VHDL-AMS version to pattern ``xxxx``. 

291 

292 :returns: Formatted VHDL/VHDL-AMS version. 

293 """ 

294 if self.value == self.Any.value: 

295 return "Any" 

296 elif self.value == self.Latest.value: 

297 return "Latest" 

298 else: 

299 return str(self.value) 

300 

301 

302@export 

303class IEEEFlavor(Flag): 

304 Unknown = 0 

305 IEEE = 1 

306 Synopsys = 2 

307 MentorGraphics = 4 

308 WithVITAL = 32 # VITAL = VHDL Initiative Towards ASIC Libraries 

309 

310 

311@export 

312@unique 

313class ObjectClass(Enum): 

314 """ 

315 An ``ObjectClass`` is an enumeration and represents an object's class (``constant``, ``signal``, ...). 

316 

317 In case no *object class* is defined, ``Default`` is used, so the *object class* is inferred from context. 

318 """ 

319 

320 Default = 0 #: Object class not defined, thus it's context dependent. 

321 Constant = 1 #: Constant 

322 Variable = 2 #: Variable 

323 Signal = 3 #: Signal 

324 File = 4 #: File 

325 Type = 5 #: Type 

326 # FIXME: Package? 

327 Procedure = 6 #: Procedure 

328 Function = 7 #: Function 

329 

330 def __str__(self) -> str: 

331 """ 

332 Formats the object class. 

333 

334 :returns: Formatted object class. 

335 """ 

336 return ("", "constant", "variable", "signal", "file", "type", "procedure", "function")[cast(int, self.value)] # TODO: check performance 

337 

338 

339@export 

340@unique 

341class DesignUnitKind(Flag): 

342 """ 

343 A ``DesignUnitKind`` is an enumeration and represents the kind of design unit (``Entity``, ``Architecture``, ...). 

344 

345 """ 

346 Context = auto() #: Context 

347 Package = auto() #: Package 

348 PackageBody = auto() #: Package Body 

349 Entity = auto() #: Entity 

350 Architecture = auto() #: Architecture 

351 Configuration = auto() #: Configuration 

352 

353 Primary = Context | Configuration | Entity | Package #: List of primary design units. 

354 Secondary = PackageBody | Architecture #: List of secondary design units. 

355 WithContext = Configuration | Package | Entity | PackageBody | Architecture #: List of design units with a context. 

356 WithDeclaredItems = Package | Entity | PackageBody | Architecture #: List of design units having a declaration region. 

357 

358 All = Primary | Secondary #: List of all design units. 

359 

360 

361@export 

362@unique 

363class DependencyGraphVertexKind(Flag): 

364 """ 

365 A ``DependencyGraphVertexKind`` is an enumeration and represents the kind of vertex in the dependency graph. 

366 """ 

367 Document = auto() #: A document (VHDL source file). 

368 Library = auto() #: A VHDL library. 

369 

370 Context = auto() #: A context design unit. 

371 Package = auto() #: A package design unit. 

372 PackageBody = auto() #: A package body design unit. 

373 Entity = auto() #: A entity design unit. 

374 Architecture = auto() #: A architecture design unit. 

375 Component = auto() #: A VHDL component. 

376 Configuration = auto() #: A configuration design unit. 

377 

378 

379@export 

380@unique 

381class DependencyGraphEdgeKind(Flag): 

382 """ 

383 A ``DependencyGraphEdgeKind`` is an enumeration and represents the kind of edge in the dependency graph. 

384 """ 

385 Document = auto() 

386 Library = auto() 

387 Context = auto() 

388 Package = auto() 

389 Entity = auto() 

390 # Architecture = auto() 

391 Configuration = auto() 

392 Component = auto() 

393 

394 DeclaredIn = auto() 

395 Order = auto() 

396 Reference = auto() 

397 Implementation = auto() 

398 Instantiation = auto() 

399 

400 SourceFile = Document | DeclaredIn 

401 CompileOrder = Document | Order 

402 

403 LibraryClause = Library | Reference 

404 UseClause = Package | Reference 

405 ContextReference = Context | Reference 

406 

407 EntityImplementation = Entity | Implementation 

408 PackageImplementation = Package | Implementation 

409 

410 EntityInstantiation = Entity | Instantiation 

411 ComponentInstantiation = Component | Instantiation 

412 ConfigurationInstantiation = Configuration | Instantiation 

413 

414 

415@export 

416@unique 

417class ObjectGraphVertexKind(Flag): 

418 """ 

419 A ``ObjectGraphVertexKind`` is an enumeration and represents the kind of vertex in the object graph. 

420 """ 

421 Type = auto() 

422 Subtype = auto() 

423 

424 Constant = auto() 

425 DeferredConstant = auto() 

426 Variable = auto() 

427 Signal = auto() 

428 File = auto() 

429 

430 Alias = auto() 

431 

432 

433@export 

434@unique 

435class ObjectGraphEdgeKind(Flag): 

436 """ 

437 A ``ObjectGraphEdgeKind`` is an enumeration and represents the kind of edge in the object graph. 

438 """ 

439 BaseType = auto() 

440 Subtype = auto() 

441 

442 ReferenceInExpression = auto() 

443 

444 

445@export 

446class Design(ModelEntity, AllowBlackboxMixin): 

447 """ 

448 A ``Design`` represents set of VHDL libraries as well as all loaded and analysed source files (see :class:`~pyVHDLModel.Document`). 

449 

450 It's the root of this code document-object-model (CodeDOM). It contains at least one VHDL library (see :class:`~pyVHDLModel.Library`). When the design is 

451 analysed (see :meth:`Analyze`), multiple graph data structures will be created and populated with vertices and edges. As a first result, the design's compile 

452 order and hierarchy can be iterated. As a second result, the design's *top-level* is identified and referenced from the design (see :attr:`TopLevel`). 

453 

454 The *design* contains references to the following graphs: 

455 

456 * :attr:`DependencyGraph` 

457 * :attr:`CompileOrderGraph` 

458 * :attr:`HierarchyGraph` 

459 * :attr:`ObjectGraph` 

460 """ 

461 _name: Nullable[str] #: Name of the design. 

462 _allowBlackbox: bool #: Allow blackboxes after linking the design. 

463 _libraries: Dict[str, 'Library'] #: List of all libraries defined for a design. 

464 _documents: List['Document'] #: List of all documents loaded for a design. 

465 _dependencyGraph: Graph[None, None, None, None, None, None, None, None, str, DesignUnit, None, None, None, None, None, None, None, None, None, None, None, None, None] #: The graph of all dependencies in the designs. 

466 _compileOrderGraph: Graph[None, None, None, None, None, None, None, None, None, 'Document', None, None, None, None, None, None, None, None, None, None, None, None, None] #: A graph derived from dependency graph containing the order of documents for compilation. 

467 _hierarchyGraph: Graph[None, None, None, None, None, None, None, None, str, DesignUnit, None, None, None, None, None, None, None, None, None, None, None, None, None] #: A graph derived from dependency graph containing the design hierarchy. 

468 _objectGraph: Graph[None, None, None, None, None, None, None, None, str, Obj, None, None, None, None, None, None, None, None, None, None, None, None, None] #: The graph of all types and objects in the design. 

469 _toplevel: Union[Entity, Configuration] #: When computed, the toplevel design unit is cached in this field. 

470 

471 def __init__( 

472 self, 

473 name: Nullable[str] = None, 

474 allowBlackbox: bool = False 

475 ) -> None: 

476 """ 

477 Initialize a VHDL design. 

478 

479 :param allowBlackbox: Specify if blackboxes are allowed in this design. 

480 :param name: Name of the design. 

481 """ 

482 super().__init__() 

483 AllowBlackboxMixin.__init__(self, allowBlackbox) 

484 

485 self._name = name 

486 

487 self._libraries = {} 

488 self._documents = [] 

489 

490 self._compileOrderGraph = Graph() 

491 self._dependencyGraph = Graph() 

492 self._hierarchyGraph = Graph() 

493 self._objectGraph = Graph() 

494 self._toplevel = None 

495 

496 @readonly 

497 def Name(self) -> Nullable[str]: 

498 """ 

499 Read-only property to access the design's name (:attr:`_name`). 

500 

501 :returns: The name of the design. 

502 """ 

503 return self._name 

504 

505 @readonly 

506 def Libraries(self) -> Dict[str, 'Library']: 

507 """ 

508 Read-only property to access the dictionary of library names and VHDL libraries (:attr:`_libraries`). 

509 

510 :returns: A dictionary of library names and VHDL libraries. 

511 """ 

512 return self._libraries 

513 

514 @readonly 

515 def Documents(self) -> List['Document']: 

516 """ 

517 Read-only property to access the list of all documents (VHDL source files) loaded for this design (:attr:`_documents`). 

518 

519 :returns: A list of all documents. 

520 """ 

521 return self._documents 

522 

523 @readonly 

524 def CompileOrderGraph(self) -> Graph: 

525 """ 

526 Read-only property to access the compile-order graph (:attr:`_compileOrderGraph`). 

527 

528 :returns: Reference to the compile-order graph. 

529 """ 

530 return self._compileOrderGraph 

531 

532 @readonly 

533 def DependencyGraph(self) -> Graph: 

534 """ 

535 Read-only property to access the dependency graph (:attr:`_dependencyGraph`). 

536 

537 :returns: Reference to the dependency graph. 

538 """ 

539 return self._dependencyGraph 

540 

541 @readonly 

542 def HierarchyGraph(self) -> Graph: 

543 """ 

544 Read-only property to access the hierarchy graph (:attr:`_hierarchyGraph`). 

545 

546 :returns: Reference to the hierarchy graph. 

547 """ 

548 return self._hierarchyGraph 

549 

550 @readonly 

551 def ObjectGraph(self) -> Graph: 

552 """ 

553 Read-only property to access the object graph (:attr:`_objectGraph`). 

554 

555 :returns: Reference to the object graph. 

556 """ 

557 return self._objectGraph 

558 

559 @readonly 

560 def TopLevel(self) -> Union[Entity, Configuration]: 

561 """ 

562 Read-only property to access the design's *top-level* (:attr:`_toplevel`). 

563 

564 When called the first time, the hierarchy graph is checked for its root elements. When there is only one root element in the graph, a new field ``toplevel`` 

565 is added to :attr:`_hierarchyGraph` referencing that single element. In addition, the result is cached in :attr:`_toplevel`. 

566 

567 :returns: Reference to the design's *top-level*. 

568 :raises VHDLModelException: If the hierarchy graph is not yet computed from dependency graph. 

569 :raises VHDLModelException: If there is more than one *top-level*. 

570 """ 

571 # Check for cached result 

572 if self._toplevel is not None: 

573 return self._toplevel 

574 

575 if self._hierarchyGraph.EdgeCount == 0: 

576 raise VHDLModelException(f"Hierarchy is not yet computed from dependency graph.") 

577 

578 roots = tuple(self._hierarchyGraph.IterateRoots()) 

579 if len(roots) == 1: 

580 toplevel = roots[0] 

581 self._hierarchyGraph["toplevel"] = toplevel 

582 self._toplevel = toplevel.Value 

583 

584 return toplevel.Value 

585 else: 

586 raise VHDLModelException(f"Found more than one toplevel: {', '.join(str(r) for r in roots)}") 

587 

588 def LoadStdLibrary(self) -> 'Library': 

589 """ 

590 Load the predefined VHDL library ``std`` into the design. 

591 

592 This will create a virtual source code file ``std.vhdl`` and register VHDL design units of library ``std`` to that file. 

593 

594 :returns: The library object of library ``std``. 

595 """ 

596 from pyVHDLModel.STD import Std 

597 

598 doc = Document(Path("std.vhdl"), parent=self) 

599 

600 library = Std() 

601 for designUnit in library.IterateDesignUnits(): 

602 doc._AddDesignUnit(designUnit) 

603 

604 self.AddLibrary(library) 

605 

606 return library 

607 

608 def LoadIEEELibrary(self, flavor: Nullable[IEEEFlavor] = None) -> 'Library': 

609 """ 

610 Load the predefined VHDL library ``ieee`` into the design. 

611 

612 This will create a virtual source code file ``ieee.vhdl`` and register VHDL design units of library ``ieee`` to that file. 

613 

614 :param flavor: Select the IEEE library flavor: IEEE, Synopsys, MentorGraphics. 

615 :returns: The library object of library ``ieee``. 

616 """ 

617 from pyVHDLModel.IEEE import Ieee 

618 

619 doc = Document(Path("ieee.vhdl"), parent=self) 

620 

621 library = Ieee(flavor) 

622 for designUnit in library.IterateDesignUnits(): 

623 doc._AddDesignUnit(designUnit) 

624 

625 self.AddLibrary(library) 

626 

627 return library 

628 

629 def AddLibrary(self, library: 'Library') -> None: 

630 """ 

631 Add a VHDL library to the design. 

632 

633 Ensure the libraries name doesn't collide with existing libraries in the design. |br| 

634 If ok, set the libraries parent reference to the design. 

635 

636 :param library: Library object to loaded. 

637 :raises LibraryExistsInDesignError: If the library already exists in the design. 

638 :raises LibraryRegisteredToForeignDesignError: If library is already used by a different design. 

639 """ 

640 libraryIdentifier = library.NormalizedIdentifier 

641 if libraryIdentifier in self._libraries: 

642 raise LibraryExistsInDesignError(library) 

643 

644 if library._parent is not None: 

645 raise LibraryRegisteredToForeignDesignError(library) 

646 

647 self._libraries[libraryIdentifier] = library 

648 library._parent = self 

649 

650 def GetLibrary(self, libraryName: str) -> 'Library': 

651 """ 

652 Return an (existing) VHDL library object of name ``libraryName``. 

653 

654 If the requested VHDL library doesn't exist, a new VHDL library with that name will be created. 

655 

656 :param libraryName: Name of the requested VHDL library. 

657 :returns: The VHDL library object. 

658 """ 

659 libraryIdentifier = libraryName.lower() 

660 try: 

661 return self._libraries[libraryIdentifier] 

662 except KeyError: 

663 lib = Library(libraryName, parent=self) 

664 self._libraries[libraryIdentifier] = lib 

665 lib._parent = self 

666 return lib 

667 

668 # TODO: allow overloaded parameter library to be str? 

669 def AddDocument(self, document: 'Document', library: 'Library') -> None: 

670 """ 

671 Add a document (VHDL source file) to the design and register all embedded design units to the given VHDL library. 

672 

673 .. rubric:: Algorithm 

674 

675 1. Iterate all entities in the document 

676 

677 1. Check if entity name might exist in target library. 

678 2. Add entity to library and update library membership. 

679 

680 2. Iterate all architectures in the document 

681 

682 1. Check if architecture name might exist in target library. 

683 2. Add architecture to library and update library membership. 

684 

685 3. Iterate all packages in the document 

686 

687 1. Check if package name might exist in target library. 

688 2. Add package to library and update library membership. 

689 

690 4. Iterate all package bodies in the document 

691 

692 1. Check if package body name might exist in target library. 

693 2. Add package body to library and update library membership. 

694 

695 5. Iterate all configurations in the document 

696 

697 1. Check if configuration name might exist in target library. 

698 2. Add configuration to library and update library membership. 

699 

700 6. Iterate all contexts in the document 

701 

702 1. Check if context name might exist in target library. 

703 2. Add context to library and update library membership. 

704 

705 :param document: The VHDL source code file. 

706 :param library: The VHDL library used to register the embedded design units to. 

707 :raises LibraryNotRegisteredError: If the given VHDL library is not a library in the design. 

708 :raises EntityExistsInLibraryError: If the processed entity's name is already existing in the VHDL library. 

709 :raises ArchitectureExistsInLibraryError: If the processed architecture's name is already existing in the VHDL library. 

710 :raises PackageExistsInLibraryError: If the processed package's name is already existing in the VHDL library. 

711 :raises PackageBodyExistsError: If the processed package body's name is already existing in the VHDL library. 

712 :raises ConfigurationExistsInLibraryError: If the processed configuration's name is already existing in the VHDL library. 

713 :raises ContextExistsInLibraryError: If the processed context's name is already existing in the VHDL library. 

714 """ 

715 # FIXME: this checks for the library name, but not the object 

716 # should the libraries parent be checked too? 

717 if library._normalizedIdentifier not in self._libraries: 717 ↛ 718line 717 didn't jump to line 718 because the condition on line 717 was never true

718 raise LibraryNotRegisteredError(library) 

719 

720 self._documents.append(document) 

721 document._parent = self 

722 

723 for entityIdentifier, entity in document._entities.items(): 

724 if entityIdentifier in library._entities: 724 ↛ 725line 724 didn't jump to line 725 because the condition on line 724 was never true

725 raise EntityExistsInLibraryError(entity, library) 

726 

727 library._entities[entityIdentifier] = entity 

728 entity.Library = library 

729 

730 for entityIdentifier, architectures in document._architectures.items(): 

731 try: 

732 architecturesPerEntity = library._architectures[entityIdentifier] 

733 for architectureIdentifier, architecture in architectures.items(): 

734 if architectureIdentifier in architecturesPerEntity: 

735 raise ArchitectureExistsInLibraryError(architecture, library._entities[entityIdentifier], library) 

736 

737 architecturesPerEntity[architectureIdentifier] = architecture 

738 architecture.Library = library 

739 except KeyError: 

740 architecturesPerEntity = document._architectures[entityIdentifier].copy() 

741 library._architectures[entityIdentifier] = architecturesPerEntity 

742 

743 for architecture in architecturesPerEntity.values(): 

744 architecture.Library = library 

745 

746 for packageIdentifier, package in document._packages.items(): 

747 if packageIdentifier in library._packages: 747 ↛ 748line 747 didn't jump to line 748 because the condition on line 747 was never true

748 raise PackageExistsInLibraryError(package, library) 

749 

750 library._packages[packageIdentifier] = package 

751 package.Library = library 

752 

753 for packageBodyIdentifier, packageBody in document._packageBodies.items(): 

754 if packageBodyIdentifier in library._packageBodies: 754 ↛ 755line 754 didn't jump to line 755 because the condition on line 754 was never true

755 raise PackageBodyExistsError(packageBody, library) 

756 

757 library._packageBodies[packageBodyIdentifier] = packageBody 

758 packageBody.Library = library 

759 

760 for configurationIdentifier, configuration in document._configurations.items(): 

761 if configurationIdentifier in library._configurations: 761 ↛ 762line 761 didn't jump to line 762 because the condition on line 761 was never true

762 raise ConfigurationExistsInLibraryError(configuration, library) 

763 

764 library._configurations[configurationIdentifier] = configuration 

765 configuration.Library = library 

766 

767 for contextIdentifier, context in document._contexts.items(): 

768 if contextIdentifier in library._contexts: 768 ↛ 769line 768 didn't jump to line 769 because the condition on line 768 was never true

769 raise ContextExistsInLibraryError(context, library) 

770 

771 library._contexts[contextIdentifier] = context 

772 context.Library = library 

773 

774 def IterateDesignUnits(self, filter: DesignUnitKind = DesignUnitKind.All) -> Generator[DesignUnit, None, None]: 

775 """ 

776 Iterate all design units in the design. 

777 

778 A union of :class:`DesignUnitKind` values can be given to filter the returned result for suitable design units. 

779 

780 .. rubric:: Algorithm 

781 

782 1. Iterate all VHDL libraries. 

783 

784 1. Iterate all contexts in that library. 

785 2. Iterate all packages in that library. 

786 3. Iterate all package bodies in that library. 

787 4. Iterate all entites in that library. 

788 5. Iterate all architectures in that library. 

789 6. Iterate all configurations in that library. 

790 

791 :param filter: An enumeration with possibly multiple flags to filter the returned design units. 

792 :returns: A generator to iterate all matched design units in the design. 

793 

794 .. seealso:: 

795 

796 :meth:`pyVHDLModel.Library.IterateDesignUnits` 

797 Iterate all design units in the library. 

798 :meth:`pyVHDLModel.Document.IterateDesignUnits` 

799 Iterate all design units in the document. 

800 """ 

801 for library in self._libraries.values(): 

802 yield from library.IterateDesignUnits(filter) 

803 

804 def Analyze(self) -> None: 

805 """ 

806 Analyze the whole design. 

807 

808 .. rubric:: Algorithm 

809 

810 1. Analyze dependencies of design units. |br| 

811 This will also yield the design hierarchy and the compiler order. 

812 2. Analyze dependencies of types and objects. 

813 

814 .. seealso:: 

815 

816 :meth:`AnalyzeDependencies` 

817 Analyze the dependencies of design units. 

818 

819 :meth:`AnalyzeObjects` 

820 Analyze the dependencies of types and objects. 

821 """ 

822 self.AnalyzeDependencies() 

823 self.AnalyzeObjects() 

824 

825 def AnalyzeDependencies(self) -> None: 

826 """ 

827 Analyze the dependencies of design units. 

828 

829 .. rubric:: Algorithm 

830 

831 1. Create all vertices of the dependency graph by iterating all design units in all libraries. |br| 

832 |rarr| :meth:`CreateDependencyGraph` 

833 2. Create the compile order graph. |br| 

834 |rarr| :meth:`CreateCompileOrderGraph` 

835 3. Index all packages. |br| 

836 |rarr| :meth:`IndexPackages` 

837 4. Index all architectures. |br| 

838 |rarr| :meth:`IndexArchitectures` 

839 5. Link all contexts |br| 

840 |rarr| :meth:`LinkContexts` 

841 6. Link all architectures. |br| 

842 |rarr| :meth:`LinkArchitectures` 

843 7. Link all package bodies. |br| 

844 |rarr| :meth:`LinkPackageBodies` 

845 8. Link all library references. |br| 

846 |rarr| :meth:`LinkLibraryReferences` 

847 9. Link all package references. |br| 

848 |rarr| :meth:`LinkPackageReferences` 

849 10. Link all context references. |br| 

850 |rarr| :meth:`LinkContextReferences` 

851 11. Link all components. |br| 

852 |rarr| :meth:`LinkComponents` 

853 12. Link all instantiations. |br| 

854 |rarr| :meth:`LinkInstantiations` 

855 13. Create the hierarchy graph. |br| 

856 |rarr| :meth:`CreateHierarchyGraph` 

857 14. Compute the compile order. |br| 

858 |rarr| :meth:`ComputeCompileOrder` 

859 """ 

860 self.CreateDependencyGraph() 

861 self.CreateCompileOrderGraph() 

862 

863 self.IndexPackages() 

864 self.IndexArchitectures() 

865 

866 self.LinkContexts() 

867 self.LinkArchitectures() 

868 self.LinkPackageBodies() 

869 self.LinkLibraryReferences() 

870 self.LinkPackageReferences() 

871 self.LinkContextReferences() 

872 

873 self.LinkComponents() 

874 self.LinkInstantiations() 

875 self.CreateHierarchyGraph() 

876 self.ComputeCompileOrder() 

877 

878 def AnalyzeObjects(self) -> None: 

879 """ 

880 Analyze the dependencies of types and objects. 

881 

882 .. rubric:: Algorithm 

883 

884 1. Index all entities. |br| 

885 |rarr| :meth:`IndexEntities` 

886 2. Index all package bodies. |br| 

887 |rarr| :meth:`IndexPackageBodies` 

888 3. Import objects. |br| 

889 |rarr| :meth:`ImportObjects` 

890 4. Create the type and object graph. |br| 

891 |rarr| :meth:`CreateTypeAndObjectGraph` 

892 """ 

893 self.IndexEntities() 

894 self.IndexPackageBodies() 

895 

896 self.ImportObjects() 

897 self.CreateTypeAndObjectGraph() 

898 

899 def CreateDependencyGraph(self) -> None: 

900 """ 

901 Create all vertices of the dependency graph by iterating all design units in all libraries. 

902 

903 This method will purely create a sea of vertices without any linking between vertices. The edges will be created later by other methods. |br| 

904 See :meth:`AnalyzeDependencies` for these methods and their algorithmic order. 

905 

906 Each vertex has the following properties: 

907 

908 * The vertex' ID is the design unit's identifier. 

909 * The vertex' value references the design unit. 

910 * A key-value-pair called ``kind`` denotes the vertex's kind as an enumeration value of type :class:`DependencyGraphVertexKind`. 

911 * A key-value-pair called ``predefined`` denotes if the referenced design unit is a predefined language entity. 

912 

913 .. rubric:: Algorithm 

914 

915 1. Iterate all libraries in the design. 

916 

917 * Create a vertex for that library and reference the library by the vertex' value field. |br| 

918 In return, set the library's :attr:`~pyVHDLModel.Library._dependencyVertex` field to reference the created vertex. 

919 

920 1. Iterate all contexts in that library. 

921 

922 * Create a vertex for that context and reference the context by the vertex' value field. |br| 

923 In return, set the context's :attr:`~pyVHDLModel.DesignUnit.Context._dependencyVertex` field to reference the created vertex. 

924 

925 2. Iterate all packages in that library. 

926 

927 * Create a vertex for that package and reference the package by the vertex' value field. |br| 

928 In return, set the package's :attr:`~pyVHDLModel.DesignUnit.Package._dependencyVertex` field to reference the created vertex. 

929 

930 3. Iterate all package bodies in that library. 

931 

932 * Create a vertex for that package body and reference the package body by the vertex' value field. |br| 

933 In return, set the package body's :attr:`~pyVHDLModel.DesignUnit.PackageBody._dependencyVertex` field to reference the created vertex. 

934 

935 4. Iterate all entities in that library. 

936 

937 * Create a vertex for that entity and reference the entity by the vertex' value field. |br| 

938 In return, set the entity's :attr:`~pyVHDLModel.DesignUnit.Entity._dependencyVertex` field to reference the created vertex. 

939 

940 5. Iterate all architectures in that library. 

941 

942 * Create a vertex for that architecture and reference the architecture by the vertex' value field. |br| 

943 In return, set the architecture's :attr:`~pyVHDLModel.DesignUnit.Architecture._dependencyVertex` field to reference the created vertex. 

944 

945 6. Iterate all configurations in that library. 

946 

947 * Create a vertex for that configuration and reference the configuration by the vertex' value field. |br| 

948 In return, set the configuration's :attr:`~pyVHDLModel.DesignUnit.Configuration._dependencyVertex` field to reference the created vertex. 

949 """ 

950 predefinedLibraries = ("std", "ieee") 

951 

952 for libraryIdentifier, library in self._libraries.items(): 

953 dependencyVertex = Vertex(vertexID=f"{libraryIdentifier}", value=library, graph=self._dependencyGraph) 

954 dependencyVertex["kind"] = DependencyGraphVertexKind.Library 

955 dependencyVertex["predefined"] = libraryIdentifier in predefinedLibraries 

956 library._dependencyVertex = dependencyVertex 

957 

958 for contextIdentifier, context in library._contexts.items(): 

959 dependencyVertex = Vertex(vertexID=f"{libraryIdentifier}.{contextIdentifier}", value=context, graph=self._dependencyGraph) 

960 dependencyVertex["kind"] = DependencyGraphVertexKind.Context 

961 dependencyVertex["predefined"] = context._parent._normalizedIdentifier in predefinedLibraries 

962 context._dependencyVertex = dependencyVertex 

963 

964 for packageIdentifier, package in library._packages.items(): 

965 dependencyVertex = Vertex(vertexID=f"{libraryIdentifier}.{packageIdentifier}", value=package, graph=self._dependencyGraph) 

966 dependencyVertex["kind"] = DependencyGraphVertexKind.Package 

967 dependencyVertex["predefined"] = package._parent._normalizedIdentifier in predefinedLibraries 

968 package._dependencyVertex = dependencyVertex 

969 

970 for packageBodyIdentifier, packageBody in library._packageBodies.items(): 

971 dependencyVertex = Vertex(vertexID=f"{libraryIdentifier}.{packageBodyIdentifier}(body)", value=packageBody, graph=self._dependencyGraph) 

972 dependencyVertex["kind"] = DependencyGraphVertexKind.PackageBody 

973 dependencyVertex["predefined"] = packageBody._parent._normalizedIdentifier in predefinedLibraries 

974 packageBody._dependencyVertex = dependencyVertex 

975 

976 for entityIdentifier, entity in library._entities.items(): 

977 dependencyVertex = Vertex(vertexID=f"{libraryIdentifier}.{entityIdentifier}", value=entity, graph=self._dependencyGraph) 

978 dependencyVertex["kind"] = DependencyGraphVertexKind.Entity 

979 dependencyVertex["predefined"] = entity._parent._normalizedIdentifier in predefinedLibraries 

980 entity._dependencyVertex = dependencyVertex 

981 

982 for entityIdentifier, architectures in library._architectures.items(): 

983 for architectureIdentifier, architecture in architectures.items(): 

984 dependencyVertex = Vertex(vertexID=f"{libraryIdentifier}.{entityIdentifier}({architectureIdentifier})", value=architecture, graph=self._dependencyGraph) 

985 dependencyVertex["kind"] = DependencyGraphVertexKind.Architecture 

986 dependencyVertex["predefined"] = architecture._parent._normalizedIdentifier in predefinedLibraries 

987 architecture._dependencyVertex = dependencyVertex 

988 

989 for configurationIdentifier, configuration in library._configurations.items(): 

990 dependencyVertex = Vertex(vertexID=f"{libraryIdentifier}.{configurationIdentifier}", value=configuration, graph=self._dependencyGraph) 

991 dependencyVertex["kind"] = DependencyGraphVertexKind.Configuration 

992 dependencyVertex["predefined"] = configuration._parent._normalizedIdentifier in predefinedLibraries 

993 configuration._dependencyVertex = dependencyVertex 

994 

995 def CreateCompileOrderGraph(self) -> None: 

996 """ 

997 Create a compile-order graph with bidirectional references to the dependency graph. 

998 

999 Add vertices representing a document (VHDL source file) to the dependency graph. Each "document" vertex in dependency graph is copied into the compile-order 

1000 graph and bidirectionally referenced. 

1001 

1002 In addition, each vertex of a corresponding design unit in a document is linked to the vertex representing that document to express the design unit in 

1003 document relationship. 

1004 

1005 Each added vertex has the following properties: 

1006 

1007 * The vertex' ID is the document's filename. 

1008 * The vertex' value references the document. 

1009 * A key-value-pair called ``kind`` denotes the vertex's kind as an enumeration value of type :class:`DependencyGraphVertexKind`. 

1010 * A key-value-pair called ``predefined`` does not exist. 

1011 

1012 .. rubric:: Algorithm 

1013 

1014 1. Iterate all documents in the design. 

1015 

1016 * Create a vertex for that document and reference the document by the vertex' value field. |br| 

1017 In return, set the documents's :attr:`~pyVHDLModel.Document._dependencyVertex` field to reference the created vertex. 

1018 * Copy the vertex from dependency graph to compile-order graph and link both vertices bidirectionally. |br| 

1019 In addition, set the documents's :attr:`~pyVHDLModel.Document._dependencyVertex` field to reference the copied vertex. 

1020 

1021 * Add a key-value-pair called ``compileOrderVertex`` to the dependency graph's vertex. 

1022 * Add a key-value-pair called ``dependencyVertex`` to the compiler-order graph's vertex. 

1023 

1024 1. Iterate the documents design units and create an edge from the design unit's corresponding dependency vertex to the documents corresponding 

1025 dependency vertex. This expresses a "design unit is located in document" relation. 

1026 

1027 * Add a key-value-pair called `kind`` denoting the edge's kind as an enumeration value of type :class:`DependencyGraphEdgeKind`. 

1028 """ 

1029 for document in self._documents: 

1030 dependencyVertex = Vertex(vertexID=document.Path.name, value=document, graph=self._dependencyGraph) 

1031 dependencyVertex["kind"] = DependencyGraphVertexKind.Document 

1032 document._dependencyVertex = dependencyVertex 

1033 

1034 compilerOrderVertex = dependencyVertex.Copy( 

1035 self._compileOrderGraph, 

1036 copyDict=True, 

1037 linkingKeyToOriginalVertex="dependencyVertex", 

1038 linkingKeyFromOriginalVertex="compileOrderVertex" 

1039 ) 

1040 document._compileOrderVertex = compilerOrderVertex 

1041 

1042 for designUnit in document._designUnits: 

1043 edge = dependencyVertex.EdgeFromVertex(designUnit._dependencyVertex) 

1044 edge["kind"] = DependencyGraphEdgeKind.SourceFile 

1045 

1046 def ImportObjects(self) -> None: 

1047 def _ImportObjects(package: Package) -> None: 

1048 from pyVHDLModel.Declaration import AttributeSpecification 

1049 

1050 for referencedLibrary in package._referencedPackages.values(): 

1051 for referencedPackage in referencedLibrary.values(): 

1052 for declaredItem in referencedPackage._declaredItems: 

1053 if isinstance(declaredItem, MultipleNamedEntityMixin): 1053 ↛ 1054line 1053 didn't jump to line 1054 because the condition on line 1053 was never true

1054 for normalizedIdentifier in declaredItem._normalizedIdentifiers: 

1055 package._namespace._elements[normalizedIdentifier] = declaredItem 

1056 elif isinstance(declaredItem, NamedEntityMixin): 1056 ↛ 1058line 1056 didn't jump to line 1058 because the condition on line 1056 was always true

1057 package._namespace._elements[declaredItem._normalizedIdentifier] = declaredItem 

1058 elif isinstance(declaredItem, AttributeSpecification): 

1059 # FIXME: actually, this is not a declared item, but a application of an attribute to named entities 

1060 WarningCollector.Raise(NotImplementedWarning(f"Attribute specification.")) 

1061 

1062 else: 

1063 raise VHDLModelException(f"Unexpected declared item.") 

1064 

1065 for libraryName in ("std", "ieee"): 

1066 for package in self.GetLibrary(libraryName).IterateDesignUnits(filter=DesignUnitKind.Package): # type: Package 

1067 _ImportObjects(package) 

1068 

1069 for document in self.IterateDocumentsInCompileOrder(): 

1070 for package in document.IterateDesignUnits(filter=DesignUnitKind.Package): # type: Package 

1071 _ImportObjects(package) 

1072 

1073 def CreateTypeAndObjectGraph(self) -> None: 

1074 def _HandlePackage(package) -> None: 

1075 packagePrefix = f"{package.Library.NormalizedIdentifier}.{package.NormalizedIdentifier}" 

1076 

1077 for deferredConstant in package._deferredConstants.values(): 1077 ↛ 1078line 1077 didn't jump to line 1078 because the loop on line 1077 never started

1078 print(f"Deferred Constant: {deferredConstant}") 

1079 deferredConstantVertex = Vertex( 

1080 vertexID=f"{packagePrefix}.{deferredConstant.NormalizedIdentifiers[0]}", 

1081 value=deferredConstant, 

1082 graph=self._objectGraph 

1083 ) 

1084 deferredConstantVertex["kind"] = ObjectGraphVertexKind.DeferredConstant 

1085 deferredConstant._objectVertex = deferredConstantVertex 

1086 

1087 for constant in package._constants.values(): 1087 ↛ 1088line 1087 didn't jump to line 1088 because the loop on line 1087 never started

1088 print(f"Constant: {constant}") 

1089 constantVertex = Vertex( 

1090 vertexID=f"{packagePrefix}.{constant.NormalizedIdentifiers[0]}", 

1091 value=constant, 

1092 graph=self._objectGraph 

1093 ) 

1094 constantVertex["kind"] = ObjectGraphVertexKind.Constant 

1095 constant._objectVertex = constantVertex 

1096 

1097 for type in package._types.values(): 

1098 print(f"Type: {type}") 

1099 typeVertex = Vertex( 

1100 vertexID=f"{packagePrefix}.{type.NormalizedIdentifier}", 

1101 value=type, 

1102 graph=self._objectGraph 

1103 ) 

1104 typeVertex["kind"] = ObjectGraphVertexKind.Type 

1105 type._objectVertex = typeVertex 

1106 

1107 for subtype in package._subtypes.values(): 

1108 print(f"Subtype: {subtype}") 

1109 subtypeVertex = Vertex( 

1110 vertexID=f"{packagePrefix}.{subtype.NormalizedIdentifier}", 

1111 value=subtype, 

1112 graph=self._objectGraph 

1113 ) 

1114 subtypeVertex["kind"] = ObjectGraphVertexKind.Subtype 

1115 subtype._objectVertex = subtypeVertex 

1116 

1117 for function in package._functions.values(): 1117 ↛ 1118line 1117 didn't jump to line 1118 because the loop on line 1117 never started

1118 print(f"Function: {function}") 

1119 functionVertex = Vertex( 

1120 vertexID=f"{packagePrefix}.{function.NormalizedIdentifier}", 

1121 value=function, 

1122 graph=self._objectGraph 

1123 ) 

1124 functionVertex["kind"] = ObjectGraphVertexKind.Function 

1125 function._objectVertex = functionVertex 

1126 

1127 for procedure in package._procedures.values(): 1127 ↛ 1128line 1127 didn't jump to line 1128 because the loop on line 1127 never started

1128 print(f"Procedure: {procedure}") 

1129 procedureVertex = Vertex( 

1130 vertexID=f"{packagePrefix}.{procedure.NormalizedIdentifier}", 

1131 value=procedure, 

1132 graph=self._objectGraph 

1133 ) 

1134 procedureVertex["kind"] = ObjectGraphVertexKind.Function 

1135 procedure._objectVertex = procedureVertex 

1136 

1137 for signal in package._signals.values(): 1137 ↛ 1138line 1137 didn't jump to line 1138 because the loop on line 1137 never started

1138 print(f"Signal: {signal}") 

1139 signalVertex = Vertex( 

1140 vertexID=f"{packagePrefix}.{signal.NormalizedIdentifiers[0]}", 

1141 value=signal, 

1142 graph=self._objectGraph 

1143 ) 

1144 signalVertex["kind"] = ObjectGraphVertexKind.Signal 

1145 signal._objectVertex = signalVertex 

1146 

1147 def _LinkSymbolsInExpression(expression, namespace: Namespace, typeVertex: Vertex): 

1148 if isinstance(expression, UnaryExpression): 1148 ↛ 1149line 1148 didn't jump to line 1149 because the condition on line 1148 was never true

1149 _LinkSymbolsInExpression(expression.Operand, namespace, typeVertex) 

1150 elif isinstance(expression, BinaryExpression): 1150 ↛ 1151line 1150 didn't jump to line 1151 because the condition on line 1150 was never true

1151 _LinkSymbolsInExpression(expression.LeftOperand, namespace, typeVertex) 

1152 _LinkSymbolsInExpression(expression.RightOperand, namespace, typeVertex) 

1153 elif isinstance(expression, TernaryExpression): 1153 ↛ 1154line 1153 didn't jump to line 1154 because the condition on line 1153 was never true

1154 WarningCollector.Raise(NotImplementedWarning(f"Handling of ternary expression.")) 

1155 elif isinstance(expression, SimpleObjectOrFunctionCallSymbol): 1155 ↛ 1156line 1155 didn't jump to line 1156 because the condition on line 1155 was never true

1156 obj = namespace.FindObject(expression) 

1157 expression._reference = obj 

1158 

1159 edge = obj._objectVertex.EdgeToVertex(typeVertex) 

1160 edge["kind"] = ObjectGraphEdgeKind.ReferenceInExpression 

1161 else: 

1162 WarningCollector.Raise(NotImplementedWarning(f"Unhandled else-branch")) 

1163 

1164 def _LinkItems(package: Package): 

1165 for item in package._declaredItems: 

1166 if isinstance(item, Constant): 1166 ↛ 1167line 1166 didn't jump to line 1167 because the condition on line 1166 was never true

1167 print(f"constant: {item}") 

1168 elif isinstance(item, DeferredConstant): 1168 ↛ 1169line 1168 didn't jump to line 1169 because the condition on line 1168 was never true

1169 print(f"deferred constant: {item}") 

1170 elif isinstance(item, Signal): 1170 ↛ 1171line 1170 didn't jump to line 1171 because the condition on line 1170 was never true

1171 print(f"signal: {item}") 

1172 elif isinstance(item, IntegerType): 

1173 typeNode = item._objectVertex 

1174 

1175 _LinkSymbolsInExpression(item.Range.LeftBound, package._namespace, typeNode) 

1176 _LinkSymbolsInExpression(item.Range.RightBound, package._namespace, typeNode) 

1177 # elif isinstance(item, FloatingType): 

1178 # print(f"signal: {item}") 

1179 elif isinstance(item, PhysicalType): 

1180 typeNode = item._objectVertex 

1181 

1182 _LinkSymbolsInExpression(item.Range.LeftBound, package._namespace, typeNode) 

1183 _LinkSymbolsInExpression(item.Range.RightBound, package._namespace, typeNode) 

1184 elif isinstance(item, ArrayType): 

1185 # Resolve dimensions 

1186 for dimension in item._dimensions: 

1187 subtype = package._namespace.FindSubtype(dimension) 

1188 dimension._reference = subtype 

1189 

1190 edge = item._objectVertex.EdgeToVertex(subtype._objectVertex) 

1191 edge["kind"] = ObjectGraphEdgeKind.Subtype 

1192 

1193 # Resolve element subtype 

1194 subtype = package._namespace.FindSubtype(item._elementType) 

1195 item._elementType._reference = subtype 

1196 

1197 edge = item._objectVertex.EdgeToVertex(subtype._objectVertex) 

1198 edge["kind"] = ObjectGraphEdgeKind.Subtype 

1199 elif isinstance(item, RecordType): 1199 ↛ 1201line 1199 didn't jump to line 1201 because the condition on line 1199 was never true

1200 # Resolve each elements subtype 

1201 for element in item._elements: 

1202 subtype = package._namespace.FindSubtype(element._subtype) 

1203 element._subtype._reference = subtype 

1204 

1205 edge = item._objectVertex.EdgeToVertex(subtype._objectVertex) 

1206 edge["kind"] = ObjectGraphEdgeKind.Subtype 

1207 else: 

1208 print(f"not handled: {item}") 

1209 

1210 for libraryName in ("std", "ieee"): 

1211 for package in self.GetLibrary(libraryName).IterateDesignUnits(filter=DesignUnitKind.Package): # type: Package 

1212 _HandlePackage(package) 

1213 _LinkItems(package) 

1214 

1215 for document in self.IterateDocumentsInCompileOrder(): 

1216 for package in document.IterateDesignUnits(filter=DesignUnitKind.Package): # type: Package 

1217 _HandlePackage(package) 

1218 _LinkItems(package) 

1219 

1220 def LinkContexts(self) -> None: 

1221 """ 

1222 Resolves and links all items (library clauses, use clauses and nested context references) in contexts. 

1223 

1224 It iterates all contexts in the design. Therefore, the library of the context is used as the working library. By 

1225 default, the working library is implicitly referenced in :data:`_referencedLibraries`. In addition, a new empty 

1226 dictionary is created in :data:`_referencedPackages` and :data:`_referencedContexts` for that working library. 

1227 

1228 At first, all library clauses are resolved (a library clause my have multiple library reference symbols). For each 

1229 referenced library an entry in :data:`_referencedLibraries` is generated and new empty dictionaries in 

1230 :data:`_referencedPackages` and :data:`_referencedContexts` for that working library. In addition, a vertex in the 

1231 dependency graph is added for that relationship. 

1232 

1233 At second, all use clauses are resolved (a use clause my have multiple package member reference symbols). For each 

1234 referenced package, 

1235 """ 

1236 for context in self.IterateDesignUnits(DesignUnitKind.Context): # type: Context 

1237 # Create entries in _referenced*** for the current working library under its real name. 

1238 workingLibrary: Library = context.Library 

1239 libraryNormalizedIdentifier = workingLibrary._normalizedIdentifier 

1240 

1241 context._referencedLibraries[libraryNormalizedIdentifier] = self._libraries[libraryNormalizedIdentifier] 

1242 context._referencedPackages[libraryNormalizedIdentifier] = {} 

1243 context._referencedContexts[libraryNormalizedIdentifier] = {} 

1244 

1245 # Process all library clauses 

1246 for libraryReference in context._libraryReferences: 

1247 # A library clause can have multiple comma-separated references 

1248 for libraryName in libraryReference.Symbols: 

1249 libraryNormalizedIdentifier = libraryName.Name._normalizedIdentifier 

1250 try: 

1251 library = self._libraries[libraryNormalizedIdentifier] 

1252 except KeyError: 

1253 raise ReferencedLibraryNotExistingError(context, libraryName) 

1254 # TODO: add position to these messages 

1255 

1256 libraryName.Library = library 

1257 

1258 context._referencedLibraries[libraryNormalizedIdentifier] = library 

1259 context._referencedPackages[libraryNormalizedIdentifier] = {} 

1260 context._referencedContexts[libraryNormalizedIdentifier] = {} 

1261 # TODO: warn duplicate library reference 

1262 

1263 dependency = context._dependencyVertex.EdgeToVertex(library._dependencyVertex, edgeValue=libraryReference) 

1264 dependency["kind"] = DependencyGraphEdgeKind.LibraryClause 

1265 

1266 # Process all use clauses 

1267 for packageReference in context.PackageReferences: 

1268 # A use clause can have multiple comma-separated references 

1269 for symbol in packageReference.Symbols: # type: PackageReferenceSymbol 

1270 packageName = symbol.Name.Prefix 

1271 libraryName = packageName.Prefix 

1272 

1273 libraryNormalizedIdentifier = libraryName._normalizedIdentifier 

1274 packageNormalizedIdentifier = packageName._normalizedIdentifier 

1275 

1276 # In case work is used, resolve to the real library name. 

1277 if libraryNormalizedIdentifier == "work": 1277 ↛ 1278line 1277 didn't jump to line 1278 because the condition on line 1277 was never true

1278 library: Library = context._parent 

1279 libraryNormalizedIdentifier = library._normalizedIdentifier 

1280 elif libraryNormalizedIdentifier not in context._referencedLibraries: 1280 ↛ 1282line 1280 didn't jump to line 1282 because the condition on line 1280 was never true

1281 # TODO: This check doesn't trigger if it's the working library. 

1282 raise VHDLModelException(f"Use clause references library '{libraryName._identifier}', which was not referenced by a library clause.") 

1283 else: 

1284 library = self._libraries[libraryNormalizedIdentifier] 

1285 

1286 try: 

1287 package = library._packages[packageNormalizedIdentifier] 

1288 except KeyError: 

1289 raise VHDLModelException(f"Package '{packageName._identifier}' not found in {'working ' if libraryName._normalizedIdentifier == 'work' else ''}library '{library._identifier}'.") 

1290 

1291 symbol.Package = package 

1292 

1293 # TODO: warn duplicate package reference 

1294 context._referencedPackages[libraryNormalizedIdentifier][packageNormalizedIdentifier] = package 

1295 

1296 dependency = context._dependencyVertex.EdgeToVertex(package._dependencyVertex, edgeValue=packageReference) 

1297 dependency["kind"] = DependencyGraphEdgeKind.UseClause 

1298 

1299 # TODO: update the namespace with visible members 

1300 if isinstance(symbol, AllPackageMembersReferenceSymbol): 1300 ↛ 1303line 1300 didn't jump to line 1303 because the condition on line 1300 was always true

1301 WarningCollector.Raise(NotImplementedWarning(f"Handling of 'myLib.myPackage.all'.")) 

1302 

1303 elif isinstance(symbol, PackageMemberReferenceSymbol): 

1304 WarningCollector.Raise(NotImplementedWarning(f"Handling of 'myLib.myPackage.mySymbol'.")) 

1305 

1306 else: 

1307 raise VHDLModelException() 

1308 

1309 def LinkArchitectures(self) -> None: 

1310 """ 

1311 Link all architectures to corresponding entities in all libraries. 

1312 

1313 .. rubric:: Algorithm 

1314 

1315 1. Iterate all libraries: 

1316 

1317 1. Iterate all architecture groups (grouped per entity symbol's name). 

1318 |rarr| :meth:`pyVHDLModel.Library.LinkArchitectures` 

1319 

1320 * Check if entity symbol's name exists as an entity in this library. 

1321 

1322 1. For each architecture in the same architecture group: 

1323 

1324 * Add architecture to entities architecture dictionary :attr:`pyVHDLModel.DesignUnit.Entity._architectures`. 

1325 * Assign found entity to architecture's entity symbol :attr:`pyVHDLModel.DesignUnit.Architecture._entity` 

1326 * Set parent namespace of architecture's namespace to the entitie's namespace. 

1327 * Add an edge in the dependency graph from the architecture's corresponding dependency vertex to the entity's corresponding dependency vertex. 

1328 

1329 .. seealso:: 

1330 

1331 :meth:`LinkPackageBodies` 

1332 Link all package bodies to corresponding packages in all libraries. 

1333 """ 

1334 for library in self._libraries.values(): 

1335 library.LinkArchitectures() 

1336 

1337 def LinkPackageBodies(self) -> None: 

1338 """ 

1339 Link all package bodies to corresponding packages in all libraries. 

1340 

1341 .. rubric:: Algorithm 

1342 

1343 1. Iterate all libraries: 

1344 

1345 1. Iterate all package bodies. 

1346 |rarr| :meth:`pyVHDLModel.Library.LinkPackageBodies` 

1347 

1348 * Check if package body symbol's name exists as a package in this library. 

1349 * Add package body to package :attr:`pyVHDLModel.DesignUnit.Package._packageBody`. 

1350 * Assign found package to package body's package symbol :attr:`pyVHDLModel.DesignUnit.PackageBody._package` 

1351 * Set parent namespace of package body's namespace to the package's namespace. 

1352 * Add an edge in the dependency graph from the package body's corresponding dependency vertex to the package's corresponding dependency vertex. 

1353 

1354 .. seealso:: 

1355 

1356 :meth:`LinkArchitectures` 

1357 Link all architectures to corresponding entities in all libraries. 

1358 """ 

1359 for library in self._libraries.values(): 

1360 library.LinkPackageBodies() 

1361 

1362 def LinkLibraryReferences(self) -> None: 

1363 DEFAULT_LIBRARIES = ("std",) 

1364 

1365 for designUnit in self.IterateDesignUnits(DesignUnitKind.WithContext): 

1366 # All primary units supporting a context, have at least one library implicitly referenced 

1367 if isinstance(designUnit, PrimaryUnit): 

1368 for libraryIdentifier in DEFAULT_LIBRARIES: 

1369 referencedLibrary = self._libraries[libraryIdentifier] 

1370 designUnit._referencedLibraries[libraryIdentifier] = referencedLibrary 

1371 designUnit._referencedPackages[libraryIdentifier] = {} 

1372 designUnit._referencedContexts[libraryIdentifier] = {} 

1373 # TODO: catch KeyError on self._libraries[libName] 

1374 # TODO: warn duplicate library reference 

1375 

1376 dependency = designUnit._dependencyVertex.EdgeToVertex(referencedLibrary._dependencyVertex) 

1377 dependency["kind"] = DependencyGraphEdgeKind.LibraryClause 

1378 

1379 workingLibrary: Library = designUnit.Library 

1380 libraryIdentifier = workingLibrary.NormalizedIdentifier 

1381 referencedLibrary = self._libraries[libraryIdentifier] 

1382 

1383 

1384 designUnit._referencedLibraries[libraryIdentifier] = referencedLibrary 

1385 designUnit._referencedPackages[libraryIdentifier] = {} 

1386 designUnit._referencedContexts[libraryIdentifier] = {} 

1387 

1388 dependency = designUnit._dependencyVertex.EdgeToVertex(referencedLibrary._dependencyVertex) 

1389 dependency["kind"] = DependencyGraphEdgeKind.LibraryClause 

1390 

1391 # All secondary units inherit referenced libraries from their primary units. 

1392 else: 

1393 if isinstance(designUnit, Architecture): 

1394 referencedLibraries = designUnit.Entity.Entity._referencedLibraries 

1395 elif isinstance(designUnit, PackageBody): 1395 ↛ 1398line 1395 didn't jump to line 1398 because the condition on line 1395 was always true

1396 referencedLibraries = designUnit.Package.Package._referencedLibraries 

1397 else: 

1398 raise VHDLModelException() 

1399 

1400 for libraryIdentifier, library in referencedLibraries.items(): 

1401 designUnit._referencedLibraries[libraryIdentifier] = library 

1402 

1403 for libraryReference in designUnit._libraryReferences: 

1404 # A library clause can have multiple comma-separated references 

1405 for librarySymbol in libraryReference.Symbols: 

1406 libraryIdentifier = librarySymbol.Name.NormalizedIdentifier 

1407 if libraryIdentifier == "work": 1407 ↛ 1408line 1407 didn't jump to line 1408 because the condition on line 1407 was never true

1408 continue 

1409 

1410 try: 

1411 library = self._libraries[libraryIdentifier] 

1412 except KeyError: 

1413 ex = VHDLModelException(f"Library '{librarySymbol.Name.Identifier}' referenced by library clause of design unit '{designUnit.Identifier}' doesn't exist in design.") 

1414 ex.add_note(f"""Known libraries: '{"', '".join(library for library in self._libraries)}'""") 

1415 raise ex 

1416 

1417 librarySymbol.Library = library 

1418 designUnit._referencedLibraries[libraryIdentifier] = library 

1419 designUnit._referencedPackages[libraryIdentifier] = {} 

1420 designUnit._referencedContexts[libraryIdentifier] = {} 

1421 # TODO: warn duplicate library reference 

1422 

1423 dependency = designUnit._dependencyVertex.EdgeToVertex(library._dependencyVertex, edgeValue=libraryReference) 

1424 dependency["kind"] = DependencyGraphEdgeKind.LibraryClause 

1425 

1426 def LinkPackageReferences(self) -> None: 

1427 DEFAULT_PACKAGES = ( 

1428 ("std", ("standard",)), 

1429 ) 

1430 

1431 for designUnit in self.IterateDesignUnits(DesignUnitKind.WithContext): 

1432 # All primary units supporting a context, have at least one package implicitly referenced 

1433 if isinstance(designUnit, PrimaryUnit): 

1434 if designUnit.Library.NormalizedIdentifier != "std" and \ 

1435 designUnit.NormalizedIdentifier != "standard": 

1436 for lib in DEFAULT_PACKAGES: 

1437 if lib[0] not in designUnit._referencedLibraries: 1437 ↛ 1438line 1437 didn't jump to line 1438 because the condition on line 1437 was never true

1438 raise VHDLModelException() 

1439 for pack in lib[1]: 

1440 referencedPackage = self._libraries[lib[0]]._packages[pack] 

1441 designUnit._referencedPackages[lib[0]][pack] = referencedPackage 

1442 # TODO: catch KeyError on self._libraries[lib[0]]._packages[pack] 

1443 # TODO: warn duplicate package reference 

1444 

1445 dependency = designUnit._dependencyVertex.EdgeToVertex(referencedPackage._dependencyVertex) 

1446 dependency["kind"] = DependencyGraphEdgeKind.UseClause 

1447 

1448 # All secondary units inherit referenced packages from their primary units. 

1449 else: 

1450 if isinstance(designUnit, Architecture): 

1451 referencedPackages = designUnit.Entity.Entity._referencedPackages 

1452 elif isinstance(designUnit, PackageBody): 1452 ↛ 1455line 1452 didn't jump to line 1455 because the condition on line 1452 was always true

1453 referencedPackages = designUnit.Package.Package._referencedPackages 

1454 else: 

1455 raise VHDLModelException() 

1456 

1457 for packageIdentifier, package in referencedPackages.items(): 

1458 designUnit._referencedPackages[packageIdentifier] = package 

1459 

1460 for packageReference in designUnit.PackageReferences: 

1461 # A use clause can have multiple comma-separated references 

1462 for packageMemberSymbol in packageReference.Symbols: 

1463 packageName = packageMemberSymbol.Name.Prefix 

1464 libraryName = packageName.Prefix 

1465 

1466 libraryIdentifier = libraryName.NormalizedIdentifier 

1467 packageIdentifier = packageName.NormalizedIdentifier 

1468 

1469 # In case work is used, resolve to the real library name. 

1470 if libraryIdentifier == "work": 

1471 library: Library = designUnit.Library 

1472 libraryIdentifier = library.NormalizedIdentifier 

1473 elif libraryIdentifier not in designUnit._referencedLibraries: 1473 ↛ 1475line 1473 didn't jump to line 1475 because the condition on line 1473 was never true

1474 # TODO: This check doesn't trigger if it's the working library. 

1475 raise VHDLModelException(f"Use clause references library '{libraryName.Identifier}', which was not referenced by a library clause.") 

1476 else: 

1477 library = self._libraries[libraryIdentifier] 

1478 

1479 try: 

1480 package = library._packages[packageIdentifier] 

1481 except KeyError: 

1482 ex = VHDLModelException(f"Package '{packageName.Identifier}' not found in {'working ' if libraryName.NormalizedIdentifier == 'work' else ''}library '{library.Identifier}'.") 

1483 ex.add_note(f"Caused in design unit '{designUnit}' in file '{designUnit.Document}'.") 

1484 raise ex 

1485 

1486 packageMemberSymbol.Package = package 

1487 

1488 # TODO: warn duplicate package reference 

1489 designUnit._referencedPackages[libraryIdentifier][packageIdentifier] = package 

1490 

1491 dependency = designUnit._dependencyVertex.EdgeToVertex(package._dependencyVertex, edgeValue=packageReference) 

1492 dependency["kind"] = DependencyGraphEdgeKind.UseClause 

1493 

1494 # TODO: update the namespace with visible members 

1495 if isinstance(packageMemberSymbol, AllPackageMembersReferenceSymbol): 1495 ↛ 1501line 1495 didn't jump to line 1501 because the condition on line 1495 was always true

1496 WarningCollector.Raise(NotImplementedWarning(f"Handling of 'myLib.myPackage.all'. Exception: components are handled.")) 

1497 

1498 for componentIdentifier, component in package._components.items(): 1498 ↛ 1499line 1498 didn't jump to line 1499 because the loop on line 1498 never started

1499 designUnit._namespace._elements[componentIdentifier] = component 

1500 

1501 elif isinstance(packageMemberSymbol, PackageMemberReferenceSymbol): 

1502 WarningCollector.Raise(NotImplementedWarning(f"Handling of 'myLib.myPackage.mySymbol'.")) 

1503 

1504 else: 

1505 raise VHDLModelException() 

1506 

1507 def LinkContextReferences(self) -> None: 

1508 for designUnit in self.IterateDesignUnits(): 

1509 for contextReference in designUnit._contextReferences: 

1510 # A context reference can have multiple comma-separated references 

1511 for contextSymbol in contextReference.Symbols: 

1512 libraryName = contextSymbol.Name.Prefix 

1513 

1514 libraryIdentifier = libraryName.NormalizedIdentifier 

1515 contextIdentifier = contextSymbol.Name.NormalizedIdentifier 

1516 

1517 # In case work is used, resolve to the real library name. 

1518 if libraryIdentifier == "work": 1518 ↛ 1521line 1518 didn't jump to line 1521 because the condition on line 1518 was always true

1519 referencedLibrary = designUnit.Library 

1520 libraryIdentifier = referencedLibrary.NormalizedIdentifier 

1521 elif libraryIdentifier not in designUnit._referencedLibraries: 

1522 # TODO: This check doesn't trigger if it's the working library. 

1523 raise VHDLModelException(f"Context reference references library '{libraryName.Identifier}', which was not referenced by a library clause.") 

1524 else: 

1525 referencedLibrary = self._libraries[libraryIdentifier] 

1526 

1527 try: 

1528 referencedContext = referencedLibrary._contexts[contextIdentifier] 

1529 except KeyError: 

1530 raise VHDLModelException(f"Context '{contextSymbol.Name.Identifier}' not found in {'working ' if libraryName.NormalizedIdentifier == 'work' else ''}library '{referencedLibrary.Identifier}'.") 

1531 

1532 contextSymbol.Package = referencedContext 

1533 

1534 # TODO: warn duplicate referencedContext reference 

1535 designUnit._referencedContexts[libraryIdentifier][contextIdentifier] = referencedContext 

1536 

1537 dependency = designUnit._dependencyVertex.EdgeToVertex(referencedContext._dependencyVertex, edgeValue=contextReference) 

1538 dependency["kind"] = DependencyGraphEdgeKind.ContextReference 

1539 

1540 for vertex in self._dependencyGraph.IterateTopologically(): 

1541 if vertex["kind"] is DependencyGraphVertexKind.Context: 

1542 context: Context = vertex.Value 

1543 for designUnitVertex in vertex.IteratePredecessorVertices(): 

1544 designUnit: DesignUnit = designUnitVertex.Value 

1545 for libraryIdentifier, library in context._referencedLibraries.items(): 

1546 # if libraryIdentifier in designUnit._referencedLibraries: 

1547 # raise VHDLModelException(f"Referenced library '{library.Identifier}' already exists in references for design unit '{designUnit.Identifier}'.") 

1548 

1549 designUnit._referencedLibraries[libraryIdentifier] = library 

1550 designUnit._referencedPackages[libraryIdentifier] = {} 

1551 

1552 for libraryIdentifier, packages in context._referencedPackages.items(): 

1553 for packageIdentifier, package in packages.items(): 

1554 if packageIdentifier in designUnit._referencedPackages: 1554 ↛ 1555line 1554 didn't jump to line 1555 because the condition on line 1554 was never true

1555 raise VHDLModelException(f"Referenced package '{package.Identifier}' already exists in references for design unit '{designUnit.Identifier}'.") 

1556 

1557 designUnit._referencedPackages[libraryIdentifier][packageIdentifier] = package 

1558 

1559 def LinkComponents(self) -> None: 

1560 """ 

1561 Link components to matching entities found in same VHDL library. 

1562 

1563 .. rubric:: Algorithm 

1564 

1565 1. Iterate all design units with component declarations (packages and architectures): 

1566 

1567 1. Iterate all component declarations in a package or architecture: 

1568 

1569 * Check if an entity with matching name can be found in the VHDL library the package is declared within. If 

1570 found, set the component's entity reference to that entity, otherwise check if blackboxes are allowed for 

1571 that component. If so, mark the component as a blackbox, otherwise, raise an exception. 

1572 

1573 2. Iterate concurrent statements with declaration regions (block statements, generate statements) if the design 

1574 unit is an architecture: 

1575 

1576 * If the statement is an :class:`IfGenerateStatement`: 

1577 

1578 1. Iterate declared components in the :class:`IfGenerateBranch`. 

1579 2. Iterate declared components in each :class:`ElIfGenerateBranch`. 

1580 3. Iterate declared components in the :class:`ElseGenerateBranch` if it exists. 

1581 

1582 * If the statement is an :class:`ForGenerateStatement`: 

1583 

1584 1. Iterate declared components. 

1585 

1586 * If the statement is an :class:`CaseGenerateStatement`: 

1587 

1588 1. Iterate declared components. 

1589 2. Iterate 

1590 

1591 .. seealso:: 

1592 

1593 :meth:`LinkInstantiations` 

1594 Link instantiations to components and entities. 

1595 :meth:`AnalyzeDependencies` 

1596 Analyze dependencies in a design (calls this method). 

1597 """ 

1598 def linkStatements(library: Library, concurrent: ConcurrentStatementsMixin) -> None: 

1599 for statement in concurrent._statements: 

1600 if isinstance(statement, IfGenerateStatement): 1600 ↛ 1601line 1600 didn't jump to line 1601 because the condition on line 1600 was never true

1601 linkComponents(library, statement._ifBranch) 

1602 linkStatements(library, statement._ifBranch) 

1603 for branch in statement._elsifBranches: 

1604 linkComponents(library, branch) 

1605 linkStatements(library, branch) 

1606 if (branch := statement._elseBranch) is not None: 

1607 linkComponents(library, branch) 

1608 linkStatements(library, branch) 

1609 elif isinstance(statement, ForGenerateStatement): 1609 ↛ 1610line 1609 didn't jump to line 1610 because the condition on line 1609 was never true

1610 linkComponents(library, statement) 

1611 linkStatements(library, statement) 

1612 elif isinstance(statement, CaseGenerateStatement): 1612 ↛ 1613line 1612 didn't jump to line 1613 because the condition on line 1612 was never true

1613 for case in statement._cases: 

1614 linkComponents(library, case) 

1615 linkStatements(library, case) 

1616 elif isinstance(statement, ConcurrentBlockStatement): 1616 ↛ 1617line 1616 didn't jump to line 1617 because the condition on line 1616 was never true

1617 linkComponents(library, statement) 

1618 linkStatements(library, statement) 

1619 

1620 def searchEntityAndLinkComponent(library: Library, component: Component) -> None: 

1621 # QUESTION: Add link in dependency graph as dashed line from component to entity? 

1622 # Currently, component has no _dependencyVertex field 

1623 try: 

1624 entity = library._entities[component.NormalizedIdentifier] 

1625 except KeyError: 

1626 if component.AllowBlackbox: 

1627 component._isBlackBox = True 

1628 return 

1629 else: 

1630 raise VHDLModelException( 

1631 f"Entity '{component.Identifier}' not found for component '{component.Identifier}' in library '{library.Identifier}'.") 

1632 

1633 component.Entity = entity 

1634 

1635 def linkComponents(library: Library, declarationRegion: ConcurrentDeclarationRegionMixin) -> None: 

1636 for item in declarationRegion._declaredItems: 

1637 if isinstance(item, Component): 

1638 searchEntityAndLinkComponent(library, item) 

1639 

1640 for designUnit in self.IterateDesignUnits(DesignUnitKind.Package | DesignUnitKind.Architecture): # type: Union[Package, Architecture] 

1641 library = designUnit._parent 

1642 for component in designUnit._components.values(): 1642 ↛ 1643line 1642 didn't jump to line 1643 because the loop on line 1642 never started

1643 searchEntityAndLinkComponent(library, component) 

1644 

1645 if isinstance(designUnit, Architecture): 

1646 linkStatements(library, designUnit) 

1647 

1648 def LinkInstantiations(self) -> None: 

1649 for architecture in self.IterateDesignUnits(DesignUnitKind.Architecture): # type: Architecture 

1650 for instance in architecture.IterateInstantiations(): 

1651 if isinstance(instance, EntityInstantiation): 1651 ↛ 1684line 1651 didn't jump to line 1684 because the condition on line 1651 was always true

1652 libraryName = instance.Entity.Name.Prefix 

1653 libraryIdentifier = libraryName.Identifier 

1654 normalizedLibraryIdentifier = libraryName.NormalizedIdentifier 

1655 if normalizedLibraryIdentifier == "work": 

1656 libraryIdentifier = architecture.Library.Identifier 

1657 normalizedLibraryIdentifier = architecture.Library.NormalizedIdentifier 

1658 elif normalizedLibraryIdentifier not in architecture._referencedLibraries: 1658 ↛ 1659line 1658 didn't jump to line 1659 because the condition on line 1658 was never true

1659 ex = VHDLModelException(f"Referenced library '{libraryIdentifier}' in direct entity instantiation '{instance.Label}: entity {instance.Entity.Prefix.Identifier}.{instance.Entity.Identifier}' not found in architecture '{architecture!r}'.") 

1660 ex.add_note(f"Add a library reference to the architecture or entity using a library clause like: 'library {libraryIdentifier};'.") 

1661 raise ex 

1662 

1663 try: 

1664 library = self._libraries[normalizedLibraryIdentifier] 

1665 except KeyError: 

1666 ex = VHDLModelException(f"Referenced library '{libraryIdentifier}' in direct entity instantiation '{instance.Label}: entity {instance.Entity.Prefix.Identifier}.{instance.Entity.Identifier}' not found in design.") 

1667 ex.add_note(f"No design units were parsed into library '{libraryIdentifier}'. Thus it doesn't exist in design.") 

1668 raise ex 

1669 

1670 try: 

1671 entity = library._entities[instance.Entity.Name.NormalizedIdentifier] 

1672 except KeyError: 

1673 ex = VHDLModelException(f"Referenced entity '{instance.Entity.Name.Identifier}' in direct entity instantiation '{instance.Label}: entity {instance.Entity.Name.Prefix.Identifier}.{instance.Entity.Name.Identifier}' not found in {'working ' if instance.Entity.Name.Prefix.NormalizedIdentifier == 'work' else ''}library '{libraryIdentifier}'.") 

1674 libs = [library.Identifier for library in self._libraries.values() for entityIdentifier in library._entities.keys() if entityIdentifier == instance.Entity.Name.NormalizedIdentifier] 

1675 if libs: 

1676 ex.add_note(f"Found entity '{instance.Entity!s}' in other libraries: {', '.join(libs)}") 

1677 raise ex 

1678 

1679 instance.Entity.Entity = entity 

1680 

1681 dependency = architecture._dependencyVertex.EdgeToVertex(entity._dependencyVertex, edgeValue=instance) 

1682 dependency["kind"] = DependencyGraphEdgeKind.EntityInstantiation 

1683 

1684 elif isinstance(instance, ComponentInstantiation): 

1685 component = architecture._namespace.FindComponent(instance.Component) 

1686 

1687 instance.Component.Component = component 

1688 

1689 if not component.IsBlackbox: 

1690 dependency = architecture._dependencyVertex.EdgeToVertex(component.Entity._dependencyVertex, edgeValue=instance) 

1691 dependency["kind"] = DependencyGraphEdgeKind.ComponentInstantiation 

1692 else: 

1693 WarningCollector.Raise(BlackboxWarning(f"Blackbox caused by '{instance.Label}: {instance.Component.Name}'.")) 

1694 

1695 elif isinstance(instance, ConfigurationInstantiation): 

1696 WarningCollector.Raise(NotImplementedWarning(f"Configuration instantiation of '{instance.Label}: {instance.Configuration}'.")) 

1697 

1698 def IndexPackages(self) -> None: 

1699 """ 

1700 Index all declared items in all packages in all libraries. 

1701 

1702 .. rubric:: Algorithm 

1703 

1704 1. Iterate all libraries: 

1705 

1706 1. Iterate all packages |br| 

1707 |rarr| :meth:`pyVHDLModel.Library.IndexPackages` 

1708 

1709 * Index all declared items in that package. |br| 

1710 |rarr| :meth:`pyVHDLModel.DesignUnit.Package.IndexDeclaredItems` 

1711 

1712 .. seealso:: 

1713 

1714 :meth:`IndexPackageBodies` 

1715 Index all declared items in all package bodies in all libraries. 

1716 :meth:`IndexEntities` 

1717 Index all declared items in all entities in all libraries. 

1718 :meth:`IndexArchitectures` 

1719 Index all declared items in all architectures in all libraries. 

1720 """ 

1721 for library in self._libraries.values(): 

1722 library.IndexPackages() 

1723 

1724 def IndexPackageBodies(self) -> None: 

1725 """ 

1726 Index all declared items in all packages in all libraries. 

1727 

1728 .. rubric:: Algorithm 

1729 

1730 1. Iterate all libraries: 

1731 

1732 1. Iterate all packages |br| 

1733 |rarr| :meth:`pyVHDLModel.Library.IndexPackageBodies` 

1734 

1735 * Index all declared items in that package body. |br| 

1736 |rarr| :meth:`pyVHDLModel.DesignUnit.PackageBody.IndexDeclaredItems` 

1737 

1738 .. seealso:: 

1739 

1740 :meth:`IndexPackages` 

1741 Index all declared items in all packages in all libraries. 

1742 :meth:`IndexEntities` 

1743 Index all declared items in all entities in all libraries. 

1744 :meth:`IndexArchitectures` 

1745 Index all declared items in all architectures in all libraries. 

1746 """ 

1747 for library in self._libraries.values(): 

1748 library.IndexPackageBodies() 

1749 

1750 def IndexEntities(self) -> None: 

1751 """ 

1752 Index all declared items in all packages in all libraries. 

1753 

1754 .. rubric:: Algorithm 

1755 

1756 1. Iterate all libraries: 

1757 

1758 1. Iterate all packages |br| 

1759 |rarr| :meth:`pyVHDLModel.Library.IndexEntities` 

1760 

1761 * Index all declared items in that entity. |br| 

1762 |rarr| :meth:`pyVHDLModel.DesignUnit.Entity.IndexDeclaredItems` 

1763 

1764 .. seealso:: 

1765 

1766 :meth:`IndexPackages` 

1767 Index all declared items in all packages in all libraries. 

1768 :meth:`IndexPackageBodies` 

1769 Index all declared items in all package bodies in all libraries. 

1770 :meth:`IndexArchitectures` 

1771 Index all declared items in all architectures in all libraries. 

1772 """ 

1773 for library in self._libraries.values(): 

1774 library.IndexEntities() 

1775 

1776 def IndexArchitectures(self) -> None: 

1777 """ 

1778 Index all declared items in all packages in all libraries. 

1779 

1780 .. rubric:: Algorithm 

1781 

1782 1. Iterate all libraries: 

1783 

1784 1. Iterate all packages |br| 

1785 |rarr| :meth:`pyVHDLModel.Library.IndexArchitectures` 

1786 

1787 * Index all declared items in that architecture. |br| 

1788 |rarr| :meth:`pyVHDLModel.DesignUnit.Architecture.IndexDeclaredItems` 

1789 

1790 .. seealso:: 

1791 

1792 :meth:`IndexPackages` 

1793 Index all declared items in all packages in all libraries. 

1794 :meth:`IndexPackageBodies` 

1795 Index all declared items in all package bodies in all libraries. 

1796 :meth:`IndexEntities` 

1797 Index all declared items in all entities in all libraries. 

1798 """ 

1799 for library in self._libraries.values(): 

1800 library.IndexArchitectures() 

1801 

1802 def CreateHierarchyGraph(self) -> None: 

1803 """ 

1804 Create the hierarchy graph from dependency graph. 

1805 

1806 .. rubric:: Algorithm 

1807 

1808 1. Iterate all vertices corresponding to entities and architectures in the dependency graph: 

1809 

1810 * Copy these vertices to the hierarchy graph and create a bidirectional linking. |br| 

1811 In addition, set the referenced design unit's :attr:`~pyVHDLModel.Document._hierarchyVertex` field to reference the copied vertex. 

1812 

1813 * Add a key-value-pair called ``hierarchyVertex`` to the dependency graph's vertex. 

1814 * Add a key-value-pair called ``dependencyVertex`` to the hierarchy graph's vertex. 

1815 

1816 2. Iterate all architectures ... 

1817 

1818 .. todo:: Design::CreateHierarchyGraph describe algorithm 

1819 

1820 1. Iterate all outbound edges 

1821 

1822 .. todo:: Design::CreateHierarchyGraph describe algorithm 

1823 """ 

1824 # Copy all entity and architecture vertices from dependency graph to hierarchy graph and double-link them 

1825 entityArchitectureFilter = lambda v: v["kind"] in DependencyGraphVertexKind.Entity | DependencyGraphVertexKind.Architecture 

1826 for vertex in self._dependencyGraph.IterateVertices(predicate=entityArchitectureFilter): 

1827 hierarchyVertex = vertex.Copy(self._hierarchyGraph, copyDict=True, linkingKeyToOriginalVertex="dependencyVertex", linkingKeyFromOriginalVertex="hierarchyVertex") 

1828 vertex.Value._hierarchyVertex = hierarchyVertex 

1829 

1830 # Copy implementation edges from 

1831 for hierarchyArchitectureVertex in self._hierarchyGraph.IterateVertices(predicate=lambda v: v["kind"] is DependencyGraphVertexKind.Architecture): 

1832 for dependencyEdge in hierarchyArchitectureVertex["dependencyVertex"].IterateOutboundEdges(): 

1833 kind: DependencyGraphEdgeKind = dependencyEdge["kind"] 

1834 if DependencyGraphEdgeKind.Implementation in kind: 

1835 hierarchyDestinationVertex = dependencyEdge.Destination["hierarchyVertex"] 

1836 newEdge = hierarchyArchitectureVertex.EdgeFromVertex(hierarchyDestinationVertex) 

1837 elif DependencyGraphEdgeKind.Instantiation in kind: 

1838 hierarchyDestinationVertex = dependencyEdge.Destination["hierarchyVertex"] 

1839 

1840 # FIXME: avoid parallel edges, to graph can be converted to a tree until "real" hierarchy is computed (unrole generics and blocks) 

1841 if hierarchyArchitectureVertex.HasEdgeToDestination(hierarchyDestinationVertex): 

1842 continue 

1843 

1844 newEdge = hierarchyArchitectureVertex.EdgeToVertex(hierarchyDestinationVertex) 

1845 else: 

1846 continue 

1847 

1848 newEdge["kind"] = kind 

1849 

1850 def ComputeCompileOrder(self) -> None: 

1851 def predicate(edge: Edge) -> bool: 

1852 return ( 

1853 DependencyGraphEdgeKind.Implementation in edge["kind"] or 

1854 DependencyGraphEdgeKind.Instantiation in edge["kind"] or 

1855 DependencyGraphEdgeKind.UseClause in edge["kind"] or 

1856 DependencyGraphEdgeKind.ContextReference in edge["kind"] 

1857 ) and edge.Destination["predefined"] is False 

1858 

1859 for edge in self._dependencyGraph.IterateEdges(predicate=predicate): 

1860 sourceDocument: Document = edge.Source.Value.Document 

1861 destinationDocument: Document = edge.Destination.Value.Document 

1862 

1863 sourceVertex = sourceDocument._compileOrderVertex 

1864 destinationVertex = destinationDocument._compileOrderVertex 

1865 

1866 # Don't add self-edges 

1867 if sourceVertex is destinationVertex: 1867 ↛ 1870line 1867 didn't jump to line 1870 because the condition on line 1867 was always true

1868 continue 

1869 # Don't add parallel edges 

1870 elif sourceVertex.HasEdgeToDestination(destinationVertex): 

1871 continue 

1872 

1873 e = sourceVertex.EdgeToVertex(destinationVertex) 

1874 e["kind"] = DependencyGraphEdgeKind.CompileOrder 

1875 

1876 e = sourceVertex["dependencyVertex"].EdgeToVertex(destinationVertex["dependencyVertex"]) 

1877 e["kind"] = DependencyGraphEdgeKind.CompileOrder 

1878 

1879 def IterateDocumentsInCompileOrder(self) -> Generator['Document', None, None]: 

1880 """ 

1881 Iterate all document in compile-order. 

1882 

1883 .. rubric:: Algorithm 

1884 

1885 * Check if compile-order graph was populated with vertices and its vertices are linked by edges. 

1886 

1887 1. Iterate compile-order graph in topological order. |br| 

1888 :meth:`pyTooling.Graph.Graph.IterateTopologically` 

1889 

1890 * yield the compiler-order vertex' referenced document. 

1891 

1892 :returns: A generator to iterate all documents in compile-order in the design. 

1893 :raises VHDLModelException: If compile-order was not computed. 

1894 

1895 .. seealso:: 

1896 

1897 .. todo:: missing text 

1898 

1899 :meth:`pyVHDLModel.Design.ComputeCompileOrder` 

1900 

1901 """ 

1902 if self._compileOrderGraph.EdgeCount < self._compileOrderGraph.VertexCount - 1: 1902 ↛ 1903line 1902 didn't jump to line 1903 because the condition on line 1902 was never true

1903 raise VHDLModelException(f"Compile order is not yet computed from dependency graph.") 

1904 

1905 for compileOrderNode in self._compileOrderGraph.IterateTopologically(): 

1906 yield compileOrderNode.Value 

1907 

1908 def GetUnusedDesignUnits(self) -> List[DesignUnit]: 

1909 WarningCollector.Raise(NotImplementedWarning(f"Compute unused design units.")) 

1910 

1911 def __repr__(self) -> str: 

1912 """ 

1913 Formats a representation of the design. 

1914 

1915 **Format:** ``Document: 'my_design'`` 

1916 

1917 :returns: String representation of the design. 

1918 """ 

1919 return f"Design: {self._name}" 

1920 

1921 __str__ = __repr__ 

1922 

1923 

1924@export 

1925class Library(ModelEntity, NamedEntityMixin, AllowBlackboxMixin): 

1926 """A ``Library`` represents a VHDL library. It contains all *primary* and *secondary* design units.""" 

1927 

1928 _allowBlackbox: Nullable[bool] #: Allow blackboxes for components in this library. 

1929 _contexts: Dict[str, Context] #: Dictionary of all contexts defined in a library. 

1930 _configurations: Dict[str, Configuration] #: Dictionary of all configurations defined in a library. 

1931 _entities: Dict[str, Entity] #: Dictionary of all entities defined in a library. 

1932 _architectures: Dict[str, Dict[str, Architecture]] #: Dictionary of all architectures defined in a library. 

1933 _packages: Dict[str, Package] #: Dictionary of all packages defined in a library. 

1934 _packageBodies: Dict[str, PackageBody] #: Dictionary of all package bodies defined in a library. 

1935 

1936 _dependencyVertex: Vertex[None, None, str, Union['Library', DesignUnit], None, None, None, None, None, None, None, None, None, None, None, None, None] #: Reference to the vertex in the dependency graph representing the library. |br| This reference is set by :meth:`~pyVHDLModel.Design.CreateDependencyGraph`. 

1937 

1938 def __init__( 

1939 self, 

1940 identifier: str, 

1941 allowBlackbox: Nullable[bool] = None, 

1942 parent: ModelEntity = None 

1943 ) -> None: 

1944 """ 

1945 Initialize a VHDL library. 

1946 

1947 :param identifier: Name of the VHDL library. 

1948 :param allowBlackbox: Specify if blackboxes are allowed in this design. 

1949 :param parent: The parent model entity (design) of this VHDL library. 

1950 """ 

1951 super().__init__(parent) 

1952 NamedEntityMixin.__init__(self, identifier) 

1953 AllowBlackboxMixin.__init__(self, allowBlackbox) 

1954 

1955 self._contexts = {} 

1956 self._configurations = {} 

1957 self._entities = {} 

1958 self._architectures = {} 

1959 self._packages = {} 

1960 self._packageBodies = {} 

1961 

1962 self._dependencyVertex = None 

1963 

1964 @readonly 

1965 def Contexts(self) -> Dict[str, Context]: 

1966 """Returns a list of all context declarations declared in this library.""" 

1967 return self._contexts 

1968 

1969 @readonly 

1970 def Configurations(self) -> Dict[str, Configuration]: 

1971 """Returns a list of all configuration declarations declared in this library.""" 

1972 return self._configurations 

1973 

1974 @readonly 

1975 def Entities(self) -> Dict[str, Entity]: 

1976 """Returns a list of all entity declarations declared in this library.""" 

1977 return self._entities 

1978 

1979 @readonly 

1980 def Architectures(self) -> Dict[str, Dict[str, Architecture]]: 

1981 """Returns a list of all architectures declarations declared in this library.""" 

1982 return self._architectures 

1983 

1984 @readonly 

1985 def Packages(self) -> Dict[str, Package]: 

1986 """Returns a list of all package declarations declared in this library.""" 

1987 return self._packages 

1988 

1989 @readonly 

1990 def PackageBodies(self) -> Dict[str, PackageBody]: 

1991 """Returns a list of all package body declarations declared in this library.""" 

1992 return self._packageBodies 

1993 

1994 @readonly 

1995 def DependencyVertex(self) -> Vertex: 

1996 """ 

1997 Read-only property to access the corresponding dependency vertex (:attr:`_dependencyVertex`). 

1998 

1999 The dependency vertex references this library by its value field. 

2000 

2001 :returns: The corresponding dependency vertex. 

2002 """ 

2003 return self._dependencyVertex 

2004 

2005 def IterateDesignUnits(self, filter: DesignUnitKind = DesignUnitKind.All) -> Generator[DesignUnit, None, None]: 

2006 """ 

2007 Iterate all design units in the library. 

2008 

2009 A union of :class:`DesignUnitKind` values can be given to filter the returned result for suitable design units. 

2010 

2011 .. rubric:: Algorithm 

2012 

2013 1. Iterate all contexts in that library. 

2014 2. Iterate all packages in that library. 

2015 3. Iterate all package bodies in that library. 

2016 4. Iterate all entities in that library. 

2017 5. Iterate all architectures in that library. 

2018 6. Iterate all configurations in that library. 

2019 

2020 :param filter: An enumeration with possibly multiple flags to filter the returned design units. 

2021 :returns: A generator to iterate all matched design units in the library. 

2022 

2023 .. seealso:: 

2024 

2025 :meth:`pyVHDLModel.Design.IterateDesignUnits` 

2026 Iterate all design units in the design. 

2027 :meth:`pyVHDLModel.Document.IterateDesignUnits` 

2028 Iterate all design units in the document. 

2029 """ 

2030 if DesignUnitKind.Context in filter: 

2031 for context in self._contexts.values(): 

2032 yield context 

2033 

2034 if DesignUnitKind.Package in filter: 

2035 for package in self._packages.values(): 

2036 yield package 

2037 

2038 if DesignUnitKind.PackageBody in filter: 

2039 for packageBody in self._packageBodies.values(): 

2040 yield packageBody 

2041 

2042 if DesignUnitKind.Entity in filter: 

2043 for entity in self._entities.values(): 

2044 yield entity 

2045 

2046 if DesignUnitKind.Architecture in filter: 

2047 for architectures in self._architectures.values(): 

2048 for architecture in architectures.values(): 

2049 yield architecture 

2050 

2051 if DesignUnitKind.Configuration in filter: 

2052 for configuration in self._configurations.values(): 

2053 yield configuration 

2054 

2055 # for verificationProperty in self._verificationUnits.values(): 

2056 # yield verificationProperty 

2057 # for verificationUnit in self._verificationProperties.values(): 

2058 # yield entity 

2059 # for verificationMode in self._verificationModes.values(): 

2060 # yield verificationMode 

2061 

2062 def LinkArchitectures(self) -> None: 

2063 """ 

2064 Link all architectures to corresponding entities. 

2065 

2066 .. rubric:: Algorithm 

2067 

2068 1. Iterate all architecture groups (grouped per entity symbol's name). 

2069 

2070 * Check if entity symbol's name exists as an entity in this library. 

2071 

2072 1. For each architecture in the same architecture group: 

2073 

2074 * Add architecture to entities architecture dictionary :attr:`pyVHDLModel.DesignUnit.Entity._architectures`. 

2075 * Assign found entity to architecture's entity symbol :attr:`pyVHDLModel.DesignUnit.Architecture._entity` 

2076 * Set parent namespace of architecture's namespace to the entitie's namespace. 

2077 * Add an edge in the dependency graph from the architecture's corresponding dependency vertex to the entity's corresponding dependency vertex. 

2078 

2079 :raises VHDLModelException: If entity name doesn't exist. 

2080 :raises VHDLModelException: If architecture name already exists for entity. 

2081 

2082 .. seealso:: 

2083 

2084 :meth:`LinkPackageBodies` 

2085 Link all package bodies to corresponding packages. 

2086 """ 

2087 for entityName, architecturesPerEntity in self._architectures.items(): 

2088 if entityName not in self._entities: 2088 ↛ 2089line 2088 didn't jump to line 2089 because the condition on line 2088 was never true

2089 architectureNames = "', '".join(architecturesPerEntity.keys()) 

2090 raise VHDLModelException(f"Entity '{entityName}' referenced by architecture(s) '{architectureNames}' doesn't exist in library '{self._identifier}'.") 

2091 # TODO: search in other libraries to find that entity. 

2092 # TODO: add code position 

2093 

2094 entity = self._entities[entityName] 

2095 for architecture in architecturesPerEntity.values(): 

2096 if architecture._normalizedIdentifier in entity._architectures: 2096 ↛ 2097line 2096 didn't jump to line 2097 because the condition on line 2096 was never true

2097 raise VHDLModelException(f"Architecture '{architecture._identifier}' already exists for entity '{entity._identifier}'.") 

2098 # TODO: add code position of existing and current 

2099 

2100 entity._architectures[architecture._normalizedIdentifier] = architecture 

2101 architecture._entity.Entity = entity 

2102 architecture._namespace._parentNamespace = entity._namespace 

2103 

2104 # add "architecture -> entity" relation in dependency graph 

2105 dependency = architecture._dependencyVertex.EdgeToVertex(entity._dependencyVertex) 

2106 dependency["kind"] = DependencyGraphEdgeKind.EntityImplementation 

2107 

2108 def LinkPackageBodies(self) -> None: 

2109 """ 

2110 Link all package bodies to corresponding packages. 

2111 

2112 .. rubric:: Algorithm 

2113 

2114 1. Iterate all package bodies. 

2115 

2116 * Check if package body symbol's name exists as a package in this library. 

2117 * Add package body to package :attr:`pyVHDLModel.DesignUnit.Package._packageBody`. 

2118 * Assign found package to package body's package symbol :attr:`pyVHDLModel.DesignUnit.PackageBody._package` 

2119 * Set parent namespace of package body's namespace to the package's namespace. 

2120 * Add an edge in the dependency graph from the package body's corresponding dependency vertex to the package's corresponding dependency vertex. 

2121 

2122 :raises VHDLModelException: If package name doesn't exist. 

2123 

2124 .. seealso:: 

2125 

2126 :meth:`LinkArchitectures` 

2127 Link all architectures to corresponding entities. 

2128 """ 

2129 for packageBodyName, packageBody in self._packageBodies.items(): 

2130 if packageBodyName not in self._packages: 2130 ↛ 2131line 2130 didn't jump to line 2131 because the condition on line 2130 was never true

2131 raise VHDLModelException(f"Package '{packageBodyName}' referenced by package body '{packageBodyName}' doesn't exist in library '{self._identifier}'.") 

2132 

2133 package = self._packages[packageBodyName] 

2134 package._packageBody = packageBody # TODO: add warning if package had already a body, which is now replaced 

2135 packageBody._package.Package = package 

2136 packageBody._namespace._parentNamespace = package._namespace 

2137 

2138 # add "package body -> package" relation in dependency graph 

2139 dependency = packageBody._dependencyVertex.EdgeToVertex(package._dependencyVertex) 

2140 dependency["kind"] = DependencyGraphEdgeKind.PackageImplementation 

2141 

2142 def IndexPackages(self) -> None: 

2143 """ 

2144 Index declared items in all packages. 

2145 

2146 .. rubric:: Algorithm 

2147 

2148 1. Iterate all packages: 

2149 

2150 * Index all declared items. |br| 

2151 |rarr| :meth:`pyVHDLModel.DesignUnit.Package.IndexDeclaredItems` 

2152 

2153 .. seealso:: 

2154 

2155 :meth:`IndexPackageBodies` 

2156 Index all declared items in a package body. 

2157 :meth:`IndexEntities` 

2158 Index all declared items in an entity. 

2159 :meth:`IndexArchitectures` 

2160 Index all declared items in an architecture. 

2161 """ 

2162 for package in self._packages.values(): 

2163 if isinstance(package, Package): 2163 ↛ 2162line 2163 didn't jump to line 2162 because the condition on line 2163 was always true

2164 package.IndexDeclaredItems() 

2165 

2166 def IndexPackageBodies(self) -> None: 

2167 """ 

2168 Index declared items in all package bodies. 

2169 

2170 .. rubric:: Algorithm 

2171 

2172 1. Iterate all package bodies: 

2173 

2174 * Index all declared items. |br| 

2175 |rarr| :meth:`pyVHDLModel.DesignUnit.PackageBody.IndexDeclaredItems` 

2176 

2177 .. seealso:: 

2178 

2179 :meth:`IndexPackages` 

2180 Index all declared items in a package. 

2181 :meth:`IndexEntities` 

2182 Index all declared items in an entity. 

2183 :meth:`IndexArchitectures` 

2184 Index all declared items in an architecture. 

2185 """ 

2186 for packageBody in self._packageBodies.values(): 

2187 packageBody.IndexDeclaredItems() 

2188 

2189 def IndexEntities(self) -> None: 

2190 """ 

2191 Index declared items in all entities. 

2192 

2193 .. rubric:: Algorithm 

2194 

2195 1. Iterate all entities: 

2196 

2197 * Index all declared items. |br| 

2198 |rarr| :meth:`pyVHDLModel.DesignUnit.Entity.IndexDeclaredItems` 

2199 

2200 .. seealso:: 

2201 

2202 :meth:`IndexPackages` 

2203 Index all declared items in a package. 

2204 :meth:`IndexPackageBodies` 

2205 Index all declared items in a package body. 

2206 :meth:`IndexArchitectures` 

2207 Index all declared items in an architecture. 

2208 """ 

2209 for entity in self._entities.values(): 

2210 entity.IndexDeclaredItems() 

2211 

2212 def IndexArchitectures(self) -> None: 

2213 """ 

2214 Index declared items in all architectures. 

2215 

2216 .. rubric:: Algorithm 

2217 

2218 1. Iterate all architectures: 

2219 

2220 * Index all declared items. |br| 

2221 |rarr| :meth:`pyVHDLModel.DesignUnit.Architecture.IndexDeclaredItems` 

2222 

2223 .. seealso:: 

2224 

2225 :meth:`IndexPackages` 

2226 Index all declared items in a package. 

2227 :meth:`IndexPackageBodies` 

2228 Index all declared items in a package body. 

2229 :meth:`IndexEntities` 

2230 Index all declared items in an entity. 

2231 """ 

2232 for architectures in self._architectures.values(): 

2233 for architecture in architectures.values(): 

2234 architecture.IndexDeclaredItems() 

2235 architecture.IndexStatements() 

2236 

2237 def __repr__(self) -> str: 

2238 """ 

2239 Formats a representation of the library. 

2240 

2241 **Format:** ``Library: 'my_library'`` 

2242 

2243 :returns: String representation of the library. 

2244 """ 

2245 return f"Library: '{self._identifier}'" 

2246 

2247 __str__ = __repr__ 

2248 

2249 

2250@export 

2251class Document(ModelEntity, DocumentedEntityMixin): 

2252 """A ``Document`` represents a sourcefile. It contains *primary* and *secondary* design units.""" 

2253 

2254 _path: Path #: path to the document. ``None`` if virtual document. 

2255 _designUnits: List[DesignUnit] #: List of all design units defined in a document. 

2256 _contexts: Dict[str, Context] #: Dictionary of all contexts defined in a document. 

2257 _configurations: Dict[str, Configuration] #: Dictionary of all configurations defined in a document. 

2258 _entities: Dict[str, Entity] #: Dictionary of all entities defined in a document. 

2259 _architectures: Dict[str, Dict[str, Architecture]] #: Dictionary of all architectures defined in a document. 

2260 _packages: Dict[str, Package] #: Dictionary of all packages defined in a document. 

2261 _packageBodies: Dict[str, PackageBody] #: Dictionary of all package bodies defined in a document. 

2262 _verificationUnits: Dict[str, VerificationUnit] #: Dictionary of all PSL verification units defined in a document. 

2263 _verificationProperties: Dict[str, VerificationProperty] #: Dictionary of all PSL verification properties defined in a document. 

2264 _verificationModes: Dict[str, VerificationMode] #: Dictionary of all PSL verification modes defined in a document. 

2265 

2266 _dependencyVertex: Vertex[None, None, None, 'Document', None, None, None, None, None, None, None, None, None, None, None, None, None] #: Reference to the vertex in the dependency graph representing the document. |br| This reference is set by :meth:`~pyVHDLModel.Design.CreateCompileOrderGraph`. 

2267 _compileOrderVertex: Vertex[None, None, None, 'Document', None, None, None, None, None, None, None, None, None, None, None, None, None] #: Reference to the vertex in the compile-order graph representing the document. |br| This reference is set by :meth:`~pyVHDLModel.Design.CreateCompileOrderGraph`. 

2268 

2269 def __init__(self, path: Path, documentation: Nullable[str] = None, parent: ModelEntity = None) -> None: 

2270 super().__init__(parent) 

2271 DocumentedEntityMixin.__init__(self, documentation) 

2272 

2273 self._path = path 

2274 self._designUnits = [] 

2275 self._contexts = {} 

2276 self._configurations = {} 

2277 self._entities = {} 

2278 self._architectures = {} 

2279 self._packages = {} 

2280 self._packageBodies = {} 

2281 self._verificationUnits = {} 

2282 self._verificationProperties = {} 

2283 self._verificationModes = {} 

2284 

2285 self._dependencyVertex = None 

2286 self._compileOrderVertex = None 

2287 

2288 def _AddEntity(self, item: Entity) -> None: 

2289 """ 

2290 Add an entity to the document's lists of design units. 

2291 

2292 :param item: Entity object to be added to the document. 

2293 :raises TypeError: If parameter 'item' is not of type :class:`~pyVHDLModel.DesignUnits.Entity`. 

2294 :raises VHDLModelException: If entity name already exists in document. 

2295 """ 

2296 if not isinstance(item, Entity): 2296 ↛ 2297line 2296 didn't jump to line 2297 because the condition on line 2296 was never true

2297 ex = TypeError(f"Parameter 'item' is not of type 'Entity'.") 

2298 if version_info >= (3, 11): # pragma: no cover 

2299 ex.add_note(f"Got type '{getFullyQualifiedName(item)}'.") 

2300 raise ex 

2301 

2302 identifier = item._normalizedIdentifier 

2303 if identifier in self._entities: 2303 ↛ 2305line 2303 didn't jump to line 2305 because the condition on line 2303 was never true

2304 # TODO: use a more specific exception 

2305 raise VHDLModelException(f"An entity '{item._identifier}' already exists in this document.") 

2306 

2307 self._entities[identifier] = item 

2308 self._designUnits.append(item) 

2309 item._document = self 

2310 

2311 def _AddArchitecture(self, item: Architecture) -> None: 

2312 """ 

2313 Add an architecture to the document's lists of design units. 

2314 

2315 :param item: Architecture object to be added to the document. 

2316 :raises TypeError: If parameter 'item' is not of type :class:`~pyVHDLModel.DesignUnits.Architecture`. 

2317 :raises VHDLModelException: If architecture name already exists for the referenced entity name in document. 

2318 """ 

2319 if not isinstance(item, Architecture): 2319 ↛ 2320line 2319 didn't jump to line 2320 because the condition on line 2319 was never true

2320 ex = TypeError(f"Parameter 'item' is not of type 'Architecture'.") 

2321 if version_info >= (3, 11): # pragma: no cover 

2322 ex.add_note(f"Got type '{getFullyQualifiedName(item)}'.") 

2323 raise ex 

2324 

2325 entity = item._entity.Name 

2326 entityIdentifier = entity._normalizedIdentifier 

2327 try: 

2328 architectures = self._architectures[entityIdentifier] 

2329 if item._normalizedIdentifier in architectures: 

2330 # TODO: use a more specific exception 

2331 # FIXME: this is allowed and should be a warning or a strict mode. 

2332 raise VHDLModelException(f"An architecture '{item._identifier}' for entity '{entity._identifier}' already exists in this document.") 

2333 

2334 architectures[item.Identifier] = item 

2335 except KeyError: 

2336 self._architectures[entityIdentifier] = {item._identifier: item} 

2337 

2338 self._designUnits.append(item) 

2339 item._document = self 

2340 

2341 def _AddPackage(self, item: Package) -> None: 

2342 """ 

2343 Add a package to the document's lists of design units. 

2344 

2345 :param item: Package object to be added to the document. 

2346 :raises TypeError: If parameter 'item' is not of type :class:`~pyVHDLModel.DesignUnits.Package`. 

2347 :raises VHDLModelException: If package name already exists in document. 

2348 """ 

2349 if not isinstance(item, (Package, PackageInstantiation)): 2349 ↛ 2350line 2349 didn't jump to line 2350 because the condition on line 2349 was never true

2350 ex = TypeError(f"Parameter 'item' is not of type 'Package' or 'PackageInstantiation'.") 

2351 if version_info >= (3, 11): # pragma: no cover 

2352 ex.add_note(f"Got type '{getFullyQualifiedName(item)}'.") 

2353 raise ex 

2354 

2355 identifier = item._normalizedIdentifier 

2356 if identifier in self._packages: 2356 ↛ 2358line 2356 didn't jump to line 2358 because the condition on line 2356 was never true

2357 # TODO: use a more specific exception 

2358 raise VHDLModelException(f"A package '{item._identifier}' already exists in this document.") 

2359 

2360 self._packages[identifier] = item 

2361 self._designUnits.append(item) 

2362 item._document = self 

2363 

2364 def _AddPackageBody(self, item: PackageBody) -> None: 

2365 """ 

2366 Add a package body to the document's lists of design units. 

2367 

2368 :param item: Package body object to be added to the document. 

2369 :raises TypeError: If parameter 'item' is not of type :class:`~pyVHDLModel.DesignUnits.PackageBody`. 

2370 :raises VHDLModelException: If package body name already exists in document. 

2371 """ 

2372 if not isinstance(item, PackageBody): 2372 ↛ 2373line 2372 didn't jump to line 2373 because the condition on line 2372 was never true

2373 ex = TypeError(f"Parameter 'item' is not of type 'PackageBody'.") 

2374 if version_info >= (3, 11): # pragma: no cover 

2375 ex.add_note(f"Got type '{getFullyQualifiedName(item)}'.") 

2376 raise ex 

2377 

2378 identifier = item._normalizedIdentifier 

2379 if identifier in self._packageBodies: 2379 ↛ 2381line 2379 didn't jump to line 2381 because the condition on line 2379 was never true

2380 # TODO: use a more specific exception 

2381 raise VHDLModelException(f"A package body '{item._identifier}' already exists in this document.") 

2382 

2383 self._packageBodies[identifier] = item 

2384 self._designUnits.append(item) 

2385 item._document = self 

2386 

2387 def _AddContext(self, item: Context) -> None: 

2388 """ 

2389 Add a context to the document's lists of design units. 

2390 

2391 :param item: Context object to be added to the document. 

2392 :raises TypeError: If parameter 'item' is not of type :class:`~pyVHDLModel.DesignUnits.Context`. 

2393 :raises VHDLModelException: If context name already exists in document. 

2394 """ 

2395 if not isinstance(item, Context): 2395 ↛ 2396line 2395 didn't jump to line 2396 because the condition on line 2395 was never true

2396 ex = TypeError(f"Parameter 'item' is not of type 'Context'.") 

2397 if version_info >= (3, 11): # pragma: no cover 

2398 ex.add_note(f"Got type '{getFullyQualifiedName(item)}'.") 

2399 raise ex 

2400 

2401 identifier = item._normalizedIdentifier 

2402 if identifier in self._contexts: 2402 ↛ 2404line 2402 didn't jump to line 2404 because the condition on line 2402 was never true

2403 # TODO: use a more specific exception 

2404 raise VHDLModelException(f"A context '{item._identifier}' already exists in this document.") 

2405 

2406 self._contexts[identifier] = item 

2407 self._designUnits.append(item) 

2408 item._document = self 

2409 

2410 def _AddConfiguration(self, item: Configuration) -> None: 

2411 """ 

2412 Add a configuration to the document's lists of design units. 

2413 

2414 :param item: Configuration object to be added to the document. 

2415 :raises TypeError: If parameter 'item' is not of type :class:`~pyVHDLModel.DesignUnits.Configuration`. 

2416 :raises VHDLModelException: If configuration name already exists in document. 

2417 """ 

2418 if not isinstance(item, Configuration): 2418 ↛ 2419line 2418 didn't jump to line 2419 because the condition on line 2418 was never true

2419 ex = TypeError(f"Parameter 'item' is not of type 'Configuration'.") 

2420 if version_info >= (3, 11): # pragma: no cover 

2421 ex.add_note(f"Got type '{getFullyQualifiedName(item)}'.") 

2422 raise ex 

2423 

2424 identifier = item._normalizedIdentifier 

2425 if identifier in self._configurations: 2425 ↛ 2427line 2425 didn't jump to line 2427 because the condition on line 2425 was never true

2426 # TODO: use a more specific exception 

2427 raise VHDLModelException(f"A configuration '{item._identifier}' already exists in this document.") 

2428 

2429 self._configurations[identifier] = item 

2430 self._designUnits.append(item) 

2431 item._document = self 

2432 

2433 def _AddVerificationUnit(self, item: VerificationUnit) -> None: 

2434 if not isinstance(item, VerificationUnit): 

2435 ex = TypeError(f"Parameter 'item' is not of type 'VerificationUnit'.") 

2436 if version_info >= (3, 11): # pragma: no cover 

2437 ex.add_note(f"Got type '{getFullyQualifiedName(item)}'.") 

2438 raise ex 

2439 

2440 identifier = item._normalizedIdentifier 

2441 if identifier in self._verificationUnits: 

2442 raise ValueError(f"A verification unit '{item._identifier}' already exists in this document.") 

2443 

2444 self._verificationUnits[identifier] = item 

2445 self._designUnits.append(item) 

2446 item._document = self 

2447 

2448 def _AddVerificationProperty(self, item: VerificationProperty) -> None: 

2449 if not isinstance(item, VerificationProperty): 

2450 ex = TypeError(f"Parameter 'item' is not of type 'VerificationProperty'.") 

2451 if version_info >= (3, 11): # pragma: no cover 

2452 ex.add_note(f"Got type '{getFullyQualifiedName(item)}'.") 

2453 raise ex 

2454 

2455 identifier = item.NormalizedIdentifier 

2456 if identifier in self._verificationProperties: 

2457 raise ValueError(f"A verification property '{item.Identifier}' already exists in this document.") 

2458 

2459 self._verificationProperties[identifier] = item 

2460 self._designUnits.append(item) 

2461 item._document = self 

2462 

2463 def _AddVerificationMode(self, item: VerificationMode) -> None: 

2464 if not isinstance(item, VerificationMode): 

2465 ex = TypeError(f"Parameter 'item' is not of type 'VerificationMode'.") 

2466 if version_info >= (3, 11): # pragma: no cover 

2467 ex.add_note(f"Got type '{getFullyQualifiedName(item)}'.") 

2468 raise ex 

2469 

2470 identifier = item.NormalizedIdentifier 

2471 if identifier in self._verificationModes: 

2472 raise ValueError(f"A verification mode '{item.Identifier}' already exists in this document.") 

2473 

2474 self._verificationModes[identifier] = item 

2475 self._designUnits.append(item) 

2476 item._document = self 

2477 

2478 def _AddDesignUnit(self, item: DesignUnit) -> None: 

2479 """ 

2480 Add a design unit to the document's lists of design units. 

2481 

2482 :param item: Configuration object to be added to the document. 

2483 :raises TypeError: If parameter 'item' is not of type :class:`~pyVHDLModel.DesignUnits.DesignUnit`. 

2484 :raises ValueError: If parameter 'item' is an unknown :class:`~pyVHDLModel.DesignUnits.DesignUnit`. 

2485 :raises VHDLModelException: If configuration name already exists in document. 

2486 """ 

2487 if not isinstance(item, DesignUnit): 2487 ↛ 2488line 2487 didn't jump to line 2488 because the condition on line 2487 was never true

2488 ex = TypeError(f"Parameter 'item' is not of type 'DesignUnit'.") 

2489 if version_info >= (3, 11): # pragma: no cover 

2490 ex.add_note(f"Got type '{getFullyQualifiedName(item)}'.") 

2491 raise ex 

2492 

2493 if isinstance(item, Entity): 

2494 self._AddEntity(item) 

2495 elif isinstance(item, Architecture): 

2496 self._AddArchitecture(item) 

2497 elif isinstance(item, Package): 

2498 self._AddPackage(item) 

2499 elif isinstance(item, PackageBody): 

2500 self._AddPackageBody(item) 

2501 elif isinstance(item, Context): 

2502 self._AddContext(item) 

2503 elif isinstance(item, Configuration): 2503 ↛ 2505line 2503 didn't jump to line 2505 because the condition on line 2503 was always true

2504 self._AddConfiguration(item) 

2505 elif isinstance(item, VerificationUnit): 

2506 self._AddVerificationUnit(item) 

2507 elif isinstance(item, VerificationProperty): 

2508 self._AddVerificationProperty(item) 

2509 elif isinstance(item, VerificationMode): 

2510 self._AddVerificationMode(item) 

2511 else: 

2512 ex = ValueError(f"Parameter 'item' is an unknown 'DesignUnit'.") 

2513 if version_info >= (3, 11): # pragma: no cover 

2514 ex.add_note(f"Got type '{getFullyQualifiedName(item)}'.") 

2515 raise ex 

2516 

2517 @readonly 

2518 def Path(self) -> Path: 

2519 """ 

2520 Read-only property to access the document's path (:attr:`_path`). 

2521 

2522 :returns: The path of this document. 

2523 """ 

2524 return self._path 

2525 

2526 @readonly 

2527 def DesignUnits(self) -> List[DesignUnit]: 

2528 """ 

2529 Read-only property to access a list of all design units declarations found in this document (:attr:`_designUnits`). 

2530 

2531 :returns: List of all design units. 

2532 """ 

2533 return self._designUnits 

2534 

2535 @readonly 

2536 def Contexts(self) -> Dict[str, Context]: 

2537 """ 

2538 Read-only property to access a list of all context declarations found in this document (:attr:`_contexts`). 

2539 

2540 :returns: List of all contexts. 

2541 """ 

2542 return self._contexts 

2543 

2544 @readonly 

2545 def Configurations(self) -> Dict[str, Configuration]: 

2546 """ 

2547 Read-only property to access a list of all configuration declarations found in this document (:attr:`_configurations`). 

2548 

2549 :returns: List of all configurations. 

2550 """ 

2551 return self._configurations 

2552 

2553 @readonly 

2554 def Entities(self) -> Dict[str, Entity]: 

2555 """ 

2556 Read-only property to access a list of all entity declarations found in this document (:attr:`_entities`). 

2557 

2558 :returns: List of all entities. 

2559 """ 

2560 return self._entities 

2561 

2562 @readonly 

2563 def Architectures(self) -> Dict[str, Dict[str, Architecture]]: 

2564 """ 

2565 Read-only property to access a list of all architecture declarations found in this document (:attr:`_architectures`). 

2566 

2567 :returns: List of all architectures. 

2568 """ 

2569 return self._architectures 

2570 

2571 @readonly 

2572 def Packages(self) -> Dict[str, Package]: 

2573 """ 

2574 Read-only property to access a list of all package declarations found in this document (:attr:`_packages`). 

2575 

2576 :returns: List of all packages. 

2577 """ 

2578 return self._packages 

2579 

2580 @readonly 

2581 def PackageBodies(self) -> Dict[str, PackageBody]: 

2582 """ 

2583 Read-only property to access a list of all package body declarations found in this document (:attr:`_packageBodies`). 

2584 

2585 :returns: List of all package bodies. 

2586 """ 

2587 return self._packageBodies 

2588 

2589 @readonly 

2590 def VerificationUnits(self) -> Dict[str, VerificationUnit]: 

2591 """ 

2592 Read-only property to access a list of all verification unit declarations found in this document (:attr:`_verificationUnits`). 

2593 

2594 :returns: List of all verification units. 

2595 """ 

2596 return self._verificationUnits 

2597 

2598 @readonly 

2599 def VerificationProperties(self) -> Dict[str, VerificationProperty]: 

2600 """ 

2601 Read-only property to access a list of all verification properties declarations found in this document (:attr:`_verificationProperties`). 

2602 

2603 :returns: List of all verification properties. 

2604 """ 

2605 return self._verificationProperties 

2606 

2607 @readonly 

2608 def VerificationModes(self) -> Dict[str, VerificationMode]: 

2609 """ 

2610 Read-only property to access a list of all verification modes declarations found in this document (:attr:`_verificationModes`). 

2611 

2612 :returns: List of all verification modes. 

2613 """ 

2614 return self._verificationModes 

2615 

2616 @readonly 

2617 def CompileOrderVertex(self) -> Vertex[None, None, None, 'Document', None, None, None, None, None, None, None, None, None, None, None, None, None]: 

2618 """ 

2619 Read-only property to access the corresponding compile-order vertex (:attr:`_compileOrderVertex`). 

2620 

2621 The compile-order vertex references this document by its value field. 

2622 

2623 :returns: The corresponding compile-order vertex. 

2624 """ 

2625 return self._compileOrderVertex 

2626 

2627 def IterateDesignUnits(self, filter: DesignUnitKind = DesignUnitKind.All) -> Generator[DesignUnit, None, None]: 

2628 """ 

2629 Iterate all design units in the document. 

2630 

2631 A union of :class:`DesignUnitKind` values can be given to filter the returned result for suitable design units. 

2632 

2633 .. rubric:: Algorithm 

2634 

2635 * If contexts are selected in the filter: 

2636 

2637 1. Iterate all contexts in that library. 

2638 

2639 * If packages are selected in the filter: 

2640 

2641 1. Iterate all packages in that library. 

2642 

2643 * If package bodies are selected in the filter: 

2644 

2645 1. Iterate all package bodies in that library. 

2646 

2647 * If entites are selected in the filter: 

2648 

2649 1. Iterate all entites in that library. 

2650 

2651 * If architectures are selected in the filter: 

2652 

2653 1. Iterate all architectures in that library. 

2654 

2655 * If configurations are selected in the filter: 

2656 

2657 1. Iterate all configurations in that library. 

2658 

2659 :param filter: An enumeration with possibly multiple flags to filter the returned design units. 

2660 :returns: A generator to iterate all matched design units in the document. 

2661 

2662 .. seealso:: 

2663 

2664 :meth:`pyVHDLModel.Design.IterateDesignUnits` 

2665 Iterate all design units in the design. 

2666 :meth:`pyVHDLModel.Library.IterateDesignUnits` 

2667 Iterate all design units in the library. 

2668 """ 

2669 if DesignUnitKind.Context in filter: 

2670 for context in self._contexts.values(): 

2671 yield context 

2672 

2673 if DesignUnitKind.Package in filter: 2673 ↛ 2677line 2673 didn't jump to line 2677 because the condition on line 2673 was always true

2674 for package in self._packages.values(): 

2675 yield package 

2676 

2677 if DesignUnitKind.PackageBody in filter: 

2678 for packageBody in self._packageBodies.values(): 

2679 yield packageBody 

2680 

2681 if DesignUnitKind.Entity in filter: 

2682 for entity in self._entities.values(): 

2683 yield entity 

2684 

2685 if DesignUnitKind.Architecture in filter: 

2686 for architectures in self._architectures.values(): 

2687 for architecture in architectures.values(): 

2688 yield architecture 

2689 

2690 if DesignUnitKind.Configuration in filter: 

2691 for configuration in self._configurations.values(): 

2692 yield configuration 

2693 

2694 # for verificationProperty in self._verificationUnits.values(): 

2695 # yield verificationProperty 

2696 # for verificationUnit in self._verificationProperties.values(): 

2697 # yield entity 

2698 # for verificationMode in self._verificationModes.values(): 

2699 # yield verificationMode 

2700 

2701 def __repr__(self) -> str: 

2702 """ 

2703 Formats a representation of the document. 

2704 

2705 **Format:** ``Document: 'path/to/file.vhdl'`` 

2706 

2707 :returns: String representation of the document. 

2708 """ 

2709 return f"Document: '{self._path}'" 

2710 

2711 __str__ = __repr__