Coverage for pyVHDLModel/DesignUnit.py: 91%

307 statements  

« prev     ^ index     » next       coverage.py v7.16.0, created at 2026-09-11 23:50 +0000

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

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

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

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

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

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

7# |_| |___/ # 

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

9# Authors: # 

10# Patrick Lehmann # 

11# # 

12# License: # 

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

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

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

16# # 

17# Licensed under the Apache License, Version 2.0 (the "License"); # 

18# you may not use this file except in compliance with the License. # 

19# You may obtain a copy of the License at # 

20# # 

21# http://www.apache.org/licenses/LICENSE-2.0 # 

22# # 

23# Unless required by applicable law or agreed to in writing, software # 

24# distributed under the License is distributed on an "AS IS" BASIS, # 

25# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # 

26# See the License for the specific language governing permissions and # 

27# limitations under the License. # 

28# # 

29# SPDX-License-Identifier: Apache-2.0 # 

30# ==================================================================================================================== # 

31# 

32""" 

33This module contains parts of an abstract document language model for VHDL. 

34 

35Design units are contexts, entities, architectures, packages and their bodies as well as configurations. 

36""" 

37from typing import ClassVar, List, Dict, Union, Iterable, Optional as Nullable 

38 

39from pyTooling.Decorators import export, readonly 

40from pyTooling.MetaClasses import ExtendedType, abstractmethod 

41from pyTooling.Graph import Vertex 

42 

43from pyVHDLModel.Common import AllowBlackboxMixin 

44from pyVHDLModel.Exception import VHDLModelException 

45from pyVHDLModel.Base import ModelEntity, NamedEntityMixin, DocumentedEntityMixin 

46from pyVHDLModel.Namespace import Namespace 

47from pyVHDLModel.Regions import ConcurrentDeclarationRegionMixin 

48from pyVHDLModel.Symbol import Symbol, PackageSymbol, EntitySymbol, LibraryReferenceSymbol 

49from pyVHDLModel.Interface import GenericInterfaceItemMixin, PortInterfaceItemMixin, WithGenericsMixin, WithPortsMixin 

50from pyVHDLModel.Object import DeferredConstant 

51from pyVHDLModel.Concurrent import ConcurrentStatement, ConcurrentStatementsMixin 

52from pyVHDLModel.Configuration import BlockConfiguration 

53 

54 

55@export 

56class Reference(ModelEntity): 

57 """ 

58 A base-class for all references. 

59 

60 .. seealso:: 

61 

62 * :class:`Library clause <pyVHDLModel.DesignUnit.LibraryClause>` 

63 * :class:`Use clause <pyVHDLModel.DesignUnit.UseClause>` 

64 * :class:`Context reference <pyVHDLModel.DesignUnit.ContextReference>` 

65 """ 

66 

67 _symbols: List[Symbol] #: List of all symbols referenced by this clause. 

68 

69 def __init__(self, symbols: Iterable[Symbol], parent: Nullable[ModelEntity] = None) -> None: 

70 """ 

71 Initializes a reference by taking a list of symbols and a parent reference. 

72 

73 :param symbols: A list of symbols this reference references to. 

74 :param parent: Reference to the logical parent in the model hierarchy. 

75 """ 

76 super().__init__(parent) 

77 

78 self._symbols = [s for s in symbols] 

79 

80 @readonly 

81 def Symbols(self) -> List[Symbol]: 

82 """ 

83 Read-only property to access the symbols this reference references to (:attr:`_symbols`). 

84 

85 :returns: A list of symbols. 

86 """ 

87 return self._symbols 

88 

89 

90@export 

91class LibraryClause(Reference): 

92 """ 

93 Represents a library clause. 

94 

95 .. admonition:: Example 

96 

97 .. code-block:: VHDL 

98 

99 library std, ieee; 

100 """ 

101 

102 @readonly 

103 def Symbols(self) -> List[LibraryReferenceSymbol]: 

104 """ 

105 Read-only property to access the symbols this library clause references to (:attr:`_symbols`). 

106 

107 :returns: A list of library reference symbols. 

108 """ 

109 return self._symbols 

110 

111 

112@export 

113class UseClause(Reference): 

114 """ 

115 Represents a use clause. 

116 

117 .. admonition:: Example 

118 

119 .. code-block:: VHDL 

120 

121 use std.text_io.all, ieee.numeric_std.all; 

122 """ 

123 

124 

125@export 

126class ContextReference(Reference): 

127 """ 

128 Represents a context reference. 

129 

130 .. hint:: It's called *context reference* not *context clause* by the LRM. 

131 

132 .. admonition:: Example 

133 

134 .. code-block:: VHDL 

135 

136 context ieee.ieee_std_context; 

137 """ 

138 

139 

140ContextUnion = Union[ 

141 LibraryClause, 

142 UseClause, 

143 ContextReference 

144] 

145 

146 

147@export 

148class DesignUnitWithContextMixin(metaclass=ExtendedType, mixin=True): 

149 """ 

150 A mixin-class for all design units with a context. 

151 

152 .. seealso:: 

153 

154 * :class:`Package <pyVHDLModel.DesignUnit.Package>` 

155 * :class:`Package body <pyVHDLModel.DesignUnit.PackageBody>` 

156 * :class:`Entity <pyVHDLModel.DesignUnit.Entity>` 

157 * :class:`Architecture <pyVHDLModel.DesignUnit.Architecture>` 

158 * :class:`Configuration <pyVHDLModel.DesignUnit.Configuration>` 

159 """ 

160 

161 

162@export 

163class DesignUnit(ModelEntity, NamedEntityMixin, DocumentedEntityMixin): 

164 """ 

165 A base-class for all design units. 

166 

167 When a design unit is formatted, an unknown part - a library that is not set, or an entity with no 

168 known architecture - is rendered as ``?``. 

169 

170 .. seealso:: 

171 

172 * :class:`Primary design units <pyVHDLModel.DesignUnit.PrimaryUnit>` 

173 

174 * :class:`Context <pyVHDLModel.DesignUnit.Context>` 

175 * :class:`Entity <pyVHDLModel.DesignUnit.Entity>` 

176 * :class:`Package <pyVHDLModel.DesignUnit.Package>` 

177 * :class:`Configuration <pyVHDLModel.DesignUnit.Configuration>` 

178 

179 * :class:`Secondary design units <pyVHDLModel.DesignUnit.SecondaryUnit>` 

180 

181 * :class:`Architecture <pyVHDLModel.DesignUnit.Architecture>` 

182 * :class:`Package body <pyVHDLModel.DesignUnit.PackageBody>` 

183 """ 

184 

185 _continuesParentRegion: ClassVar[bool] = False #: ``True`` if it continues its parent's declarative region. 

186 

187 _document: 'Document' #: The VHDL library, the design unit was analyzed into. 

188 

189 # Either written as statements before (e.g. entity, architecture, package, ...), or as statements inside (context) 

190 _contextItems: List['ContextUnion'] #: List of all context items (library, use and context clauses). 

191 _libraryReferences: List['LibraryClause'] #: List of library clauses. 

192 _packageReferences: List['UseClause'] #: List of use clauses. 

193 _contextReferences: List['ContextReference'] #: List of context clauses. 

194 

195 _referencedLibraries: Dict[str, 'Library'] #: Referenced libraries based on explicit library clauses or implicit inheritance 

196 _referencedPackages: Dict[str, Dict[str, 'Package']] #: Referenced packages based on explicit use clauses or implicit inheritance 

197 _referencedContexts: Dict[str, 'Context'] #: Referenced contexts based on explicit context references or implicit inheritance 

198 

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

200 _hierarchyVertex: Vertex[None, None, str, 'DesignUnit', None, None, None, None, None, None, None, None, None, None, None, None, None] #: The vertex in the hierarchy graph 

201 

202 _namespace: 'Namespace' #: The namespace of this design unit's declarative region. 

203 

204 def __init__(self, identifier: str, contextItems: Nullable[Iterable[ContextUnion]] = None, documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None: 

205 """ 

206 Initializes a design unit. 

207 

208 :param identifier: Identifier (name) of the design unit. 

209 :param contextItems: A sequence of library, use or context clauses. 

210 :param documentation: Associated documentation of the design unit. 

211 :param parent: Reference to the logical parent in the model hierarchy. 

212 """ 

213 super().__init__(parent) 

214 NamedEntityMixin.__init__(self, identifier) 

215 DocumentedEntityMixin.__init__(self, documentation) 

216 

217 self._document = None 

218 

219 self._contextItems = [] 

220 self._libraryReferences = [] 

221 self._packageReferences = [] 

222 self._contextReferences = [] 

223 

224 if contextItems is not None: 

225 for item in contextItems: 

226 self._contextItems.append(item) 

227 if isinstance(item, UseClause): 

228 self._packageReferences.append(item) 

229 elif isinstance(item, LibraryClause): 

230 self._libraryReferences.append(item) 

231 elif isinstance(item, ContextReference): 231 ↛ 225line 231 didn't jump to line 225 because the condition on line 231 was always true

232 self._contextReferences.append(item) 

233 

234 self._referencedLibraries = {} 

235 self._referencedPackages = {} 

236 self._referencedContexts = {} 

237 

238 self._dependencyVertex = None 

239 self._hierarchyVertex = None 

240 

241 self._namespace = Namespace(self._normalizedIdentifier, sharesRegionWithParent=self._continuesParentRegion) 

242 

243 @property 

244 def Document(self) -> 'Document': 

245 """ 

246 Property to access the document (:attr:`_document`). 

247 

248 :returns: The document. 

249 """ 

250 return self._document 

251 

252 @Document.setter 

253 def Document(self, document: 'Document') -> None: 

254 self._document = document 

255 

256 @property 

257 def Library(self) -> 'Library': 

258 """ 

259 Property to access the library (:attr:`_parent`). 

260 

261 :returns: The library. 

262 """ 

263 return self._parent 

264 

265 @Library.setter 

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

267 self._parent = library 

268 

269 @readonly 

270 def ContextItems(self) -> List['ContextUnion']: 

271 """ 

272 Read-only property to access the sequence of all context items comprising library, use and context clauses 

273 (:attr:`_contextItems`). 

274 

275 :returns: Sequence of context items. 

276 """ 

277 return self._contextItems 

278 

279 @readonly 

280 def ContextReferences(self) -> List['ContextReference']: 

281 """ 

282 Read-only property to access the sequence of context clauses (:attr:`_contextReferences`). 

283 

284 :returns: Sequence of context clauses. 

285 """ 

286 return self._contextReferences 

287 

288 @readonly 

289 def LibraryReferences(self) -> List['LibraryClause']: 

290 """ 

291 Read-only property to access the sequence of library clauses (:attr:`_libraryReferences`). 

292 

293 :returns: Sequence of library clauses. 

294 """ 

295 return self._libraryReferences 

296 

297 @readonly 

298 def PackageReferences(self) -> List['UseClause']: 

299 """ 

300 Read-only property to access the sequence of use clauses (:attr:`_packageReferences`). 

301 

302 :returns: Sequence of use clauses. 

303 """ 

304 return self._packageReferences 

305 

306 @readonly 

307 def ReferencedLibraries(self) -> Dict[str, 'Library']: 

308 """ 

309 Read-only property to access the referenced libraries (:attr:`_referencedLibraries`). 

310 

311 :returns: Dictionary of referenced libraries, indexed by normalized identifier. 

312 """ 

313 return self._referencedLibraries 

314 

315 @readonly 

316 def ReferencedPackages(self) -> Dict[str, 'Package']: 

317 """ 

318 Read-only property to access the referenced packages (:attr:`_referencedPackages`). 

319 

320 :returns: Dictionary of referenced packages, indexed by normalized identifier. 

321 """ 

322 return self._referencedPackages 

323 

324 @readonly 

325 def ReferencedContexts(self) -> Dict[str, 'Context']: 

326 """ 

327 Read-only property to access the referenced contexts (:attr:`_referencedContexts`). 

328 

329 :returns: Dictionary of referenced contexts, indexed by normalized identifier. 

330 """ 

331 return self._referencedContexts 

332 

333 @readonly 

334 def DependencyVertex(self) -> Vertex: 

335 """ 

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

337 

338 The dependency vertex references this design unit by its value field. 

339 

340 :returns: The corresponding dependency vertex. 

341 """ 

342 return self._dependencyVertex 

343 

344 @readonly 

345 def HierarchyVertex(self) -> Vertex: 

346 """ 

347 Read-only property to access the corresponding hierarchy vertex (:attr:`_hierarchyVertex`). 

348 

349 The hierarchy vertex references this design unit by its value field. 

350 

351 :returns: The corresponding hierarchy vertex. 

352 """ 

353 return self._hierarchyVertex 

354 

355 @abstractmethod 

356 def __str__(self) -> str: 

357 """ 

358 Formats the design unit. 

359 

360 Every concrete design unit renders itself, so this base-class provides no implementation. 

361 

362 :returns: Formatted design unit. 

363 """ 

364 

365 

366@export 

367class PrimaryUnit(DesignUnit): 

368 """ 

369 A base-class for all primary design units. 

370 

371 .. seealso:: 

372 

373 * :class:`Context <pyVHDLModel.DesignUnit.Context>` 

374 * :class:`Package <pyVHDLModel.DesignUnit.Package>` 

375 * :class:`Entity <pyVHDLModel.DesignUnit.Entity>` 

376 * :class:`Configuration <pyVHDLModel.DesignUnit.Configuration>` 

377 * :class:`PSL primary unit <pyVHDLModel.PSLModel.PSLPrimaryUnit>` (PSL is not supported) 

378 """ 

379 

380 

381@export 

382class SecondaryUnit(DesignUnit): 

383 """ 

384 A base-class for all secondary design units. 

385 

386 .. seealso:: 

387 

388 * :class:`Package body <pyVHDLModel.DesignUnit.PackageBody>` 

389 * :class:`Architecture <pyVHDLModel.DesignUnit.Architecture>` 

390 """ 

391 

392 

393@export 

394class Context(PrimaryUnit): 

395 """ 

396 Represents a context declaration. 

397 

398 A context contains a generic list of all its items (library clauses, use clauses and context references) in 

399 :data:`_references`. 

400 

401 Furthermore, when a context gets initialized, the item kinds get separated into individual lists: 

402 

403 * :class:`~pyVHDLModel.DesignUnit.LibraryClause` |rarr| :data:`_libraryReferences` 

404 * :class:`~pyVHDLModel.DesignUnit.UseClause` |rarr| :data:`_packageReferences` 

405 * :class:`~pyVHDLModel.DesignUnit.ContextReference` |rarr| :data:`_contextReferences` 

406 

407 When :meth:`pyVHDLModel.Design.LinkContexts` got called, these lists were processed and the fields: 

408 

409 * :data:`_referencedLibraries` (:pycode:`Dict[libName, Library]`) 

410 * :data:`_referencedPackages` (:pycode:`Dict[libName, [pkgName, Package]]`) 

411 * :data:`_referencedContexts` (:pycode:`Dict[libName, [ctxName, Context]]`) 

412 

413 are populated. 

414 

415 .. admonition:: Example 

416 

417 .. code-block:: VHDL 

418 

419 context ctx is 

420 -- ... 

421 end context; 

422 

423 .. seealso:: 

424 

425 * :class:`Library clause <pyVHDLModel.DesignUnit.LibraryClause>` 

426 * :class:`Use clause <pyVHDLModel.DesignUnit.UseClause>` 

427 """ 

428 

429 _references: List[ContextUnion] #: All context items, in declaration order. 

430 

431 def __init__(self, identifier: str, references: Nullable[Iterable[ContextUnion]] = None, documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None: 

432 """ 

433 Initializes a context declaration. 

434 

435 :param identifier: The identifier of a model entity. 

436 :param references: All context items, in declaration order. 

437 :param documentation: The documentation comment associated with this declaration. 

438 :param parent: The parent model entity of this entity. 

439 :raises VHDLModelException: If a context item is neither a library clause, use clause, nor context reference. 

440 """ 

441 super().__init__(identifier, None, documentation, parent) 

442 

443 self._references = [] 

444 self._libraryReferences = [] 

445 self._packageReferences = [] 

446 self._contextReferences = [] 

447 

448 if references is not None: 

449 for reference in references: 

450 self._references.append(reference) 

451 reference.Parent = self 

452 

453 if isinstance(reference, LibraryClause): 

454 self._libraryReferences.append(reference) 

455 elif isinstance(reference, UseClause): 

456 self._packageReferences.append(reference) 

457 elif isinstance(reference, ContextReference): 

458 self._contextReferences.append(reference) 

459 else: 

460 raise VHDLModelException(f"Reference '{reference!r}' is neither a library clause, use clause, nor context reference.") 

461 

462 @readonly 

463 def LibraryReferences(self) -> List[LibraryClause]: 

464 """ 

465 Read-only property to access the library references (:attr:`_libraryReferences`). 

466 

467 :returns: List of library references. 

468 """ 

469 return self._libraryReferences 

470 

471 @readonly 

472 def PackageReferences(self) -> List[UseClause]: 

473 """ 

474 Read-only property to access the package references (:attr:`_packageReferences`). 

475 

476 :returns: List of package references. 

477 """ 

478 return self._packageReferences 

479 

480 @readonly 

481 def ContextReferences(self) -> List[ContextReference]: 

482 """ 

483 Read-only property to access the context references (:attr:`_contextReferences`). 

484 

485 :returns: List of context references. 

486 """ 

487 return self._contextReferences 

488 

489 def __str__(self) -> str: 

490 """ 

491 Formats the context declaration. 

492 

493 **Format:** ``Context: mylib.myContext`` 

494 

495 :returns: Formatted context declaration. 

496 """ 

497 lib = self._parent._identifier if self._parent is not None else "?" 

498 

499 return f"Context: {lib}.{self._identifier}" 

500 

501 

502@export 

503class Package(PrimaryUnit, DesignUnitWithContextMixin, WithGenericsMixin, ConcurrentDeclarationRegionMixin, AllowBlackboxMixin): 

504 """ 

505 Represents a package declaration. 

506 

507 .. admonition:: Example 

508 

509 .. code-block:: VHDL 

510 

511 package pkg is 

512 -- ... 

513 end package; 

514 

515 .. seealso:: 

516 

517 * :class:`Package instantiation <pyVHDLModel.Instantiation.PackageInstantiation>` 

518 * :class:`Predefined package <pyVHDLModel.Predefined.PredefinedPackage>` 

519 * :class:`Package body implementing it <pyVHDLModel.DesignUnit.PackageBody>` 

520 """ 

521 

522 _packageBody: Nullable["PackageBody"] #: The corresponding package body, or ``None`` if none was analyzed. 

523 

524 _deferredConstants: Dict[str, DeferredConstant] #: Deferred constants, indexed by name. 

525 _components: Dict[str, 'Component'] #: Components, indexed by name. 

526 

527 def __init__( 

528 self, 

529 identifier: str, 

530 contextItems: Nullable[Iterable[ContextUnion]] = None, 

531 genericItems: Nullable[Iterable[GenericInterfaceItemMixin]] = None, 

532 declaredItems: Nullable[Iterable] = None, 

533 documentation: Nullable[str] = None, 

534 allowBlackbox: Nullable[bool] = None, 

535 parent: Nullable[ModelEntity] = None 

536 ) -> None: 

537 """ 

538 Initialize a package. 

539 

540 :param identifier: Name of the VHDL package. 

541 :param contextItems: 

542 :param genericItems: 

543 :param declaredItems: 

544 :param documentation: 

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

546 :param parent: The parent model entity (library) of this VHDL package. 

547 """ 

548 super().__init__(identifier, contextItems, documentation, parent) 

549 DesignUnitWithContextMixin.__init__(self) 

550 WithGenericsMixin.__init__(self, genericItems) 

551 ConcurrentDeclarationRegionMixin.__init__(self, declaredItems) 

552 AllowBlackboxMixin.__init__(self, allowBlackbox) 

553 

554 self._packageBody = None 

555 

556 self._deferredConstants = {} 

557 self._components = {} 

558 

559 @readonly 

560 def PackageBody(self) -> Nullable["PackageBody"]: 

561 """ 

562 Read-only property to access the package body (:attr:`_packageBody`). 

563 

564 :returns: The package body, or ``None`` if not set. 

565 """ 

566 return self._packageBody 

567 

568 @readonly 

569 def DeclaredItems(self) -> List: 

570 """ 

571 Read-only property to access the declared items (:attr:`_declaredItems`). 

572 

573 :returns: List of declared items. 

574 """ 

575 return self._declaredItems 

576 

577 @readonly 

578 def DeferredConstants(self) -> Dict[str, DeferredConstant]: 

579 """ 

580 Read-only property to access the deferred constants (:attr:`_deferredConstants`). 

581 

582 :returns: Dictionary of deferred constants, indexed by normalized identifier. 

583 """ 

584 return self._deferredConstants 

585 

586 @readonly 

587 def Components(self) -> Dict[str, 'Component']: 

588 """ 

589 Read-only property to access the components (:attr:`_components`). 

590 

591 :returns: Dictionary of components, indexed by normalized identifier. 

592 """ 

593 return self._components 

594 

595 def _IndexOtherDeclaredItem(self, item) -> None: 

596 if isinstance(item, DeferredConstant): 596 ↛ 599line 596 didn't jump to line 599 because the condition on line 596 was always true

597 for normalizedIdentifier in item.NormalizedIdentifiers: 

598 self._deferredConstants[normalizedIdentifier] = item 

599 elif isinstance(item, Component): 

600 self._components[item._normalizedIdentifier] = item 

601 else: 

602 super()._IndexOtherDeclaredItem(item) 

603 

604 def __str__(self) -> str: 

605 """ 

606 Formats the package declaration. 

607 

608 **Format:** ``Package: 'mylib.myPackage'`` 

609 

610 :returns: Formatted package declaration. 

611 """ 

612 lib = self._parent._identifier if self._parent is not None else "?" 

613 

614 return f"Package: '{lib}.{self._identifier}'" 

615 

616 def __repr__(self) -> str: 

617 """ 

618 Formats a representation of the package declaration. 

619 

620 **Format:** ``mylib.myPackage`` 

621 

622 :returns: String representation of the package declaration. 

623 """ 

624 lib = self._parent._identifier if self._parent is not None else "?" 

625 

626 return f"{lib}.{self._identifier}" 

627 

628 

629 def IndexDeclaredItems(self) -> None: 

630 """A generic package's generics share the declarative region of its declarative part.""" 

631 self._IndexGenericItems() 

632 

633 super().IndexDeclaredItems() 

634 

635 

636@export 

637class PackageBody(SecondaryUnit, DesignUnitWithContextMixin, ConcurrentDeclarationRegionMixin): 

638 """ 

639 Represents a package body declaration. 

640 

641 .. admonition:: Example 

642 

643 .. code-block:: VHDL 

644 

645 package body pkg is 

646 -- ... 

647 end package body; 

648 

649 .. seealso:: 

650 

651 * :class:`Predefined package body <pyVHDLModel.Predefined.PredefinedPackageBody>` 

652 * :class:`Package it implements <pyVHDLModel.DesignUnit.Package>` 

653 """ 

654 

655 _continuesParentRegion: ClassVar[bool] = True #: A package body continues its package's declarative region. 

656 

657 _package: PackageSymbol #: Reference to the package this body implements. 

658 

659 def __init__( 

660 self, 

661 packageSymbol: PackageSymbol, 

662 contextItems: Nullable[Iterable[ContextUnion]] = None, 

663 declaredItems: Nullable[Iterable] = None, 

664 documentation: Nullable[str] = None, 

665 parent: Nullable[ModelEntity] = None 

666 ) -> None: 

667 """ 

668 Initializes a package body declaration. 

669 

670 :param packageSymbol: Reference to the package this body implements. 

671 :param contextItems: List of all context items (library, use and context clauses). 

672 :param declaredItems: List of all declared items in this concurrent declaration region. 

673 :param documentation: The documentation comment associated with this declaration. 

674 :param parent: The parent model entity of this entity. 

675 """ 

676 super().__init__(packageSymbol.Name.Identifier, contextItems, documentation, parent) 

677 DesignUnitWithContextMixin.__init__(self) 

678 ConcurrentDeclarationRegionMixin.__init__(self, declaredItems) 

679 

680 self._package = packageSymbol 

681 packageSymbol.Parent = self 

682 

683 @readonly 

684 def Package(self) -> PackageSymbol: 

685 """ 

686 Read-only property to access the package (:attr:`_package`). 

687 

688 :returns: The package. 

689 """ 

690 return self._package 

691 

692 @readonly 

693 def DeclaredItems(self) -> List: 

694 """ 

695 Read-only property to access the declared items (:attr:`_declaredItems`). 

696 

697 :returns: List of declared items. 

698 """ 

699 return self._declaredItems 

700 

701 def LinkDeclaredItemsToPackage(self) -> None: 

702 pass 

703 

704 def __str__(self) -> str: 

705 """ 

706 Formats the package body declaration. 

707 

708 **Format:** ``Package Body: mylib.myPackage(body)`` 

709 

710 :returns: Formatted package body declaration. 

711 """ 

712 lib = self._parent._identifier if self._parent is not None else "?" 

713 

714 return f"Package Body: {lib}.{self._identifier}(body)" 

715 

716 def __repr__(self) -> str: 

717 """ 

718 Formats a representation of the package body declaration. 

719 

720 **Format:** ``mylib.myPackage(body)`` 

721 

722 :returns: String representation of the package body declaration. 

723 """ 

724 lib = self._parent._identifier if self._parent is not None else "?" 

725 

726 return f"{lib}.{self._identifier}(body)" 

727 

728 

729@export 

730class Entity(PrimaryUnit, DesignUnitWithContextMixin, WithGenericsMixin, WithPortsMixin, ConcurrentDeclarationRegionMixin, ConcurrentStatementsMixin, AllowBlackboxMixin): 

731 """ 

732 Represents an entity declaration. 

733 

734 .. admonition:: Example 

735 

736 .. code-block:: VHDL 

737 

738 entity ent is 

739 -- ... 

740 end entity; 

741 

742 .. seealso:: 

743 

744 * :class:`Architecture implementing it <pyVHDLModel.DesignUnit.Architecture>` 

745 * :class:`Component declaring the same interface <pyVHDLModel.DesignUnit.Component>` 

746 * :class:`Configuration binding it <pyVHDLModel.DesignUnit.Configuration>` 

747 """ 

748 

749 _architectures: Dict[str, 'Architecture'] #: Dictionary of all architectures of this entity, indexed by name. 

750 

751 def __init__( 

752 self, 

753 identifier: str, 

754 contextItems: Nullable[Iterable[ContextUnion]] = None, 

755 genericItems: Nullable[Iterable[GenericInterfaceItemMixin]] = None, 

756 portItems: Nullable[Iterable[PortInterfaceItemMixin]] = None, 

757 declaredItems: Nullable[Iterable] = None, 

758 statements: Nullable[Iterable[ConcurrentStatement]] = None, 

759 documentation: Nullable[str] = None, 

760 allowBlackbox: Nullable[bool] = None, 

761 parent: Nullable[ModelEntity] = None 

762 ) -> None: 

763 """ 

764 Initializes an entity declaration. 

765 

766 :param identifier: The identifier of a model entity. 

767 :param contextItems: List of all context items (library, use and context clauses). 

768 :param genericItems: List of all generics, in declaration order. 

769 :param portItems: List of all ports, in declaration order. 

770 :param declaredItems: List of all declared items in this concurrent declaration region. 

771 :param statements: List of all concurrent statements in this construct. 

772 :param documentation: The documentation comment associated with this declaration. 

773 :param allowBlackbox: Allow blackboxes for components in language entity. 

774 :param parent: The parent model entity of this entity. 

775 """ 

776 super().__init__(identifier, contextItems, documentation, parent) 

777 DesignUnitWithContextMixin.__init__(self) 

778 WithGenericsMixin.__init__(self, genericItems) 

779 WithPortsMixin.__init__(self, portItems) 

780 ConcurrentDeclarationRegionMixin.__init__(self, declaredItems) 

781 ConcurrentStatementsMixin.__init__(self, statements) 

782 AllowBlackboxMixin.__init__(self, allowBlackbox) 

783 

784 self._architectures = {} 

785 

786 @readonly 

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

788 """ 

789 Read-only property to access the architectures (:attr:`_architectures`). 

790 

791 :returns: Dictionary of architectures, indexed by normalized identifier. 

792 """ 

793 return self._architectures 

794 

795 def __str__(self) -> str: 

796 """ 

797 Formats the entity declaration. 

798 

799 **Format:** ``Entity: 'mylib.myEntity(rtl, sim)'`` 

800 

801 The parenthesis lists the known architectures, or ``?`` if there are none. 

802 

803 :returns: Formatted entity declaration. 

804 """ 

805 lib = self._parent._identifier if self._parent is not None else "?" 

806 archs = ', '.join(self._architectures.keys()) if self._architectures else "?" 

807 

808 return f"Entity: '{lib}.{self._identifier}({archs})'" 

809 

810 def __repr__(self) -> str: 

811 """ 

812 Formats a representation of the entity declaration. 

813 

814 **Format:** ``mylib.myEntity(rtl, sim)`` 

815 

816 :returns: String representation of the entity declaration. 

817 """ 

818 lib = self._parent._identifier if self._parent is not None else "?" 

819 archs = ', '.join(self._architectures.keys()) if self._architectures else "?" 

820 

821 return f"{lib}.{self._identifier}({archs})" 

822 

823 

824 def IndexDeclaredItems(self) -> None: 

825 """An entity's generics and ports share the declarative region of its declarative part.""" 

826 self._IndexGenericItems() 

827 self._IndexPortItems() 

828 

829 super().IndexDeclaredItems() 

830 

831 

832@export 

833class Architecture(SecondaryUnit, DesignUnitWithContextMixin, ConcurrentDeclarationRegionMixin, ConcurrentStatementsMixin, AllowBlackboxMixin): 

834 """ 

835 Represents an architecture declaration. 

836 

837 .. admonition:: Example 

838 

839 .. code-block:: VHDL 

840 

841 architecture rtl of ent is 

842 -- ... 

843 begin 

844 -- ... 

845 end architecture; 

846 

847 .. seealso:: 

848 

849 * :class:`Entity it implements <pyVHDLModel.DesignUnit.Entity>` 

850 """ 

851 

852 _continuesParentRegion: ClassVar[bool] = True #: An architecture continues its entity's declarative region. 

853 

854 _entity: EntitySymbol #: Reference to the entity this architecture implements. 

855 

856 def __init__( 

857 self, 

858 identifier: str, 

859 entity: EntitySymbol, 

860 contextItems: Nullable[Iterable[Context]] = None, 

861 declaredItems: Nullable[Iterable] = None, 

862 statements: Iterable['ConcurrentStatement'] = None, 

863 documentation: Nullable[str] = None, 

864 allowBlackbox: Nullable[bool] = None, 

865 parent: Nullable[ModelEntity] = None 

866 ) -> None: 

867 """ 

868 Initializes an architecture declaration. 

869 

870 :param identifier: The identifier of a model entity. 

871 :param entity: Reference to the entity this architecture implements. 

872 :param contextItems: List of all context items (library, use and context clauses). 

873 :param declaredItems: List of all declared items in this concurrent declaration region. 

874 :param statements: List of all concurrent statements in this construct. 

875 :param documentation: The documentation comment associated with this declaration. 

876 :param allowBlackbox: Allow blackboxes for components in language entity. 

877 :param parent: The parent model entity of this entity. 

878 """ 

879 super().__init__(identifier, contextItems, documentation, parent) 

880 DesignUnitWithContextMixin.__init__(self) 

881 ConcurrentDeclarationRegionMixin.__init__(self, declaredItems) 

882 ConcurrentStatementsMixin.__init__(self, statements) 

883 AllowBlackboxMixin.__init__(self, allowBlackbox) 

884 

885 self._entity = entity 

886 entity.Parent = self 

887 

888 @readonly 

889 def Entity(self) -> EntitySymbol: # FIXME: change to entitySymbol, offer entity directly, but raise exception if not resolved. 

890 """ 

891 Read-only property to access the entity (:attr:`_entity`). 

892 

893 :returns: The entity. 

894 """ 

895 return self._entity 

896 

897 def __str__(self) -> str: 

898 """ 

899 Formats the architecture declaration. 

900 

901 **Format:** ``Architecture: mylib.myEntity(rtl)`` 

902 

903 :returns: Formatted architecture declaration. 

904 """ 

905 lib = self._parent._identifier if self._parent is not None else "?" 

906 ent = self._entity._name._identifier if self._entity is not None else "?" 

907 

908 return f"Architecture: {lib}.{ent}({self._identifier})" 

909 

910 def __repr__(self) -> str: 

911 """ 

912 Formats a representation of the architecture declaration. 

913 

914 **Format:** ``mylib.myEntity(rtl)`` 

915 

916 :returns: String representation of the architecture declaration. 

917 """ 

918 lib = self._parent._identifier if self._parent is not None else "?" 

919 ent = self._entity._name._identifier if self._entity is not None else "?" 

920 

921 return f"{lib}.{ent}({self._identifier})" 

922 

923 

924@export 

925class Component(ModelEntity, NamedEntityMixin, DocumentedEntityMixin, AllowBlackboxMixin): 

926 """ 

927 Represents a component declaration. 

928 

929 .. admonition:: Example 

930 

931 .. code-block:: VHDL 

932 

933 component ent is 

934 -- ... 

935 end component; 

936 

937 .. seealso:: 

938 

939 * :class:`Entity it may be bound to <pyVHDLModel.DesignUnit.Entity>` 

940 * :class:`Component configuration <pyVHDLModel.Configuration.ComponentConfiguration>` 

941 """ 

942 

943 _isBlackbox: Nullable[bool] #: Component is a blackbox. 

944 

945 _genericItems: List[GenericInterfaceItemMixin] #: List of all generics of this component, in declaration order. 

946 _portItems: List[PortInterfaceItemMixin] #: List of all ports of this component, in declaration order. 

947 

948 _entity: Nullable[Entity] #: Linked entity, or ``None`` if unresolved. 

949 

950 def __init__( 

951 self, 

952 identifier: str, 

953 genericItems: Nullable[Iterable[GenericInterfaceItemMixin]] = None, 

954 portItems: Nullable[Iterable[PortInterfaceItemMixin]] = None, 

955 documentation: Nullable[str] = None, 

956 allowBlackbox: Nullable[bool] = None, 

957 parent: Nullable[ModelEntity] = None 

958 ) -> None: 

959 """ 

960 Initializes a component declaration. 

961 

962 :param identifier: The identifier of a model entity. 

963 :param genericItems: List of all generics of this component, in declaration order. 

964 :param portItems: List of all ports of this component, in declaration order. 

965 :param documentation: The documentation comment associated with this declaration. 

966 :param allowBlackbox: Allow blackboxes for components in language entity. 

967 :param parent: The parent model entity of this entity. 

968 """ 

969 super().__init__(parent) 

970 NamedEntityMixin.__init__(self, identifier) 

971 DocumentedEntityMixin.__init__(self, documentation) 

972 AllowBlackboxMixin.__init__(self, allowBlackbox) 

973 

974 self._isBlackbox = None 

975 self._entity = None 

976 

977 # TODO: extract to mixin 

978 self._genericItems = [] 

979 if genericItems is not None: 

980 for item in genericItems: 

981 self._genericItems.append(item) 

982 item.Parent = self 

983 

984 # TODO: extract to mixin 

985 self._portItems = [] 

986 if portItems is not None: 

987 for item in portItems: 

988 self._portItems.append(item) 

989 item.Parent = self 

990 

991 @readonly 

992 def IsBlackbox(self) -> Nullable[bool]: 

993 """ 

994 Check if the component is a blackbox (:attr:`_isBlackbox`). 

995 

996 If components were not linked to matching entities, this property returns ``None``. 

997 

998 :returns: ``True``, if the component is a blackbox; ``False``, if it is not; ``None``, if components 

999 were not linked to entities yet. 

1000 """ 

1001 return self._isBlackbox 

1002 

1003 @readonly 

1004 def GenericItems(self) -> List[GenericInterfaceItemMixin]: 

1005 """ 

1006 Read-only property to access the generic items (:attr:`_genericItems`). 

1007 

1008 :returns: List of generic items. 

1009 """ 

1010 return self._genericItems 

1011 

1012 @readonly 

1013 def PortItems(self) -> List[PortInterfaceItemMixin]: 

1014 """ 

1015 Read-only property to access the port items (:attr:`_portItems`). 

1016 

1017 :returns: List of port items. 

1018 """ 

1019 return self._portItems 

1020 

1021 @property 

1022 def Entity(self) -> Nullable[Entity]: 

1023 """ 

1024 Property to access the entity (:attr:`_entity`). 

1025 

1026 :returns: The entity, or ``None`` if not set. 

1027 """ 

1028 return self._entity 

1029 

1030 @Entity.setter 

1031 def Entity(self, value: Entity) -> None: 

1032 self._entity = value 

1033 self._isBlackbox = False 

1034 

1035 def __str__(self) -> str: 

1036 """ 

1037 Formats the component declaration. 

1038 

1039 **Format:** ``Component: myComponent`` 

1040 

1041 :returns: Formatted component declaration. 

1042 """ 

1043 return f"Component: {self._identifier}" 

1044 

1045 def __repr__(self) -> str: 

1046 """ 

1047 Formats a representation of the component declaration. 

1048 

1049 **Format:** ``mylib.myPackage:myComponent`` 

1050 

1051 :returns: String representation of the component declaration. 

1052 """ 

1053 return f"{self._parent!r}:{self._identifier}" 

1054 

1055 

1056@export 

1057class Configuration(PrimaryUnit, DesignUnitWithContextMixin): 

1058 """ 

1059 Represents a configuration declaration. 

1060 

1061 .. admonition:: Example 

1062 

1063 .. code-block:: VHDL 

1064 

1065 configuration cfg of ent is 

1066 for rtl 

1067 -- ... 

1068 end for; 

1069 end configuration; 

1070 

1071 .. seealso:: 

1072 

1073 * :class:`Entity it configures <pyVHDLModel.DesignUnit.Entity>` 

1074 * :class:`Block configuration <pyVHDLModel.Configuration.BlockConfiguration>` 

1075 """ 

1076 

1077 _entity: EntitySymbol #: Reference to the entity this configuration configures. 

1078 _blockConfiguration: BlockConfiguration #: The configuration of the entity's architecture. 

1079 

1080 def __init__( 

1081 self, 

1082 identifier: str, 

1083 entity: EntitySymbol, 

1084 blockConfiguration: BlockConfiguration, 

1085 contextItems: Nullable[Iterable[Context]] = None, 

1086 documentation: Nullable[str] = None, 

1087 parent: Nullable[ModelEntity] = None 

1088 ) -> None: 

1089 """ 

1090 Initializes a configuration declaration. 

1091 

1092 :param identifier: The identifier of a model entity. 

1093 :param entity: Reference to the entity this configuration configures. 

1094 :param blockConfiguration: The configuration of the entity's architecture. 

1095 :param contextItems: List of all context items (library, use and context clauses). 

1096 :param documentation: The documentation comment associated with this declaration. 

1097 :param parent: The parent model entity of this entity. 

1098 """ 

1099 super().__init__(identifier, contextItems, documentation, parent) 

1100 DesignUnitWithContextMixin.__init__(self) 

1101 

1102 self._entity = entity 

1103 entity.Parent = self 

1104 

1105 self._blockConfiguration = blockConfiguration 

1106 blockConfiguration.Parent = self 

1107 

1108 @readonly 

1109 def Entity(self) -> EntitySymbol: 

1110 """ 

1111 Read-only property to access the entity (:attr:`_entity`). 

1112 

1113 :returns: The entity. 

1114 """ 

1115 return self._entity 

1116 

1117 @readonly 

1118 def BlockConfiguration(self) -> BlockConfiguration: 

1119 """ 

1120 Read-only property to access the block configuration (:attr:`_blockConfiguration`). 

1121 

1122 :returns: The block configuration. 

1123 """ 

1124 return self._blockConfiguration 

1125 

1126 def __str__(self) -> str: 

1127 """ 

1128 Formats the configuration declaration. 

1129 

1130 **Format:** ``Configuration: mylib.myConfiguration`` 

1131 

1132 :returns: Formatted configuration declaration. 

1133 """ 

1134 lib = self._parent._identifier if self._parent is not None else "?" 

1135 

1136 return f"Configuration: {lib}.{self._identifier}" 

1137 

1138 def __repr__(self) -> str: 

1139 """ 

1140 Formats a representation of the configuration declaration. 

1141 

1142 **Format:** ``mylib.myConfiguration`` 

1143 

1144 :returns: String representation of the configuration declaration. 

1145 """ 

1146 lib = self._parent._identifier if self._parent is not None else "?" 

1147 

1148 return f"{lib}.{self._identifier}"