Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# -------------------------------------------------------------------------------------------------- 

2# Copyright (c) Lukas Vik. All rights reserved. 

3# 

4# This file is part of the tsfpga project. 

5# https://tsfpga.com 

6# https://gitlab.com/tsfpga/tsfpga 

7# -------------------------------------------------------------------------------------------------- 

8 

9 

10class LessThan: 

11 

12 """ 

13 Limit to be used with a checker to see that a figure is less than the specified value. 

14 """ 

15 

16 def __init__(self, value): 

17 """ 

18 Arguments: 

19 value (int): The result value shall be less than this. 

20 """ 

21 self.value = value 

22 

23 def check(self, result_value): 

24 return result_value < self.value 

25 

26 def __str__(self): 

27 return f"< {self.value}" 

28 

29 

30class EqualTo: 

31 

32 """ 

33 Limit to be used with a checker to see that a figure is equal to the specified value. 

34 """ 

35 

36 def __init__(self, value): 

37 """ 

38 Arguments: 

39 value (int): The result value shall be equal to this. 

40 """ 

41 self.value = value 

42 

43 def check(self, result_value): 

44 return result_value == self.value 

45 

46 def __str__(self): 

47 return str(self.value) 

48 

49 

50class BuildResultChecker: 

51 

52 """ 

53 Check a build result value against a limit. 

54 

55 Overload and implement the ``check`` method according to the resource you want to check. 

56 """ 

57 

58 def __init__(self, limit): 

59 """ 

60 Arguments: 

61 limit: The limit that the specified resource shall be checked against. Should 

62 be e.g. a :class:`LessThan` object. 

63 """ 

64 self.limit = limit 

65 

66 def check(self, build_result): 

67 """ 

68 Arguments: 

69 build_result (.build_result.BuildResult): Build result that shall be checked. 

70 

71 Returns: 

72 bool: True if check passed, false otherwise. 

73 """ 

74 raise NotImplementedError("Implement in child class") 

75 

76 def _check_value(self, resource_name, value): 

77 if self.limit.check(value): 

78 message = f"Result size check passed for {resource_name}: {value} ({self.limit})" 

79 print(message) 

80 return True 

81 

82 message = ( 

83 f"Result size check failed for {resource_name}. " f"Got {value}, expected {self.limit}." 

84 ) 

85 print(message) 

86 return False 

87 

88 

89class MaximumLogicLevel(BuildResultChecker): 

90 

91 """ 

92 Check the maximum logic level of a build result against a limit. 

93 """ 

94 

95 def check(self, build_result): 

96 return self._check_value("maximum logic level", build_result.maximum_logic_level) 

97 

98 

99class SizeChecker(BuildResultChecker): 

100 

101 """ 

102 Check a build result size value against a limit. 

103 

104 Overload and set the correct ``resource_name``, according to the names 

105 in the vendor utilization report. 

106 

107 Note that since this is to be used by netlist builds it checks the synthesized size, not 

108 the implemented one, even if available. 

109 """ 

110 

111 resource_name = "" 

112 

113 def check(self, build_result): 

114 return self._check_value( 

115 self.resource_name, build_result.synthesis_size[self.resource_name] 

116 ) 

117 

118 

119class TotalLuts(SizeChecker): 

120 

121 resource_name = "Total LUTs" 

122 

123 

124class LogicLuts(SizeChecker): 

125 

126 resource_name = "Logic LUTs" 

127 

128 

129class LutRams(SizeChecker): 

130 

131 resource_name = "LUTRAMs" 

132 

133 

134class Srls(SizeChecker): 

135 

136 resource_name = "SRLs" 

137 

138 

139class Ffs(SizeChecker): 

140 

141 resource_name = "FFs" 

142 

143 

144class Ramb36(SizeChecker): 

145 

146 resource_name = "RAMB36" 

147 

148 

149class Ramb18(SizeChecker): 

150 

151 resource_name = "RAMB18" 

152 

153 

154class Uram(SizeChecker): 

155 

156 resource_name = "URAM" 

157 

158 

159class DspBlocks(SizeChecker): 

160 

161 """ 

162 In Vivado pre-2020.1 the resource was called "DSP48 Blocks" in the utilization report. 

163 After that it is called "DSP Blocks". This class checks for both. 

164 """ 

165 

166 resource_name = "DSP Blocks" 

167 

168 def check(self, build_result): 

169 """ 

170 Same as parent class, but checks for the legacy name as well as the current name. 

171 """ 

172 legacy_name = "DSP48 Blocks" 

173 if legacy_name in build_result.synthesis_size: 

174 return self._check_value(legacy_name, build_result.synthesis_size[legacy_name]) 

175 

176 return self._check_value( 

177 self.resource_name, build_result.synthesis_size[self.resource_name] 

178 )