hdl.ast: actually implement the // operator.
This commit is contained in:
parent
450d7efdf2
commit
1621ceb65a
|
@ -146,6 +146,10 @@ class _RHSValueCompiler(_ValueCompiler):
|
|||
return lambda state: normalize(lhs(state) - rhs(state), shape)
|
||||
if value.op == "*":
|
||||
return lambda state: normalize(lhs(state) * rhs(state), shape)
|
||||
if value.op == "//":
|
||||
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 == "&":
|
||||
return lambda state: normalize(lhs(state) & rhs(state), shape)
|
||||
if value.op == "|":
|
||||
|
|
|
@ -388,7 +388,7 @@ class _RHSValueCompiler(_ValueCompiler):
|
|||
(2, "+"): "$add",
|
||||
(2, "-"): "$sub",
|
||||
(2, "*"): "$mul",
|
||||
(2, "/"): "$div",
|
||||
(2, "//"): "$div",
|
||||
(2, "%"): "$mod",
|
||||
(2, "**"): "$pow",
|
||||
(2, "<<"): "$sshl",
|
||||
|
|
|
@ -87,10 +87,10 @@ class Value(metaclass=ABCMeta):
|
|||
return Operator("%", [self, other])
|
||||
def __rmod__(self, other):
|
||||
return Operator("%", [other, self])
|
||||
def __div__(self, other):
|
||||
return Operator("/", [self, other])
|
||||
def __rdiv__(self, other):
|
||||
return Operator("/", [other, self])
|
||||
def __floordiv__(self, other):
|
||||
return Operator("//", [self, other])
|
||||
def __rfloordiv__(self, other):
|
||||
return Operator("//", [other, self])
|
||||
def __lshift__(self, other):
|
||||
return Operator("<<", [self, other])
|
||||
def __rlshift__(self, other):
|
||||
|
@ -475,6 +475,9 @@ class Operator(Value):
|
|||
return width + 1, signed
|
||||
if self.op == "*":
|
||||
return a_width + b_width, a_signed or b_signed
|
||||
if self.op == "//":
|
||||
# division by -1 can overflow
|
||||
return a_width + b_signed, a_signed or b_signed
|
||||
if self.op == "%":
|
||||
return a_width, a_signed
|
||||
if self.op in ("<", "<=", "==", "!=", ">", ">="):
|
||||
|
|
|
@ -181,6 +181,17 @@ class OperatorTestCase(FHDLTestCase):
|
|||
v5 = 10 * Const(0, 4)
|
||||
self.assertEqual(v5.shape(), (8, False))
|
||||
|
||||
def test_floordiv(self):
|
||||
v1 = Const(0, (4, False)) // Const(0, (6, False))
|
||||
self.assertEqual(repr(v1), "(// (const 4'd0) (const 6'd0))")
|
||||
self.assertEqual(v1.shape(), (4, False))
|
||||
v2 = Const(0, (4, True)) // Const(0, (6, True))
|
||||
self.assertEqual(v2.shape(), (5, True))
|
||||
v3 = Const(0, (4, True)) // Const(0, (4, False))
|
||||
self.assertEqual(v3.shape(), (4, True))
|
||||
v5 = 10 // Const(0, 4)
|
||||
self.assertEqual(v5.shape(), (4, False))
|
||||
|
||||
def test_and(self):
|
||||
v1 = Const(0, (4, False)) & Const(0, (6, False))
|
||||
self.assertEqual(repr(v1), "(& (const 4'd0) (const 6'd0))")
|
||||
|
|
|
@ -95,6 +95,12 @@ class SimulatorUnitTestCase(FHDLTestCase):
|
|||
self.assertStatement(stmt, [C(2, 4), C(2, 4)], C(4, 8))
|
||||
self.assertStatement(stmt, [C(7, 4), C(7, 4)], C(49, 8))
|
||||
|
||||
def test_floordiv(self):
|
||||
stmt = lambda y, a, b: y.eq(a // b)
|
||||
self.assertStatement(stmt, [C(2, 4), C(1, 4)], C(2, 8))
|
||||
self.assertStatement(stmt, [C(2, 4), C(2, 4)], C(1, 8))
|
||||
self.assertStatement(stmt, [C(7, 4), C(2, 4)], C(3, 8))
|
||||
|
||||
def test_and(self):
|
||||
stmt = lambda y, a, b: y.eq(a & b)
|
||||
self.assertStatement(stmt, [C(0b1100, 4), C(0b1010, 4)], C(0b1000, 4))
|
||||
|
|
Loading…
Reference in a new issue