Coverage for tsfpga/vivado/build_result.py: 97%

31 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-10 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 """ 

20 Attributes: 

21 name (`str`): The name of the build. 

22 success (`bool`): True if the build and all pre- and post hooks succeeded. 

23 synthesis_size (`dict`): A dictionary with the utilization of primitives for the 

24 synthesized design. 

25 Will be ``None`` if synthesis failed or did not run. 

26 implementation_size (`dict`): A dictionary with the utilization of primitives for 

27 the implemented design. 

28 Will be ``None`` if implementation failed or did not run. 

29 logic_level_distribution (str): A table with logic level distribution as reported by Vivado. 

30 Will be ``None`` for non-netlist builds. 

31 Will be ``None`` if synthesis failed or did not run. 

32 """ 

33 

34 def __init__(self, name: str): 

35 """ 

36 Arguments: 

37 name: The name of the build. 

38 """ 

39 self.name = name 

40 self.success: bool = True 

41 self.synthesis_size: Optional[dict[str, int]] = None 

42 self.implementation_size: Optional[dict[str, int]] = None 

43 self.logic_level_distribution: Optional[str] = None 

44 

45 def size_summary(self) -> Union[str, None]: 

46 """ 

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

48 

49 Return: 

50 A human-readable message of the latest size. ``None`` if no size is set. 

51 """ 

52 build_step = None 

53 size = None 

54 

55 if self.implementation_size: 

56 build_step = "implementation" 

57 size = self.implementation_size 

58 

59 elif self.synthesis_size: 

60 build_step = "synthesis" 

61 size = self.synthesis_size 

62 

63 else: 

64 return None 

65 

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

67 

68 def report(self) -> Union[str, None]: 

69 """ 

70 Return a report of the build result. Includes all metrics and information that has been 

71 extracted from the Vivado reports. 

72 """ 

73 result = self.size_summary() 

74 

75 if self.logic_level_distribution: 

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

77 

78 return result 

79 

80 @property 

81 def maximum_logic_level(self) -> Union[None, int]: 

82 """ 

83 The maximum level in the the :attr:`.BuildResult.logic_level_distribution`. 

84 Will be ``None`` for non-netlist builds. 

85 Will be ``None`` if synthesis failed or did not run. 

86 

87 Return: 

88 The maximum logic level. 

89 """ 

90 if not self.logic_level_distribution: 

91 return None 

92 

93 return LogicLevelDistributionParser.get_maximum_logic_level( 

94 table=self.logic_level_distribution 

95 )