make mis-matched FPSCR errors much easier to read
authorJacob Lifshay <programmerjake@gmail.com>
Tue, 16 May 2023 06:47:03 +0000 (23:47 -0700)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 2 Jun 2023 18:51:18 +0000 (19:51 +0100)
src/openpower/fpscr.py
src/openpower/test/state.py

index 1ae31ce398417015763d6a1675b02f48f170ca70..d4e8a1d7612a6b12f33ef8b8fe8e4e1880db5905 100644 (file)
@@ -129,7 +129,7 @@ class FPSCR_FPRF(FieldSelectableInt):
 
 
 class FPSCRState(SelectableInt):
-    def __init__(self, value=0):
+    def __init__(self, value=0, *, auto_update_summary_bits=True):
         self.__do_update_summary_bits = False
         SelectableInt.__init__(self, value, 64)
         self.fsi = {}
@@ -164,7 +164,8 @@ class FPSCRState(SelectableInt):
                 fs = tuple(offs)
             v = FieldSelectableInt(self, fs)
             self.fsi[field] = v
-        self.__update_summary_bits()
+        if auto_update_summary_bits:
+            self.__update_summary_bits()
 
     @property
     def value(self):
index 3ce183801f0e31faf5ad5fc1d4da611e759e4a30..3841891dadb61c8aa6f9eaa37996c16c3f7f339c 100644 (file)
@@ -25,6 +25,7 @@ methods, the use of yield from/yield is required.
 from openpower.decoder.power_enums import XER_bits
 from openpower.decoder.isa.radixmmu import RADIX
 from openpower.util import log
+from openpower.fpscr import FPSCRState
 import os
 import sys
 from copy import deepcopy
@@ -133,9 +134,26 @@ class State:
 
         # fpscr
         if self.fpscr is not None and s2.fpscr is not None:
-            self.dut.assertEqual(
-                self.fpscr, s2.fpscr, "fpscr mismatch (%s != %s) %s" %
-                (self.state_type, s2.state_type, repr(self.code)))
+            if self.fpscr != s2.fpscr:
+                # use FPSCRState.fsi since that's much easier to read than a
+                # decimal integer and since unittest has fancy dict diffs.
+
+                # use auto_update_summary_bits=False since HDL might
+                # mis-compute those summary bits and we want to show the
+                # actual bits, not the corrected bits
+                fpscr1 = FPSCRState(self.fpscr, auto_update_summary_bits=False)
+                fpscr2 = FPSCRState(s2.fpscr, auto_update_summary_bits=False)
+                # FieldSelectableInt.__repr__ is too long
+                fpscr1 = {k: hex(int(v)) for k, v in fpscr1.fsi.items()}
+                fpscr2 = {k: hex(int(v)) for k, v in fpscr2.fsi.items()}
+                old_max_diff = self.dut.maxDiff
+                self.dut.maxDiff = None  # show full diff
+                try:
+                    self.dut.assertEqual(
+                        fpscr1, fpscr2, "fpscr mismatch (%s != %s) %s\n" %
+                        (self.state_type, s2.state_type, repr(self.code)))
+                finally:
+                    self.dut.maxDiff = old_max_diff
 
     def compare_mem(self, s2):
         # copy dics to preserve state mem then pad empty locs since