pyEDAA.OutputFilter 0.1.0__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyedaa_outputfilter-0.1.0 → pyedaa_outputfilter-0.2.0}/PKG-INFO +32 -27
- {pyedaa_outputfilter-0.1.0 → pyedaa_outputfilter-0.2.0}/README.md +9 -4
- {pyedaa_outputfilter-0.1.0 → pyedaa_outputfilter-0.2.0}/pyEDAA/OutputFilter/CLI/Vivado.py +85 -60
- pyedaa_outputfilter-0.2.0/pyEDAA/OutputFilter/Xilinx/Synthesis.py +656 -0
- pyedaa_outputfilter-0.2.0/pyEDAA/OutputFilter/Xilinx/__init__.py +644 -0
- {pyedaa_outputfilter-0.1.0 → pyedaa_outputfilter-0.2.0}/pyEDAA/OutputFilter/__init__.py +1 -1
- {pyedaa_outputfilter-0.1.0 → pyedaa_outputfilter-0.2.0}/pyEDAA.OutputFilter.egg-info/PKG-INFO +32 -27
- {pyedaa_outputfilter-0.1.0 → pyedaa_outputfilter-0.2.0}/pyEDAA.OutputFilter.egg-info/requires.txt +22 -22
- pyedaa_outputfilter-0.1.0/pyEDAA/OutputFilter/Xilinx/Synthesis.py +0 -573
- pyedaa_outputfilter-0.1.0/pyEDAA/OutputFilter/Xilinx/__init__.py +0 -179
- {pyedaa_outputfilter-0.1.0 → pyedaa_outputfilter-0.2.0}/LICENSE.md +0 -0
- {pyedaa_outputfilter-0.1.0 → pyedaa_outputfilter-0.2.0}/pyEDAA/OutputFilter/CLI/__init__.py +0 -0
- {pyedaa_outputfilter-0.1.0 → pyedaa_outputfilter-0.2.0}/pyEDAA.OutputFilter.egg-info/SOURCES.txt +0 -0
- {pyedaa_outputfilter-0.1.0 → pyedaa_outputfilter-0.2.0}/pyEDAA.OutputFilter.egg-info/dependency_links.txt +0 -0
- {pyedaa_outputfilter-0.1.0 → pyedaa_outputfilter-0.2.0}/pyEDAA.OutputFilter.egg-info/entry_points.txt +0 -0
- {pyedaa_outputfilter-0.1.0 → pyedaa_outputfilter-0.2.0}/pyEDAA.OutputFilter.egg-info/top_level.txt +0 -0
- {pyedaa_outputfilter-0.1.0 → pyedaa_outputfilter-0.2.0}/pyproject.toml +0 -0
- {pyedaa_outputfilter-0.1.0 → pyedaa_outputfilter-0.2.0}/setup.cfg +0 -0
- {pyedaa_outputfilter-0.1.0 → pyedaa_outputfilter-0.2.0}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyEDAA.OutputFilter
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Post-processing of EDA Tool outputs (log files).
|
|
5
5
|
Home-page: https://GitHub.com/edaa-org/pyEDAA.OutputFilter
|
|
6
6
|
Author: Patrick Lehmann
|
|
@@ -27,45 +27,45 @@ Description-Content-Type: text/markdown
|
|
|
27
27
|
License-File: LICENSE.md
|
|
28
28
|
Requires-Dist: pyTooling[terminal]~=8.5
|
|
29
29
|
Provides-Extra: doc
|
|
30
|
+
Requires-Dist: sphinx_design~=0.6.1; extra == "doc"
|
|
31
|
+
Requires-Dist: pyTooling[terminal]~=8.5; extra == "doc"
|
|
30
32
|
Requires-Dist: docutils_stubs~=0.0.22; extra == "doc"
|
|
31
|
-
Requires-Dist: sphinxcontrib-autoprogram~=0.1; extra == "doc"
|
|
32
|
-
Requires-Dist: sphinxcontrib-mermaid~=1.0; extra == "doc"
|
|
33
|
-
Requires-Dist: autoapi>=2.0.1; extra == "doc"
|
|
34
33
|
Requires-Dist: sphinx_rtd_theme~=3.0; extra == "doc"
|
|
35
|
-
Requires-Dist:
|
|
36
|
-
Requires-Dist: pyTooling[terminal]~=8.5; extra == "doc"
|
|
34
|
+
Requires-Dist: sphinxcontrib-mermaid~=1.0; extra == "doc"
|
|
37
35
|
Requires-Dist: sphinx_autodoc_typehints~=3.2; extra == "doc"
|
|
38
|
-
Requires-Dist: sphinx_design~=0.6.1; extra == "doc"
|
|
39
36
|
Requires-Dist: sphinx-copybutton>=0.5.2; extra == "doc"
|
|
40
37
|
Requires-Dist: sphinx~=8.2; extra == "doc"
|
|
41
38
|
Requires-Dist: sphinx_reports~=0.9; extra == "doc"
|
|
39
|
+
Requires-Dist: autoapi>=2.0.1; extra == "doc"
|
|
40
|
+
Requires-Dist: docutils~=0.21; extra == "doc"
|
|
41
|
+
Requires-Dist: sphinxcontrib-autoprogram~=0.1; extra == "doc"
|
|
42
42
|
Provides-Extra: test
|
|
43
|
-
Requires-Dist: typing_extensions~=4.13; extra == "test"
|
|
44
|
-
Requires-Dist: mypy~=1.16; extra == "test"
|
|
45
|
-
Requires-Dist: lxml~=5.4; extra == "test"
|
|
46
|
-
Requires-Dist: pytest-cov~=6.2; extra == "test"
|
|
47
|
-
Requires-Dist: Coverage~=7.9; extra == "test"
|
|
48
43
|
Requires-Dist: pyTooling[terminal]~=8.5; extra == "test"
|
|
44
|
+
Requires-Dist: typing_extensions~=4.14; extra == "test"
|
|
45
|
+
Requires-Dist: pytest-cov~=6.2; extra == "test"
|
|
49
46
|
Requires-Dist: pytest~=8.4; extra == "test"
|
|
47
|
+
Requires-Dist: Coverage~=7.9; extra == "test"
|
|
48
|
+
Requires-Dist: lxml~=5.4; extra == "test"
|
|
49
|
+
Requires-Dist: mypy~=1.16; extra == "test"
|
|
50
50
|
Provides-Extra: all
|
|
51
|
+
Requires-Dist: sphinx_design~=0.6.1; extra == "all"
|
|
52
|
+
Requires-Dist: pyTooling[terminal]~=8.5; extra == "all"
|
|
51
53
|
Requires-Dist: docutils_stubs~=0.0.22; extra == "all"
|
|
52
|
-
Requires-Dist: sphinxcontrib-autoprogram~=0.1; extra == "all"
|
|
53
|
-
Requires-Dist: typing_extensions~=4.13; extra == "all"
|
|
54
|
-
Requires-Dist: mypy~=1.16; extra == "all"
|
|
55
|
-
Requires-Dist: lxml~=5.4; extra == "all"
|
|
56
54
|
Requires-Dist: sphinxcontrib-mermaid~=1.0; extra == "all"
|
|
57
|
-
Requires-Dist: pytest-cov~=6.2; extra == "all"
|
|
58
|
-
Requires-Dist: autoapi>=2.0.1; extra == "all"
|
|
59
|
-
Requires-Dist: Coverage~=7.9; extra == "all"
|
|
60
55
|
Requires-Dist: sphinx_rtd_theme~=3.0; extra == "all"
|
|
61
|
-
Requires-Dist: docutils~=0.21; extra == "all"
|
|
62
|
-
Requires-Dist: pyTooling[terminal]~=8.5; extra == "all"
|
|
63
56
|
Requires-Dist: sphinx_autodoc_typehints~=3.2; extra == "all"
|
|
64
|
-
Requires-Dist: sphinx_design~=0.6.1; extra == "all"
|
|
65
57
|
Requires-Dist: sphinx-copybutton>=0.5.2; extra == "all"
|
|
66
58
|
Requires-Dist: sphinx~=8.2; extra == "all"
|
|
67
|
-
Requires-Dist:
|
|
59
|
+
Requires-Dist: typing_extensions~=4.14; extra == "all"
|
|
68
60
|
Requires-Dist: sphinx_reports~=0.9; extra == "all"
|
|
61
|
+
Requires-Dist: pytest-cov~=6.2; extra == "all"
|
|
62
|
+
Requires-Dist: pytest~=8.4; extra == "all"
|
|
63
|
+
Requires-Dist: Coverage~=7.9; extra == "all"
|
|
64
|
+
Requires-Dist: lxml~=5.4; extra == "all"
|
|
65
|
+
Requires-Dist: autoapi>=2.0.1; extra == "all"
|
|
66
|
+
Requires-Dist: docutils~=0.21; extra == "all"
|
|
67
|
+
Requires-Dist: sphinxcontrib-autoprogram~=0.1; extra == "all"
|
|
68
|
+
Requires-Dist: mypy~=1.16; extra == "all"
|
|
69
69
|
Dynamic: author
|
|
70
70
|
Dynamic: author-email
|
|
71
71
|
Dynamic: classifier
|
|
@@ -110,13 +110,18 @@ Dynamic: summary
|
|
|
110
110
|
|
|
111
111
|
# Main Goals
|
|
112
112
|
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
* Extract
|
|
113
|
+
* Live and offline parsing and classification of message lines from tool outputs.
|
|
114
|
+
* Provide a data model for tool specific log files.
|
|
115
|
+
* Extract values, lists and tables of embedded reports or summaries.
|
|
116
|
+
* Implement checks and policies.
|
|
116
117
|
|
|
117
118
|
# Use Cases
|
|
118
119
|
|
|
119
|
-
*
|
|
120
|
+
* Write colorized logs to CI server logs or to shells based on classification.
|
|
121
|
+
* Increase or decrease the severity level of message.
|
|
122
|
+
* List messages of a certain kind (e.g. unused sequential elements).
|
|
123
|
+
* Check for existence / non-existence of messages or outputs (e.g. latches).
|
|
124
|
+
* Collect statistics and convert to datasets for a time series database (TSDB).
|
|
120
125
|
|
|
121
126
|
# Examples
|
|
122
127
|
|
|
@@ -27,13 +27,18 @@
|
|
|
27
27
|
|
|
28
28
|
# Main Goals
|
|
29
29
|
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* Extract
|
|
30
|
+
* Live and offline parsing and classification of message lines from tool outputs.
|
|
31
|
+
* Provide a data model for tool specific log files.
|
|
32
|
+
* Extract values, lists and tables of embedded reports or summaries.
|
|
33
|
+
* Implement checks and policies.
|
|
33
34
|
|
|
34
35
|
# Use Cases
|
|
35
36
|
|
|
36
|
-
*
|
|
37
|
+
* Write colorized logs to CI server logs or to shells based on classification.
|
|
38
|
+
* Increase or decrease the severity level of message.
|
|
39
|
+
* List messages of a certain kind (e.g. unused sequential elements).
|
|
40
|
+
* Check for existence / non-existence of messages or outputs (e.g. latches).
|
|
41
|
+
* Collect statistics and convert to datasets for a time series database (TSDB).
|
|
37
42
|
|
|
38
43
|
# Examples
|
|
39
44
|
|
|
@@ -30,60 +30,23 @@
|
|
|
30
30
|
#
|
|
31
31
|
from argparse import Namespace
|
|
32
32
|
from pathlib import Path
|
|
33
|
-
from
|
|
34
|
-
from typing import NoReturn
|
|
33
|
+
from typing import NoReturn, Iterable
|
|
35
34
|
|
|
36
|
-
from pyTooling.Decorators
|
|
37
|
-
from pyTooling.MetaClasses
|
|
38
|
-
from pyTooling.
|
|
39
|
-
from pyTooling.Attributes.ArgParse
|
|
40
|
-
from pyTooling.Attributes.ArgParse.
|
|
41
|
-
from pyTooling.Attributes.ArgParse.ValuedFlag import LongValuedFlag
|
|
42
|
-
from pyTooling.Stopwatch import Stopwatch
|
|
35
|
+
from pyTooling.Decorators import readonly
|
|
36
|
+
from pyTooling.MetaClasses import ExtendedType
|
|
37
|
+
from pyTooling.Attributes.ArgParse import CommandHandler
|
|
38
|
+
from pyTooling.Attributes.ArgParse.Flag import LongFlag
|
|
39
|
+
from pyTooling.Attributes.ArgParse.ValuedFlag import LongValuedFlag
|
|
43
40
|
|
|
44
|
-
from pyEDAA.OutputFilter.Xilinx
|
|
41
|
+
from pyEDAA.OutputFilter.Xilinx import Preamble, LineKind, Line
|
|
42
|
+
from pyEDAA.OutputFilter.Xilinx.Synthesis import WritingSynthesisReport, Processor, LoadingPart
|
|
45
43
|
|
|
46
44
|
|
|
47
|
-
class
|
|
48
|
-
@readonly
|
|
49
|
-
def Verbose(self) -> bool:
|
|
50
|
-
...
|
|
51
|
-
|
|
52
|
-
@readonly
|
|
53
|
-
def Width(self) -> int:
|
|
54
|
-
...
|
|
55
|
-
|
|
56
|
-
def _PrintHeadline(self):
|
|
57
|
-
...
|
|
58
|
-
|
|
59
|
-
def WriteDebug(self, a: str, appendLinebreak: bool = True):
|
|
60
|
-
...
|
|
61
|
-
|
|
62
|
-
def WriteVerbose(self, a: str, appendLinebreak: bool = True):
|
|
63
|
-
...
|
|
64
|
-
|
|
65
|
-
def WriteNormal(self, a: str, appendLinebreak: bool = True):
|
|
66
|
-
...
|
|
67
|
-
|
|
68
|
-
def WriteWarning(self, a: str, appendLinebreak: bool = True):
|
|
69
|
-
...
|
|
70
|
-
|
|
71
|
-
def WriteCritical(self, a: str, appendLinebreak: bool = True):
|
|
72
|
-
...
|
|
73
|
-
|
|
74
|
-
def WriteError(self, a: str, appendLinebreak: bool = True):
|
|
75
|
-
...
|
|
76
|
-
|
|
77
|
-
def WriteFatal(self, a: str, appendLinebreak: bool = True, immediateExit: bool = True):
|
|
78
|
-
...
|
|
79
|
-
|
|
80
|
-
def Exit(self, i: int = 0) -> NoReturn:
|
|
81
|
-
...
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
class VivadoHandlers(Proto, metaclass=ExtendedType, mixin=True):
|
|
45
|
+
class VivadoHandlers(metaclass=ExtendedType, mixin=True):
|
|
85
46
|
@CommandHandler("vivado-synth", help="Parse AMD/Xilinx Vivado Synthesis log files.", description="Parse AMD/Xilinx Vivado Synthesis log files.")
|
|
86
47
|
@LongValuedFlag("--file", dest="logfile", metaName='Synthesis Log', help="Synthesis log file (*.vds).")
|
|
48
|
+
@LongFlag("--colored", dest="colored", help="Render logfile with colored lines.")
|
|
49
|
+
@LongFlag("--summary", dest="summary", help="Print a summary.")
|
|
87
50
|
@LongFlag("--info", dest="info", help="Print info messages.")
|
|
88
51
|
@LongFlag("--warning", dest="warning", help="Print warning messages.")
|
|
89
52
|
@LongFlag("--critical", dest="critical", help="Print critical warning messages.")
|
|
@@ -110,6 +73,9 @@ class VivadoHandlers(Proto, metaclass=ExtendedType, mixin=True):
|
|
|
110
73
|
processor = Processor(logfile)
|
|
111
74
|
processor.Parse()
|
|
112
75
|
|
|
76
|
+
if args.colored:
|
|
77
|
+
self.ColoredOutput(processor._lines)
|
|
78
|
+
|
|
113
79
|
if args.info:
|
|
114
80
|
self.WriteNormal(f"INFO messages: {len(processor.InfoMessages)}")
|
|
115
81
|
for message in processor.InfoMessages:
|
|
@@ -150,18 +116,77 @@ class VivadoHandlers(Proto, metaclass=ExtendedType, mixin=True):
|
|
|
150
116
|
|
|
151
117
|
self.WriteNormal(influxString)
|
|
152
118
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
119
|
+
if args.summary:
|
|
120
|
+
self.WriteNormal("Summary:")
|
|
121
|
+
self.WriteNormal(f" Tool version: {processor[Preamble].ToolVersion}")
|
|
122
|
+
self.WriteNormal(f" Started at: {processor[Preamble].StartDatetime}")
|
|
123
|
+
self.WriteNormal(f" Processing duration: {processor.Duration:.3f} s")
|
|
124
|
+
self.WriteNormal(f" Info: {len(processor.InfoMessages)}")
|
|
125
|
+
self.WriteNormal(f" Warning: {len(processor.WarningMessages)}")
|
|
126
|
+
self.WriteNormal(f" Critical Warning: {len(processor.CriticalWarningMessages)}")
|
|
127
|
+
self.WriteNormal(f" Error: {len(processor.ErrorMessages)}")
|
|
128
|
+
self.WriteNormal(f" Part: {processor[LoadingPart].Part}")
|
|
129
|
+
|
|
130
|
+
self.WriteNormal("Policies:")
|
|
131
|
+
self.WriteNormal(f" Latches: {'found' if processor.HasLatches else '----'}")
|
|
132
|
+
if processor.HasLatches:
|
|
133
|
+
for cellName in ("LD", ):
|
|
134
|
+
try:
|
|
135
|
+
self.WriteNormal(f" {cellName}: {processor.Cells[cellName]}")
|
|
136
|
+
except KeyError:
|
|
137
|
+
pass
|
|
138
|
+
for latch in processor.Latches:
|
|
139
|
+
self.WriteNormal(f" {latch}")
|
|
140
|
+
self.WriteNormal(f" Blackboxes: {'found' if processor.HasBlackboxes else '----'}")
|
|
141
|
+
if processor.HasBlackboxes:
|
|
142
|
+
for bbox in processor[WritingSynthesisReport].Blackboxes:
|
|
143
|
+
self.WriteNormal(f" {bbox}")
|
|
144
|
+
|
|
145
|
+
self.WriteNormal(f"VHDL report statements ({len(processor.VHDLReportMessages)}):")
|
|
146
|
+
for message in processor.VHDLReportMessages:
|
|
147
|
+
self.WriteNormal(f" {message}")
|
|
148
|
+
self.WriteNormal(f"VHDL assert statements ({len(processor.VHDLAssertMessages)}):")
|
|
149
|
+
for message in processor.VHDLAssertMessages:
|
|
150
|
+
self.WriteNormal(f" {message}")
|
|
151
|
+
|
|
152
|
+
self.WriteNormal(f"Cells: {len(processor.Cells)}")
|
|
153
|
+
for cell, count in processor.Cells.items():
|
|
154
|
+
self.WriteNormal(f" {cell}: {count}")
|
|
156
155
|
|
|
157
156
|
self.ExitOnPreviousErrors()
|
|
158
157
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
158
|
+
def ColoredOutput(self, lines: Iterable[Line]) -> None:
|
|
159
|
+
for i, line in enumerate(lines, start=1):
|
|
160
|
+
if line.Kind is LineKind.Normal:
|
|
161
|
+
print(f"{i:4}: {line.Message}")
|
|
162
|
+
elif LineKind.Message in line.Kind:
|
|
163
|
+
if line.Kind is LineKind.InfoMessage:
|
|
164
|
+
print(f"{i:4}: {{BLUE}}{line}{{NOCOLOR}}".format(**self.Foreground))
|
|
165
|
+
elif line.Kind is LineKind.WarningMessage:
|
|
166
|
+
print(f"{i:4}: {{YELLOW}}{line}{{NOCOLOR}}".format(**self.Foreground))
|
|
167
|
+
elif line.Kind is LineKind.CriticalWarningMessage:
|
|
168
|
+
print(f"{i:4}: {{MAGENTA}}{line}{{NOCOLOR}}".format(**self.Foreground))
|
|
169
|
+
elif line.Kind is LineKind.ErrorMessage:
|
|
170
|
+
print(f"{i:4}: {{RED}}{line}{{NOCOLOR}}".format(**self.Foreground))
|
|
171
|
+
elif LineKind.Command in line.Kind:
|
|
172
|
+
print(f"{i:4}: {{CYAN}}{line}{{NOCOLOR}}".format(**self.Foreground))
|
|
173
|
+
elif (LineKind.Start in line.Kind) or (LineKind.End in line.Kind):
|
|
174
|
+
print(f"{i:4}: {{DARK_CYAN}}{line}{{NOCOLOR}}".format(**self.Foreground))
|
|
175
|
+
elif line.Kind is LineKind.ParagraphHeadline:
|
|
176
|
+
print(f"{i:4}: {{DARK_YELLOW}}{line}{{NOCOLOR}}".format(**self.Foreground))
|
|
177
|
+
elif LineKind.Table in line.Kind:
|
|
178
|
+
print(f"{i:4}: {{WHITE}}{line}{{NOCOLOR}}".format(**self.Foreground))
|
|
179
|
+
elif LineKind.Delimiter in line.Kind:
|
|
180
|
+
print(f"{i:4}: {{GRAY}}{line}{{NOCOLOR}}".format(**self.Foreground))
|
|
181
|
+
elif LineKind.Verbose in line.Kind:
|
|
182
|
+
print(f"{i:4}: {{DARK_GRAY}}{line}{{NOCOLOR}}".format(**self.Foreground))
|
|
183
|
+
elif line.Kind is LineKind.Empty:
|
|
184
|
+
print(f"{i:4}:")
|
|
185
|
+
elif line.Kind is LineKind.ProcessorError:
|
|
186
|
+
print(f"{i:4}: {{RED}}{line}{{NOCOLOR}}".format(**self.Foreground))
|
|
187
|
+
elif line.Kind is LineKind.Unprocessed:
|
|
188
|
+
print(f"{i:4}: {{DARK_RED}}{line}{{NOCOLOR}}".format(**self.Foreground))
|
|
189
|
+
else:
|
|
190
|
+
print(f"{i:4}: Unknown LineKind '{line._kind}' for line {line._lineNumber}.")
|
|
191
|
+
print(line)
|
|
192
|
+
raise Exception()
|