Coverage for tsfpga/vivado/build_result.py: 97%
31 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-02-21 20:51 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-02-21 20:51 +0000
1# --------------------------------------------------------------------------------------------------
2# Copyright (c) Lukas Vik. All rights reserved.
3#
4# This file is part of the tsfpga project, a project platform for modern FPGA development.
5# https://tsfpga.com
6# https://github.com/tsfpga/tsfpga
7# --------------------------------------------------------------------------------------------------
9from __future__ import annotations
11import json
13from .logic_level_distribution_parser import LogicLevelDistributionParser
16class BuildResult:
17 """
18 Attributes:
19 name (`str`): The name of the build.
20 success (`bool`): True if the build and all pre- and post hooks succeeded.
21 synthesis_size (`dict`): A dictionary with the utilization of primitives for the
22 synthesized design.
23 Will be ``None`` if synthesis failed or did not run.
24 implementation_size (`dict`): A dictionary with the utilization of primitives for
25 the implemented design.
26 Will be ``None`` if implementation failed or did not run.
27 logic_level_distribution (str): A table with logic level distribution as reported by Vivado.
28 Will be ``None`` for non-netlist builds.
29 Will be ``None`` if synthesis failed or did not run.
30 """
32 def __init__(self, name: str) -> None:
33 """
34 Arguments:
35 name: The name of the build.
36 """
37 self.name = name
38 self.success: bool = True
39 self.synthesis_size: dict[str, int] | None = None
40 self.implementation_size: dict[str, int] | None = None
41 self.logic_level_distribution: str | None = None
43 def size_summary(self) -> str | None:
44 """
45 Return a string with a formatted message of the size.
47 Return:
48 A human-readable message of the latest size. ``None`` if no size is set.
49 """
50 build_step = None
51 size = None
53 if self.implementation_size:
54 build_step = "implementation"
55 size = self.implementation_size
57 elif self.synthesis_size:
58 build_step = "synthesis"
59 size = self.synthesis_size
61 else:
62 return None
64 return f"Size of {self.name} after {build_step}:\n{json.dumps(size, indent=2)}"
66 def report(self) -> str | None:
67 """
68 Return a report of the build result. Includes all metrics and information that has been
69 extracted from the Vivado reports.
70 """
71 result = self.size_summary()
73 if self.logic_level_distribution:
74 result = f"{result}\nLogic level distribution:\n{self.logic_level_distribution}"
76 return result
78 @property
79 def maximum_logic_level(self) -> None | int:
80 """
81 The maximum level in the the :attr:`.BuildResult.logic_level_distribution`.
82 Will be ``None`` for non-netlist builds.
83 Will be ``None`` if synthesis failed or did not run.
85 Return:
86 The maximum logic level.
87 """
88 if not self.logic_level_distribution:
89 return None
91 return LogicLevelDistributionParser.get_maximum_logic_level(
92 table=self.logic_level_distribution
93 )