hdl.{ast,dst}: directly represent RTLIL default case.
authorwhitequark <whitequark@whitequark.org>
Tue, 25 Jun 2019 17:53:09 +0000 (17:53 +0000)
committerwhitequark <whitequark@whitequark.org>
Tue, 25 Jun 2019 22:01:14 +0000 (22:01 +0000)
This makes RTLIL mildly nicer:

 casez ({ \$5 , \$3 , \$1  })
   3'bzz1:
       \$next\o  = \$7 ;
   3'bz1z:
       \$next\o  = \$9 ;
   3'b1zz:
       \$next\o  = \$11 ;
-  3'bz:
+  default:
       { \$next\co , \$next\o  } = \$13 ;
 endcase

nmigen/back/pysim.py
nmigen/hdl/ast.py
nmigen/hdl/dsl.py
nmigen/test/test_hdl_dsl.py

index fee545a88c7ad35411a4cfb00ae292be34ddd9da..c07677f998ed8ab84fed32659b47983f5791780a 100644 (file)
@@ -319,16 +319,18 @@ class _StatementCompiler(StatementVisitor):
         test  = self.rrhs_compiler(stmt.test)
         cases = []
         for value, stmts in stmt.cases.items():
-            if "-" in value:
-                mask  = "".join("0" if b == "-" else "1" for b in value)
-                value = "".join("0" if b == "-" else  b  for b in value)
+            if value is None:
+                check = lambda test: True
             else:
-                mask  = "1" * len(value)
-            mask  = int(mask,  2)
-            value = int(value, 2)
-            def make_test(mask, value):
-                return lambda test: test & mask == value
-            cases.append((make_test(mask, value), self.on_statements(stmts)))
+                if "-" in value:
+                    mask  = "".join("0" if b == "-" else "1" for b in value)
+                    value = "".join("0" if b == "-" else  b  for b in value)
+                else:
+                    mask  = "1" * len(value)
+                mask  = int(mask,  2)
+                value = int(value, 2)
+                check = lambda test: test & mask == value
+            cases.append((check, self.on_statements(stmts)))
         def run(state):
             test_value = test(state)
             for check, body in cases:
index 8be490d449cfbd861a2e86b2df517540156bb604..1bcbc5ef91663957a3474e2f5a9c8900caf6bfca 100644 (file)
@@ -1024,10 +1024,12 @@ class Switch(Statement):
                 key = "{:0{}b}".format(key, len(self.test))
             elif isinstance(key, str):
                 pass
+            elif key is None:
+                pass
             else:
                 raise TypeError("Object '{!r}' cannot be used as a switch key"
                                 .format(key))
-            assert len(key) == len(self.test)
+            assert key is None or len(key) == len(self.test)
             if not isinstance(stmts, Iterable):
                 stmts = [stmts]
             self.cases[key] = Statement.wrap(stmts)
@@ -1043,7 +1045,9 @@ class Switch(Statement):
         return self.test._rhs_signals() | signals
 
     def __repr__(self):
-        cases = ["(case {} {})".format(key, " ".join(map(repr, stmts)))
+        cases = ["(default {})".format(" ".join(map(repr, stmts)))
+                 if key is None else
+                 "(case {} {})".format(key, " ".join(map(repr, stmts)))
                  for key, stmts in self.cases.items()]
         return "(switch {!r} {})".format(self.test, " ".join(cases))
 
index 30629c4ae183842deac6e6219eb314a8537053a2..851d721149f9f866677b7a3ecf1a1addd89b3cce 100644 (file)
@@ -316,7 +316,7 @@ class Module(_ModuleBuilderRoot, Elaboratable):
                 if if_test is not None:
                     match = ("1" + "-" * (len(tests) - 1)).rjust(len(if_tests), "-")
                 else:
-                    match = "-" * len(tests)
+                    match = None
                 cases[match] = if_case
 
             self._statements.append(Switch(Cat(tests), cases))
index 0e703e0c995b94db5fdef07830cae834318072ec..e15b1aacc769590edfbb62fddbcb99723005c021 100644 (file)
@@ -174,7 +174,7 @@ class DSLTestCase(FHDLTestCase):
             (switch (cat (sig s1) (sig s2))
                 (case -1 (eq (sig c1) (const 1'd1)))
                 (case 1- (eq (sig c2) (const 1'd0)))
-                (case -- (eq (sig c3) (const 1'd1)))
+                (default (eq (sig c3) (const 1'd1)))
             )
         )
         """)
@@ -234,7 +234,7 @@ class DSLTestCase(FHDLTestCase):
                         (case 1 (eq (sig c2) (const 1'd1)))
                     )
                 )
-                (case -
+                (default
                     (eq (sig c3) (const 1'd1))
                 )
             )