Coverage for tsfpga/vivado/build_result.py: 97%
31 statements
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-07 20:51 +0000
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-07 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# --------------------------------------------------------------------------------------------------
9# Standard libraries
10import json
11from typing import Optional, Union
13# Local folder libraries
14from .logic_level_distribution_parser import LogicLevelDistributionParser
17class BuildResult:
18 """
19 Attributes:
20 name (`str`): The name of the build.
21 success (`bool`): True if the build and all pre- and post hooks succeeded.
22 synthesis_size (`dict`): A dictionary with the utilization of primitives for the
23 synthesized design.
24 Will be ``None`` if synthesis failed or did not run.
25 implementation_size (`dict`): A dictionary with the utilization of primitives for
26 the implemented design.
27 Will be ``None`` if implementation failed or did not run.
28 logic_level_distribution (str): A table with logic level distribution as reported by Vivado.
29 Will be ``None`` for non-netlist builds.
30 Will be ``None`` if synthesis failed or did not run.
31 """
33 def __init__(self, name: str):
34 """
35 Arguments:
36 name: The name of the build.
37 """
38 self.name = name
39 self.success: bool = True
40 self.synthesis_size: Optional[dict[str, int]] = None
41 self.implementation_size: Optional[dict[str, int]] = None
42 self.logic_level_distribution: Optional[str] = None
44 def size_summary(self) -> Optional[str]:
45 """
46 Return a string with a formatted message of the size.
48 Return:
49 A human-readable message of the latest size. ``None`` if no size is set.
50 """
51 build_step = None
52 size = None
54 if self.implementation_size:
55 build_step = "implementation"
56 size = self.implementation_size
58 elif self.synthesis_size:
59 build_step = "synthesis"
60 size = self.synthesis_size
62 else:
63 return None
65 return f"Size of {self.name} after {build_step}:\n{json.dumps(size, indent=2)}"
67 def report(self) -> Optional[str]:
68 """
69 Return a report of the build result. Includes all metrics and information that has been
70 extracted from the Vivado reports.
71 """
72 result = self.size_summary()
74 if self.logic_level_distribution:
75 result = f"{result}\nLogic level distribution:\n{self.logic_level_distribution}"
77 return result
79 @property
80 def maximum_logic_level(self) -> Union[None, int]:
81 """
82 The maximum level in the the :attr:`.BuildResult.logic_level_distribution`.
83 Will be ``None`` for non-netlist builds.
84 Will be ``None`` if synthesis failed or did not run.
86 Return:
87 The maximum logic level.
88 """
89 if not self.logic_level_distribution:
90 return None
92 return LogicLevelDistributionParser.get_maximum_logic_level(
93 table=self.logic_level_distribution
94 )