Coverage for pyVHDLModel/DesignUnit.py: 94%

469 statements  

« prev     ^ index     » next       coverage.py v7.17.0, created at 2026-10-25 10:05 +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 __future__ import annotations 

38 

39from typing import TYPE_CHECKING, ClassVar, Union, Iterable, Optional as Nullable 

40 

41from pyTooling.Common import getFullyQualifiedName, getTypeName 

42from pyTooling.Decorators import export, readonly 

43from pyTooling.MetaClasses import ExtendedType, abstractmethod, abstractclass 

44from pyTooling.Graph import Vertex 

45 

46from pyVHDLModel.Common import AllowBlackboxMixin 

47from pyVHDLModel.Exception import VHDLModelException, AlreadyInDesignError, NotAChildError 

48from pyVHDLModel.Base import ModelEntity, NamedEntityMixin, MultipleNamedEntityMixin, DocumentedEntityMixin, \ 

49 normalizedIdentifiersOf 

50from pyVHDLModel.Namespace import Namespace 

51from pyVHDLModel.Regions import ConcurrentDeclarationRegionMixin, WithGenericsMixin, WithPortsMixin, \ 

52 WithoutStatementsMixin 

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

54from pyVHDLModel.Interface import GenericInterfaceItemMixin, PortInterfaceItemMixin 

55from pyVHDLModel.Object import DeferredConstant 

56from pyVHDLModel.Concurrent import ConcurrentStatement, ConcurrentStatementsMixin 

57from pyVHDLModel.Configuration import BlockConfiguration 

58 

59if TYPE_CHECKING: 59 ↛ 60line 59 didn't jump to line 60 because the condition on line 59 was never true

60 from pyVHDLModel.Visitor import Visitor 

61 

62 

63@export 

64@abstractclass 

65class Reference(ModelEntity): 

66 """ 

67 A base-class for all references. 

68 

69 .. seealso:: 

70 

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

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

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

74 """ 

75 

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

77 

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

79 """ 

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

81 

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

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

84 """ 

85 super().__init__(parent) 

86 

87 self._symbols = list(symbols) 

88 

89 @readonly 

90 def Symbols(self) -> list[Symbol]: 

91 """ 

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

93 

94 :returns: A list of symbols. 

95 """ 

96 return self._symbols 

97 

98 def _VisitSymbols(self, visitor: Visitor) -> None: 

99 """ 

100 Walk the referenced symbols, separated by commas, with a visitor. 

101 

102 :param visitor: The visitor receiving the events. 

103 """ 

104 for index, symbol in enumerate(self._symbols): 

105 if index > 0: 

106 visitor.VisitComma(self) 

107 

108 symbol.Visit(visitor) 

109 

110 

111@export 

112class LibraryClause(Reference): 

113 """ 

114 Represents a library clause. 

115 

116 .. admonition:: Example 

117 

118 .. code-block:: VHDL 

119 

120 library std, ieee; 

121 """ 

122 

123 @readonly 

124 def Symbols(self) -> list[LibraryReferenceSymbol]: 

125 """ 

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

127 

128 :returns: A list of library reference symbols. 

129 """ 

130 return self._symbols 

131 

132 def Visit(self, visitor: Visitor) -> None: 

133 """ 

134 Walk this library clause and its library names with a visitor. 

135 

136 :param visitor: The visitor receiving the events. 

137 """ 

138 visitor.VisitLibraryClause(self) 

139 self._VisitSymbols(visitor) 

140 visitor.DepartLibraryClause(self) 

141 

142 

143@export 

144class UseClause(Reference): 

145 """ 

146 Represents a use clause. 

147 

148 .. admonition:: Example 

149 

150 .. code-block:: VHDL 

151 

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

153 """ 

154 

155 def Visit(self, visitor: Visitor) -> None: 

156 """ 

157 Walk this use clause and its selected names with a visitor. 

158 

159 :param visitor: The visitor receiving the events. 

160 """ 

161 visitor.VisitUseClause(self) 

162 self._VisitSymbols(visitor) 

163 visitor.DepartUseClause(self) 

164 

165 

166@export 

167class ContextReference(Reference): 

168 """ 

169 Represents a context reference. 

170 

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

172 

173 .. admonition:: Example 

174 

175 .. code-block:: VHDL 

176 

177 context ieee.ieee_std_context; 

178 """ 

179 

180 def Visit(self, visitor: Visitor) -> None: 

181 """ 

182 Walk this context reference and its context names with a visitor. 

183 

184 :param visitor: The visitor receiving the events. 

185 """ 

186 visitor.VisitContextReference(self) 

187 self._VisitSymbols(visitor) 

188 visitor.DepartContextReference(self) 

189 

190 

191ContextUnion = Union[ 

192 LibraryClause, 

193 UseClause, 

194 ContextReference 

195] 

196 

197 

198@export 

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

200 """ 

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

202 

203 .. seealso:: 

204 

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

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

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

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

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

210 """ 

211 

212 

213@export 

214@abstractclass 

215class DesignUnit(ModelEntity, NamedEntityMixin, DocumentedEntityMixin): 

216 """ 

217 A base-class for all design units. 

218 

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

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

221 

222 .. seealso:: 

223 

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

225 

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

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

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

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

230 

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

232 

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

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

235 """ 

236 

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

238 

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

240 

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

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

243 _libraryReferences: list[LibraryClause] #: List of library clauses. 

244 _packageReferences: list[UseClause] #: List of use clauses. 

245 _contextReferences: list[ContextReference] #: List of context clauses. 

246 

247 _referencedLibraries: dict[str, Library] #: Referenced libraries based on explicit library clauses or implicit inheritance 

248 _referencedPackages: dict[str, dict[str, Package]] #: Referenced packages based on explicit use clauses or implicit inheritance 

249 _referencedContexts: dict[str, Context] #: Referenced contexts based on explicit context references or implicit inheritance 

250 

251 _dependencyVertex: Vertex #: Reference to the vertex in the dependency graph representing the design unit. |br| This reference is set by :meth:`~pyVHDLModel.Design.CreateDependencyGraph`. 

252 _hierarchyVertex: Vertex #: The vertex in the hierarchy graph 

253 

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

255 """ 

256 Initializes a design unit. 

257 

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

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

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

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

262 """ 

263 super().__init__(parent) 

264 NamedEntityMixin.__init__(self, identifier) 

265 DocumentedEntityMixin.__init__(self, documentation) 

266 

267 self._document = None 

268 

269 self._contextItems = contextItemList = [] 

270 self._libraryReferences = libraryReferences = [] 

271 self._packageReferences = packageReferences = [] 

272 self._contextReferences = contextReferences = [] 

273 

274 if contextItems is not None: 

275 for item in contextItems: 

276 contextItemList.append(item) 

277 item.Parent = self 

278 if isinstance(item, UseClause): 

279 packageReferences.append(item) 

280 elif isinstance(item, LibraryClause): 

281 libraryReferences.append(item) 

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

283 contextReferences.append(item) 

284 

285 self._referencedLibraries = {} 

286 self._referencedPackages = {} 

287 self._referencedContexts = {} 

288 

289 self._dependencyVertex = None 

290 self._hierarchyVertex = None 

291 

292 @property 

293 def Document(self) -> Document: 

294 """ 

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

296 

297 :returns: The document. 

298 """ 

299 return self._document 

300 

301 @Document.setter 

302 def Document(self, document: Document) -> None: 

303 self._document = document 

304 

305 @property 

306 def Library(self) -> Library: 

307 """ 

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

309 

310 :returns: The library. 

311 """ 

312 return self._parent 

313 

314 @Library.setter 

315 def Library(self, library: Library) -> None: 

316 self._parent = library 

317 

318 @readonly 

319 def ContextItems(self) -> list[ContextUnion]: 

320 """ 

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

322 (:attr:`_contextItems`). 

323 

324 :returns: Sequence of context items. 

325 """ 

326 return self._contextItems 

327 

328 @readonly 

329 def ContextReferences(self) -> list[ContextReference]: 

330 """ 

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

332 

333 :returns: Sequence of context clauses. 

334 """ 

335 return self._contextReferences 

336 

337 @readonly 

338 def LibraryReferences(self) -> list[LibraryClause]: 

339 """ 

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

341 

342 :returns: Sequence of library clauses. 

343 """ 

344 return self._libraryReferences 

345 

346 def _VisitContextClause(self, visitor: Visitor) -> None: 

347 """ 

348 Walk the context clause, i.e. the context items preceding the design unit, with a visitor. 

349 

350 The context clause is reported, even if it has no context items. 

351 

352 :param visitor: The visitor receiving the events. 

353 """ 

354 visitor.VisitContextClause(self) 

355 for item in self._contextItems: 

356 item.Visit(visitor) 

357 

358 visitor.DepartContextClause(self) 

359 

360 @readonly 

361 def PackageReferences(self) -> list[UseClause]: 

362 """ 

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

364 

365 :returns: Sequence of use clauses. 

366 """ 

367 return self._packageReferences 

368 

369 def AddContextItem(self, contextItem: ContextUnion) -> None: 

370 """ 

371 Add a context item at the end of the context clause. 

372 

373 The context item's parent is set to this design unit. A library clause is also added to :data:`LibraryReferences`, a 

374 use clause to :data:`PackageReferences` and a context reference to :data:`ContextReferences`, in the order of 

375 :data:`ContextItems`. A context item may repeat an earlier one. 

376 

377 :param contextItem: The library clause, use clause or context reference to add. 

378 :raises ValueError: If parameter 'contextItem' is ``None``. 

379 :raises TypeError: If parameter 'contextItem' is not of type :class:`LibraryClause`, :class:`UseClause` 

380 or :class:`ContextReference`. 

381 :raises AlreadyInDesignError: If parameter 'contextItem' already has a parent. 

382 

383 .. attention:: 

384 

385 The mutator doesn't update what :meth:`~pyVHDLModel.Design.Analyze` derived from the context items: the 

386 referenced libraries, packages and contexts (:data:`ReferencedLibraries`, :data:`ReferencedPackages`, 

387 :data:`ReferencedContexts`), the namespace entries of a use clause, the edges of the dependency graph, and the 

388 references of the symbols. A design changed after its analysis needs a new analysis. 

389 

390 .. seealso:: 

391 

392 :meth:`InsertContextItem` 

393 |rarr| Insert a context item at a position of the context clause. 

394 :meth:`RemoveContextItem` 

395 |rarr| Remove a context item from the context clause. 

396 """ 

397 self.InsertContextItem(len(self._contextItems), contextItem) 

398 

399 def InsertContextItem(self, index: int, contextItem: ContextUnion) -> None: 

400 """ 

401 Insert a context item at a position of the context clause. 

402 

403 The context item's parent is set to this design unit. A library clause is also added to :data:`LibraryReferences`, a 

404 use clause to :data:`PackageReferences` and a context reference to :data:`ContextReferences`, in the order of 

405 :data:`ContextItems`. A context item may repeat an earlier one. 

406 

407 :param index: Position, from ``0`` (first) to the number of context items (append). A negative index 

408 counts from the end, as for :meth:`list.insert`: ``-1`` inserts before the last 

409 context item. 

410 :param contextItem: The library clause, use clause or context reference to insert. 

411 :raises ValueError: If parameter 'index' is ``None``. 

412 :raises TypeError: If parameter 'index' is not of type :class:`int`. 

413 :raises ValueError: If parameter 'index' is out of range. 

414 :raises ValueError: If parameter 'contextItem' is ``None``. 

415 :raises TypeError: If parameter 'contextItem' is not of type :class:`LibraryClause`, :class:`UseClause` 

416 or :class:`ContextReference`. 

417 :raises AlreadyInDesignError: If parameter 'contextItem' already has a parent. 

418 

419 .. attention:: 

420 

421 The mutator doesn't update what :meth:`~pyVHDLModel.Design.Analyze` derived from the context items: the 

422 referenced libraries, packages and contexts (:data:`ReferencedLibraries`, :data:`ReferencedPackages`, 

423 :data:`ReferencedContexts`), the namespace entries of a use clause, the edges of the dependency graph, and the 

424 references of the symbols. A design changed after its analysis needs a new analysis. 

425 

426 .. seealso:: 

427 

428 :meth:`AddContextItem` 

429 |rarr| Add a context item at the end of the context clause. 

430 :meth:`RemoveContextItem` 

431 |rarr| Remove a context item from the context clause. 

432 """ 

433 count = len(self._contextItems) 

434 if index is None: 

435 raise ValueError("Parameter 'index' is None.") 

436 elif not isinstance(index, int): 

437 ex = TypeError("Parameter 'index' is not of type 'int'.") 

438 ex.add_note(f"Got type '{getFullyQualifiedName(index)}'.") 

439 raise ex 

440 elif not (-count <= index <= count): 

441 ex = ValueError(f"Parameter 'index' is out of range {-count}..{count}.") 

442 ex.add_note(f"Got value '{index}'.") 

443 raise ex 

444 

445 if contextItem is None: 

446 raise ValueError("Parameter 'contextItem' is None.") 

447 elif not isinstance(contextItem, (LibraryClause, UseClause, ContextReference)): 

448 ex = TypeError("Parameter 'contextItem' is not of type 'LibraryClause', 'UseClause' or 'ContextReference'.") 

449 ex.add_note(f"Got type '{getFullyQualifiedName(contextItem)}'.") 

450 raise ex 

451 elif contextItem._parent is not None: 

452 ex = AlreadyInDesignError( 

453 f"{getTypeName(contextItem)} already has a parent.", 

454 element=contextItem, 

455 parent=contextItem._parent 

456 ) 

457 ex.add_note(f"Remove it from its {getTypeName(contextItem._parent)} first.") 

458 raise ex 

459 

460 if isinstance(contextItem, LibraryClause): 

461 references = self._libraryReferences 

462 referenceType = LibraryClause 

463 elif isinstance(contextItem, UseClause): 

464 references = self._packageReferences 

465 referenceType = UseClause 

466 else: 

467 references = self._contextReferences 

468 referenceType = ContextReference 

469 

470 position = index if index >= 0 else count + index 

471 referenceIndex = sum(1 for item in self._contextItems[:position] if isinstance(item, referenceType)) 

472 

473 self._contextItems.insert(position, contextItem) 

474 references.insert(referenceIndex, contextItem) 

475 contextItem.Parent = self 

476 

477 def RemoveContextItem(self, contextItem: ContextUnion) -> None: 

478 """ 

479 Remove a context item from the context clause. 

480 

481 The context item is detached: its parent is cleared, and it's removed from :data:`ContextItems` and from 

482 :data:`LibraryReferences`, :data:`PackageReferences` or :data:`ContextReferences`. The context item itself is 

483 unchanged and can be added to another design unit, or inserted at another position. 

484 

485 :param contextItem: The library clause, use clause or context reference to remove. 

486 :raises ValueError: If parameter 'contextItem' is ``None``. 

487 :raises TypeError: If parameter 'contextItem' is not of type :class:`LibraryClause`, :class:`UseClause` or 

488 :class:`ContextReference`. 

489 :raises NotAChildError: If parameter 'contextItem' is not a context item of this design unit. 

490 

491 .. attention:: 

492 

493 The mutator doesn't update what :meth:`~pyVHDLModel.Design.Analyze` derived from the context items: the 

494 referenced libraries, packages and contexts (:data:`ReferencedLibraries`, :data:`ReferencedPackages`, 

495 :data:`ReferencedContexts`), the namespace entries of a use clause, the edges of the dependency graph, and the 

496 references of the symbols. A design changed after its analysis needs a new analysis. 

497 

498 .. seealso:: 

499 

500 :meth:`AddContextItem` 

501 |rarr| Add a context item at the end of the context clause. 

502 :meth:`InsertContextItem` 

503 |rarr| Insert a context item at a position of the context clause. 

504 """ 

505 if contextItem is None: 

506 raise ValueError("Parameter 'contextItem' is None.") 

507 elif not isinstance(contextItem, (LibraryClause, UseClause, ContextReference)): 

508 ex = TypeError("Parameter 'contextItem' is not of type 'LibraryClause', 'UseClause' or 'ContextReference'.") 

509 ex.add_note(f"Got type '{getFullyQualifiedName(contextItem)}'.") 

510 raise ex 

511 

512 for index, item in enumerate(self._contextItems): 

513 if item is contextItem: 

514 break 

515 else: 

516 raise NotAChildError( 

517 f"{getTypeName(contextItem)} is not a context item of this {getTypeName(self)}.", 

518 element=contextItem, 

519 parent=self 

520 ) 

521 

522 if isinstance(contextItem, LibraryClause): 

523 references = self._libraryReferences 

524 elif isinstance(contextItem, UseClause): 524 ↛ 527line 524 didn't jump to line 527 because the condition on line 524 was always true

525 references = self._packageReferences 

526 else: 

527 references = self._contextReferences 

528 

529 del self._contextItems[index] 

530 references.remove(contextItem) 

531 contextItem._parent = None 

532 

533 @readonly 

534 def ReferencedLibraries(self) -> dict[str, Library]: 

535 """ 

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

537 

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

539 """ 

540 return self._referencedLibraries 

541 

542 @readonly 

543 def ReferencedPackages(self) -> dict[str, Package]: 

544 """ 

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

546 

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

548 """ 

549 return self._referencedPackages 

550 

551 @readonly 

552 def ReferencedContexts(self) -> dict[str, Context]: 

553 """ 

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

555 

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

557 """ 

558 return self._referencedContexts 

559 

560 @readonly 

561 def DependencyVertex(self) -> Vertex: 

562 """ 

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

564 

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

566 

567 :returns: The corresponding dependency vertex. 

568 """ 

569 return self._dependencyVertex 

570 

571 @readonly 

572 def HierarchyVertex(self) -> Vertex: 

573 """ 

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

575 

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

577 

578 :returns: The corresponding hierarchy vertex. 

579 """ 

580 return self._hierarchyVertex 

581 

582 @abstractmethod 

583 def __str__(self) -> str: 

584 """ 

585 Formats the design unit. 

586 

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

588 

589 :returns: Formatted design unit. 

590 """ 

591 

592 

593@export 

594@abstractclass 

595class PrimaryUnit(DesignUnit): 

596 """ 

597 A base-class for all primary design units. 

598 

599 .. seealso:: 

600 

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

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

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

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

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

606 """ 

607 

608 

609@export 

610@abstractclass 

611class SecondaryUnit(DesignUnit): 

612 """ 

613 A base-class for all secondary design units. 

614 

615 .. seealso:: 

616 

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

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

619 """ 

620 

621 

622@export 

623class Context(PrimaryUnit): 

624 """ 

625 Represents a context declaration. 

626 

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

628 :data:`_contextItems`. 

629 

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

631 

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

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

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

635 

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

637 

638 * :data:`_referencedLibraries` (:pycode:`dict[libName, Library]`) 

639 * :data:`_referencedPackages` (:pycode:`dict[libName, [pkgName, Package]]`) 

640 * :data:`_referencedContexts` (:pycode:`dict[libName, [ctxName, Context]]`) 

641 

642 are populated. 

643 

644 .. admonition:: Example 

645 

646 .. code-block:: VHDL 

647 

648 context ctx is 

649 -- ... 

650 end context; 

651 

652 .. seealso:: 

653 

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

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

656 """ 

657 

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

659 """ 

660 Initializes a context declaration. 

661 

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

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

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

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

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

667 """ 

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

669 

670 if references is not None: 

671 for reference in references: 

672 self._contextItems.append(reference) 

673 reference.Parent = self 

674 

675 if isinstance(reference, LibraryClause): 

676 self._libraryReferences.append(reference) 

677 elif isinstance(reference, UseClause): 

678 self._packageReferences.append(reference) 

679 elif isinstance(reference, ContextReference): 

680 self._contextReferences.append(reference) 

681 else: 

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

683 

684 @readonly 

685 def LibraryReferences(self) -> list[LibraryClause]: 

686 """ 

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

688 

689 :returns: List of library references. 

690 """ 

691 return self._libraryReferences 

692 

693 @readonly 

694 def PackageReferences(self) -> list[UseClause]: 

695 """ 

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

697 

698 :returns: List of package references. 

699 """ 

700 return self._packageReferences 

701 

702 @readonly 

703 def ContextReferences(self) -> list[ContextReference]: 

704 """ 

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

706 

707 :returns: List of context references. 

708 """ 

709 return self._contextReferences 

710 

711 def Visit(self, visitor: Visitor) -> None: 

712 """ 

713 Walk this context declaration and its context items with a visitor. 

714 

715 A context declaration has no context clause: its context items are walked inside the declaration. 

716 

717 :param visitor: The visitor receiving the events. 

718 """ 

719 visitor.VisitContext(self) 

720 for item in self._contextItems: 

721 item.Visit(visitor) 

722 

723 visitor.DepartContext(self) 

724 

725 def __str__(self) -> str: 

726 """ 

727 Formats the context declaration. 

728 

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

730 

731 :returns: Formatted context declaration. 

732 """ 

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

734 

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

736 

737 

738@export 

739class Package( 

740 PrimaryUnit, 

741 DesignUnitWithContextMixin, 

742 WithGenericsMixin, 

743 ConcurrentDeclarationRegionMixin, 

744 WithoutStatementsMixin, 

745 AllowBlackboxMixin 

746): 

747 """ 

748 Represents a package declaration. 

749 

750 .. admonition:: Example 

751 

752 .. code-block:: VHDL 

753 

754 package pkg is 

755 -- ... 

756 end package; 

757 

758 .. seealso:: 

759 

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

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

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

763 """ 

764 

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

766 

767 _deferredConstants: dict[str, DeferredConstant] #: Deferred constants, indexed by name. 

768 

769 def __init__( 

770 self, 

771 identifier: str, 

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

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

774 declaredItems: Nullable[Iterable] = None, 

775 documentation: Nullable[str] = None, 

776 allowBlackbox: Nullable[bool] = None, 

777 parent: Nullable[ModelEntity] = None 

778 ) -> None: 

779 """ 

780 Initialize a package. 

781 

782 :param identifier: Name of the VHDL package. 

783 :param contextItems: 

784 :param genericItems: 

785 :param declaredItems: 

786 :param documentation: 

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

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

789 """ 

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

791 DesignUnitWithContextMixin.__init__(self) 

792 ConcurrentDeclarationRegionMixin.__init__( 

793 self, self._normalizedIdentifier, declaredItems, self._CONTINUES_PARENT_REGION 

794 ) 

795 WithGenericsMixin.__init__(self, genericItems) 

796 AllowBlackboxMixin.__init__(self, allowBlackbox) 

797 

798 self._packageBody = None 

799 

800 self._deferredConstants = {} 

801 self._components = {} 

802 

803 @readonly 

804 def PackageBody(self) -> Nullable[PackageBody]: 

805 """ 

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

807 

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

809 """ 

810 return self._packageBody 

811 

812 @readonly 

813 def DeclaredItems(self) -> list: 

814 """ 

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

816 

817 :returns: List of declared items. 

818 """ 

819 return self._declaredItems 

820 

821 @readonly 

822 def DeferredConstants(self) -> dict[str, DeferredConstant]: 

823 """ 

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

825 

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

827 """ 

828 return self._deferredConstants 

829 

830 @readonly 

831 def Components(self) -> dict[str, Component]: 

832 """ 

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

834 

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

836 """ 

837 return self._components 

838 

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

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

841 for normalizedIdentifier in item.NormalizedIdentifiers: 

842 self._deferredConstants[normalizedIdentifier] = item 

843 elif isinstance(item, Component): 

844 self._components[item._normalizedIdentifier] = item 

845 else: 

846 super()._IndexOtherDeclaredItem(item) 

847 

848 def _UnindexOtherDeclaredItem(self, item: ModelEntity) -> None: 

849 """ 

850 Remove a declared item, which a concurrent declaration region doesn't handle itself. 

851 

852 A deferred constant is removed from :attr:`_deferredConstants`. An entry referring to another deferred constant of 

853 the same identifier (a duplicate declaration) is kept: :meth:`RemoveDeclaredItem` indexes the region again. 

854 

855 :param item: The declared item. 

856 """ 

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

858 for normalizedIdentifier in item._normalizedIdentifiers: 

859 if self._deferredConstants.get(normalizedIdentifier) is item: 859 ↛ 858line 859 didn't jump to line 858 because the condition on line 859 was always true

860 del self._deferredConstants[normalizedIdentifier] 

861 else: 

862 super()._UnindexOtherDeclaredItem(item) 

863 

864 def _SharedRegions(self) -> tuple[ConcurrentDeclarationRegionMixin, ...]: 

865 """ 

866 Return the other language constructs forming one declarative region with this package. 

867 

868 :returns: Tuple of the package body, if linked (:attr:`_packageBody`). 

869 """ 

870 return () if self._packageBody is None else (self._packageBody, ) 

871 

872 def Visit(self, visitor: Visitor) -> None: 

873 """ 

874 Walk this package declaration, its context clause, its generic clause and its declared items with a visitor. 

875 

876 :param visitor: The visitor receiving the events. 

877 """ 

878 self._VisitContextClause(visitor) 

879 visitor.VisitPackage(self) 

880 self._VisitGenericClause(visitor) 

881 self._VisitDeclaredItems(visitor) 

882 visitor.DepartPackage(self) 

883 

884 def __str__(self) -> str: 

885 """ 

886 Formats the package declaration. 

887 

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

889 

890 :returns: Formatted package declaration. 

891 """ 

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

893 

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

895 

896 def __repr__(self) -> str: 

897 """ 

898 Formats a representation of the package declaration. 

899 

900 **Format:** ``mylib.myPackage`` 

901 

902 :returns: String representation of the package declaration. 

903 """ 

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

905 

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

907 

908 

909 def IndexDeclaredItems(self) -> None: 

910 """ 

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

912 

913 :raises UnhandledCriticalWarningError: If an identifier is declared twice in a declarative region and no 

914 :class:`~pyTooling.Warning.WarningCollector` collects the 

915 :exc:`~pyVHDLModel.Exception.DuplicateDeclarationWarning`. 

916 """ 

917 self._deferredConstants.clear() 

918 self._IndexGenericItems() 

919 

920 super().IndexDeclaredItems() 

921 

922 def _Declarations(self) -> tuple[ModelEntity, ...]: 

923 """ 

924 Return all declarations of this package: its generics share the declarative region. 

925 

926 :returns: Tuple of declarations: the generics, then the declared items. 

927 """ 

928 return (*self._genericItems, *super()._Declarations()) 

929 

930 

931@export 

932class PackageBody(SecondaryUnit, DesignUnitWithContextMixin, ConcurrentDeclarationRegionMixin, WithoutStatementsMixin): 

933 """ 

934 Represents a package body declaration. 

935 

936 .. admonition:: Example 

937 

938 .. code-block:: VHDL 

939 

940 package body pkg is 

941 -- ... 

942 end package body; 

943 

944 .. seealso:: 

945 

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

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

948 """ 

949 

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

951 

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

953 

954 def __init__( 

955 self, 

956 packageSymbol: PackageSymbol, 

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

958 declaredItems: Nullable[Iterable] = None, 

959 documentation: Nullable[str] = None, 

960 parent: Nullable[ModelEntity] = None 

961 ) -> None: 

962 """ 

963 Initializes a package body declaration. 

964 

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

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

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

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

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

970 """ 

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

972 DesignUnitWithContextMixin.__init__(self) 

973 ConcurrentDeclarationRegionMixin.__init__( 

974 self, self._normalizedIdentifier, declaredItems, self._CONTINUES_PARENT_REGION 

975 ) 

976 

977 self._package = packageSymbol 

978 packageSymbol.Parent = self 

979 

980 @readonly 

981 def Package(self) -> PackageSymbol: 

982 """ 

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

984 

985 :returns: The package. 

986 """ 

987 return self._package 

988 

989 @readonly 

990 def DeclaredItems(self) -> list: 

991 """ 

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

993 

994 :returns: List of declared items. 

995 """ 

996 return self._declaredItems 

997 

998 def LinkDeclaredItemsToPackage(self) -> None: 

999 pass 

1000 

1001 def _SharedRegions(self) -> tuple[ConcurrentDeclarationRegionMixin, ...]: 

1002 """ 

1003 Return the other language constructs forming one declarative region with this package body. 

1004 

1005 :returns: Tuple of the package, if linked. 

1006 """ 

1007 package = self._package.Package 

1008 return () if package is None else (package, ) 

1009 

1010 def Visit(self, visitor: Visitor) -> None: 

1011 """ 

1012 Walk this package body, its context clause and its declared items with a visitor. 

1013 

1014 :param visitor: The visitor receiving the events. 

1015 """ 

1016 self._VisitContextClause(visitor) 

1017 visitor.VisitPackageBody(self) 

1018 self._VisitDeclaredItems(visitor) 

1019 visitor.DepartPackageBody(self) 

1020 

1021 def __str__(self) -> str: 

1022 """ 

1023 Formats the package body declaration. 

1024 

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

1026 

1027 :returns: Formatted package body declaration. 

1028 """ 

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

1030 

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

1032 

1033 def __repr__(self) -> str: 

1034 """ 

1035 Formats a representation of the package body declaration. 

1036 

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

1038 

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

1040 """ 

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

1042 

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

1044 

1045 

1046@export 

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

1048 """ 

1049 Represents an entity declaration. 

1050 

1051 .. admonition:: Example 

1052 

1053 .. code-block:: VHDL 

1054 

1055 entity ent is 

1056 -- ... 

1057 end entity; 

1058 

1059 .. seealso:: 

1060 

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

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

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

1064 """ 

1065 

1066 _architectures: dict[str, Architecture] #: Dictionary of all architectures of this entity, indexed by name. 

1067 

1068 def __init__( 

1069 self, 

1070 identifier: str, 

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

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

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

1074 declaredItems: Nullable[Iterable] = None, 

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

1076 documentation: Nullable[str] = None, 

1077 allowBlackbox: Nullable[bool] = None, 

1078 parent: Nullable[ModelEntity] = None 

1079 ) -> None: 

1080 """ 

1081 Initializes an entity declaration. 

1082 

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

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

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

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

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

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

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

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

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

1092 """ 

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

1094 DesignUnitWithContextMixin.__init__(self) 

1095 ConcurrentDeclarationRegionMixin.__init__( 

1096 self, self._normalizedIdentifier, declaredItems, self._CONTINUES_PARENT_REGION 

1097 ) 

1098 WithGenericsMixin.__init__(self, genericItems) 

1099 WithPortsMixin.__init__(self, portItems) 

1100 ConcurrentStatementsMixin.__init__(self, statements) 

1101 AllowBlackboxMixin.__init__(self, allowBlackbox) 

1102 

1103 self._architectures = {} 

1104 

1105 @readonly 

1106 def Architectures(self) -> dict[str, Architecture]: 

1107 """ 

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

1109 

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

1111 """ 

1112 return self._architectures 

1113 

1114 def Visit(self, visitor: Visitor) -> None: 

1115 """ 

1116 Walk this entity, its context clause, its interface, its declared items and its statements with a visitor. 

1117 

1118 :param visitor: The visitor receiving the events. 

1119 """ 

1120 self._VisitContextClause(visitor) 

1121 visitor.VisitEntity(self) 

1122 self._VisitGenericClause(visitor) 

1123 self._VisitPortClause(visitor) 

1124 self._VisitDeclaredItems(visitor) 

1125 visitor.VisitBegin(self) 

1126 self._VisitStatements(visitor) 

1127 visitor.DepartEntity(self) 

1128 

1129 def __str__(self) -> str: 

1130 """ 

1131 Formats the entity declaration. 

1132 

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

1134 

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

1136 

1137 :returns: Formatted entity declaration. 

1138 """ 

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

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

1141 

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

1143 

1144 def __repr__(self) -> str: 

1145 """ 

1146 Formats a representation of the entity declaration. 

1147 

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

1149 

1150 :returns: String representation of the entity declaration. 

1151 """ 

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

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

1154 

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

1156 

1157 

1158 def IndexDeclaredItems(self) -> None: 

1159 """ 

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

1161 

1162 :raises UnhandledCriticalWarningError: If an identifier is declared twice in a declarative region and no 

1163 :class:`~pyTooling.Warning.WarningCollector` collects the 

1164 :exc:`~pyVHDLModel.Exception.DuplicateDeclarationWarning`. 

1165 """ 

1166 self._IndexGenericItems() 

1167 self._IndexPortItems() 

1168 

1169 super().IndexDeclaredItems() 

1170 

1171 def _Declarations(self) -> tuple[ModelEntity, ...]: 

1172 """ 

1173 Return all declarations of this entity: its generics and ports share the declarative region. 

1174 

1175 :returns: Tuple of declarations: the generics, the ports, then the declared items. 

1176 """ 

1177 return (*self._genericItems, *self._portItems, *super()._Declarations()) 

1178 

1179 def _SharedRegions(self) -> tuple[ConcurrentDeclarationRegionMixin, ...]: 

1180 """ 

1181 Return the other language constructs forming one declarative region with this entity. 

1182 

1183 :returns: Tuple of the linked architectures (:attr:`_architectures`). 

1184 """ 

1185 return tuple(self._architectures.values()) 

1186 

1187 

1188@export 

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

1190 """ 

1191 Represents an architecture declaration. 

1192 

1193 .. admonition:: Example 

1194 

1195 .. code-block:: VHDL 

1196 

1197 architecture rtl of ent is 

1198 -- ... 

1199 begin 

1200 -- ... 

1201 end architecture; 

1202 

1203 .. seealso:: 

1204 

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

1206 """ 

1207 

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

1209 

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

1211 

1212 def __init__( 

1213 self, 

1214 identifier: str, 

1215 entity: EntitySymbol, 

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

1217 declaredItems: Nullable[Iterable] = None, 

1218 statements: Iterable[ConcurrentStatement] = None, 

1219 documentation: Nullable[str] = None, 

1220 allowBlackbox: Nullable[bool] = None, 

1221 parent: Nullable[ModelEntity] = None 

1222 ) -> None: 

1223 """ 

1224 Initializes an architecture declaration. 

1225 

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

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

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

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

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

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

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

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

1234 """ 

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

1236 DesignUnitWithContextMixin.__init__(self) 

1237 ConcurrentDeclarationRegionMixin.__init__( 

1238 self, self._normalizedIdentifier, declaredItems, self._CONTINUES_PARENT_REGION 

1239 ) 

1240 ConcurrentStatementsMixin.__init__(self, statements) 

1241 AllowBlackboxMixin.__init__(self, allowBlackbox) 

1242 

1243 self._entity = entity 

1244 entity.Parent = self 

1245 

1246 @readonly 

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

1248 """ 

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

1250 

1251 :returns: The entity. 

1252 """ 

1253 return self._entity 

1254 

1255 def Visit(self, visitor: Visitor) -> None: 

1256 """ 

1257 Walk this architecture, its context clause, its entity, its declared items and its statements with a visitor. 

1258 

1259 :param visitor: The visitor receiving the events. 

1260 """ 

1261 self._VisitContextClause(visitor) 

1262 visitor.VisitArchitecture(self) 

1263 self._entity.Visit(visitor) 

1264 visitor.VisitIs(self) 

1265 self._VisitDeclaredItems(visitor) 

1266 visitor.VisitBegin(self) 

1267 self._VisitStatements(visitor) 

1268 visitor.DepartArchitecture(self) 

1269 

1270 def __str__(self) -> str: 

1271 """ 

1272 Formats the architecture declaration. 

1273 

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

1275 

1276 :returns: Formatted architecture declaration. 

1277 """ 

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

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

1280 

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

1282 

1283 def __repr__(self) -> str: 

1284 """ 

1285 Formats a representation of the architecture declaration. 

1286 

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

1288 

1289 :returns: String representation of the architecture declaration. 

1290 """ 

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

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

1293 

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

1295 

1296 def _SharedRegions(self) -> tuple[ConcurrentDeclarationRegionMixin, ...]: 

1297 """ 

1298 Return the other language constructs forming one declarative region with this architecture. 

1299 

1300 :returns: Tuple of the entity, if linked. 

1301 """ 

1302 entity = self._entity.Entity 

1303 return () if entity is None else (entity, ) 

1304 

1305 

1306@export 

1307class Component( 

1308 ModelEntity, 

1309 NamedEntityMixin, 

1310 DocumentedEntityMixin, 

1311 WithGenericsMixin, 

1312 WithPortsMixin, 

1313 AllowBlackboxMixin 

1314): 

1315 """ 

1316 Represents a component declaration. 

1317 

1318 .. admonition:: Example 

1319 

1320 .. code-block:: VHDL 

1321 

1322 component ent is 

1323 -- ... 

1324 end component; 

1325 

1326 .. seealso:: 

1327 

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

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

1330 """ 

1331 

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

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

1334 

1335 def __init__( 

1336 self, 

1337 identifier: str, 

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

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

1340 documentation: Nullable[str] = None, 

1341 allowBlackbox: Nullable[bool] = None, 

1342 parent: Nullable[ModelEntity] = None 

1343 ) -> None: 

1344 """ 

1345 Initializes a component declaration. 

1346 

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

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

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

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

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

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

1353 """ 

1354 super().__init__(parent) 

1355 NamedEntityMixin.__init__(self, identifier) 

1356 DocumentedEntityMixin.__init__(self, documentation) 

1357 WithGenericsMixin.__init__(self, genericItems) 

1358 WithPortsMixin.__init__(self, portItems) 

1359 AllowBlackboxMixin.__init__(self, allowBlackbox) 

1360 

1361 self._isBlackbox = None 

1362 self._entity = None 

1363 

1364 def Visit(self, visitor: Visitor) -> None: 

1365 """ 

1366 Walk this component declaration, its generic clause and its port clause with a visitor. 

1367 

1368 :param visitor: The visitor receiving the events. 

1369 """ 

1370 visitor.VisitComponent(self) 

1371 self._VisitGenericClause(visitor) 

1372 self._VisitPortClause(visitor) 

1373 visitor.DepartComponent(self) 

1374 

1375 def _AddToNamespace(self, element: NamedEntityMixin | MultipleNamedEntityMixin) -> None: 

1376 """ 

1377 Add nothing, because a component has no namespace. 

1378 

1379 :param element: The named element, e.g. an interface item. 

1380 """ 

1381 

1382 def _RemoveFromNamespace(self, element: NamedEntityMixin | MultipleNamedEntityMixin) -> None: 

1383 """ 

1384 Remove nothing, because a component has no namespace. 

1385 

1386 :param element: The named element, e.g. an interface item. 

1387 """ 

1388 

1389 def _ClashingDeclarations(self, item: NamedEntityMixin | MultipleNamedEntityMixin) -> tuple[ModelEntity, ...]: 

1390 """ 

1391 Return the generics and ports of this component sharing an identifier with the given item. 

1392 

1393 :param item: The new generic or port. 

1394 :returns: Tuple of clashing generics and ports. 

1395 """ 

1396 identifiers = set(normalizedIdentifiersOf(item)) 

1397 return tuple( 

1398 declaration for declaration in (*self._genericItems, *self._portItems) 

1399 if not identifiers.isdisjoint(normalizedIdentifiersOf(declaration)) 

1400 ) 

1401 

1402 @readonly 

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

1404 """ 

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

1406 

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

1408 

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

1410 were not linked to entities yet. 

1411 """ 

1412 return self._isBlackbox 

1413 

1414 @property 

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

1416 """ 

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

1418 

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

1420 """ 

1421 return self._entity 

1422 

1423 @Entity.setter 

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

1425 self._entity = value 

1426 self._isBlackbox = False 

1427 

1428 def __str__(self) -> str: 

1429 """ 

1430 Formats the component declaration. 

1431 

1432 **Format:** ``Component: myComponent`` 

1433 

1434 :returns: Formatted component declaration. 

1435 """ 

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

1437 

1438 def __repr__(self) -> str: 

1439 """ 

1440 Formats a representation of the component declaration. 

1441 

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

1443 

1444 :returns: String representation of the component declaration. 

1445 """ 

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

1447 

1448 

1449@export 

1450class Configuration(PrimaryUnit, DesignUnitWithContextMixin): 

1451 """ 

1452 Represents a configuration declaration. 

1453 

1454 .. admonition:: Example 

1455 

1456 .. code-block:: VHDL 

1457 

1458 configuration cfg of ent is 

1459 for rtl 

1460 -- ... 

1461 end for; 

1462 end configuration; 

1463 

1464 .. seealso:: 

1465 

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

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

1468 """ 

1469 

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

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

1472 _namespace: Namespace #: The namespace of this configuration's declarative region. 

1473 

1474 def __init__( 

1475 self, 

1476 identifier: str, 

1477 entity: EntitySymbol, 

1478 blockConfiguration: BlockConfiguration, 

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

1480 documentation: Nullable[str] = None, 

1481 parent: Nullable[ModelEntity] = None 

1482 ) -> None: 

1483 """ 

1484 Initializes a configuration declaration. 

1485 

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

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

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

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

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

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

1492 """ 

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

1494 DesignUnitWithContextMixin.__init__(self) 

1495 

1496 self._namespace = Namespace(self._normalizedIdentifier) 

1497 

1498 self._entity = entity 

1499 entity.Parent = self 

1500 

1501 self._blockConfiguration = blockConfiguration 

1502 blockConfiguration.Parent = self 

1503 

1504 @readonly 

1505 def Entity(self) -> EntitySymbol: 

1506 """ 

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

1508 

1509 :returns: The entity. 

1510 """ 

1511 return self._entity 

1512 

1513 @readonly 

1514 def BlockConfiguration(self) -> BlockConfiguration: 

1515 """ 

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

1517 

1518 :returns: The block configuration. 

1519 """ 

1520 return self._blockConfiguration 

1521 

1522 def Visit(self, visitor: Visitor) -> None: 

1523 """ 

1524 Walk this configuration, its context clause, its entity and its block configuration with a visitor. 

1525 

1526 :param visitor: The visitor receiving the events. 

1527 """ 

1528 self._VisitContextClause(visitor) 

1529 visitor.VisitConfiguration(self) 

1530 self._entity.Visit(visitor) 

1531 visitor.VisitIs(self) 

1532 self._blockConfiguration.Visit(visitor) 

1533 visitor.DepartConfiguration(self) 

1534 

1535 def __str__(self) -> str: 

1536 """ 

1537 Formats the configuration declaration. 

1538 

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

1540 

1541 :returns: Formatted configuration declaration. 

1542 """ 

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

1544 

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

1546 

1547 def __repr__(self) -> str: 

1548 """ 

1549 Formats a representation of the configuration declaration. 

1550 

1551 **Format:** ``mylib.myConfiguration`` 

1552 

1553 :returns: String representation of the configuration declaration. 

1554 """ 

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

1556 

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