Coverage for tsfpga/vivado/build_result_checker.py: 98%
58 statements
« prev ^ index » next coverage.py v6.4, created at 2022-05-28 04:01 +0000
« prev ^ index » next coverage.py v6.4, created at 2022-05-28 04:01 +0000
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# --------------------------------------------------------------------------------------------------
10class LessThan:
12 """
13 Limit to be used with a checker to see that a figure is less than the specified value.
14 """
16 def __init__(self, value):
17 """
18 Arguments:
19 value (int): The result value shall be less than this.
20 """
21 self.value = value
23 def check(self, result_value):
24 return result_value < self.value
26 def __str__(self):
27 return f"< {self.value}"
30class EqualTo:
32 """
33 Limit to be used with a checker to see that a figure is equal to the specified value.
34 """
36 def __init__(self, value):
37 """
38 Arguments:
39 value (int): The result value shall be equal to this.
40 """
41 self.value = value
43 def check(self, result_value):
44 return result_value == self.value
46 def __str__(self):
47 return str(self.value)
50class BuildResultChecker:
52 """
53 Check a build result value against a limit.
55 Overload and implement the ``check`` method according to the resource you want to check.
56 """
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
66 def check(self, build_result):
67 """
68 Arguments:
69 build_result (tsfpga.vivado.build_result.BuildResult): Build result that shall
70 be checked.
72 Returns:
73 bool: True if check passed, false otherwise.
74 """
75 raise NotImplementedError("Implement in child class")
77 def _check_value(self, name, value):
78 if self.limit.check(value):
79 message = f"Result check passed for {name}: {value} ({self.limit})"
80 print(message)
81 return True
83 message = f"Result check failed for {name}. " f"Got {value}, expected {self.limit}."
84 print(message)
85 return False
88class MaximumLogicLevel(BuildResultChecker):
90 """
91 Check the maximum logic level of a build result against a limit.
92 """
94 name = "Maximum logic level"
96 def check(self, build_result):
97 return self._check_value("maximum logic level", build_result.maximum_logic_level)
100class SizeChecker(BuildResultChecker):
102 """
103 Check a build result size value against a limit.
105 Overload and set the correct ``name``, according to the names
106 in the vendor utilization report.
108 Note that since this is to be used by netlist builds it checks the synthesized size, not
109 the implemented one, even if available.
110 """
112 name = ""
114 def check(self, build_result):
115 return self._check_value(self.name, build_result.synthesis_size[self.name])
118class TotalLuts(SizeChecker):
120 name = "Total LUTs"
123class LogicLuts(SizeChecker):
125 name = "Logic LUTs"
128class LutRams(SizeChecker):
130 name = "LUTRAMs"
133class Srls(SizeChecker):
135 name = "SRLs"
138class Ffs(SizeChecker):
140 name = "FFs"
143class Ramb36(SizeChecker):
145 name = "RAMB36"
148class Ramb18(SizeChecker):
150 name = "RAMB18"
153class Uram(SizeChecker):
155 name = "URAM"
158class DspBlocks(SizeChecker):
160 """
161 In Vivado pre-2020.1 the resource was called "DSP48 Blocks" in the utilization report.
162 After that it is called "DSP Blocks". This class checks for both.
163 """
165 name = "DSP Blocks"
167 def check(self, build_result):
168 """
169 Same as parent class, but checks for the legacy name as well as the current name.
170 """
171 legacy_name = "DSP48 Blocks"
172 if legacy_name in build_result.synthesis_size:
173 return self._check_value(legacy_name, build_result.synthesis_size[legacy_name])
175 return self._check_value(self.name, build_result.synthesis_size[self.name])