From 357cb9746c53e3f32fc9c2f28686c25e388918c3 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Thu, 12 Aug 2021 13:06:11 +0200 Subject: Preparations for sequential statements. --- pyGHDL/dom/Sequential.py | 388 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 388 insertions(+) create mode 100644 pyGHDL/dom/Sequential.py (limited to 'pyGHDL/dom/Sequential.py') diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py new file mode 100644 index 000000000..896b09544 --- /dev/null +++ b/pyGHDL/dom/Sequential.py @@ -0,0 +1,388 @@ +# ============================================================================= +# ____ _ _ ____ _ _ +# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___ +# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \ +# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | | +# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_| +# |_| |___/ +# ============================================================================= +# Authors: +# Patrick Lehmann +# +# Package module: DOM: Sequential statements. +# +# License: +# ============================================================================ +# Copyright (C) 2019-2021 Tristan Gingold +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# SPDX-License-Identifier: GPL-2.0-or-later +# ============================================================================ +from typing import Iterable + +from pydecor import export + +from pyGHDL.dom.Concurrent import WaveformElement # TODO: move out from concurrent? +from pyGHDL.dom.Range import Range +from pyVHDLModel.SyntaxModel import ( + IfBranch as VHDLModel_IfBranch, + ElsifBranch as VHDLModel_ElsifBranch, + ElseBranch as VHDLModel_ElseBranch, + IfStatement as VHDLModel_IfStatement, + IndexedChoice as VHDLModel_IndexedChoice, + RangedChoice as VHDLModel_RangedChoice, + OthersCase as VHDLModel_OthersCase, + Case as VHDLModel_Case, + CaseStatement as VHDLModel_CaseStatement, + ForLoopStatement as VHDLModel_ForLoopStatement, + SequentialSimpleSignalAssignment as VHDLModel_SequentialSimpleSignalAssignment, + SequentialProcedureCall as VHDLModel_SequentialProcedureCall, + Name, + SequentialStatement, + Expression, + SequentialChoice, SequentialCase, +) + + +from pyGHDL.libghdl import Iir, utils +from pyGHDL.libghdl.vhdl import nodes +from pyGHDL.dom import DOMMixin +from pyGHDL.dom._Utils import GetNameOfNode + + +@export +class IfBranch(VHDLModel_IfBranch): + def __init__( + self, + branchNode: Iir, + condition: Expression, + statements: Iterable[SequentialStatement] = None, + ): + super().__init__(condition, statements) + DOMMixin.__init__(self, branchNode) + + @classmethod + def parse(cls, generateNode: Iir, label: str) -> "IfBranch": + from pyGHDL.dom._Translate import ( + GetSequentialStatementsFromChainedNodes, + GetExpressionFromNode, + ) + + condition = GetExpressionFromNode(nodes.Get_Condition(generateNode)) + body = nodes.Get_Generate_Statement_Body(generateNode) + + statementChain = nodes.Get_Sequential_Statement_Chain(body) + statements = GetSequentialStatementsFromChainedNodes( + statementChain, "if branch", label + ) + + return cls(generateNode, condition, statements) + + +@export +class ElsifBranch(VHDLModel_ElsifBranch): + def __init__( + self, + branchNode: Iir, + condition: Expression, + statements: Iterable[SequentialStatement] = None, + ): + super().__init__(condition, statements) + DOMMixin.__init__(self, branchNode) + + @classmethod + def parse(cls, generateNode: Iir, condition: Iir, label: str) -> "ElsifBranch": + from pyGHDL.dom._Translate import ( + GetSequentialStatementsFromChainedNodes, + GetExpressionFromNode, + ) + + condition = GetExpressionFromNode(condition) + body = nodes.Get_Generate_Statement_Body(generateNode) + + statementChain = nodes.Get_Sequential_Statement_Chain(body) + statements = GetSequentialStatementsFromChainedNodes( + statementChain, "elsif branch", label + ) + + return cls(generateNode, condition, statements) + + +@export +class ElseBranch(VHDLModel_ElseBranch): + def __init__( + self, + branchNode: Iir, + statements: Iterable[SequentialStatement] = None, + ): + super().__init__(statements) + DOMMixin.__init__(self, branchNode) + + @classmethod + def parse(cls, generateNode: Iir, label: str) -> "ElseBranch": + from pyGHDL.dom._Translate import ( + GetSequentialStatementsFromChainedNodes, + ) + + body = nodes.Get_Generate_Statement_Body(generateNode) + + statementChain = nodes.Get_Sequential_Statement_Chain(body) + statements = GetSequentialStatementsFromChainedNodes( + statementChain, "else branch", label + ) + + return cls(generateNode, statements) + + +@export +class IfStatement(VHDLModel_IfStatement, DOMMixin): + def __init__( + self, + generateNode: Iir, + ifBranch: IfBranch, + elsifBranches: Iterable[ElsifBranch] = None, + elseBranch: ElseBranch = None, + label: str = None, + ): + super().__init__(ifBranch, elsifBranches, elseBranch, label) + DOMMixin.__init__(self, generateNode) + + @classmethod + def parse(cls, generateNode: Iir, label: str) -> "IfStatement": + ifBranch = IfBranch.parse(generateNode, label) + elsifBranches = [] + elseBranch = None + # WORKAROUND: Python 3.8 syntax + # elseClause = generateNode + # while (elseClause := nodes.Get_Generate_Else_Clause(elseClause)) != nodes.Null_Iir: + elseClause = nodes.Get_Generate_Else_Clause(generateNode) + while elseClause != nodes.Null_Iir: + condition = nodes.Get_Condition(elseClause) + if condition != nodes.Null_Iir: + elsifBranches.append(ElsifBranch.parse(elseClause, condition, label)) + else: + elseBranch = ElseBranch.parse(elseClause, label) + break + + elseClause = nodes.Get_Generate_Else_Clause(elseClause) + + return cls(generateNode, ifBranch, elsifBranches, elseBranch, label) + + +@export +class IndexedChoice(VHDLModel_IndexedChoice, DOMMixin): + def __init__(self, node: Iir, expression: Expression): + super().__init__(expression) + DOMMixin.__init__(self, node) + + +@export +class RangedChoice(VHDLModel_RangedChoice, DOMMixin): + def __init__(self, node: Iir, rng: Range): + super().__init__(rng) + DOMMixin.__init__(self, node) + + +@export +class Case(VHDLModel_Case, DOMMixin): + def __init__(self, node: Iir, choices: Iterable[SequentialChoice], statements: Iterable[SequentialStatement]): + super().__init__(choices, statements) + DOMMixin.__init__(self, node) + + @classmethod + def parse(cls, caseNode: Iir, label: str) -> "Case": + from pyGHDL.dom._Translate import ( + GetSequentialStatementsFromChainedNodes, + ) + + body = nodes.Get_Generate_Statement_Body(caseNode) + + statementChain = nodes.Get_Sequential_Statement_Chain(body) + statements = GetSequentialStatementsFromChainedNodes( + statementChain, "case", label + ) + + choices = [] + + return cls(caseNode, choices, statements) + + +@export +class OthersCase(VHDLModel_OthersCase, DOMMixin): + def __init__( + self, + caseNode: Iir, + statements: Iterable[SequentialStatement] = None, + ): + super().__init__(statements) + DOMMixin.__init__(self, caseNode) + + @classmethod + def parse(cls, caseNode: Iir) -> "OthersCase": + from pyGHDL.dom._Translate import ( + GetDeclaredItemsFromChainedNodes, + GetSequentialStatementsFromChainedNodes, + ) + + # body = nodes.Get_Generate_Statement_Body(caseNode) + # + # statementChain = nodes.Get_Sequential_Statement_Chain(body) + # statements = GetStatementsFromChainedNodes( + # statementChain, "else branch", alternativeLabel + # ) + + # return cls(caseNode, declaredItems, statements, alternativeLabel) + return cls(caseNode, [], [], "") + + +@export +class CaseStatement(VHDLModel_CaseStatement, DOMMixin): + def __init__( + self, generateNode: Iir, label: str, expression: Expression, cases: Iterable[SequentialCase] + ): + super().__init__(expression, cases, label) + DOMMixin.__init__(self, generateNode) + + @classmethod + def parse(cls, generateNode: Iir, label: str) -> "CaseStatement": + from pyGHDL.dom._Translate import ( + GetExpressionFromNode, + GetIirKindOfNode, + GetRangeFromNode, + ) + + # TODO: get choices + + expression = GetExpressionFromNode(nodes.Get_Expression(generateNode)) + + cases = [] + choices = [] + alternatives = nodes.Get_Case_Statement_Alternative_Chain(generateNode) + for alternative in utils.chain_iter(alternatives): + choiceKind = GetIirKindOfNode(alternative) + + if choiceKind in ( + nodes.Iir_Kind.Choice_By_Name, + nodes.Iir_Kind.Choice_By_Expression, + ): + choiceExpression = GetExpressionFromNode( + nodes.Get_Choice_Expression(alternative) + ) + choices.append(IndexedChoice(alternative, choiceExpression)) + cases.append(Case(alternative, choices)) + choices = [] + elif choiceKind is nodes.Iir_Kind.Choice_By_Range: + rng = GetRangeFromNode(nodes.Get_Choice_Range(alternative)) + choices.append(RangedChoice(alternative, rng)) + cases.append(Case(alternative, choices)) + choices = [] + elif choiceKind is nodes.Iir_Kind.Choice_By_Others: + cases.append(OthersCase.parse(alternative)) + else: + print(choiceKind) + + return cls(generateNode, label, expression, cases) + + +@export +class ForLoopStatement(VHDLModel_ForLoopStatement, DOMMixin): + def __init__( + self, + generateNode: Iir, + loopIndex: str, + range: Range, + statements: Iterable[SequentialStatement] = None, + label: str = None, + ): + super().__init__(loopIndex, range, statements, label) + DOMMixin.__init__(self, generateNode) + + @classmethod + def parse(cls, generateNode: Iir, label: str) -> "ForLoopStatement": + from pyGHDL.dom._Translate import ( + GetSequentialStatementsFromChainedNodes, + GetRangeFromNode, + ) + + spec = nodes.Get_Parameter_Specification(generateNode) + loopIndex = GetNameOfNode(spec) + rng = GetRangeFromNode(nodes.Get_Discrete_Range(spec)) + + body = nodes.Get_Generate_Statement_Body(generateNode) + + statementChain = nodes.Get_Sequential_Statement_Chain(body) + statements = GetSequentialStatementsFromChainedNodes( + statementChain, "for", label + ) + + return cls(generateNode, loopIndex, rng, statements, label) + + +@export +class SequentialSimpleSignalAssignment( + VHDLModel_SequentialSimpleSignalAssignment, DOMMixin +): + def __init__( + self, + assignmentNode: Iir, + target: Name, + waveform: Iterable[WaveformElement], + label: str = None, + ): + super().__init__(target, waveform, label) + DOMMixin.__init__(self, assignmentNode) + + @classmethod + def parse( + cls, assignmentNode: Iir, label: str = None + ) -> "SequentialSimpleSignalAssignment": + from pyGHDL.dom._Translate import GetNameFromNode + + target = nodes.Get_Target(assignmentNode) + targetName = GetNameFromNode(target) + + waveform = nodes.Get_Waveform_Chain(assignmentNode) + + # TODO: translate waveforms to series of "expressions". + expression = [None] + + return cls(assignmentNode, targetName, expression, label) + + +@export +class SequentialProcedureCall(VHDLModel_SequentialProcedureCall, DOMMixin): + def __init__( + self, + callNode: Iir, + label: str, + procedureName: Name, + parameterMappings: Iterable, + ): + super().__init__(label, procedureName, parameterMappings) + DOMMixin.__init__(self, callNode) + + @classmethod + def parse(cls, callNode: Iir, label: str) -> "SequentialProcedureCall": + from pyGHDL.dom._Translate import GetNameFromNode, GetIirKindOfNode + + call = nodes.Get_Procedure_Call(callNode) + prefix = nodes.Get_Prefix(call) + + procedureName = GetNameFromNode(prefix) + + # TODO: parameter mappings + parameterMappings = [] + + return cls(callNode, label, procedureName, parameterMappings) -- cgit v1.2.3 From c4326161ce97d3286e8dffe31d0c168e05f3f9ea Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Fri, 13 Aug 2021 22:21:04 +0200 Subject: Improved handling of ranges (e.g. via attribute names). --- pyGHDL/dom/Sequential.py | 51 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 7 deletions(-) (limited to 'pyGHDL/dom/Sequential.py') diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py index 896b09544..cc5a58d15 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -34,7 +34,7 @@ from typing import Iterable from pydecor import export -from pyGHDL.dom.Concurrent import WaveformElement # TODO: move out from concurrent? +from pyGHDL.dom.Concurrent import WaveformElement # TODO: move out from concurrent? from pyGHDL.dom.Range import Range from pyVHDLModel.SyntaxModel import ( IfBranch as VHDLModel_IfBranch, @@ -52,13 +52,14 @@ from pyVHDLModel.SyntaxModel import ( Name, SequentialStatement, Expression, - SequentialChoice, SequentialCase, + SequentialChoice, + SequentialCase, ) from pyGHDL.libghdl import Iir, utils from pyGHDL.libghdl.vhdl import nodes -from pyGHDL.dom import DOMMixin +from pyGHDL.dom import DOMMixin, Position, DOMException from pyGHDL.dom._Utils import GetNameOfNode @@ -257,10 +258,11 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): @classmethod def parse(cls, generateNode: Iir, label: str) -> "CaseStatement": + from pyGHDL.dom._Utils import GetIirKindOfNode from pyGHDL.dom._Translate import ( GetExpressionFromNode, - GetIirKindOfNode, GetRangeFromNode, + GetNameFromNode, ) # TODO: get choices @@ -284,7 +286,23 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): cases.append(Case(alternative, choices)) choices = [] elif choiceKind is nodes.Iir_Kind.Choice_By_Range: - rng = GetRangeFromNode(nodes.Get_Choice_Range(alternative)) + choiceRange = nodes.Get_Choice_Range(alternative) + choiceRangeKind = GetIirKindOfNode(choiceRange) + if choiceRangeKind == nodes.Iir_Kind.Range_Expression: + rng = GetRangeFromNode(choiceRange) + elif choiceRangeKind in ( + nodes.Iir_Kind.Attribute_Name, + nodes.Iir_Kind.Parenthesis_Name, + ): + rng = GetNameFromNode(choiceRange) + else: + pos = Position.parse(generateNode) + raise DOMException( + "Unknown choice range kind '{kind}' in case statement at line {line}.".format( + kind=choiceRangeKind.name, line=pos.Line + ) + ) + choices.append(RangedChoice(alternative, rng)) cases.append(Case(alternative, choices)) choices = [] @@ -311,14 +329,32 @@ class ForLoopStatement(VHDLModel_ForLoopStatement, DOMMixin): @classmethod def parse(cls, generateNode: Iir, label: str) -> "ForLoopStatement": + from pyGHDL.dom._Utils import GetIirKindOfNode from pyGHDL.dom._Translate import ( GetSequentialStatementsFromChainedNodes, GetRangeFromNode, + GetNameFromNode, ) spec = nodes.Get_Parameter_Specification(generateNode) loopIndex = GetNameOfNode(spec) - rng = GetRangeFromNode(nodes.Get_Discrete_Range(spec)) + + discreteRange = nodes.Get_Discrete_Range(spec) + rangeKind = GetIirKindOfNode(discreteRange) + if rangeKind == nodes.Iir_Kind.Range_Expression: + rng = GetRangeFromNode(discreteRange) + elif rangeKind in ( + nodes.Iir_Kind.Attribute_Name, + nodes.Iir_Kind.Parenthesis_Name, + ): + rng = GetNameFromNode(discreteRange) + else: + pos = Position.parse(generateNode) + raise DOMException( + "Unknown discete range kind '{kind}' in for...loop statement at line {line}.".format( + kind=rangeKind.name, line=pos.Line + ) + ) body = nodes.Get_Generate_Statement_Body(generateNode) @@ -375,7 +411,8 @@ class SequentialProcedureCall(VHDLModel_SequentialProcedureCall, DOMMixin): @classmethod def parse(cls, callNode: Iir, label: str) -> "SequentialProcedureCall": - from pyGHDL.dom._Translate import GetNameFromNode, GetIirKindOfNode + from pyGHDL.dom._Utils import GetIirKindOfNode + from pyGHDL.dom._Translate import GetNameFromNode call = nodes.Get_Procedure_Call(callNode) prefix = nodes.Get_Prefix(call) -- cgit v1.2.3 From edd59b8997c30c8a559d4d7d433631ef03c19546 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Fri, 13 Aug 2021 22:36:41 +0200 Subject: Black formatting. --- pyGHDL/dom/Sequential.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'pyGHDL/dom/Sequential.py') diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py index cc5a58d15..47caf3c3b 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -198,7 +198,12 @@ class RangedChoice(VHDLModel_RangedChoice, DOMMixin): @export class Case(VHDLModel_Case, DOMMixin): - def __init__(self, node: Iir, choices: Iterable[SequentialChoice], statements: Iterable[SequentialStatement]): + def __init__( + self, + node: Iir, + choices: Iterable[SequentialChoice], + statements: Iterable[SequentialStatement], + ): super().__init__(choices, statements) DOMMixin.__init__(self, node) @@ -251,7 +256,11 @@ class OthersCase(VHDLModel_OthersCase, DOMMixin): @export class CaseStatement(VHDLModel_CaseStatement, DOMMixin): def __init__( - self, generateNode: Iir, label: str, expression: Expression, cases: Iterable[SequentialCase] + self, + generateNode: Iir, + label: str, + expression: Expression, + cases: Iterable[SequentialCase], ): super().__init__(expression, cases, label) DOMMixin.__init__(self, generateNode) -- cgit v1.2.3 From 05b01cb126a3a18b2e067ea240a271f6de134311 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Fri, 13 Aug 2021 23:02:55 +0200 Subject: Some naming cleanups. --- pyGHDL/dom/Sequential.py | 60 ++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 30 deletions(-) (limited to 'pyGHDL/dom/Sequential.py') diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py index 47caf3c3b..64a87e878 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -75,21 +75,21 @@ class IfBranch(VHDLModel_IfBranch): DOMMixin.__init__(self, branchNode) @classmethod - def parse(cls, generateNode: Iir, label: str) -> "IfBranch": + def parse(cls, branchNode: Iir, label: str) -> "IfBranch": from pyGHDL.dom._Translate import ( GetSequentialStatementsFromChainedNodes, GetExpressionFromNode, ) - condition = GetExpressionFromNode(nodes.Get_Condition(generateNode)) - body = nodes.Get_Generate_Statement_Body(generateNode) + condition = GetExpressionFromNode(nodes.Get_Condition(branchNode)) + body = nodes.Get_Generate_Statement_Body(branchNode) statementChain = nodes.Get_Sequential_Statement_Chain(body) statements = GetSequentialStatementsFromChainedNodes( statementChain, "if branch", label ) - return cls(generateNode, condition, statements) + return cls(branchNode, condition, statements) @export @@ -104,21 +104,21 @@ class ElsifBranch(VHDLModel_ElsifBranch): DOMMixin.__init__(self, branchNode) @classmethod - def parse(cls, generateNode: Iir, condition: Iir, label: str) -> "ElsifBranch": + def parse(cls, branchNode: Iir, condition: Iir, label: str) -> "ElsifBranch": from pyGHDL.dom._Translate import ( GetSequentialStatementsFromChainedNodes, GetExpressionFromNode, ) condition = GetExpressionFromNode(condition) - body = nodes.Get_Generate_Statement_Body(generateNode) + body = nodes.Get_Generate_Statement_Body(branchNode) statementChain = nodes.Get_Sequential_Statement_Chain(body) statements = GetSequentialStatementsFromChainedNodes( statementChain, "elsif branch", label ) - return cls(generateNode, condition, statements) + return cls(branchNode, condition, statements) @export @@ -132,43 +132,43 @@ class ElseBranch(VHDLModel_ElseBranch): DOMMixin.__init__(self, branchNode) @classmethod - def parse(cls, generateNode: Iir, label: str) -> "ElseBranch": + def parse(cls, elseNode: Iir, label: str) -> "ElseBranch": from pyGHDL.dom._Translate import ( GetSequentialStatementsFromChainedNodes, ) - body = nodes.Get_Generate_Statement_Body(generateNode) + body = nodes.Get_Generate_Statement_Body(elseNode) statementChain = nodes.Get_Sequential_Statement_Chain(body) statements = GetSequentialStatementsFromChainedNodes( statementChain, "else branch", label ) - return cls(generateNode, statements) + return cls(elseNode, statements) @export class IfStatement(VHDLModel_IfStatement, DOMMixin): def __init__( self, - generateNode: Iir, + ifNode: Iir, ifBranch: IfBranch, elsifBranches: Iterable[ElsifBranch] = None, elseBranch: ElseBranch = None, label: str = None, ): super().__init__(ifBranch, elsifBranches, elseBranch, label) - DOMMixin.__init__(self, generateNode) + DOMMixin.__init__(self, ifNode) @classmethod - def parse(cls, generateNode: Iir, label: str) -> "IfStatement": - ifBranch = IfBranch.parse(generateNode, label) + def parse(cls, ifNode: Iir, label: str) -> "IfStatement": + ifBranch = IfBranch.parse(ifNode, label) elsifBranches = [] elseBranch = None # WORKAROUND: Python 3.8 syntax # elseClause = generateNode # while (elseClause := nodes.Get_Generate_Else_Clause(elseClause)) != nodes.Null_Iir: - elseClause = nodes.Get_Generate_Else_Clause(generateNode) + elseClause = nodes.Get_Generate_Else_Clause(ifNode) while elseClause != nodes.Null_Iir: condition = nodes.Get_Condition(elseClause) if condition != nodes.Null_Iir: @@ -179,7 +179,7 @@ class IfStatement(VHDLModel_IfStatement, DOMMixin): elseClause = nodes.Get_Generate_Else_Clause(elseClause) - return cls(generateNode, ifBranch, elsifBranches, elseBranch, label) + return cls(ifNode, ifBranch, elsifBranches, elseBranch, label) @export @@ -257,16 +257,16 @@ class OthersCase(VHDLModel_OthersCase, DOMMixin): class CaseStatement(VHDLModel_CaseStatement, DOMMixin): def __init__( self, - generateNode: Iir, + caseNode: Iir, label: str, expression: Expression, cases: Iterable[SequentialCase], ): super().__init__(expression, cases, label) - DOMMixin.__init__(self, generateNode) + DOMMixin.__init__(self, caseNode) @classmethod - def parse(cls, generateNode: Iir, label: str) -> "CaseStatement": + def parse(cls, caseNode: Iir, label: str) -> "CaseStatement": from pyGHDL.dom._Utils import GetIirKindOfNode from pyGHDL.dom._Translate import ( GetExpressionFromNode, @@ -276,11 +276,11 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): # TODO: get choices - expression = GetExpressionFromNode(nodes.Get_Expression(generateNode)) + expression = GetExpressionFromNode(nodes.Get_Expression(caseNode)) cases = [] choices = [] - alternatives = nodes.Get_Case_Statement_Alternative_Chain(generateNode) + alternatives = nodes.Get_Case_Statement_Alternative_Chain(caseNode) for alternative in utils.chain_iter(alternatives): choiceKind = GetIirKindOfNode(alternative) @@ -305,7 +305,7 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): ): rng = GetNameFromNode(choiceRange) else: - pos = Position.parse(generateNode) + pos = Position.parse(caseNode) raise DOMException( "Unknown choice range kind '{kind}' in case statement at line {line}.".format( kind=choiceRangeKind.name, line=pos.Line @@ -320,24 +320,24 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): else: print(choiceKind) - return cls(generateNode, label, expression, cases) + return cls(caseNode, label, expression, cases) @export class ForLoopStatement(VHDLModel_ForLoopStatement, DOMMixin): def __init__( self, - generateNode: Iir, + loopNode: Iir, loopIndex: str, range: Range, statements: Iterable[SequentialStatement] = None, label: str = None, ): super().__init__(loopIndex, range, statements, label) - DOMMixin.__init__(self, generateNode) + DOMMixin.__init__(self, loopNode) @classmethod - def parse(cls, generateNode: Iir, label: str) -> "ForLoopStatement": + def parse(cls, loopNode: Iir, label: str) -> "ForLoopStatement": from pyGHDL.dom._Utils import GetIirKindOfNode from pyGHDL.dom._Translate import ( GetSequentialStatementsFromChainedNodes, @@ -345,7 +345,7 @@ class ForLoopStatement(VHDLModel_ForLoopStatement, DOMMixin): GetNameFromNode, ) - spec = nodes.Get_Parameter_Specification(generateNode) + spec = nodes.Get_Parameter_Specification(loopNode) loopIndex = GetNameOfNode(spec) discreteRange = nodes.Get_Discrete_Range(spec) @@ -358,21 +358,21 @@ class ForLoopStatement(VHDLModel_ForLoopStatement, DOMMixin): ): rng = GetNameFromNode(discreteRange) else: - pos = Position.parse(generateNode) + pos = Position.parse(loopNode) raise DOMException( "Unknown discete range kind '{kind}' in for...loop statement at line {line}.".format( kind=rangeKind.name, line=pos.Line ) ) - body = nodes.Get_Generate_Statement_Body(generateNode) + body = nodes.Get_Generate_Statement_Body(loopNode) statementChain = nodes.Get_Sequential_Statement_Chain(body) statements = GetSequentialStatementsFromChainedNodes( statementChain, "for", label ) - return cls(generateNode, loopIndex, rng, statements, label) + return cls(loopNode, loopIndex, rng, statements, label) @export -- cgit v1.2.3 From c74c26bbb6b58e0cf7fba78e382f0949240b7721 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Mon, 16 Aug 2021 17:43:29 +0200 Subject: Handle if-statements. --- pyGHDL/dom/Sequential.py | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'pyGHDL/dom/Sequential.py') diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py index 64a87e878..6e04b9a04 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -82,9 +82,7 @@ class IfBranch(VHDLModel_IfBranch): ) condition = GetExpressionFromNode(nodes.Get_Condition(branchNode)) - body = nodes.Get_Generate_Statement_Body(branchNode) - - statementChain = nodes.Get_Sequential_Statement_Chain(body) + statementChain = nodes.Get_Sequential_Statement_Chain(branchNode) statements = GetSequentialStatementsFromChainedNodes( statementChain, "if branch", label ) @@ -111,9 +109,7 @@ class ElsifBranch(VHDLModel_ElsifBranch): ) condition = GetExpressionFromNode(condition) - body = nodes.Get_Generate_Statement_Body(branchNode) - - statementChain = nodes.Get_Sequential_Statement_Chain(body) + statementChain = nodes.Get_Sequential_Statement_Chain(branchNode) statements = GetSequentialStatementsFromChainedNodes( statementChain, "elsif branch", label ) @@ -132,19 +128,16 @@ class ElseBranch(VHDLModel_ElseBranch): DOMMixin.__init__(self, branchNode) @classmethod - def parse(cls, elseNode: Iir, label: str) -> "ElseBranch": + def parse(cls, branchNode: Iir, label: str) -> "ElseBranch": from pyGHDL.dom._Translate import ( GetSequentialStatementsFromChainedNodes, ) - - body = nodes.Get_Generate_Statement_Body(elseNode) - - statementChain = nodes.Get_Sequential_Statement_Chain(body) + statementChain = nodes.Get_Sequential_Statement_Chain(branchNode) statements = GetSequentialStatementsFromChainedNodes( statementChain, "else branch", label ) - return cls(elseNode, statements) + return cls(branchNode, statements) @export @@ -168,7 +161,7 @@ class IfStatement(VHDLModel_IfStatement, DOMMixin): # WORKAROUND: Python 3.8 syntax # elseClause = generateNode # while (elseClause := nodes.Get_Generate_Else_Clause(elseClause)) != nodes.Null_Iir: - elseClause = nodes.Get_Generate_Else_Clause(ifNode) + elseClause = nodes.Get_Else_Clause(ifNode) while elseClause != nodes.Null_Iir: condition = nodes.Get_Condition(elseClause) if condition != nodes.Null_Iir: @@ -177,7 +170,7 @@ class IfStatement(VHDLModel_IfStatement, DOMMixin): elseBranch = ElseBranch.parse(elseClause, label) break - elseClause = nodes.Get_Generate_Else_Clause(elseClause) + elseClause = nodes.Get_Else_Clause(elseClause) return cls(ifNode, ifBranch, elsifBranches, elseBranch, label) -- cgit v1.2.3 From db48ba4042769646676f7ffb981149cbb5e52740 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Mon, 16 Aug 2021 18:06:59 +0200 Subject: Implemented if, case and for-loop statements. --- pyGHDL/dom/Sequential.py | 106 ++++++++++++++++++++++++++++++----------------- 1 file changed, 67 insertions(+), 39 deletions(-) (limited to 'pyGHDL/dom/Sequential.py') diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py index 6e04b9a04..0503eca25 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -132,6 +132,7 @@ class ElseBranch(VHDLModel_ElseBranch): from pyGHDL.dom._Translate import ( GetSequentialStatementsFromChainedNodes, ) + statementChain = nodes.Get_Sequential_Statement_Chain(branchNode) statements = GetSequentialStatementsFromChainedNodes( statementChain, "else branch", label @@ -195,26 +196,26 @@ class Case(VHDLModel_Case, DOMMixin): self, node: Iir, choices: Iterable[SequentialChoice], - statements: Iterable[SequentialStatement], + statements: Iterable[SequentialStatement] = None, ): super().__init__(choices, statements) DOMMixin.__init__(self, node) @classmethod - def parse(cls, caseNode: Iir, label: str) -> "Case": - from pyGHDL.dom._Translate import ( - GetSequentialStatementsFromChainedNodes, - ) + def parse( + cls, caseNode: Iir, choices: Iterable[SequentialChoice], label: str + ) -> "Case": + from pyGHDL.dom._Translate import GetSequentialStatementsFromChainedNodes - body = nodes.Get_Generate_Statement_Body(caseNode) + block = nodes.Get_Associated_Block(caseNode) + if block is nodes.Null_Iir: + return cls(caseNode, choices) - statementChain = nodes.Get_Sequential_Statement_Chain(body) + statementChain = nodes.Get_Sequential_Statement_Chain(block) statements = GetSequentialStatementsFromChainedNodes( statementChain, "case", label ) - choices = [] - return cls(caseNode, choices, statements) @@ -229,21 +230,19 @@ class OthersCase(VHDLModel_OthersCase, DOMMixin): DOMMixin.__init__(self, caseNode) @classmethod - def parse(cls, caseNode: Iir) -> "OthersCase": - from pyGHDL.dom._Translate import ( - GetDeclaredItemsFromChainedNodes, - GetSequentialStatementsFromChainedNodes, - ) + def parse(cls, caseNode: Iir, label: str = None) -> "OthersCase": + from pyGHDL.dom._Translate import GetSequentialStatementsFromChainedNodes - # body = nodes.Get_Generate_Statement_Body(caseNode) - # - # statementChain = nodes.Get_Sequential_Statement_Chain(body) - # statements = GetStatementsFromChainedNodes( - # statementChain, "else branch", alternativeLabel - # ) + body = nodes.Get_Associated_Block(caseNode) + if body is nodes.Null_Iir: + return cls(caseNode) - # return cls(caseNode, declaredItems, statements, alternativeLabel) - return cls(caseNode, [], [], "") + statementChain = nodes.Get_Concurrent_Statement_Chain(body) + statements = GetSequentialStatementsFromChainedNodes( + statementChain, "case others", label + ) + + return cls(caseNode, statements) @export @@ -267,15 +266,17 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): GetNameFromNode, ) - # TODO: get choices - expression = GetExpressionFromNode(nodes.Get_Expression(caseNode)) cases = [] - choices = [] - alternatives = nodes.Get_Case_Statement_Alternative_Chain(caseNode) - for alternative in utils.chain_iter(alternatives): + choices = None + alternative = nodes.Get_Case_Statement_Alternative_Chain(caseNode) + caseNode = alternative + + while alternative != nodes.Null_Iir: choiceKind = GetIirKindOfNode(alternative) + sameAlternative = nodes.Get_Same_Alternative_Flag(alternative) + print("sameAlternative: ", sameAlternative) if choiceKind in ( nodes.Iir_Kind.Choice_By_Name, @@ -284,9 +285,12 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): choiceExpression = GetExpressionFromNode( nodes.Get_Choice_Expression(alternative) ) - choices.append(IndexedChoice(alternative, choiceExpression)) - cases.append(Case(alternative, choices)) - choices = [] + + choice = IndexedChoice(alternative, choiceExpression) + if sameAlternative: + choices.append(choice) + alternative = nodes.Get_Chain(alternative) + continue elif choiceKind is nodes.Iir_Kind.Choice_By_Range: choiceRange = nodes.Get_Choice_Range(alternative) choiceRangeKind = GetIirKindOfNode(choiceRange) @@ -298,20 +302,46 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): ): rng = GetNameFromNode(choiceRange) else: - pos = Position.parse(caseNode) + pos = Position.parse(alternative) raise DOMException( "Unknown choice range kind '{kind}' in case statement at line {line}.".format( kind=choiceRangeKind.name, line=pos.Line ) ) - choices.append(RangedChoice(alternative, rng)) - cases.append(Case(alternative, choices)) - choices = [] + choice = RangedChoice(alternative, rng) + if sameAlternative: + choices.append(choice) + alternative = nodes.Get_Chain(alternative) + continue elif choiceKind is nodes.Iir_Kind.Choice_By_Others: - cases.append(OthersCase.parse(alternative)) + if choices is not None: + cases.append(Case.parse(alternative, choices, label)) + choices = None + cases.append(OthersCase.parse(alternative, label)) + alternative = nodes.Get_Chain(alternative) + caseNode = alternative + continue else: - print(choiceKind) + pos = Position.parse(alternative) + raise DOMException( + "Unknown choice kind '{kind}' in case statement at line {line}.".format( + kind=choiceKind.name, line=pos.Line + ) + ) + + if choices is not None: + cases.append(Case.parse(alternative, choices, label)) + + caseNode = alternative + choices = [ + choice, + ] + + alternative = nodes.Get_Chain(alternative) + + if choices is not None: + cases.append(Case.parse(alternative, choices, label)) return cls(caseNode, label, expression, cases) @@ -358,9 +388,7 @@ class ForLoopStatement(VHDLModel_ForLoopStatement, DOMMixin): ) ) - body = nodes.Get_Generate_Statement_Body(loopNode) - - statementChain = nodes.Get_Sequential_Statement_Chain(body) + statementChain = nodes.Get_Sequential_Statement_Chain(loopNode) statements = GetSequentialStatementsFromChainedNodes( statementChain, "for", label ) -- cgit v1.2.3 From 3f0308a5f807269aa5691fa1c704c0e9147d45f1 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Mon, 16 Aug 2021 23:47:04 +0200 Subject: Handle contexts. --- pyGHDL/dom/Sequential.py | 1 - 1 file changed, 1 deletion(-) (limited to 'pyGHDL/dom/Sequential.py') diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py index 0503eca25..7fe94fad5 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -276,7 +276,6 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): while alternative != nodes.Null_Iir: choiceKind = GetIirKindOfNode(alternative) sameAlternative = nodes.Get_Same_Alternative_Flag(alternative) - print("sameAlternative: ", sameAlternative) if choiceKind in ( nodes.Iir_Kind.Choice_By_Name, -- cgit v1.2.3 From c34b020a8c1b6aa5083a637e3e9062c7a71b309a Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Tue, 17 Aug 2021 10:16:59 +0200 Subject: Some updates. --- pyGHDL/dom/Sequential.py | 68 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 59 insertions(+), 9 deletions(-) (limited to 'pyGHDL/dom/Sequential.py') diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py index 7fe94fad5..cb6fa5a8f 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -49,6 +49,8 @@ from pyVHDLModel.SyntaxModel import ( ForLoopStatement as VHDLModel_ForLoopStatement, SequentialSimpleSignalAssignment as VHDLModel_SequentialSimpleSignalAssignment, SequentialProcedureCall as VHDLModel_SequentialProcedureCall, + SequentialAssertStatement as VHDLModel_SequentialAssertStatement, + SequentialReportStatement as VHDLModel_SequentialReportStatement, Name, SequentialStatement, Expression, @@ -211,7 +213,7 @@ class Case(VHDLModel_Case, DOMMixin): if block is nodes.Null_Iir: return cls(caseNode, choices) - statementChain = nodes.Get_Sequential_Statement_Chain(block) + statementChain = nodes.Get_Sequential_Statement_Chain(caseNode) statements = GetSequentialStatementsFromChainedNodes( statementChain, "case", label ) @@ -271,7 +273,7 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): cases = [] choices = None alternative = nodes.Get_Case_Statement_Alternative_Chain(caseNode) - caseNode = alternative + cNode = alternative while alternative != nodes.Null_Iir: choiceKind = GetIirKindOfNode(alternative) @@ -319,7 +321,7 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): choices = None cases.append(OthersCase.parse(alternative, label)) alternative = nodes.Get_Chain(alternative) - caseNode = alternative + cNode = alternative continue else: pos = Position.parse(alternative) @@ -330,9 +332,9 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): ) if choices is not None: - cases.append(Case.parse(alternative, choices, label)) + cases.append(Case.parse(cNode, choices, label)) - caseNode = alternative + cNode = alternative choices = [ choice, ] @@ -340,7 +342,7 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): alternative = nodes.Get_Chain(alternative) if choices is not None: - cases.append(Case.parse(alternative, choices, label)) + cases.append(Case.parse(cNode, choices, label)) return cls(caseNode, label, expression, cases) @@ -431,11 +433,11 @@ class SequentialProcedureCall(VHDLModel_SequentialProcedureCall, DOMMixin): def __init__( self, callNode: Iir, - label: str, procedureName: Name, parameterMappings: Iterable, + label: str = None, ): - super().__init__(label, procedureName, parameterMappings) + super().__init__(procedureName, parameterMappings, label) DOMMixin.__init__(self, callNode) @classmethod @@ -451,4 +453,52 @@ class SequentialProcedureCall(VHDLModel_SequentialProcedureCall, DOMMixin): # TODO: parameter mappings parameterMappings = [] - return cls(callNode, label, procedureName, parameterMappings) + return cls(callNode, procedureName, parameterMappings, label) + + +@export +class SequentialAssertStatement(VHDLModel_SequentialAssertStatement, DOMMixin): + def __init__( + self, + assertNode: Iir, + condition: Expression, + message: Expression, + severity: Expression = None, + label: str = None, + ): + super().__init__(label, condition, message, severity, label) + DOMMixin.__init__(self, assertNode) + + @classmethod + def parse(cls, assertNode: Iir, label: str) -> "SequentialAssertStatement": + from pyGHDL.dom._Utils import GetIirKindOfNode + from pyGHDL.dom._Translate import GetExpressionFromNode + + condition = "" + message = "" + severity = "" + + return cls(assertNode, condition, message, severity, label) + + +@export +class SequentialReportStatement(VHDLModel_SequentialReportStatement, DOMMixin): + def __init__( + self, + reportNode: Iir, + message: Expression, + severity: Expression = None, + label: str = None, + ): + super().__init__(label, message, severity, label) + DOMMixin.__init__(self, reportNode) + + @classmethod + def parse(cls, reportNode: Iir, label: str) -> "SequentialReportStatement": + from pyGHDL.dom._Utils import GetIirKindOfNode + from pyGHDL.dom._Translate import GetExpressionFromNode + + message = "" + severity = "" + + return cls(reportNode, message, severity, label) -- cgit v1.2.3 From 2488e55caba1c369785a93ab2578c4a1e0c40c65 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Tue, 17 Aug 2021 10:44:34 +0200 Subject: Read condition, message and severity from asserts and reports. --- pyGHDL/dom/Sequential.py | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'pyGHDL/dom/Sequential.py') diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py index cb6fa5a8f..b0f1d2e97 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -466,19 +466,19 @@ class SequentialAssertStatement(VHDLModel_SequentialAssertStatement, DOMMixin): severity: Expression = None, label: str = None, ): - super().__init__(label, condition, message, severity, label) + super().__init__(condition, message, severity, label) DOMMixin.__init__(self, assertNode) - @classmethod - def parse(cls, assertNode: Iir, label: str) -> "SequentialAssertStatement": - from pyGHDL.dom._Utils import GetIirKindOfNode - from pyGHDL.dom._Translate import GetExpressionFromNode + @classmethod + def parse(cls, assertNode: Iir, label: str) -> "SequentialAssertStatement": + from pyGHDL.dom._Translate import GetExpressionFromNode - condition = "" - message = "" - severity = "" + condition = GetExpressionFromNode(nodes.Get_Assertion_Condition(assertNode)) + message = GetExpressionFromNode(nodes.Get_Report_Expression(assertNode)) + severityNode = nodes.Get_Severity_Expression(assertNode) + severity = None if severityNode is nodes.Null_Iir else GetExpressionFromNode(severityNode) - return cls(assertNode, condition, message, severity, label) + return cls(assertNode, condition, message, severity, label) @export @@ -490,15 +490,15 @@ class SequentialReportStatement(VHDLModel_SequentialReportStatement, DOMMixin): severity: Expression = None, label: str = None, ): - super().__init__(label, message, severity, label) + super().__init__(message, severity, label) DOMMixin.__init__(self, reportNode) - @classmethod - def parse(cls, reportNode: Iir, label: str) -> "SequentialReportStatement": - from pyGHDL.dom._Utils import GetIirKindOfNode - from pyGHDL.dom._Translate import GetExpressionFromNode + @classmethod + def parse(cls, reportNode: Iir, label: str) -> "SequentialReportStatement": + from pyGHDL.dom._Translate import GetExpressionFromNode - message = "" - severity = "" + message = GetExpressionFromNode(nodes.Get_Report_Expression(reportNode)) + severityNode = nodes.Get_Severity_Expression(reportNode) + severity = None if severityNode is nodes.Null_Iir else GetExpressionFromNode(severityNode) - return cls(reportNode, message, severity, label) + return cls(reportNode, message, severity, label) -- cgit v1.2.3 From d0dc820554320ad076854481f5cb0957edd3cda5 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Tue, 17 Aug 2021 12:17:51 +0200 Subject: Implemented handling of wait statements. --- pyGHDL/dom/Sequential.py | 53 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) (limited to 'pyGHDL/dom/Sequential.py') diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py index b0f1d2e97..d2efef8eb 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -51,6 +51,7 @@ from pyVHDLModel.SyntaxModel import ( SequentialProcedureCall as VHDLModel_SequentialProcedureCall, SequentialAssertStatement as VHDLModel_SequentialAssertStatement, SequentialReportStatement as VHDLModel_SequentialReportStatement, + WaitStatement as VHDLModel_WaitStatement, Name, SequentialStatement, Expression, @@ -476,7 +477,11 @@ class SequentialAssertStatement(VHDLModel_SequentialAssertStatement, DOMMixin): condition = GetExpressionFromNode(nodes.Get_Assertion_Condition(assertNode)) message = GetExpressionFromNode(nodes.Get_Report_Expression(assertNode)) severityNode = nodes.Get_Severity_Expression(assertNode) - severity = None if severityNode is nodes.Null_Iir else GetExpressionFromNode(severityNode) + severity = ( + None + if severityNode is nodes.Null_Iir + else GetExpressionFromNode(severityNode) + ) return cls(assertNode, condition, message, severity, label) @@ -499,6 +504,50 @@ class SequentialReportStatement(VHDLModel_SequentialReportStatement, DOMMixin): message = GetExpressionFromNode(nodes.Get_Report_Expression(reportNode)) severityNode = nodes.Get_Severity_Expression(reportNode) - severity = None if severityNode is nodes.Null_Iir else GetExpressionFromNode(severityNode) + severity = ( + None + if severityNode is nodes.Null_Iir + else GetExpressionFromNode(severityNode) + ) return cls(reportNode, message, severity, label) + + +@export +class WaitStatement(VHDLModel_WaitStatement, DOMMixin): + def __init__( + self, + waitNode: Iir, + sensitivityList: Iterable[Name] = None, + condition: Expression = None, + timeout: Expression = None, + label: str = None, + ): + super().__init__(sensitivityList, condition, timeout, label) + DOMMixin.__init__(self, waitNode) + + @classmethod + def parse(cls, waitNode: Iir, label: str) -> "WaitStatement": + from pyGHDL.dom._Utils import GetIirKindOfNode + from pyGHDL.dom._Translate import GetExpressionFromNode + + sensitivityList = None + sensitivityListNode = nodes.Get_Sensitivity_List(waitNode) + if sensitivityListNode is not nodes.Null_Iir: + print(GetIirKindOfNode(sensitivityListNode)) + + conditionNode = nodes.Get_Condition_Clause(waitNode) + condition = ( + None + if conditionNode is nodes.Null_Iir + else GetExpressionFromNode(conditionNode) + ) + + timeoutNode = nodes.Get_Timeout_Clause(waitNode) + timeout = ( + None + if timeoutNode is nodes.Null_Iir + else GetExpressionFromNode(timeoutNode) + ) + + return cls(waitNode, sensitivityList, condition, timeout, label) -- cgit v1.2.3 From f8d7ac62564e4bdefb35e58178c4df1b4feae844 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Tue, 17 Aug 2021 13:30:49 +0200 Subject: Handle simple sequential signal assignments and it's waveforms. --- pyGHDL/dom/Sequential.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'pyGHDL/dom/Sequential.py') diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py index d2efef8eb..28b6f2b98 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -421,12 +421,11 @@ class SequentialSimpleSignalAssignment( target = nodes.Get_Target(assignmentNode) targetName = GetNameFromNode(target) - waveform = nodes.Get_Waveform_Chain(assignmentNode) + waveform = [] + for wave in utils.chain_iter(nodes.Get_Waveform_Chain(assignmentNode)): + waveform.append(WaveformElement.parse(wave)) - # TODO: translate waveforms to series of "expressions". - expression = [None] - - return cls(assignmentNode, targetName, expression, label) + return cls(assignmentNode, targetName, waveform, label) @export -- cgit v1.2.3 From 94a3027f9108f0d81a84f7d52a3e4afe93c1eb66 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Tue, 17 Aug 2021 20:19:59 +0200 Subject: Also handle parameters for sequential procedure calls. --- pyGHDL/dom/Sequential.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'pyGHDL/dom/Sequential.py') diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py index 28b6f2b98..f752b432d 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -442,18 +442,17 @@ class SequentialProcedureCall(VHDLModel_SequentialProcedureCall, DOMMixin): @classmethod def parse(cls, callNode: Iir, label: str) -> "SequentialProcedureCall": - from pyGHDL.dom._Utils import GetIirKindOfNode - from pyGHDL.dom._Translate import GetNameFromNode + from pyGHDL.dom._Translate import GetNameFromNode, GetParameterMapAspect call = nodes.Get_Procedure_Call(callNode) - prefix = nodes.Get_Prefix(call) + prefix = nodes.Get_Prefix(call) procedureName = GetNameFromNode(prefix) + parameterAssociations = GetParameterMapAspect( + nodes.Get_Parameter_Association_Chain(callNode) + ) - # TODO: parameter mappings - parameterMappings = [] - - return cls(callNode, procedureName, parameterMappings, label) + return cls(callNode, procedureName, parameterAssociations, label) @export -- cgit v1.2.3 From 32cb30ea5f674acd7ad7d5923fbd462be38d2046 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Wed, 18 Aug 2021 00:47:31 +0200 Subject: Assertion messages are optional in assert statements. --- pyGHDL/dom/Sequential.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'pyGHDL/dom/Sequential.py') diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py index f752b432d..a4eae8767 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -461,7 +461,7 @@ class SequentialAssertStatement(VHDLModel_SequentialAssertStatement, DOMMixin): self, assertNode: Iir, condition: Expression, - message: Expression, + message: Expression = None, severity: Expression = None, label: str = None, ): @@ -473,7 +473,12 @@ class SequentialAssertStatement(VHDLModel_SequentialAssertStatement, DOMMixin): from pyGHDL.dom._Translate import GetExpressionFromNode condition = GetExpressionFromNode(nodes.Get_Assertion_Condition(assertNode)) - message = GetExpressionFromNode(nodes.Get_Report_Expression(assertNode)) + messageNode = nodes.Get_Report_Expression(assertNode) + message = ( + None + if messageNode is nodes.Null_Iir + else GetExpressionFromNode(messageNode) + ) severityNode = nodes.Get_Severity_Expression(assertNode) severity = ( None -- cgit v1.2.3 From 07d8c06b4562e2e0d7390b98732ce1b6d30320d4 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Sun, 22 Aug 2021 23:32:21 +0200 Subject: Fixed case statement. --- pyGHDL/dom/Sequential.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'pyGHDL/dom/Sequential.py') diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py index a4eae8767..fe7c83614 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -210,11 +210,7 @@ class Case(VHDLModel_Case, DOMMixin): ) -> "Case": from pyGHDL.dom._Translate import GetSequentialStatementsFromChainedNodes - block = nodes.Get_Associated_Block(caseNode) - if block is nodes.Null_Iir: - return cls(caseNode, choices) - - statementChain = nodes.Get_Sequential_Statement_Chain(caseNode) + statementChain = nodes.Get_Associated_Chain(caseNode) statements = GetSequentialStatementsFromChainedNodes( statementChain, "case", label ) -- cgit v1.2.3 From 8fb4da723067b2ff99050f9ef9fc0bbd3c835ef4 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Mon, 23 Aug 2021 00:13:43 +0200 Subject: Some fixes. --- pyGHDL/dom/Sequential.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'pyGHDL/dom/Sequential.py') diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py index fe7c83614..4f511c16f 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -34,7 +34,10 @@ from typing import Iterable from pydecor import export -from pyGHDL.dom.Concurrent import WaveformElement # TODO: move out from concurrent? +from pyGHDL.dom.Concurrent import ( + WaveformElement, + ParameterAssociationItem, +) # TODO: move out from concurrent? from pyGHDL.dom.Range import Range from pyVHDLModel.SyntaxModel import ( IfBranch as VHDLModel_IfBranch, @@ -350,11 +353,11 @@ class ForLoopStatement(VHDLModel_ForLoopStatement, DOMMixin): self, loopNode: Iir, loopIndex: str, - range: Range, + rng: Range, statements: Iterable[SequentialStatement] = None, label: str = None, ): - super().__init__(loopIndex, range, statements, label) + super().__init__(loopIndex, rng, statements, label) DOMMixin.__init__(self, loopNode) @classmethod @@ -430,7 +433,7 @@ class SequentialProcedureCall(VHDLModel_SequentialProcedureCall, DOMMixin): self, callNode: Iir, procedureName: Name, - parameterMappings: Iterable, + parameterMappings: Iterable[ParameterAssociationItem], label: str = None, ): super().__init__(procedureName, parameterMappings, label) -- cgit v1.2.3 From 8b98e2883b40b00922c9944c2470211ee055a9a5 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Mon, 23 Aug 2021 09:02:47 +0200 Subject: Fixes due to a bug in pyVHDLModel. Name Context was used twice. --- pyGHDL/dom/Sequential.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'pyGHDL/dom/Sequential.py') diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py index 4f511c16f..be4793b2a 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -57,7 +57,7 @@ from pyVHDLModel.SyntaxModel import ( WaitStatement as VHDLModel_WaitStatement, Name, SequentialStatement, - Expression, + ExpressionUnion, SequentialChoice, SequentialCase, ) @@ -74,7 +74,7 @@ class IfBranch(VHDLModel_IfBranch): def __init__( self, branchNode: Iir, - condition: Expression, + condition: ExpressionUnion, statements: Iterable[SequentialStatement] = None, ): super().__init__(condition, statements) @@ -101,7 +101,7 @@ class ElsifBranch(VHDLModel_ElsifBranch): def __init__( self, branchNode: Iir, - condition: Expression, + condition: ExpressionUnion, statements: Iterable[SequentialStatement] = None, ): super().__init__(condition, statements) @@ -184,7 +184,7 @@ class IfStatement(VHDLModel_IfStatement, DOMMixin): @export class IndexedChoice(VHDLModel_IndexedChoice, DOMMixin): - def __init__(self, node: Iir, expression: Expression): + def __init__(self, node: Iir, expression: ExpressionUnion): super().__init__(expression) DOMMixin.__init__(self, node) @@ -253,7 +253,7 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): self, caseNode: Iir, label: str, - expression: Expression, + expression: ExpressionUnion, cases: Iterable[SequentialCase], ): super().__init__(expression, cases, label) @@ -459,9 +459,9 @@ class SequentialAssertStatement(VHDLModel_SequentialAssertStatement, DOMMixin): def __init__( self, assertNode: Iir, - condition: Expression, - message: Expression = None, - severity: Expression = None, + condition: ExpressionUnion, + message: ExpressionUnion = None, + severity: ExpressionUnion = None, label: str = None, ): super().__init__(condition, message, severity, label) @@ -493,8 +493,8 @@ class SequentialReportStatement(VHDLModel_SequentialReportStatement, DOMMixin): def __init__( self, reportNode: Iir, - message: Expression, - severity: Expression = None, + message: ExpressionUnion, + severity: ExpressionUnion = None, label: str = None, ): super().__init__(message, severity, label) @@ -521,8 +521,8 @@ class WaitStatement(VHDLModel_WaitStatement, DOMMixin): self, waitNode: Iir, sensitivityList: Iterable[Name] = None, - condition: Expression = None, - timeout: Expression = None, + condition: ExpressionUnion = None, + timeout: ExpressionUnion = None, label: str = None, ): super().__init__(sensitivityList, condition, timeout, label) -- cgit v1.2.3