hdl.ast: Operator.{op→operator}
Both "operator" and "operand" were shortened to "op" in different places in code, which caused confusion.
This commit is contained in:
parent
7ff4c6ce43
commit
fa1e466a65
|
@ -123,64 +123,64 @@ class _RHSValueCompiler(_ValueCompiler):
|
||||||
shape = value.shape()
|
shape = value.shape()
|
||||||
if len(value.operands) == 1:
|
if len(value.operands) == 1:
|
||||||
arg, = map(self, value.operands)
|
arg, = map(self, value.operands)
|
||||||
if value.op == "~":
|
if value.operator == "~":
|
||||||
return lambda state: normalize(~arg(state), shape)
|
return lambda state: normalize(~arg(state), shape)
|
||||||
if value.op == "-":
|
if value.operator == "-":
|
||||||
return lambda state: normalize(-arg(state), shape)
|
return lambda state: normalize(-arg(state), shape)
|
||||||
if value.op == "b":
|
if value.operator == "b":
|
||||||
return lambda state: normalize(bool(arg(state)), shape)
|
return lambda state: normalize(bool(arg(state)), shape)
|
||||||
if value.op == "r|":
|
if value.operator == "r|":
|
||||||
return lambda state: normalize(arg(state) != 0, shape)
|
return lambda state: normalize(arg(state) != 0, shape)
|
||||||
if value.op == "r&":
|
if value.operator == "r&":
|
||||||
val, = value.operands
|
val, = value.operands
|
||||||
mask = (1 << len(val)) - 1
|
mask = (1 << len(val)) - 1
|
||||||
return lambda state: normalize(arg(state) == mask, shape)
|
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.
|
# 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)
|
return lambda state: normalize(format(arg(state), "b").count("1") % 2, shape)
|
||||||
elif len(value.operands) == 2:
|
elif len(value.operands) == 2:
|
||||||
lhs, rhs = map(self, value.operands)
|
lhs, rhs = map(self, value.operands)
|
||||||
if value.op == "+":
|
if value.operator == "+":
|
||||||
return lambda state: normalize(lhs(state) + rhs(state), shape)
|
return lambda state: normalize(lhs(state) + rhs(state), shape)
|
||||||
if value.op == "-":
|
if value.operator == "-":
|
||||||
return lambda state: normalize(lhs(state) - rhs(state), shape)
|
return lambda state: normalize(lhs(state) - rhs(state), shape)
|
||||||
if value.op == "*":
|
if value.operator == "*":
|
||||||
return lambda state: normalize(lhs(state) * rhs(state), shape)
|
return lambda state: normalize(lhs(state) * rhs(state), shape)
|
||||||
if value.op == "//":
|
if value.operator == "//":
|
||||||
def floordiv(lhs, rhs):
|
def floordiv(lhs, rhs):
|
||||||
return 0 if rhs == 0 else lhs // rhs
|
return 0 if rhs == 0 else lhs // rhs
|
||||||
return lambda state: normalize(floordiv(lhs(state), rhs(state)), shape)
|
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)
|
return lambda state: normalize(lhs(state) & rhs(state), shape)
|
||||||
if value.op == "|":
|
if value.operator == "|":
|
||||||
return lambda state: normalize(lhs(state) | rhs(state), shape)
|
return lambda state: normalize(lhs(state) | rhs(state), shape)
|
||||||
if value.op == "^":
|
if value.operator == "^":
|
||||||
return lambda state: normalize(lhs(state) ^ rhs(state), shape)
|
return lambda state: normalize(lhs(state) ^ rhs(state), shape)
|
||||||
if value.op == "<<":
|
if value.operator == "<<":
|
||||||
def sshl(lhs, rhs):
|
def sshl(lhs, rhs):
|
||||||
return lhs << rhs if rhs >= 0 else lhs >> -rhs
|
return lhs << rhs if rhs >= 0 else lhs >> -rhs
|
||||||
return lambda state: normalize(sshl(lhs(state), rhs(state)), shape)
|
return lambda state: normalize(sshl(lhs(state), rhs(state)), shape)
|
||||||
if value.op == ">>":
|
if value.operator == ">>":
|
||||||
def sshr(lhs, rhs):
|
def sshr(lhs, rhs):
|
||||||
return lhs >> rhs if rhs >= 0 else lhs << -rhs
|
return lhs >> rhs if rhs >= 0 else lhs << -rhs
|
||||||
return lambda state: normalize(sshr(lhs(state), rhs(state)), shape)
|
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)
|
return lambda state: normalize(lhs(state) == rhs(state), shape)
|
||||||
if value.op == "!=":
|
if value.operator == "!=":
|
||||||
return lambda state: normalize(lhs(state) != rhs(state), shape)
|
return lambda state: normalize(lhs(state) != rhs(state), shape)
|
||||||
if value.op == "<":
|
if value.operator == "<":
|
||||||
return lambda state: normalize(lhs(state) < rhs(state), shape)
|
return lambda state: normalize(lhs(state) < rhs(state), shape)
|
||||||
if value.op == "<=":
|
if value.operator == "<=":
|
||||||
return lambda state: normalize(lhs(state) <= rhs(state), shape)
|
return lambda state: normalize(lhs(state) <= rhs(state), shape)
|
||||||
if value.op == ">":
|
if value.operator == ">":
|
||||||
return lambda state: normalize(lhs(state) > rhs(state), shape)
|
return lambda state: normalize(lhs(state) > rhs(state), shape)
|
||||||
if value.op == ">=":
|
if value.operator == ">=":
|
||||||
return lambda state: normalize(lhs(state) >= rhs(state), shape)
|
return lambda state: normalize(lhs(state) >= rhs(state), shape)
|
||||||
elif len(value.operands) == 3:
|
elif len(value.operands) == 3:
|
||||||
if value.op == "m":
|
if value.operator == "m":
|
||||||
sel, val1, val0 = map(self, value.operands)
|
sel, val1, val0 = map(self, value.operands)
|
||||||
return lambda state: val1(state) if sel(state) else val0(state)
|
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):
|
def on_Slice(self, value):
|
||||||
shape = value.shape()
|
shape = value.shape()
|
||||||
|
|
|
@ -452,7 +452,7 @@ class _RHSValueCompiler(_ValueCompiler):
|
||||||
arg_bits, arg_sign = arg.shape()
|
arg_bits, arg_sign = arg.shape()
|
||||||
res_bits, res_sign = value.shape()
|
res_bits, res_sign = value.shape()
|
||||||
res = self.s.rtlil.wire(width=res_bits, src=src(value.src_loc))
|
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),
|
"\\A": self(arg),
|
||||||
"\\Y": res,
|
"\\Y": res,
|
||||||
}, params={
|
}, params={
|
||||||
|
@ -485,7 +485,7 @@ class _RHSValueCompiler(_ValueCompiler):
|
||||||
lhs, rhs = value.operands
|
lhs, rhs = value.operands
|
||||||
lhs_bits, lhs_sign = lhs.shape()
|
lhs_bits, lhs_sign = lhs.shape()
|
||||||
rhs_bits, rhs_sign = rhs.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)
|
lhs_wire = self(lhs)
|
||||||
rhs_wire = self(rhs)
|
rhs_wire = self(rhs)
|
||||||
else:
|
else:
|
||||||
|
@ -494,7 +494,7 @@ class _RHSValueCompiler(_ValueCompiler):
|
||||||
rhs_wire = self.match_shape(rhs, rhs_bits, rhs_sign)
|
rhs_wire = self.match_shape(rhs, rhs_bits, rhs_sign)
|
||||||
res_bits, res_sign = value.shape()
|
res_bits, res_sign = value.shape()
|
||||||
res = self.s.rtlil.wire(width=res_bits, src=src(value.src_loc))
|
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,
|
"\\A": lhs_wire,
|
||||||
"\\B": rhs_wire,
|
"\\B": rhs_wire,
|
||||||
"\\Y": res,
|
"\\Y": res,
|
||||||
|
@ -505,7 +505,7 @@ class _RHSValueCompiler(_ValueCompiler):
|
||||||
"B_WIDTH": rhs_bits,
|
"B_WIDTH": rhs_bits,
|
||||||
"Y_WIDTH": res_bits,
|
"Y_WIDTH": res_bits,
|
||||||
}, src=src(value.src_loc))
|
}, 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.
|
# RTLIL leaves division by zero undefined, but we require it to return zero.
|
||||||
divmod_res = res
|
divmod_res = res
|
||||||
res = self.s.rtlil.wire(width=res_bits, src=src(value.src_loc))
|
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:
|
elif len(value.operands) == 2:
|
||||||
return self.on_Operator_binary(value)
|
return self.on_Operator_binary(value)
|
||||||
elif len(value.operands) == 3:
|
elif len(value.operands) == 3:
|
||||||
assert value.op == "m"
|
assert value.operator == "m"
|
||||||
return self.on_Operator_mux(value)
|
return self.on_Operator_mux(value)
|
||||||
else:
|
else:
|
||||||
raise TypeError # :nocov:
|
raise TypeError # :nocov:
|
||||||
|
|
|
@ -453,12 +453,18 @@ class AnySeq(AnyValue):
|
||||||
|
|
||||||
@final
|
@final
|
||||||
class Operator(Value):
|
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)
|
super().__init__(src_loc_at=1 + src_loc_at)
|
||||||
self.op = op
|
self.operator = operator
|
||||||
self.operands = [Value.cast(o) for o in operands]
|
self.operands = [Value.cast(op) for op in operands]
|
||||||
|
|
||||||
@staticmethod
|
# 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):
|
def _bitwise_binary_shape(a_shape, b_shape):
|
||||||
a_bits, a_sign = a_shape
|
a_bits, a_sign = a_shape
|
||||||
b_bits, b_sign = b_shape
|
b_bits, b_sign = b_shape
|
||||||
|
@ -475,57 +481,56 @@ class Operator(Value):
|
||||||
# first signed, second operand unsigned (add sign bit)
|
# first signed, second operand unsigned (add sign bit)
|
||||||
return max(a_bits, b_bits + 1), True
|
return max(a_bits, b_bits + 1), True
|
||||||
|
|
||||||
def shape(self):
|
|
||||||
op_shapes = list(map(lambda x: x.shape(), self.operands))
|
op_shapes = list(map(lambda x: x.shape(), self.operands))
|
||||||
if len(op_shapes) == 1:
|
if len(op_shapes) == 1:
|
||||||
(a_width, a_signed), = op_shapes
|
(a_width, a_signed), = op_shapes
|
||||||
if self.op in ("+", "~"):
|
if self.operator in ("+", "~"):
|
||||||
return a_width, a_signed
|
return a_width, a_signed
|
||||||
if self.op == "-":
|
if self.operator == "-":
|
||||||
if not a_signed:
|
if not a_signed:
|
||||||
return a_width + 1, True
|
return a_width + 1, True
|
||||||
else:
|
else:
|
||||||
return a_width, a_signed
|
return a_width, a_signed
|
||||||
if self.op in ("b", "r|", "r&", "r^"):
|
if self.operator in ("b", "r|", "r&", "r^"):
|
||||||
return 1, False
|
return 1, False
|
||||||
elif len(op_shapes) == 2:
|
elif len(op_shapes) == 2:
|
||||||
(a_width, a_signed), (b_width, b_signed) = op_shapes
|
(a_width, a_signed), (b_width, b_signed) = op_shapes
|
||||||
if self.op == "+" or self.op == "-":
|
if self.operator == "+" or self.operator == "-":
|
||||||
width, signed = self._bitwise_binary_shape(*op_shapes)
|
width, signed = _bitwise_binary_shape(*op_shapes)
|
||||||
return width + 1, signed
|
return width + 1, signed
|
||||||
if self.op == "*":
|
if self.operator == "*":
|
||||||
return a_width + b_width, a_signed or b_signed
|
return a_width + b_width, a_signed or b_signed
|
||||||
if self.op in ("//", "%"):
|
if self.operator in ("//", "%"):
|
||||||
assert not b_signed
|
assert not b_signed
|
||||||
return a_width, a_signed
|
return a_width, a_signed
|
||||||
if self.op in ("<", "<=", "==", "!=", ">", ">="):
|
if self.operator in ("<", "<=", "==", "!=", ">", ">="):
|
||||||
return 1, False
|
return 1, False
|
||||||
if self.op in ("&", "^", "|"):
|
if self.operator in ("&", "^", "|"):
|
||||||
return self._bitwise_binary_shape(*op_shapes)
|
return _bitwise_binary_shape(*op_shapes)
|
||||||
if self.op == "<<":
|
if self.operator == "<<":
|
||||||
if b_signed:
|
if b_signed:
|
||||||
extra = 2 ** (b_width - 1) - 1
|
extra = 2 ** (b_width - 1) - 1
|
||||||
else:
|
else:
|
||||||
extra = 2 ** (b_width) - 1
|
extra = 2 ** (b_width) - 1
|
||||||
return a_width + extra, a_signed
|
return a_width + extra, a_signed
|
||||||
if self.op == ">>":
|
if self.operator == ">>":
|
||||||
if b_signed:
|
if b_signed:
|
||||||
extra = 2 ** (b_width - 1)
|
extra = 2 ** (b_width - 1)
|
||||||
else:
|
else:
|
||||||
extra = 0
|
extra = 0
|
||||||
return a_width + extra, a_signed
|
return a_width + extra, a_signed
|
||||||
elif len(op_shapes) == 3:
|
elif len(op_shapes) == 3:
|
||||||
if self.op == "m":
|
if self.operator == "m":
|
||||||
s_shape, a_shape, b_shape = op_shapes
|
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"
|
raise NotImplementedError("Operator {}/{} not implemented"
|
||||||
.format(self.op, len(op_shapes))) # :nocov:
|
.format(self.operator, len(op_shapes))) # :nocov:
|
||||||
|
|
||||||
def _rhs_signals(self):
|
def _rhs_signals(self):
|
||||||
return union(op._rhs_signals() for op in self.operands)
|
return union(op._rhs_signals() for op in self.operands)
|
||||||
|
|
||||||
def __repr__(self):
|
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):
|
def Mux(sel, val1, val0):
|
||||||
|
@ -1478,7 +1483,8 @@ class ValueKey:
|
||||||
elif isinstance(self.value, (ClockSignal, ResetSignal)):
|
elif isinstance(self.value, (ClockSignal, ResetSignal)):
|
||||||
self._hash = hash(self.value.domain)
|
self._hash = hash(self.value.domain)
|
||||||
elif isinstance(self.value, Operator):
|
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):
|
elif isinstance(self.value, Slice):
|
||||||
self._hash = hash((ValueKey(self.value.value), self.value.start, self.value.end))
|
self._hash = hash((ValueKey(self.value.value), self.value.start, self.value.end))
|
||||||
elif isinstance(self.value, Part):
|
elif isinstance(self.value, Part):
|
||||||
|
@ -1513,7 +1519,7 @@ class ValueKey:
|
||||||
elif isinstance(self.value, (ClockSignal, ResetSignal)):
|
elif isinstance(self.value, (ClockSignal, ResetSignal)):
|
||||||
return self.value.domain == other.value.domain
|
return self.value.domain == other.value.domain
|
||||||
elif isinstance(self.value, Operator):
|
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
|
len(self.value.operands) == len(other.value.operands) and
|
||||||
all(ValueKey(a) == ValueKey(b)
|
all(ValueKey(a) == ValueKey(b)
|
||||||
for a, b in zip(self.value.operands, other.value.operands)))
|
for a, b in zip(self.value.operands, other.value.operands)))
|
||||||
|
|
|
@ -157,7 +157,7 @@ class ValueTransformer(ValueVisitor):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def on_Operator(self, 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):
|
def on_Slice(self, value):
|
||||||
return Slice(self.on_value(value.value), value.start, value.end)
|
return Slice(self.on_value(value.value), value.start, value.end)
|
||||||
|
|
Loading…
Reference in a new issue