Coverage for pyVHDLModel / Concurrent.py: 52%

367 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-04-24 22:37 +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 

44from pyVHDLModel.Regions import ConcurrentDeclarationRegionMixin 

45from pyVHDLModel.Namespace import Namespace 

46from pyVHDLModel.Name import Name 

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

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

49from pyVHDLModel.Association import AssociationItem, ParameterAssociationItem 

50from pyVHDLModel.Interface import PortInterfaceItemMixin 

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

52from pyVHDLModel.Sequential import SequentialStatement, SequentialStatementsMixin, SequentialDeclarationsMixin 

53 

54 

55ExpressionUnion = Union[ 

56 BaseExpression, 

57 QualifiedExpression, 

58 FunctionCall, 

59 TypeConversion, 

60 # ConstantOrSymbol, TODO: ObjectSymbol 

61 Literal, 

62] 

63 

64 

65@export 

66class ConcurrentStatement(Statement): 

67 """A base-class for all concurrent statements.""" 

68 

69 

70@export 

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

72 """ 

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

74 

75 .. seealso:: 

76 

77 .. todo:: concurrent declaration region 

78 """ 

79 

80 _statements: List[ConcurrentStatement] 

81 

82 _instantiations: Dict[str, 'Instantiation'] # TODO: add another instantiation class level for entity/configuration/component inst. 

83 _blocks: Dict[str, 'ConcurrentBlockStatement'] 

84 _generates: Dict[str, 'GenerateStatement'] 

85 _hierarchy: Dict[str, Union['ConcurrentBlockStatement', 'GenerateStatement']] 

86 

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

88 self._statements = [] 

89 

90 self._instantiations = {} 

91 self._blocks = {} 

92 self._generates = {} 

93 self._hierarchy = {} 

94 

95 if statements is not None: 

96 for statement in statements: 

97 self._statements.append(statement) 

98 statement._parent = self 

99 

100 @readonly 

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

102 return self._statements 

103 

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

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

106 yield instance 

107 

108 for block in self._blocks.values(): 108 ↛ 109line 108 didn't jump to line 109 because the loop on line 108 never started

109 yield from block.IterateInstantiations() 

110 

111 for generate in self._generates.values(): 111 ↛ 112line 111 didn't jump to line 112 because the loop on line 111 never started

112 yield from generate.IterateInstantiations() 

113 

114 # TODO: move into _init__ 

115 def IndexStatements(self) -> None: 

116 for statement in self._statements: 

117 if isinstance(statement, (EntityInstantiation, ComponentInstantiation, ConfigurationInstantiation)): 117 ↛ 119line 117 didn't jump to line 119 because the condition on line 117 was always true

118 self._instantiations[statement.NormalizedLabel] = statement 

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

120 self._generates[statement.NormalizedLabel] = statement 

121 statement.IndexStatement() 

122 elif isinstance(statement, ConcurrentBlockStatement): 

123 self._hierarchy[statement.NormalizedLabel] = statement 

124 statement.IndexStatements() 

125 

126 

127@export 

128class Instantiation(ConcurrentStatement): 

129 """ 

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

131 """ 

132 

133 _genericAssociations: List[AssociationItem] 

134 _portAssociations: List[AssociationItem] 

135 

136 def __init__( 

137 self, 

138 label: str, 

139 genericAssociations: Nullable[Iterable[AssociationItem]] = None, 

140 portAssociations: Nullable[Iterable[AssociationItem]] = None, 

141 parent: ModelEntity = None 

142 ) -> None: 

143 super().__init__(label, parent) 

144 

145 # TODO: extract to mixin 

146 self._genericAssociations = [] 

147 if genericAssociations is not None: 147 ↛ 148line 147 didn't jump to line 148 because the condition on line 147 was never true

148 for association in genericAssociations: 

149 self._genericAssociations.append(association) 

150 association._parent = self 

151 

152 # TODO: extract to mixin 

153 self._portAssociations = [] 

154 if portAssociations is not None: 154 ↛ 155line 154 didn't jump to line 155 because the condition on line 154 was never true

155 for association in portAssociations: 

156 self._portAssociations.append(association) 

157 association._parent = self 

158 

159 @readonly 

160 def GenericAssociations(self) -> List[AssociationItem]: 

161 return self._genericAssociations 

162 

163 @property 

164 def PortAssociations(self) -> List[AssociationItem]: 

165 return self._portAssociations 

166 

167 

168@export 

169class ComponentInstantiation(Instantiation): 

170 """ 

171 Represents a component instantiation by referring to a component name. 

172 

173 .. admonition:: Example 

174 

175 .. code-block:: VHDL 

176 

177 inst : component Counter; 

178 """ 

179 

180 _component: ComponentInstantiationSymbol 

181 

182 def __init__( 

183 self, 

184 label: str, 

185 componentSymbol: ComponentInstantiationSymbol, 

186 genericAssociations: Nullable[Iterable[AssociationItem]] = None, 

187 portAssociations: Nullable[Iterable[AssociationItem]] = None, 

188 parent: ModelEntity = None 

189 ) -> None: 

190 super().__init__(label, genericAssociations, portAssociations, parent) 

191 

192 self._component = componentSymbol 

193 componentSymbol._parent = self 

194 

195 @property 

196 def Component(self) -> ComponentInstantiationSymbol: 

197 return self._component 

198 

199 

200@export 

201class EntityInstantiation(Instantiation): 

202 """ 

203 Represents an entity instantiation by referring to an entity name with optional architecture name. 

204 

205 .. admonition:: Example 

206 

207 .. code-block:: VHDL 

208 

209 inst : entity work. Counter; 

210 """ 

211 

212 _entity: EntityInstantiationSymbol 

213 _architecture: ArchitectureSymbol 

214 

215 def __init__( 

216 self, 

217 label: str, 

218 entitySymbol: EntityInstantiationSymbol, 

219 architectureSymbol: Nullable[ArchitectureSymbol] = None, 

220 genericAssociations: Nullable[Iterable[AssociationItem]] = None, 

221 portAssociations: Nullable[Iterable[AssociationItem]] = None, 

222 parent: ModelEntity = None 

223 ) -> None: 

224 super().__init__(label, genericAssociations, portAssociations, parent) 

225 

226 self._entity = entitySymbol 

227 entitySymbol._parent = self 

228 

229 self._architecture = architectureSymbol 

230 if architectureSymbol is not None: 230 ↛ 231line 230 didn't jump to line 231 because the condition on line 230 was never true

231 architectureSymbol._parent = self 

232 

233 @property 

234 def Entity(self) -> EntityInstantiationSymbol: 

235 return self._entity 

236 

237 @property 

238 def Architecture(self) -> ArchitectureSymbol: 

239 return self._architecture 

240 

241 

242@export 

243class ConfigurationInstantiation(Instantiation): 

244 """ 

245 Represents a configuration instantiation by referring to a configuration name. 

246 

247 .. admonition:: Example 

248 

249 .. code-block:: VHDL 

250 

251 inst : configuration Counter; 

252 """ 

253 

254 _configuration: ConfigurationInstantiationSymbol 

255 

256 def __init__( 

257 self, 

258 label: str, 

259 configurationSymbol: ConfigurationInstantiationSymbol, 

260 genericAssociations: Nullable[Iterable[AssociationItem]] = None, 

261 portAssociations: Nullable[Iterable[AssociationItem]] = None, 

262 parent: ModelEntity = None 

263 ) -> None: 

264 super().__init__(label, genericAssociations, portAssociations, parent) 

265 

266 self._configuration = configurationSymbol 

267 configurationSymbol._parent = self 

268 

269 @property 

270 def Configuration(self) -> ConfigurationInstantiationSymbol: 

271 return self._configuration 

272 

273 

274@export 

275class ProcessStatement(ConcurrentStatement, SequentialDeclarationsMixin, SequentialStatementsMixin, DocumentedEntityMixin): 

276 """ 

277 Represents a process statement with sensitivity list, sequential declaration region and sequential statements. 

278 

279 .. admonition:: Example 

280 

281 .. code-block:: VHDL 

282 

283 proc: process(Clock) 

284 -- sequential declarations 

285 begin 

286 -- sequential statements 

287 end process; 

288 """ 

289 

290 _sensitivityList: List[Name] # TODO: implement a SignalSymbol 

291 

292 def __init__( 

293 self, 

294 label: Nullable[str] = None, 

295 declaredItems: Nullable[Iterable] = None, 

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

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

298 documentation: Nullable[str] = None, 

299 parent: ModelEntity = None 

300 ) -> None: 

301 super().__init__(label, parent) 

302 SequentialDeclarationsMixin.__init__(self, declaredItems) 

303 SequentialStatementsMixin.__init__(self, statements) 

304 DocumentedEntityMixin.__init__(self, documentation) 

305 

306 if sensitivityList is None: 

307 self._sensitivityList = None 

308 else: 

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

310 for signalSymbol in sensitivityList: 

311 self._sensitivityList.append(signalSymbol) 

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

313 

314 @property 

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

316 return self._sensitivityList 

317 

318 

319@export 

320class ConcurrentProcedureCall(ConcurrentStatement, ProcedureCallMixin): 

321 def __init__( 

322 self, 

323 label: str, 

324 procedureName: Name, 

325 parameterMappings: Nullable[Iterable[ParameterAssociationItem]] = None, 

326 parent: ModelEntity = None 

327 ) -> None: 

328 super().__init__(label, parent) 

329 ProcedureCallMixin.__init__(self, procedureName, parameterMappings) 

330 

331 

332@export 

333class ConcurrentBlockStatement(ConcurrentStatement, BlockStatementMixin, LabeledEntityMixin, ConcurrentDeclarationRegionMixin, ConcurrentStatementsMixin, DocumentedEntityMixin, AllowBlackboxMixin): 

334 _portItems: List[PortInterfaceItemMixin] 

335 

336 def __init__( 

337 self, 

338 label: str, 

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

340 declaredItems: Nullable[Iterable] = None, 

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

342 documentation: Nullable[str] = None, 

343 allowBlackbox: Nullable[bool] = None, 

344 parent: ModelEntity = None 

345 ) -> None: 

346 super().__init__(label, parent) 

347 BlockStatementMixin.__init__(self) 

348 LabeledEntityMixin.__init__(self, label) 

349 ConcurrentDeclarationRegionMixin.__init__(self, declaredItems) 

350 ConcurrentStatementsMixin.__init__(self, statements) 

351 DocumentedEntityMixin.__init__(self, documentation) 

352 AllowBlackboxMixin.__init__(self, allowBlackbox) 

353 

354 # TODO: extract to mixin 

355 self._portItems = [] 

356 if portItems is not None: 

357 for item in portItems: 

358 self._portItems.append(item) 

359 item._parent = self 

360 

361 @property 

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

363 return self._portItems 

364 

365 

366@export 

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

368 """ 

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

370 

371 .. seealso:: 

372 

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

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

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

376 """ 

377 

378 _alternativeLabel: Nullable[str] 

379 _normalizedAlternativeLabel: Nullable[str] 

380 

381 _namespace: Namespace 

382 

383 def __init__( 

384 self, 

385 declaredItems: Nullable[Iterable] = None, 

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

387 alternativeLabel: Nullable[str] = None, 

388 allowBlackbox: Nullable[bool] = None, 

389 parent: ModelEntity = None 

390 ) -> None: 

391 super().__init__(parent) 

392 ConcurrentDeclarationRegionMixin.__init__(self, declaredItems) 

393 ConcurrentStatementsMixin.__init__(self, statements) 

394 AllowBlackboxMixin.__init__(self, allowBlackbox) 

395 

396 self._alternativeLabel = alternativeLabel 

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

398 

399 self._namespace = Namespace(self._normalizedAlternativeLabel) 

400 

401 @property 

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

403 return self._alternativeLabel 

404 

405 @property 

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

407 return self._normalizedAlternativeLabel 

408 

409 

410@export 

411class IfGenerateBranch(GenerateBranch, IfBranchMixin): 

412 """ 

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

414 

415 .. admonition:: Example 

416 

417 .. code-block:: VHDL 

418 

419 gen: if condition generate 

420 -- concurrent declarations 

421 begin 

422 -- concurrent statements 

423 elsif condition generate 

424 -- ... 

425 else generate 

426 -- ... 

427 end generate; 

428 """ 

429 

430 def __init__( 

431 self, 

432 condition: ExpressionUnion, 

433 declaredItems: Nullable[Iterable] = None, 

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

435 alternativeLabel: Nullable[str] = None, 

436 allowBlackbox: Nullable[bool] = None, 

437 parent: ModelEntity = None 

438 ) -> None: 

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

440 IfBranchMixin.__init__(self, condition) 

441 

442 

443@export 

444class ElsifGenerateBranch(GenerateBranch, ElsifBranchMixin): 

445 """ 

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

447 

448 .. admonition:: Example 

449 

450 .. code-block:: VHDL 

451 

452 gen: if condition generate 

453 -- ... 

454 elsif condition generate 

455 -- concurrent declarations 

456 begin 

457 -- concurrent statements 

458 else generate 

459 -- ... 

460 end generate; 

461 """ 

462 

463 def __init__( 

464 self, 

465 condition: ExpressionUnion, 

466 declaredItems: Nullable[Iterable] = None, 

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

468 alternativeLabel: Nullable[str] = None, 

469 allowBlackbox: Nullable[bool] = None, 

470 parent: ModelEntity = None 

471 ) -> None: 

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

473 ElsifBranchMixin.__init__(self, condition) 

474 

475 

476@export 

477class ElseGenerateBranch(GenerateBranch, ElseBranchMixin): 

478 """ 

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

480 

481 .. admonition:: Example 

482 

483 .. code-block:: VHDL 

484 

485 gen: if condition generate 

486 -- ... 

487 elsif condition generate 

488 -- ... 

489 else generate 

490 -- concurrent declarations 

491 begin 

492 -- concurrent statements 

493 end generate; 

494 """ 

495 

496 def __init__( 

497 self, 

498 declaredItems: Nullable[Iterable] = None, 

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

500 alternativeLabel: Nullable[str] = None, 

501 allowBlackbox: Nullable[bool] = None, 

502 parent: ModelEntity = None 

503 ) -> None: 

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

505 ElseBranchMixin.__init__(self) 

506 

507 

508@export 

509class GenerateStatement(ConcurrentStatement, AllowBlackboxMixin): 

510 """ 

511 A base-class for all generate statements. 

512 

513 .. seealso:: 

514 

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

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

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

518 """ 

519 

520 _namespace: Namespace 

521 

522 def __init__( 

523 self, 

524 label: Nullable[str] = None, 

525 allowBlackbox: Nullable[bool] = None, 

526 parent: ModelEntity = None 

527 ) -> None: 

528 super().__init__(label, parent) 

529 AllowBlackboxMixin.__init__(self, allowBlackbox) 

530 

531 self._namespace = Namespace(self._normalizedLabel) 

532 

533 # @mustoverride 

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

535 raise NotImplementedError() 

536 

537 # @mustoverride 

538 def IndexStatement(self) -> None: 

539 raise NotImplementedError() 

540 

541 

542@export 

543class IfGenerateStatement(GenerateStatement): 

544 """ 

545 Represents an if...generate statement. 

546 

547 .. admonition:: Example 

548 

549 .. code-block:: VHDL 

550 

551 gen: if condition generate 

552 -- ... 

553 elsif condition generate 

554 -- ... 

555 else generate 

556 -- ... 

557 end generate; 

558 

559 .. seealso:: 

560 

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

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

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

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

565 """ 

566 

567 _ifBranch: IfGenerateBranch 

568 _elsifBranches: List[ElsifGenerateBranch] 

569 _elseBranch: Nullable[ElseGenerateBranch] 

570 

571 def __init__( 

572 self, 

573 label: str, 

574 ifBranch: IfGenerateBranch, 

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

576 elseBranch: Nullable[ElseGenerateBranch] = None, 

577 allowBlackbox: Nullable[bool] = None, 

578 parent: ModelEntity = None 

579 ) -> None: 

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

581 

582 self._ifBranch = ifBranch 

583 ifBranch._parent = self 

584 

585 self._elsifBranches = [] 

586 if elsifBranches is not None: 

587 for branch in elsifBranches: 

588 self._elsifBranches.append(branch) 

589 branch._parent = self 

590 

591 if elseBranch is not None: 

592 self._elseBranch = elseBranch 

593 elseBranch._parent = self 

594 else: 

595 self._elseBranch = None 

596 

597 @property 

598 def IfBranch(self) -> IfGenerateBranch: 

599 return self._ifBranch 

600 

601 @property 

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

603 return self._elsifBranches 

604 

605 @property 

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

607 return self._elseBranch 

608 

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

610 yield from self._ifBranch.IterateInstantiations() 

611 for branch in self._elsifBranches: 

612 yield from branch.IterateInstantiations() 

613 if self._elseBranch is not None: 

614 yield from self._ifBranch.IterateInstantiations() 

615 

616 def IndexStatement(self) -> None: 

617 self._ifBranch.IndexStatements() 

618 for branch in self._elsifBranches: 

619 branch.IndexStatements() 

620 if self._elseBranch is not None: 

621 self._elseBranch.IndexStatements() 

622 

623 

624@export 

625class ConcurrentChoice(BaseChoice): 

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

627 

628 

629@export 

630class IndexedGenerateChoice(ConcurrentChoice): 

631 _expression: ExpressionUnion 

632 

633 def __init__(self, expression: ExpressionUnion, parent: ModelEntity = None) -> None: 

634 super().__init__(parent) 

635 

636 self._expression = expression 

637 expression._parent = self 

638 

639 @property 

640 def Expression(self) -> ExpressionUnion: 

641 return self._expression 

642 

643 def __str__(self) -> str: 

644 return str(self._expression) 

645 

646 

647@export 

648class RangedGenerateChoice(ConcurrentChoice): 

649 _range: 'Range' 

650 

651 def __init__(self, rng: 'Range', parent: ModelEntity = None) -> None: 

652 super().__init__(parent) 

653 

654 self._range = rng 

655 rng._parent = self 

656 

657 @property 

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

659 return self._range 

660 

661 def __str__(self) -> str: 

662 return str(self._range) 

663 

664 

665@export 

666class ConcurrentCase(BaseCase, LabeledEntityMixin, ConcurrentDeclarationRegionMixin, ConcurrentStatementsMixin, AllowBlackboxMixin): 

667 def __init__( 

668 self, 

669 declaredItems: Nullable[Iterable] = None, 

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

671 alternativeLabel: Nullable[str] = None, 

672 allowBlackbox: Nullable[bool] = None, 

673 parent: ModelEntity = None 

674 ) -> None: 

675 super().__init__(parent) 

676 LabeledEntityMixin.__init__(self, alternativeLabel) 

677 ConcurrentDeclarationRegionMixin.__init__(self, declaredItems) 

678 ConcurrentStatementsMixin.__init__(self, statements) 

679 AllowBlackboxMixin.__init__(self, allowBlackbox) 

680 

681 

682@export 

683class GenerateCase(ConcurrentCase): 

684 _choices: List[ConcurrentChoice] 

685 

686 def __init__( 

687 self, 

688 choices: Iterable[ConcurrentChoice], 

689 declaredItems: Nullable[Iterable] = None, 

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

691 alternativeLabel: Nullable[str] = None, 

692 allowBlackbox: Nullable[bool] = None, 

693 parent: ModelEntity = None 

694 ) -> None: 

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

696 

697 # TODO: move to parent or grandparent 

698 self._choices = [] 

699 if choices is not None: 

700 for choice in choices: 

701 self._choices.append(choice) 

702 choice._parent = self 

703 

704 # TODO: move to parent or grandparent 

705 @property 

706 def Choices(self) -> List[ConcurrentChoice]: 

707 return self._choices 

708 

709 def __str__(self) -> str: 

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

711 

712 

713@export 

714class OthersGenerateCase(ConcurrentCase): 

715 def __str__(self) -> str: 

716 return "when others =>" 

717 

718 

719@export 

720class CaseGenerateStatement(GenerateStatement): 

721 """ 

722 Represents a case...generate statement. 

723 

724 .. admonition:: Example 

725 

726 .. code-block:: VHDL 

727 

728 gen: case selector generate 

729 case choice1 => 

730 -- ... 

731 case choice2 => 

732 -- ... 

733 case others => 

734 -- ... 

735 end generate; 

736 """ 

737 

738 _expression: ExpressionUnion 

739 _cases: List[GenerateCase] 

740 

741 def __init__( 

742 self, 

743 label: str, 

744 expression: ExpressionUnion, 

745 cases: Iterable[ConcurrentCase], 

746 allowBlackbox: Nullable[bool] = None, 

747 parent: ModelEntity = None 

748 ) -> None: 

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

750 

751 self._expression = expression 

752 expression._parent = self 

753 

754 # TODO: create a mixin for things with cases 

755 self._cases = [] 

756 if cases is not None: 

757 for case in cases: 

758 self._cases.append(case) 

759 case._parent = self 

760 

761 @property 

762 def SelectExpression(self) -> ExpressionUnion: 

763 return self._expression 

764 

765 @property 

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

767 return self._cases 

768 

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

770 for case in self._cases: 

771 yield from case.IterateInstantiations() 

772 

773 def IndexStatement(self) -> None: 

774 for case in self._cases: 

775 case.IndexStatements() 

776 

777 

778@export 

779class ForGenerateStatement(GenerateStatement, ConcurrentDeclarationRegionMixin, ConcurrentStatementsMixin): 

780 """ 

781 Represents a for...generate statement. 

782 

783 .. admonition:: Example 

784 

785 .. code-block:: VHDL 

786 

787 gen: for i in 0 to 3 generate 

788 -- ... 

789 end generate; 

790 """ 

791 

792 _loopIndex: str 

793 _range: Range 

794 

795 def __init__( 

796 self, 

797 label: str, 

798 loopIndex: str, 

799 rng: Range, 

800 declaredItems: Nullable[Iterable] = None, 

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

802 allowBlackbox: Nullable[bool] = None, 

803 parent: ModelEntity = None 

804 ) -> None: 

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

806 ConcurrentDeclarationRegionMixin.__init__(self, declaredItems) 

807 ConcurrentStatementsMixin.__init__(self, statements) 

808 

809 self._loopIndex = loopIndex 

810 

811 self._range = rng 

812 rng._parent = self 

813 

814 @property 

815 def LoopIndex(self) -> str: 

816 return self._loopIndex 

817 

818 @property 

819 def Range(self) -> Range: 

820 return self._range 

821 

822 # IndexDeclaredItems = ConcurrentStatements.IndexDeclaredItems 

823 

824 def IndexStatement(self) -> None: 

825 self.IndexStatements() 

826 

827 def IndexStatements(self) -> None: 

828 super().IndexStatements() 

829 

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

831 return ConcurrentStatementsMixin.IterateInstantiations(self) 

832 

833 

834@export 

835class ConcurrentSignalAssignment(ConcurrentStatement, SignalAssignmentMixin): 

836 """ 

837 A base-class for concurrent signal assignments. 

838 

839 .. seealso:: 

840 

841 * :class:`~pyVHDLModel.Concurrent.ConcurrentSimpleSignalAssignment` 

842 * :class:`~pyVHDLModel.Concurrent.ConcurrentSelectedSignalAssignment` 

843 * :class:`~pyVHDLModel.Concurrent.ConcurrentConditionalSignalAssignment` 

844 """ 

845 def __init__(self, label: str, target: Name, parent: ModelEntity = None) -> None: 

846 super().__init__(label, parent) 

847 SignalAssignmentMixin.__init__(self, target) 

848 

849 

850@export 

851class ConcurrentSimpleSignalAssignment(ConcurrentSignalAssignment): 

852 _waveform: List[WaveformElement] 

853 

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

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

856 

857 # TODO: extract to mixin 

858 self._waveform = [] 

859 if waveform is not None: 

860 for waveformElement in waveform: 

861 self._waveform.append(waveformElement) 

862 waveformElement._parent = self 

863 

864 @property 

865 def Waveform(self) -> List[WaveformElement]: 

866 return self._waveform 

867 

868 

869@export 

870class ConcurrentSelectedSignalAssignment(ConcurrentSignalAssignment): 

871 def __init__(self, label: str, target: Name, expression: ExpressionUnion, parent: ModelEntity = None) -> None: 

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

873 

874 

875@export 

876class ConcurrentConditionalSignalAssignment(ConcurrentSignalAssignment): 

877 def __init__(self, label: str, target: Name, expression: ExpressionUnion, parent: ModelEntity = None) -> None: 

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

879 

880 

881@export 

882class ConcurrentAssertStatement(ConcurrentStatement, AssertStatementMixin): 

883 def __init__( 

884 self, 

885 condition: ExpressionUnion, 

886 message: ExpressionUnion, 

887 severity: Nullable[ExpressionUnion] = None, 

888 label: Nullable[str] = None, 

889 parent: ModelEntity = None 

890 ) -> None: 

891 super().__init__(label, parent) 

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