fhdl.ir: fix incorrect uses of positive to say non-negative.
Also test Part and Slice properly.
This commit is contained in:
parent
9010805040
commit
f5e8c9033d
|
@ -236,7 +236,7 @@ class Const(Value):
|
||||||
shape = shape, self.value < 0
|
shape = shape, self.value < 0
|
||||||
self.nbits, self.signed = shape
|
self.nbits, self.signed = shape
|
||||||
if not isinstance(self.nbits, int) or self.nbits < 0:
|
if not isinstance(self.nbits, int) or self.nbits < 0:
|
||||||
raise TypeError("Width must be a positive integer")
|
raise TypeError("Width must be a non-negative integer")
|
||||||
self.value = self.normalize(self.value, shape)
|
self.value = self.normalize(self.value, shape)
|
||||||
|
|
||||||
def shape(self):
|
def shape(self):
|
||||||
|
@ -313,7 +313,7 @@ class Operator(Value):
|
||||||
return obs[0]
|
return obs[0]
|
||||||
elif self.op == "m":
|
elif self.op == "m":
|
||||||
return self._bitwise_binary_shape(obs[1], obs[2])
|
return self._bitwise_binary_shape(obs[1], obs[2])
|
||||||
raise NotImplementedError("Operator '{!r}' not implemented".format(self.op)) # :nocov:
|
raise NotImplementedError("Operator '{}' not implemented".format(self.op)) # :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)
|
||||||
|
@ -344,9 +344,9 @@ def Mux(sel, val1, val0):
|
||||||
class Slice(Value):
|
class Slice(Value):
|
||||||
def __init__(self, value, start, end):
|
def __init__(self, value, start, end):
|
||||||
if not isinstance(start, int):
|
if not isinstance(start, int):
|
||||||
raise TypeError("Slice start must be integer, not {!r}".format(start))
|
raise TypeError("Slice start must be an integer, not {!r}".format(start))
|
||||||
if not isinstance(end, int):
|
if not isinstance(end, int):
|
||||||
raise TypeError("Slice end must be integer, not {!r}".format(end))
|
raise TypeError("Slice end must be an integer, not {!r}".format(end))
|
||||||
|
|
||||||
n = len(value)
|
n = len(value)
|
||||||
if start not in range(-n, n):
|
if start not in range(-n, n):
|
||||||
|
@ -381,7 +381,7 @@ class Slice(Value):
|
||||||
class Part(Value):
|
class Part(Value):
|
||||||
def __init__(self, value, offset, width):
|
def __init__(self, value, offset, width):
|
||||||
if not isinstance(width, int) or width < 0:
|
if not isinstance(width, int) or width < 0:
|
||||||
raise TypeError("Part width must be a positive integer, not {!r}".format(width))
|
raise TypeError("Part width must be a non-negative integer, not {!r}".format(width))
|
||||||
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.value = value
|
self.value = value
|
||||||
|
@ -398,7 +398,7 @@ class Part(Value):
|
||||||
return self.value._rhs_signals()
|
return self.value._rhs_signals()
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "(part {} {})".format(repr(self.value), repr(self.offset), self.width)
|
return "(part {} {} {})".format(repr(self.value), repr(self.offset), self.width)
|
||||||
|
|
||||||
|
|
||||||
class Cat(Value):
|
class Cat(Value):
|
||||||
|
@ -464,7 +464,8 @@ class Repl(Value):
|
||||||
"""
|
"""
|
||||||
def __init__(self, value, count):
|
def __init__(self, value, count):
|
||||||
if not isinstance(count, int) or count < 0:
|
if not isinstance(count, int) or count < 0:
|
||||||
raise TypeError("Replication count must be a positive integer, not {!r}".format(count))
|
raise TypeError("Replication count must be a non-negative integer, not {!r}"
|
||||||
|
.format(count))
|
||||||
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.value = Value.wrap(value)
|
self.value = Value.wrap(value)
|
||||||
|
@ -557,7 +558,7 @@ class Signal(Value, DUID):
|
||||||
self.nbits, self.signed = shape
|
self.nbits, self.signed = shape
|
||||||
|
|
||||||
if not isinstance(self.nbits, int) or self.nbits < 0:
|
if not isinstance(self.nbits, int) or self.nbits < 0:
|
||||||
raise TypeError("Width must be a positive integer, not {!r}".format(self.nbits))
|
raise TypeError("Width must be a non-negative integer, not {!r}".format(self.nbits))
|
||||||
self.reset = int(reset)
|
self.reset = int(reset)
|
||||||
self.reset_less = bool(reset_less)
|
self.reset_less = bool(reset_less)
|
||||||
|
|
||||||
|
|
|
@ -64,9 +64,11 @@ class ConstTestCase(FHDLTestCase):
|
||||||
self.assertEqual(Const(10).shape(), (4, False))
|
self.assertEqual(Const(10).shape(), (4, False))
|
||||||
self.assertEqual(Const(-10).shape(), (5, True))
|
self.assertEqual(Const(-10).shape(), (5, True))
|
||||||
|
|
||||||
self.assertEqual(Const(1, 4).shape(), (4, False))
|
self.assertEqual(Const(1, 4).shape(), (4, False))
|
||||||
self.assertEqual(Const(1, (4, True)).shape(), (4, True))
|
self.assertEqual(Const(1, (4, True)).shape(), (4, True))
|
||||||
|
self.assertEqual(Const(0, (0, False)).shape(), (0, False))
|
||||||
|
|
||||||
|
def test_shape_bad(self):
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
Const(1, -1)
|
Const(1, -1)
|
||||||
|
|
||||||
|
@ -234,11 +236,53 @@ class SliceTestCase(FHDLTestCase):
|
||||||
s2 = Const(-10)[0:2]
|
s2 = Const(-10)[0:2]
|
||||||
self.assertEqual(s2.shape(), (2, False))
|
self.assertEqual(s2.shape(), (2, False))
|
||||||
|
|
||||||
|
def test_start_end_negative(self):
|
||||||
|
c = Const(0, 8)
|
||||||
|
s1 = Slice(c, 0, -1)
|
||||||
|
self.assertEqual((s1.start, s1.end), (0, 7))
|
||||||
|
s1 = Slice(c, -4, -1)
|
||||||
|
self.assertEqual((s1.start, s1.end), (4, 7))
|
||||||
|
|
||||||
|
def test_start_end_wrong(self):
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
Slice(0, "x", 1)
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
Slice(0, 1, "x")
|
||||||
|
|
||||||
|
def test_start_end_out_of_range(self):
|
||||||
|
c = Const(0, 8)
|
||||||
|
with self.assertRaises(IndexError):
|
||||||
|
Slice(c, 10, 12)
|
||||||
|
with self.assertRaises(IndexError):
|
||||||
|
Slice(c, 0, 12)
|
||||||
|
with self.assertRaises(IndexError):
|
||||||
|
Slice(c, 4, 2)
|
||||||
|
|
||||||
def test_repr(self):
|
def test_repr(self):
|
||||||
s1 = Const(10)[2]
|
s1 = Const(10)[2]
|
||||||
self.assertEqual(repr(s1), "(slice (const 4'd10) 2:3)")
|
self.assertEqual(repr(s1), "(slice (const 4'd10) 2:3)")
|
||||||
|
|
||||||
|
|
||||||
|
class PartTestCase(FHDLTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.c = Const(0, 8)
|
||||||
|
self.s = Signal(max=self.c.nbits)
|
||||||
|
|
||||||
|
def test_shape(self):
|
||||||
|
s1 = self.c.part(self.s, 2)
|
||||||
|
self.assertEqual(s1.shape(), (2, False))
|
||||||
|
s2 = self.c.part(self.s, 0)
|
||||||
|
self.assertEqual(s2.shape(), (0, False))
|
||||||
|
|
||||||
|
def test_width_bad(self):
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
self.c.part(self.s, -1)
|
||||||
|
|
||||||
|
def test_repr(self):
|
||||||
|
s = self.c.part(self.s, 2)
|
||||||
|
self.assertEqual(repr(s), "(part (const 8'd0) (sig s) 2)")
|
||||||
|
|
||||||
|
|
||||||
class CatTestCase(FHDLTestCase):
|
class CatTestCase(FHDLTestCase):
|
||||||
def test_shape(self):
|
def test_shape(self):
|
||||||
c1 = Cat(Const(10))
|
c1 = Cat(Const(10))
|
||||||
|
@ -255,8 +299,10 @@ class CatTestCase(FHDLTestCase):
|
||||||
|
|
||||||
class ReplTestCase(FHDLTestCase):
|
class ReplTestCase(FHDLTestCase):
|
||||||
def test_shape(self):
|
def test_shape(self):
|
||||||
r1 = Repl(Const(10), 3)
|
s1 = Repl(Const(10), 3)
|
||||||
self.assertEqual(r1.shape(), (12, False))
|
self.assertEqual(s1.shape(), (12, False))
|
||||||
|
s2 = Repl(Const(10), 0)
|
||||||
|
self.assertEqual(s2.shape(), (0, False))
|
||||||
|
|
||||||
def test_count_wrong(self):
|
def test_count_wrong(self):
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
|
@ -265,8 +311,8 @@ class ReplTestCase(FHDLTestCase):
|
||||||
Repl(Const(10), "str")
|
Repl(Const(10), "str")
|
||||||
|
|
||||||
def test_repr(self):
|
def test_repr(self):
|
||||||
r1 = Repl(Const(10), 3)
|
s = Repl(Const(10), 3)
|
||||||
self.assertEqual(repr(r1), "(repl (const 4'd10) 3)")
|
self.assertEqual(repr(s), "(repl (const 4'd10) 3)")
|
||||||
|
|
||||||
|
|
||||||
class SignalTestCase(FHDLTestCase):
|
class SignalTestCase(FHDLTestCase):
|
||||||
|
@ -287,7 +333,10 @@ class SignalTestCase(FHDLTestCase):
|
||||||
self.assertEqual(s7.shape(), (5, True))
|
self.assertEqual(s7.shape(), (5, True))
|
||||||
s8 = Signal(min=-20, max=16)
|
s8 = Signal(min=-20, max=16)
|
||||||
self.assertEqual(s8.shape(), (6, True))
|
self.assertEqual(s8.shape(), (6, True))
|
||||||
|
s9 = Signal(0)
|
||||||
|
self.assertEqual(s9.shape(), (0, False))
|
||||||
|
|
||||||
|
def test_shape_bad(self):
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
Signal(min=10, max=4)
|
Signal(min=10, max=4)
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
|
@ -326,8 +375,10 @@ class SignalTestCase(FHDLTestCase):
|
||||||
self.assertEqual(s3.reset_less, True)
|
self.assertEqual(s3.reset_less, True)
|
||||||
s4 = Signal.like(Signal(attrs={"no_retiming": True}))
|
s4 = Signal.like(Signal(attrs={"no_retiming": True}))
|
||||||
self.assertEqual(s4.attrs, {"no_retiming": True})
|
self.assertEqual(s4.attrs, {"no_retiming": True})
|
||||||
s5 = Signal.like(10)
|
s5 = Signal.like(Signal(decoder=str))
|
||||||
self.assertEqual(s5.shape(), (4, False))
|
self.assertEqual(s5.decoder, str)
|
||||||
|
s6 = Signal.like(10)
|
||||||
|
self.assertEqual(s6.shape(), (4, False))
|
||||||
|
|
||||||
|
|
||||||
class ClockSignalTestCase(FHDLTestCase):
|
class ClockSignalTestCase(FHDLTestCase):
|
||||||
|
@ -340,6 +391,9 @@ class ClockSignalTestCase(FHDLTestCase):
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
ClockSignal(1)
|
ClockSignal(1)
|
||||||
|
|
||||||
|
def test_shape(self):
|
||||||
|
self.assertEqual(ClockSignal().shape(), (1, False))
|
||||||
|
|
||||||
def test_repr(self):
|
def test_repr(self):
|
||||||
s1 = ClockSignal()
|
s1 = ClockSignal()
|
||||||
self.assertEqual(repr(s1), "(clk sync)")
|
self.assertEqual(repr(s1), "(clk sync)")
|
||||||
|
@ -355,6 +409,9 @@ class ResetSignalTestCase(FHDLTestCase):
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
ResetSignal(1)
|
ResetSignal(1)
|
||||||
|
|
||||||
|
def test_shape(self):
|
||||||
|
self.assertEqual(ResetSignal().shape(), (1, False))
|
||||||
|
|
||||||
def test_repr(self):
|
def test_repr(self):
|
||||||
s1 = ResetSignal()
|
s1 = ResetSignal()
|
||||||
self.assertEqual(repr(s1), "(rst sync)")
|
self.assertEqual(repr(s1), "(rst sync)")
|
Loading…
Reference in a new issue