hdl.ast: implement abs() on values.
authorwhitequark <whitequark@whitequark.org>
Sun, 22 Mar 2020 20:50:07 +0000 (20:50 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 31 Dec 2021 13:21:31 +0000 (13:21 +0000)
nmigen/hdl/ast.py
nmigen/test/test_sim.py

index af1d8319c7735f8118194f23f147418fe40c43c2..cadf9600c6d5cc62c295a53f911a9a19f87a4d58 100644 (file)
@@ -220,6 +220,13 @@ class Value(metaclass=ABCMeta):
     def __ge__(self, other):
         return Operator(">=", [self, other])
 
+    def __abs__(self):
+        width, signed = self.shape()
+        if signed:
+            return Mux(self >= 0, self, -self)
+        else:
+            return self
+
     def __len__(self):
         return self.shape().width
 
index 677f2570ca9f54a5306609f177ce118394db5719..7996bec45bdef95b6811b57c4f6fda5d49cf8dd3 100644 (file)
@@ -180,6 +180,13 @@ class SimulatorUnitTestCase(FHDLTestCase):
         self.assertStatement(stmt, [C(2, 4), C(3, 4), C(0)], C(3, 4))
         self.assertStatement(stmt, [C(2, 4), C(3, 4), C(1)], C(2, 4))
 
+    def test_abs(self):
+        stmt = lambda y, a: y.eq(abs(a))
+        self.assertStatement(stmt, [C(3,  unsigned(8))], C(3,  unsigned(8)))
+        self.assertStatement(stmt, [C(-3, unsigned(8))], C(-3, unsigned(8)))
+        self.assertStatement(stmt, [C(3,  signed(8))],   C(3,  signed(8)))
+        self.assertStatement(stmt, [C(-3, signed(8))],   C(3,  signed(8)))
+
     def test_slice(self):
         stmt1 = lambda y, a: y.eq(a[2])
         self.assertStatement(stmt1, [C(0b10110100, 8)], C(0b1,  1))