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

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# -------------------------------------------------------------------------------------------------- 

8 

9from __future__ import annotations 

10 

11import json 

12 

13from .logic_level_distribution_parser import LogicLevelDistributionParser 

14 

15 

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 """ 

31 

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 

42 

43 def size_summary(self) -> str | None: 

44 """ 

45 Return a string with a formatted message of the size. 

46 

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 

52 

53 if self.implementation_size: 

54 build_step = "implementation" 

55 size = self.implementation_size 

56 

57 elif self.synthesis_size: 

58 build_step = "synthesis" 

59 size = self.synthesis_size 

60 

61 else: 

62 return None 

63 

64 return f"Size of {self.name} after {build_step}:\n{json.dumps(size, indent=2)}" 

65 

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() 

72 

73 if self.logic_level_distribution: 

74 result = f"{result}\nLogic level distribution:\n{self.logic_level_distribution}" 

75 

76 return result 

77 

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. 

84 

85 Return: 

86 The maximum logic level. 

87 """ 

88 if not self.logic_level_distribution: 

89 return None 

90 

91 return LogicLevelDistributionParser.get_maximum_logic_level( 

92 table=self.logic_level_distribution 

93 )