hdl.dsl: cases wider than switch test value are unreachable.
authorwhitequark <cz@m-labs.hk>
Sun, 13 Jan 2019 08:51:49 +0000 (08:51 +0000)
committerwhitequark <cz@m-labs.hk>
Sun, 13 Jan 2019 08:51:49 +0000 (08:51 +0000)
In 3083c1d6 they were erroneously fixed via truncation.

nmigen/hdl/dsl.py
nmigen/test/test_hdl_dsl.py
nmigen/test/tools.py

index de0231b4649370c28e74fcfea3f8ec72992aa090..918e8e351589a15bc3584dcd5416b635280b487c 100644 (file)
@@ -219,17 +219,19 @@ class Module(_ModuleBuilderRoot):
         if isinstance(value, str) and len(value) != len(switch_data["test"]):
             raise SyntaxError("Case value '{}' must have the same width as test (which is {})"
                               .format(value, len(switch_data["test"])))
+        omit_case = False
         if isinstance(value, int) and bits_for(value) > len(switch_data["test"]):
             warnings.warn("Case value '{:b}' is wider than test (which has width {}); "
-                          "comparison will be made against truncated value"
+                          "comparison will never be true"
                           .format(value, len(switch_data["test"])), SyntaxWarning, stacklevel=3)
-            value &= (1 << len(switch_data["test"])) - 1
+            omit_case = True
         try:
             _outer_case, self._statements = self._statements, []
             self._ctrl_context = None
             yield
             self._flush_ctrl()
-            switch_data["cases"][value] = self._statements
+            if not omit_case:
+                switch_data["cases"][value] = self._statements
         finally:
             self._ctrl_context = "Switch"
             self._statements = _outer_case
index 3e3df1d1102cc825eb425c6558ea11f00641d742..31753fd046f3eb363709ef172c0d1745fdb849b2 100644 (file)
@@ -289,14 +289,12 @@ class DSLTestCase(FHDLTestCase):
                     pass
             with self.assertWarns(SyntaxWarning,
                     msg="Case value '10110' is wider than test (which has width 4); comparison "
-                        "will be made against truncated value"):
+                        "will never be true"):
                 with m.Case(0b10110):
                     pass
         self.assertRepr(m._statements, """
         (
-            (switch (sig w1)
-                (case 0110 )
-            )
+            (switch (sig w1) )
         )
         """)
 
index 7c89e885bf412ad87fac92a7d36431747e518e2d..e1b1a3d70347c8eda9d981cd5f957d6ec47d20d0 100644 (file)
@@ -12,10 +12,12 @@ __all__ = ["FHDLTestCase"]
 class FHDLTestCase(unittest.TestCase):
     def assertRepr(self, obj, repr_str):
         obj = Statement.wrap(obj)
-        repr_str = re.sub(r"\s+",   " ",  repr_str)
-        repr_str = re.sub(r"\( (?=\()", "(", repr_str)
-        repr_str = re.sub(r"\) (?=\))", ")", repr_str)
-        self.assertEqual(repr(obj), repr_str.strip())
+        def prepare_repr(repr_str):
+            repr_str = re.sub(r"\s+",   " ",  repr_str)
+            repr_str = re.sub(r"\( (?=\()", "(", repr_str)
+            repr_str = re.sub(r"\) (?=\))", ")", repr_str)
+            return repr_str.strip()
+        self.assertEqual(prepare_repr(repr(obj)), prepare_repr(repr_str))
 
     @contextmanager
     def assertRaises(self, exception, msg=None):