Synthesis

A Vivado synthesis log output (*.vds log file) is comprised of mostly one-liner human-readable text outputs. The document starts with a preamble, has circa 20 sections and ends with a epilog. Each sections is framed by Start xxx and Finished xxx lines. In between, messages of categories: INFO, WARNING, CRITICAL WARNING or ERROR are interweaved.

Processing the *.vds File

A logfile can be processed by Processor. First, it reads a logfile into a list of lines, which get pre-classified as normal output lines or messages. At next, lines are passed to a parser for extracting information of the synthesis log’s sections. Each section might have different output formatting styles like trees or tables.

Besides low-level information extraction, also complex results can be derived from the collected data. This allows higher software layers to implement policies. A common use case is the detection of unused code or the detection of latches.

The whole processing duration is measured and accessible via Duration.

from pyEDAA.OutputFilter.Xilinx.Synthesis import Processor

logfile = Path("tests/data/Stopwatch/toplevel.vds")
processor = Processor(logfile)
processor.Parse()

print(f"Processing duration: {processor.Duration:.3f} seconds")

Extracted Information

Messages

All messages (besides some irregular formats) have the following format:

INFO: [Synth 8-7075] Helper process launched with PID 24240

Messages are classified into 4 categories: INFO, WARNING, CRITICAL WARNING or ERROR. Each message mentions the generating tool (e.g. Synth), the tool’s ID (e.g. 8) and a message kind ID (e.g. 7075) followed by the message string.

All messages of the same category can be accessed in order of appearance in the tool’s output via read-only properties:

  • InfoMessages

  • WarningMessages

  • CriticalWarningMessages

  • ErrorMessages

In addition, messages are grouped in two stages by tool ID and message kind ID. These can be accessed via data:~pyEDAA.OutputFilter.Xilinx.Synthesis.Processor.MessagesByID.

from pathlib import Path
from pyEDAA.OutputFilter.Xilinx.Synthesis import Processor

logfile = Path("tests/data/Stopwatch/toplevel.vds")
processor = Processor(logfile)
processor.Parse()

print(f"Messages by ID:")
for toolID, messageGroup in processor.MessagesByID.items():
  print(f"{processor.ToolNames[toolID]} {toolID}:")
  for messageID, messages in messageGroup.items():
    print(f"  {messageID} ({len(messages)}):")
    for message in messages:
      print(f"    {message}")
from pathlib import Path
from pyEDAA.OutputFilter.Xilinx.Synthesis import Processor

logfile = Path("tests/data/Stopwatch/toplevel.vds")
processor = Processor(logfile)
processor.Parse()

print(f"INFO Messages ({len(processor.InfoMessages)}):")
for message in processor.InfoMessages:
  print(f"  {message}")
from pathlib import Path
from pyEDAA.OutputFilter.Xilinx.Synthesis import Processor

logfile = Path("tests/data/Stopwatch/toplevel.vds")
processor = Processor(logfile)
processor.Parse()

print(f"WARNING Messages ({len(processor.WarningMessages)}):")
for message in processor.WarningMessages:
  print(f"  {message}")
from pathlib import Path
from pyEDAA.OutputFilter.Xilinx.Synthesis import Processor

logfile = Path("tests/data/Stopwatch/toplevel.vds")
processor = Processor(logfile)
processor.Parse()

print(f"CRITICAL WARNING Messages ({len(processor.CriticalWarningMessages)}):")
for message in processor.CriticalWarningMessages:
  print(f"  {message}")
from pathlib import Path
from pyEDAA.OutputFilter.Xilinx.Synthesis import Processor

logfile = Path("tests/data/Stopwatch/toplevel.vds")
processor = Processor(logfile)
processor.Parse()

print(f"ERROR Messages ({len(processor.ErrorMessages)}):")
for message in processor.ErrorMessages:
  print(f"  {message}")

Tool Version

The used Vivado version is extracted by the Preamble parser and can be accessed via ToolVersion as YearReleaseVersion.

from pathlib import Path
from pyEDAA.OutputFilter.Xilinx.Synthesis import Processor

logfile = Path("tests/data/Stopwatch/toplevel.vds")
processor = Processor(logfile)
processor.Parse()

print(f"Vivado version: v{processor[Preamble].ToolVersion}")

Synthesis start time and date

The start timestamp (as datetime) is extracted by the Preamble parser and can be accessed via StartDateTime.

from pathlib import Path
from pyEDAA.OutputFilter.Xilinx.Synthesis import Processor

logfile = Path("tests/data/Stopwatch/toplevel.vds")
processor = Processor(logfile)
processor.Parse()

print(f"Synthesis started: v{processor[Preamble].StartDatetime}")

Synthesis duration

The synthesis runtime is extracted by the WritingSynthesisReport parser.

from pathlib import Path
from pyEDAA.OutputFilter.Xilinx.Synthesis import Processor

logfile = Path("tests/data/Stopwatch/toplevel.vds")
processor = Processor(logfile)
processor.Parse()

print(f"Synthesis duration: v{processor[WritingSynthesisReport].Duration:.1f} seconds")

Blackboxes

tbd

from pathlib import Path
from pyEDAA.OutputFilter.Xilinx.Synthesis import Processor

logfile = Path("tests/data/Stopwatch/toplevel.vds")
processor = Processor(logfile)
processor.Parse()

FPGA Low-Level Cells

tbd

from pathlib import Path
from pyEDAA.OutputFilter.Xilinx.Synthesis import Processor

logfile = Path("tests/data/Stopwatch/toplevel.vds")
processor = Processor(logfile)
processor.Parse()

Policies

Latches

Latches are present in the design, if warning Synth 8-327 was found or when the low-level cell report contains cell LD.

from pathlib import Path
from pyEDAA.OutputFilter.Xilinx.Synthesis import Processor

logfile = Path("tests/data/Stopwatch/toplevel.vds")
processor = Processor(logfile)
processor.Parse()

print(f"Synthesis duration: v{processor[WritingSynthesisReport].Duration:.1f} seconds")

Sensitivity List

Synth 8-614

from pathlib import Path
from pyEDAA.OutputFilter.Xilinx.Synthesis import Processor

logfile = Path("tests/data/Stopwatch/toplevel.vds")
processor = Processor(logfile)
processor.Parse()

Unused Signals

Synth 8-3332

from pathlib import Path
from pyEDAA.OutputFilter.Xilinx.Synthesis import Processor

logfile = Path("tests/data/Stopwatch/toplevel.vds")
processor = Processor(logfile)
processor.Parse()

Processing Steps

Preamble

Extracted information:

  • Tool version

  • Start time and date

RTLElaboration

HandlingCustomAttributes1

LoadingPart

Extracted information:

  • 🚧 Part name

ApplySetProperty

RTLComponentStatistics

PartResourceSummary

CrossBoundaryAndAreaOptimization

ApplyingXDCTimingConstraints

TimingOptimization

TechnologyMapping

IOInsertion

FlatteningBeforeIOInsertion

FinalNetlistCleanup

RenamingGeneratedInstances

RebuildingUserHierarchy

RenamingGeneratedPorts

HandlingCustomAttributes2

RenamingGeneratedNets

WritingSynthesisReport

Extracted information:

  • List of blackboxes

  • Low-level resource usage (cells)

Derived information:

  • Are latches (LD) present?