Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
2691122
Bumped version to v0.5.0. [skip ci]
Paebbels Jul 27, 2025
dcd2dc7
place_design: Support older section names for older Vivado versions.
Paebbels Jul 28, 2025
da841bf
route_design: Support older section names for older Vivado versions.
Paebbels Jul 28, 2025
e7d2848
Implemented Vivado version switching using new VersionRange class fro…
Paebbels Aug 14, 2025
eb87504
Added Vivado 2024.2 synthesis and implementation logfiles provided by…
Paebbels Aug 14, 2025
0a1fe53
Add example reports for different Vivado versions.
tiago-gomes-enclustra Sep 2, 2025
1ab01cd
Add example reports for Vivado 2025.1.
tiago-gomes-enclustra Sep 3, 2025
a5366a0
Added synthesis and implementation logs for Mercury ZX5 board.
Paebbels Sep 3, 2025
ba1f53e
Integrated new Enclustra Mercury XZ5 reports into unit testing.
Paebbels Sep 4, 2025
bef1409
Added support for more version differences for TCl command `optimize_…
Paebbels Sep 6, 2025
eda6d08
Fixed handling of 'RTL Hierarchical Component Statistics' for TCL com…
Paebbels Sep 6, 2025
9663976
Bumped dependencies.
Paebbels Oct 28, 2025
fbcc008
Added PowerOptPatchEnablesTask.
Paebbels Oct 28, 2025
c412fa6
Added TaskWithSubTasks and SubTask.
Paebbels Oct 28, 2025
03546ca
Also run with Python 3.14.
Paebbels Oct 28, 2025
dd1fe71
Adjusted wheel package classifiers to match supported Python versions.
Paebbels Oct 29, 2025
6d6787c
New RegExp based approach.
Paebbels Nov 3, 2025
587a163
Improved START_PREFIX
Paebbels Nov 5, 2025
db8aee7
Improved FINISH strings matches.
Paebbels Nov 6, 2025
ed25a08
Improved end of section handling.
Paebbels Nov 8, 2025
37ce698
Improved checks for parsed Vivado log files.
Paebbels Nov 8, 2025
7ff2389
Added warning collector to tests.
Paebbels Nov 9, 2025
b4a2b78
Removed VersionRange handling due to new RexExp-based parsing.
Paebbels Nov 9, 2025
65bd112
Added last missing sections and phases.
Paebbels Nov 10, 2025
4d645a1
Renamed Phase classes to SubPhase, SubSubPhase, ....
Paebbels Nov 10, 2025
e4078ba
Updated pyproject configuration for new pytest v9.0.
Paebbels Nov 10, 2025
c2ffb13
Reduced code duplications.
Paebbels Nov 10, 2025
aa6b7fb
Counted some INFO and WARNING messages in log files.
Paebbels Nov 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions .github/workflows/Pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,18 @@ on:

jobs:
Pipeline:
uses: pyTooling/Actions/.github/workflows/CompletePipeline.yml@dev
uses: pyTooling/Actions/.github/workflows/CompletePipeline.yml@r6
with:
package_namespace: pyEDAA
package_name: OutputFilter
unittest_python_version_list: '3.11 3.12 3.13'
codecov: true
codacy: true
dorny: true
cleanup: false
package_namespace: 'pyEDAA'
package_name: 'OutputFilter'
unittest_python_version_list: '3.11 3.12 3.13 3.14 pypy-3.11'
unittest_disable_list: 'macos:* windows-arm:pypy-3.11'
bandit: 'true'
pylint: 'false'
codecov: 'true'
codacy: 'true'
dorny: 'true'
cleanup: 'false'
secrets:
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
Expand Down
2 changes: 1 addition & 1 deletion dist/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
wheel ~= 0.45
twine ~= 6.1
twine ~= 6.2
22 changes: 11 additions & 11 deletions doc/Dependency.rst

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion doc/make.bat
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pushd %~dp0
REM Command file for Sphinx documentation

if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=py -3.13 -m sphinx.cmd.build
set SPHINXBUILD=py -3.14 -m sphinx.cmd.build
)
set SOURCEDIR=.
set BUILDDIR=_build
Expand Down
6 changes: 3 additions & 3 deletions doc/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ sphinx_rtd_theme ~= 3.0
sphinxcontrib-mermaid ~= 1.0
sphinxcontrib-autoprogram ~= 0.1
autoapi >= 2.0.1
sphinx_design ~= 0.6.1
sphinx-copybutton >= 0.5.2
sphinx_autodoc_typehints ~= 3.2
sphinx_design ~= 0.6
sphinx-copybutton >= 0.5
sphinx_autodoc_typehints ~= 3.5
sphinx_reports ~= 0.9
17 changes: 11 additions & 6 deletions pyEDAA/OutputFilter/CLI/Vivado.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
from pyTooling.Attributes.ArgParse.Flag import LongFlag
from pyTooling.Attributes.ArgParse.ValuedFlag import LongValuedFlag
from pyTooling.Stopwatch import Stopwatch
from pyTooling.Warning import WarningCollector

from pyEDAA.OutputFilter.Xilinx import Document, ProcessorException, SynthesizeDesign, Processor
from pyEDAA.OutputFilter.Xilinx.Common import LineKind, Line
Expand Down Expand Up @@ -97,19 +98,23 @@ def HandleVivado(self, args: Namespace) -> None:
writeOutput = self._WriteOutput

with Stopwatch() as sw:
next(generator := processor.LineClassification())
for rawLine in inputFile.readlines():
line = generator.send(rawLine.rstrip("\r\n"))
with WarningCollector() as warnings:
next(generator := processor.LineClassification())
for rawLine in inputFile.readlines():
line = generator.send(rawLine.rstrip("\r\n"))

writeOutput(line)
writeOutput(line)

for warning in warnings:
print(warning)

def _WriteOutput(self, line: Line):
self.WriteNormal(f"{line}")
self.WriteNormal(f"{line.LineNumber:4}: {line}")

def _WriteColoredOutput(self, line: Line):
color = self.GetColorOfLine(line)
message = str(line).replace("{", "{{").replace("}", "}}")
self.WriteNormal(f"{{{color}}}{message}{{NOCOLOR}}".format(**self.Foreground))
self.WriteNormal(f"{line.LineNumber:4}: {{{color}}}{message}{{NOCOLOR}}".format(**self.Foreground))


# if args.info:
Expand Down
68 changes: 49 additions & 19 deletions pyEDAA/OutputFilter/Xilinx/Commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,27 @@
"""Basic classes for outputs from AMD/Xilinx Vivado."""
from pathlib import Path
from re import compile as re_compile
from typing import ClassVar, Generator, Union, List, Type, Dict, Iterator, Any, Tuple
from typing import ClassVar, Generator, Union, List, Type, Dict, Iterator, Any, Tuple

from pyTooling.Decorators import export, readonly

from pyEDAA.OutputFilter.Xilinx import VivadoTclCommand
from pyEDAA.OutputFilter.Xilinx.Exception import ProcessorException
from pyEDAA.OutputFilter.Xilinx.Common import Line, LineKind, VivadoMessage, VHDLReportMessage
from pyEDAA.OutputFilter.Xilinx.Common2 import Parser
from pyTooling.Versioning import YearReleaseVersion
from pyTooling.Warning import WarningCollector

from pyEDAA.OutputFilter import OutputFilterException
from pyEDAA.OutputFilter.Xilinx import VivadoTclCommand
from pyEDAA.OutputFilter.Xilinx.Exception import ProcessorException
from pyEDAA.OutputFilter.Xilinx.Common import Line, LineKind, VivadoMessage, VHDLReportMessage
from pyEDAA.OutputFilter.Xilinx.Common2 import Parser, UnknownSection, UnknownTask
from pyEDAA.OutputFilter.Xilinx.SynthesizeDesign import Section, RTLElaboration, HandlingCustomAttributes
from pyEDAA.OutputFilter.Xilinx.SynthesizeDesign import ConstraintValidation, LoadingPart, ApplySetProperty
from pyEDAA.OutputFilter.Xilinx.SynthesizeDesign import RTLComponentStatistics, PartResourceSummary
from pyEDAA.OutputFilter.Xilinx.SynthesizeDesign import CrossBoundaryAndAreaOptimization, ROM_RAM_DSP_SR_Retiming
from pyEDAA.OutputFilter.Xilinx.SynthesizeDesign import ApplyingXDCTimingConstraints, TimingOptimization
from pyEDAA.OutputFilter.Xilinx.SynthesizeDesign import TechnologyMapping, IOInsertion, FlatteningBeforeIOInsertion
from pyEDAA.OutputFilter.Xilinx.SynthesizeDesign import FinalNetlistCleanup, RenamingGeneratedInstances
from pyEDAA.OutputFilter.Xilinx.SynthesizeDesign import RebuildingUserHierarchy, RenamingGeneratedPorts
from pyEDAA.OutputFilter.Xilinx.SynthesizeDesign import RenamingGeneratedNets, WritingSynthesisReport
from pyEDAA.OutputFilter.Xilinx.SynthesizeDesign import RTLComponentStatistics, RTLHierarchicalComponentStatistics
from pyEDAA.OutputFilter.Xilinx.SynthesizeDesign import PartResourceSummary, CrossBoundaryAndAreaOptimization
from pyEDAA.OutputFilter.Xilinx.SynthesizeDesign import ROM_RAM_DSP_SR_Retiming, ApplyingXDCTimingConstraints
from pyEDAA.OutputFilter.Xilinx.SynthesizeDesign import TimingOptimization, TechnologyMapping, IOInsertion
from pyEDAA.OutputFilter.Xilinx.SynthesizeDesign import FlatteningBeforeIOInsertion, FinalNetlistCleanup
from pyEDAA.OutputFilter.Xilinx.SynthesizeDesign import RenamingGeneratedInstances, RebuildingUserHierarchy
from pyEDAA.OutputFilter.Xilinx.SynthesizeDesign import RenamingGeneratedPorts, RenamingGeneratedNets
from pyEDAA.OutputFilter.Xilinx.SynthesizeDesign import WritingSynthesisReport
from pyEDAA.OutputFilter.Xilinx.OptimizeDesign import Task, DRCTask, CacheTimingInformationTask, LogicOptimizationTask
from pyEDAA.OutputFilter.Xilinx.OptimizeDesign import PowerOptimizationTask, FinalCleanupTask, NetlistObfuscationTask
from pyEDAA.OutputFilter.Xilinx.PlaceDesign import PlacerTask
Expand Down Expand Up @@ -135,11 +139,16 @@ def SectionDetector(self, line: Line) -> Generator[Union[Line, ProcessorExceptio

line = yield line

def __str__(self) -> str:
return f"{self._TCL_COMMAND}"


@export
class CommandWithSections(Command):
_sections: Dict[Type[Section], Section]

_PARSERS: ClassVar[Tuple[Type[Section], ...]] = dict()

def __init__(self, processor: "Processor") -> None:
super().__init__(processor)

Expand Down Expand Up @@ -173,13 +182,14 @@ def __getitem__(self, key: Type[Task]) -> Task:
@export
class SynthesizeDesign(CommandWithSections):
_TCL_COMMAND: ClassVar[str] = "synth_design"
_PARSERS: ClassVar[List[Type[Section]]] = (
_PARSERS: ClassVar[Tuple[Type[Section], ...]] = (
RTLElaboration,
HandlingCustomAttributes1,
ConstraintValidation,
LoadingPart,
ApplySetProperty,
RTLComponentStatistics,
RTLHierarchicalComponentStatistics,
PartResourceSummary,
CrossBoundaryAndAreaOptimization,
ROM_RAM_DSP_SR_Retiming1,
Expand Down Expand Up @@ -275,7 +285,11 @@ def SectionDetector(self, line: Line) -> Generator[Union[Line, ProcessorExceptio
line._previousLine._kind = LineKind.SectionStart | LineKind.SectionDelimiter
break
else:
raise Exception(f"Unknown section: {line!r}")
WarningCollector.Raise(UnknownSection(f"Unknown section: '{line!r}'", line))
ex = Exception(f"How to recover from here? Unknown section: '{line!r}'")
ex.add_note(f"Current task: start pattern='{self._task}'")
ex.add_note(f"Current cmd: {self._task._command}")
raise ex
break
elif line.StartsWith("Starting "):
if line.StartsWith(rtlElaboration._START):
Expand Down Expand Up @@ -451,7 +465,11 @@ def SectionDetector(self, line: Line) -> Generator[Union[Line, ProcessorExceptio
line = yield next(task := parser.Generator(line))
break
else:
raise Exception(f"Unknown task: {line!r}")
WarningCollector.Raise(UnknownTask(f"Unknown task: '{line!r}'", line))
ex = Exception(f"How to recover from here? Unknown task: '{line!r}'")
ex.add_note(f"Current task: start pattern='{self._task}'")
ex.add_note(f"Current cmd: {self._task._command}")
raise ex
break
elif line.StartsWith(self._TCL_COMMAND):
if line[len(self._TCL_COMMAND) + 1:].startswith("completed successfully"):
Expand Down Expand Up @@ -517,7 +535,11 @@ def SectionDetector(self, line: Line) -> Generator[Union[Line, ProcessorExceptio
line = yield next(task := parser.Generator(line))
break
else:
raise Exception(f"Unknown task: {line!r}")
WarningCollector.Raise(UnknownTask(f"Unknown task: '{line!r}'", line))
ex = Exception(f"How to recover from here? Unknown task: '{line!r}'")
ex.add_note(f"Current task: start pattern='{self._task}'")
ex.add_note(f"Current cmd: {self._task._command}")
raise ex
break
elif line.StartsWith(self._TCL_COMMAND):
if line[len(self._TCL_COMMAND) + 1:].startswith("completed successfully"):
Expand Down Expand Up @@ -584,7 +606,11 @@ def SectionDetector(self, line: Line) -> Generator[Union[Line, ProcessorExceptio
line = yield next(task := parser.Generator(line))
break
else:
raise Exception(f"Unknown task: {line!r}")
WarningCollector.Raise(UnknownTask(f"Unknown task: '{line!r}'", line))
ex = Exception(f"How to recover from here? Unknown task: '{line!r}'")
ex.add_note(f"Current task: start pattern='{self._task}'")
ex.add_note(f"Current cmd: {self._task._command}")
raise ex
break
elif line.StartsWith(self._TCL_COMMAND):
if line[len(self._TCL_COMMAND) + 1:].startswith("completed successfully"):
Expand Down Expand Up @@ -650,7 +676,11 @@ def SectionDetector(self, line: Line) -> Generator[Union[Line, ProcessorExceptio
line = yield next(task := parser.Generator(line))
break
else:
raise Exception(f"Unknown task: {line!r}")
WarningCollector.Raise(UnknownTask(f"Unknown task: '{line!r}'", line))
ex = Exception(f"How to recover from here? Unknown task: '{line!r}'")
ex.add_note(f"Current task: start pattern='{self._task}'")
ex.add_note(f"Current cmd: {self._task._command}")
raise ex
break
elif line.StartsWith(self._TCL_COMMAND):
if line[len(self._TCL_COMMAND) + 1:].startswith("completed successfully"):
Expand Down
Loading
Loading