fhdl.ast: bits_sign→shape.
This commit is contained in:
parent
dc486ad8b9
commit
f0f4c0ce61
|
@ -285,8 +285,8 @@ class _ValueTransformer(xfrm.ValueTransformer):
|
||||||
|
|
||||||
def on_Operator_unary(self, node):
|
def on_Operator_unary(self, node):
|
||||||
arg, = node.operands
|
arg, = node.operands
|
||||||
arg_bits, arg_sign = arg.bits_sign()
|
arg_bits, arg_sign = arg.shape()
|
||||||
res_bits, res_sign = node.bits_sign()
|
res_bits, res_sign = node.shape()
|
||||||
res = self.rtlil.wire(width=res_bits)
|
res = self.rtlil.wire(width=res_bits)
|
||||||
self.rtlil.cell(self.operator_map[(1, node.op)], ports={
|
self.rtlil.cell(self.operator_map[(1, node.op)], ports={
|
||||||
"\\A": self(arg),
|
"\\A": self(arg),
|
||||||
|
@ -298,11 +298,11 @@ class _ValueTransformer(xfrm.ValueTransformer):
|
||||||
})
|
})
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def match_bits_sign(self, node, new_bits, new_sign):
|
def match_shape(self, node, new_bits, new_sign):
|
||||||
if isinstance(node, ast.Const):
|
if isinstance(node, ast.Const):
|
||||||
return self(ast.Const(node.value, (new_bits, new_sign)))
|
return self(ast.Const(node.value, (new_bits, new_sign)))
|
||||||
|
|
||||||
node_bits, node_sign = node.bits_sign()
|
node_bits, node_sign = node.shape()
|
||||||
if new_bits > node_bits:
|
if new_bits > node_bits:
|
||||||
res = self.rtlil.wire(width=new_bits)
|
res = self.rtlil.wire(width=new_bits)
|
||||||
self.rtlil.cell("$pos", ports={
|
self.rtlil.cell("$pos", ports={
|
||||||
|
@ -319,17 +319,17 @@ class _ValueTransformer(xfrm.ValueTransformer):
|
||||||
|
|
||||||
def on_Operator_binary(self, node):
|
def on_Operator_binary(self, node):
|
||||||
lhs, rhs = node.operands
|
lhs, rhs = node.operands
|
||||||
lhs_bits, lhs_sign = lhs.bits_sign()
|
lhs_bits, lhs_sign = lhs.shape()
|
||||||
rhs_bits, rhs_sign = rhs.bits_sign()
|
rhs_bits, rhs_sign = rhs.shape()
|
||||||
if lhs_sign == rhs_sign:
|
if lhs_sign == rhs_sign:
|
||||||
lhs_wire = self(lhs)
|
lhs_wire = self(lhs)
|
||||||
rhs_wire = self(rhs)
|
rhs_wire = self(rhs)
|
||||||
else:
|
else:
|
||||||
lhs_sign = rhs_sign = True
|
lhs_sign = rhs_sign = True
|
||||||
lhs_bits = rhs_bits = max(lhs_bits, rhs_bits)
|
lhs_bits = rhs_bits = max(lhs_bits, rhs_bits)
|
||||||
lhs_wire = self.match_bits_sign(lhs, lhs_bits, lhs_sign)
|
lhs_wire = self.match_shape(lhs, lhs_bits, lhs_sign)
|
||||||
rhs_wire = self.match_bits_sign(rhs, rhs_bits, rhs_sign)
|
rhs_wire = self.match_shape(rhs, rhs_bits, rhs_sign)
|
||||||
res_bits, res_sign = node.bits_sign()
|
res_bits, res_sign = node.shape()
|
||||||
res = self.rtlil.wire(width=res_bits)
|
res = self.rtlil.wire(width=res_bits)
|
||||||
self.rtlil.cell(self.operator_map[(2, node.op)], ports={
|
self.rtlil.cell(self.operator_map[(2, node.op)], ports={
|
||||||
"\\A": lhs_wire,
|
"\\A": lhs_wire,
|
||||||
|
@ -346,9 +346,9 @@ class _ValueTransformer(xfrm.ValueTransformer):
|
||||||
|
|
||||||
def on_Operator_mux(self, node):
|
def on_Operator_mux(self, node):
|
||||||
sel, lhs, rhs = node.operands
|
sel, lhs, rhs = node.operands
|
||||||
lhs_bits, lhs_sign = lhs.bits_sign()
|
lhs_bits, lhs_sign = lhs.shape()
|
||||||
rhs_bits, rhs_sign = rhs.bits_sign()
|
rhs_bits, rhs_sign = rhs.shape()
|
||||||
res_bits, res_sign = node.bits_sign()
|
res_bits, res_sign = node.shape()
|
||||||
res = self.rtlil.wire(width=res_bits)
|
res = self.rtlil.wire(width=res_bits)
|
||||||
self.rtlil.cell("$mux", ports={
|
self.rtlil.cell("$mux", ports={
|
||||||
"\\A": self(lhs),
|
"\\A": self(lhs),
|
||||||
|
@ -418,12 +418,12 @@ def convert_fragment(builder, fragment, name, clock_domains):
|
||||||
def _convert_stmts(case, stmts):
|
def _convert_stmts(case, stmts):
|
||||||
for stmt in stmts:
|
for stmt in stmts:
|
||||||
if isinstance(stmt, ast.Assign):
|
if isinstance(stmt, ast.Assign):
|
||||||
lhs_bits, lhs_sign = stmt.lhs.bits_sign()
|
lhs_bits, lhs_sign = stmt.lhs.shape()
|
||||||
rhs_bits, rhs_sign = stmt.rhs.bits_sign()
|
rhs_bits, rhs_sign = stmt.rhs.shape()
|
||||||
if lhs_bits == rhs_bits:
|
if lhs_bits == rhs_bits:
|
||||||
rhs_sigspec = xformer(stmt.rhs)
|
rhs_sigspec = xformer(stmt.rhs)
|
||||||
else:
|
else:
|
||||||
rhs_sigspec = xformer.match_bits_sign(
|
rhs_sigspec = xformer.match_shape(
|
||||||
stmt.rhs, lhs_bits, rhs_sign)
|
stmt.rhs, lhs_bits, rhs_sign)
|
||||||
with xformer.lhs():
|
with xformer.lhs():
|
||||||
lhs_sigspec = xformer(stmt.lhs)
|
lhs_sigspec = xformer(stmt.lhs)
|
||||||
|
|
|
@ -16,6 +16,6 @@ def bits_for(n, require_sign_bit=False):
|
||||||
return tools.bits_for(n, require_sign_bit)
|
return tools.bits_for(n, require_sign_bit)
|
||||||
|
|
||||||
|
|
||||||
@deprecated("instead of `value_bits_sign(v)`, use `v.bits_sign()`")
|
@deprecated("instead of `value_bits_sign(v)`, use `v.shape()`")
|
||||||
def value_bits_sign(v):
|
def value_bits_sign(v):
|
||||||
return ast.Value.wrap(v).bits_sign()
|
return ast.Value.wrap(v).shape()
|
||||||
|
|
|
@ -98,7 +98,7 @@ class Value:
|
||||||
return Operator(">=", [self, other])
|
return Operator(">=", [self, other])
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
return self.bits_sign()[0]
|
return self.shape()[0]
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
n = len(self)
|
n = len(self)
|
||||||
|
@ -160,7 +160,7 @@ class Value:
|
||||||
"""
|
"""
|
||||||
return Assign(self, value)
|
return Assign(self, value)
|
||||||
|
|
||||||
def bits_sign(self):
|
def shape(self):
|
||||||
"""Bit length and signedness of a value.
|
"""Bit length and signedness of a value.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
|
@ -171,9 +171,9 @@ class Value:
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
--------
|
--------
|
||||||
>>> Value.bits_sign(Signal(8))
|
>>> Value.shape(Signal(8))
|
||||||
8, False
|
8, False
|
||||||
>>> Value.bits_sign(C(0xaa))
|
>>> Value.shape(C(0xaa))
|
||||||
8, False
|
8, False
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError # :nocov:
|
raise NotImplementedError # :nocov:
|
||||||
|
@ -194,10 +194,10 @@ class Const(Value):
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
value : int
|
value : int
|
||||||
bits_sign : int or tuple or None
|
shape : int or tuple or None
|
||||||
Either an integer `bits` or a tuple `(bits, signed)`
|
Either an integer `bits` or a tuple `(bits, signed)`
|
||||||
specifying the number of bits in this `Const` and whether it is
|
specifying the number of bits in this `Const` and whether it is
|
||||||
signed (can represent negative values). `bits_sign` defaults
|
signed (can represent negative values). `shape` defaults
|
||||||
to the minimum width and signedness of `value`.
|
to the minimum width and signedness of `value`.
|
||||||
|
|
||||||
Attributes
|
Attributes
|
||||||
|
@ -205,17 +205,17 @@ class Const(Value):
|
||||||
nbits : int
|
nbits : int
|
||||||
signed : bool
|
signed : bool
|
||||||
"""
|
"""
|
||||||
def __init__(self, value, bits_sign=None):
|
def __init__(self, value, shape=None):
|
||||||
self.value = int(value)
|
self.value = int(value)
|
||||||
if bits_sign is None:
|
if shape is None:
|
||||||
bits_sign = self.value.bit_length(), self.value < 0
|
shape = self.value.bit_length(), self.value < 0
|
||||||
if isinstance(bits_sign, int):
|
if isinstance(shape, int):
|
||||||
bits_sign = bits_sign, self.value < 0
|
shape = shape, self.value < 0
|
||||||
self.nbits, self.signed = bits_sign
|
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 positive integer")
|
||||||
|
|
||||||
def bits_sign(self):
|
def shape(self):
|
||||||
return self.nbits, self.signed
|
return self.nbits, self.signed
|
||||||
|
|
||||||
def _rhs_signals(self):
|
def _rhs_signals(self):
|
||||||
|
@ -235,7 +235,7 @@ class Operator(Value):
|
||||||
self.operands = [Value.wrap(o) for o in operands]
|
self.operands = [Value.wrap(o) for o in operands]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _bitwise_binary_bits_sign(a, b):
|
def _bitwise_binary_shape(a, b):
|
||||||
if not a[1] and not b[1]:
|
if not a[1] and not b[1]:
|
||||||
# both operands unsigned
|
# both operands unsigned
|
||||||
return max(a[0], b[0]), False
|
return max(a[0], b[0]), False
|
||||||
|
@ -249,15 +249,15 @@ class Operator(Value):
|
||||||
# first signed, second operand unsigned (add sign bit)
|
# first signed, second operand unsigned (add sign bit)
|
||||||
return max(a[0], b[0] + 1), True
|
return max(a[0], b[0] + 1), True
|
||||||
|
|
||||||
def bits_sign(self):
|
def shape(self):
|
||||||
obs = list(map(lambda x: x.bits_sign(), self.operands))
|
obs = list(map(lambda x: x.shape(), self.operands))
|
||||||
if self.op == "+" or self.op == "-":
|
if self.op == "+" or self.op == "-":
|
||||||
if len(obs) == 1:
|
if len(obs) == 1:
|
||||||
if self.op == "-" and not obs[0][1]:
|
if self.op == "-" and not obs[0][1]:
|
||||||
return obs[0][0] + 1, True
|
return obs[0][0] + 1, True
|
||||||
else:
|
else:
|
||||||
return obs[0]
|
return obs[0]
|
||||||
n, s = self._bitwise_binary_bits_sign(*obs)
|
n, s = self._bitwise_binary_shape(*obs)
|
||||||
return n + 1, s
|
return n + 1, s
|
||||||
elif self.op == "*":
|
elif self.op == "*":
|
||||||
if not obs[0][1] and not obs[1][1]:
|
if not obs[0][1] and not obs[1][1]:
|
||||||
|
@ -282,14 +282,14 @@ class Operator(Value):
|
||||||
extra = 0
|
extra = 0
|
||||||
return obs[0][0] + extra, obs[0][1]
|
return obs[0][0] + extra, obs[0][1]
|
||||||
elif self.op == "&" or self.op == "^" or self.op == "|":
|
elif self.op == "&" or self.op == "^" or self.op == "|":
|
||||||
return self._bitwise_binary_bits_sign(*obs)
|
return self._bitwise_binary_shape(*obs)
|
||||||
elif (self.op == "<" or self.op == "<=" or self.op == "==" or self.op == "!=" or
|
elif (self.op == "<" or self.op == "<=" or self.op == "==" or self.op == "!=" or
|
||||||
self.op == ">" or self.op == ">=" or self.op == "b"):
|
self.op == ">" or self.op == ">=" or self.op == "b"):
|
||||||
return 1, False
|
return 1, False
|
||||||
elif self.op == "~":
|
elif self.op == "~":
|
||||||
return obs[0]
|
return obs[0]
|
||||||
elif self.op == "m":
|
elif self.op == "m":
|
||||||
return self._bitwise_binary_bits_sign(obs[1], obs[2])
|
return self._bitwise_binary_shape(obs[1], obs[2])
|
||||||
else:
|
else:
|
||||||
raise TypeError # :nocov:
|
raise TypeError # :nocov:
|
||||||
|
|
||||||
|
@ -341,7 +341,7 @@ class Slice(Value):
|
||||||
self.start = start
|
self.start = start
|
||||||
self.end = end
|
self.end = end
|
||||||
|
|
||||||
def bits_sign(self):
|
def shape(self):
|
||||||
return self.end - self.start, False
|
return self.end - self.start, False
|
||||||
|
|
||||||
def _lhs_signals(self):
|
def _lhs_signals(self):
|
||||||
|
@ -364,7 +364,7 @@ class Part(Value):
|
||||||
self.offset = Value.wrap(offset)
|
self.offset = Value.wrap(offset)
|
||||||
self.width = width
|
self.width = width
|
||||||
|
|
||||||
def bits_sign(self):
|
def shape(self):
|
||||||
return self.width, False
|
return self.width, False
|
||||||
|
|
||||||
def _lhs_signals(self):
|
def _lhs_signals(self):
|
||||||
|
@ -405,7 +405,7 @@ class Cat(Value):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.operands = [Value.wrap(v) for v in flatten(args)]
|
self.operands = [Value.wrap(v) for v in flatten(args)]
|
||||||
|
|
||||||
def bits_sign(self):
|
def shape(self):
|
||||||
return sum(len(op) for op in self.operands), False
|
return sum(len(op) for op in self.operands), False
|
||||||
|
|
||||||
def _lhs_signals(self):
|
def _lhs_signals(self):
|
||||||
|
@ -446,7 +446,7 @@ class Repl(Value):
|
||||||
self.value = Value.wrap(value)
|
self.value = Value.wrap(value)
|
||||||
self.count = count
|
self.count = count
|
||||||
|
|
||||||
def bits_sign(self):
|
def shape(self):
|
||||||
return len(self.value) * self.count, False
|
return len(self.value) * self.count, False
|
||||||
|
|
||||||
def _rhs_signals(self):
|
def _rhs_signals(self):
|
||||||
|
@ -461,10 +461,10 @@ class Signal(Value, DUID):
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
bits_sign : int or tuple or None
|
shape : int or tuple or None
|
||||||
Either an integer ``bits`` or a tuple ``(bits, signed)`` specifying the number of bits
|
Either an integer ``bits`` or a tuple ``(bits, signed)`` specifying the number of bits
|
||||||
in this ``Signal`` and whether it is signed (can represent negative values).
|
in this ``Signal`` and whether it is signed (can represent negative values).
|
||||||
``bits_sign`` defaults to 1-bit and non-signed.
|
``shape`` defaults to 1-bit and non-signed.
|
||||||
name : str
|
name : str
|
||||||
Name hint for this signal. If ``None`` (default) the name is inferred from the variable
|
Name hint for this signal. If ``None`` (default) the name is inferred from the variable
|
||||||
name this ``Signal`` is assigned to. Name collisions are automatically resolved by
|
name this ``Signal`` is assigned to. Name collisions are automatically resolved by
|
||||||
|
@ -482,9 +482,9 @@ class Signal(Value, DUID):
|
||||||
Defaults to ``False``.
|
Defaults to ``False``.
|
||||||
min : int or None
|
min : int or None
|
||||||
max : int or None
|
max : int or None
|
||||||
If `bits_sign` is `None`, the signal bit width and signedness are
|
If ``shape`` is ``None``, the signal bit width and signedness are
|
||||||
determined by the integer range given by `min` (inclusive,
|
determined by the integer range given by ``min`` (inclusive,
|
||||||
defaults to 0) and `max` (exclusive, defaults to 2).
|
defaults to 0) and ``max`` (exclusive, defaults to 2).
|
||||||
attrs : dict
|
attrs : dict
|
||||||
Dictionary of synthesis attributes.
|
Dictionary of synthesis attributes.
|
||||||
|
|
||||||
|
@ -498,7 +498,7 @@ class Signal(Value, DUID):
|
||||||
attrs : dict
|
attrs : dict
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, bits_sign=None, name=None, reset=0, reset_less=False, min=None, max=None,
|
def __init__(self, shape=None, name=None, reset=0, reset_less=False, min=None, max=None,
|
||||||
attrs=None):
|
attrs=None):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
|
@ -509,7 +509,7 @@ class Signal(Value, DUID):
|
||||||
name = "$signal"
|
name = "$signal"
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
if bits_sign is None:
|
if shape is None:
|
||||||
if min is None:
|
if min is None:
|
||||||
min = 0
|
min = 0
|
||||||
if max is None:
|
if max is None:
|
||||||
|
@ -524,10 +524,10 @@ class Signal(Value, DUID):
|
||||||
else:
|
else:
|
||||||
if not (min is None and max is None):
|
if not (min is None and max is None):
|
||||||
raise ValueError("Only one of bits/signedness or bounds may be specified")
|
raise ValueError("Only one of bits/signedness or bounds may be specified")
|
||||||
if isinstance(bits_sign, int):
|
if isinstance(shape, int):
|
||||||
self.nbits, self.signed = bits_sign, False
|
self.nbits, self.signed = shape, False
|
||||||
else:
|
else:
|
||||||
self.nbits, self.signed = bits_sign
|
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 positive integer, not {!r}".format(self.nbits))
|
||||||
|
@ -545,13 +545,13 @@ class Signal(Value, DUID):
|
||||||
other : Value
|
other : Value
|
||||||
Object to base this Signal on.
|
Object to base this Signal on.
|
||||||
"""
|
"""
|
||||||
kw = dict(bits_sign=cls.wrap(other).bits_sign())
|
kw = dict(shape=cls.wrap(other).shape())
|
||||||
if isinstance(other, cls):
|
if isinstance(other, cls):
|
||||||
kw.update(reset=other.reset, reset_less=other.reset_less, attrs=other.attrs)
|
kw.update(reset=other.reset, reset_less=other.reset_less, attrs=other.attrs)
|
||||||
kw.update(kwargs)
|
kw.update(kwargs)
|
||||||
return cls(**kw)
|
return cls(**kw)
|
||||||
|
|
||||||
def bits_sign(self):
|
def shape(self):
|
||||||
return self.nbits, self.signed
|
return self.nbits, self.signed
|
||||||
|
|
||||||
def _lhs_signals(self):
|
def _lhs_signals(self):
|
||||||
|
|
|
@ -10,8 +10,8 @@ class MultiReg:
|
||||||
self.o = o
|
self.o = o
|
||||||
self.odomain = odomain
|
self.odomain = odomain
|
||||||
|
|
||||||
self._regs = [Signal(self.i.bits_sign(), name="cdc{}".format(i),
|
self._regs = [Signal(self.i.shape(), name="cdc{}".format(i), reset=reset, reset_less=True,
|
||||||
reset=reset, reset_less=True, attrs={"no_retiming": True})
|
attrs={"no_retiming": True})
|
||||||
for i in range(n)]
|
for i in range(n)]
|
||||||
|
|
||||||
def get_fragment(self, platform):
|
def get_fragment(self, platform):
|
||||||
|
|
|
@ -59,14 +59,14 @@ class ValueTestCase(unittest.TestCase):
|
||||||
|
|
||||||
|
|
||||||
class ConstTestCase(unittest.TestCase):
|
class ConstTestCase(unittest.TestCase):
|
||||||
def test_bits_sign(self):
|
def test_shape(self):
|
||||||
self.assertEqual(Const(0).bits_sign(), (0, False))
|
self.assertEqual(Const(0).shape(), (0, False))
|
||||||
self.assertEqual(Const(1).bits_sign(), (1, False))
|
self.assertEqual(Const(1).shape(), (1, False))
|
||||||
self.assertEqual(Const(10).bits_sign(), (4, False))
|
self.assertEqual(Const(10).shape(), (4, False))
|
||||||
self.assertEqual(Const(-10).bits_sign(), (4, True))
|
self.assertEqual(Const(-10).shape(), (4, True))
|
||||||
|
|
||||||
self.assertEqual(Const(1, 4).bits_sign(), (4, False))
|
self.assertEqual(Const(1, 4).shape(), (4, False))
|
||||||
self.assertEqual(Const(1, (4, True)).bits_sign(), (4, True))
|
self.assertEqual(Const(1, (4, True)).shape(), (4, True))
|
||||||
|
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
Const(1, -1)
|
Const(1, -1)
|
||||||
|
@ -87,138 +87,138 @@ class OperatorTestCase(unittest.TestCase):
|
||||||
def test_invert(self):
|
def test_invert(self):
|
||||||
v = ~Const(0, 4)
|
v = ~Const(0, 4)
|
||||||
self.assertEqual(repr(v), "(~ (const 4'd0))")
|
self.assertEqual(repr(v), "(~ (const 4'd0))")
|
||||||
self.assertEqual(v.bits_sign(), (4, False))
|
self.assertEqual(v.shape(), (4, False))
|
||||||
|
|
||||||
def test_neg(self):
|
def test_neg(self):
|
||||||
v1 = -Const(0, (4, False))
|
v1 = -Const(0, (4, False))
|
||||||
self.assertEqual(repr(v1), "(- (const 4'd0))")
|
self.assertEqual(repr(v1), "(- (const 4'd0))")
|
||||||
self.assertEqual(v1.bits_sign(), (5, True))
|
self.assertEqual(v1.shape(), (5, True))
|
||||||
v2 = -Const(0, (4, True))
|
v2 = -Const(0, (4, True))
|
||||||
self.assertEqual(repr(v2), "(- (const 4'sd0))")
|
self.assertEqual(repr(v2), "(- (const 4'sd0))")
|
||||||
self.assertEqual(v2.bits_sign(), (4, True))
|
self.assertEqual(v2.shape(), (4, True))
|
||||||
|
|
||||||
def test_add(self):
|
def test_add(self):
|
||||||
v1 = Const(0, (4, False)) + Const(0, (6, False))
|
v1 = Const(0, (4, False)) + Const(0, (6, False))
|
||||||
self.assertEqual(repr(v1), "(+ (const 4'd0) (const 6'd0))")
|
self.assertEqual(repr(v1), "(+ (const 4'd0) (const 6'd0))")
|
||||||
self.assertEqual(v1.bits_sign(), (7, False))
|
self.assertEqual(v1.shape(), (7, False))
|
||||||
v2 = Const(0, (4, True)) + Const(0, (6, True))
|
v2 = Const(0, (4, True)) + Const(0, (6, True))
|
||||||
self.assertEqual(v2.bits_sign(), (7, True))
|
self.assertEqual(v2.shape(), (7, True))
|
||||||
v3 = Const(0, (4, True)) + Const(0, (4, False))
|
v3 = Const(0, (4, True)) + Const(0, (4, False))
|
||||||
self.assertEqual(v3.bits_sign(), (6, True))
|
self.assertEqual(v3.shape(), (6, True))
|
||||||
v4 = Const(0, (4, False)) + Const(0, (4, True))
|
v4 = Const(0, (4, False)) + Const(0, (4, True))
|
||||||
self.assertEqual(v4.bits_sign(), (6, True))
|
self.assertEqual(v4.shape(), (6, True))
|
||||||
v5 = 10 + Const(0, 4)
|
v5 = 10 + Const(0, 4)
|
||||||
self.assertEqual(v5.bits_sign(), (5, False))
|
self.assertEqual(v5.shape(), (5, False))
|
||||||
|
|
||||||
def test_sub(self):
|
def test_sub(self):
|
||||||
v1 = Const(0, (4, False)) - Const(0, (6, False))
|
v1 = Const(0, (4, False)) - Const(0, (6, False))
|
||||||
self.assertEqual(repr(v1), "(- (const 4'd0) (const 6'd0))")
|
self.assertEqual(repr(v1), "(- (const 4'd0) (const 6'd0))")
|
||||||
self.assertEqual(v1.bits_sign(), (7, False))
|
self.assertEqual(v1.shape(), (7, False))
|
||||||
v2 = Const(0, (4, True)) - Const(0, (6, True))
|
v2 = Const(0, (4, True)) - Const(0, (6, True))
|
||||||
self.assertEqual(v2.bits_sign(), (7, True))
|
self.assertEqual(v2.shape(), (7, True))
|
||||||
v3 = Const(0, (4, True)) - Const(0, (4, False))
|
v3 = Const(0, (4, True)) - Const(0, (4, False))
|
||||||
self.assertEqual(v3.bits_sign(), (6, True))
|
self.assertEqual(v3.shape(), (6, True))
|
||||||
v4 = Const(0, (4, False)) - Const(0, (4, True))
|
v4 = Const(0, (4, False)) - Const(0, (4, True))
|
||||||
self.assertEqual(v4.bits_sign(), (6, True))
|
self.assertEqual(v4.shape(), (6, True))
|
||||||
v5 = 10 - Const(0, 4)
|
v5 = 10 - Const(0, 4)
|
||||||
self.assertEqual(v5.bits_sign(), (5, False))
|
self.assertEqual(v5.shape(), (5, False))
|
||||||
|
|
||||||
def test_mul(self):
|
def test_mul(self):
|
||||||
v1 = Const(0, (4, False)) * Const(0, (6, False))
|
v1 = Const(0, (4, False)) * Const(0, (6, False))
|
||||||
self.assertEqual(repr(v1), "(* (const 4'd0) (const 6'd0))")
|
self.assertEqual(repr(v1), "(* (const 4'd0) (const 6'd0))")
|
||||||
self.assertEqual(v1.bits_sign(), (10, False))
|
self.assertEqual(v1.shape(), (10, False))
|
||||||
v2 = Const(0, (4, True)) * Const(0, (6, True))
|
v2 = Const(0, (4, True)) * Const(0, (6, True))
|
||||||
self.assertEqual(v2.bits_sign(), (9, True))
|
self.assertEqual(v2.shape(), (9, True))
|
||||||
v3 = Const(0, (4, True)) * Const(0, (4, False))
|
v3 = Const(0, (4, True)) * Const(0, (4, False))
|
||||||
self.assertEqual(v3.bits_sign(), (8, True))
|
self.assertEqual(v3.shape(), (8, True))
|
||||||
v5 = 10 * Const(0, 4)
|
v5 = 10 * Const(0, 4)
|
||||||
self.assertEqual(v5.bits_sign(), (8, False))
|
self.assertEqual(v5.shape(), (8, False))
|
||||||
|
|
||||||
def test_and(self):
|
def test_and(self):
|
||||||
v1 = Const(0, (4, False)) & Const(0, (6, False))
|
v1 = Const(0, (4, False)) & Const(0, (6, False))
|
||||||
self.assertEqual(repr(v1), "(& (const 4'd0) (const 6'd0))")
|
self.assertEqual(repr(v1), "(& (const 4'd0) (const 6'd0))")
|
||||||
self.assertEqual(v1.bits_sign(), (6, False))
|
self.assertEqual(v1.shape(), (6, False))
|
||||||
v2 = Const(0, (4, True)) & Const(0, (6, True))
|
v2 = Const(0, (4, True)) & Const(0, (6, True))
|
||||||
self.assertEqual(v2.bits_sign(), (6, True))
|
self.assertEqual(v2.shape(), (6, True))
|
||||||
v3 = Const(0, (4, True)) & Const(0, (4, False))
|
v3 = Const(0, (4, True)) & Const(0, (4, False))
|
||||||
self.assertEqual(v3.bits_sign(), (5, True))
|
self.assertEqual(v3.shape(), (5, True))
|
||||||
v4 = Const(0, (4, False)) & Const(0, (4, True))
|
v4 = Const(0, (4, False)) & Const(0, (4, True))
|
||||||
self.assertEqual(v4.bits_sign(), (5, True))
|
self.assertEqual(v4.shape(), (5, True))
|
||||||
v5 = 10 & Const(0, 4)
|
v5 = 10 & Const(0, 4)
|
||||||
self.assertEqual(v5.bits_sign(), (4, False))
|
self.assertEqual(v5.shape(), (4, False))
|
||||||
|
|
||||||
def test_or(self):
|
def test_or(self):
|
||||||
v1 = Const(0, (4, False)) | Const(0, (6, False))
|
v1 = Const(0, (4, False)) | Const(0, (6, False))
|
||||||
self.assertEqual(repr(v1), "(| (const 4'd0) (const 6'd0))")
|
self.assertEqual(repr(v1), "(| (const 4'd0) (const 6'd0))")
|
||||||
self.assertEqual(v1.bits_sign(), (6, False))
|
self.assertEqual(v1.shape(), (6, False))
|
||||||
v2 = Const(0, (4, True)) | Const(0, (6, True))
|
v2 = Const(0, (4, True)) | Const(0, (6, True))
|
||||||
self.assertEqual(v2.bits_sign(), (6, True))
|
self.assertEqual(v2.shape(), (6, True))
|
||||||
v3 = Const(0, (4, True)) | Const(0, (4, False))
|
v3 = Const(0, (4, True)) | Const(0, (4, False))
|
||||||
self.assertEqual(v3.bits_sign(), (5, True))
|
self.assertEqual(v3.shape(), (5, True))
|
||||||
v4 = Const(0, (4, False)) | Const(0, (4, True))
|
v4 = Const(0, (4, False)) | Const(0, (4, True))
|
||||||
self.assertEqual(v4.bits_sign(), (5, True))
|
self.assertEqual(v4.shape(), (5, True))
|
||||||
v5 = 10 | Const(0, 4)
|
v5 = 10 | Const(0, 4)
|
||||||
self.assertEqual(v5.bits_sign(), (4, False))
|
self.assertEqual(v5.shape(), (4, False))
|
||||||
|
|
||||||
def test_xor(self):
|
def test_xor(self):
|
||||||
v1 = Const(0, (4, False)) ^ Const(0, (6, False))
|
v1 = Const(0, (4, False)) ^ Const(0, (6, False))
|
||||||
self.assertEqual(repr(v1), "(^ (const 4'd0) (const 6'd0))")
|
self.assertEqual(repr(v1), "(^ (const 4'd0) (const 6'd0))")
|
||||||
self.assertEqual(v1.bits_sign(), (6, False))
|
self.assertEqual(v1.shape(), (6, False))
|
||||||
v2 = Const(0, (4, True)) ^ Const(0, (6, True))
|
v2 = Const(0, (4, True)) ^ Const(0, (6, True))
|
||||||
self.assertEqual(v2.bits_sign(), (6, True))
|
self.assertEqual(v2.shape(), (6, True))
|
||||||
v3 = Const(0, (4, True)) ^ Const(0, (4, False))
|
v3 = Const(0, (4, True)) ^ Const(0, (4, False))
|
||||||
self.assertEqual(v3.bits_sign(), (5, True))
|
self.assertEqual(v3.shape(), (5, True))
|
||||||
v4 = Const(0, (4, False)) ^ Const(0, (4, True))
|
v4 = Const(0, (4, False)) ^ Const(0, (4, True))
|
||||||
self.assertEqual(v4.bits_sign(), (5, True))
|
self.assertEqual(v4.shape(), (5, True))
|
||||||
v5 = 10 ^ Const(0, 4)
|
v5 = 10 ^ Const(0, 4)
|
||||||
self.assertEqual(v5.bits_sign(), (4, False))
|
self.assertEqual(v5.shape(), (4, False))
|
||||||
|
|
||||||
def test_lt(self):
|
def test_lt(self):
|
||||||
v = Const(0, 4) < Const(0, 6)
|
v = Const(0, 4) < Const(0, 6)
|
||||||
self.assertEqual(repr(v), "(< (const 4'd0) (const 6'd0))")
|
self.assertEqual(repr(v), "(< (const 4'd0) (const 6'd0))")
|
||||||
self.assertEqual(v.bits_sign(), (1, False))
|
self.assertEqual(v.shape(), (1, False))
|
||||||
|
|
||||||
def test_le(self):
|
def test_le(self):
|
||||||
v = Const(0, 4) <= Const(0, 6)
|
v = Const(0, 4) <= Const(0, 6)
|
||||||
self.assertEqual(repr(v), "(<= (const 4'd0) (const 6'd0))")
|
self.assertEqual(repr(v), "(<= (const 4'd0) (const 6'd0))")
|
||||||
self.assertEqual(v.bits_sign(), (1, False))
|
self.assertEqual(v.shape(), (1, False))
|
||||||
|
|
||||||
def test_gt(self):
|
def test_gt(self):
|
||||||
v = Const(0, 4) > Const(0, 6)
|
v = Const(0, 4) > Const(0, 6)
|
||||||
self.assertEqual(repr(v), "(> (const 4'd0) (const 6'd0))")
|
self.assertEqual(repr(v), "(> (const 4'd0) (const 6'd0))")
|
||||||
self.assertEqual(v.bits_sign(), (1, False))
|
self.assertEqual(v.shape(), (1, False))
|
||||||
|
|
||||||
def test_ge(self):
|
def test_ge(self):
|
||||||
v = Const(0, 4) >= Const(0, 6)
|
v = Const(0, 4) >= Const(0, 6)
|
||||||
self.assertEqual(repr(v), "(>= (const 4'd0) (const 6'd0))")
|
self.assertEqual(repr(v), "(>= (const 4'd0) (const 6'd0))")
|
||||||
self.assertEqual(v.bits_sign(), (1, False))
|
self.assertEqual(v.shape(), (1, False))
|
||||||
|
|
||||||
def test_eq(self):
|
def test_eq(self):
|
||||||
v = Const(0, 4) == Const(0, 6)
|
v = Const(0, 4) == Const(0, 6)
|
||||||
self.assertEqual(repr(v), "(== (const 4'd0) (const 6'd0))")
|
self.assertEqual(repr(v), "(== (const 4'd0) (const 6'd0))")
|
||||||
self.assertEqual(v.bits_sign(), (1, False))
|
self.assertEqual(v.shape(), (1, False))
|
||||||
|
|
||||||
def test_ne(self):
|
def test_ne(self):
|
||||||
v = Const(0, 4) != Const(0, 6)
|
v = Const(0, 4) != Const(0, 6)
|
||||||
self.assertEqual(repr(v), "(!= (const 4'd0) (const 6'd0))")
|
self.assertEqual(repr(v), "(!= (const 4'd0) (const 6'd0))")
|
||||||
self.assertEqual(v.bits_sign(), (1, False))
|
self.assertEqual(v.shape(), (1, False))
|
||||||
|
|
||||||
def test_mux(self):
|
def test_mux(self):
|
||||||
s = Const(0)
|
s = Const(0)
|
||||||
v1 = Mux(s, Const(0, (4, False)), Const(0, (6, False)))
|
v1 = Mux(s, Const(0, (4, False)), Const(0, (6, False)))
|
||||||
self.assertEqual(repr(v1), "(m (const 0'd0) (const 4'd0) (const 6'd0))")
|
self.assertEqual(repr(v1), "(m (const 0'd0) (const 4'd0) (const 6'd0))")
|
||||||
self.assertEqual(v1.bits_sign(), (6, False))
|
self.assertEqual(v1.shape(), (6, False))
|
||||||
v2 = Mux(s, Const(0, (4, True)), Const(0, (6, True)))
|
v2 = Mux(s, Const(0, (4, True)), Const(0, (6, True)))
|
||||||
self.assertEqual(v2.bits_sign(), (6, True))
|
self.assertEqual(v2.shape(), (6, True))
|
||||||
v3 = Mux(s, Const(0, (4, True)), Const(0, (4, False)))
|
v3 = Mux(s, Const(0, (4, True)), Const(0, (4, False)))
|
||||||
self.assertEqual(v3.bits_sign(), (5, True))
|
self.assertEqual(v3.shape(), (5, True))
|
||||||
v4 = Mux(s, Const(0, (4, False)), Const(0, (4, True)))
|
v4 = Mux(s, Const(0, (4, False)), Const(0, (4, True)))
|
||||||
self.assertEqual(v4.bits_sign(), (5, True))
|
self.assertEqual(v4.shape(), (5, True))
|
||||||
|
|
||||||
def test_bool(self):
|
def test_bool(self):
|
||||||
v = Const(0).bool()
|
v = Const(0).bool()
|
||||||
self.assertEqual(repr(v), "(b (const 0'd0))")
|
self.assertEqual(repr(v), "(b (const 0'd0))")
|
||||||
self.assertEqual(v.bits_sign(), (1, False))
|
self.assertEqual(v.shape(), (1, False))
|
||||||
|
|
||||||
def test_hash(self):
|
def test_hash(self):
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
|
@ -226,11 +226,11 @@ class OperatorTestCase(unittest.TestCase):
|
||||||
|
|
||||||
|
|
||||||
class SliceTestCase(unittest.TestCase):
|
class SliceTestCase(unittest.TestCase):
|
||||||
def test_bits_sign(self):
|
def test_shape(self):
|
||||||
s1 = Const(10)[2]
|
s1 = Const(10)[2]
|
||||||
self.assertEqual(s1.bits_sign(), (1, False))
|
self.assertEqual(s1.shape(), (1, False))
|
||||||
s2 = Const(-10)[0:2]
|
s2 = Const(-10)[0:2]
|
||||||
self.assertEqual(s2.bits_sign(), (2, False))
|
self.assertEqual(s2.shape(), (2, False))
|
||||||
|
|
||||||
def test_repr(self):
|
def test_repr(self):
|
||||||
s1 = Const(10)[2]
|
s1 = Const(10)[2]
|
||||||
|
@ -238,13 +238,13 @@ class SliceTestCase(unittest.TestCase):
|
||||||
|
|
||||||
|
|
||||||
class CatTestCase(unittest.TestCase):
|
class CatTestCase(unittest.TestCase):
|
||||||
def test_bits_sign(self):
|
def test_shape(self):
|
||||||
c1 = Cat(Const(10))
|
c1 = Cat(Const(10))
|
||||||
self.assertEqual(c1.bits_sign(), (4, False))
|
self.assertEqual(c1.shape(), (4, False))
|
||||||
c2 = Cat(Const(10), Const(1))
|
c2 = Cat(Const(10), Const(1))
|
||||||
self.assertEqual(c2.bits_sign(), (5, False))
|
self.assertEqual(c2.shape(), (5, False))
|
||||||
c3 = Cat(Const(10), Const(1), Const(0))
|
c3 = Cat(Const(10), Const(1), Const(0))
|
||||||
self.assertEqual(c3.bits_sign(), (5, False))
|
self.assertEqual(c3.shape(), (5, False))
|
||||||
|
|
||||||
def test_repr(self):
|
def test_repr(self):
|
||||||
c1 = Cat(Const(10), Const(1))
|
c1 = Cat(Const(10), Const(1))
|
||||||
|
@ -252,9 +252,9 @@ class CatTestCase(unittest.TestCase):
|
||||||
|
|
||||||
|
|
||||||
class ReplTestCase(unittest.TestCase):
|
class ReplTestCase(unittest.TestCase):
|
||||||
def test_bits_sign(self):
|
def test_shape(self):
|
||||||
r1 = Repl(Const(10), 3)
|
r1 = Repl(Const(10), 3)
|
||||||
self.assertEqual(r1.bits_sign(), (12, False))
|
self.assertEqual(r1.shape(), (12, False))
|
||||||
|
|
||||||
def test_count_wrong(self):
|
def test_count_wrong(self):
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
|
@ -268,23 +268,23 @@ class ReplTestCase(unittest.TestCase):
|
||||||
|
|
||||||
|
|
||||||
class SignalTestCase(unittest.TestCase):
|
class SignalTestCase(unittest.TestCase):
|
||||||
def test_bits_sign(self):
|
def test_shape(self):
|
||||||
s1 = Signal()
|
s1 = Signal()
|
||||||
self.assertEqual(s1.bits_sign(), (1, False))
|
self.assertEqual(s1.shape(), (1, False))
|
||||||
s2 = Signal(2)
|
s2 = Signal(2)
|
||||||
self.assertEqual(s2.bits_sign(), (2, False))
|
self.assertEqual(s2.shape(), (2, False))
|
||||||
s3 = Signal((2, False))
|
s3 = Signal((2, False))
|
||||||
self.assertEqual(s3.bits_sign(), (2, False))
|
self.assertEqual(s3.shape(), (2, False))
|
||||||
s4 = Signal((2, True))
|
s4 = Signal((2, True))
|
||||||
self.assertEqual(s4.bits_sign(), (2, True))
|
self.assertEqual(s4.shape(), (2, True))
|
||||||
s5 = Signal(max=16)
|
s5 = Signal(max=16)
|
||||||
self.assertEqual(s5.bits_sign(), (4, False))
|
self.assertEqual(s5.shape(), (4, False))
|
||||||
s6 = Signal(min=4, max=16)
|
s6 = Signal(min=4, max=16)
|
||||||
self.assertEqual(s6.bits_sign(), (4, False))
|
self.assertEqual(s6.shape(), (4, False))
|
||||||
s7 = Signal(min=-4, max=16)
|
s7 = Signal(min=-4, max=16)
|
||||||
self.assertEqual(s7.bits_sign(), (5, True))
|
self.assertEqual(s7.shape(), (5, True))
|
||||||
s8 = Signal(min=-20, max=16)
|
s8 = Signal(min=-20, max=16)
|
||||||
self.assertEqual(s8.bits_sign(), (6, True))
|
self.assertEqual(s8.shape(), (6, True))
|
||||||
|
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
Signal(min=10, max=4)
|
Signal(min=10, max=4)
|
||||||
|
@ -316,16 +316,16 @@ class SignalTestCase(unittest.TestCase):
|
||||||
|
|
||||||
def test_like(self):
|
def test_like(self):
|
||||||
s1 = Signal.like(Signal(4))
|
s1 = Signal.like(Signal(4))
|
||||||
self.assertEqual(s1.bits_sign(), (4, False))
|
self.assertEqual(s1.shape(), (4, False))
|
||||||
s2 = Signal.like(Signal(min=-15))
|
s2 = Signal.like(Signal(min=-15))
|
||||||
self.assertEqual(s2.bits_sign(), (5, True))
|
self.assertEqual(s2.shape(), (5, True))
|
||||||
s3 = Signal.like(Signal(4, reset=0b111, reset_less=True))
|
s3 = Signal.like(Signal(4, reset=0b111, reset_less=True))
|
||||||
self.assertEqual(s3.reset, 0b111)
|
self.assertEqual(s3.reset, 0b111)
|
||||||
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(10)
|
||||||
self.assertEqual(s5.bits_sign(), (4, False))
|
self.assertEqual(s5.shape(), (4, False))
|
||||||
|
|
||||||
|
|
||||||
class ClockSignalTestCase(unittest.TestCase):
|
class ClockSignalTestCase(unittest.TestCase):
|
||||||
|
|
Loading…
Reference in a new issue