hdl.ast: Operator.{op→operator}
authorwhitequark <whitequark@whitequark.org>
Fri, 11 Oct 2019 11:37:26 +0000 (11:37 +0000)
committerwhitequark <whitequark@whitequark.org>
Fri, 11 Oct 2019 11:37:26 +0000 (11:37 +0000)
Both "operator" and "operand" were shortened to "op" in different
places in code, which caused confusion.

nmigen/back/pysim.py
nmigen/back/rtlil.py
nmigen/hdl/ast.py
nmigen/hdl/xfrm.py

index 472cc574e2fe02075b84df31a7d1867af43610f0..0949d5e92c96729b80b39fd38afb7874ce4588d2 100644 (file)
@@ -123,64 +123,64 @@ class _RHSValueCompiler(_ValueCompiler):
         shape = value.shape()
         if len(value.operands) == 1:
             arg, = map(self, value.operands)
-            if value.op == "~":
+            if value.operator == "~":
                 return lambda state: normalize(~arg(state), shape)
-            if value.op == "-":
+            if value.operator == "-":
                 return lambda state: normalize(-arg(state), shape)
-            if value.op == "b":
+            if value.operator == "b":
                 return lambda state: normalize(bool(arg(state)), shape)
-            if value.op == "r|":
+            if value.operator == "r|":
                 return lambda state: normalize(arg(state) != 0, shape)
-            if value.op == "r&":
+            if value.operator == "r&":
                 val, = value.operands
                 mask = (1 << len(val)) - 1
                 return lambda state: normalize(arg(state) == mask, shape)
-            if value.op == "r^":
+            if value.operator == "r^":
                 # Believe it or not, this is the fastest way to compute a sideways XOR in Python.
                 return lambda state: normalize(format(arg(state), "b").count("1") % 2, shape)
         elif len(value.operands) == 2:
             lhs, rhs = map(self, value.operands)
-            if value.op == "+":
+            if value.operator == "+":
                 return lambda state: normalize(lhs(state) +  rhs(state), shape)
-            if value.op == "-":
+            if value.operator == "-":
                 return lambda state: normalize(lhs(state) -  rhs(state), shape)
-            if value.op == "*":
+            if value.operator == "*":
                 return lambda state: normalize(lhs(state) *  rhs(state), shape)
-            if value.op == "//":
+            if value.operator == "//":
                 def floordiv(lhs, rhs):
                     return 0 if rhs == 0 else lhs // rhs
                 return lambda state: normalize(floordiv(lhs(state), rhs(state)), shape)
-            if value.op == "&":
+            if value.operator == "&":
                 return lambda state: normalize(lhs(state) &  rhs(state), shape)
-            if value.op == "|":
+            if value.operator == "|":
                 return lambda state: normalize(lhs(state) |  rhs(state), shape)
-            if value.op == "^":
+            if value.operator == "^":
                 return lambda state: normalize(lhs(state) ^  rhs(state), shape)
-            if value.op == "<<":
+            if value.operator == "<<":
                 def sshl(lhs, rhs):
                     return lhs << rhs if rhs >= 0 else lhs >> -rhs
                 return lambda state: normalize(sshl(lhs(state), rhs(state)), shape)
-            if value.op == ">>":
+            if value.operator == ">>":
                 def sshr(lhs, rhs):
                     return lhs >> rhs if rhs >= 0 else lhs << -rhs
                 return lambda state: normalize(sshr(lhs(state), rhs(state)), shape)
-            if value.op == "==":
+            if value.operator == "==":
                 return lambda state: normalize(lhs(state) == rhs(state), shape)
-            if value.op == "!=":
+            if value.operator == "!=":
                 return lambda state: normalize(lhs(state) != rhs(state), shape)
-            if value.op == "<":
+            if value.operator == "<":
                 return lambda state: normalize(lhs(state) <  rhs(state), shape)
-            if value.op == "<=":
+            if value.operator == "<=":
                 return lambda state: normalize(lhs(state) <= rhs(state), shape)
-            if value.op == ">":
+            if value.operator == ">":
                 return lambda state: normalize(lhs(state) >  rhs(state), shape)
-            if value.op == ">=":
+            if value.operator == ">=":
                 return lambda state: normalize(lhs(state) >= rhs(state), shape)
         elif len(value.operands) == 3:
-            if value.op == "m":
+            if value.operator == "m":
                 sel, val1, val0 = map(self, value.operands)
                 return lambda state: val1(state) if sel(state) else val0(state)
-        raise NotImplementedError("Operator '{}' not implemented".format(value.op)) # :nocov:
+        raise NotImplementedError("Operator '{}' not implemented".format(value.operator)) # :nocov:
 
     def on_Slice(self, value):
         shape = value.shape()
index 7dbe085dc26461116839b67cf7b094f45cf6b0eb..43a1bd015d05d4d537d30b48d06dec8c527fc89e 100644 (file)
@@ -452,7 +452,7 @@ class _RHSValueCompiler(_ValueCompiler):
         arg_bits, arg_sign = arg.shape()
         res_bits, res_sign = value.shape()
         res = self.s.rtlil.wire(width=res_bits, src=src(value.src_loc))
-        self.s.rtlil.cell(self.operator_map[(1, value.op)], ports={
+        self.s.rtlil.cell(self.operator_map[(1, value.operator)], ports={
             "\\A": self(arg),
             "\\Y": res,
         }, params={
@@ -485,7 +485,7 @@ class _RHSValueCompiler(_ValueCompiler):
         lhs, rhs = value.operands
         lhs_bits, lhs_sign = lhs.shape()
         rhs_bits, rhs_sign = rhs.shape()
-        if lhs_sign == rhs_sign or value.op in ("<<", ">>", "**"):
+        if lhs_sign == rhs_sign or value.operator in ("<<", ">>", "**"):
             lhs_wire = self(lhs)
             rhs_wire = self(rhs)
         else:
@@ -494,7 +494,7 @@ class _RHSValueCompiler(_ValueCompiler):
             rhs_wire = self.match_shape(rhs, rhs_bits, rhs_sign)
         res_bits, res_sign = value.shape()
         res = self.s.rtlil.wire(width=res_bits, src=src(value.src_loc))
-        self.s.rtlil.cell(self.operator_map[(2, value.op)], ports={
+        self.s.rtlil.cell(self.operator_map[(2, value.operator)], ports={
             "\\A": lhs_wire,
             "\\B": rhs_wire,
             "\\Y": res,
@@ -505,7 +505,7 @@ class _RHSValueCompiler(_ValueCompiler):
             "B_WIDTH": rhs_bits,
             "Y_WIDTH": res_bits,
         }, src=src(value.src_loc))
-        if value.op in ("//", "%"):
+        if value.operator in ("//", "%"):
             # RTLIL leaves division by zero undefined, but we require it to return zero.
             divmod_res = res
             res = self.s.rtlil.wire(width=res_bits, src=src(value.src_loc))
@@ -544,7 +544,7 @@ class _RHSValueCompiler(_ValueCompiler):
         elif len(value.operands) == 2:
             return self.on_Operator_binary(value)
         elif len(value.operands) == 3:
-            assert value.op == "m"
+            assert value.operator == "m"
             return self.on_Operator_mux(value)
         else:
             raise TypeError # :nocov:
index db1a70bba811d67963b3f69f286d266724be6717..f142c1db28613c4ebf6aeb1c088c5c8d487f044b 100644 (file)
@@ -453,79 +453,84 @@ class AnySeq(AnyValue):
 
 @final
 class Operator(Value):
-    def __init__(self, op, operands, *, src_loc_at=0):
+    def __init__(self, operator, operands, *, src_loc_at=0):
         super().__init__(src_loc_at=1 + src_loc_at)
-        self.op = op
-        self.operands = [Value.cast(o) for o in operands]
+        self.operator = operator
+        self.operands = [Value.cast(op) for op in operands]
 
-    @staticmethod
-    def _bitwise_binary_shape(a_shape, b_shape):
-        a_bits, a_sign = a_shape
-        b_bits, b_sign = b_shape
-        if not a_sign and not b_sign:
-            # both operands unsigned
-            return max(a_bits, b_bits), False
-        elif a_sign and b_sign:
-            # both operands signed
-            return max(a_bits, b_bits), True
-        elif not a_sign and b_sign:
-            # first operand unsigned (add sign bit), second operand signed
-            return max(a_bits + 1, b_bits), True
-        else:
-            # first signed, second operand unsigned (add sign bit)
-            return max(a_bits, b_bits + 1), True
+    # TODO(nmigen-0.2): move this to nmigen.compat and make it a deprecated extension
+    @property
+    @deprecated("instead of `.op`, use `.operator`")
+    def op(self):
+        return self.operator
 
     def shape(self):
+        def _bitwise_binary_shape(a_shape, b_shape):
+            a_bits, a_sign = a_shape
+            b_bits, b_sign = b_shape
+            if not a_sign and not b_sign:
+                # both operands unsigned
+                return max(a_bits, b_bits), False
+            elif a_sign and b_sign:
+                # both operands signed
+                return max(a_bits, b_bits), True
+            elif not a_sign and b_sign:
+                # first operand unsigned (add sign bit), second operand signed
+                return max(a_bits + 1, b_bits), True
+            else:
+                # first signed, second operand unsigned (add sign bit)
+                return max(a_bits, b_bits + 1), True
+
         op_shapes = list(map(lambda x: x.shape(), self.operands))
         if len(op_shapes) == 1:
             (a_width, a_signed), = op_shapes
-            if self.op in ("+", "~"):
+            if self.operator in ("+", "~"):
                 return a_width, a_signed
-            if self.op == "-":
+            if self.operator == "-":
                 if not a_signed:
                     return a_width + 1, True
                 else:
                     return a_width, a_signed
-            if self.op in ("b", "r|", "r&", "r^"):
+            if self.operator in ("b", "r|", "r&", "r^"):
                 return 1, False
         elif len(op_shapes) == 2:
             (a_width, a_signed), (b_width, b_signed) = op_shapes
-            if self.op == "+" or self.op == "-":
-                width, signed = self._bitwise_binary_shape(*op_shapes)
+            if self.operator == "+" or self.operator == "-":
+                width, signed = _bitwise_binary_shape(*op_shapes)
                 return width + 1, signed
-            if self.op == "*":
+            if self.operator == "*":
                 return a_width + b_width, a_signed or b_signed
-            if self.op in ("//", "%"):
+            if self.operator in ("//", "%"):
                 assert not b_signed
                 return a_width, a_signed
-            if self.op in ("<", "<=", "==", "!=", ">", ">="):
+            if self.operator in ("<", "<=", "==", "!=", ">", ">="):
                 return 1, False
-            if self.op in ("&", "^", "|"):
-                return self._bitwise_binary_shape(*op_shapes)
-            if self.op == "<<":
+            if self.operator in ("&", "^", "|"):
+                return _bitwise_binary_shape(*op_shapes)
+            if self.operator == "<<":
                 if b_signed:
                     extra = 2 ** (b_width - 1) - 1
                 else:
                     extra = 2 ** (b_width)     - 1
                 return a_width + extra, a_signed
-            if self.op == ">>":
+            if self.operator == ">>":
                 if b_signed:
                     extra = 2 ** (b_width - 1)
                 else:
                     extra = 0
                 return a_width + extra, a_signed
         elif len(op_shapes) == 3:
-            if self.op == "m":
+            if self.operator == "m":
                 s_shape, a_shape, b_shape = op_shapes
-                return self._bitwise_binary_shape(a_shape, b_shape)
+                return _bitwise_binary_shape(a_shape, b_shape)
         raise NotImplementedError("Operator {}/{} not implemented"
-                                  .format(self.op, len(op_shapes))) # :nocov:
+                                  .format(self.operator, len(op_shapes))) # :nocov:
 
     def _rhs_signals(self):
         return union(op._rhs_signals() for op in self.operands)
 
     def __repr__(self):
-        return "({} {})".format(self.op, " ".join(map(repr, self.operands)))
+        return "({} {})".format(self.operator, " ".join(map(repr, self.operands)))
 
 
 def Mux(sel, val1, val0):
@@ -1478,7 +1483,8 @@ class ValueKey:
         elif isinstance(self.value, (ClockSignal, ResetSignal)):
             self._hash = hash(self.value.domain)
         elif isinstance(self.value, Operator):
-            self._hash = hash((self.value.op, tuple(ValueKey(o) for o in self.value.operands)))
+            self._hash = hash((self.value.operator,
+                               tuple(ValueKey(o) for o in self.value.operands)))
         elif isinstance(self.value, Slice):
             self._hash = hash((ValueKey(self.value.value), self.value.start, self.value.end))
         elif isinstance(self.value, Part):
@@ -1513,7 +1519,7 @@ class ValueKey:
         elif isinstance(self.value, (ClockSignal, ResetSignal)):
             return self.value.domain == other.value.domain
         elif isinstance(self.value, Operator):
-            return (self.value.op == other.value.op and
+            return (self.value.operator == other.value.operator and
                     len(self.value.operands) == len(other.value.operands) and
                     all(ValueKey(a) == ValueKey(b)
                         for a, b in zip(self.value.operands, other.value.operands)))
index 4e3b9c922debc03bb4c894d0dc2752c5ce47c040..018b3687e3244f4ef51ea662754da84b3995bdcc 100644 (file)
@@ -157,7 +157,7 @@ class ValueTransformer(ValueVisitor):
         return value
 
     def on_Operator(self, value):
-        return Operator(value.op, [self.on_value(o) for o in value.operands])
+        return Operator(value.operator, [self.on_value(o) for o in value.operands])
 
     def on_Slice(self, value):
         return Slice(self.on_value(value.value), value.start, value.end)