Skip to content

Commit a2041f6

Browse files
committed
More doc-strings.
1 parent 0f4b05f commit a2041f6

5 files changed

Lines changed: 242 additions & 33 deletions

File tree

pyEDAA/OutputFilter/Xilinx/Common2.py

Lines changed: 139 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -189,35 +189,84 @@ def Processor(self) -> "Processor":
189189

190190
@export
191191
class Preamble(Parser):
192-
_toolVersion: Nullable[YearReleaseVersion]
193-
_startDatetime: Nullable[datetime]
192+
"""
193+
A parser for the preamble emitted by Vivado at session start.
194194
195+
.. rubric:: Extracted information
196+
197+
* Vivado tool version. |br|
198+
See :data:`ToolVersion`
199+
* Session start timestamp (date and time). |br|
200+
See :data:`StartDatetime`
201+
202+
.. rubric:: Example
203+
204+
.. code-block::
205+
206+
#-----------------------------------------------------------
207+
# Vivado v2019.1 (64-bit)
208+
# SW Build 2552052 on Fri May 24 14:49:42 MDT 2019
209+
# IP Build 2548770 on Fri May 24 18:01:18 MDT 2019
210+
# Start of session at: Tue Sep 2 08:44:13 2025
211+
# Process ID: 35680
212+
# Current directory: C:/[...]/MercuryZX5_PE1.runs/synth_1
213+
# Command line: vivado.exe -log system_top.vds -product Vivado -mode batch -messageDb vivado.pb -notrace -source system_top.tcl
214+
# Log file: C:/[...]/MercuryZX5_PE1.runs/synth_1/system_top.vds
215+
# Journal file: C:/[...]/MercuryZX5_PE1.runs/synth_1/vivado.jou
216+
#-----------------------------------------------------------
217+
218+
"""
195219
_VERSION: ClassVar[Pattern] = re_compile(r"""# Vivado v(\d+\.\d(\.\d)?) \(64-bit\)""")
196-
_STARTTIME: ClassVar[Pattern] = re_compile(r"""# Start of session at: (\w+ \w+ \d+ \d+:\d+:\d+ \d+)""")
220+
_STARTTIME: ClassVar[Pattern] = re_compile(r"""# Start of session at: (\w+\s+\w+\s+\d+\s+\d+:\d+:\d+\s+\d+)""")
221+
222+
_toolVersion: Nullable[YearReleaseVersion] #: Used Vivado version.
223+
_startDatetime: Nullable[datetime] #: Session start timestamp.
197224

198225
def __init__(self, processor: "BaseProcessor") -> None:
226+
"""
227+
Initializes a Vivado preamble parser.
228+
229+
:param processor: Reference to the Vivado log processor.
230+
"""
199231
super().__init__(processor)
200232

201233
self._toolVersion = None
202234
self._startDatetime = None
203235

204236
@readonly
205237
def ToolVersion(self) -> YearReleaseVersion:
238+
"""
239+
Read-only property to access the extracted Vivado tool version.
240+
241+
:returns: The used Vivado version as reported in the Vivado log messages.
242+
"""
206243
return self._toolVersion
207244

208245
@readonly
209246
def StartDatetime(self) -> datetime:
247+
"""
248+
Read-only property to access the date and time when the Vivado session was started.
249+
250+
:returns: Datatime when the session was started.
251+
"""
210252
return self._startDatetime
211253

212254
def Generator(self, line: Line) -> Generator[Line, Line, Line]:
255+
"""
256+
A generator for processing the Vivado session preamble line-by-line.
257+
258+
:param line: First line to process.
259+
:returns: A generator processing log messages.
260+
"""
213261
if line.StartsWith("#----"):
214262
line._kind = LineKind.SectionDelimiter
215263
else:
216-
line._kind |= LineKind.ProcessorError
264+
line._kind |= LineKind.ProcessorError # TODO: throw / return error
217265

218266
line = yield line
219267

220-
while True:
268+
# a normal preamble has 11 lines including both delimiter lines.
269+
for _ in range(15):
221270
if (match := self._VERSION.match(line._message)) is not None:
222271
self._toolVersion = YearReleaseVersion.Parse(match[1])
223272
line._kind = LineKind.Normal
@@ -231,31 +280,68 @@ def Generator(self, line: Line) -> Generator[Line, Line, Line]:
231280
line._kind = LineKind.Verbose
232281

233282
line = yield line
283+
else:
284+
line._kind |= LineKind.ProcessorError # TODO: throw / return error
234285

235286
nextLine = yield line
236287
return nextLine
237288

238289

239290
@export
240291
class Task(BaseParser, VivadoMessagesMixin, metaclass=ExtendedType, slots=True):
292+
"""
293+
A task's output emitted by a Vivado command.
294+
295+
.. rubric:: Extracted information
296+
297+
* Vivado messages (info, warning, critical warning, error).
298+
299+
.. rubric:: Example
300+
301+
.. code-block::
302+
303+
Starting Cache Timing Information Task
304+
INFO: [Timing 38-35] 79-Done setting XDC timing constraints.
305+
Ending Cache Timing Information Task | Checksum: 19fe8cb97
306+
307+
Time (s): cpu = 00:00:09 ; elapsed = 00:00:09 . Memory (MB): peak = 1370.594 ; gain = 493.266
308+
309+
"""
241310
# _START: ClassVar[str]
242311
# _FINISH: ClassVar[str]
243312
_TIME: ClassVar[str] = "Time (s):"
244313

245-
_command: "Command"
246-
_duration: float
314+
_command: "Command" #: Reference to the command (parent).
315+
_duration: float #: Duration of a task according to reported times by Vivado.
247316

248317
def __init__(self, command: "Command") -> None:
318+
"""
319+
Initializes a task (without child elements).
320+
321+
:param command: Reference to the command.
322+
"""
249323
super().__init__()
250324
VivadoMessagesMixin.__init__(self)
251325

252326
self._command = command
253327

254328
@readonly
255329
def Command(self) -> "Command":
330+
"""
331+
Read-only property to access the command.
332+
333+
:returns: The command this task's output was logged for.
334+
"""
256335
return self._command
257336

258337
def _TaskStart(self, line: Line) -> Generator[Line, Line, Line]:
338+
"""
339+
A generator for processing a task start (single line).
340+
341+
:param line: First line to process (task start).
342+
:returns: A generator processing log messages.
343+
:raises ProcessorException: If first line doesn't conform to the *task start* pattern.
344+
"""
259345
if not line.StartsWith(self._START):
260346
raise ProcessorException(f"{self.__class__.__name__}._TaskStart(): Expected '{self._START}' at line {line._lineNumber}.")
261347

@@ -264,12 +350,19 @@ def _TaskStart(self, line: Line) -> Generator[Line, Line, Line]:
264350
return nextLine
265351

266352
def _TaskFinish(self, line: Line) -> Generator[Line, Line, Line]:
353+
"""
354+
A generator for processing a task finish line-by-line.
355+
356+
:param line: First line to process (task finish).
357+
:returns: A generator processing log messages.
358+
:raises ProcessorException: If finish line doesn't conform to the *task finish* pattern.
359+
"""
267360
if not line.StartsWith(self._FINISH):
268361
raise ProcessorException(f"{self.__class__.__name__}._TaskFinish(): Expected '{self._FINISH}' at line {line._lineNumber}.")
269362

270363
line._kind = LineKind.TaskEnd
271364
line = yield line
272-
while self._TIME is not None:
365+
while self._TIME is not None: # TODO: limit search for time pattern to XX lines
273366
if line.StartsWith(self._TIME):
274367
line._kind = LineKind.TaskTime
275368
break
@@ -280,6 +373,23 @@ def _TaskFinish(self, line: Line) -> Generator[Line, Line, Line]:
280373
return line
281374

282375
def Generator(self, line: Line) -> Generator[Line, Line, Line]:
376+
"""
377+
A generator for processing a task without child elements line-by-line.
378+
379+
.. rubric:: Algorithm
380+
381+
1. Send first line to :meth:`_TaskStart`.
382+
2. Process body lines
383+
384+
* Collect Vivado messages (info, warning, critical warning, error).
385+
* Check for *task finish* pattern.
386+
* Check for *time* pattern.
387+
388+
3. Send last lines to :meth:`_TaskFinish`.
389+
390+
:param line: First line to process.
391+
:returns: A generator processing log messages.
392+
"""
283393
line = yield from self._TaskStart(line)
284394

285395
while True:
@@ -306,13 +416,32 @@ def __str__(self) -> str:
306416

307417
@export
308418
class TaskWithSubTasks(Task):
419+
"""
420+
A task's output emitted by a Vivado command.
421+
422+
.. rubric:: Extracted information
423+
424+
* Vivado messages (info, warning, critical warning, error).
425+
* Subtasks
426+
427+
.. rubric:: Example
428+
429+
.. code-block::
430+
431+
Starting Cache Timing Information Task
432+
INFO: [Timing 38-35] 79-Done setting XDC timing constraints.
433+
Ending Cache Timing Information Task | Checksum: 19fe8cb97
434+
435+
Time (s): cpu = 00:00:09 ; elapsed = 00:00:09 . Memory (MB): peak = 1370.594 ; gain = 493.266
436+
437+
"""
309438
# _START: ClassVar[str]
310439
# _FINISH: ClassVar[str]
311440
# _TIME: ClassVar[str] = "Time (s):"
312441

313-
_PARSERS: ClassVar[Dict[YearReleaseVersion,Tuple[Type["SubTask"], ...]]] = dict()
442+
_PARSERS: ClassVar[Dict[YearReleaseVersion,Tuple[Type["SubTask"], ...]]] = dict()
314443

315-
_subtasks: Dict[Type["SubTask"], "SubTask"]
444+
_subtasks: Dict[Type["SubTask"], "SubTask"]
316445

317446
def __init__(self, command: "Command") -> None:
318447
super().__init__(command)

pyEDAA/OutputFilter/Xilinx/PlaceDesign.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ class Phase_PlacerInitialization(PhaseWithChildren):
9393
"""
9494
*Placer Initialization* phase.
9595
96-
.. topic:: Uses
96+
.. rubric:: Uses
9797
9898
* :class:`SubPhase_PlacerInitializationNetlistSorting`
9999
* :class:`SubPhase_IOPlacement_ClockPlacement_BuildPlacerDevice`
@@ -230,7 +230,7 @@ class Phase_GlobalPlacement(PhaseWithChildren):
230230
"""
231231
*Global Placement* phase.
232232
233-
.. topic:: Uses
233+
.. rubric:: Uses
234234
235235
* :class:`SubPhase_Floorplanning`
236236
* :class:`SubPhase_UpdateTimingBeforeSLRPathOpt`
@@ -411,7 +411,7 @@ class Phase_DetailPlacement(PhaseWithChildren):
411411
"""
412412
*Detail Placement* phase.
413413
414-
.. topic:: Uses
414+
.. rubric:: Uses
415415
416416
* :class:`SubPhase_CommitMultiColumnMacros`
417417
* :class:`SubPhase_CommitMostMacrosLUTRAMs`
@@ -539,7 +539,7 @@ class Phase_PostPlacementOptimizationAndCleanUp(PhaseWithChildren):
539539
"""
540540
*Post Placement Optimization and Clean-Up* phase.
541541
542-
.. topic:: Uses
542+
.. rubric:: Uses
543543
544544
* :class:`SubPhase_PostCommitOptimization`
545545
* :class:`SubPhase_PostPlacementCleanup`
@@ -566,7 +566,7 @@ class PlacerTask(TaskWithPhases):
566566
"""
567567
*Placer* task.
568568
569-
.. topic:: Uses
569+
.. rubric:: Uses
570570
571571
* :class:`Phase_PlacerInitialization`
572572
* :class:`Phase_GlobalPlacement`

pyEDAA/OutputFilter/Xilinx/RouteDesign.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ class SubPhase_UpdateTimingForBusSkew(SubPhaseWithChildren):
140140
"""
141141
*Update Timing for Bus Skew* subphase.
142142
143-
.. topic:: Uses
143+
.. rubric:: Uses
144144
145145
* :class:`SubSubPhase_UpdateTiming`
146146
@@ -160,7 +160,7 @@ class Phase_RouterInitialization(PhaseWithChildren):
160160
"""
161161
*Router Initialization* phase.
162162
163-
.. topic:: Uses
163+
.. rubric:: Uses
164164
165165
* :class:`SubPhase_CreateTimer`
166166
* :class:`SubPhase_FixTopologyConstraints`
@@ -216,7 +216,7 @@ class Phase_Initial_Routing(PhaseWithChildren):
216216
"""
217217
*Initial Routing* phase.
218218
219-
.. topic:: Uses
219+
.. rubric:: Uses
220220
221221
* :class:`SubPhase_GlobalRouting`
222222
* :class:`SubPhase_InitialNetRouting`
@@ -298,7 +298,7 @@ class Phase_RipUpAndReroute(PhaseWithChildren):
298298
"""
299299
*Rip-up And Reroute* phase.
300300
301-
.. topic:: Uses
301+
.. rubric:: Uses
302302
303303
* :class:`SubPhase_GlobalIteration0`
304304
* :class:`SubPhase_AdditionalIterationForHold`
@@ -336,7 +336,7 @@ class Phase_InitialRouting(PhaseWithChildren):
336336
"""
337337
*Initial Routing* phase.
338338
339-
.. topic:: Uses
339+
.. rubric:: Uses
340340
341341
* :class:`SubPhase_InitialNetRoutingPass`
342342
* :class:`SubPhase_GlobalRouting`
@@ -384,7 +384,7 @@ class Phase_DelayAndSkewOptimization(PhaseWithChildren):
384384
"""
385385
*Delay and Skew Optimization* phase.
386386
387-
.. topic:: Uses
387+
.. rubric:: Uses
388388
389389
* :class:`SubPhase_DelayCleanUp`
390390
* :class:`SubPhase_ClockSkewOptimization`
@@ -434,7 +434,7 @@ class Phase_DelayAndSkewOptimization(PhaseWithChildren):
434434
"""
435435
*Delay and Skew Optimization* phase.
436436
437-
.. topic:: Uses
437+
.. rubric:: Uses
438438
439439
* :class:`SubPhase_DelayCleanUp`
440440
* :class:`SubPhase_ClockSkewOptimization`
@@ -592,7 +592,7 @@ class RoutingTask(TaskWithPhases):
592592
"""
593593
*Routing* task.
594594
595-
.. topic:: Uses
595+
.. rubric:: Uses
596596
597597
* :class:`Phase_BuildRTDesign`
598598
* :class:`Phase_RouterInitialization`

pyEDAA/OutputFilter/Xilinx/SynthesizeDesign.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -664,7 +664,7 @@ def _BlackboxesGenerator(self, line: Line) -> Generator[Line, Line, Line]:
664664
:param line: First line to process.
665665
:returns: A generator to process multiple lines containing a table of blackboxes.
666666
667-
.. topic:: Example
667+
.. rubric:: Example
668668
669669
.. code-block::
670670
@@ -718,7 +718,7 @@ def _CellGenerator(self, line: Line) -> Generator[Line, Line, Line]:
718718
:param line: First line to process.
719719
:returns: A generator to process multiple lines containing a table of cell statistics.
720720
721-
.. topic:: Example
721+
.. rubric:: Example
722722
723723
.. code-block::
724724

0 commit comments

Comments
 (0)