else:
return Cat(*matches).any()
- def rotate_left(self, offset):
+ def shift_left(self, amount):
+ """Shift left by constant amount.
+
+ Parameters
+ ----------
+ amount : int
+ Amount to shift by.
+
+ Returns
+ -------
+ Value, out
+ If the amount is positive, the input shifted left. Otherwise, the input shifted right.
+ """
+ if not isinstance(amount, int):
+ raise TypeError("Shift amount must be an integer, not {!r}".format(amount))
+ if amount < 0:
+ return self.shift_right(-amount)
+ if self.shape().signed:
+ return Cat(Const(0, amount), self).as_signed()
+ else:
+ return Cat(Const(0, amount), self) # unsigned
+
+ def shift_right(self, amount):
+ """Shift right by constant amount.
+
+ Parameters
+ ----------
+ amount : int
+ Amount to shift by.
+
+ Returns
+ -------
+ Value, out
+ If the amount is positive, the input shifted right. Otherwise, the input shifted left.
+ """
+ if not isinstance(amount, int):
+ raise TypeError("Shift amount must be an integer, not {!r}".format(amount))
+ if amount < 0:
+ return self.shift_left(-amount)
+ if self.shape().signed:
+ return self[amount:].as_signed()
+ else:
+ return self[amount:] # unsigned
+
+ def rotate_left(self, amount):
"""Rotate left by constant amount.
Parameters
----------
- offset : int
+ amount : int
Amount to rotate by.
Returns
-------
Value, out
- If the offset is positive, the input rotated left. Otherwise, the input rotated right.
+ If the amount is positive, the input rotated left. Otherwise, the input rotated right.
"""
- if not isinstance(offset, int):
- raise TypeError("Rotate amount must be an integer, not {!r}".format(offset))
- offset %= len(self)
- return Cat(self[-offset:], self[:-offset]) # meow :3
+ if not isinstance(amount, int):
+ raise TypeError("Rotate amount must be an integer, not {!r}".format(amount))
+ amount %= len(self)
+ return Cat(self[-amount:], self[:-amount]) # meow :3
- def rotate_right(self, offset):
+ def rotate_right(self, amount):
"""Rotate right by constant amount.
Parameters
----------
- offset : int
+ amount : int
Amount to rotate by.
Returns
-------
Value, out
- If the offset is positive, the input rotated right. Otherwise, the input rotated right.
+ If the amount is positive, the input rotated right. Otherwise, the input rotated right.
"""
- if not isinstance(offset, int):
- raise TypeError("Rotate amount must be an integer, not {!r}".format(offset))
- offset %= len(self)
- return Cat(self[offset:], self[:offset])
+ if not isinstance(amount, int):
+ raise TypeError("Rotate amount must be an integer, not {!r}".format(amount))
+ amount %= len(self)
+ return Cat(self[amount:], self[:amount])
def eq(self, value):
"""Assignment.
msg="Cannot index value with 'str'"):
Const(31)["str"]
+ def test_shift_left(self):
+ self.assertRepr(Const(256, unsigned(9)).shift_left(0),
+ "(cat (const 0'd0) (const 9'd256))")
+
+ self.assertRepr(Const(256, unsigned(9)).shift_left(1),
+ "(cat (const 1'd0) (const 9'd256))")
+ self.assertRepr(Const(256, unsigned(9)).shift_left(5),
+ "(cat (const 5'd0) (const 9'd256))")
+ self.assertRepr(Const(256, signed(9)).shift_left(1),
+ "(s (cat (const 1'd0) (const 9'sd-256)))")
+ self.assertRepr(Const(256, signed(9)).shift_left(5),
+ "(s (cat (const 5'd0) (const 9'sd-256)))")
+
+ self.assertRepr(Const(256, unsigned(9)).shift_left(-1),
+ "(slice (const 9'd256) 1:9)")
+ self.assertRepr(Const(256, unsigned(9)).shift_left(-5),
+ "(slice (const 9'd256) 5:9)")
+ self.assertRepr(Const(256, signed(9)).shift_left(-1),
+ "(s (slice (const 9'sd-256) 1:9))")
+ self.assertRepr(Const(256, signed(9)).shift_left(-5),
+ "(s (slice (const 9'sd-256) 5:9))")
+ self.assertRepr(Const(256, signed(9)).shift_left(-15),
+ "(s (slice (const 9'sd-256) 9:9))")
+
+ def test_shift_left_wrong(self):
+ with self.assertRaises(TypeError,
+ msg="Shift amount must be an integer, not 'str'"):
+ Const(31).shift_left("str")
+
+ def test_shift_right(self):
+ self.assertRepr(Const(256, unsigned(9)).shift_right(0),
+ "(slice (const 9'd256) 0:9)")
+
+ self.assertRepr(Const(256, unsigned(9)).shift_right(-1),
+ "(cat (const 1'd0) (const 9'd256))")
+ self.assertRepr(Const(256, unsigned(9)).shift_right(-5),
+ "(cat (const 5'd0) (const 9'd256))")
+ self.assertRepr(Const(256, signed(9)).shift_right(-1),
+ "(s (cat (const 1'd0) (const 9'sd-256)))")
+ self.assertRepr(Const(256, signed(9)).shift_right(-5),
+ "(s (cat (const 5'd0) (const 9'sd-256)))")
+
+ self.assertRepr(Const(256, unsigned(9)).shift_right(1),
+ "(slice (const 9'd256) 1:9)")
+ self.assertRepr(Const(256, unsigned(9)).shift_right(5),
+ "(slice (const 9'd256) 5:9)")
+ self.assertRepr(Const(256, signed(9)).shift_right(1),
+ "(s (slice (const 9'sd-256) 1:9))")
+ self.assertRepr(Const(256, signed(9)).shift_right(5),
+ "(s (slice (const 9'sd-256) 5:9))")
+ self.assertRepr(Const(256, signed(9)).shift_right(15),
+ "(s (slice (const 9'sd-256) 9:9))")
+
+ def test_shift_right_wrong(self):
+ with self.assertRaises(TypeError,
+ msg="Shift amount must be an integer, not 'str'"):
+ Const(31).shift_left("str")
+
def test_rotate_left(self):
- self.assertRepr(Value.cast(256).rotate_left(1), "(cat (slice (const 9'd256) 8:9) (slice (const 9'd256) 0:8))")
- self.assertRepr(Value.cast(256).rotate_left(7), "(cat (slice (const 9'd256) 2:9) (slice (const 9'd256) 0:2))")
- self.assertRepr(Value.cast(256).rotate_left(-1), "(cat (slice (const 9'd256) 1:9) (slice (const 9'd256) 0:1))")
- self.assertRepr(Value.cast(256).rotate_left(-7), "(cat (slice (const 9'd256) 7:9) (slice (const 9'd256) 0:7))")
+ self.assertRepr(Const(256).rotate_left(1),
+ "(cat (slice (const 9'd256) 8:9) (slice (const 9'd256) 0:8))")
+ self.assertRepr(Const(256).rotate_left(7),
+ "(cat (slice (const 9'd256) 2:9) (slice (const 9'd256) 0:2))")
+ self.assertRepr(Const(256).rotate_left(-1),
+ "(cat (slice (const 9'd256) 1:9) (slice (const 9'd256) 0:1))")
+ self.assertRepr(Const(256).rotate_left(-7),
+ "(cat (slice (const 9'd256) 7:9) (slice (const 9'd256) 0:7))")
def test_rotate_left_wrong(self):
with self.assertRaises(TypeError,
Const(31).rotate_left("str")
def test_rotate_right(self):
- self.assertRepr(Value.cast(256).rotate_right(1), "(cat (slice (const 9'd256) 1:9) (slice (const 9'd256) 0:1))")
- self.assertRepr(Value.cast(256).rotate_right(7), "(cat (slice (const 9'd256) 7:9) (slice (const 9'd256) 0:7))")
- self.assertRepr(Value.cast(256).rotate_right(-1), "(cat (slice (const 9'd256) 8:9) (slice (const 9'd256) 0:8))")
- self.assertRepr(Value.cast(256).rotate_right(-7), "(cat (slice (const 9'd256) 2:9) (slice (const 9'd256) 0:2))")
+ self.assertRepr(Const(256).rotate_right(1),
+ "(cat (slice (const 9'd256) 1:9) (slice (const 9'd256) 0:1))")
+ self.assertRepr(Const(256).rotate_right(7),
+ "(cat (slice (const 9'd256) 7:9) (slice (const 9'd256) 0:7))")
+ self.assertRepr(Const(256).rotate_right(-1),
+ "(cat (slice (const 9'd256) 8:9) (slice (const 9'd256) 0:8))")
+ self.assertRepr(Const(256).rotate_right(-7),
+ "(cat (slice (const 9'd256) 2:9) (slice (const 9'd256) 0:2))")
def test_rotate_right_wrong(self):
with self.assertRaises(TypeError,
msg="Rotate amount must be an integer, not 'str'"):
Const(31).rotate_right("str")
+
class ConstTestCase(FHDLTestCase):
def test_shape(self):
self.assertEqual(Const(0).shape(), unsigned(1))
for i in range(10):
self.assertStatement(stmt, [C(i)], C(0))
+ def test_shift_left(self):
+ stmt1 = lambda y, a: y.eq(a.shift_left(1))
+ self.assertStatement(stmt1, [C(0b10100010, 8)], C( 0b101000100, 9))
+ stmt2 = lambda y, a: y.eq(a.shift_left(4))
+ self.assertStatement(stmt2, [C(0b10100010, 8)], C(0b101000100000, 12))
+
+ def test_shift_right(self):
+ stmt1 = lambda y, a: y.eq(a.shift_right(1))
+ self.assertStatement(stmt1, [C(0b10100010, 8)], C(0b1010001, 7))
+ stmt2 = lambda y, a: y.eq(a.shift_right(4))
+ self.assertStatement(stmt2, [C(0b10100010, 8)], C( 0b1010, 4))
+
def test_rotate_left(self):
stmt = lambda y, a: y.eq(a.rotate_left(1))
self.assertStatement(stmt, [C(0b1)], C(0b1))