Coverage for pyVHDLModel / __init__.py: 76%

1118 statements  

« prev     ^ index     » next       coverage.py v7.12.0, created at 2025-11-21 22:17 +0000

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

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

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

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

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

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

7# |_| |___/ # 

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

9# Authors: # 

10# Patrick Lehmann # 

11# # 

12# License: # 

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

14# Copyright 2017-2025 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-2025 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-2025, Patrick Lehmann" 

50__license__ = "Apache License, Version 2.0" 

51__version__ = "0.33.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.Concurrent import EntityInstantiation, ComponentInstantiation, ConfigurationInstantiation 

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

76from pyVHDLModel.PSLModel import VerificationUnit, VerificationProperty, VerificationMode 

77from pyVHDLModel.Instantiation import PackageInstantiation 

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

79 

80 

81@export 

82@unique 

83class VHDLVersion(Enum): 

84 """ 

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

86 

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

88 enumeration value. 

89 

90 This enumeration supports compare operators. 

91 """ 

92 

93 Any = -1 #: Any 

94 VHDL87 = 87 #: VHDL-1987 

95 VHDL93 = 93 #: VHDL-1993 

96 AMS93 = 1993 #: VHDL-AMS-1993 

97 AMS99 = 1999 #: VHDL-AMS-1999 

98 VHDL2000 = 2000 #: VHDL-2000 

99 VHDL2002 = 2002 #: VHDL-2002 

100 VHDL2008 = 2008 #: VHDL-2008 

101 AMS2017 = 2017 #: VHDL-AMS-2017 

102 VHDL2019 = 2019 #: VHDL-2019 

103 Latest = 10000 #: Latest VHDL (2019) 

104 

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

106 -1: Any, 

107 87: VHDL87, 

108 93: VHDL93, 

109 # 93: AMS93, 

110 99: AMS99, 

111 0: VHDL2000, 

112 2: VHDL2002, 

113 8: VHDL2008, 

114 17: AMS2017, 

115 19: VHDL2019, 

116 1987: VHDL87, 

117 # 1993: VHDL93, 

118 1993: AMS93, 

119 1999: AMS99, 

120 2000: VHDL2000, 

121 2002: VHDL2002, 

122 2008: VHDL2008, 

123 2017: AMS2017, 

124 2019: VHDL2019, 

125 10000: Latest, 

126 "Any": Any, 

127 "87": VHDL87, 

128 "93": VHDL93, 

129 # "93": AMS93, 

130 "99": AMS99, 

131 "00": VHDL2000, 

132 "02": VHDL2002, 

133 "08": VHDL2008, 

134 "17": AMS2017, 

135 "19": VHDL2019, 

136 "1987": VHDL87, 

137 # "1993": VHDL93, 

138 "1993": AMS93, 

139 "1999": AMS99, 

140 "2000": VHDL2000, 

141 "2002": VHDL2002, 

142 "2008": VHDL2008, 

143 "2017": AMS2017, 

144 "2019": VHDL2019, 

145 "Latest": Latest, 

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

147 

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

149 """Patch the embedded MAP dictionary""" 

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

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

152 self.__class__.__VERSION_MAPPINGS__[k] = self 

153 

154 @classmethod 

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

156 """ 

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

158 

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

160 :returns: Enumeration value. 

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

162 """ 

163 try: 

164 return cls.__VERSION_MAPPINGS__[value] 

165 except KeyError: 

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

167 

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

169 """ 

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

171 

172 :param other: Parameter to compare against. 

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

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

175 """ 

176 if isinstance(other, VHDLVersion): 

177 return self.value < other.value 

178 else: 

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

180 

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

182 """ 

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

184 

185 :param other: Parameter to compare against. 

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

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

188 """ 

189 if isinstance(other, VHDLVersion): 

190 return self.value <= other.value 

191 else: 

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

193 

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

195 """ 

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

197 

198 :param other: Parameter to compare against. 

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

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

201 """ 

202 if isinstance(other, VHDLVersion): 

203 return self.value > other.value 

204 else: 

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

206 

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

208 """ 

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

210 

211 :param other: Parameter to compare against. 

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

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

214 """ 

215 if isinstance(other, VHDLVersion): 

216 return self.value >= other.value 

217 else: 

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

219 

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

221 """ 

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

223 

224 :param other: Parameter to compare against. 

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

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

227 """ 

228 if isinstance(other, VHDLVersion): 

229 return self.value != other.value 

230 else: 

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

232 

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

234 """ 

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

236 

237 :param other: Parameter to compare against. 

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

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

240 """ 

241 if isinstance(other, VHDLVersion): 

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

243 return True 

244 else: 

245 return self.value == other.value 

246 else: 

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

248 

249 @readonly 

250 def IsVHDL(self) -> bool: 

251 """ 

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

253 

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

255 """ 

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

257 

258 @readonly 

259 def IsAMS(self) -> bool: 

260 """ 

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

262 

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

264 """ 

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

266 

267 def __str__(self) -> str: 

268 """ 

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

270 

271 :return: Formatted VHDL/VHDL-AMS version. 

272 """ 

273 if self.value == self.Any.value: 

274 return "VHDL'Any" 

275 elif self.value == self.Latest.value: 

276 return "VHDL'Latest" 

277 

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

279 if self.IsVHDL: 

280 return f"VHDL'{year}" 

281 else: 

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

283 

284 def __repr__(self) -> str: 

285 """ 

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

287 

288 :return: Formatted VHDL/VHDL-AMS version. 

289 """ 

290 if self.value == self.Any.value: 

291 return "Any" 

292 elif self.value == self.Latest.value: 

293 return "Latest" 

294 else: 

295 return str(self.value) 

296 

297 

298@export 

299class IEEEFlavor(Enum): 

300 IEEE = 0 

301 Synopsys = 1 

302 MentorGraphics = 2 

303 

304 

305@export 

306@unique 

307class ObjectClass(Enum): 

308 """ 

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

310 

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

312 """ 

313 

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

315 Constant = 1 #: Constant 

316 Variable = 2 #: Variable 

317 Signal = 3 #: Signal 

318 File = 4 #: File 

319 Type = 5 #: Type 

320 # FIXME: Package? 

321 Procedure = 6 #: Procedure 

322 Function = 7 #: Function 

323 

324 def __str__(self) -> str: 

325 """ 

326 Formats the object class. 

327 

328 :return: Formatted object class. 

329 """ 

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

331 

332 

333@export 

334@unique 

335class DesignUnitKind(Flag): 

336 """ 

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

338 

339 """ 

340 Context = auto() #: Context 

341 Package = auto() #: Package 

342 PackageBody = auto() #: Package Body 

343 Entity = auto() #: Entity 

344 Architecture = auto() #: Architecture 

345 Configuration = auto() #: Configuration 

346 

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

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

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

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

351 

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

353 

354 

355@export 

356@unique 

357class DependencyGraphVertexKind(Flag): 

358 """ 

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

360 """ 

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

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

363 

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

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

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

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

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

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

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

371 

372 

373@export 

374@unique 

375class DependencyGraphEdgeKind(Flag): 

376 """ 

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

378 """ 

379 Document = auto() 

380 Library = auto() 

381 Context = auto() 

382 Package = auto() 

383 Entity = auto() 

384 # Architecture = auto() 

385 Configuration = auto() 

386 Component = auto() 

387 

388 DeclaredIn = auto() 

389 Order = auto() 

390 Reference = auto() 

391 Implementation = auto() 

392 Instantiation = auto() 

393 

394 SourceFile = Document | DeclaredIn 

395 CompileOrder = Document | Order 

396 

397 LibraryClause = Library | Reference 

398 UseClause = Package | Reference 

399 ContextReference = Context | Reference 

400 

401 EntityImplementation = Entity | Implementation 

402 PackageImplementation = Package | Implementation 

403 

404 EntityInstantiation = Entity | Instantiation 

405 ComponentInstantiation = Component | Instantiation 

406 ConfigurationInstantiation = Configuration | Instantiation 

407 

408 

409@export 

410@unique 

411class ObjectGraphVertexKind(Flag): 

412 """ 

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

414 """ 

415 Type = auto() 

416 Subtype = auto() 

417 

418 Constant = auto() 

419 DeferredConstant = auto() 

420 Variable = auto() 

421 Signal = auto() 

422 File = auto() 

423 

424 Alias = auto() 

425 

426 

427@export 

428@unique 

429class ObjectGraphEdgeKind(Flag): 

430 """ 

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

432 """ 

433 BaseType = auto() 

434 Subtype = auto() 

435 

436 ReferenceInExpression = auto() 

437 

438 

439@export 

440class Design(ModelEntity): 

441 """ 

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

443 

444 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 

445 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 

446 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`). 

447 

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

449 

450 * :attr:`DependencyGraph` 

451 * :attr:`CompileOrderGraph` 

452 * :attr:`HierarchyGraph` 

453 * :attr:`ObjectGraph` 

454 """ 

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

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

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

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

459 _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. 

460 _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. 

461 _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. 

462 _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. 

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

464 

465 def __init__( 

466 self, 

467 name: Nullable[str] = None, 

468 allowBlackbox: bool = False 

469 ) -> None: 

470 """ 

471 Initialize a VHDL design. 

472 

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

474 :param name: Name of the design. 

475 """ 

476 super().__init__() 

477 

478 self._name = name 

479 self._allowBlackbox = allowBlackbox 

480 

481 self._libraries = {} 

482 self._documents = [] 

483 

484 self._compileOrderGraph = Graph() 

485 self._dependencyGraph = Graph() 

486 self._hierarchyGraph = Graph() 

487 self._objectGraph = Graph() 

488 self._toplevel = None 

489 

490 @readonly 

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

492 """ 

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

494 

495 :returns: The name of the design. 

496 """ 

497 return self._name 

498 

499 @property 

500 def AllowBlackbox(self) -> bool: 

501 """ 

502 Read-only property to check if a design supports blackboxes (:attr:`_allowBlackbox`). 

503 

504 :returns: If blackboxes are allowed. 

505 """ 

506 return self._allowBlackbox 

507 

508 @AllowBlackbox.setter 

509 def AllowBlackbox(self, value: Nullable[bool]) -> None: 

510 if value is None: 

511 raise ValueError(f"Property 'AllowBlackbox' doesn't accept value 'None'.") 

512 

513 self._allowBlackbox = value 

514 

515 @readonly 

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

517 """ 

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

519 

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

521 """ 

522 return self._libraries 

523 

524 @readonly 

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

526 """ 

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

528 

529 :returns: A list of all documents. 

530 """ 

531 return self._documents 

532 

533 @readonly 

534 def CompileOrderGraph(self) -> Graph: 

535 """ 

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

537 

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

539 """ 

540 return self._compileOrderGraph 

541 

542 @readonly 

543 def DependencyGraph(self) -> Graph: 

544 """ 

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

546 

547 :returns: Reference to the dependency graph. 

548 """ 

549 return self._dependencyGraph 

550 

551 @readonly 

552 def HierarchyGraph(self) -> Graph: 

553 """ 

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

555 

556 :returns: Reference to the hierarchy graph. 

557 """ 

558 return self._hierarchyGraph 

559 

560 @readonly 

561 def ObjectGraph(self) -> Graph: 

562 """ 

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

564 

565 :returns: Reference to the object graph. 

566 """ 

567 return self._objectGraph 

568 

569 @readonly 

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

571 """ 

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

573 

574 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`` 

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

576 

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

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

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

580 """ 

581 # Check for cached result 

582 if self._toplevel is not None: 

583 return self._toplevel 

584 

585 if self._hierarchyGraph.EdgeCount == 0: 

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

587 

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

589 if len(roots) == 1: 

590 toplevel = roots[0] 

591 self._hierarchyGraph["toplevel"] = toplevel 

592 self._toplevel = toplevel.Value 

593 

594 return toplevel.Value 

595 else: 

596 raise VHDLModelException(f"Found more than one toplevel: {', '.join(roots)}") 

597 

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

599 """ 

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

601 

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

603 

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

605 """ 

606 from pyVHDLModel.STD import Std 

607 

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

609 

610 library = Std() 

611 for designUnit in library.IterateDesignUnits(): 

612 doc._AddDesignUnit(designUnit) 

613 

614 self.AddLibrary(library) 

615 

616 return library 

617 

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

619 """ 

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

621 

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

623 

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

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

626 """ 

627 from pyVHDLModel.IEEE import Ieee 

628 

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

630 

631 library = Ieee(flavor) 

632 for designUnit in library.IterateDesignUnits(): 

633 doc._AddDesignUnit(designUnit) 

634 

635 self.AddLibrary(library) 

636 

637 return library 

638 

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

640 """ 

641 Add a VHDL library to the design. 

642 

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

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

645 

646 :param library: Library object to loaded. 

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

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

649 """ 

650 libraryIdentifier = library.NormalizedIdentifier 

651 if libraryIdentifier in self._libraries: 

652 raise LibraryExistsInDesignError(library) 

653 

654 if library._parent is not None: 

655 raise LibraryRegisteredToForeignDesignError(library) 

656 

657 self._libraries[libraryIdentifier] = library 

658 library._parent = self 

659 

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

661 """ 

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

663 

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

665 

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

667 :returns: The VHDL library object. 

668 """ 

669 libraryIdentifier = libraryName.lower() 

670 try: 

671 return self._libraries[libraryIdentifier] 

672 except KeyError: 

673 lib = Library(libraryName, parent=self) 

674 self._libraries[libraryIdentifier] = lib 

675 lib._parent = self 

676 return lib 

677 

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

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

680 """ 

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

682 

683 .. rubric:: Algorithm 

684 

685 1. Iterate all entities in the document 

686 

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

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

689 

690 2. Iterate all architectures in the document 

691 

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

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

694 

695 3. Iterate all packages in the document 

696 

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

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

699 

700 4. Iterate all package bodies in the document 

701 

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

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

704 

705 5. Iterate all configurations in the document 

706 

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

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

709 

710 6. Iterate all contexts in the document 

711 

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

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

714 

715 :param document: The VHDL source code file. 

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

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

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

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

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

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

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

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

724 """ 

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

726 # should the libraries parent be checked too? 

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

728 raise LibraryNotRegisteredError(library) 

729 

730 self._documents.append(document) 

731 document._parent = self 

732 

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

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

735 raise EntityExistsInLibraryError(entity, library) 

736 

737 library._entities[entityIdentifier] = entity 

738 entity.Library = library 

739 

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

741 try: 

742 architecturesPerEntity = library._architectures[entityIdentifier] 

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

744 if architectureIdentifier in architecturesPerEntity: 

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

746 

747 architecturesPerEntity[architectureIdentifier] = architecture 

748 architecture.Library = library 

749 except KeyError: 

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

751 library._architectures[entityIdentifier] = architecturesPerEntity 

752 

753 for architecture in architecturesPerEntity.values(): 

754 architecture.Library = library 

755 

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

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

758 raise PackageExistsInLibraryError(package, library) 

759 

760 library._packages[packageIdentifier] = package 

761 package.Library = library 

762 

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

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

765 raise PackageBodyExistsError(packageBody, library) 

766 

767 library._packageBodies[packageBodyIdentifier] = packageBody 

768 packageBody.Library = library 

769 

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

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

772 raise ConfigurationExistsInLibraryError(configuration, library) 

773 

774 library._configurations[configurationIdentifier] = configuration 

775 configuration.Library = library 

776 

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

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

779 raise ContextExistsInLibraryError(context, library) 

780 

781 library._contexts[contextIdentifier] = context 

782 context.Library = library 

783 

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

785 """ 

786 Iterate all design units in the design. 

787 

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

789 

790 .. rubric:: Algorithm 

791 

792 1. Iterate all VHDL libraries. 

793 

794 1. Iterate all contexts in that library. 

795 2. Iterate all packages in that library. 

796 3. Iterate all package bodies in that library. 

797 4. Iterate all entites in that library. 

798 5. Iterate all architectures in that library. 

799 6. Iterate all configurations in that library. 

800 

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

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

803 

804 .. seealso:: 

805 

806 :meth:`pyVHDLModel.Library.IterateDesignUnits` 

807 Iterate all design units in the library. 

808 :meth:`pyVHDLModel.Document.IterateDesignUnits` 

809 Iterate all design units in the document. 

810 """ 

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

812 yield from library.IterateDesignUnits(filter) 

813 

814 def Analyze(self) -> None: 

815 """ 

816 Analyze the whole design. 

817 

818 .. rubric:: Algorithm 

819 

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

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

822 2. Analyze dependencies of types and objects. 

823 

824 .. seealso:: 

825 

826 :meth:`AnalyzeDependencies` 

827 Analyze the dependencies of design units. 

828 

829 :meth:`AnalyzeObjects` 

830 Analyze the dependencies of types and objects. 

831 """ 

832 self.AnalyzeDependencies() 

833 self.AnalyzeObjects() 

834 

835 def AnalyzeDependencies(self) -> None: 

836 """ 

837 Analyze the dependencies of design units. 

838 

839 .. rubric:: Algorithm 

840 

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

842 |rarr| :meth:`CreateDependencyGraph` 

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

844 |rarr| :meth:`CreateCompileOrderGraph` 

845 3. Index all packages. |br| 

846 |rarr| :meth:`IndexPackages` 

847 4. Index all architectures. |br| 

848 |rarr| :meth:`IndexArchitectures` 

849 5. Link all contexts |br| 

850 |rarr| :meth:`LinkContexts` 

851 6. Link all architectures. |br| 

852 |rarr| :meth:`LinkArchitectures` 

853 7. Link all package bodies. |br| 

854 |rarr| :meth:`LinkPackageBodies` 

855 8. Link all library references. |br| 

856 |rarr| :meth:`LinkLibraryReferences` 

857 9. Link all package references. |br| 

858 |rarr| :meth:`LinkPackageReferences` 

859 10. Link all context references. |br| 

860 |rarr| :meth:`LinkContextReferences` 

861 11. Link all components. |br| 

862 |rarr| :meth:`LinkComponents` 

863 12. Link all instantiations. |br| 

864 |rarr| :meth:`LinkInstantiations` 

865 13. Create the hierarchy graph. |br| 

866 |rarr| :meth:`CreateHierarchyGraph` 

867 14. Compute the compile order. |br| 

868 |rarr| :meth:`ComputeCompileOrder` 

869 """ 

870 self.CreateDependencyGraph() 

871 self.CreateCompileOrderGraph() 

872 

873 self.IndexPackages() 

874 self.IndexArchitectures() 

875 

876 self.LinkContexts() 

877 self.LinkArchitectures() 

878 self.LinkPackageBodies() 

879 self.LinkLibraryReferences() 

880 self.LinkPackageReferences() 

881 self.LinkContextReferences() 

882 

883 self.LinkComponents() 

884 self.LinkInstantiations() 

885 self.CreateHierarchyGraph() 

886 self.ComputeCompileOrder() 

887 

888 def AnalyzeObjects(self) -> None: 

889 """ 

890 Analyze the dependencies of types and objects. 

891 

892 .. rubric:: Algorithm 

893 

894 1. Index all entities. |br| 

895 |rarr| :meth:`IndexEntities` 

896 2. Index all package bodies. |br| 

897 |rarr| :meth:`IndexPackageBodies` 

898 3. Import objects. |br| 

899 |rarr| :meth:`ImportObjects` 

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

901 |rarr| :meth:`CreateTypeAndObjectGraph` 

902 """ 

903 self.IndexEntities() 

904 self.IndexPackageBodies() 

905 

906 self.ImportObjects() 

907 self.CreateTypeAndObjectGraph() 

908 

909 def CreateDependencyGraph(self) -> None: 

910 """ 

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

912 

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

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

915 

916 Each vertex has the following properties: 

917 

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

919 * The vertex' value references the design unit. 

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

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

922 

923 .. rubric:: Algorithm 

924 

925 1. Iterate all libraries in the design. 

926 

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

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

929 

930 1. Iterate all contexts in that library. 

931 

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

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

934 

935 2. Iterate all packages in that library. 

936 

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

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

939 

940 3. Iterate all package bodies in that library. 

941 

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

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

944 

945 4. Iterate all entities in that library. 

946 

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

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

949 

950 5. Iterate all architectures in that library. 

951 

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

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

954 

955 6. Iterate all configurations in that library. 

956 

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

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

959 """ 

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

961 

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

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

964 dependencyVertex["kind"] = DependencyGraphVertexKind.Library 

965 dependencyVertex["predefined"] = libraryIdentifier in predefinedLibraries 

966 library._dependencyVertex = dependencyVertex 

967 

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

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

970 dependencyVertex["kind"] = DependencyGraphVertexKind.Context 

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

972 context._dependencyVertex = dependencyVertex 

973 

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

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

976 dependencyVertex["kind"] = DependencyGraphVertexKind.Package 

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

978 package._dependencyVertex = dependencyVertex 

979 

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

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

982 dependencyVertex["kind"] = DependencyGraphVertexKind.PackageBody 

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

984 packageBody._dependencyVertex = dependencyVertex 

985 

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

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

988 dependencyVertex["kind"] = DependencyGraphVertexKind.Entity 

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

990 entity._dependencyVertex = dependencyVertex 

991 

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

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

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

995 dependencyVertex["kind"] = DependencyGraphVertexKind.Architecture 

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

997 architecture._dependencyVertex = dependencyVertex 

998 

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

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

1001 dependencyVertex["kind"] = DependencyGraphVertexKind.Configuration 

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

1003 configuration._dependencyVertex = dependencyVertex 

1004 

1005 def CreateCompileOrderGraph(self) -> None: 

1006 """ 

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

1008 

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

1010 graph and bidirectionally referenced. 

1011 

1012 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 

1013 document relationship. 

1014 

1015 Each added vertex has the following properties: 

1016 

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

1018 * The vertex' value references the document. 

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

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

1021 

1022 .. rubric:: Algorithm 

1023 

1024 1. Iterate all documents in the design. 

1025 

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

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

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

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

1030 

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

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

1033 

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

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

1036 

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

1038 """ 

1039 for document in self._documents: 

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

1041 dependencyVertex["kind"] = DependencyGraphVertexKind.Document 

1042 document._dependencyVertex = dependencyVertex 

1043 

1044 compilerOrderVertex = dependencyVertex.Copy( 

1045 self._compileOrderGraph, 

1046 copyDict=True, 

1047 linkingKeyToOriginalVertex="dependencyVertex", 

1048 linkingKeyFromOriginalVertex="compileOrderVertex" 

1049 ) 

1050 document._compileOrderVertex = compilerOrderVertex 

1051 

1052 for designUnit in document._designUnits: 

1053 edge = dependencyVertex.EdgeFromVertex(designUnit._dependencyVertex) 

1054 edge["kind"] = DependencyGraphEdgeKind.SourceFile 

1055 

1056 def ImportObjects(self) -> None: 

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

1058 from pyVHDLModel.Declaration import AttributeSpecification 

1059 

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

1061 for referencedPackage in referencedLibrary.values(): 

1062 for declaredItem in referencedPackage._declaredItems: 

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

1064 for normalizedIdentifier in declaredItem._normalizedIdentifiers: 

1065 package._namespace._elements[normalizedIdentifier] = declaredItem 

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

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

1068 elif isinstance(declaredItem, AttributeSpecification): 

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

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

1071 

1072 else: 

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

1074 

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

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

1077 _ImportObjects(package) 

1078 

1079 for document in self.IterateDocumentsInCompileOrder(): 

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

1081 _ImportObjects(package) 

1082 

1083 def CreateTypeAndObjectGraph(self) -> None: 

1084 def _HandlePackage(package) -> None: 

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

1086 

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

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

1089 deferredConstantVertex = Vertex( 

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

1091 value=deferredConstant, 

1092 graph=self._objectGraph 

1093 ) 

1094 deferredConstantVertex["kind"] = ObjectGraphVertexKind.DeferredConstant 

1095 deferredConstant._objectVertex = deferredConstantVertex 

1096 

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

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

1099 constantVertex = Vertex( 

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

1101 value=constant, 

1102 graph=self._objectGraph 

1103 ) 

1104 constantVertex["kind"] = ObjectGraphVertexKind.Constant 

1105 constant._objectVertex = constantVertex 

1106 

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

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

1109 typeVertex = Vertex( 

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

1111 value=type, 

1112 graph=self._objectGraph 

1113 ) 

1114 typeVertex["kind"] = ObjectGraphVertexKind.Type 

1115 type._objectVertex = typeVertex 

1116 

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

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

1119 subtypeVertex = Vertex( 

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

1121 value=subtype, 

1122 graph=self._objectGraph 

1123 ) 

1124 subtypeVertex["kind"] = ObjectGraphVertexKind.Subtype 

1125 subtype._objectVertex = subtypeVertex 

1126 

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

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

1129 functionVertex = Vertex( 

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

1131 value=function, 

1132 graph=self._objectGraph 

1133 ) 

1134 functionVertex["kind"] = ObjectGraphVertexKind.Function 

1135 function._objectVertex = functionVertex 

1136 

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

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

1139 procedureVertex = Vertex( 

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

1141 value=procedure, 

1142 graph=self._objectGraph 

1143 ) 

1144 procedureVertex["kind"] = ObjectGraphVertexKind.Function 

1145 procedure._objectVertex = procedureVertex 

1146 

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

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

1149 signalVertex = Vertex( 

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

1151 value=signal, 

1152 graph=self._objectGraph 

1153 ) 

1154 signalVertex["kind"] = ObjectGraphVertexKind.Signal 

1155 signal._objectVertex = signalVertex 

1156 

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

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

1159 _LinkSymbolsInExpression(expression.Operand, namespace, typeVertex) 

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

1161 _LinkSymbolsInExpression(expression.LeftOperand, namespace, typeVertex) 

1162 _LinkSymbolsInExpression(expression.RightOperand, namespace, typeVertex) 

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

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

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

1166 obj = namespace.FindObject(expression) 

1167 expression._reference = obj 

1168 

1169 edge = obj._objectVertex.EdgeToVertex(typeVertex) 

1170 edge["kind"] = ObjectGraphEdgeKind.ReferenceInExpression 

1171 else: 

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

1173 

1174 def _LinkItems(package: Package): 

1175 for item in package._declaredItems: 

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

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

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

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

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

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

1182 elif isinstance(item, IntegerType): 

1183 typeNode = item._objectVertex 

1184 

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

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

1187 # elif isinstance(item, FloatingType): 

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

1189 elif isinstance(item, PhysicalType): 

1190 typeNode = item._objectVertex 

1191 

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

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

1194 elif isinstance(item, ArrayType): 

1195 # Resolve dimensions 

1196 for dimension in item._dimensions: 

1197 subtype = package._namespace.FindSubtype(dimension) 

1198 dimension._reference = subtype 

1199 

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

1201 edge["kind"] = ObjectGraphEdgeKind.Subtype 

1202 

1203 # Resolve element subtype 

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

1205 item._elementType._reference = subtype 

1206 

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

1208 edge["kind"] = ObjectGraphEdgeKind.Subtype 

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

1210 # Resolve each elements subtype 

1211 for element in item._elements: 

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

1213 element._subtype._reference = subtype 

1214 

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

1216 edge["kind"] = ObjectGraphEdgeKind.Subtype 

1217 else: 

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

1219 

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

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

1222 _HandlePackage(package) 

1223 _LinkItems(package) 

1224 

1225 for document in self.IterateDocumentsInCompileOrder(): 

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

1227 _HandlePackage(package) 

1228 _LinkItems(package) 

1229 

1230 def LinkContexts(self) -> None: 

1231 """ 

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

1233 

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

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

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

1237 

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

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

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

1241 dependency graph is added for that relationship. 

1242 

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

1244 referenced package, 

1245 """ 

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

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

1248 workingLibrary: Library = context.Library 

1249 libraryNormalizedIdentifier = workingLibrary._normalizedIdentifier 

1250 

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

1252 context._referencedPackages[libraryNormalizedIdentifier] = {} 

1253 context._referencedContexts[libraryNormalizedIdentifier] = {} 

1254 

1255 # Process all library clauses 

1256 for libraryReference in context._libraryReferences: 

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

1258 for libraryName in libraryReference.Symbols: 

1259 libraryNormalizedIdentifier = libraryName.Name._normalizedIdentifier 

1260 try: 

1261 library = self._libraries[libraryNormalizedIdentifier] 

1262 except KeyError: 

1263 raise ReferencedLibraryNotExistingError(context, libraryName) 

1264 # TODO: add position to these messages 

1265 

1266 libraryName.Library = library 

1267 

1268 context._referencedLibraries[libraryNormalizedIdentifier] = library 

1269 context._referencedPackages[libraryNormalizedIdentifier] = {} 

1270 context._referencedContexts[libraryNormalizedIdentifier] = {} 

1271 # TODO: warn duplicate library reference 

1272 

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

1274 dependency["kind"] = DependencyGraphEdgeKind.LibraryClause 

1275 

1276 # Process all use clauses 

1277 for packageReference in context.PackageReferences: 

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

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

1280 packageName = symbol.Name.Prefix 

1281 libraryName = packageName.Prefix 

1282 

1283 libraryNormalizedIdentifier = libraryName._normalizedIdentifier 

1284 packageNormalizedIdentifier = packageName._normalizedIdentifier 

1285 

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

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

1288 library: Library = context._parent 

1289 libraryNormalizedIdentifier = library._normalizedIdentifier 

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

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

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

1293 else: 

1294 library = self._libraries[libraryNormalizedIdentifier] 

1295 

1296 try: 

1297 package = library._packages[packageNormalizedIdentifier] 

1298 except KeyError: 

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

1300 

1301 symbol.Package = package 

1302 

1303 # TODO: warn duplicate package reference 

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

1305 

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

1307 dependency["kind"] = DependencyGraphEdgeKind.UseClause 

1308 

1309 # TODO: update the namespace with visible members 

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

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

1312 

1313 elif isinstance(symbol, PackageMemberReferenceSymbol): 

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

1315 

1316 else: 

1317 raise VHDLModelException() 

1318 

1319 def LinkArchitectures(self) -> None: 

1320 """ 

1321 Link all architectures to corresponding entities in all libraries. 

1322 

1323 .. rubric:: Algorithm 

1324 

1325 1. Iterate all libraries: 

1326 

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

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

1329 

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

1331 

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

1333 

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

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

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

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

1338 

1339 .. seealso:: 

1340 

1341 :meth:`LinkPackageBodies` 

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

1343 """ 

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

1345 library.LinkArchitectures() 

1346 

1347 def LinkPackageBodies(self) -> None: 

1348 """ 

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

1350 

1351 .. rubric:: Algorithm 

1352 

1353 1. Iterate all libraries: 

1354 

1355 1. Iterate all package bodies. 

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

1357 

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

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

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

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

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

1363 

1364 .. seealso:: 

1365 

1366 :meth:`LinkArchitectures` 

1367 Link all architectures to corresponding entities in all libraries. 

1368 """ 

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

1370 library.LinkPackageBodies() 

1371 

1372 def LinkLibraryReferences(self) -> None: 

1373 DEFAULT_LIBRARIES = ("std",) 

1374 

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

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

1377 if isinstance(designUnit, PrimaryUnit): 

1378 for libraryIdentifier in DEFAULT_LIBRARIES: 

1379 referencedLibrary = self._libraries[libraryIdentifier] 

1380 designUnit._referencedLibraries[libraryIdentifier] = referencedLibrary 

1381 designUnit._referencedPackages[libraryIdentifier] = {} 

1382 designUnit._referencedContexts[libraryIdentifier] = {} 

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

1384 # TODO: warn duplicate library reference 

1385 

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

1387 dependency["kind"] = DependencyGraphEdgeKind.LibraryClause 

1388 

1389 workingLibrary: Library = designUnit.Library 

1390 libraryIdentifier = workingLibrary.NormalizedIdentifier 

1391 referencedLibrary = self._libraries[libraryIdentifier] 

1392 

1393 

1394 designUnit._referencedLibraries[libraryIdentifier] = referencedLibrary 

1395 designUnit._referencedPackages[libraryIdentifier] = {} 

1396 designUnit._referencedContexts[libraryIdentifier] = {} 

1397 

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

1399 dependency["kind"] = DependencyGraphEdgeKind.LibraryClause 

1400 

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

1402 else: 

1403 if isinstance(designUnit, Architecture): 

1404 referencedLibraries = designUnit.Entity.Entity._referencedLibraries 

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

1406 referencedLibraries = designUnit.Package.Package._referencedLibraries 

1407 else: 

1408 raise VHDLModelException() 

1409 

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

1411 designUnit._referencedLibraries[libraryIdentifier] = library 

1412 

1413 for libraryReference in designUnit._libraryReferences: 

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

1415 for librarySymbol in libraryReference.Symbols: 

1416 libraryIdentifier = librarySymbol.Name.NormalizedIdentifier 

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

1418 continue 

1419 

1420 try: 

1421 library = self._libraries[libraryIdentifier] 

1422 except KeyError: 

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

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

1425 raise ex 

1426 

1427 librarySymbol.Library = library 

1428 designUnit._referencedLibraries[libraryIdentifier] = library 

1429 designUnit._referencedPackages[libraryIdentifier] = {} 

1430 designUnit._referencedContexts[libraryIdentifier] = {} 

1431 # TODO: warn duplicate library reference 

1432 

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

1434 dependency["kind"] = DependencyGraphEdgeKind.LibraryClause 

1435 

1436 def LinkPackageReferences(self) -> None: 

1437 DEFAULT_PACKAGES = ( 

1438 ("std", ("standard",)), 

1439 ) 

1440 

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

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

1443 if isinstance(designUnit, PrimaryUnit): 

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

1445 designUnit.NormalizedIdentifier != "standard": 

1446 for lib in DEFAULT_PACKAGES: 

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

1448 raise VHDLModelException() 

1449 for pack in lib[1]: 

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

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

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

1453 # TODO: warn duplicate package reference 

1454 

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

1456 dependency["kind"] = DependencyGraphEdgeKind.UseClause 

1457 

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

1459 else: 

1460 if isinstance(designUnit, Architecture): 

1461 referencedPackages = designUnit.Entity.Entity._referencedPackages 

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

1463 referencedPackages = designUnit.Package.Package._referencedPackages 

1464 else: 

1465 raise VHDLModelException() 

1466 

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

1468 designUnit._referencedPackages[packageIdentifier] = package 

1469 

1470 for packageReference in designUnit.PackageReferences: 

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

1472 for packageMemberSymbol in packageReference.Symbols: 

1473 packageName = packageMemberSymbol.Name.Prefix 

1474 libraryName = packageName.Prefix 

1475 

1476 libraryIdentifier = libraryName.NormalizedIdentifier 

1477 packageIdentifier = packageName.NormalizedIdentifier 

1478 

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

1480 if libraryIdentifier == "work": 

1481 library: Library = designUnit.Library 

1482 libraryIdentifier = library.NormalizedIdentifier 

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

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

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

1486 else: 

1487 library = self._libraries[libraryIdentifier] 

1488 

1489 try: 

1490 package = library._packages[packageIdentifier] 

1491 except KeyError: 

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

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

1494 raise ex 

1495 

1496 packageMemberSymbol.Package = package 

1497 

1498 # TODO: warn duplicate package reference 

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

1500 

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

1502 dependency["kind"] = DependencyGraphEdgeKind.UseClause 

1503 

1504 # TODO: update the namespace with visible members 

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

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

1507 

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

1509 designUnit._namespace._elements[componentIdentifier] = component 

1510 

1511 elif isinstance(packageMemberSymbol, PackageMemberReferenceSymbol): 

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

1513 

1514 else: 

1515 raise VHDLModelException() 

1516 

1517 def LinkContextReferences(self) -> None: 

1518 for designUnit in self.IterateDesignUnits(): 

1519 for contextReference in designUnit._contextReferences: 

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

1521 for contextSymbol in contextReference.Symbols: 

1522 libraryName = contextSymbol.Name.Prefix 

1523 

1524 libraryIdentifier = libraryName.NormalizedIdentifier 

1525 contextIdentifier = contextSymbol.Name.NormalizedIdentifier 

1526 

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

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

1529 referencedLibrary = designUnit.Library 

1530 libraryIdentifier = referencedLibrary.NormalizedIdentifier 

1531 elif libraryIdentifier not in designUnit._referencedLibraries: 

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

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

1534 else: 

1535 referencedLibrary = self._libraries[libraryIdentifier] 

1536 

1537 try: 

1538 referencedContext = referencedLibrary._contexts[contextIdentifier] 

1539 except KeyError: 

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

1541 

1542 contextSymbol.Package = referencedContext 

1543 

1544 # TODO: warn duplicate referencedContext reference 

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

1546 

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

1548 dependency["kind"] = DependencyGraphEdgeKind.ContextReference 

1549 

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

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

1552 context: Context = vertex.Value 

1553 for designUnitVertex in vertex.IteratePredecessorVertices(): 

1554 designUnit: DesignUnit = designUnitVertex.Value 

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

1556 # if libraryIdentifier in designUnit._referencedLibraries: 

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

1558 

1559 designUnit._referencedLibraries[libraryIdentifier] = library 

1560 designUnit._referencedPackages[libraryIdentifier] = {} 

1561 

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

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

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

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

1566 

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

1568 

1569 def LinkComponents(self) -> None: 

1570 for package in self.IterateDesignUnits(DesignUnitKind.Package): # type: Package 

1571 library = package._parent 

1572 for component in package._components.values(): 1572 ↛ 1573line 1572 didn't jump to line 1573 because the loop on line 1572 never started

1573 try: 

1574 entity = library._entities[component.NormalizedIdentifier] 

1575 except KeyError: 

1576 if not component.AllowBlackbox: 

1577 raise VHDLModelException(f"Entity '{component.Identifier}' not found for component '{component.Identifier}' in library '{library.Identifier}'.") 

1578 else: 

1579 component._isBlackBox = True 

1580 continue 

1581 

1582 component.Entity = entity 

1583 

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

1585 # Currently, component has no _dependencyVertex field 

1586 

1587 # FIXME: also link components in architectures (and nested structures like generate statements and block statements 

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

1589 # library = architecture._parent 

1590 # for component in architecture._components.values(): 

1591 # pass 

1592 

1593 def LinkInstantiations(self) -> None: 

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

1595 for instance in architecture.IterateInstantiations(): 

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

1597 libraryName = instance.Entity.Name.Prefix 

1598 libraryIdentifier = libraryName.Identifier 

1599 normalizedLibraryIdentifier = libraryName.NormalizedIdentifier 

1600 if normalizedLibraryIdentifier == "work": 

1601 libraryIdentifier = architecture.Library.Identifier 

1602 normalizedLibraryIdentifier = architecture.Library.NormalizedIdentifier 

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

1604 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}'.") 

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

1606 raise ex 

1607 

1608 try: 

1609 library = self._libraries[normalizedLibraryIdentifier] 

1610 except KeyError: 

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

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

1613 raise ex 

1614 

1615 try: 

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

1617 except KeyError: 

1618 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}'.") 

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

1620 if libs: 

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

1622 raise ex 

1623 

1624 instance.Entity.Entity = entity 

1625 

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

1627 dependency["kind"] = DependencyGraphEdgeKind.EntityInstantiation 

1628 

1629 elif isinstance(instance, ComponentInstantiation): 

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

1631 

1632 instance.Component.Component = component 

1633 

1634 if not component.IsBlackbox: 

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

1636 dependency["kind"] = DependencyGraphEdgeKind.ComponentInstantiation 

1637 else: 

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

1639 

1640 elif isinstance(instance, ConfigurationInstantiation): 

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

1642 

1643 def IndexPackages(self) -> None: 

1644 """ 

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

1646 

1647 .. rubric:: Algorithm 

1648 

1649 1. Iterate all libraries: 

1650 

1651 1. Iterate all packages |br| 

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

1653 

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

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

1656 

1657 .. seealso:: 

1658 

1659 :meth:`IndexPackageBodies` 

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

1661 :meth:`IndexEntities` 

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

1663 :meth:`IndexArchitectures` 

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

1665 """ 

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

1667 library.IndexPackages() 

1668 

1669 def IndexPackageBodies(self) -> None: 

1670 """ 

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

1672 

1673 .. rubric:: Algorithm 

1674 

1675 1. Iterate all libraries: 

1676 

1677 1. Iterate all packages |br| 

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

1679 

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

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

1682 

1683 .. seealso:: 

1684 

1685 :meth:`IndexPackages` 

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

1687 :meth:`IndexEntities` 

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

1689 :meth:`IndexArchitectures` 

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

1691 """ 

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

1693 library.IndexPackageBodies() 

1694 

1695 def IndexEntities(self) -> None: 

1696 """ 

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

1698 

1699 .. rubric:: Algorithm 

1700 

1701 1. Iterate all libraries: 

1702 

1703 1. Iterate all packages |br| 

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

1705 

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

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

1708 

1709 .. seealso:: 

1710 

1711 :meth:`IndexPackages` 

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

1713 :meth:`IndexPackageBodies` 

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

1715 :meth:`IndexArchitectures` 

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

1717 """ 

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

1719 library.IndexEntities() 

1720 

1721 def IndexArchitectures(self) -> None: 

1722 """ 

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

1724 

1725 .. rubric:: Algorithm 

1726 

1727 1. Iterate all libraries: 

1728 

1729 1. Iterate all packages |br| 

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

1731 

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

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

1734 

1735 .. seealso:: 

1736 

1737 :meth:`IndexPackages` 

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

1739 :meth:`IndexPackageBodies` 

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

1741 :meth:`IndexEntities` 

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

1743 """ 

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

1745 library.IndexArchitectures() 

1746 

1747 def CreateHierarchyGraph(self) -> None: 

1748 """ 

1749 Create the hierarchy graph from dependency graph. 

1750 

1751 .. rubric:: Algorithm 

1752 

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

1754 

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

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

1757 

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

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

1760 

1761 2. Iterate all architectures ... 

1762 

1763 .. todo:: Design::CreateHierarchyGraph describe algorithm 

1764 

1765 1. Iterate all outbound edges 

1766 

1767 .. todo:: Design::CreateHierarchyGraph describe algorithm 

1768 """ 

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

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

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

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

1773 vertex.Value._hierarchyVertex = hierarchyVertex 

1774 

1775 # Copy implementation edges from 

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

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

1778 kind: DependencyGraphEdgeKind = dependencyEdge["kind"] 

1779 if DependencyGraphEdgeKind.Implementation in kind: 

1780 hierarchyDestinationVertex = dependencyEdge.Destination["hierarchyVertex"] 

1781 newEdge = hierarchyArchitectureVertex.EdgeFromVertex(hierarchyDestinationVertex) 

1782 elif DependencyGraphEdgeKind.Instantiation in kind: 

1783 hierarchyDestinationVertex = dependencyEdge.Destination["hierarchyVertex"] 

1784 

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

1786 if hierarchyArchitectureVertex.HasEdgeToDestination(hierarchyDestinationVertex): 

1787 continue 

1788 

1789 newEdge = hierarchyArchitectureVertex.EdgeToVertex(hierarchyDestinationVertex) 

1790 else: 

1791 continue 

1792 

1793 newEdge["kind"] = kind 

1794 

1795 def ComputeCompileOrder(self) -> None: 

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

1797 return ( 

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

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

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

1801 DependencyGraphEdgeKind.ContextReference in edge["kind"] 

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

1803 

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

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

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

1807 

1808 sourceVertex = sourceDocument._compileOrderVertex 

1809 destinationVertex = destinationDocument._compileOrderVertex 

1810 

1811 # Don't add self-edges 

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

1813 continue 

1814 # Don't add parallel edges 

1815 elif sourceVertex.HasEdgeToDestination(destinationVertex): 

1816 continue 

1817 

1818 e = sourceVertex.EdgeToVertex(destinationVertex) 

1819 e["kind"] = DependencyGraphEdgeKind.CompileOrder 

1820 

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

1822 e["kind"] = DependencyGraphEdgeKind.CompileOrder 

1823 

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

1825 """ 

1826 Iterate all document in compile-order. 

1827 

1828 .. rubric:: Algorithm 

1829 

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

1831 

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

1833 :meth:`pyTooling.Graph.Graph.IterateTopologically` 

1834 

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

1836 

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

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

1839 

1840 .. seealso:: 

1841 

1842 .. todo:: missing text 

1843 

1844 :meth:`pyVHDLModel.Design.ComputeCompileOrder` 

1845 

1846 """ 

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

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

1849 

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

1851 yield compileOrderNode.Value 

1852 

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

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

1855 

1856 def __repr__(self) -> str: 

1857 """ 

1858 Formats a representation of the design. 

1859 

1860 **Format:** ``Document: 'my_design'`` 

1861 

1862 :returns: String representation of the design. 

1863 """ 

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

1865 

1866 __str__ = __repr__ 

1867 

1868 

1869@export 

1870class Library(ModelEntity, NamedEntityMixin): 

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

1872 

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

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

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

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

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

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

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

1880 

1881 _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`. 

1882 

1883 def __init__( 

1884 self, 

1885 identifier: str, 

1886 allowBlackbox: Nullable[bool] = None, 

1887 parent: ModelEntity = None 

1888 ) -> None: 

1889 """ 

1890 Initialize a VHDL library. 

1891 

1892 :param identifier: Name of the VHDL library. 

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

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

1895 """ 

1896 super().__init__(parent) 

1897 NamedEntityMixin.__init__(self, identifier) 

1898 

1899 self._allowBlackbox = allowBlackbox 

1900 

1901 self._contexts = {} 

1902 self._configurations = {} 

1903 self._entities = {} 

1904 self._architectures = {} 

1905 self._packages = {} 

1906 self._packageBodies = {} 

1907 

1908 self._dependencyVertex = None 

1909 

1910 @property 

1911 def AllowBlackbox(self) -> bool: 

1912 """ 

1913 Read-only property to check if a design supports blackboxes (:attr:`_allowBlackbox`). 

1914 

1915 :returns: If blackboxes are allowed. 

1916 """ 

1917 if self._allowBlackbox is None: 

1918 return self._parent.AllowBlackbox 

1919 else: 

1920 return self._allowBlackbox 

1921 

1922 @AllowBlackbox.setter 

1923 def AllowBlackbox(self, value: Nullable[bool]) -> None: 

1924 self._allowBlackbox = value 

1925 

1926 @readonly 

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

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

1929 return self._contexts 

1930 

1931 @readonly 

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

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

1934 return self._configurations 

1935 

1936 @readonly 

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

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

1939 return self._entities 

1940 

1941 @readonly 

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

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

1944 return self._architectures 

1945 

1946 @readonly 

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

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

1949 return self._packages 

1950 

1951 @readonly 

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

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

1954 return self._packageBodies 

1955 

1956 @readonly 

1957 def DependencyVertex(self) -> Vertex: 

1958 """ 

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

1960 

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

1962 

1963 :returns: The corresponding dependency vertex. 

1964 """ 

1965 return self._dependencyVertex 

1966 

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

1968 """ 

1969 Iterate all design units in the library. 

1970 

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

1972 

1973 .. rubric:: Algorithm 

1974 

1975 1. Iterate all contexts in that library. 

1976 2. Iterate all packages in that library. 

1977 3. Iterate all package bodies in that library. 

1978 4. Iterate all entities in that library. 

1979 5. Iterate all architectures in that library. 

1980 6. Iterate all configurations in that library. 

1981 

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

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

1984 

1985 .. seealso:: 

1986 

1987 :meth:`pyVHDLModel.Design.IterateDesignUnits` 

1988 Iterate all design units in the design. 

1989 :meth:`pyVHDLModel.Document.IterateDesignUnits` 

1990 Iterate all design units in the document. 

1991 """ 

1992 if DesignUnitKind.Context in filter: 

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

1994 yield context 

1995 

1996 if DesignUnitKind.Package in filter: 

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

1998 yield package 

1999 

2000 if DesignUnitKind.PackageBody in filter: 

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

2002 yield packageBody 

2003 

2004 if DesignUnitKind.Entity in filter: 

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

2006 yield entity 

2007 

2008 if DesignUnitKind.Architecture in filter: 

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

2010 for architecture in architectures.values(): 

2011 yield architecture 

2012 

2013 if DesignUnitKind.Configuration in filter: 

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

2015 yield configuration 

2016 

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

2018 # yield verificationProperty 

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

2020 # yield entity 

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

2022 # yield verificationMode 

2023 

2024 def LinkArchitectures(self) -> None: 

2025 """ 

2026 Link all architectures to corresponding entities. 

2027 

2028 .. rubric:: Algorithm 

2029 

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

2031 

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

2033 

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

2035 

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

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

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

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

2040 

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

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

2043 

2044 .. seealso:: 

2045 

2046 :meth:`LinkPackageBodies` 

2047 Link all package bodies to corresponding packages. 

2048 """ 

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

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

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

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

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

2054 # TODO: add code position 

2055 

2056 entity = self._entities[entityName] 

2057 for architecture in architecturesPerEntity.values(): 

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

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

2060 # TODO: add code position of existing and current 

2061 

2062 entity._architectures[architecture._normalizedIdentifier] = architecture 

2063 architecture._entity.Entity = entity 

2064 architecture._namespace._parentNamespace = entity._namespace 

2065 

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

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

2068 dependency["kind"] = DependencyGraphEdgeKind.EntityImplementation 

2069 

2070 def LinkPackageBodies(self) -> None: 

2071 """ 

2072 Link all package bodies to corresponding packages. 

2073 

2074 .. rubric:: Algorithm 

2075 

2076 1. Iterate all package bodies. 

2077 

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

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

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

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

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

2083 

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

2085 

2086 .. seealso:: 

2087 

2088 :meth:`LinkArchitectures` 

2089 Link all architectures to corresponding entities. 

2090 """ 

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

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

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

2094 

2095 package = self._packages[packageBodyName] 

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

2097 packageBody._package.Package = package 

2098 packageBody._namespace._parentNamespace = package._namespace 

2099 

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

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

2102 dependency["kind"] = DependencyGraphEdgeKind.PackageImplementation 

2103 

2104 def IndexPackages(self) -> None: 

2105 """ 

2106 Index declared items in all packages. 

2107 

2108 .. rubric:: Algorithm 

2109 

2110 1. Iterate all packages: 

2111 

2112 * Index all declared items. |br| 

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

2114 

2115 .. seealso:: 

2116 

2117 :meth:`IndexPackageBodies` 

2118 Index all declared items in a package body. 

2119 :meth:`IndexEntities` 

2120 Index all declared items in an entity. 

2121 :meth:`IndexArchitectures` 

2122 Index all declared items in an architecture. 

2123 """ 

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

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

2126 package.IndexDeclaredItems() 

2127 

2128 def IndexPackageBodies(self) -> None: 

2129 """ 

2130 Index declared items in all package bodies. 

2131 

2132 .. rubric:: Algorithm 

2133 

2134 1. Iterate all package bodies: 

2135 

2136 * Index all declared items. |br| 

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

2138 

2139 .. seealso:: 

2140 

2141 :meth:`IndexPackages` 

2142 Index all declared items in a package. 

2143 :meth:`IndexEntities` 

2144 Index all declared items in an entity. 

2145 :meth:`IndexArchitectures` 

2146 Index all declared items in an architecture. 

2147 """ 

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

2149 packageBody.IndexDeclaredItems() 

2150 

2151 def IndexEntities(self) -> None: 

2152 """ 

2153 Index declared items in all entities. 

2154 

2155 .. rubric:: Algorithm 

2156 

2157 1. Iterate all entities: 

2158 

2159 * Index all declared items. |br| 

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

2161 

2162 .. seealso:: 

2163 

2164 :meth:`IndexPackages` 

2165 Index all declared items in a package. 

2166 :meth:`IndexPackageBodies` 

2167 Index all declared items in a package body. 

2168 :meth:`IndexArchitectures` 

2169 Index all declared items in an architecture. 

2170 """ 

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

2172 entity.IndexDeclaredItems() 

2173 

2174 def IndexArchitectures(self) -> None: 

2175 """ 

2176 Index declared items in all architectures. 

2177 

2178 .. rubric:: Algorithm 

2179 

2180 1. Iterate all architectures: 

2181 

2182 * Index all declared items. |br| 

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

2184 

2185 .. seealso:: 

2186 

2187 :meth:`IndexPackages` 

2188 Index all declared items in a package. 

2189 :meth:`IndexPackageBodies` 

2190 Index all declared items in a package body. 

2191 :meth:`IndexEntities` 

2192 Index all declared items in an entity. 

2193 """ 

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

2195 for architecture in architectures.values(): 

2196 architecture.IndexDeclaredItems() 

2197 architecture.IndexStatements() 

2198 

2199 def __repr__(self) -> str: 

2200 """ 

2201 Formats a representation of the library. 

2202 

2203 **Format:** ``Library: 'my_library'`` 

2204 

2205 :returns: String representation of the library. 

2206 """ 

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

2208 

2209 __str__ = __repr__ 

2210 

2211 

2212@export 

2213class Document(ModelEntity, DocumentedEntityMixin): 

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

2215 

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

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

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

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

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

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

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

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

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

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

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

2227 

2228 _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`. 

2229 _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`. 

2230 

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

2232 super().__init__(parent) 

2233 DocumentedEntityMixin.__init__(self, documentation) 

2234 

2235 self._path = path 

2236 self._designUnits = [] 

2237 self._contexts = {} 

2238 self._configurations = {} 

2239 self._entities = {} 

2240 self._architectures = {} 

2241 self._packages = {} 

2242 self._packageBodies = {} 

2243 self._verificationUnits = {} 

2244 self._verificationProperties = {} 

2245 self._verificationModes = {} 

2246 

2247 self._dependencyVertex = None 

2248 self._compileOrderVertex = None 

2249 

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

2251 """ 

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

2253 

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

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

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

2257 """ 

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

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

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

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

2262 raise ex 

2263 

2264 identifier = item._normalizedIdentifier 

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

2266 # TODO: use a more specific exception 

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

2268 

2269 self._entities[identifier] = item 

2270 self._designUnits.append(item) 

2271 item._document = self 

2272 

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

2274 """ 

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

2276 

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

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

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

2280 """ 

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

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

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

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

2285 raise ex 

2286 

2287 entity = item._entity.Name 

2288 entityIdentifier = entity._normalizedIdentifier 

2289 try: 

2290 architectures = self._architectures[entityIdentifier] 

2291 if item._normalizedIdentifier in architectures: 

2292 # TODO: use a more specific exception 

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

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

2295 

2296 architectures[item.Identifier] = item 

2297 except KeyError: 

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

2299 

2300 self._designUnits.append(item) 

2301 item._document = self 

2302 

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

2304 """ 

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

2306 

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

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

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

2310 """ 

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

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

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

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

2315 raise ex 

2316 

2317 identifier = item._normalizedIdentifier 

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

2319 # TODO: use a more specific exception 

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

2321 

2322 self._packages[identifier] = item 

2323 self._designUnits.append(item) 

2324 item._document = self 

2325 

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

2327 """ 

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

2329 

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

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

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

2333 """ 

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

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

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

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

2338 raise ex 

2339 

2340 identifier = item._normalizedIdentifier 

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

2342 # TODO: use a more specific exception 

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

2344 

2345 self._packageBodies[identifier] = item 

2346 self._designUnits.append(item) 

2347 item._document = self 

2348 

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

2350 """ 

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

2352 

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

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

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

2356 """ 

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

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

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

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

2361 raise ex 

2362 

2363 identifier = item._normalizedIdentifier 

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

2365 # TODO: use a more specific exception 

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

2367 

2368 self._contexts[identifier] = item 

2369 self._designUnits.append(item) 

2370 item._document = self 

2371 

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

2373 """ 

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

2375 

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

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

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

2379 """ 

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

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

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

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

2384 raise ex 

2385 

2386 identifier = item._normalizedIdentifier 

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

2388 # TODO: use a more specific exception 

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

2390 

2391 self._configurations[identifier] = item 

2392 self._designUnits.append(item) 

2393 item._document = self 

2394 

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

2396 if not isinstance(item, VerificationUnit): 

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

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

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

2400 raise ex 

2401 

2402 identifier = item._normalizedIdentifier 

2403 if identifier in self._verificationUnits: 

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

2405 

2406 self._verificationUnits[identifier] = item 

2407 self._designUnits.append(item) 

2408 item._document = self 

2409 

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

2411 if not isinstance(item, VerificationProperty): 

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

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

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

2415 raise ex 

2416 

2417 identifier = item.NormalizedIdentifier 

2418 if identifier in self._verificationProperties: 

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

2420 

2421 self._verificationProperties[identifier] = item 

2422 self._designUnits.append(item) 

2423 item._document = self 

2424 

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

2426 if not isinstance(item, VerificationMode): 

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

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

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

2430 raise ex 

2431 

2432 identifier = item.NormalizedIdentifier 

2433 if identifier in self._verificationModes: 

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

2435 

2436 self._verificationModes[identifier] = item 

2437 self._designUnits.append(item) 

2438 item._document = self 

2439 

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

2441 """ 

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

2443 

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

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

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

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

2448 """ 

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

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

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

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

2453 raise ex 

2454 

2455 if isinstance(item, Entity): 

2456 self._AddEntity(item) 

2457 elif isinstance(item, Architecture): 

2458 self._AddArchitecture(item) 

2459 elif isinstance(item, Package): 

2460 self._AddPackage(item) 

2461 elif isinstance(item, PackageBody): 

2462 self._AddPackageBody(item) 

2463 elif isinstance(item, Context): 

2464 self._AddContext(item) 

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

2466 self._AddConfiguration(item) 

2467 elif isinstance(item, VerificationUnit): 

2468 self._AddVerificationUnit(item) 

2469 elif isinstance(item, VerificationProperty): 

2470 self._AddVerificationProperty(item) 

2471 elif isinstance(item, VerificationMode): 

2472 self._AddVerificationMode(item) 

2473 else: 

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

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

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

2477 raise ex 

2478 

2479 @readonly 

2480 def Path(self) -> Path: 

2481 """ 

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

2483 

2484 :returns: The path of this document. 

2485 """ 

2486 return self._path 

2487 

2488 @readonly 

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

2490 """ 

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

2492 

2493 :returns: List of all design units. 

2494 """ 

2495 return self._designUnits 

2496 

2497 @readonly 

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

2499 """ 

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

2501 

2502 :returns: List of all contexts. 

2503 """ 

2504 return self._contexts 

2505 

2506 @readonly 

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

2508 """ 

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

2510 

2511 :returns: List of all configurations. 

2512 """ 

2513 return self._configurations 

2514 

2515 @readonly 

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

2517 """ 

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

2519 

2520 :returns: List of all entities. 

2521 """ 

2522 return self._entities 

2523 

2524 @readonly 

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

2526 """ 

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

2528 

2529 :returns: List of all architectures. 

2530 """ 

2531 return self._architectures 

2532 

2533 @readonly 

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

2535 """ 

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

2537 

2538 :returns: List of all packages. 

2539 """ 

2540 return self._packages 

2541 

2542 @readonly 

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

2544 """ 

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

2546 

2547 :returns: List of all package bodies. 

2548 """ 

2549 return self._packageBodies 

2550 

2551 @readonly 

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

2553 """ 

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

2555 

2556 :returns: List of all verification units. 

2557 """ 

2558 return self._verificationUnits 

2559 

2560 @readonly 

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

2562 """ 

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

2564 

2565 :returns: List of all verification properties. 

2566 """ 

2567 return self._verificationProperties 

2568 

2569 @readonly 

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

2571 """ 

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

2573 

2574 :returns: List of all verification modes. 

2575 """ 

2576 return self._verificationModes 

2577 

2578 @readonly 

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

2580 """ 

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

2582 

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

2584 

2585 :returns: The corresponding compile-order vertex. 

2586 """ 

2587 return self._compileOrderVertex 

2588 

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

2590 """ 

2591 Iterate all design units in the document. 

2592 

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

2594 

2595 .. rubric:: Algorithm 

2596 

2597 * If contexts are selected in the filter: 

2598 

2599 1. Iterate all contexts in that library. 

2600 

2601 * If packages are selected in the filter: 

2602 

2603 1. Iterate all packages in that library. 

2604 

2605 * If package bodies are selected in the filter: 

2606 

2607 1. Iterate all package bodies in that library. 

2608 

2609 * If entites are selected in the filter: 

2610 

2611 1. Iterate all entites in that library. 

2612 

2613 * If architectures are selected in the filter: 

2614 

2615 1. Iterate all architectures in that library. 

2616 

2617 * If configurations are selected in the filter: 

2618 

2619 1. Iterate all configurations in that library. 

2620 

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

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

2623 

2624 .. seealso:: 

2625 

2626 :meth:`pyVHDLModel.Design.IterateDesignUnits` 

2627 Iterate all design units in the design. 

2628 :meth:`pyVHDLModel.Library.IterateDesignUnits` 

2629 Iterate all design units in the library. 

2630 """ 

2631 if DesignUnitKind.Context in filter: 

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

2633 yield context 

2634 

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

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

2637 yield package 

2638 

2639 if DesignUnitKind.PackageBody in filter: 

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

2641 yield packageBody 

2642 

2643 if DesignUnitKind.Entity in filter: 

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

2645 yield entity 

2646 

2647 if DesignUnitKind.Architecture in filter: 

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

2649 for architecture in architectures.values(): 

2650 yield architecture 

2651 

2652 if DesignUnitKind.Configuration in filter: 

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

2654 yield configuration 

2655 

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

2657 # yield verificationProperty 

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

2659 # yield entity 

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

2661 # yield verificationMode 

2662 

2663 def __repr__(self) -> str: 

2664 """ 

2665 Formats a representation of the document. 

2666 

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

2668 

2669 :returns: String representation of the document. 

2670 """ 

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

2672 

2673 __str__ = __repr__