Coverage for pyVHDLModel/Concurrent.py: 95%

355 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 

35Concurrent defines all concurrent statements used in entities, architectures, generates and block statements. 

36""" 

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

38 

39from pyTooling.Decorators import export, readonly 

40from pyTooling.MetaClasses import ExtendedType 

41 

42from pyVHDLModel.Base import ModelEntity, LabeledEntityMixin, DocumentedEntityMixin, Range, BaseChoice, BaseCase, IfBranchMixin 

43from pyVHDLModel.Base import ElsifBranchMixin, ElseBranchMixin, AssertStatementMixin, BlockStatementMixin, WaveformElement, ChoicesMixin 

44from pyVHDLModel.Regions import ConcurrentDeclarationRegionMixin, SequentialDeclarationRegionMixin 

45from pyVHDLModel.Namespace import Namespace 

46from pyVHDLModel.Name import Name 

47from pyVHDLModel.Symbol import ComponentInstantiationSymbol, EntityInstantiationSymbol, ArchitectureSymbol, ConfigurationInstantiationSymbol 

48from pyVHDLModel.Symbol import SignalSymbol 

49from pyVHDLModel.Expression import BaseExpression, QualifiedExpression, FunctionCall, TypeConversion, Literal 

50from pyVHDLModel.Association import AssociationItem, ParameterAssociationItem 

51from pyVHDLModel.Association import GenericAssociationItem, PortAssociationItem 

52from pyVHDLModel.Association import GenericMapAspectMixin, PortMapAspectMixin 

53from pyVHDLModel.Interface import PortInterfaceItemMixin, WithPortsMixin 

54from pyVHDLModel.Interface import GenericInterfaceItemMixin, WithGenericsMixin 

55from pyVHDLModel.Common import Statement, ProcedureCallMixin, SignalAssignmentMixin, AllowBlackboxMixin 

56from pyVHDLModel.Common import ConditionalWaveform, SelectedWaveform, OthersSelectedWaveform 

57from pyVHDLModel.Common import ConditionalWaveformsMixin, WaveformMixin 

58from pyVHDLModel.Common import ExpressionMixin, SelectedWaveformsMixin 

59from pyVHDLModel.Sequential import SequentialStatement, SequentialStatementsMixin 

60 

61 

62ExpressionUnion = Union[ 

63 BaseExpression, 

64 QualifiedExpression, 

65 FunctionCall, 

66 TypeConversion, 

67 # ConstantOrSymbol, TODO: ObjectSymbol 

68 Literal, 

69] 

70 

71 

72@export 

73class ConcurrentStatement(Statement): 

74 """ 

75 A base-class for all concurrent statements. 

76 

77 .. seealso:: 

78 

79 * :class:`Instantiation <pyVHDLModel.Concurrent.Instantiation>` 

80 * :class:`Process statement <pyVHDLModel.Concurrent.ProcessStatement>` 

81 * :class:`Concurrent procedure call <pyVHDLModel.Concurrent.ConcurrentProcedureCall>` 

82 * :class:`Concurrent block statement <pyVHDLModel.Concurrent.ConcurrentBlockStatement>` 

83 * :class:`Generate statement <pyVHDLModel.Concurrent.GenerateStatement>` 

84 * :class:`Concurrent signal assignment <pyVHDLModel.Concurrent.ConcurrentSignalAssignment>` 

85 * :class:`Concurrent assert statement <pyVHDLModel.Concurrent.ConcurrentAssertStatement>` 

86 """ 

87 

88 

89@export 

90class ConcurrentStatementsMixin(metaclass=ExtendedType, mixin=True): 

91 """ 

92 A mixin-class for all language constructs supporting concurrent statements. 

93 

94 .. seealso:: 

95 

96 * :class:`Concurrent block statement <pyVHDLModel.Concurrent.ConcurrentBlockStatement>` 

97 * :class:`Generate branch <pyVHDLModel.Concurrent.GenerateBranch>` 

98 * :class:`Concurrent case <pyVHDLModel.Concurrent.ConcurrentCase>` 

99 * :class:`For generate statement <pyVHDLModel.Concurrent.ForGenerateStatement>` 

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

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

102 

103 .. todo:: concurrent declaration region 

104 """ 

105 

106 _statements: List[ConcurrentStatement] #: List of all concurrent statements in this construct. 

107 

108 # TODO: add another instantiation class level for entity/configuration/component inst. 

109 _instantiations: Dict[str, 'Instantiation'] #: All instantiations, indexed by label. 

110 _hierarchy: Dict[str, Union['ConcurrentBlockStatement', 'GenerateStatement']] #: All elements creating a hierarchy level (blocks and generates), in declaration order. 

111 

112 def __init__(self, statements: Nullable[Iterable[ConcurrentStatement]] = None) -> None: 

113 """ 

114 Initializes concurrent statements. 

115 

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

117 """ 

118 self._statements = [] 

119 

120 self._instantiations = {} 

121 self._hierarchy = {} 

122 

123 if statements is not None: 

124 for statement in statements: 

125 self._statements.append(statement) 

126 statement.Parent = self 

127 

128 @readonly 

129 def Statements(self) -> List[ConcurrentStatement]: 

130 """ 

131 Read-only property to access the statements (:attr:`_statements`). 

132 

133 :returns: List of statements. 

134 """ 

135 return self._statements 

136 

137 def IterateInstantiations(self) -> Generator['Instantiation', None, None]: 

138 for instance in self._instantiations.values(): 

139 yield instance 

140 

141 for element in self._hierarchy.values(): 

142 yield from element.IterateInstantiations() 

143 

144 # TODO: move into _init__ 

145 def IndexStatements(self) -> None: 

146 for statement in self._statements: 

147 if isinstance(statement, (EntityInstantiation, ComponentInstantiation, ConfigurationInstantiation)): 

148 self._instantiations[statement.NormalizedLabel] = statement 

149 elif isinstance(statement, (ForGenerateStatement, IfGenerateStatement, CaseGenerateStatement)): 

150 self._hierarchy[statement.NormalizedLabel] = statement 

151 statement.IndexStatement() 

152 elif isinstance(statement, ConcurrentBlockStatement): 152 ↛ 146line 152 didn't jump to line 146 because the condition on line 152 was always true

153 self._hierarchy[statement.NormalizedLabel] = statement 

154 statement.IndexStatements() 

155 

156 

157@export 

158class Instantiation(ConcurrentStatement, GenericMapAspectMixin, PortMapAspectMixin): 

159 """ 

160 A base-class for all (component) instantiations. 

161 

162 .. seealso:: 

163 

164 * :class:`Component instantiation <pyVHDLModel.Concurrent.ComponentInstantiation>` 

165 * :class:`Entity instantiation <pyVHDLModel.Concurrent.EntityInstantiation>` 

166 * :class:`Configuration instantiation <pyVHDLModel.Concurrent.ConfigurationInstantiation>` 

167 """ 

168 

169 def __init__( 

170 self, 

171 label: str, 

172 genericAssociationItems: Nullable[Iterable[GenericAssociationItem]] = None, 

173 portAssociationItems: Nullable[Iterable[PortAssociationItem]] = None, 

174 parent: Nullable[ModelEntity] = None 

175 ) -> None: 

176 """ 

177 Initializes an instantiation. 

178 

179 :param label: The label of a model entity. 

180 :param genericAssociationItems: List of all generic associations in the generic map aspect. 

181 :param portAssociationItems: List of all port associations in the port map aspect. 

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

183 """ 

184 super().__init__(label, parent) 

185 GenericMapAspectMixin.__init__(self, genericAssociationItems) 

186 PortMapAspectMixin.__init__(self, portAssociationItems) 

187 

188 

189 

190 

191@export 

192class ComponentInstantiation(Instantiation): 

193 """ 

194 Represents a component instantiation. 

195 

196 The instantiated component is available as :data:`Component`, the associations as 

197 :data:`GenericAssociationItems` and :data:`PortAssociationItems`. The label is mandatory. 

198 

199 .. admonition:: Example 

200 

201 .. code-block:: VHDL 

202 

203 inst : component Counter; 

204 --^^^^ <- Label 

205 -- ^^^^^^^ <- Component 

206 """ 

207 

208 _component: ComponentInstantiationSymbol #: Reference to the instantiated component. 

209 

210 def __init__( 

211 self, 

212 label: str, 

213 componentSymbol: ComponentInstantiationSymbol, 

214 genericAssociationItems: Nullable[Iterable[AssociationItem]] = None, 

215 portAssociationItems: Nullable[Iterable[AssociationItem]] = None, 

216 parent: Nullable[ModelEntity] = None 

217 ) -> None: 

218 """ 

219 Initializes a component instantiation. 

220 

221 :param label: The label of a model entity. 

222 :param componentSymbol: Reference to the instantiated component. 

223 :param genericAssociationItems: List of all generic associations in the generic map aspect. 

224 :param portAssociationItems: List of all port associations in the port map aspect. 

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

226 """ 

227 super().__init__(label, genericAssociationItems, portAssociationItems, parent) 

228 

229 self._component = componentSymbol 

230 componentSymbol.Parent = self 

231 

232 @readonly 

233 def Component(self) -> ComponentInstantiationSymbol: 

234 """ 

235 Read-only property to access the component (:attr:`_component`). 

236 

237 :returns: The component. 

238 """ 

239 return self._component 

240 

241 

242@export 

243class EntityInstantiation(Instantiation): 

244 """ 

245 Represents a direct entity instantiation. 

246 

247 The instantiated entity is available as :data:`Entity` and the optionally selected architecture 

248 as :data:`Architecture`. The label is mandatory. 

249 

250 .. admonition:: Example 

251 

252 .. code-block:: VHDL 

253 

254 inst : entity work.Counter(rtl); 

255 --^^^^ <- Label 

256 -- ^^^^^^^^^^^^ <- Entity 

257 -- ^^^ <- optional Architecture 

258 """ 

259 

260 _entity: EntityInstantiationSymbol #: Reference to the directly instantiated entity. 

261 _architecture: ArchitectureSymbol #: Reference to the selected architecture, if one was given. 

262 

263 def __init__( 

264 self, 

265 label: str, 

266 entitySymbol: EntityInstantiationSymbol, 

267 architectureSymbol: Nullable[ArchitectureSymbol] = None, 

268 genericAssociationItems: Nullable[Iterable[AssociationItem]] = None, 

269 portAssociationItems: Nullable[Iterable[AssociationItem]] = None, 

270 parent: Nullable[ModelEntity] = None 

271 ) -> None: 

272 """ 

273 Initializes a direct entity instantiation. 

274 

275 :param label: The label of a model entity. 

276 :param entitySymbol: Reference to the directly instantiated entity. 

277 :param architectureSymbol: Reference to the selected architecture, if one was given. 

278 :param genericAssociationItems: List of all generic associations in the generic map aspect. 

279 :param portAssociationItems: List of all port associations in the port map aspect. 

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

281 """ 

282 super().__init__(label, genericAssociationItems, portAssociationItems, parent) 

283 

284 self._entity = entitySymbol 

285 entitySymbol.Parent = self 

286 

287 self._architecture = architectureSymbol 

288 if architectureSymbol is not None: 

289 architectureSymbol.Parent = self 

290 

291 @readonly 

292 def Entity(self) -> EntityInstantiationSymbol: 

293 """ 

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

295 

296 :returns: The entity. 

297 """ 

298 return self._entity 

299 

300 @readonly 

301 def Architecture(self) -> ArchitectureSymbol: 

302 """ 

303 Read-only property to access the architecture (:attr:`_architecture`). 

304 

305 :returns: The architecture. 

306 """ 

307 return self._architecture 

308 

309 

310@export 

311class ConfigurationInstantiation(Instantiation): 

312 """ 

313 Represents a configuration instantiation. 

314 

315 The instantiated configuration is available as :data:`Configuration`. The label is mandatory. 

316 

317 .. admonition:: Example 

318 

319 .. code-block:: VHDL 

320 

321 inst : configuration Counter; 

322 --^^^^ <- Label 

323 -- ^^^^^^^ <- Configuration 

324 """ 

325 

326 _configuration: ConfigurationInstantiationSymbol #: Reference to the instantiated configuration. 

327 

328 def __init__( 

329 self, 

330 label: str, 

331 configurationSymbol: ConfigurationInstantiationSymbol, 

332 genericAssociationItems: Nullable[Iterable[AssociationItem]] = None, 

333 portAssociationItems: Nullable[Iterable[AssociationItem]] = None, 

334 parent: Nullable[ModelEntity] = None 

335 ) -> None: 

336 """ 

337 Initializes a configuration instantiation. 

338 

339 :param label: The label of a model entity. 

340 :param configurationSymbol: Reference to the instantiated configuration. 

341 :param genericAssociationItems: List of all generic associations in the generic map aspect. 

342 :param portAssociationItems: List of all port associations in the port map aspect. 

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

344 """ 

345 super().__init__(label, genericAssociationItems, portAssociationItems, parent) 

346 

347 self._configuration = configurationSymbol 

348 configurationSymbol.Parent = self 

349 

350 @readonly 

351 def Configuration(self) -> ConfigurationInstantiationSymbol: 

352 """ 

353 Read-only property to access the configuration (:attr:`_configuration`). 

354 

355 :returns: The configuration. 

356 """ 

357 return self._configuration 

358 

359 

360@export 

361class ProcessStatement(ConcurrentStatement, SequentialDeclarationRegionMixin, SequentialStatementsMixin, DocumentedEntityMixin): 

362 """ 

363 Represents a process statement. 

364 

365 A process declares its own items (:data:`DeclaredItems`) and groups sequential statements 

366 (:data:`Statements`). It may name a sensitivity list (:data:`SensitivityList`). 

367 

368 .. admonition:: Example 

369 

370 .. code-block:: VHDL 

371 

372 proc : process (clock) 

373 --^^^^ <- optional Label 

374 -- ^^^^^ <- optional SensitivityList 

375 variable v : bit; 

376 -- ^^^^^^^^^^^^^^^^^ <- DeclaredItems 

377 begin 

378 v := '1'; 

379 -- ^^^^^^^^^ <- Statements 

380 end process; 

381 """ 

382 

383 # TODO: implement a SignalSymbol 

384 _sensitivityList: List[Name] #: List of all signal names in the sensitivity list, or ``None`` if none was given. 

385 

386 def __init__( 

387 self, 

388 label: Nullable[str] = None, 

389 declaredItems: Nullable[Iterable] = None, 

390 statements: Nullable[Iterable[SequentialStatement]] = None, 

391 sensitivityList: Nullable[Iterable[Name]] = None, 

392 documentation: Nullable[str] = None, 

393 parent: Nullable[ModelEntity] = None 

394 ) -> None: 

395 """ 

396 Initializes a process statement. 

397 

398 :param label: The label of a model entity. 

399 :param declaredItems: List of all declared items in this sequential declaration region. 

400 :param statements: List of all sequential statements in this construct. 

401 :param sensitivityList: List of all signal names in the sensitivity list, or ``None`` if none was given. 

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

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

404 """ 

405 super().__init__(label, parent) 

406 SequentialDeclarationRegionMixin.__init__(self, self._normalizedLabel, declaredItems) 

407 SequentialStatementsMixin.__init__(self, statements) 

408 DocumentedEntityMixin.__init__(self, documentation) 

409 

410 if sensitivityList is None: 

411 self._sensitivityList = None 

412 else: 

413 self._sensitivityList = [] # TODO: convert to dict 

414 for signalSymbol in sensitivityList: 

415 self._sensitivityList.append(signalSymbol) 

416 # signalSymbol._parent = self # FIXME: currently str are provided 

417 

418 @ConcurrentStatement.Parent.setter 

419 def Parent(self, parent: ModelEntity) -> None: 

420 ConcurrentStatement.Parent.fset(self, parent) 

421 

422 # Connect the process' namespace to the enclosing declaration region's namespace, so a declaration 

423 # inside the process hides a same-named one from the architecture, block or generate around it. 

424 self._namespace.ParentNamespace = parent._namespace 

425 

426 @readonly 

427 def SensitivityList(self) -> List[Name]: 

428 """ 

429 Read-only property to access the sensitivity list (:attr:`_sensitivityList`). 

430 

431 :returns: List of sensitivity list. 

432 """ 

433 return self._sensitivityList 

434 

435 

436@export 

437class ConcurrentProcedureCall(ConcurrentStatement, ProcedureCallMixin): 

438 """ 

439 Represents a concurrent procedure call. 

440 

441 Like every concurrent statement, it can carry an optional label (:data:`Label`). 

442 

443 .. admonition:: Example 

444 

445 .. code-block:: VHDL 

446 

447 proc_lbl : proc(clock, open); 

448 --^^^^^^^^ <- optional Label 

449 -- ^^^^^^^^^^^^^^^^^ <- the call 

450 

451 .. seealso:: 

452 

453 * :class:`Sequential counterpart <pyVHDLModel.Sequential.SequentialProcedureCall>` 

454 """ 

455 def __init__( 

456 self, 

457 label: str, 

458 procedureName: Name, 

459 parameterAssociationItems: Nullable[Iterable[ParameterAssociationItem]] = None, 

460 parent: Nullable[ModelEntity] = None 

461 ) -> None: 

462 """ 

463 Initializes a concurrent procedure call. 

464 

465 :param label: The label of a model entity. 

466 :param procedureName: Reference to the called procedure. 

467 :param parameterAssociationItems: List of all parameter associations of the call. 

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

469 """ 

470 super().__init__(label, parent) 

471 ProcedureCallMixin.__init__(self, procedureName, parameterAssociationItems) 

472 

473 

474@export 

475class ConcurrentBlockStatement( 

476 ConcurrentStatement, 

477 BlockStatementMixin, 

478 LabeledEntityMixin, 

479 WithGenericsMixin, 

480 WithPortsMixin, 

481 GenericMapAspectMixin, 

482 PortMapAspectMixin, 

483 ConcurrentDeclarationRegionMixin, 

484 ConcurrentStatementsMixin, 

485 DocumentedEntityMixin, 

486 AllowBlackboxMixin 

487): 

488 """ 

489 Represents a block statement. 

490 

491 A block groups concurrent statements (:data:`Statements`) and may declare its own items 

492 (:data:`DeclaredItems`). It always forms a hierarchy level; independently of that, it may also have 

493 a block header: a generic clause (:data:`GenericItems`) with its generic map aspect 

494 (:data:`GenericAssociationItems`), and a port clause (:data:`PortItems`) with its port map aspect 

495 (:data:`PortAssociationItems`). 

496 

497 .. admonition:: Example 

498 

499 .. code-block:: VHDL 

500 

501 blk : block 

502 --^^^ <- Label 

503 generic (G : positive := 1); 

504 -- ^^^^^^^^^^^^^^^^^^ <- GenericItems 

505 generic map (G => 2); 

506 -- ^^^^^^^^ <- GenericAssociationItems 

507 port (bp : in bit); 

508 -- ^^^^^^^^^^^ <- PortItems 

509 port map (bp => clock); 

510 -- ^^^^^^^^^^^^ <- PortAssociationItems 

511 signal inner : bit := '0'; 

512 -- ^^^^^^^^^^^^^^^^^^^^^^^^^^ <- DeclaredItems 

513 begin 

514 inner <= bp; 

515 -- ^^^^^^^^^^^^ <- Statements 

516 end block; 

517 

518 .. seealso:: 

519 

520 * :class:`Generate statement <pyVHDLModel.Concurrent.GenerateStatement>` 

521 """ 

522 _namespace: Namespace #: The namespace of this block's declarative region. 

523 

524 def __init__( 

525 self, 

526 label: str, 

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

528 genericAssociationItems: Nullable[Iterable[GenericAssociationItem]] = None, 

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

530 portAssociationItems: Nullable[Iterable[PortAssociationItem]] = None, 

531 declaredItems: Nullable[Iterable] = None, 

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

533 documentation: Nullable[str] = None, 

534 allowBlackbox: Nullable[bool] = None, 

535 parent: Nullable[ModelEntity] = None 

536 ) -> None: 

537 """ 

538 Initializes a block statement. 

539 

540 :param label: The label of a model entity. 

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

542 :param genericAssociationItems: List of all generic associations in the generic map aspect. 

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

544 :param portAssociationItems: List of all port associations in the port map aspect. 

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

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

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

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

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

550 """ 

551 super().__init__(label, parent) 

552 

553 self._namespace = Namespace(self._normalizedLabel) 

554 if parent is not None: 554 ↛ 555line 554 didn't jump to line 555 because the condition on line 554 was never true

555 self._namespace.ParentNamespace = parent._namespace 

556 

557 BlockStatementMixin.__init__(self) 

558 LabeledEntityMixin.__init__(self, label) 

559 WithGenericsMixin.__init__(self, genericItems) 

560 WithPortsMixin.__init__(self, portItems) 

561 GenericMapAspectMixin.__init__(self, genericAssociationItems) 

562 PortMapAspectMixin.__init__(self, portAssociationItems) 

563 ConcurrentDeclarationRegionMixin.__init__(self, declaredItems) 

564 ConcurrentStatementsMixin.__init__(self, statements) 

565 DocumentedEntityMixin.__init__(self, documentation) 

566 AllowBlackboxMixin.__init__(self, allowBlackbox) 

567 

568 @ConcurrentStatement.Parent.setter 

569 def Parent(self, parent: ModelEntity) -> None: 

570 ConcurrentStatement.Parent.fset(self, parent) 

571 

572 self._namespace.ParentNamespace = parent._namespace 

573 

574 

575 def IndexDeclaredItems(self) -> None: 

576 """A block's ports share the declarative region of its declarative part.""" 

577 self._IndexPortItems() 

578 

579 super().IndexDeclaredItems() 

580 

581 

582@export 

583class GenerateBranch(ModelEntity, ConcurrentDeclarationRegionMixin, ConcurrentStatementsMixin, AllowBlackboxMixin): 

584 """ 

585 A base-class for all branches in a generate statements. 

586 

587 .. seealso:: 

588 

589 * :class:`If generate branch <pyVHDLModel.Concurrent.IfGenerateBranch>` 

590 * :class:`Elsif generate branch <pyVHDLModel.Concurrent.ElsifGenerateBranch>` 

591 * :class:`Else generate branch <pyVHDLModel.Concurrent.ElseGenerateBranch>` 

592 """ 

593 

594 _alternativeLabel: Nullable[str] #: The branch's alternative label, if one was given. 

595 _normalizedAlternativeLabel: Nullable[str] #: The normalized (lower case) alternative label. 

596 

597 _namespace: Namespace #: The namespace of this branch's declarative region. 

598 

599 def __init__( 

600 self, 

601 declaredItems: Nullable[Iterable] = None, 

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

603 alternativeLabel: Nullable[str] = None, 

604 allowBlackbox: Nullable[bool] = None, 

605 parent: Nullable[ModelEntity] = None 

606 ) -> None: 

607 """ 

608 Initializes a generate branch. 

609 

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

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

612 :param alternativeLabel: The branch's alternative label, if one was given. 

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

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

615 """ 

616 super().__init__(parent) 

617 

618 self._alternativeLabel = alternativeLabel 

619 self._normalizedAlternativeLabel = alternativeLabel.lower() if alternativeLabel is not None else None 

620 

621 self._namespace = Namespace(self._normalizedAlternativeLabel) 

622 if parent is not None: 622 ↛ 623line 622 didn't jump to line 623 because the condition on line 622 was never true

623 self._namespace.ParentNamespace = parent._namespace 

624 

625 ConcurrentDeclarationRegionMixin.__init__(self, declaredItems) 

626 ConcurrentStatementsMixin.__init__(self, statements) 

627 AllowBlackboxMixin.__init__(self, allowBlackbox) 

628 

629 @readonly 

630 def AlternativeLabel(self) -> Nullable[str]: 

631 """ 

632 Read-only property to access the alternative label (:attr:`_alternativeLabel`). 

633 

634 :returns: The alternative label, or ``None`` if not set. 

635 """ 

636 return self._alternativeLabel 

637 

638 @readonly 

639 def NormalizedAlternativeLabel(self) -> Nullable[str]: 

640 """ 

641 Read-only property to access the normalized alternative label (:attr:`_normalizedAlternativeLabel`). 

642 

643 :returns: The normalized alternative label, or ``None`` if not set. 

644 """ 

645 return self._normalizedAlternativeLabel 

646 

647 

648@export 

649class IfGenerateBranch(GenerateBranch, IfBranchMixin): 

650 """ 

651 Represents if-generate branch in a generate statement with a concurrent declaration region and concurrent statements. 

652 

653 .. admonition:: Example 

654 

655 .. code-block:: VHDL 

656 

657 gen: if condition generate 

658 -- concurrent declarations 

659 begin 

660 -- concurrent statements 

661 elsif condition generate 

662 -- ... 

663 else generate 

664 -- ... 

665 end generate; 

666 """ 

667 

668 def __init__( 

669 self, 

670 condition: ExpressionUnion, 

671 declaredItems: Nullable[Iterable] = None, 

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

673 alternativeLabel: Nullable[str] = None, 

674 allowBlackbox: Nullable[bool] = None, 

675 parent: Nullable[ModelEntity] = None 

676 ) -> None: 

677 """ 

678 Initializes an if generate branch. 

679 

680 :param condition: The condition guarding this statement. 

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

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

683 :param alternativeLabel: The branch's alternative label, if one was given. 

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

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

686 """ 

687 super().__init__(declaredItems, statements, alternativeLabel, allowBlackbox, parent) 

688 IfBranchMixin.__init__(self, condition) 

689 

690 

691@export 

692class ElsifGenerateBranch(GenerateBranch, ElsifBranchMixin): 

693 """ 

694 Represents elsif-generate branch in a generate statement with a concurrent declaration region and concurrent statements. 

695 

696 .. admonition:: Example 

697 

698 .. code-block:: VHDL 

699 

700 gen: if condition generate 

701 -- ... 

702 elsif condition generate 

703 -- concurrent declarations 

704 begin 

705 -- concurrent statements 

706 else generate 

707 -- ... 

708 end generate; 

709 """ 

710 

711 def __init__( 

712 self, 

713 condition: ExpressionUnion, 

714 declaredItems: Nullable[Iterable] = None, 

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

716 alternativeLabel: Nullable[str] = None, 

717 allowBlackbox: Nullable[bool] = None, 

718 parent: Nullable[ModelEntity] = None 

719 ) -> None: 

720 """ 

721 Initializes an elsif generate branch. 

722 

723 :param condition: The condition guarding this statement. 

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

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

726 :param alternativeLabel: The branch's alternative label, if one was given. 

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

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

729 """ 

730 super().__init__(declaredItems, statements, alternativeLabel, allowBlackbox, parent) 

731 ElsifBranchMixin.__init__(self, condition) 

732 

733 

734@export 

735class ElseGenerateBranch(GenerateBranch, ElseBranchMixin): 

736 """ 

737 Represents else-generate branch in a generate statement with a concurrent declaration region and concurrent statements. 

738 

739 .. admonition:: Example 

740 

741 .. code-block:: VHDL 

742 

743 gen: if condition generate 

744 -- ... 

745 elsif condition generate 

746 -- ... 

747 else generate 

748 -- concurrent declarations 

749 begin 

750 -- concurrent statements 

751 end generate; 

752 """ 

753 

754 def __init__( 

755 self, 

756 declaredItems: Nullable[Iterable] = None, 

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

758 alternativeLabel: Nullable[str] = None, 

759 allowBlackbox: Nullable[bool] = None, 

760 parent: Nullable[ModelEntity] = None 

761 ) -> None: 

762 """ 

763 Initializes an else generate branch. 

764 

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

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

767 :param alternativeLabel: The branch's alternative label, if one was given. 

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

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

770 """ 

771 super().__init__(declaredItems, statements, alternativeLabel, allowBlackbox, parent) 

772 ElseBranchMixin.__init__(self) 

773 

774 

775@export 

776class GenerateStatement(ConcurrentStatement, AllowBlackboxMixin): 

777 """ 

778 Represents the base-class of all generate statements. 

779 

780 A generate statement replicates or conditionally elaborates concurrent statements. 

781 

782 .. seealso:: 

783 

784 * :class:`If generate statement <pyVHDLModel.Concurrent.IfGenerateStatement>` 

785 * :class:`Case generate statement <pyVHDLModel.Concurrent.CaseGenerateStatement>` 

786 * :class:`For generate statement <pyVHDLModel.Concurrent.ForGenerateStatement>` 

787 """ 

788 

789 def __init__( 

790 self, 

791 label: Nullable[str] = None, 

792 allowBlackbox: Nullable[bool] = None, 

793 parent: Nullable[ModelEntity] = None 

794 ) -> None: 

795 """ 

796 Initializes a generate statement. 

797 

798 :param label: The label of a model entity. 

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

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

801 """ 

802 super().__init__(label, parent) 

803 AllowBlackboxMixin.__init__(self, allowBlackbox) 

804 

805 # @mustoverride 

806 def IterateInstantiations(self) -> Generator[Instantiation, None, None]: 

807 raise NotImplementedError() 

808 

809 # @mustoverride 

810 def IndexStatement(self) -> None: 

811 raise NotImplementedError() 

812 

813 

814@export 

815class IfGenerateStatement(GenerateStatement): 

816 """ 

817 Represents an if-generate statement. 

818 

819 It has one ``if`` branch (:data:`IfBranch`), any number of ``elsif`` branches 

820 (:data:`ElsifBranches`) and an optional ``else`` branch (:data:`ElseBranch`). The label is 

821 mandatory and the branch conditions must be static expressions. 

822 

823 .. admonition:: Example 

824 

825 .. code-block:: VHDL 

826 

827 gen : if WIDTH > 8 generate 

828 --^^^ <- Label 

829 -- ^^^^^^^^^^^^^^^^^^^^^ <- IfBranch 

830 q <= '0'; 

831 elsif WIDTH > 4 generate 

832 --^^^^^^^^^^^^^^^^^^^^^^^^ <- ElsifBranches[0] 

833 q <= '1'; 

834 else generate 

835 --^^^^^^^^^^^^^ <- ElseBranch 

836 q <= 'Z'; 

837 end generate; 

838 

839 .. seealso:: 

840 

841 * :class:`Generate branch <pyVHDLModel.Concurrent.GenerateBranch>` base-class 

842 * :class:`If-generate branch <pyVHDLModel.Concurrent.IfGenerateBranch>` 

843 * :class:`Elsif-generate branch <pyVHDLModel.Concurrent.ElsifGenerateBranch>` 

844 * :class:`Else-generate branch <pyVHDLModel.Concurrent.ElseGenerateBranch>` 

845 * :class:`Case-generate statement <pyVHDLModel.Concurrent.CaseGenerateStatement>` 

846 * :class:`For-generate statement <pyVHDLModel.Concurrent.ForGenerateStatement>` 

847 """ 

848 

849 _ifBranch: IfGenerateBranch #: The mandatory ``if`` branch. 

850 _elsifBranches: List[ElsifGenerateBranch] #: List of all ``elsif`` branches, in the order they were written. 

851 _elseBranch: Nullable[ElseGenerateBranch] #: The optional ``else`` branch, or ``None`` if none was given. 

852 

853 def __init__( 

854 self, 

855 label: str, 

856 ifBranch: IfGenerateBranch, 

857 elsifBranches: Nullable[Iterable[ElsifGenerateBranch]] = None, 

858 elseBranch: Nullable[ElseGenerateBranch] = None, 

859 allowBlackbox: Nullable[bool] = None, 

860 parent: Nullable[ModelEntity] = None 

861 ) -> None: 

862 """ 

863 Initializes an if-generate statement. 

864 

865 :param label: The label of a model entity. 

866 :param ifBranch: The mandatory ``if`` branch. 

867 :param elsifBranches: List of all ``elsif`` branches, in the order they were written. 

868 :param elseBranch: The optional ``else`` branch, or ``None`` if none was given. 

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

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

871 """ 

872 super().__init__(label, allowBlackbox, parent) 

873 

874 self._ifBranch = ifBranch 

875 ifBranch.Parent = self 

876 

877 self._elsifBranches = [] 

878 if elsifBranches is not None: 

879 for branch in elsifBranches: 

880 self._elsifBranches.append(branch) 

881 branch.Parent = self 

882 

883 if elseBranch is not None: 

884 self._elseBranch = elseBranch 

885 elseBranch.Parent = self 

886 else: 

887 self._elseBranch = None 

888 

889 @GenerateStatement.Parent.setter 

890 def Parent(self, parent: ModelEntity) -> None: 

891 from pyVHDLModel.DesignUnit import Architecture 

892 

893 GenerateStatement.Parent.fset(self, parent) 

894 

895 # Connect namespaces 

896 namespace = self._ifBranch._namespace 

897 namespace.ParentNamespace = parent._namespace 

898 if namespace._name is None: 898 ↛ 901line 898 didn't jump to line 901 because the condition on line 898 was always true

899 namespace._name = self._normalizedLabel 

900 

901 for elseBranch in self._elsifBranches: 

902 elseBranch._namespace.ParentNamespace = parent._namespace 

903 

904 if self._elseBranch is not None: 904 ↛ exitline 904 didn't return from function 'Parent' because the condition on line 904 was always true

905 self._elseBranch._namespace.ParentNamespace = parent._namespace 

906 

907 @readonly 

908 def IfBranch(self) -> IfGenerateBranch: 

909 """ 

910 Read-only property to access the if branch (:attr:`_ifBranch`). 

911 

912 :returns: The if branch. 

913 """ 

914 return self._ifBranch 

915 

916 @readonly 

917 def ElsifBranches(self) -> List[ElsifGenerateBranch]: 

918 """ 

919 Read-only property to access the elsif branches (:attr:`_elsifBranches`). 

920 

921 :returns: List of elsif branches. 

922 """ 

923 return self._elsifBranches 

924 

925 @readonly 

926 def ElseBranch(self) -> Nullable[ElseGenerateBranch]: 

927 """ 

928 Read-only property to access the else branch (:attr:`_elseBranch`). 

929 

930 :returns: The else branch, or ``None`` if not set. 

931 """ 

932 return self._elseBranch 

933 

934 def IterateInstantiations(self) -> Generator[Instantiation, None, None]: 

935 yield from self._ifBranch.IterateInstantiations() 

936 for branch in self._elsifBranches: 936 ↛ 937line 936 didn't jump to line 937 because the loop on line 936 never started

937 yield from branch.IterateInstantiations() 

938 if self._elseBranch is not None: 938 ↛ 939line 938 didn't jump to line 939 because the condition on line 938 was never true

939 yield from self._ifBranch.IterateInstantiations() 

940 

941 def IndexStatement(self) -> None: 

942 self._ifBranch.IndexStatements() 

943 for branch in self._elsifBranches: 943 ↛ 944line 943 didn't jump to line 944 because the loop on line 943 never started

944 branch.IndexStatements() 

945 if self._elseBranch is not None: 945 ↛ 946line 945 didn't jump to line 946 because the condition on line 945 was never true

946 self._elseBranch.IndexStatements() 

947 

948 

949@export 

950class ConcurrentChoice(BaseChoice): 

951 """ 

952 A base-class for all concurrent choices (in case...generate statements). 

953 

954 .. seealso:: 

955 

956 * :class:`Indexed generate choice <pyVHDLModel.Concurrent.IndexedGenerateChoice>` 

957 * :class:`Ranged generate choice <pyVHDLModel.Concurrent.RangedGenerateChoice>` 

958 """ 

959 

960 

961@export 

962class IndexedGenerateChoice(ConcurrentChoice): 

963 """ 

964 Represents a case-generate choice given by a single value. 

965 

966 The value is available as :data:`Expression`. 

967 

968 .. admonition:: Example 

969 

970 .. code-block:: VHDL 

971 

972 when 8 => 

973 -- ^ <- Expression 

974 """ 

975 _expression: ExpressionUnion #: The expression this choice selects on. 

976 

977 def __init__(self, expression: ExpressionUnion, parent: Nullable[ModelEntity] = None) -> None: 

978 """ 

979 Initializes a case-generate choice given by a single value. 

980 

981 :param expression: The expression this choice selects on. 

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

983 """ 

984 super().__init__(parent) 

985 

986 self._expression = expression 

987 expression.Parent = self 

988 

989 @readonly 

990 def Expression(self) -> ExpressionUnion: 

991 """ 

992 Read-only property to access the expression (:attr:`_expression`). 

993 

994 :returns: The expression. 

995 """ 

996 return self._expression 

997 

998 def __str__(self) -> str: 

999 """ 

1000 Formats the indexed case-generate choice. 

1001 

1002 **Format:** ``0`` 

1003 

1004 :returns: Formatted indexed case-generate choice. 

1005 """ 

1006 return str(self._expression) 

1007 

1008 

1009@export 

1010class RangedGenerateChoice(ConcurrentChoice): 

1011 """ 

1012 Represents a case-generate choice given by a range. 

1013 

1014 The range is available as :data:`Range`. 

1015 

1016 .. admonition:: Example 

1017 

1018 .. code-block:: VHDL 

1019 

1020 when 0 to 3 => 

1021 -- ^^^^^^ <- Range 

1022 """ 

1023 _range: 'Range' #: The range this choice selects on. 

1024 

1025 def __init__(self, rng: 'Range', parent: Nullable[ModelEntity] = None) -> None: 

1026 """ 

1027 Initializes a case-generate choice given by a range. 

1028 

1029 :param rng: The range this choice selects on. 

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

1031 """ 

1032 super().__init__(parent) 

1033 

1034 self._range = rng 

1035 rng.Parent = self 

1036 

1037 @readonly 

1038 def Range(self) -> 'Range': 

1039 """ 

1040 Read-only property to access the range (:attr:`_range`). 

1041 

1042 :returns: The range. 

1043 """ 

1044 return self._range 

1045 

1046 def __str__(self) -> str: 

1047 """ 

1048 Formats the ranged case-generate choice. 

1049 

1050 **Format:** ``0 to 3`` 

1051 

1052 :returns: Formatted ranged case-generate choice. 

1053 """ 

1054 return str(self._range) 

1055 

1056 

1057@export 

1058class ConcurrentCase(BaseCase, LabeledEntityMixin, ConcurrentDeclarationRegionMixin, ConcurrentStatementsMixin, AllowBlackboxMixin, ChoicesMixin): 

1059 """ 

1060 Represents the base-class of all alternatives of a case-generate statement. 

1061 

1062 .. seealso:: 

1063 

1064 * :class:`Generate case <pyVHDLModel.Concurrent.GenerateCase>` 

1065 * :class:`Others generate case <pyVHDLModel.Concurrent.OthersGenerateCase>` 

1066 """ 

1067 _namespace: Namespace #: The namespace of this alternative's declarative region. 

1068 

1069 def __init__( 

1070 self, 

1071 declaredItems: Nullable[Iterable] = None, 

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

1073 alternativeLabel: Nullable[str] = None, 

1074 choices: Nullable[Iterable[BaseChoice]] = None, 

1075 allowBlackbox: Nullable[bool] = None, 

1076 parent: Nullable[ModelEntity] = None 

1077 ) -> None: 

1078 """ 

1079 Initializes a concurrent case. 

1080 

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

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

1083 :param alternativeLabel: The alternative's label. 

1084 :param choices: List of all choices selecting this alternative. 

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

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

1087 """ 

1088 super().__init__(parent) 

1089 LabeledEntityMixin.__init__(self, alternativeLabel) 

1090 

1091 # TODO: Why not handover self? 

1092 # This allows access to Label and NormalizedLabel, also to create a full instance path in case a lookup goes wrong. 

1093 # TODO: How about a WithNamespaceMixin class? 

1094 self._namespace = Namespace(self._normalizedLabel) 

1095 if parent is not None: 1095 ↛ 1096line 1095 didn't jump to line 1096 because the condition on line 1095 was never true

1096 self._namespace.ParentNamespace = parent._namespace 

1097 

1098 ConcurrentDeclarationRegionMixin.__init__(self, declaredItems) 

1099 ConcurrentStatementsMixin.__init__(self, statements) 

1100 AllowBlackboxMixin.__init__(self, allowBlackbox) 

1101 ChoicesMixin.__init__(self, choices) 

1102 

1103 

1104@export 

1105class GenerateCase(ConcurrentCase): 

1106 """ 

1107 Represents one alternative of a case-generate statement, selected by its choices. 

1108 

1109 .. admonition:: Example 

1110 

1111 .. code-block:: VHDL 

1112 

1113 when 8 => 

1114 -- ^ <- Choices 

1115 """ 

1116 def __init__( 

1117 self, 

1118 choices: Iterable[ConcurrentChoice], 

1119 declaredItems: Nullable[Iterable] = None, 

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

1121 alternativeLabel: Nullable[str] = None, 

1122 allowBlackbox: Nullable[bool] = None, 

1123 parent: Nullable[ModelEntity] = None 

1124 ) -> None: 

1125 """ 

1126 Initializes a generate case. 

1127 

1128 :param choices: List of all choices selecting this alternative. 

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

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

1131 :param alternativeLabel: The alternative's label. 

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

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

1134 """ 

1135 super().__init__(declaredItems, statements, alternativeLabel, choices, allowBlackbox, parent) 

1136 

1137 def __str__(self) -> str: 

1138 """ 

1139 Formats the case-generate alternative. 

1140 

1141 **Format:** ``when 0 | 1 =>`` 

1142 

1143 :returns: Formatted case-generate alternative. 

1144 """ 

1145 return "when {choices} =>".format(choices=" | ".join(str(c) for c in self._choices)) 

1146 

1147 

1148@export 

1149class OthersGenerateCase(ConcurrentCase): 

1150 """ 

1151 Represents the ``others`` alternative of a case-generate statement. 

1152 

1153 It covers every choice not named explicitly. 

1154 

1155 .. admonition:: Example 

1156 

1157 .. code-block:: VHDL 

1158 

1159 when others => 

1160 -- ^^^^^^ <- the choice 

1161 """ 

1162 def __str__(self) -> str: 

1163 """ 

1164 Formats the ``others`` case-generate alternative. 

1165 

1166 **Format:** ``when others =>`` 

1167 

1168 :returns: Formatted ``others`` case-generate alternative. 

1169 """ 

1170 return "when others =>" 

1171 

1172 

1173@export 

1174class CaseGenerateStatement(GenerateStatement): 

1175 """ 

1176 Represents a case-generate statement. 

1177 

1178 The expression being tested is available as :data:`SelectExpression`, the alternatives as 

1179 :data:`Cases`. The label is mandatory and the selector must be a static expression. 

1180 

1181 .. admonition:: Example 

1182 

1183 .. code-block:: VHDL 

1184 

1185 gen : case MODE generate 

1186 --^^^ <- Label 

1187 -- ^^^^ <- SelectExpression 

1188 when 0 => q <= '0'; 

1189 -- ^^^^^^^^^^^^^^^^^^^ <- Cases[0] 

1190 when others => q <= '1'; 

1191 -- ^^^^^^^^^^^^^^^^^^^^^^^^ <- Cases[1] 

1192 end generate; 

1193 

1194 .. seealso:: 

1195 

1196 * :class:`If-generate statement <pyVHDLModel.Concurrent.IfGenerateStatement>` 

1197 * :class:`For-generate statement <pyVHDLModel.Concurrent.ForGenerateStatement>` 

1198 """ 

1199 

1200 _expression: ExpressionUnion #: The expression being tested; it must be static. 

1201 _cases: List[GenerateCase] #: List of all alternatives, in the order they were written. 

1202 

1203 def __init__( 

1204 self, 

1205 label: str, 

1206 expression: ExpressionUnion, 

1207 cases: Iterable[ConcurrentCase], 

1208 allowBlackbox: Nullable[bool] = None, 

1209 parent: Nullable[ModelEntity] = None 

1210 ) -> None: 

1211 """ 

1212 Initializes a case-generate statement. 

1213 

1214 :param label: The label of a model entity. 

1215 :param expression: The expression being tested; it must be static. 

1216 :param cases: List of all alternatives, in the order they were written. 

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

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

1219 """ 

1220 super().__init__(label, allowBlackbox, parent) 

1221 

1222 self._expression = expression 

1223 expression.Parent = self 

1224 

1225 # TODO: create a mixin for things with cases 

1226 self._cases = [] 

1227 if cases is not None: 1227 ↛ exitline 1227 didn't return from function '__init__' because the condition on line 1227 was always true

1228 for case in cases: 

1229 self._cases.append(case) 

1230 case.Parent = self 

1231 

1232 @GenerateStatement.Parent.setter 

1233 def Parent(self, parent: ModelEntity) -> None: 

1234 GenerateStatement.Parent.fset(self, parent) 

1235 

1236 # Connect namespaces 

1237 for case in self._cases: 

1238 case._namespace.ParentNamespace = parent._namespace 

1239 

1240 @readonly 

1241 def SelectExpression(self) -> ExpressionUnion: 

1242 """ 

1243 Read-only property to access the select expression (:attr:`_expression`). 

1244 

1245 :returns: The select expression. 

1246 """ 

1247 return self._expression 

1248 

1249 @readonly 

1250 def Cases(self) -> List[GenerateCase]: 

1251 """ 

1252 Read-only property to access the cases (:attr:`_cases`). 

1253 

1254 :returns: List of cases. 

1255 """ 

1256 return self._cases 

1257 

1258 def IterateInstantiations(self) -> Generator[Instantiation, None, None]: 

1259 for case in self._cases: 

1260 yield from case.IterateInstantiations() 

1261 

1262 def IndexStatement(self) -> None: 

1263 for case in self._cases: 

1264 case.IndexStatements() 

1265 

1266 

1267@export 

1268class ForGenerateStatement(GenerateStatement, ConcurrentDeclarationRegionMixin, ConcurrentStatementsMixin): 

1269 """ 

1270 Represents a for-generate statement. 

1271 

1272 The loop index is available as :data:`LoopIndex`, the iteration range as :data:`Range` and the 

1273 generated statements as :data:`Statements`. The label is mandatory. 

1274 

1275 .. admonition:: Example 

1276 

1277 .. code-block:: VHDL 

1278 

1279 gen : for i in 0 to 3 generate 

1280 --^^^ <- Label 

1281 -- ^ <- LoopIndex 

1282 -- ^^^^^^ <- Range 

1283 q(i) <= '0'; 

1284 -- ^^^^^^^^^^^^ <- Statements 

1285 end generate; 

1286 

1287 .. seealso:: 

1288 

1289 * :class:`If-generate statement <pyVHDLModel.Concurrent.IfGenerateStatement>` 

1290 * :class:`Case-generate statement <pyVHDLModel.Concurrent.CaseGenerateStatement>` 

1291 """ 

1292 

1293 _loopIndex: str #: The name of the generate loop's index. 

1294 _range: Range #: The range the generate loop iterates over. 

1295 

1296 _namespace: Namespace #: The namespace of the generate loop's declarative region. 

1297 

1298 def __init__( 

1299 self, 

1300 label: str, 

1301 loopIndex: str, 

1302 rng: Range, 

1303 declaredItems: Nullable[Iterable] = None, 

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

1305 allowBlackbox: Nullable[bool] = None, 

1306 parent: Nullable[ModelEntity] = None 

1307 ) -> None: 

1308 """ 

1309 Initializes a for-generate statement. 

1310 

1311 :param label: The label of a model entity. 

1312 :param loopIndex: The name of the generate loop's index. 

1313 :param rng: The range the generate loop iterates over. 

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

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

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

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

1318 """ 

1319 super().__init__(label, allowBlackbox, parent) 

1320 

1321 self._namespace = Namespace(self._normalizedLabel) 

1322 if parent is not None: 1322 ↛ 1323line 1322 didn't jump to line 1323 because the condition on line 1322 was never true

1323 self._namespace.ParentNamespace = parent._namespace 

1324 

1325 ConcurrentDeclarationRegionMixin.__init__(self, declaredItems) 

1326 ConcurrentStatementsMixin.__init__(self, statements) 

1327 

1328 self._loopIndex = loopIndex 

1329 

1330 self._range = rng 

1331 rng.Parent = self 

1332 

1333 @GenerateStatement.Parent.setter 

1334 def Parent(self, parent: ModelEntity) -> None: 

1335 GenerateStatement.Parent.fset(self, parent) 

1336 

1337 self._namespace.ParentNamespace = parent._namespace 

1338 

1339 @readonly 

1340 def LoopIndex(self) -> str: 

1341 """ 

1342 Read-only property to access the loop index (:attr:`_loopIndex`). 

1343 

1344 :returns: The loop index. 

1345 """ 

1346 return self._loopIndex 

1347 

1348 @readonly 

1349 def Range(self) -> Range: 

1350 """ 

1351 Read-only property to access the range (:attr:`_range`). 

1352 

1353 :returns: The range. 

1354 """ 

1355 return self._range 

1356 

1357 # IndexDeclaredItems = ConcurrentStatements.IndexDeclaredItems 

1358 

1359 def IndexStatement(self) -> None: 

1360 self.IndexStatements() 

1361 

1362 def IndexStatements(self) -> None: 

1363 super().IndexStatements() 

1364 

1365 def IterateInstantiations(self) -> Generator[Instantiation, None, None]: 

1366 return ConcurrentStatementsMixin.IterateInstantiations(self) 

1367 

1368 

1369@export 

1370class ConcurrentSignalAssignment(ConcurrentStatement, SignalAssignmentMixin): 

1371 """ 

1372 Represents the base-class of all concurrent signal assignments. 

1373 

1374 .. seealso:: 

1375 

1376 * :class:`Concurrent simple signal assignment <pyVHDLModel.Concurrent.ConcurrentSimpleSignalAssignment>` 

1377 * :class:`Concurrent selected signal assignment <pyVHDLModel.Concurrent.ConcurrentSelectedSignalAssignment>` 

1378 * :class:`Conditional signal assignment <pyVHDLModel.Concurrent.ConcurrentConditionalSignalAssignment>` """ 

1379 def __init__(self, label: str, target: SignalSymbol, parent: Nullable[ModelEntity] = None) -> None: 

1380 """ 

1381 Initializes a concurrent signal assignment. 

1382 

1383 :param label: The label of a model entity. 

1384 :param target: Reference to the assignment's destination. 

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

1386 """ 

1387 super().__init__(label, parent) 

1388 SignalAssignmentMixin.__init__(self, target) 

1389 

1390 

1391@export 

1392class ConcurrentSimpleSignalAssignment(ConcurrentSignalAssignment, WaveformMixin): 

1393 """ 

1394 Represents a simple concurrent signal assignment. 

1395 

1396 The assignment's destination is available as :data:`Target`, its value as :data:`Waveform`. 

1397 

1398 .. admonition:: Example 

1399 

1400 .. code-block:: VHDL 

1401 

1402 lbl : q <= '1'; 

1403 --^^^ <- optional Label 

1404 -- ^ <- Target 

1405 -- ^^^ <- Waveform 

1406 

1407 .. seealso:: 

1408 

1409 * :class:`Sequential counterpart <pyVHDLModel.Sequential.SequentialSimpleSignalAssignment>` 

1410 """ 

1411 def __init__(self, label: str, target: SignalSymbol, waveform: Iterable[WaveformElement], parent: Nullable[ModelEntity] = None) -> None: 

1412 """ 

1413 Initializes a simple concurrent signal assignment. 

1414 

1415 :param label: The label of a model entity. 

1416 :param target: Reference to the assignment's destination. 

1417 :param waveform: List of all waveform elements, in the order they were written. 

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

1419 """ 

1420 super().__init__(label, target, parent) 

1421 WaveformMixin.__init__(self, waveform) 

1422 

1423 

1424@export 

1425class ConcurrentSelectedSignalAssignment(ConcurrentSignalAssignment, ExpressionMixin, SelectedWaveformsMixin): 

1426 """ 

1427 Represents a selected concurrent signal assignment. 

1428 

1429 The selector is available as :data:`Expression`, the alternatives as :data:`SelectedWaveforms`, 

1430 a list of :class:`~pyVHDLModel.Common.SelectedWaveform`. The model holds them in a list and has 

1431 no distinct field per alternative, so the markers below name list elements. 

1432 

1433 .. admonition:: Example 

1434 

1435 .. code-block:: VHDL 

1436 

1437 lbl : with sel select q <= '1' when '0', '0' when others; 

1438 --^^^ <- optional Label 

1439 -- ^^^ <- Expression 

1440 -- ^ <- Target 

1441 -- ^^^^^^^^^^^^ <- SelectedWaveforms[0] 

1442 -- ^^^^^^^^^^^^^^^ <- SelectedWaveforms[1] 

1443 

1444 .. seealso:: 

1445 

1446 * :class:`Sequential counterpart <pyVHDLModel.Sequential.SequentialSelectedSignalAssignment>` 

1447 * :class:`Selected waveform <pyVHDLModel.Common.SelectedWaveform>` 

1448 """ 

1449 

1450 def __init__( 

1451 self, 

1452 label: str, 

1453 target: SignalSymbol, 

1454 expression: ExpressionUnion, 

1455 selectedWaveforms: Iterable[SelectedWaveform], 

1456 parent: Nullable[ModelEntity] = None 

1457 ) -> None: 

1458 """ 

1459 Initializes a selected concurrent signal assignment. 

1460 

1461 :param label: The label of a model entity. 

1462 :param target: Reference to the assignment's destination. 

1463 :param expression: The selector expression. 

1464 :param selectedWaveforms: All alternatives, in order. 

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

1466 """ 

1467 super().__init__(label, target, parent) 

1468 ExpressionMixin.__init__(self, expression) 

1469 SelectedWaveformsMixin.__init__(self, selectedWaveforms) 

1470 

1471 

1472@export 

1473class ConcurrentConditionalSignalAssignment(ConcurrentSignalAssignment, ConditionalWaveformsMixin): 

1474 """ 

1475 Represents a conditional concurrent signal assignment. 

1476 

1477 The alternatives are available as :data:`ConditionalWaveforms`, a list of 

1478 :class:`~pyVHDLModel.Common.ConditionalWaveform`. The model holds them in a list and has no 

1479 distinct field per alternative, so the markers below name list elements. 

1480 

1481 .. admonition:: Example 

1482 

1483 .. code-block:: VHDL 

1484 

1485 lbl : q <= '1' when cond else '0'; 

1486 --^^^ <- optional Label 

1487 -- ^ <- Target 

1488 -- ^^^^^^^^^^^^^ <- ConditionalWaveforms[0] 

1489 -- ^^^ <- ConditionalWaveforms[1] 

1490 

1491 .. seealso:: 

1492 

1493 * :class:`Sequential counterpart <pyVHDLModel.Sequential.SequentialConditionalSignalAssignment>` 

1494 * :class:`Conditional waveform <pyVHDLModel.Common.ConditionalWaveform>` 

1495 """ 

1496 

1497 def __init__( 

1498 self, 

1499 label: str, 

1500 target: SignalSymbol, 

1501 conditionalWaveforms: Iterable[ConditionalWaveform], 

1502 parent: Nullable[ModelEntity] = None 

1503 ) -> None: 

1504 """ 

1505 Initializes a conditional concurrent signal assignment. 

1506 

1507 :param label: The label of a model entity. 

1508 :param target: Reference to the assignment's destination. 

1509 :param conditionalWaveforms: All alternatives, in order. 

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

1511 """ 

1512 super().__init__(label, target, parent) 

1513 ConditionalWaveformsMixin.__init__(self, conditionalWaveforms) 

1514 

1515 

1516@export 

1517class ConcurrentAssertStatement(ConcurrentStatement, AssertStatementMixin): 

1518 """ 

1519 Represents a concurrent assertion statement. 

1520 

1521 The checked condition is available as :data:`Condition`, the optional report string as 

1522 :data:`Message` and the optional severity as :data:`Severity`. 

1523 

1524 .. admonition:: Example 

1525 

1526 .. code-block:: VHDL 

1527 

1528 lbl : assert cond report "bad" severity note; 

1529 --^^^ <- optional Label 

1530 -- ^^^^ <- Condition 

1531 -- ^^^^^ <- optional Message 

1532 -- ^^^^ <- optional Severity 

1533 

1534 .. seealso:: 

1535 

1536 * :class:`Sequential counterpart <pyVHDLModel.Sequential.SequentialAssertStatement>` 

1537 """ 

1538 def __init__( 

1539 self, 

1540 condition: ExpressionUnion, 

1541 message: ExpressionUnion, 

1542 severity: Nullable[ExpressionUnion] = None, 

1543 label: Nullable[str] = None, 

1544 parent: Nullable[ModelEntity] = None 

1545 ) -> None: 

1546 """ 

1547 Initializes a concurrent assertion statement. 

1548 

1549 :param condition: The condition guarding this statement. 

1550 :param message: The reported message, or ``None`` if none was given. 

1551 :param severity: The reported severity level, or ``None`` if none was given. 

1552 :param label: The label of a model entity. 

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

1554 """ 

1555 super().__init__(label, parent) 

1556 AssertStatementMixin.__init__(self, condition, message, severity)