hdl.ast: warn if reset value is truncated.
authorwhitequark <cz@m-labs.hk>
Tue, 10 Sep 2019 07:25:28 +0000 (07:25 +0000)
committerwhitequark <cz@m-labs.hk>
Tue, 10 Sep 2019 07:26:34 +0000 (07:26 +0000)
Fixes #183.

nmigen/hdl/ast.py
nmigen/test/test_hdl_ast.py

index 0afa5d93ac759200908ccb15a8706208a4d007a0..56671eda88c43666dcd17b68d4a49f6c2d3f8e6f 100644 (file)
@@ -665,6 +665,14 @@ class Signal(Value, DUID):
 
         if not isinstance(self.nbits, int) or self.nbits < 0:
             raise TypeError("Width must be a non-negative integer, not '{!r}'".format(self.nbits))
+
+        reset_nbits = bits_for(reset, self.signed)
+        if reset != 0 and reset_nbits > self.nbits:
+            warnings.warn("Reset value {!r} requires {} bits to represent, but the signal "
+                          "only has {} bits"
+                          .format(reset, reset_nbits, self.nbits),
+                          SyntaxWarning, stacklevel=2 + src_loc_at)
+
         self.reset = int(reset)
         self.reset_less = bool(reset_less)
 
index 1fd70aaef021922a62e9a74366ed265a3a91426a..9ad4d327242db20a012b2b989346aac0d38151f7 100644 (file)
@@ -510,6 +510,17 @@ class SignalTestCase(FHDLTestCase):
         self.assertEqual(s1.reset, 0b111)
         self.assertEqual(s1.reset_less, True)
 
+    def test_reset_narrow(self):
+        with self.assertWarns(SyntaxWarning,
+                msg="Reset value 8 requires 4 bits to represent, but the signal only has 3 bits"):
+            Signal(3, reset=8)
+        with self.assertWarns(SyntaxWarning,
+                msg="Reset value 4 requires 4 bits to represent, but the signal only has 3 bits"):
+            Signal((3, True), reset=4)
+        with self.assertWarns(SyntaxWarning,
+                msg="Reset value -5 requires 4 bits to represent, but the signal only has 3 bits"):
+            Signal((3, True), reset=-5)
+
     def test_attrs(self):
         s1 = Signal()
         self.assertEqual(s1.attrs, {})