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

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 

9# Standard libraries 

10import json 

11from typing import Optional, Union 

12 

13# Local folder libraries 

14from .logic_level_distribution_parser import LogicLevelDistributionParser 

15 

16 

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

32 

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 

43 

44 def size_summary(self) -> Optional[str]: 

45 """ 

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

47 

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 

53 

54 if self.implementation_size: 

55 build_step = "implementation" 

56 size = self.implementation_size 

57 

58 elif self.synthesis_size: 

59 build_step = "synthesis" 

60 size = self.synthesis_size 

61 

62 else: 

63 return None 

64 

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

66 

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

73 

74 if self.logic_level_distribution: 

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

76 

77 return result 

78 

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. 

85 

86 Return: 

87 The maximum logic level. 

88 """ 

89 if not self.logic_level_distribution: 

90 return None 

91 

92 return LogicLevelDistributionParser.get_maximum_logic_level( 

93 table=self.logic_level_distribution 

94 )