Coverage for pyVHDLModel/Formatting/VHDL.py: 99%
1103 statements
« prev ^ index » next coverage.py v7.17.0, created at 2026-10-25 10:05 +0000
« 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 2026-2026 Patrick Lehmann - Bötzingen, Germany #
15# #
16# Licensed under the Apache License, Version 2.0 (the "License"); #
17# you may not use this file except in compliance with the License. #
18# You may obtain a copy of the License at #
19# #
20# http://www.apache.org/licenses/LICENSE-2.0 #
21# #
22# Unless required by applicable law or agreed to in writing, software #
23# distributed under the License is distributed on an "AS IS" BASIS, #
24# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
25# See the License for the specific language governing permissions and #
26# limitations under the License. #
27# #
28# SPDX-License-Identifier: Apache-2.0 #
29# ==================================================================================================================== #
30#
31"""
32This module contains a writer, which formats a VHDL language model as VHDL source text.
34The writer is a :class:`~pyVHDLModel.Visitor.Visitor`: a model element walks itself and the writer appends the VHDL
35source text of each event to a buffer. A parser's subclass of a model class (e.g. from ``pyGHDL.dom``) is written like
36that model class. Writing is a re-format: comments, blank lines and the letter case of reserved words in a parsed source
37are not preserved.
38"""
39from __future__ import annotations
41from enum import Enum, unique
42from math import copysign, isfinite
43from typing import ClassVar, Iterable, Optional as Nullable
45from pyTooling.Common import getFullyQualifiedName
46from pyTooling.Decorators import export, readonly
47from pyTooling.MetaClasses import ExtendedType
49from pyVHDLModel.Association import AssociationItem, GenericMapAspectMixin, PortMapAspectMixin
50from pyVHDLModel.Base import ModelElementUnion, ModelEntity, Mode, ReservedWord, SimpleRange, RangeFromName, \
51 WaveformElement, ReportStatementMixin
52from pyVHDLModel.Common import Statement, ProcedureCallMixin, SignalAssignmentMixin, WaveformMixin, \
53 ConditionalWaveform, SelectedWaveform, OthersSelectedWaveform, \
54 ConditionalWaveformsMixin, SelectedWaveformsMixin, AssignmentMixin, \
55 ConditionalExpression, SelectedExpression, OthersSelectedExpression, \
56 SelectedExpressionsMixin
57from pyVHDLModel.Concurrent import ProcessStatement, ConcurrentProcedureCall, ConcurrentSimpleSignalAssignment, \
58 ConcurrentSelectedSignalAssignment, ConcurrentConditionalSignalAssignment, \
59 ConcurrentAssertStatement, ComponentInstantiation, EntityInstantiation, \
60 ConfigurationInstantiation, ConcurrentBlockStatement, GenerateBranch, \
61 IfGenerateBranch, ElsifGenerateBranch, ElseGenerateBranch, IfGenerateStatement, \
62 IndexedGenerateChoice, ConcurrentCase, GenerateCase, OthersGenerateCase, \
63 CaseGenerateStatement, ForGenerateStatement
64from pyVHDLModel.Configuration import EntityAspectEntity, EntityAspectConfiguration, EntityAspectOpen, \
65 BindingIndication, AllInstantiationList, OthersInstantiationList, \
66 ComponentConfiguration, BlockConfiguration
67from pyVHDLModel.Declaration import EntityClass, Attribute, AttributeSpecification, Alias
68from pyVHDLModel.DesignUnit import Reference, LibraryClause, UseClause, ContextReference, DesignUnit, Context, \
69 Package, PackageBody, Entity, Architecture, Configuration, Component
70from pyVHDLModel.Exception import VHDLWriterError
71from pyVHDLModel.Expression import OperatorPrecedence, NullLiteral, EnumerationLiteral, IntegerLiteral, \
72 FloatingPointLiteral, PhysicalIntegerLiteral, PhysicalFloatingLiteral, \
73 CharacterLiteral, StringLiteral, BitStringBase, BitStringLiteral, \
74 UnaryExpression, NegationExpression, IdentityExpression, TypeConversion, \
75 SubExpression, BinaryExpression, RangeExpression, AddingExpression, \
76 MultiplyingExpression, ExponentiationExpression, LogicalExpression, \
77 AndExpression, OrExpression, XorExpression, XnorExpression, \
78 RelationalExpression, ShiftExpression, QualifiedExpression, WhenElseExpression, \
79 SubtypeAllocation, QualifiedExpressionAllocation, SimpleAggregateElement, \
80 IndexedAggregateElement, RangedAggregateElement, NamedAggregateElement, \
81 OthersAggregateElement, Aggregate
82from pyVHDLModel.Name import SimpleName, ParenthesisName, IndexedName, SlicedName, SelectedName, \
83 AttributeName, AllName, OpenName
84from pyVHDLModel.Interface import ModeViewDeclaration, SimpleModeViewElement, CompositeModeViewElement, \
85 GenericConstantInterfaceItem, GenericTypeInterfaceItem, \
86 PortSimpleSignalInterfaceItem, PortViewSignalInterfaceItem, \
87 ParameterConstantInterfaceItem, ParameterVariableInterfaceItem, \
88 ParameterSimpleSignalInterfaceItem, ParameterViewSignalInterfaceItem, \
89 ParameterFileInterfaceItem, GenericProcedureInterfaceItem, \
90 GenericFunctionInterfaceItem
91from pyVHDLModel.Instantiation import ProcedureInstantiation, FunctionInstantiation, PackageInstantiation
92from pyVHDLModel.Object import Obj, WithDefaultExpressionMixin, Constant, DeferredConstant, Variable, \
93 SharedVariable, Signal, File
94from pyVHDLModel.Regions import WithGenericsMixin, WithPortsMixin, WithParametersMixin
95from pyVHDLModel.Sequential import IndexedChoice, SequentialProcedureCall, SequentialSimpleSignalAssignment, \
96 SequentialVariableAssignment, SequentialConditionalVariableAssignment, \
97 SequentialConditionalSignalAssignment, SequentialSelectedVariableAssignment, \
98 SequentialSelectedSignalAssignment, SignalForceAssignment, \
99 SignalReleaseAssignment, SequentialReportStatement, SequentialAssertStatement, \
100 NullStatement, ReturnStatement, WaitStatement, IfBranch, ElsifBranch, \
101 ElseBranch, IfStatement, SequentialCase, Case, OthersCase, CaseStatement, \
102 LoopStatement, EndlessLoopStatement, ForLoopStatement, WhileLoopStatement, \
103 LoopControlStatement, NextStatement, ExitStatement
104from pyVHDLModel.Subprogram import Subprogram, Procedure, Function
105from pyVHDLModel.Symbol import Symbol, ConstrainedScalarSubtypeSymbol, ConstrainedArraySubtypeSymbol, \
106 ConstrainedRecordSubtypeSymbol
107from pyVHDLModel.Type import AnonymousType, FullType, Subtype, EnumeratedType, IntegerType, RealType, \
108 PhysicalType, ArrayType, RecordTypeElement, RecordType, AccessType, FileType, \
109 ProtectedType, ProtectedTypeBody
110from pyVHDLModel.Visitor import Visitor
113@export
114@unique
115class KeywordCase(Enum):
116 """
117 An enumeration of letter cases for VHDL reserved words in the written source text.
119 .. seealso::
121 :ref:`vsg:configuring-uppercase-and-lowercase-rules`
122 |rarr| vhdl-style-guide's option ``case``.
123 """
125 Lower = 0 #: Lower case, e.g. ``downto``.
126 Upper = 1 #: Upper case, e.g. ``DOWNTO``.
129@export
130@unique
131class IndentStyle(Enum):
132 """
133 An enumeration of indentation styles of the written source text, as vhdl-style-guide's option ``indent_style``.
135 .. seealso::
137 :ref:`vsg:configuring-indent-rules`
138 |rarr| vhdl-style-guide's options ``indent_style`` and ``indent_size``, with an example of smart tabs.
139 """
141 Spaces = 0 #: Spaces, ``indent_size`` per indentation level (VSG: ``spaces``).
142 SmartTabs = 1 #: One tab per indentation level (VSG: ``smart_tabs`` - tabs indent, spaces align).
145@export
146class VHDLStyle(metaclass=ExtendedType, slots=True):
147 """
148 Represents the formatting options of the :class:`VHDL writer <VHDLWriter>`.
150 The options follow vhdl-style-guide's names and values.
152 .. seealso::
154 :ref:`vsg:configuring-uppercase-and-lowercase-rules`
155 |rarr| vhdl-style-guide's option ``case``.
156 :ref:`vsg:configuring-indent-rules`
157 |rarr| vhdl-style-guide's options ``indent_style`` and ``indent_size``.
158 """
160 _keywordCase: KeywordCase #: Letter case of reserved words.
161 _indentStyle: IndentStyle #: Indentation style.
162 _indentSize: int #: Number of spaces per indentation level.
164 def __init__(
165 self,
166 keywordCase: KeywordCase = KeywordCase.Lower,
167 indentStyle: IndentStyle = IndentStyle.Spaces,
168 indentSize: int = 2
169 ) -> None:
170 """
171 Initializes the formatting options.
173 :param keywordCase: Optional, letter case of reserved words. Default: ``KeywordCase.Lower``.
174 :param indentStyle: Optional, indentation style. Default: ``IndentStyle.Spaces``.
175 :param indentSize: Optional, number of spaces per indentation level. Default: ``2``.
176 :raises ValueError: If parameter 'keywordCase' is None.
177 :raises TypeError: If parameter 'keywordCase' is not of type :class:`KeywordCase`.
178 :raises ValueError: If parameter 'indentStyle' is None.
179 :raises TypeError: If parameter 'indentStyle' is not of type :class:`IndentStyle`.
180 :raises ValueError: If parameter 'indentSize' is None.
181 :raises TypeError: If parameter 'indentSize' is not of type :class:`int`.
182 :raises ValueError: If parameter 'indentSize' is less than 1.
183 """
184 if keywordCase is None:
185 raise ValueError("Parameter 'keywordCase' is None.")
186 elif not isinstance(keywordCase, KeywordCase):
187 ex = TypeError("Parameter 'keywordCase' is not of type 'KeywordCase'.")
188 ex.add_note(f"Got type '{getFullyQualifiedName(keywordCase)}'.")
189 raise ex
191 if indentStyle is None:
192 raise ValueError("Parameter 'indentStyle' is None.")
193 elif not isinstance(indentStyle, IndentStyle):
194 ex = TypeError("Parameter 'indentStyle' is not of type 'IndentStyle'.")
195 ex.add_note(f"Got type '{getFullyQualifiedName(indentStyle)}'.")
196 raise ex
198 if indentSize is None:
199 raise ValueError("Parameter 'indentSize' is None.")
200 elif not isinstance(indentSize, int) or isinstance(indentSize, bool):
201 ex = TypeError("Parameter 'indentSize' is not of type 'int'.")
202 ex.add_note(f"Got type '{getFullyQualifiedName(indentSize)}'.")
203 raise ex
204 elif indentSize < 1:
205 ex = ValueError("Parameter 'indentSize' is less than 1.")
206 ex.add_note(f"Got value '{indentSize}'.")
207 raise ex
209 self._keywordCase = keywordCase
210 self._indentStyle = indentStyle
211 self._indentSize = indentSize
213 @readonly
214 def KeywordCase(self) -> KeywordCase:
215 """
216 Read-only property to access the letter case of reserved words (:attr:`_keywordCase`).
218 :returns: The letter case of reserved words.
219 """
220 return self._keywordCase
222 @readonly
223 def IndentStyle(self) -> IndentStyle:
224 """
225 Read-only property to access the indentation style (:attr:`_indentStyle`).
227 :returns: The indentation style.
228 """
229 return self._indentStyle
231 @readonly
232 def IndentSize(self) -> int:
233 """
234 Read-only property to access the number of spaces per indentation level (:attr:`_indentSize`).
236 :returns: The number of spaces per indentation level.
237 """
238 return self._indentSize
243@export
244class VHDLWriter(Visitor):
245 """
246 A writer formatting VHDL language model elements as VHDL source text.
248 The writer handles the :mod:`visitor events <pyVHDLModel.Visitor>` of each supported model class. An element of a
249 class without a walk of its own raises :exc:`NotImplementedError`; nothing is skipped.
251 Expressions are written with the parentheses VHDL's operator precedence requires (IEEE Std 1076-2008, clause 9.2).
252 Parentheses from the source (:class:`~pyVHDLModel.Expression.SubExpression`) are kept. Symbols are written from their
253 :attr:`~pyVHDLModel.Symbol.Symbol.Name`, whether resolved or not.
254 """
256 _BASE_SPECIFIERS: ClassVar[dict[BitStringBase, str]] = {
257 BitStringBase.Binary: "b",
258 BitStringBase.Octal: "o",
259 BitStringBase.Decimal: "d",
260 BitStringBase.Hexadecimal: "x",
261 } #: Dictionary of base specifiers, indexed by bit string base.
263 _style: VHDLStyle #: Formatting options.
264 _buffer: list[str] #: Fragments of the VHDL source text written by :meth:`Format`.
265 _minimum: OperatorPrecedence #: Loosest precedence of the next operand without parentheses.
266 _frames: list[tuple[OperatorPrecedence, bool]] #: Stack of entered operands: precedence and if in parentheses.
267 _indentation: int #: Indentation level of the next line.
269 def __init__(self, style: Nullable[VHDLStyle] = None) -> None:
270 """
271 Initializes a VHDL writer.
273 :param style: Optional, formatting options. Default: ``VHDLStyle()``.
274 :raises TypeError: If parameter 'style' is not of type :class:`VHDLStyle`.
275 """
276 super().__init__()
278 if style is None:
279 style = VHDLStyle()
280 elif not isinstance(style, VHDLStyle):
281 ex = TypeError("Parameter 'style' is not of type 'VHDLStyle'.")
282 ex.add_note(f"Got type '{getFullyQualifiedName(style)}'.")
283 raise ex
285 self._style = style
286 self._buffer = []
287 self._minimum = OperatorPrecedence.Range
288 self._frames = []
289 self._indentation = 0
291 @readonly
292 def Style(self) -> VHDLStyle:
293 """
294 Read-only property to access the formatting options (:attr:`_style`).
296 :returns: The formatting options.
297 """
298 return self._style
300 def Format(self, element: ModelElementUnion) -> str:
301 """
302 Format a model element as VHDL source text.
304 Each call starts with an empty buffer at indentation level 0. A declaration, a statement or a design unit ends with
305 a newline.
307 :param element: The model element to format.
308 :returns: The VHDL source text.
309 :raises ValueError: If parameter 'element' is None.
310 :raises TypeError: If parameter 'element' is not of type :class:`~pyVHDLModel.Base.ModelEntity` or
311 :class:`~pyVHDLModel.Symbol.Symbol`.
312 :raises NotImplementedError: If the class of the element or of one of its children has no walk of its own.
313 :raises VHDLWriterError: If the element or one of its children has no VHDL notation.
314 """
315 if element is None:
316 raise ValueError("Parameter 'element' is None.")
317 elif not isinstance(element, (ModelEntity, Symbol)):
318 ex = TypeError("Parameter 'element' is not of type 'ModelEntity' or 'Symbol'.")
319 ex.add_note(f"Got type '{getFullyQualifiedName(element)}'.")
320 raise ex
322 self._buffer = []
323 self._minimum = OperatorPrecedence.Range
324 self._frames = []
325 self._indentation = 0
326 element.Visit(self)
327 return "".join(self._buffer)
329 def VisitLeftParenthesis(
330 self,
331 element: IndexedName | ParenthesisName | TypeConversion | EntityAspectEntity | EntityInstantiation
332 ) -> None:
333 """
334 Write the left parenthesis opening a parenthesized list.
336 :param element: The element enclosing the list.
337 """
338 self._Write("(")
339 self._minimum = OperatorPrecedence.Range
341 def _Write(self, text: str) -> None:
342 """
343 Append VHDL source text to the buffer.
345 :param text: The VHDL source text.
346 """
347 self._buffer.append(text)
349 def VisitComma(
350 self,
351 element: IndexedName | ParenthesisName | Aggregate | ConstrainedArraySubtypeSymbol |
352 ConstrainedRecordSubtypeSymbol | EnumeratedType | ArrayType | AttributeSpecification |
353 GenericMapAspectMixin | PortMapAspectMixin | Reference | ComponentConfiguration | ProcessStatement |
354 ProcedureCallMixin | WaveformMixin | SelectedWaveformsMixin | SelectedExpressionsMixin | WaitStatement
355 ) -> None:
356 """
357 Write the comma between two items of a list.
359 In a map aspect, the next association starts on a new line.
361 :param element: The element containing the list.
362 """
363 if isinstance(element, (GenericMapAspectMixin, PortMapAspectMixin)):
364 self._Write(",\n")
365 self._WriteIndentation()
366 else:
367 self._Write(", ")
369 self._minimum = OperatorPrecedence.Range
371 def VisitArrow(
372 self,
373 element: AssociationItem | IndexedAggregateElement | RangedAggregateElement | NamedAggregateElement |
374 ConcurrentCase | SequentialCase
375 ) -> None:
376 """
377 Write the arrow (``=>``) between a choice or formal and its value.
379 After the choices of a case or case-generate alternative, the alternative's body follows on new lines, indented.
381 :param element: The element containing the arrow.
382 """
383 if isinstance(element, (ConcurrentCase, SequentialCase)):
384 self._Write(" =>\n")
385 self._indentation += 1
386 else:
387 self._Write(" => ")
388 self._minimum = OperatorPrecedence.Range
390 def VisitApostrophe(self, expression: QualifiedExpression) -> None:
391 """
392 Write the apostrophe of a qualified expression and, unless the operand brings its own, a left parenthesis.
394 An aggregate or a parenthesized sub-expression brings its own parentheses.
396 :param expression: The qualified expression.
397 """
398 if isinstance(expression.Operand, (Aggregate, SubExpression)):
399 self._Write("'")
400 else:
401 self._Write("'(")
403 self._minimum = OperatorPrecedence.Range
405 def VisitWhen(
406 self,
407 element: WhenElseExpression | ConditionalWaveform | SelectedWaveform | OthersSelectedWaveform |
408 ConditionalExpression | SelectedExpression | OthersSelectedExpression | LoopControlStatement
409 ) -> None:
410 """
411 Write the reserved word ``when`` of a conditional expression or waveform, or of a selected waveform or expression.
413 :param element: The conditional expression, the conditional waveform or the selected waveform or expression.
414 """
415 self._Write(f" {self._Keyword(ReservedWord.When)} ")
416 if isinstance(element, WhenElseExpression):
417 self._minimum = OperatorPrecedence.Logical
418 else:
419 self._minimum = OperatorPrecedence.Range
421 def _Keyword(self, keyword: ReservedWord) -> str:
422 """
423 Apply the keyword case of the formatting options to a reserved word.
425 :param keyword: The reserved word.
426 :returns: The reserved word in the configured letter case.
427 """
428 if self._style.KeywordCase is KeywordCase.Upper:
429 return keyword.value.upper()
431 return keyword.value
433 def _Keywords(self, keywords: Iterable[ReservedWord]) -> str:
434 """
435 Apply the keyword case of the formatting options to reserved words and join them by spaces.
437 **Format:** ``shared variable``, ``protected body``
439 :param keywords: The reserved words.
440 :returns: The reserved words in the configured letter case, separated by spaces.
441 """
442 return " ".join(self._Keyword(keyword) for keyword in keywords)
444 def VisitElse(
445 self,
446 element: WhenElseExpression | ConditionalWaveformsMixin | SequentialConditionalVariableAssignment
447 ) -> None:
448 """
449 Write the reserved word ``else`` of a conditional expression or between the alternatives of an assignment.
451 :param element: The conditional expression or the conditional assignment.
452 """
453 self._Write(f" {self._Keyword(ReservedWord.Else)} ")
454 if isinstance(element, WhenElseExpression):
455 self._minimum = OperatorPrecedence.Conditional
456 else:
457 self._minimum = OperatorPrecedence.Range
459 def VisitOperator(self, expression: BinaryExpression) -> None:
460 """
461 Write the operator of a binary expression.
463 The right operand binds tighter than the operator, unless it's a primary.
465 :param expression: The binary expression.
466 """
467 precedence, _ = self._frames[-1]
468 if (reservedWord := expression._RESERVED_WORD) is None:
469 self._Write(f" {expression._FORMAT[1].strip()} ")
470 else:
471 self._Write(f" {self._Keyword(reservedWord)} ")
473 self._minimum = OperatorPrecedence(min(precedence + 1, OperatorPrecedence.Primary))
475 def VisitDirection(self, rng: RangeExpression | SimpleRange) -> None:
476 """
477 Write the direction of a range.
479 :param rng: The range.
480 """
481 self._Write(f" {self._Keyword(rng.Direction.ReservedWord)} ")
482 self._minimum = OperatorPrecedence.Adding
484 def VisitNullLiteral(self, literal: NullLiteral) -> None:
485 """
486 Write a null literal.
488 **Format:** ``null``
490 :param literal: The null literal.
491 """
492 self._Write(self._Keyword(ReservedWord.Null))
494 def VisitEnumerationLiteral(self, literal: EnumerationLiteral) -> None:
495 """
496 Write an enumeration literal.
498 **Format:** ``Idle``
500 :param literal: The enumeration literal.
501 """
502 self._Write(literal.Value)
504 def VisitIntegerLiteral(self, literal: IntegerLiteral) -> None:
505 """
506 Write an integer literal.
508 **Format:** ``42``
510 A negative value is written with a sign, so it binds like a sign.
512 :param literal: The integer literal.
513 """
514 self._Enter(OperatorPrecedence.Adding if literal.Value < 0 else OperatorPrecedence.Primary)
515 self._Write(str(literal.Value))
517 def _Enter(self, precedence: OperatorPrecedence) -> None:
518 """
519 Enter an operand and write a left parenthesis, if it binds looser than its position allows.
521 :param precedence: The precedence level of the operand.
522 """
523 parenthesized = precedence < self._minimum
524 if parenthesized:
525 self._Write("(")
527 self._frames.append((precedence, parenthesized))
529 def DepartIntegerLiteral(self, literal: IntegerLiteral) -> None:
530 """
531 Leave an integer literal.
533 :param literal: The integer literal.
534 """
535 self._Leave()
537 def _Leave(self) -> None:
538 """
539 Leave an operand and write a right parenthesis, if it was entered with a left parenthesis.
540 """
541 _, parenthesized = self._frames.pop()
542 if parenthesized:
543 self._Write(")")
545 def VisitFloatingPointLiteral(self, literal: FloatingPointLiteral) -> None:
546 """
547 Write a floating-point literal.
549 **Format:** ``3.5``
551 A negative value is written with a sign, so it binds like a sign.
553 :param literal: The floating-point literal.
554 """
555 self._Enter(self._PrecedenceOfReal(literal.Value))
556 self._Write(self._FormatReal(literal, literal.Value))
558 def DepartFloatingPointLiteral(self, literal: FloatingPointLiteral) -> None:
559 """
560 Leave a floating-point literal.
562 :param literal: The floating-point literal.
563 """
564 self._Leave()
566 @staticmethod
567 def _PrecedenceOfReal(value: float) -> OperatorPrecedence:
568 """
569 Determine how tight a floating-point value binds as an operand.
571 A negative value, ``-0.0`` included, is written with a sign, so it binds like a sign.
573 :param value: The floating-point value.
574 :returns: The precedence level.
575 """
576 if copysign(1.0, value) < 0.0:
577 return OperatorPrecedence.Adding
579 return OperatorPrecedence.Primary
581 def _FormatReal(self, element: ModelEntity, value: float) -> str:
582 """
583 Format a floating-point value as VHDL abstract literal with a decimal point.
585 **Format:** ``1.0e-09``
587 :param element: The model element carrying the value.
588 :param value: The floating-point value.
589 :returns: The VHDL source text.
590 :raises VHDLWriterError: If the value is infinite or not a number.
591 """
592 if not isfinite(value):
593 ex = VHDLWriterError("Floating-point value has no VHDL notation.", element)
594 ex.add_note(f"Got value '{value}'.")
595 raise ex
597 mantissa, separator, exponent = repr(float(value)).partition("e")
598 if "." not in mantissa:
599 mantissa = f"{mantissa}.0"
601 return f"{mantissa}{separator}{exponent}"
603 def VisitPhysicalIntegerLiteral(self, literal: PhysicalIntegerLiteral) -> None:
604 """
605 Write a physical literal with an integer value.
607 **Format:** ``10 ns``
609 :param literal: The physical literal.
610 """
611 self._Enter(OperatorPrecedence.Adding if literal.Value < 0 else OperatorPrecedence.Primary)
612 self._Write(f"{literal.Value} {literal.UnitName}")
614 def DepartPhysicalIntegerLiteral(self, literal: PhysicalIntegerLiteral) -> None:
615 """
616 Leave a physical literal with an integer value.
618 :param literal: The physical literal.
619 """
620 self._Leave()
622 def VisitPhysicalFloatingLiteral(self, literal: PhysicalFloatingLiteral) -> None:
623 """
624 Write a physical literal with a floating-point value.
626 **Format:** ``1.5 ns``
628 :param literal: The physical literal.
629 """
630 self._Enter(self._PrecedenceOfReal(literal.Value))
631 self._Write(f"{self._FormatReal(literal, literal.Value)} {literal.UnitName}")
633 def DepartPhysicalFloatingLiteral(self, literal: PhysicalFloatingLiteral) -> None:
634 """
635 Leave a physical literal with a floating-point value.
637 :param literal: The physical literal.
638 """
639 self._Leave()
641 def VisitCharacterLiteral(self, literal: CharacterLiteral) -> None:
642 """
643 Write a character literal.
645 **Format:** ``'a'``
647 :param literal: The character literal.
648 :raises VHDLWriterError: If the value is not a single graphic character.
649 """
650 if len(literal.Value) != 1 or not self._IsGraphic(literal.Value):
651 ex = VHDLWriterError("Character literal is not a single graphic character.", literal)
652 ex.add_note(f"Got value {literal.Value!r}.")
653 raise ex
655 self._Write(f"'{literal.Value}'")
657 @staticmethod
658 def _IsGraphic(text: str) -> bool:
659 """
660 Check if all characters are VHDL graphic characters (ISO/IEC 8859-1 without control characters).
662 :param text: The text to check.
663 :returns: ``True``, if all characters are graphic characters.
664 """
665 return all(32 <= ord(character) <= 126 or 160 <= ord(character) <= 255 for character in text)
667 def VisitStringLiteral(self, literal: StringLiteral) -> None:
668 """
669 Write a string literal and double each enclosed quotation mark.
671 **Format:** ``"say ""hi"" twice"``
673 :param literal: The string literal.
674 :raises VHDLWriterError: If the value contains a non-graphic character.
675 """
676 if not self._IsGraphic(literal.Value):
677 ex = VHDLWriterError("String literal contains a non-graphic character.", literal)
678 ex.add_note(f"Got value {literal.Value!r}.")
679 raise ex
681 value = literal.Value.replace("\"", "\"\"")
682 self._Write(f"\"{value}\"")
684 def VisitBitStringLiteral(self, literal: BitStringLiteral) -> None:
685 """
686 Write a bit string literal.
688 **Format:** ``8ux"A0"``
690 :param literal: The bit string literal.
691 :raises VHDLWriterError: If the literal's class has no base specifier.
692 :raises VHDLWriterError: If a decimal bit string literal is signed or unsigned.
693 :raises VHDLWriterError: If the value contains a quotation mark or a non-graphic character.
694 """
695 base = self._BASE_SPECIFIERS.get(literal._BASE)
696 if base is None: 696 ↛ 697line 696 didn't jump to line 697 because the condition on line 696 was never true
697 ex = VHDLWriterError("Model element is not supported by the VHDL writer.", literal)
698 ex.add_note(f"Got type '{getFullyQualifiedName(literal)}'.")
699 raise ex
701 if literal.IsSigned is None:
702 signedness = ""
703 elif literal._BASE is BitStringBase.Decimal:
704 raise VHDLWriterError("Decimal bit string literal can't be signed or unsigned.", literal)
705 elif literal.IsSigned:
706 signedness = "s"
707 else:
708 signedness = "u"
710 if "\"" in literal.Value or not self._IsGraphic(literal.Value):
711 ex = VHDLWriterError("Bit string literal contains a quotation mark or a non-graphic character.", literal)
712 ex.add_note(f"Got value {literal.Value!r}.")
713 raise ex
715 length = "" if literal.Length is None else str(literal.Length)
716 self._Write(f"{length}{signedness}{base}\"{literal.Value}\"")
718 def VisitUnaryExpression(self, expression: UnaryExpression) -> None:
719 """
720 Write the operator of a unary expression with a reserved word as operator; its operand is a primary.
722 **Format:** ``not (a and b)``
724 :param expression: The unary expression.
725 """
726 self._Enter(expression._PRECEDENCE)
727 self._Write(f"{self._Keyword(expression._RESERVED_WORD)} ")
728 self._minimum = OperatorPrecedence.Primary
730 def DepartUnaryExpression(self, expression: UnaryExpression) -> None:
731 """
732 Leave a unary expression with a reserved word as operator.
734 :param expression: The unary expression.
735 """
736 self._Leave()
738 def VisitNegationExpression(self, expression: NegationExpression) -> None:
739 """
740 Write the sign of a negation; its operand is a term.
742 **Format:** ``-a``
744 :param expression: The negation.
745 """
746 self._Enter(expression._PRECEDENCE)
747 self._Write(expression._FORMAT[0])
748 self._minimum = OperatorPrecedence.Multiplying
750 def DepartNegationExpression(self, expression: NegationExpression) -> None:
751 """
752 Leave a negation.
754 :param expression: The negation.
755 """
756 self._Leave()
758 def VisitIdentityExpression(self, expression: IdentityExpression) -> None:
759 """
760 Write the sign of an identity; its operand is a term.
762 **Format:** ``+a``
764 :param expression: The identity.
765 """
766 self._Enter(expression._PRECEDENCE)
767 self._Write(expression._FORMAT[0])
768 self._minimum = OperatorPrecedence.Multiplying
770 def DepartIdentityExpression(self, expression: IdentityExpression) -> None:
771 """
772 Leave an identity.
774 :param expression: The identity.
775 """
776 self._Leave()
778 def DepartTypeConversion(self, conversion: TypeConversion) -> None:
779 """
780 Write the right parenthesis closing the operand of a type conversion.
782 **Format:** ``integer(r)``
784 :param conversion: The type conversion.
785 """
786 self._Write(")")
788 def VisitSubExpression(self, expression: SubExpression) -> None:
789 """
790 Write the left parenthesis of a parenthesized sub-expression from the source.
792 **Format:** ``(a + b)``
794 :param expression: The sub-expression.
795 """
796 self._Write("(")
797 self._minimum = OperatorPrecedence.Range
799 def DepartSubExpression(self, expression: SubExpression) -> None:
800 """
801 Write the right parenthesis of a parenthesized sub-expression from the source.
803 :param expression: The sub-expression.
804 """
805 self._Write(")")
807 def VisitLogicalExpression(self, expression: LogicalExpression) -> None:
808 """
809 Enter a binary logical expression; its left operand is a relation or a chain of the same associative operator.
811 The associative operators are ``and``, ``or``, ``xor`` and ``xnor``.
813 **Format:** ``a and b and c`` or ``(a and b) or c``
815 :param expression: The logical expression.
816 """
817 self._Enter(expression._PRECEDENCE)
818 left = expression.LeftOperand
819 if any(
820 isinstance(expression, operator) and isinstance(left, operator)
821 for operator in (AndExpression, OrExpression, XorExpression, XnorExpression)
822 ):
823 self._minimum = OperatorPrecedence.Logical
824 else:
825 self._minimum = OperatorPrecedence.Relational
827 def DepartLogicalExpression(self, expression: LogicalExpression) -> None:
828 """
829 Leave a binary logical expression.
831 :param expression: The logical expression.
832 """
833 self._Leave()
835 def VisitRelationalExpression(self, expression: RelationalExpression) -> None:
836 """
837 Enter a relational expression; its left operand is a shift expression.
839 **Format:** ``a = b``
841 :param expression: The relational expression.
842 """
843 self._Enter(expression._PRECEDENCE)
844 self._minimum = OperatorPrecedence.Shift
846 def DepartRelationalExpression(self, expression: RelationalExpression) -> None:
847 """
848 Leave a relational expression.
850 :param expression: The relational expression.
851 """
852 self._Leave()
854 def VisitShiftExpression(self, expression: ShiftExpression) -> None:
855 """
856 Enter a shift or rotate expression; its left operand is a simple expression.
858 **Format:** ``a sll 2``
860 :param expression: The shift or rotate expression.
861 """
862 self._Enter(expression._PRECEDENCE)
863 self._minimum = OperatorPrecedence.Adding
865 def DepartShiftExpression(self, expression: ShiftExpression) -> None:
866 """
867 Leave a shift or rotate expression.
869 :param expression: The shift or rotate expression.
870 """
871 self._Leave()
873 def VisitAddingExpression(self, expression: AddingExpression) -> None:
874 """
875 Enter an adding expression; it associates to the left.
877 **Format:** ``a - b - c`` or ``a - (b - c)``
879 :param expression: The adding expression.
880 """
881 self._Enter(expression._PRECEDENCE)
882 self._minimum = OperatorPrecedence.Adding
884 def DepartAddingExpression(self, expression: AddingExpression) -> None:
885 """
886 Leave an adding expression.
888 :param expression: The adding expression.
889 """
890 self._Leave()
892 def VisitMultiplyingExpression(self, expression: MultiplyingExpression) -> None:
893 """
894 Enter a multiplying expression; it associates to the left.
896 **Format:** ``(a + b) * c``
898 :param expression: The multiplying expression.
899 """
900 self._Enter(expression._PRECEDENCE)
901 self._minimum = OperatorPrecedence.Multiplying
903 def DepartMultiplyingExpression(self, expression: MultiplyingExpression) -> None:
904 """
905 Leave a multiplying expression.
907 :param expression: The multiplying expression.
908 """
909 self._Leave()
911 def VisitExponentiationExpression(self, expression: ExponentiationExpression) -> None:
912 """
913 Enter an exponentiation; both operands are primaries.
915 **Format:** ``a ** (b ** c)``
917 :param expression: The exponentiation.
918 """
919 self._Enter(expression._PRECEDENCE)
920 self._minimum = OperatorPrecedence.Primary
922 def DepartExponentiationExpression(self, expression: ExponentiationExpression) -> None:
923 """
924 Leave an exponentiation.
926 :param expression: The exponentiation.
927 """
928 self._Leave()
930 def VisitRangeExpression(self, expression: RangeExpression) -> None:
931 """
932 Enter a range expression; its bounds are simple expressions.
934 **Format:** ``7 downto 0``
936 :param expression: The range expression.
937 """
938 self._Enter(expression._PRECEDENCE)
939 self._minimum = OperatorPrecedence.Adding
941 def DepartRangeExpression(self, expression: RangeExpression) -> None:
942 """
943 Leave a range expression.
945 :param expression: The range expression.
946 """
947 self._Leave()
949 def VisitWhenElseExpression(self, expression: WhenElseExpression) -> None:
950 """
951 Enter a conditional expression; its value and condition are logical expressions.
953 **Format:** ``a when c else b``
955 :param expression: The conditional expression.
956 """
957 self._Enter(expression._PRECEDENCE)
958 self._minimum = OperatorPrecedence.Logical
960 def DepartWhenElseExpression(self, expression: WhenElseExpression) -> None:
961 """
962 Leave a conditional expression.
964 :param expression: The conditional expression.
965 """
966 self._Leave()
968 def DepartQualifiedExpression(self, expression: QualifiedExpression) -> None:
969 """
970 Write the right parenthesis closing the operand of a qualified expression, unless the operand brings its own.
972 **Format:** ``byte'(others => '0')``
974 :param expression: The qualified expression.
975 """
976 if not isinstance(expression.Operand, (Aggregate, SubExpression)):
977 self._Write(")")
979 def VisitSubtypeAllocation(self, allocation: SubtypeAllocation) -> None:
980 """
981 Write the reserved word ``new`` of an allocation of a subtype.
983 **Format:** ``new node``
985 :param allocation: The allocation.
986 """
987 self._Write(f"{self._Keyword(ReservedWord.New)} ")
989 def VisitQualifiedExpressionAllocation(self, allocation: QualifiedExpressionAllocation) -> None:
990 """
991 Write the reserved word ``new`` of an allocation initialized by a qualified expression.
993 **Format:** ``new integer'(5)``
995 :param allocation: The allocation.
996 """
997 self._Write(f"{self._Keyword(ReservedWord.New)} ")
999 def VisitAggregate(self, aggregate: Aggregate) -> None:
1000 """
1001 Write the left parenthesis of an aggregate.
1003 **Format:** ``(0 => '1', others => '0')``
1005 :param aggregate: The aggregate.
1006 :raises VHDLWriterError: If the aggregate has no elements.
1007 :raises VHDLWriterError: If the aggregate has a single positional element (it would read as parentheses). |br|
1008 Use a named element, e.g. ``others => value``.
1009 """
1010 elements = aggregate.Elements
1011 if len(elements) == 0:
1012 raise VHDLWriterError("Aggregate has no elements.", aggregate)
1013 elif len(elements) == 1 and isinstance(elements[0], SimpleAggregateElement):
1014 ex = VHDLWriterError("Aggregate with a single positional element has no VHDL notation.", aggregate)
1015 ex.add_note("Use a named element, e.g. 'others => value'.")
1016 raise ex
1018 self._Write("(")
1019 self._minimum = OperatorPrecedence.Range
1021 def DepartAggregate(self, aggregate: Aggregate) -> None:
1022 """
1023 Write the right parenthesis of an aggregate.
1025 :param aggregate: The aggregate.
1026 """
1027 self._Write(")")
1029 def VisitIndexedAggregateElement(self, element: IndexedAggregateElement) -> None:
1030 """
1031 Enter an aggregate element chosen by an index; the index is a simple expression.
1033 **Format:** ``0 => '1'``
1035 :param element: The aggregate element.
1036 """
1037 self._minimum = OperatorPrecedence.Adding
1039 def VisitOthersAggregateElement(self, element: OthersAggregateElement) -> None:
1040 """
1041 Write the choice ``others`` of an aggregate element.
1043 **Format:** ``others => '0'``
1045 :param element: The aggregate element.
1046 """
1047 self._Write(f"{self._Keyword(ReservedWord.Others)} => ")
1048 self._minimum = OperatorPrecedence.Range
1050 def VisitSimpleRange(self, rng: SimpleRange) -> None:
1051 """
1052 Enter a range given by its bounds; its bounds are simple expressions.
1054 **Format:** ``0 to 7``
1056 :param rng: The range.
1057 """
1058 self._Enter(OperatorPrecedence.Range)
1059 self._minimum = OperatorPrecedence.Adding
1061 def DepartSimpleRange(self, rng: SimpleRange) -> None:
1062 """
1063 Leave a range given by its bounds.
1065 :param rng: The range.
1066 """
1067 self._Leave()
1069 def VisitRangeFromName(self, rng: RangeFromName) -> None:
1070 """
1071 Enter a range denoted by a name.
1073 **Format:** ``v'range``
1075 :param rng: The range.
1076 """
1077 self._Enter(OperatorPrecedence.Range)
1079 def DepartRangeFromName(self, rng: RangeFromName) -> None:
1080 """
1081 Leave a range denoted by a name.
1083 :param rng: The range.
1084 """
1085 self._Leave()
1087 def VisitSimpleName(self, name: SimpleName) -> None:
1088 """
1089 Write a simple name.
1091 **Format:** ``clk``
1093 :param name: The simple name.
1094 """
1095 self._Write(name.Identifier)
1097 def DepartSelectedName(self, name: SelectedName) -> None:
1098 """
1099 Write the suffix of a selected name after its prefix.
1101 **Format:** ``ieee.numeric_std``
1103 :param name: The selected name.
1104 """
1105 self._Write(f".{name.Identifier}")
1107 def DepartAllName(self, name: AllName) -> None:
1108 """
1109 Write the suffix ``all`` of a selected name after its prefix, or the reserved word ``all`` without a prefix.
1111 **Format:** ``ieee.numeric_std.all`` or ``all``
1113 :param name: The ``all`` name.
1114 """
1115 if name.Prefix is None:
1116 self._Write(self._Keyword(ReservedWord.All))
1117 else:
1118 self._Write(f".{self._Keyword(ReservedWord.All)}")
1120 def DepartAttributeName(self, name: AttributeName) -> None:
1121 """
1122 Write the attribute designator of an attribute name after its prefix.
1124 **Format:** ``v'range``
1126 :param name: The attribute name.
1127 """
1128 self._Write(f"'{name.Identifier}")
1130 def DepartIndexedName(self, name: IndexedName) -> None:
1131 """
1132 Write the right parenthesis closing the indices of an indexed name.
1134 **Format:** ``m(i, j)``
1136 :param name: The indexed name.
1137 """
1138 self._Write(")")
1140 def DepartParenthesisName(self, name: ParenthesisName) -> None:
1141 """
1142 Write the right parenthesis closing the associations of a parenthesis name (index, slice or function call).
1144 **Format:** ``resize(a, 8)``
1146 :param name: The parenthesis name.
1147 """
1148 self._Write(")")
1150 def VisitSlicedName(self, name: SlicedName) -> None:
1151 """
1152 Reject a sliced name, because it carries no discrete range.
1154 :param name: The sliced name.
1155 :raises VHDLWriterError: Always, because a sliced name carries no discrete range. |br|
1156 Use a :class:`~pyVHDLModel.Name.ParenthesisName` with a range expression as association.
1157 """
1158 ex = VHDLWriterError("Sliced name carries no discrete range.", name)
1159 ex.add_note("Use a 'ParenthesisName' with a range expression as association.")
1160 raise ex
1162 def VisitOpenName(self, name: OpenName) -> None:
1163 """
1164 Write the reserved word ``open``.
1166 **Format:** ``open``
1168 :param name: The ``open`` name.
1169 """
1170 self._Write(self._Keyword(ReservedWord.Open))
1172 def VisitAssociationItem(self, item: AssociationItem) -> None:
1173 """
1174 Check an association item before its formal and actual are written.
1176 **Format:** ``formal => actual`` or ``actual``
1178 :param item: The association item.
1179 :raises VHDLWriterError: If the association item has no actual.
1180 """
1181 if item.Actual is None:
1182 raise VHDLWriterError("Association item has no actual.", item)
1184 def VisitSemicolon(self, element: WithGenericsMixin | WithPortsMixin | WithParametersMixin) -> None:
1185 """
1186 Write the semicolon between two items of an interface list; the next item starts on a new line.
1188 :param element: The element containing the interface list.
1189 """
1190 self._Write(";\n")
1191 self._WriteIndentation()
1193 def _WriteIndentation(self) -> None:
1194 """
1195 Write the indentation of the current indentation level.
1196 """
1197 if self._style.IndentStyle is IndentStyle.SmartTabs:
1198 self._Write("\t" * self._indentation)
1199 else:
1200 self._Write(" " * (self._indentation * self._style.IndentSize))
1202 def VisitVariableAssignment(self, element: WithDefaultExpressionMixin | AssignmentMixin) -> None:
1203 """
1204 Write the variable assignment delimiter (``:=``) before a default expression or the value of a variable assignment.
1206 :param element: The element with the default expression or the variable assignment.
1207 """
1208 self._Write(" := ")
1209 self._minimum = OperatorPrecedence.Range
1211 def VisitIs(
1212 self,
1213 element: ModeViewDeclaration | Alias | AttributeSpecification | Subprogram | Architecture | Configuration |
1214 ProcessStatement | CaseStatement
1215 ) -> None:
1216 """
1217 Write the reserved word ``is`` ending the header of a declaration; its body is indented.
1219 In an alias declaration and an attribute specification, the name or the expression follows on the same line. A
1220 subprogram without declared items and statements is a subprogram declaration, which has no ``is``.
1222 :param element: The declaration.
1223 """
1224 if isinstance(element, (Alias, AttributeSpecification)):
1225 self._Write(f" {self._Keyword(ReservedWord.Is)} ")
1226 self._minimum = OperatorPrecedence.Range
1227 elif isinstance(element, Subprogram) and not self._IsSubprogramBody(element):
1228 return
1229 else:
1230 self._Write(f" {self._Keyword(ReservedWord.Is)}\n")
1231 self._indentation += 1
1233 def VisitRangeConstraint(self, symbol: ConstrainedScalarSubtypeSymbol) -> None:
1234 """
1235 Write the reserved word ``range`` of a range constraint.
1237 **Format:** ``integer range 0 to 7``
1239 :param symbol: The constrained subtype symbol.
1240 """
1241 self._Write(f" {self._Keyword(ReservedWord.Range)} ")
1242 self._minimum = OperatorPrecedence.Range
1244 def VisitIndexConstraint(
1245 self,
1246 element: ConstrainedArraySubtypeSymbol | ConstrainedRecordSubtypeSymbol | ArrayType
1247 ) -> None:
1248 """
1249 Write the left parenthesis of an index constraint.
1251 **Format:** ``bit_vector(7 downto 0)``
1253 :param element: The constrained subtype symbol or the array type.
1254 """
1255 self._Write("(")
1256 self._minimum = OperatorPrecedence.Range
1258 def DepartIndexConstraint(
1259 self,
1260 element: ConstrainedArraySubtypeSymbol | ConstrainedRecordSubtypeSymbol | ArrayType
1261 ) -> None:
1262 """
1263 Write the right parenthesis of an index constraint.
1265 :param element: The constrained subtype symbol or the array type.
1266 """
1267 self._Write(")")
1269 def VisitRecordConstraint(self, symbol: ConstrainedRecordSubtypeSymbol) -> None:
1270 """
1271 Write the left parenthesis of a record constraint.
1273 **Format:** ``frame(data(7 downto 0), mask(3 downto 0))``
1275 :param symbol: The constrained subtype symbol.
1276 """
1277 self._Write("(")
1279 def DepartRecordConstraint(self, symbol: ConstrainedRecordSubtypeSymbol) -> None:
1280 """
1281 Write the right parenthesis of a record constraint.
1283 :param symbol: The constrained subtype symbol.
1284 """
1285 self._Write(")")
1287 def VisitGenericClause(self, element: WithGenericsMixin) -> None:
1288 """
1289 Write the reserved word ``generic`` and the left parenthesis of a generic clause; each generic is on its own line.
1291 **Format:** ``generic (`` ... ``);``
1293 The generic clause of a subprogram follows its designator on the same line and ends without a semicolon.
1295 :param element: The element with generics.
1296 """
1297 if isinstance(element, Subprogram):
1298 self._Write(" ")
1299 else:
1300 self._WriteIndentation()
1302 self._Write(f"{self._Keyword(ReservedWord.Generic)} (\n")
1303 self._indentation += 1
1304 self._WriteIndentation()
1306 def DepartGenericClause(self, element: WithGenericsMixin) -> None:
1307 """
1308 Write the right parenthesis of a generic clause on its own line.
1310 :param element: The element with generics.
1311 """
1312 if isinstance(element, Subprogram):
1313 self._WriteClosingParenthesis("")
1314 else:
1315 self._WriteClosingParenthesis(";\n")
1317 def _WriteClosingParenthesis(self, terminator: str) -> None:
1318 """
1319 Write the right parenthesis closing a list on its own line, one indentation level up.
1321 :param terminator: The text following the right parenthesis.
1322 """
1323 self._Write("\n")
1324 self._indentation -= 1
1325 self._WriteIndentation()
1326 self._Write(f"){terminator}")
1328 def VisitPortClause(self, element: WithPortsMixin) -> None:
1329 """
1330 Write the reserved word ``port`` and the left parenthesis of a port clause; each port is on its own line.
1332 **Format:** ``port (`` ... ``);``
1334 :param element: The element with ports.
1335 """
1336 self._WriteIndentation()
1337 self._Write(f"{self._Keyword(ReservedWord.Port)} (\n")
1338 self._indentation += 1
1339 self._WriteIndentation()
1341 def DepartPortClause(self, element: WithPortsMixin) -> None:
1342 """
1343 Write the right parenthesis of a port clause on its own line.
1345 :param element: The element with ports.
1346 """
1347 self._WriteClosingParenthesis(";\n")
1349 def VisitConstant(self, constant: Constant) -> None:
1350 """
1351 Write the reserved word ``constant`` and the identifiers of a constant declaration.
1353 **Format:** ``constant BITS : positive := 8;``
1355 :param constant: The constant declaration.
1356 """
1357 self._WriteObjectDeclaration(constant)
1359 def _WriteObjectDeclaration(self, obj: Obj) -> None:
1360 """
1361 Write the indentation, the object class reserved word and the identifiers of an object declaration.
1363 :param obj: The object declaration.
1364 """
1365 self._WriteIndentation()
1366 self._Write(f"{self._Keywords(obj._OBJECT_KEYWORD)} {', '.join(obj.Identifiers)} : ")
1368 def DepartConstant(self, constant: Constant) -> None:
1369 """
1370 Write the semicolon ending a constant declaration.
1372 :param constant: The constant declaration.
1373 """
1374 self._Write(";\n")
1376 def VisitDeferredConstant(self, constant: DeferredConstant) -> None:
1377 """
1378 Write the reserved word ``constant`` and the identifiers of a deferred constant declaration.
1380 **Format:** ``constant BITS : positive;``
1382 :param constant: The deferred constant declaration.
1383 """
1384 self._WriteObjectDeclaration(constant)
1386 def DepartDeferredConstant(self, constant: DeferredConstant) -> None:
1387 """
1388 Write the semicolon ending a deferred constant declaration.
1390 :param constant: The deferred constant declaration.
1391 """
1392 self._Write(";\n")
1394 def VisitVariable(self, variable: Variable) -> None:
1395 """
1396 Write the reserved word ``variable`` and the identifiers of a variable declaration.
1398 **Format:** ``variable count : natural := 0;``
1400 :param variable: The variable declaration.
1401 """
1402 self._WriteObjectDeclaration(variable)
1404 def DepartVariable(self, variable: Variable) -> None:
1405 """
1406 Write the semicolon ending a variable declaration.
1408 :param variable: The variable declaration.
1409 """
1410 self._Write(";\n")
1412 def VisitSharedVariable(self, variable: SharedVariable) -> None:
1413 """
1414 Write the reserved words ``shared variable`` and the identifiers of a shared variable declaration.
1416 **Format:** ``shared variable counter : counter_t;``
1418 :param variable: The shared variable declaration.
1419 """
1420 self._WriteObjectDeclaration(variable)
1422 def DepartSharedVariable(self, variable: SharedVariable) -> None:
1423 """
1424 Write the semicolon ending a shared variable declaration.
1426 :param variable: The shared variable declaration.
1427 """
1428 self._Write(";\n")
1430 def VisitSignal(self, signal: Signal) -> None:
1431 """
1432 Write the reserved word ``signal`` and the identifiers of a signal declaration.
1434 **Format:** ``signal a, b : bit := '0';``
1436 :param signal: The signal declaration.
1437 """
1438 self._WriteObjectDeclaration(signal)
1440 def DepartSignal(self, signal: Signal) -> None:
1441 """
1442 Write the semicolon ending a signal declaration.
1444 :param signal: The signal declaration.
1445 """
1446 self._Write(";\n")
1448 def VisitFile(self, file: File) -> None:
1449 """
1450 Write the reserved word ``file`` and the identifiers of a file declaration.
1452 **Format:** ``file input : text;``
1454 The model carries no file open information, so none is written.
1456 :param file: The file declaration.
1457 """
1458 self._WriteObjectDeclaration(file)
1460 def DepartFile(self, file: File) -> None:
1461 """
1462 Write the semicolon ending a file declaration.
1464 :param file: The file declaration.
1465 """
1466 self._Write(";\n")
1468 def VisitGenericConstantInterfaceItem(self, item: GenericConstantInterfaceItem) -> None:
1469 """
1470 Write the identifiers and the mode of a generic constant.
1472 **Format:** ``BITS : positive := 8``
1474 :param item: The generic constant.
1475 """
1476 self._WriteInterfaceItem(item, (), item.Mode)
1478 def _WriteInterfaceItem(self, item: Obj, keywords: tuple[ReservedWord, ...], mode: Mode) -> None:
1479 """
1480 Write the object class reserved words (if any), the identifiers and the mode (if any) of an interface item.
1482 :param item: The interface item.
1483 :param keywords: The object class reserved words, or an empty tuple.
1484 :param mode: The mode; ``Mode.Default`` writes none.
1485 """
1486 if len(keywords) > 0:
1487 self._Write(f"{self._Keywords(keywords)} ")
1489 self._Write(f"{', '.join(item.Identifiers)} : ")
1490 if mode is not Mode.Default:
1491 self._Write(f"{self._Keyword(mode.ReservedWord)} ")
1493 def VisitGenericTypeInterfaceItem(self, item: GenericTypeInterfaceItem) -> None:
1494 """
1495 Write a generic type.
1497 **Format:** ``type T``
1499 :param item: The generic type.
1500 """
1501 self._Write(f"{self._Keyword(ReservedWord.Type)} {item.Identifier}")
1503 def VisitPortSimpleSignalInterfaceItem(self, item: PortSimpleSignalInterfaceItem) -> None:
1504 """
1505 Write the identifiers and the mode of a port.
1507 **Format:** ``clk : in std_logic``
1509 :param item: The port.
1510 """
1511 self._WriteInterfaceItem(item, (), item.Mode)
1513 def VisitPortViewSignalInterfaceItem(self, item: PortViewSignalInterfaceItem) -> None:
1514 """
1515 Write the identifiers and the reserved word ``view`` of a port with a mode view.
1517 **Format:** ``link : view master``
1519 :param item: The port.
1520 """
1521 self._WriteInterfaceItem(item, (), Mode.Default)
1522 self._Write(f"{self._Keyword(ReservedWord.View)} ")
1524 def VisitParameterConstantInterfaceItem(self, item: ParameterConstantInterfaceItem) -> None:
1525 """
1526 Write the reserved word ``constant``, the identifiers and the mode of a constant parameter.
1528 **Format:** ``constant value : in integer``
1530 :param item: The constant parameter.
1531 """
1532 self._WriteInterfaceItem(item, item._OBJECT_KEYWORD, item.Mode)
1534 def VisitParameterVariableInterfaceItem(self, item: ParameterVariableInterfaceItem) -> None:
1535 """
1536 Write the reserved word ``variable``, the identifiers and the mode of a variable parameter.
1538 **Format:** ``variable result : out integer``
1540 :param item: The variable parameter.
1541 """
1542 self._WriteInterfaceItem(item, item._OBJECT_KEYWORD, item.Mode)
1544 def VisitParameterSimpleSignalInterfaceItem(self, item: ParameterSimpleSignalInterfaceItem) -> None:
1545 """
1546 Write the reserved word ``signal``, the identifiers and the mode of a signal parameter.
1548 **Format:** ``signal clk : in std_logic``
1550 :param item: The signal parameter.
1551 """
1552 self._WriteInterfaceItem(item, item._OBJECT_KEYWORD, item.Mode)
1554 def VisitParameterViewSignalInterfaceItem(self, item: ParameterViewSignalInterfaceItem) -> None:
1555 """
1556 Write the reserved word ``signal``, the identifiers and the reserved word ``view`` of a signal parameter.
1558 **Format:** ``signal link : view master``
1560 :param item: The signal parameter.
1561 """
1562 self._WriteInterfaceItem(item, item._OBJECT_KEYWORD, Mode.Default)
1563 self._Write(f"{self._Keyword(ReservedWord.View)} ")
1565 def VisitParameterFileInterfaceItem(self, item: ParameterFileInterfaceItem) -> None:
1566 """
1567 Write the reserved word ``file`` and the identifiers of a file parameter.
1569 **Format:** ``file input : text``
1571 :param item: The file parameter.
1572 """
1573 self._WriteInterfaceItem(item, item._OBJECT_KEYWORD, Mode.Default)
1575 def VisitModeViewDeclaration(self, declaration: ModeViewDeclaration) -> None:
1576 """
1577 Write the reserved word ``view``, the identifier and the reserved word ``of`` of a mode view declaration.
1579 **Format:** ``view master of bus_t is`` ... ``end view master;``
1581 :param declaration: The mode view declaration.
1582 """
1583 self._WriteIndentation()
1584 self._Write(f"{self._Keyword(ReservedWord.View)} {declaration.Identifier} {self._Keyword(ReservedWord.Of)} ")
1586 def DepartModeViewDeclaration(self, declaration: ModeViewDeclaration) -> None:
1587 """
1588 Write the end of a mode view declaration.
1590 :param declaration: The mode view declaration.
1591 """
1592 self._WriteEnd((ReservedWord.View,), declaration.Identifier)
1594 def _WriteEnd(self, keywords: tuple[ReservedWord, ...], identifier: Nullable[str]) -> None:
1595 """
1596 Leave the indented body and write the reserved word ``end``, the given reserved words and the identifier.
1598 :param keywords: The reserved words after ``end``.
1599 :param identifier: The identifier or label of the declaration or statement, or ``None`` if it has none.
1600 """
1601 self._indentation -= 1
1602 self._WriteEndLine(keywords, identifier)
1604 def _WriteEndLine(self, keywords: tuple[ReservedWord, ...], identifier: Nullable[str]) -> None:
1605 """
1606 Write the reserved word ``end``, the given reserved words and the identifier on a line of the current level.
1608 :param keywords: The reserved words after ``end``.
1609 :param identifier: The identifier or label of the declaration or statement, or ``None`` if it has none.
1610 """
1611 self._WriteIndentation()
1612 if identifier is None:
1613 self._Write(f"{self._Keyword(ReservedWord.End)} {self._Keywords(keywords)};\n")
1614 else:
1615 self._Write(f"{self._Keyword(ReservedWord.End)} {self._Keywords(keywords)} {identifier};\n")
1617 def VisitSimpleModeViewElement(self, element: SimpleModeViewElement) -> None:
1618 """
1619 Write an element of a mode view with a mode.
1621 **Format:** ``valid, data : out;``
1623 :param element: The mode view element.
1624 :raises VHDLWriterError: If the mode view element has no mode.
1625 """
1626 if element.Mode is Mode.Default:
1627 raise VHDLWriterError("Mode view element has no mode.", element)
1629 self._WriteIndentation()
1630 self._Write(f"{', '.join(element.Identifiers)} : {self._Keyword(element.Mode.ReservedWord)};\n")
1632 def VisitCompositeModeViewElement(self, element: CompositeModeViewElement) -> None:
1633 """
1634 Write the identifiers and the reserved word ``view`` of an element of a mode view with a mode view.
1636 **Format:** ``request : view master;``
1638 :param element: The mode view element.
1639 """
1640 self._WriteIndentation()
1641 self._Write(f"{', '.join(element.Identifiers)} : {self._Keyword(ReservedWord.View)} ")
1643 def DepartCompositeModeViewElement(self, element: CompositeModeViewElement) -> None:
1644 """
1645 Write the semicolon ending an element of a mode view with a mode view.
1647 :param element: The mode view element.
1648 """
1649 self._Write(";\n")
1651 def VisitComponent(self, component: Component) -> None:
1652 """
1653 Write the header of a component declaration; its generic and port clauses are indented.
1655 **Format:** ``component counter is`` ... ``end component counter;``
1657 :param component: The component declaration.
1658 """
1659 self._WriteIndentation()
1660 self._Write(f"{self._Keyword(ReservedWord.Component)} {component.Identifier} {self._Keyword(ReservedWord.Is)}\n")
1661 self._indentation += 1
1663 def DepartComponent(self, component: Component) -> None:
1664 """
1665 Write the end of a component declaration.
1667 :param component: The component declaration.
1668 """
1669 self._WriteEnd((ReservedWord.Component,), component.Identifier)
1671 def VisitBox(self, arrayType: ArrayType) -> None:
1672 """
1673 Write the reserved word ``range`` and the box (``<>``) of an unbounded index of an array type.
1675 **Format:** ``natural range <>``
1677 :param arrayType: The array type.
1678 """
1679 self._Write(f" {self._Keyword(ReservedWord.Range)} <>")
1681 def VisitOf(self, arrayType: ArrayType) -> None:
1682 """
1683 Write the reserved word ``of`` before the element subtype of an array type.
1685 :param arrayType: The array type.
1686 """
1687 self._Write(f" {self._Keyword(ReservedWord.Of)} ")
1689 def VisitUnits(self, physicalType: PhysicalType) -> None:
1690 """
1691 Write the reserved word ``units`` and the primary unit of a physical type on their own lines.
1693 :param physicalType: The physical type.
1694 """
1695 self._Write("\n")
1696 self._indentation += 1
1697 self._WriteIndentation()
1698 self._Write(f"{self._Keyword(ReservedWord.Units)}\n")
1699 self._indentation += 1
1700 self._WriteIndentation()
1701 self._Write(f"{physicalType.PrimaryUnit};\n")
1703 def VisitSecondaryUnitDeclaration(self, physicalType: PhysicalType, identifier: str) -> None:
1704 """
1705 Write the identifier of a secondary unit declaration.
1707 **Format:** ``mm = 1000 um;``
1709 :param physicalType: The physical type.
1710 :param identifier: The identifier of the secondary unit.
1711 """
1712 self._WriteIndentation()
1713 self._Write(f"{identifier} = ")
1714 self._minimum = OperatorPrecedence.Range
1716 def DepartSecondaryUnitDeclaration(self, physicalType: PhysicalType, identifier: str) -> None:
1717 """
1718 Write the semicolon ending a secondary unit declaration.
1720 :param physicalType: The physical type.
1721 :param identifier: The identifier of the secondary unit.
1722 """
1723 self._Write(";\n")
1725 def VisitEntitySpecification(self, specification: AttributeSpecification) -> None:
1726 """
1727 Write the reserved word ``of`` before the names of an attribute specification.
1729 :param specification: The attribute specification.
1730 """
1731 self._Write(f" {self._Keyword(ReservedWord.Of)} ")
1733 def DepartEntitySpecification(self, specification: AttributeSpecification) -> None:
1734 """
1735 Write the entity class after the names of an attribute specification.
1737 :param specification: The attribute specification.
1738 """
1739 self._Write(f" : {self._Keyword(specification.EntityClass.ReservedWord)}")
1741 def VisitAnonymousType(self, declaration: AnonymousType) -> None:
1742 """
1743 Write an incomplete type declaration.
1745 **Format:** ``type node;``
1747 :param declaration: The incomplete type declaration.
1748 """
1749 self._WriteIndentation()
1750 self._Write(f"{self._Keyword(ReservedWord.Type)} {declaration.Identifier};\n")
1752 def VisitSubtype(self, subtype: Subtype) -> None:
1753 """
1754 Write the reserved word ``subtype``, the identifier and the reserved word ``is`` of a subtype declaration.
1756 **Format:** ``subtype byte is bit_vector(7 downto 0);``
1758 The model's resolution function of a subtype is not written.
1760 :param subtype: The subtype declaration.
1761 """
1762 self._WriteIndentation()
1763 self._Write(f"{self._Keyword(ReservedWord.Subtype)} {subtype.Identifier} {self._Keyword(ReservedWord.Is)} ")
1765 def DepartSubtype(self, subtype: Subtype) -> None:
1766 """
1767 Write the semicolon ending a subtype declaration.
1769 :param subtype: The subtype declaration.
1770 """
1771 self._Write(";\n")
1773 def VisitEnumeratedType(self, enumeratedType: EnumeratedType) -> None:
1774 """
1775 Write the header and the left parenthesis of an enumerated type declaration.
1777 **Format:** ``type state is (Idle, Busy, Done);``
1779 :param enumeratedType: The enumerated type.
1780 """
1781 self._WriteTypeHeader(enumeratedType)
1782 self._Write("(")
1784 def _WriteTypeHeader(self, declaration: FullType) -> None:
1785 """
1786 Write the indentation, the reserved word ``type``, the identifier and the reserved word ``is`` of a type.
1788 :param declaration: The type declaration.
1789 """
1790 self._WriteIndentation()
1791 self._Write(f"{self._Keyword(ReservedWord.Type)} {declaration.Identifier} {self._Keyword(ReservedWord.Is)} ")
1793 def DepartEnumeratedType(self, enumeratedType: EnumeratedType) -> None:
1794 """
1795 Write the right parenthesis ending an enumerated type declaration.
1797 :param enumeratedType: The enumerated type.
1798 """
1799 self._Write(");\n")
1801 def VisitIntegerType(self, integerType: IntegerType) -> None:
1802 """
1803 Write the header and the reserved word ``range`` of an integer type declaration.
1805 **Format:** ``type nibble is range 0 to 15;``
1807 :param integerType: The integer type.
1808 """
1809 self._WriteTypeHeader(integerType)
1810 self._Write(f"{self._Keyword(ReservedWord.Range)} ")
1811 self._minimum = OperatorPrecedence.Range
1813 def DepartIntegerType(self, integerType: IntegerType) -> None:
1814 """
1815 Write the semicolon ending an integer type declaration.
1817 :param integerType: The integer type.
1818 """
1819 self._Write(";\n")
1821 def VisitRealType(self, realType: RealType) -> None:
1822 """
1823 Write the header and the reserved word ``range`` of a floating-point type declaration.
1825 **Format:** ``type fraction is range 0.0 to 1.0;``
1827 :param realType: The floating-point type.
1828 """
1829 self._WriteTypeHeader(realType)
1830 self._Write(f"{self._Keyword(ReservedWord.Range)} ")
1831 self._minimum = OperatorPrecedence.Range
1833 def DepartRealType(self, realType: RealType) -> None:
1834 """
1835 Write the semicolon ending a floating-point type declaration.
1837 :param realType: The floating-point type.
1838 """
1839 self._Write(";\n")
1841 def VisitPhysicalType(self, physicalType: PhysicalType) -> None:
1842 """
1843 Write the header and the reserved word ``range`` of a physical type declaration; its units are indented.
1845 **Format:** ``type distance is range 0 to 1000000`` ... ``units`` ... ``end units distance;``
1847 :param physicalType: The physical type.
1848 """
1849 self._WriteTypeHeader(physicalType)
1850 self._Write(f"{self._Keyword(ReservedWord.Range)} ")
1851 self._minimum = OperatorPrecedence.Range
1853 def DepartPhysicalType(self, physicalType: PhysicalType) -> None:
1854 """
1855 Write the end of the units of a physical type declaration.
1857 :param physicalType: The physical type.
1858 """
1859 self._WriteEnd((ReservedWord.Units,), physicalType.Identifier)
1860 self._indentation -= 1
1862 def VisitArrayType(self, arrayType: ArrayType) -> None:
1863 """
1864 Write the header and the reserved word ``array`` of an array type declaration.
1866 **Format:** ``type memory is array (0 to 255) of byte;`` or ``type bits is array (natural range <>) of bit;``
1868 :param arrayType: The array type.
1869 """
1870 self._WriteTypeHeader(arrayType)
1871 self._Write(f"{self._Keyword(ReservedWord.Array)} ")
1873 def DepartArrayType(self, arrayType: ArrayType) -> None:
1874 """
1875 Write the semicolon ending an array type declaration.
1877 :param arrayType: The array type.
1878 """
1879 self._Write(";\n")
1881 def VisitRecordType(self, recordType: RecordType) -> None:
1882 """
1883 Write the header of a record type declaration; its element declarations are indented.
1885 **Format:** ``type frame is record`` ... ``end record frame;``
1887 :param recordType: The record type.
1888 """
1889 self._WriteTypeHeader(recordType)
1890 self._Write(f"{self._Keyword(ReservedWord.Record)}\n")
1891 self._indentation += 1
1893 def DepartRecordType(self, recordType: RecordType) -> None:
1894 """
1895 Write the end of a record type declaration.
1897 :param recordType: The record type.
1898 """
1899 self._WriteEnd((ReservedWord.Record,), recordType.Identifier)
1901 def VisitRecordTypeElement(self, element: RecordTypeElement) -> None:
1902 """
1903 Write the identifiers of an element declaration of a record type.
1905 **Format:** ``valid, last : bit;``
1907 :param element: The record element declaration.
1908 """
1909 self._WriteIndentation()
1910 self._Write(f"{', '.join(element.Identifiers)} : ")
1912 def DepartRecordTypeElement(self, element: RecordTypeElement) -> None:
1913 """
1914 Write the semicolon ending an element declaration of a record type.
1916 :param element: The record element declaration.
1917 """
1918 self._Write(";\n")
1920 def VisitAccessType(self, accessType: AccessType) -> None:
1921 """
1922 Write the header and the reserved word ``access`` of an access type declaration.
1924 **Format:** ``type pointer is access node;``
1926 :param accessType: The access type.
1927 """
1928 self._WriteTypeHeader(accessType)
1929 self._Write(f"{self._Keyword(ReservedWord.Access)} ")
1931 def DepartAccessType(self, accessType: AccessType) -> None:
1932 """
1933 Write the semicolon ending an access type declaration.
1935 :param accessType: The access type.
1936 """
1937 self._Write(";\n")
1939 def VisitFileType(self, fileType: FileType) -> None:
1940 """
1941 Write the header and the reserved words ``file of`` of a file type declaration.
1943 **Format:** ``type text_file is file of string;``
1945 :param fileType: The file type.
1946 """
1947 self._WriteTypeHeader(fileType)
1948 self._Write(f"{self._Keyword(ReservedWord.File)} {self._Keyword(ReservedWord.Of)} ")
1950 def DepartFileType(self, fileType: FileType) -> None:
1951 """
1952 Write the semicolon ending a file type declaration.
1954 :param fileType: The file type.
1955 """
1956 self._Write(";\n")
1958 def VisitAlias(self, alias: Alias) -> None:
1959 """
1960 Write the reserved word ``alias`` and the identifier of an alias declaration.
1962 **Format:** ``alias low : bit_vector(3 downto 0) is data(3 downto 0);`` or ``alias clock is clk;``
1964 :param alias: The alias declaration.
1965 """
1966 self._WriteIndentation()
1967 self._Write(f"{self._Keyword(ReservedWord.Alias)} {alias.Identifier}")
1968 if alias.Subtype is not None:
1969 self._Write(" : ")
1971 def DepartAlias(self, alias: Alias) -> None:
1972 """
1973 Write the semicolon ending an alias declaration.
1975 :param alias: The alias declaration.
1976 """
1977 self._Write(";\n")
1979 def VisitAttribute(self, attribute: Attribute) -> None:
1980 """
1981 Write the reserved word ``attribute`` and the identifier of an attribute declaration.
1983 **Format:** ``attribute keep : boolean;``
1985 :param attribute: The attribute declaration.
1986 """
1987 self._WriteIndentation()
1988 self._Write(f"{self._Keyword(ReservedWord.Attribute)} {attribute.Identifier} : ")
1990 def DepartAttribute(self, attribute: Attribute) -> None:
1991 """
1992 Write the semicolon ending an attribute declaration.
1994 :param attribute: The attribute declaration.
1995 """
1996 self._Write(";\n")
1998 def VisitAttributeSpecification(self, specification: AttributeSpecification) -> None:
1999 """
2000 Write the reserved word ``attribute`` of an attribute specification.
2002 **Format:** ``attribute keep of valid, ready : signal is true;``
2004 :param specification: The attribute specification.
2005 :raises VHDLWriterError: If the entity class is ``EntityClass.Others``.
2006 """
2007 if specification.EntityClass is EntityClass.Others:
2008 raise VHDLWriterError("Entity class 'Others' has no VHDL notation.", specification)
2010 self._WriteIndentation()
2011 self._Write(f"{self._Keyword(ReservedWord.Attribute)} ")
2013 def DepartAttributeSpecification(self, specification: AttributeSpecification) -> None:
2014 """
2015 Write the semicolon ending an attribute specification.
2017 :param specification: The attribute specification.
2018 """
2019 self._Write(";\n")
2021 def VisitBegin(
2022 self,
2023 element: Subprogram | Entity | Architecture | ProcessStatement | ConcurrentBlockStatement | GenerateBranch |
2024 ConcurrentCase | ForGenerateStatement
2025 ) -> None:
2026 """
2027 Write the reserved word ``begin`` before the statement part on its own line.
2029 A subprogram declaration, an entity without statements and the body of a generate statement without declared items
2030 have no ``begin``.
2032 :param element: The element with a statement part.
2033 """
2034 if isinstance(element, Subprogram) and not self._IsSubprogramBody(element):
2035 return
2036 elif isinstance(element, Entity) and len(element.Statements) == 0:
2037 return
2038 elif isinstance(element, (GenerateBranch, ConcurrentCase, ForGenerateStatement)):
2039 if len(element.DeclaredItems) == 0:
2040 return
2042 self._indentation -= 1
2043 self._WriteIndentation()
2044 self._Write(f"{self._Keyword(ReservedWord.Begin)}\n")
2045 self._indentation += 1
2047 @staticmethod
2048 def _IsSubprogramBody(subprogram: Subprogram) -> bool:
2049 """
2050 Check if a subprogram is written as a subprogram body.
2052 A subprogram is a body, if it has declared items or statements, or if its parent is neither a package declaration
2053 nor a protected type declaration (e.g. a package body or an architecture).
2055 :param subprogram: The subprogram.
2056 :returns: ``True``, if the subprogram is written as a subprogram body.
2057 """
2058 if len(subprogram.DeclaredItems) > 0 or len(subprogram.Statements) > 0:
2059 return True
2061 return subprogram.Parent is not None and not isinstance(subprogram.Parent, (Package, ProtectedType))
2063 def VisitReturn(self, function: Function | GenericFunctionInterfaceItem) -> None:
2064 """
2065 Write the reserved word ``return`` before the return type of a function.
2067 :param function: The function.
2068 """
2069 self._Write(f" {self._Keyword(ReservedWord.Return)} ")
2071 def VisitFormalParameterList(self, element: WithParametersMixin) -> None:
2072 """
2073 Write the left parenthesis of a formal parameter list; each parameter is on its own line.
2075 **Format:** ``procedure p (`` ... ``)``
2077 After a generic clause, the reserved word ``parameter`` precedes the left parenthesis.
2079 :param element: The element with parameters.
2080 """
2081 if isinstance(element, WithGenericsMixin) and len(element.GenericItems) > 0:
2082 self._Write(f" {self._Keyword(ReservedWord.Parameter)} (\n")
2083 else:
2084 self._Write(" (\n")
2086 self._indentation += 1
2087 self._WriteIndentation()
2089 def DepartFormalParameterList(self, element: WithParametersMixin) -> None:
2090 """
2091 Write the right parenthesis of a formal parameter list on its own line.
2093 :param element: The element with parameters.
2094 """
2095 self._WriteClosingParenthesis("")
2097 def VisitGenericMapAspect(self, element: GenericMapAspectMixin) -> None:
2098 """
2099 Write the reserved words ``generic map`` and the left parenthesis on a new line; each association is on its own
2100 line.
2102 **Format:** ``generic map (`` ... ``)``
2104 The generic map aspect of a block statement is written like its generic clause and ends with a semicolon.
2106 :param element: The element with a generic map aspect.
2107 """
2108 self._WriteMapAspect(ReservedWord.Generic, element)
2110 def _WriteMapAspect(self, keyword: ReservedWord, element: GenericMapAspectMixin | PortMapAspectMixin) -> None:
2111 """
2112 Write the reserved words of a map aspect and the left parenthesis on a new line, one indentation level deeper.
2114 In a block statement, the map aspect starts its own line at the block header's indentation level.
2116 :param keyword: The reserved word ``generic`` or ``port``.
2117 :param element: The element with the map aspect.
2118 """
2119 if not isinstance(element, ConcurrentBlockStatement):
2120 self._Write("\n")
2121 self._indentation += 1
2123 self._WriteIndentation()
2124 self._Write(f"{self._Keyword(keyword)} {self._Keyword(ReservedWord.Map)} (\n")
2125 self._indentation += 1
2126 self._WriteIndentation()
2128 def DepartGenericMapAspect(self, element: GenericMapAspectMixin) -> None:
2129 """
2130 Write the right parenthesis of a generic map aspect on its own line.
2132 :param element: The element with a generic map aspect.
2133 """
2134 self._WriteMapAspectEnd(element)
2136 def _WriteMapAspectEnd(self, element: GenericMapAspectMixin | PortMapAspectMixin) -> None:
2137 """
2138 Write the right parenthesis of a map aspect on its own line and leave its indentation level.
2140 In a block statement, a semicolon follows the right parenthesis.
2142 :param element: The element with the map aspect.
2143 """
2144 if isinstance(element, ConcurrentBlockStatement):
2145 self._WriteClosingParenthesis(";\n")
2146 else:
2147 self._WriteClosingParenthesis("")
2148 self._indentation -= 1
2150 def VisitProcedure(self, procedure: Procedure) -> None:
2151 """
2152 Write the reserved word ``procedure`` and the designator of a procedure declaration or body.
2154 **Format:** ``procedure reset;`` or ``procedure reset is`` ... ``begin`` ... ``end procedure reset;``
2156 A procedure without declared items and statements is written as a procedure declaration.
2158 :param procedure: The procedure.
2159 """
2160 self._WriteIndentation()
2161 self._Write(f"{self._Keyword(ReservedWord.Procedure)} {procedure.Identifier}")
2163 def DepartProcedure(self, procedure: Procedure) -> None:
2164 """
2165 Write the semicolon ending a procedure declaration, or the end of a procedure body.
2167 :param procedure: The procedure.
2168 """
2169 if self._IsSubprogramBody(procedure):
2170 self._WriteEnd((ReservedWord.Procedure,), procedure.Identifier)
2171 else:
2172 self._Write(";\n")
2174 def VisitFunction(self, function: Function) -> None:
2175 """
2176 Write the reserved word ``impure``, if impure, ``function`` and the designator of a function declaration or body.
2178 **Format:** ``function parity return bit;`` or ``function parity return bit is`` ... ``end function parity;``
2180 A function without declared items and statements is written as a function declaration.
2182 :param function: The function.
2183 """
2184 self._WriteIndentation()
2185 self._WriteFunctionDesignator(function)
2187 def _WriteFunctionDesignator(self, function: Function) -> None:
2188 """
2189 Write the reserved word ``impure``, if impure, the reserved word ``function`` and the designator of a function.
2191 :param function: The function.
2192 """
2193 if not function.IsPure:
2194 self._Write(f"{self._Keyword(ReservedWord.Impure)} ")
2196 self._Write(f"{self._Keyword(ReservedWord.Function)} {function.Identifier}")
2198 def DepartFunction(self, function: Function) -> None:
2199 """
2200 Write the semicolon ending a function declaration, or the end of a function body.
2202 :param function: The function.
2203 """
2204 if self._IsSubprogramBody(function):
2205 self._WriteEnd((ReservedWord.Function,), function.Identifier)
2206 else:
2207 self._Write(";\n")
2209 def VisitGenericProcedureInterfaceItem(self, item: GenericProcedureInterfaceItem) -> None:
2210 """
2211 Write the reserved word ``procedure`` and the designator of a generic procedure.
2213 **Format:** ``procedure log (`` ... ``)``
2215 :param item: The generic procedure.
2216 """
2217 self._Write(f"{self._Keyword(ReservedWord.Procedure)} {item.Identifier}")
2219 def VisitGenericFunctionInterfaceItem(self, item: GenericFunctionInterfaceItem) -> None:
2220 """
2221 Write the reserved word ``impure``, if impure, ``function`` and the designator of a generic function.
2223 **Format:** ``function compare (`` ... ``) return boolean``
2225 :param item: The generic function.
2226 """
2227 self._WriteFunctionDesignator(item)
2229 def VisitProcedureInstantiation(self, instantiation: ProcedureInstantiation) -> None:
2230 """
2231 Write the reserved word ``procedure``, the designator and the reserved words ``is new`` of a procedure
2232 instantiation.
2234 **Format:** ``procedure log_byte is new log`` ... ``;``
2236 :param instantiation: The procedure instantiation.
2237 """
2238 self._WriteIndentation()
2239 self._Write(f"{self._Keyword(ReservedWord.Procedure)} {instantiation.Identifier} ")
2240 self._Write(f"{self._Keyword(ReservedWord.Is)} {self._Keyword(ReservedWord.New)} ")
2242 def DepartProcedureInstantiation(self, instantiation: ProcedureInstantiation) -> None:
2243 """
2244 Write the semicolon ending a procedure instantiation.
2246 :param instantiation: The procedure instantiation.
2247 """
2248 self._Write(";\n")
2250 def VisitFunctionInstantiation(self, instantiation: FunctionInstantiation) -> None:
2251 """
2252 Write the reserved word ``function``, the designator and the reserved words ``is new`` of a function instantiation.
2254 **Format:** ``function maximum_byte is new maximum`` ... ``;``
2256 :param instantiation: The function instantiation.
2257 """
2258 self._WriteIndentation()
2259 self._Write(f"{self._Keyword(ReservedWord.Function)} {instantiation.Identifier} ")
2260 self._Write(f"{self._Keyword(ReservedWord.Is)} {self._Keyword(ReservedWord.New)} ")
2262 def DepartFunctionInstantiation(self, instantiation: FunctionInstantiation) -> None:
2263 """
2264 Write the semicolon ending a function instantiation.
2266 :param instantiation: The function instantiation.
2267 """
2268 self._Write(";\n")
2270 def VisitProtectedType(self, protectedType: ProtectedType) -> None:
2271 """
2272 Write the header of a protected type declaration; its methods are indented.
2274 **Format:** ``type counter is protected`` ... ``end protected counter;``
2276 :param protectedType: The protected type.
2277 """
2278 self._WriteTypeHeader(protectedType)
2279 self._Write(f"{self._Keyword(ReservedWord.Protected)}\n")
2280 self._indentation += 1
2282 def DepartProtectedType(self, protectedType: ProtectedType) -> None:
2283 """
2284 Write the end of a protected type declaration.
2286 :param protectedType: The protected type.
2287 """
2288 self._WriteEnd((ReservedWord.Protected,), protectedType.Identifier)
2290 def VisitProtectedTypeBody(self, body: ProtectedTypeBody) -> None:
2291 """
2292 Write the header of a protected type body; its declared items are indented.
2294 **Format:** ``type counter is protected body`` ... ``end protected body counter;``
2296 :param body: The protected type body.
2297 """
2298 self._WriteTypeHeader(body)
2299 self._Write(f"{self._Keyword(ReservedWord.Protected)} {self._Keyword(ReservedWord.Body)}\n")
2300 self._indentation += 1
2302 def DepartProtectedTypeBody(self, body: ProtectedTypeBody) -> None:
2303 """
2304 Write the end of a protected type body.
2306 :param body: The protected type body.
2307 """
2308 self._WriteEnd((ReservedWord.Protected, ReservedWord.Body), body.Identifier)
2310 def VisitPortMapAspect(self, element: PortMapAspectMixin) -> None:
2311 """
2312 Write the reserved words ``port map`` and the left parenthesis on a new line; each association is on its own line.
2314 **Format:** ``port map (`` ... ``)``
2316 :param element: The element with a port map aspect.
2317 """
2318 self._WriteMapAspect(ReservedWord.Port, element)
2320 def DepartPortMapAspect(self, element: PortMapAspectMixin) -> None:
2321 """
2322 Write the right parenthesis of a port map aspect on its own line.
2324 :param element: The element with a port map aspect.
2325 """
2326 self._WriteMapAspectEnd(element)
2328 def VisitContextClause(self, designUnit: DesignUnit) -> None:
2329 """
2330 Separate a design unit by a blank line from the text written before it.
2332 :param designUnit: The design unit.
2333 """
2334 if len(self._buffer) > 0:
2335 self._Write("\n")
2337 def DepartContextClause(self, designUnit: DesignUnit) -> None:
2338 """
2339 Separate the context items of a design unit by a blank line from the design unit.
2341 :param designUnit: The design unit.
2342 """
2343 if len(designUnit.ContextItems) > 0:
2344 self._Write("\n")
2346 def VisitLibraryClause(self, clause: LibraryClause) -> None:
2347 """
2348 Write the reserved word ``library`` of a library clause.
2350 **Format:** ``library ieee;``
2352 :param clause: The library clause.
2353 """
2354 self._WriteIndentation()
2355 self._Write(f"{self._Keyword(ReservedWord.Library)} ")
2357 def DepartLibraryClause(self, clause: LibraryClause) -> None:
2358 """
2359 Write the semicolon ending a library clause.
2361 :param clause: The library clause.
2362 """
2363 self._Write(";\n")
2365 def VisitUseClause(self, clause: UseClause) -> None:
2366 """
2367 Write the reserved word ``use`` of a use clause.
2369 **Format:** ``use ieee.numeric_std.all;``
2371 :param clause: The use clause.
2372 """
2373 self._WriteIndentation()
2374 self._Write(f"{self._Keyword(ReservedWord.Use)} ")
2376 def DepartUseClause(self, clause: UseClause) -> None:
2377 """
2378 Write the semicolon ending a use clause.
2380 :param clause: The use clause.
2381 """
2382 self._Write(";\n")
2384 def VisitContextReference(self, reference: ContextReference) -> None:
2385 """
2386 Write the reserved word ``context`` of a context reference.
2388 **Format:** ``context ieee.ieee_std_context;``
2390 :param reference: The context reference.
2391 """
2392 self._WriteIndentation()
2393 self._Write(f"{self._Keyword(ReservedWord.Context)} ")
2395 def DepartContextReference(self, reference: ContextReference) -> None:
2396 """
2397 Write the semicolon ending a context reference.
2399 :param reference: The context reference.
2400 """
2401 self._Write(";\n")
2403 def VisitContext(self, context: Context) -> None:
2404 """
2405 Write the header of a context declaration; its context items are indented.
2407 **Format:** ``context project is`` ... ``end context project;``
2409 :param context: The context declaration.
2410 """
2411 self._WriteUnitHeader((ReservedWord.Context,), context.Identifier)
2413 def _WriteUnitHeader(self, keywords: tuple[ReservedWord, ...], identifier: str) -> None:
2414 """
2415 Write the reserved words, the identifier and the reserved word ``is`` of a header; the body is indented.
2417 :param keywords: The reserved words before the identifier.
2418 :param identifier: The identifier.
2419 """
2420 self._WriteIndentation()
2421 self._Write(f"{self._Keywords(keywords)} {identifier} {self._Keyword(ReservedWord.Is)}\n")
2422 self._indentation += 1
2424 def DepartContext(self, context: Context) -> None:
2425 """
2426 Write the end of a context declaration.
2428 :param context: The context declaration.
2429 """
2430 self._WriteEnd((ReservedWord.Context,), context.Identifier)
2432 def VisitPackage(self, package: Package) -> None:
2433 """
2434 Write the header of a package declaration; its generic clause and declared items are indented.
2436 **Format:** ``package utilities is`` ... ``end package utilities;``
2438 :param package: The package declaration.
2439 """
2440 self._WriteUnitHeader((ReservedWord.Package,), package.Identifier)
2442 def DepartPackage(self, package: Package) -> None:
2443 """
2444 Write the end of a package declaration.
2446 :param package: The package declaration.
2447 """
2448 self._WriteEnd((ReservedWord.Package,), package.Identifier)
2450 def VisitPackageBody(self, body: PackageBody) -> None:
2451 """
2452 Write the header of a package body; its declared items are indented.
2454 **Format:** ``package body utilities is`` ... ``end package body utilities;``
2456 :param body: The package body.
2457 """
2458 self._WriteUnitHeader((ReservedWord.Package, ReservedWord.Body), body.Identifier)
2460 def DepartPackageBody(self, body: PackageBody) -> None:
2461 """
2462 Write the end of a package body.
2464 :param body: The package body.
2465 """
2466 self._WriteEnd((ReservedWord.Package, ReservedWord.Body), body.Identifier)
2468 def VisitPackageInstantiation(self, instantiation: PackageInstantiation) -> None:
2469 """
2470 Write the reserved word ``package``, the identifier and the reserved words ``is new`` of a package instantiation.
2472 **Format:** ``package fifo_byte is new work.fifo`` ... ``;``
2474 :param instantiation: The package instantiation.
2475 """
2476 self._WriteIndentation()
2477 self._Write(f"{self._Keyword(ReservedWord.Package)} {instantiation.Identifier} ")
2478 self._Write(f"{self._Keywords((ReservedWord.Is, ReservedWord.New))} ")
2480 def DepartPackageInstantiation(self, instantiation: PackageInstantiation) -> None:
2481 """
2482 Write the semicolon ending a package instantiation.
2484 :param instantiation: The package instantiation.
2485 """
2486 self._Write(";\n")
2488 def VisitEntity(self, entity: Entity) -> None:
2489 """
2490 Write the header of an entity declaration; its generic and port clauses and its declared items are indented.
2492 **Format:** ``entity counter is`` ... ``end entity counter;``
2494 :param entity: The entity declaration.
2495 """
2496 self._WriteUnitHeader((ReservedWord.Entity,), entity.Identifier)
2498 def DepartEntity(self, entity: Entity) -> None:
2499 """
2500 Write the end of an entity declaration.
2502 :param entity: The entity declaration.
2503 """
2504 self._WriteEnd((ReservedWord.Entity,), entity.Identifier)
2506 def VisitArchitecture(self, architecture: Architecture) -> None:
2507 """
2508 Write the reserved word ``architecture``, the identifier and the reserved word ``of`` of an architecture body.
2510 **Format:** ``architecture rtl of counter is`` ... ``begin`` ... ``end architecture rtl;``
2512 :param architecture: The architecture body.
2513 """
2514 self._WriteIndentation()
2515 self._Write(f"{self._Keyword(ReservedWord.Architecture)} {architecture.Identifier} ")
2516 self._Write(f"{self._Keyword(ReservedWord.Of)} ")
2518 def DepartArchitecture(self, architecture: Architecture) -> None:
2519 """
2520 Write the end of an architecture body.
2522 :param architecture: The architecture body.
2523 """
2524 self._WriteEnd((ReservedWord.Architecture,), architecture.Identifier)
2526 def VisitConfiguration(self, configuration: Configuration) -> None:
2527 """
2528 Write the reserved word ``configuration``, the identifier and the reserved word ``of`` of a configuration.
2530 **Format:** ``configuration counter_cfg of counter is`` ... ``end configuration counter_cfg;``
2532 :param configuration: The configuration declaration.
2533 """
2534 self._WriteIndentation()
2535 self._Write(f"{self._Keyword(ReservedWord.Configuration)} {configuration.Identifier} ")
2536 self._Write(f"{self._Keyword(ReservedWord.Of)} ")
2538 def DepartConfiguration(self, configuration: Configuration) -> None:
2539 """
2540 Write the end of a configuration declaration.
2542 :param configuration: The configuration declaration.
2543 """
2544 self._WriteEnd((ReservedWord.Configuration,), configuration.Identifier)
2546 def VisitBlockConfiguration(self, configuration: BlockConfiguration) -> None:
2547 """
2548 Write the reserved word ``for`` of a block configuration; its nested configurations are indented.
2550 **Format:** ``for rtl`` ... ``end for;``
2552 :param configuration: The block configuration.
2553 """
2554 self._WriteIndentation()
2555 self._Write(f"{self._Keyword(ReservedWord.For)} ")
2557 def DepartBlockSpecification(self, configuration: BlockConfiguration) -> None:
2558 """
2559 End the line of a block specification; the nested configurations are indented.
2561 :param configuration: The block configuration.
2562 """
2563 self._Write("\n")
2564 self._indentation += 1
2566 def DepartBlockConfiguration(self, configuration: BlockConfiguration) -> None:
2567 """
2568 Write the end of a block configuration.
2570 :param configuration: The block configuration.
2571 """
2572 self._indentation -= 1
2573 self._WriteIndentation()
2574 self._Write(f"{self._Keyword(ReservedWord.End)} {self._Keyword(ReservedWord.For)};\n")
2576 def VisitComponentConfiguration(self, configuration: ComponentConfiguration) -> None:
2577 """
2578 Write the reserved word ``for`` of a component configuration.
2580 **Format:** ``for all : counter use entity work.counter(rtl);`` ... ``end for;``
2582 :param configuration: The component configuration.
2583 """
2584 self._WriteIndentation()
2585 self._Write(f"{self._Keyword(ReservedWord.For)} ")
2587 def DepartInstantiationList(self, configuration: ComponentConfiguration) -> None:
2588 """
2589 Write the colon between the instantiation list and the component name of a component configuration.
2591 :param configuration: The component configuration.
2592 """
2593 self._Write(" : ")
2595 def DepartComponentConfiguration(self, configuration: ComponentConfiguration) -> None:
2596 """
2597 Write the end of a component configuration on its own line.
2599 :param configuration: The component configuration.
2600 """
2601 self._Write("\n")
2602 self._WriteIndentation()
2603 self._Write(f"{self._Keyword(ReservedWord.End)} {self._Keyword(ReservedWord.For)};\n")
2605 def VisitBindingIndication(self, indication: BindingIndication) -> None:
2606 """
2607 Write the reserved word ``use`` of a binding indication on a new line, one indentation level deeper.
2609 **Format:** ``use entity work.counter(rtl)`` ... ``;``
2611 :param indication: The binding indication.
2612 """
2613 self._indentation += 1
2614 if indication.EntityAspect is not None: 2614 ↛ exitline 2614 didn't return from function 'VisitBindingIndication' because the condition on line 2614 was always true
2615 self._Write("\n")
2616 self._WriteIndentation()
2617 self._Write(f"{self._Keyword(ReservedWord.Use)} ")
2619 def DepartBindingIndication(self, indication: BindingIndication) -> None:
2620 """
2621 Write the semicolon ending a binding indication.
2623 :param indication: The binding indication.
2624 """
2625 self._Write(";")
2626 self._indentation -= 1
2628 def VisitEntityAspectEntity(self, aspect: EntityAspectEntity) -> None:
2629 """
2630 Write the reserved word ``entity`` of an entity aspect naming an entity.
2632 **Format:** ``entity work.counter(rtl)``
2634 :param aspect: The entity aspect.
2635 """
2636 self._Write(f"{self._Keyword(ReservedWord.Entity)} ")
2638 def VisitEntityAspectConfiguration(self, aspect: EntityAspectConfiguration) -> None:
2639 """
2640 Write the reserved word ``configuration`` of an entity aspect naming a configuration.
2642 **Format:** ``configuration work.counter_cfg``
2644 :param aspect: The entity aspect.
2645 """
2646 self._Write(f"{self._Keyword(ReservedWord.Configuration)} ")
2648 def VisitEntityAspectOpen(self, aspect: EntityAspectOpen) -> None:
2649 """
2650 Write the reserved word ``open`` of an open entity aspect.
2652 **Format:** ``open``
2654 :param aspect: The entity aspect.
2655 """
2656 self._Write(self._Keyword(ReservedWord.Open))
2658 def VisitAllInstantiationList(self, instantiationList: AllInstantiationList) -> None:
2659 """
2660 Write the reserved word ``all`` of an instantiation list.
2662 **Format:** ``all``
2664 :param instantiationList: The instantiation list.
2665 """
2666 self._Write(self._Keyword(ReservedWord.All))
2668 def VisitOthersInstantiationList(self, instantiationList: OthersInstantiationList) -> None:
2669 """
2670 Write the reserved word ``others`` of an instantiation list.
2672 **Format:** ``others``
2674 :param instantiationList: The instantiation list.
2675 """
2676 self._Write(self._Keyword(ReservedWord.Others))
2678 def VisitSignalAssignment(self, element: SignalAssignmentMixin) -> None:
2679 """
2680 Write the signal assignment delimiter (``<=``) between the target and the waveform of a signal assignment.
2682 In a force assignment, the reserved word ``force`` follows.
2684 :param element: The signal assignment.
2685 """
2686 if isinstance(element, SignalForceAssignment):
2687 self._Write(f" <= {self._Keyword(ReservedWord.Force)} ")
2688 else:
2689 self._Write(" <= ")
2691 self._minimum = OperatorPrecedence.Range
2693 def VisitAfter(self, element: WaveformElement) -> None:
2694 """
2695 Write the reserved word ``after`` before the delay of a waveform element.
2697 :param element: The waveform element.
2698 """
2699 self._Write(f" {self._Keyword(ReservedWord.After)} ")
2700 self._minimum = OperatorPrecedence.Range
2702 def VisitSelect(
2703 self,
2704 element: ConcurrentSelectedSignalAssignment | SequentialSelectedVariableAssignment |
2705 SequentialSelectedSignalAssignment
2706 ) -> None:
2707 """
2708 Write the reserved word ``select`` between the selector and the target of a selected assignment.
2710 :param element: The selected assignment.
2711 """
2712 self._Write(f" {self._Keyword(ReservedWord.Select)} ")
2714 def VisitBar(self, element: SelectedWaveform | GenerateCase | SelectedExpression | Case) -> None:
2715 """
2716 Write the vertical line (``|``) between two choices.
2718 :param element: The element with the choices.
2719 """
2720 self._Write(" | ")
2721 self._minimum = OperatorPrecedence.Range
2723 def VisitReport(self, element: ReportStatementMixin) -> None:
2724 """
2725 Write the reserved word ``report`` before the message of an assertion or report.
2727 A report statement starts with the reserved word.
2729 :param element: The assertion or report.
2730 """
2731 if isinstance(element, SequentialReportStatement):
2732 self._Write(f"{self._Keyword(ReservedWord.Report)} ")
2733 else:
2734 self._Write(f" {self._Keyword(ReservedWord.Report)} ")
2736 self._minimum = OperatorPrecedence.Range
2738 def VisitSeverity(self, element: ReportStatementMixin) -> None:
2739 """
2740 Write the reserved word ``severity`` before the severity level of an assertion or report.
2742 :param element: The assertion or report.
2743 """
2744 self._Write(f" {self._Keyword(ReservedWord.Severity)} ")
2745 self._minimum = OperatorPrecedence.Range
2747 def VisitSensitivityList(self, process: ProcessStatement) -> None:
2748 """
2749 Write the left parenthesis of the sensitivity list of a process.
2751 **Format:** ``process (clk, rst)`` or ``process (all)``
2753 :param process: The process.
2754 """
2755 self._Write(" (")
2757 def DepartSensitivityList(self, process: ProcessStatement) -> None:
2758 """
2759 Write the right parenthesis of the sensitivity list of a process.
2761 :param process: The process.
2762 """
2763 self._Write(")")
2765 def VisitActualParameterPart(self, call: ProcedureCallMixin) -> None:
2766 """
2767 Write the left parenthesis of the actual parameter part of a procedure call.
2769 :param call: The procedure call.
2770 """
2771 self._Write("(")
2772 self._minimum = OperatorPrecedence.Range
2774 def DepartActualParameterPart(self, call: ProcedureCallMixin) -> None:
2775 """
2776 Write the right parenthesis of the actual parameter part of a procedure call.
2778 :param call: The procedure call.
2779 """
2780 self._Write(")")
2782 def DepartOthersSelectedWaveform(self, waveform: OthersSelectedWaveform) -> None:
2783 """
2784 Write the choice ``others`` of the ``others`` selected waveform.
2786 **Format:** ``'0' when others``
2788 :param waveform: The selected waveform.
2789 """
2790 self._Write(self._Keyword(ReservedWord.Others))
2792 def VisitIndexedChoice(self, choice: IndexedChoice) -> None:
2793 """
2794 Enter a choice given by a value; the value is a simple expression.
2796 **Format:** ``'0'``
2798 :param choice: The choice.
2799 """
2800 self._minimum = OperatorPrecedence.Adding
2802 def VisitProcessStatement(self, process: ProcessStatement) -> None:
2803 """
2804 Write the label, if any, and the reserved word ``process`` of a process statement.
2806 **Format:** ``count : process (clk) is`` ... ``begin`` ... ``end process count;``
2808 A process with ``all`` as sensitivity list has a single :class:`~pyVHDLModel.Name.AllName` without prefix in its
2809 sensitivity list.
2811 :param process: The process.
2812 """
2813 self._WriteStatementStart(process)
2814 self._Write(self._Keyword(ReservedWord.Process))
2816 def _WriteStatementStart(self, statement: Statement) -> None:
2817 """
2818 Write the indentation and the label, if any, of a statement.
2820 :param statement: The statement.
2821 """
2822 self._WriteIndentation()
2823 if statement.Label is not None:
2824 self._Write(f"{statement.Label} : ")
2826 def DepartProcessStatement(self, process: ProcessStatement) -> None:
2827 """
2828 Write the end of a process statement.
2830 :param process: The process.
2831 """
2832 self._WriteEnd((ReservedWord.Process,), process.Label)
2834 def VisitConcurrentProcedureCall(self, call: ConcurrentProcedureCall) -> None:
2835 """
2836 Write the label, if any, of a concurrent procedure call.
2838 **Format:** ``check(clk, rst);``
2840 :param call: The procedure call.
2841 """
2842 self._WriteStatementStart(call)
2844 def DepartConcurrentProcedureCall(self, call: ConcurrentProcedureCall) -> None:
2845 """
2846 Write the semicolon ending a concurrent procedure call.
2848 :param call: The procedure call.
2849 """
2850 self._Write(";\n")
2852 def VisitConcurrentSimpleSignalAssignment(self, assignment: ConcurrentSimpleSignalAssignment) -> None:
2853 """
2854 Write the label, if any, of a concurrent simple signal assignment.
2856 **Format:** ``q <= d after 1 ns;``
2858 :param assignment: The signal assignment.
2859 """
2860 self._WriteStatementStart(assignment)
2862 def DepartConcurrentSimpleSignalAssignment(self, assignment: ConcurrentSimpleSignalAssignment) -> None:
2863 """
2864 Write the semicolon ending a concurrent simple signal assignment.
2866 :param assignment: The signal assignment.
2867 """
2868 self._Write(";\n")
2870 def VisitConcurrentSelectedSignalAssignment(self, assignment: ConcurrentSelectedSignalAssignment) -> None:
2871 """
2872 Write the label, if any, and the reserved word ``with`` of a concurrent selected signal assignment.
2874 **Format:** ``with sel select q <= a when '0', b when others;``
2876 :param assignment: The signal assignment.
2877 """
2878 self._WriteStatementStart(assignment)
2879 self._Write(f"{self._Keyword(ReservedWord.With)} ")
2880 self._minimum = OperatorPrecedence.Range
2882 def DepartConcurrentSelectedSignalAssignment(self, assignment: ConcurrentSelectedSignalAssignment) -> None:
2883 """
2884 Write the semicolon ending a concurrent selected signal assignment.
2886 :param assignment: The signal assignment.
2887 """
2888 self._Write(";\n")
2890 def VisitConcurrentConditionalSignalAssignment(self, assignment: ConcurrentConditionalSignalAssignment) -> None:
2891 """
2892 Write the label, if any, of a concurrent conditional signal assignment.
2894 **Format:** ``q <= a when sel = '0' else b;``
2896 :param assignment: The signal assignment.
2897 """
2898 self._WriteStatementStart(assignment)
2900 def DepartConcurrentConditionalSignalAssignment(self, assignment: ConcurrentConditionalSignalAssignment) -> None:
2901 """
2902 Write the semicolon ending a concurrent conditional signal assignment.
2904 :param assignment: The signal assignment.
2905 """
2906 self._Write(";\n")
2908 def VisitConcurrentAssertStatement(self, assertion: ConcurrentAssertStatement) -> None:
2909 """
2910 Write the label, if any, and the reserved word ``assert`` of a concurrent assertion.
2912 **Format:** ``assert BITS > 0 report "no bits" severity failure;``
2914 :param assertion: The assertion.
2915 """
2916 self._WriteStatementStart(assertion)
2917 self._Write(f"{self._Keyword(ReservedWord.Assert)} ")
2918 self._minimum = OperatorPrecedence.Range
2920 def DepartConcurrentAssertStatement(self, assertion: ConcurrentAssertStatement) -> None:
2921 """
2922 Write the semicolon ending a concurrent assertion.
2924 :param assertion: The assertion.
2925 """
2926 self._Write(";\n")
2928 def VisitRightParenthesis(self, element: EntityAspectEntity | EntityInstantiation) -> None:
2929 """
2930 Write the right parenthesis after the architecture name of an entity aspect or entity instantiation.
2932 :param element: The element enclosing the architecture name.
2933 """
2934 self._Write(")")
2936 def VisitGenerate(self, element: GenerateBranch | CaseGenerateStatement | ForGenerateStatement) -> None:
2937 """
2938 Write the reserved word ``generate``; the body of the generate statement or branch is indented.
2940 :param element: The generate statement or branch.
2941 """
2942 self._Write(f" {self._Keyword(ReservedWord.Generate)}\n")
2943 self._indentation += 1
2945 def VisitComponentInstantiation(self, instantiation: ComponentInstantiation) -> None:
2946 """
2947 Write the label and the reserved word ``component`` of a component instantiation.
2949 **Format:** ``u1 : component counter`` ... ``;``
2951 :param instantiation: The component instantiation.
2952 :raises VHDLWriterError: If the component instantiation has no label.
2953 """
2954 if instantiation.Label is None:
2955 raise VHDLWriterError("Component instantiation has no label.", instantiation)
2957 self._WriteStatementStart(instantiation)
2958 self._Write(f"{self._Keyword(ReservedWord.Component)} ")
2960 def DepartComponentInstantiation(self, instantiation: ComponentInstantiation) -> None:
2961 """
2962 Write the semicolon ending a component instantiation.
2964 :param instantiation: The component instantiation.
2965 """
2966 self._Write(";\n")
2968 def VisitEntityInstantiation(self, instantiation: EntityInstantiation) -> None:
2969 """
2970 Write the label and the reserved word ``entity`` of an entity instantiation.
2972 **Format:** ``u1 : entity work.counter(rtl)`` ... ``;``
2974 :param instantiation: The entity instantiation.
2975 :raises VHDLWriterError: If the entity instantiation has no label.
2976 """
2977 if instantiation.Label is None: 2977 ↛ 2978line 2977 didn't jump to line 2978 because the condition on line 2977 was never true
2978 raise VHDLWriterError("Entity instantiation has no label.", instantiation)
2980 self._WriteStatementStart(instantiation)
2981 self._Write(f"{self._Keyword(ReservedWord.Entity)} ")
2983 def DepartEntityInstantiation(self, instantiation: EntityInstantiation) -> None:
2984 """
2985 Write the semicolon ending an entity instantiation.
2987 :param instantiation: The entity instantiation.
2988 """
2989 self._Write(";\n")
2991 def VisitConfigurationInstantiation(self, instantiation: ConfigurationInstantiation) -> None:
2992 """
2993 Write the label and the reserved word ``configuration`` of a configuration instantiation.
2995 **Format:** ``u1 : configuration work.counter_cfg`` ... ``;``
2997 :param instantiation: The configuration instantiation.
2998 :raises VHDLWriterError: If the configuration instantiation has no label.
2999 """
3000 if instantiation.Label is None: 3000 ↛ 3001line 3000 didn't jump to line 3001 because the condition on line 3000 was never true
3001 raise VHDLWriterError("Configuration instantiation has no label.", instantiation)
3003 self._WriteStatementStart(instantiation)
3004 self._Write(f"{self._Keyword(ReservedWord.Configuration)} ")
3006 def DepartConfigurationInstantiation(self, instantiation: ConfigurationInstantiation) -> None:
3007 """
3008 Write the semicolon ending a configuration instantiation.
3010 :param instantiation: The configuration instantiation.
3011 """
3012 self._Write(";\n")
3014 def VisitConcurrentBlockStatement(self, block: ConcurrentBlockStatement) -> None:
3015 """
3016 Write the label and the reserved word ``block`` of a block statement; its header and declarations are indented.
3018 **Format:** ``inner : block`` ... ``begin`` ... ``end block inner;``
3020 :param block: The block statement.
3021 :raises VHDLWriterError: If the block statement has no label.
3022 """
3023 if block.Label is None: 3023 ↛ 3024line 3023 didn't jump to line 3024 because the condition on line 3023 was never true
3024 raise VHDLWriterError("Block statement has no label.", block)
3026 self._WriteStatementStart(block)
3027 self._Write(f"{self._Keyword(ReservedWord.Block)}\n")
3028 self._indentation += 1
3030 def DepartConcurrentBlockStatement(self, block: ConcurrentBlockStatement) -> None:
3031 """
3032 Write the end of a block statement.
3034 :param block: The block statement.
3035 """
3036 self._WriteEnd((ReservedWord.Block,), block.Label)
3038 def VisitIfGenerateStatement(self, statement: IfGenerateStatement) -> None:
3039 """
3040 Write the label of an if-generate statement; its branches follow.
3042 **Format:** ``gen : if BITS > 8 generate`` ... ``elsif`` ... ``else generate`` ... ``end generate gen;``
3044 :param statement: The if-generate statement.
3045 :raises VHDLWriterError: If the if-generate statement has no label.
3046 """
3047 if statement.Label is None: 3047 ↛ 3048line 3047 didn't jump to line 3048 because the condition on line 3047 was never true
3048 raise VHDLWriterError("If-generate statement has no label.", statement)
3050 self._WriteStatementStart(statement)
3052 def DepartIfGenerateStatement(self, statement: IfGenerateStatement) -> None:
3053 """
3054 Write the end of an if-generate statement.
3056 :param statement: The if-generate statement.
3057 """
3058 self._WriteEndLine((ReservedWord.Generate,), statement.Label)
3060 def VisitIfGenerateBranch(self, branch: IfGenerateBranch) -> None:
3061 """
3062 Write the reserved word ``if`` and the alternative label, if any, of the if branch of an if-generate statement.
3064 :param branch: The generate branch.
3065 """
3066 self._Write(f"{self._Keyword(ReservedWord.If)} ")
3067 self._WriteAlternativeLabel(branch)
3069 def _WriteAlternativeLabel(self, branch: GenerateBranch) -> None:
3070 """
3071 Write the alternative label, if any, of a generate branch, followed by a colon.
3073 :param branch: The generate branch.
3074 """
3075 if branch.AlternativeLabel is not None:
3076 self._Write(f"{branch.AlternativeLabel} : ")
3078 self._minimum = OperatorPrecedence.Range
3080 def DepartIfGenerateBranch(self, branch: IfGenerateBranch) -> None:
3081 """
3082 Leave the body of the if branch of an if-generate statement.
3084 :param branch: The generate branch.
3085 """
3086 self._indentation -= 1
3088 def VisitElsifGenerateBranch(self, branch: ElsifGenerateBranch) -> None:
3089 """
3090 Write the reserved word ``elsif`` and the alternative label, if any, of an elsif branch of an if-generate statement.
3092 :param branch: The generate branch.
3093 """
3094 self._WriteIndentation()
3095 self._Write(f"{self._Keyword(ReservedWord.ElsIf)} ")
3096 self._WriteAlternativeLabel(branch)
3098 def DepartElsifGenerateBranch(self, branch: ElsifGenerateBranch) -> None:
3099 """
3100 Leave the body of an elsif branch of an if-generate statement.
3102 :param branch: The generate branch.
3103 """
3104 self._indentation -= 1
3106 def VisitElseGenerateBranch(self, branch: ElseGenerateBranch) -> None:
3107 """
3108 Write the reserved word ``else`` and the alternative label, if any, of the else branch of an if-generate statement.
3110 :param branch: The generate branch.
3111 """
3112 self._WriteIndentation()
3113 self._Write(self._Keyword(ReservedWord.Else))
3114 if branch.AlternativeLabel is not None:
3115 self._Write(f" {branch.AlternativeLabel} :")
3117 def DepartElseGenerateBranch(self, branch: ElseGenerateBranch) -> None:
3118 """
3119 Leave the body of the else branch of an if-generate statement.
3121 :param branch: The generate branch.
3122 """
3123 self._indentation -= 1
3125 def VisitCaseGenerateStatement(self, statement: CaseGenerateStatement) -> None:
3126 """
3127 Write the label and the reserved word ``case`` of a case-generate statement; its alternatives are indented.
3129 **Format:** ``gen : case MODE generate`` ... ``when 0 =>`` ... ``end generate gen;``
3131 :param statement: The case-generate statement.
3132 :raises VHDLWriterError: If the case-generate statement has no label.
3133 """
3134 if statement.Label is None: 3134 ↛ 3135line 3134 didn't jump to line 3135 because the condition on line 3134 was never true
3135 raise VHDLWriterError("Case-generate statement has no label.", statement)
3137 self._WriteStatementStart(statement)
3138 self._Write(f"{self._Keyword(ReservedWord.Case)} ")
3139 self._minimum = OperatorPrecedence.Range
3141 def DepartCaseGenerateStatement(self, statement: CaseGenerateStatement) -> None:
3142 """
3143 Write the end of a case-generate statement.
3145 :param statement: The case-generate statement.
3146 """
3147 self._WriteEnd((ReservedWord.Generate,), statement.Label)
3149 def VisitGenerateCase(self, case: GenerateCase) -> None:
3150 """
3151 Write the reserved word ``when`` and the alternative label, if any, of an alternative of a case-generate statement.
3153 **Format:** ``when 1 | 2 =>``
3155 :param case: The case-generate alternative.
3156 """
3157 self._WriteIndentation()
3158 self._Write(f"{self._Keyword(ReservedWord.When)} ")
3159 if case.Label is not None:
3160 self._Write(f"{case.Label} : ")
3162 def DepartGenerateCase(self, case: GenerateCase) -> None:
3163 """
3164 Leave the body of an alternative of a case-generate statement.
3166 :param case: The case-generate alternative.
3167 """
3168 self._indentation -= 1
3170 def VisitOthersGenerateCase(self, case: OthersGenerateCase) -> None:
3171 """
3172 Write the reserved words ``when`` and ``others`` of the ``others`` alternative of a case-generate statement.
3174 **Format:** ``when others =>``
3176 :param case: The case-generate alternative.
3177 """
3178 self._WriteIndentation()
3179 self._Write(f"{self._Keyword(ReservedWord.When)} ")
3180 if case.Label is not None: 3180 ↛ 3181line 3180 didn't jump to line 3181 because the condition on line 3180 was never true
3181 self._Write(f"{case.Label} : ")
3183 self._Write(self._Keyword(ReservedWord.Others))
3185 def DepartOthersGenerateCase(self, case: OthersGenerateCase) -> None:
3186 """
3187 Leave the body of the ``others`` alternative of a case-generate statement.
3189 :param case: The case-generate alternative.
3190 """
3191 self._indentation -= 1
3193 def VisitIndexedGenerateChoice(self, choice: IndexedGenerateChoice) -> None:
3194 """
3195 Enter a case-generate choice given by a value; the value is a simple expression.
3197 **Format:** ``8``
3199 :param choice: The choice.
3200 """
3201 self._minimum = OperatorPrecedence.Adding
3203 def VisitForGenerateStatement(self, statement: ForGenerateStatement) -> None:
3204 """
3205 Write the label, the reserved word ``for``, the loop index and ``in`` of a for-generate statement.
3207 **Format:** ``gen : for i in 0 to 3 generate`` ... ``end generate gen;``
3209 :param statement: The for-generate statement.
3210 :raises VHDLWriterError: If the for-generate statement has no label.
3211 """
3212 if statement.Label is None:
3213 raise VHDLWriterError("For-generate statement has no label.", statement)
3215 self._WriteStatementStart(statement)
3216 self._Write(f"{self._Keyword(ReservedWord.For)} {statement.LoopIndex} {self._Keyword(ReservedWord.In)} ")
3217 self._minimum = OperatorPrecedence.Range
3219 def DepartForGenerateStatement(self, statement: ForGenerateStatement) -> None:
3220 """
3221 Write the end of a for-generate statement.
3223 :param statement: The for-generate statement.
3224 """
3225 self._WriteEnd((ReservedWord.Generate,), statement.Label)
3227 def VisitOn(self, statement: WaitStatement) -> None:
3228 """
3229 Write the reserved word ``on`` before the sensitivity list of a wait statement.
3231 :param statement: The wait statement.
3232 """
3233 self._Write(f" {self._Keyword(ReservedWord.On)} ")
3235 def VisitUntil(self, statement: WaitStatement) -> None:
3236 """
3237 Write the reserved word ``until`` before the condition of a wait statement.
3239 :param statement: The wait statement.
3240 """
3241 self._Write(f" {self._Keyword(ReservedWord.Until)} ")
3242 self._minimum = OperatorPrecedence.Range
3244 def VisitFor(self, statement: WaitStatement) -> None:
3245 """
3246 Write the reserved word ``for`` before the timeout of a wait statement.
3248 :param statement: The wait statement.
3249 """
3250 self._Write(f" {self._Keyword(ReservedWord.For)} ")
3251 self._minimum = OperatorPrecedence.Range
3253 def DepartOthersSelectedExpression(self, expression: OthersSelectedExpression) -> None:
3254 """
3255 Write the choice ``others`` of the ``others`` selected expression.
3257 **Format:** ``'0' when others``
3259 :param expression: The selected expression.
3260 """
3261 self._Write(self._Keyword(ReservedWord.Others))
3263 def VisitSequentialProcedureCall(self, call: SequentialProcedureCall) -> None:
3264 """
3265 Write the label, if any, of a procedure call.
3267 **Format:** ``check(value, limit => 4);``
3269 :param call: The procedure call.
3270 """
3271 self._WriteStatementStart(call)
3273 def DepartSequentialProcedureCall(self, call: SequentialProcedureCall) -> None:
3274 """
3275 Write the semicolon ending a procedure call.
3277 :param call: The procedure call.
3278 """
3279 self._Write(";\n")
3281 def VisitSequentialSimpleSignalAssignment(self, assignment: SequentialSimpleSignalAssignment) -> None:
3282 """
3283 Write the label, if any, of a signal assignment.
3285 **Format:** ``q <= d after 1 ns;``
3287 :param assignment: The signal assignment.
3288 """
3289 self._WriteStatementStart(assignment)
3291 def DepartSequentialSimpleSignalAssignment(self, assignment: SequentialSimpleSignalAssignment) -> None:
3292 """
3293 Write the semicolon ending a signal assignment.
3295 :param assignment: The signal assignment.
3296 """
3297 self._Write(";\n")
3299 def VisitSequentialVariableAssignment(self, assignment: SequentialVariableAssignment) -> None:
3300 """
3301 Write the label, if any, of a variable assignment.
3303 **Format:** ``count := count + 1;``
3305 :param assignment: The variable assignment.
3306 """
3307 self._WriteStatementStart(assignment)
3309 def DepartSequentialVariableAssignment(self, assignment: SequentialVariableAssignment) -> None:
3310 """
3311 Write the semicolon ending a variable assignment.
3313 :param assignment: The variable assignment.
3314 """
3315 self._Write(";\n")
3317 def VisitSequentialConditionalVariableAssignment(self, assignment: SequentialConditionalVariableAssignment) -> None:
3318 """
3319 Write the label, if any, of a conditional variable assignment.
3321 **Format:** ``v := a when sel = '0' else b;``
3323 :param assignment: The conditional variable assignment.
3324 """
3325 self._WriteStatementStart(assignment)
3327 def DepartSequentialConditionalVariableAssignment(self, assignment: SequentialConditionalVariableAssignment) -> None:
3328 """
3329 Write the semicolon ending a conditional variable assignment.
3331 :param assignment: The conditional variable assignment.
3332 """
3333 self._Write(";\n")
3335 def VisitSequentialConditionalSignalAssignment(self, assignment: SequentialConditionalSignalAssignment) -> None:
3336 """
3337 Write the label, if any, of a conditional signal assignment.
3339 **Format:** ``q <= a when sel = '0' else b;``
3341 :param assignment: The conditional signal assignment.
3342 """
3343 self._WriteStatementStart(assignment)
3345 def DepartSequentialConditionalSignalAssignment(self, assignment: SequentialConditionalSignalAssignment) -> None:
3346 """
3347 Write the semicolon ending a conditional signal assignment.
3349 :param assignment: The conditional signal assignment.
3350 """
3351 self._Write(";\n")
3353 def VisitSequentialSelectedVariableAssignment(self, assignment: SequentialSelectedVariableAssignment) -> None:
3354 """
3355 Write the label, if any, and the reserved word ``with`` of a selected variable assignment.
3357 **Format:** ``with sel select v := a when '0', b when others;``
3359 :param assignment: The selected variable assignment.
3360 """
3361 self._WriteStatementStart(assignment)
3362 self._Write(f"{self._Keyword(ReservedWord.With)} ")
3363 self._minimum = OperatorPrecedence.Range
3365 def DepartSequentialSelectedVariableAssignment(self, assignment: SequentialSelectedVariableAssignment) -> None:
3366 """
3367 Write the semicolon ending a selected variable assignment.
3369 :param assignment: The selected variable assignment.
3370 """
3371 self._Write(";\n")
3373 def VisitSequentialSelectedSignalAssignment(self, assignment: SequentialSelectedSignalAssignment) -> None:
3374 """
3375 Write the label, if any, and the reserved word ``with`` of a selected signal assignment.
3377 **Format:** ``with sel select q <= a when '0', b when others;``
3379 :param assignment: The selected signal assignment.
3380 """
3381 self._WriteStatementStart(assignment)
3382 self._Write(f"{self._Keyword(ReservedWord.With)} ")
3383 self._minimum = OperatorPrecedence.Range
3385 def DepartSequentialSelectedSignalAssignment(self, assignment: SequentialSelectedSignalAssignment) -> None:
3386 """
3387 Write the semicolon ending a selected signal assignment.
3389 :param assignment: The selected signal assignment.
3390 """
3391 self._Write(";\n")
3393 def VisitSignalForceAssignment(self, assignment: SignalForceAssignment) -> None:
3394 """
3395 Write the label, if any, of a force assignment.
3397 **Format:** ``q <= force '1';``
3399 :param assignment: The force assignment.
3400 """
3401 self._WriteStatementStart(assignment)
3403 def DepartSignalForceAssignment(self, assignment: SignalForceAssignment) -> None:
3404 """
3405 Write the semicolon ending a force assignment.
3407 :param assignment: The force assignment.
3408 """
3409 self._Write(";\n")
3411 def VisitSignalReleaseAssignment(self, assignment: SignalReleaseAssignment) -> None:
3412 """
3413 Write the label, if any, of a release assignment.
3415 **Format:** ``q <= release;``
3417 :param assignment: The release assignment.
3418 """
3419 self._WriteStatementStart(assignment)
3421 def DepartSignalReleaseAssignment(self, assignment: SignalReleaseAssignment) -> None:
3422 """
3423 Write the reserved word ``release`` and the semicolon ending a release assignment.
3425 :param assignment: The release assignment.
3426 """
3427 self._Write(f"{self._Keyword(ReservedWord.Release)};\n")
3429 def VisitSequentialReportStatement(self, statement: SequentialReportStatement) -> None:
3430 """
3431 Write the label, if any, of a report statement.
3433 **Format:** ``report "done" severity note;``
3435 :param statement: The report statement.
3436 """
3437 self._WriteStatementStart(statement)
3439 def DepartSequentialReportStatement(self, statement: SequentialReportStatement) -> None:
3440 """
3441 Write the semicolon ending a report statement.
3443 :param statement: The report statement.
3444 """
3445 self._Write(";\n")
3447 def VisitSequentialAssertStatement(self, assertion: SequentialAssertStatement) -> None:
3448 """
3449 Write the label, if any, and the reserved word ``assert`` of an assertion.
3451 **Format:** ``assert count < 8 report "overflow" severity error;``
3453 :param assertion: The assertion.
3454 """
3455 self._WriteStatementStart(assertion)
3456 self._Write(f"{self._Keyword(ReservedWord.Assert)} ")
3457 self._minimum = OperatorPrecedence.Range
3459 def DepartSequentialAssertStatement(self, assertion: SequentialAssertStatement) -> None:
3460 """
3461 Write the semicolon ending an assertion.
3463 :param assertion: The assertion.
3464 """
3465 self._Write(";\n")
3467 def VisitNullStatement(self, statement: NullStatement) -> None:
3468 """
3469 Write a null statement.
3471 **Format:** ``null;``
3473 :param statement: The null statement.
3474 """
3475 self._WriteStatementStart(statement)
3476 self._Write(f"{self._Keyword(ReservedWord.Null)};\n")
3478 def VisitReturnStatement(self, statement: ReturnStatement) -> None:
3479 """
3480 Write the label, if any, and the reserved word ``return`` of a return statement.
3482 **Format:** ``return count;``
3484 :param statement: The return statement.
3485 """
3486 self._WriteStatementStart(statement)
3487 self._Write(self._Keyword(ReservedWord.Return))
3488 if statement.ReturnValue is not None:
3489 self._Write(" ")
3490 self._minimum = OperatorPrecedence.Range
3492 def DepartReturnStatement(self, statement: ReturnStatement) -> None:
3493 """
3494 Write the semicolon ending a return statement.
3496 :param statement: The return statement.
3497 """
3498 self._Write(";\n")
3500 def VisitWaitStatement(self, statement: WaitStatement) -> None:
3501 """
3502 Write the label, if any, and the reserved word ``wait`` of a wait statement.
3504 **Format:** ``wait on clk until clk = '1' for 10 ns;``
3506 :param statement: The wait statement.
3507 """
3508 self._WriteStatementStart(statement)
3509 self._Write(self._Keyword(ReservedWord.Wait))
3511 def DepartWaitStatement(self, statement: WaitStatement) -> None:
3512 """
3513 Write the semicolon ending a wait statement.
3515 :param statement: The wait statement.
3516 """
3517 self._Write(";\n")
3519 def VisitThen(self, branch: IfBranch | ElsifBranch) -> None:
3520 """
3521 Write the reserved word ``then`` of an if or elsif branch; its statements are indented.
3523 :param branch: The branch.
3524 """
3525 self._Write(f" {self._Keyword(ReservedWord.Then)}\n")
3526 self._indentation += 1
3528 def VisitLoop(self, statement: LoopStatement) -> None:
3529 """
3530 Write the reserved word ``loop`` of a loop statement; its statements are indented.
3532 :param statement: The loop statement.
3533 """
3534 if isinstance(statement, EndlessLoopStatement):
3535 self._Write(f"{self._Keyword(ReservedWord.Loop)}\n")
3536 else:
3537 self._Write(f" {self._Keyword(ReservedWord.Loop)}\n")
3539 self._indentation += 1
3541 def VisitIfStatement(self, statement: IfStatement) -> None:
3542 """
3543 Write the label, if any, of an if statement; its branches follow.
3545 **Format:** ``if count = 0 then`` ... ``elsif`` ... ``else`` ... ``end if;``
3547 :param statement: The if statement.
3548 """
3549 self._WriteStatementStart(statement)
3551 def DepartIfStatement(self, statement: IfStatement) -> None:
3552 """
3553 Write the end of an if statement.
3555 :param statement: The if statement.
3556 """
3557 self._WriteEndLine((ReservedWord.If,), statement.Label)
3559 def VisitIfBranch(self, branch: IfBranch) -> None:
3560 """
3561 Write the reserved word ``if`` of the if branch of an if statement.
3563 :param branch: The branch.
3564 """
3565 self._Write(f"{self._Keyword(ReservedWord.If)} ")
3566 self._minimum = OperatorPrecedence.Range
3568 def DepartIfBranch(self, branch: IfBranch) -> None:
3569 """
3570 Leave the statements of the if branch of an if statement.
3572 :param branch: The branch.
3573 """
3574 self._indentation -= 1
3576 def VisitElsifBranch(self, branch: ElsifBranch) -> None:
3577 """
3578 Write the reserved word ``elsif`` of an elsif branch of an if statement.
3580 :param branch: The branch.
3581 """
3582 self._WriteIndentation()
3583 self._Write(f"{self._Keyword(ReservedWord.ElsIf)} ")
3584 self._minimum = OperatorPrecedence.Range
3586 def DepartElsifBranch(self, branch: ElsifBranch) -> None:
3587 """
3588 Leave the statements of an elsif branch of an if statement.
3590 :param branch: The branch.
3591 """
3592 self._indentation -= 1
3594 def VisitElseBranch(self, branch: ElseBranch) -> None:
3595 """
3596 Write the reserved word ``else`` of the else branch of an if statement; its statements are indented.
3598 :param branch: The branch.
3599 """
3600 self._WriteIndentation()
3601 self._Write(f"{self._Keyword(ReservedWord.Else)}\n")
3602 self._indentation += 1
3604 def DepartElseBranch(self, branch: ElseBranch) -> None:
3605 """
3606 Leave the statements of the else branch of an if statement.
3608 :param branch: The branch.
3609 """
3610 self._indentation -= 1
3612 def VisitCaseStatement(self, statement: CaseStatement) -> None:
3613 """
3614 Write the label, if any, and the reserved word ``case`` of a case statement; its alternatives are indented.
3616 **Format:** ``case state is`` ... ``when Idle =>`` ... ``end case;``
3618 :param statement: The case statement.
3619 """
3620 self._WriteStatementStart(statement)
3621 self._Write(f"{self._Keyword(ReservedWord.Case)} ")
3622 self._minimum = OperatorPrecedence.Range
3624 def DepartCaseStatement(self, statement: CaseStatement) -> None:
3625 """
3626 Write the end of a case statement.
3628 :param statement: The case statement.
3629 """
3630 self._WriteEnd((ReservedWord.Case,), statement.Label)
3632 def VisitCase(self, case: Case) -> None:
3633 """
3634 Write the reserved word ``when`` of an alternative of a case statement.
3636 **Format:** ``when 1 | 2 =>``
3638 :param case: The case alternative.
3639 """
3640 self._WriteIndentation()
3641 self._Write(f"{self._Keyword(ReservedWord.When)} ")
3643 def DepartCase(self, case: Case) -> None:
3644 """
3645 Leave the statements of an alternative of a case statement.
3647 :param case: The case alternative.
3648 """
3649 self._indentation -= 1
3651 def VisitOthersCase(self, case: OthersCase) -> None:
3652 """
3653 Write the reserved words ``when`` and ``others`` of the ``others`` alternative of a case statement.
3655 **Format:** ``when others =>``
3657 :param case: The case alternative.
3658 """
3659 self._WriteIndentation()
3660 self._Write(f"{self._Keyword(ReservedWord.When)} {self._Keyword(ReservedWord.Others)}")
3662 def DepartOthersCase(self, case: OthersCase) -> None:
3663 """
3664 Leave the statements of the ``others`` alternative of a case statement.
3666 :param case: The case alternative.
3667 """
3668 self._indentation -= 1
3670 def VisitEndlessLoopStatement(self, statement: EndlessLoopStatement) -> None:
3671 """
3672 Write the label, if any, of a loop statement without iteration scheme.
3674 **Format:** ``loop`` ... ``end loop;``
3676 :param statement: The loop statement.
3677 """
3678 self._WriteStatementStart(statement)
3680 def DepartEndlessLoopStatement(self, statement: EndlessLoopStatement) -> None:
3681 """
3682 Write the end of a loop statement without iteration scheme.
3684 :param statement: The loop statement.
3685 """
3686 self._WriteEnd((ReservedWord.Loop,), statement.Label)
3688 def VisitForLoopStatement(self, statement: ForLoopStatement) -> None:
3689 """
3690 Write the label, if any, the reserved word ``for``, the loop index and ``in`` of a for-loop statement.
3692 **Format:** ``for i in 0 to 7 loop`` ... ``end loop;``
3694 :param statement: The loop statement.
3695 """
3696 self._WriteStatementStart(statement)
3697 self._Write(f"{self._Keyword(ReservedWord.For)} {statement.LoopIndex} {self._Keyword(ReservedWord.In)} ")
3698 self._minimum = OperatorPrecedence.Range
3700 def DepartForLoopStatement(self, statement: ForLoopStatement) -> None:
3701 """
3702 Write the end of a for-loop statement.
3704 :param statement: The loop statement.
3705 """
3706 self._WriteEnd((ReservedWord.Loop,), statement.Label)
3708 def VisitWhileLoopStatement(self, statement: WhileLoopStatement) -> None:
3709 """
3710 Write the label, if any, and the reserved word ``while`` of a while-loop statement.
3712 **Format:** ``while count < 8 loop`` ... ``end loop;``
3714 :param statement: The loop statement.
3715 """
3716 self._WriteStatementStart(statement)
3717 self._Write(f"{self._Keyword(ReservedWord.While)} ")
3718 self._minimum = OperatorPrecedence.Range
3720 def DepartWhileLoopStatement(self, statement: WhileLoopStatement) -> None:
3721 """
3722 Write the end of a while-loop statement.
3724 :param statement: The loop statement.
3725 """
3726 self._WriteEnd((ReservedWord.Loop,), statement.Label)
3728 def VisitNextStatement(self, statement: NextStatement) -> None:
3729 """
3730 Write the label, if any, and the reserved word ``next`` of a next statement.
3732 **Format:** ``next when skip;``
3734 The model keeps no loop label, so none is written.
3736 :param statement: The next statement.
3737 """
3738 self._WriteStatementStart(statement)
3739 self._Write(self._Keyword(ReservedWord.Next))
3741 def DepartNextStatement(self, statement: NextStatement) -> None:
3742 """
3743 Write the semicolon ending a next statement.
3745 :param statement: The next statement.
3746 """
3747 self._Write(";\n")
3749 def VisitExitStatement(self, statement: ExitStatement) -> None:
3750 """
3751 Write the label, if any, and the reserved word ``exit`` of an exit statement.
3753 **Format:** ``exit when done;``
3755 The model keeps no loop label, so none is written.
3757 :param statement: The exit statement.
3758 """
3759 self._WriteStatementStart(statement)
3760 self._Write(self._Keyword(ReservedWord.Exit))
3762 def DepartExitStatement(self, statement: ExitStatement) -> None:
3763 """
3764 Write the semicolon ending an exit statement.
3766 :param statement: The exit statement.
3767 """
3768 self._Write(";\n")