def eq(self, r):
return _Assign(self, r)
+
+ def __len__(self):
+ return value_bits_sign(self)[0]
def __hash__(self):
return HUID.__hash__(self)
self.name_override = name_override
self.backtrace = tracer.trace_back(name)
- def __len__(self): # TODO: remove (use tools.value_bits_sign instead)
- return self.nbits
-
def __repr__(self):
return "<Signal " + (self.backtrace[-1][0] or "anonymous") + " at " + hex(id(self)) + ">"
self.specials | other.specials,
self.clock_domains + other.clock_domains,
self.sim + other.sim)
+
+def value_bits_sign(v):
+ if isinstance(v, bool):
+ return 1, False
+ elif isinstance(v, int):
+ return bits_for(v), v < 0
+ elif isinstance(v, Signal):
+ return v.nbits, v.signed
+ elif isinstance(v, (ClockSignal, ResetSignal)):
+ return 1, False
+ elif isinstance(v, _Operator):
+ obs = list(map(value_bits_sign, v.operands))
+ if v.op == "+" or v.op == "-":
+ if not obs[0][1] and not obs[1][1]:
+ # both operands unsigned
+ return max(obs[0][0], obs[1][0]) + 1, False
+ elif obs[0][1] and obs[1][1]:
+ # both operands signed
+ return max(obs[0][0], obs[1][0]) + 1, True
+ elif not obs[0][1] and obs[1][1]:
+ # first operand unsigned (add sign bit), second operand signed
+ return max(obs[0][0] + 1, obs[1][0]) + 1, True
+ else:
+ # first signed, second operand unsigned (add sign bit)
+ return max(obs[0][0], obs[1][0] + 1) + 1, True
+ elif v.op == "*":
+ if not obs[0][1] and not obs[1][1]:
+ # both operands unsigned
+ return obs[0][0] + obs[1][0]
+ elif obs[0][1] and obs[1][1]:
+ # both operands signed
+ return obs[0][0] + obs[1][0] - 1
+ else:
+ # one operand signed, the other unsigned (add sign bit)
+ return obs[0][0] + obs[1][0] + 1 - 1
+ elif v.op == "<<<":
+ if obs[1][1]:
+ extra = 2**(obs[1][0] - 1) - 1
+ else:
+ extra = 2**obs[1][0] - 1
+ return obs[0][0] + extra, obs[0][1]
+ elif v.op == ">>>":
+ if obs[1][1]:
+ extra = 2**(obs[1][0] - 1)
+ else:
+ extra = 0
+ return obs[0][0] + extra, obs[0][1]
+ elif v.op == "&" or v.op == "^" or v.op == "|":
+ if not obs[0][1] and not obs[1][1]:
+ # both operands unsigned
+ return max(obs[0][0], obs[1][0]), False
+ elif obs[0][1] and obs[1][1]:
+ # both operands signed
+ return max(obs[0][0], obs[1][0]), True
+ elif not obs[0][1] and obs[1][1]:
+ # first operand unsigned (add sign bit), second operand signed
+ return max(obs[0][0] + 1, obs[1][0]), True
+ else:
+ # first signed, second operand unsigned (add sign bit)
+ return max(obs[0][0], obs[1][0] + 1), True
+ elif v.op == "<" or v.op == "<=" or v.op == "==" or v.op == "!=" \
+ or v.op == ">" or v.op == ">=":
+ return 1, False
+ elif v.op == "~":
+ return obs[0]
+ else:
+ raise TypeError
+ elif isinstance(v, _Slice):
+ return v.stop - v.start, value_bits_sign(v.value)[1]
+ elif isinstance(v, Cat):
+ return sum(value_bits_sign(sv)[0] for sv in v.l), False
+ elif isinstance(v, Replicate):
+ return (value_bits_sign(v.v)[0])*v.n, False
+ elif isinstance(v, _ArrayProxy):
+ bsc = map(value_bits_sign, v.choices)
+ return max(bs[0] for bs in bsc), any(bs[1] for bs in bsc)
+ else:
+ raise TypeError
import collections
from migen.fhdl.structure import *
-from migen.fhdl.structure import _Operator, _Slice, _Assign, _ArrayProxy
+from migen.fhdl.structure import _Slice, _Assign
from migen.fhdl.visit import NodeVisitor, NodeTransformer
def bitreverse(s):
resetcode = [t.eq(t.reset) for t in sorted(targets, key=lambda x: x.huid)]
return [If(rst, *resetcode).Else(*sl)]
-def value_bits_sign(v):
- if isinstance(v, bool):
- return 1, False
- elif isinstance(v, int):
- return bits_for(v), v < 0
- elif isinstance(v, Signal):
- return v.nbits, v.signed
- elif isinstance(v, (ClockSignal, ResetSignal)):
- return 1, False
- elif isinstance(v, _Operator):
- obs = list(map(value_bits_sign, v.operands))
- if v.op == "+" or v.op == "-":
- if not obs[0][1] and not obs[1][1]:
- # both operands unsigned
- return max(obs[0][0], obs[1][0]) + 1, False
- elif obs[0][1] and obs[1][1]:
- # both operands signed
- return max(obs[0][0], obs[1][0]) + 1, True
- elif not obs[0][1] and obs[1][1]:
- # first operand unsigned (add sign bit), second operand signed
- return max(obs[0][0] + 1, obs[1][0]) + 1, True
- else:
- # first signed, second operand unsigned (add sign bit)
- return max(obs[0][0], obs[1][0] + 1) + 1, True
- elif v.op == "*":
- if not obs[0][1] and not obs[1][1]:
- # both operands unsigned
- return obs[0][0] + obs[1][0]
- elif obs[0][1] and obs[1][1]:
- # both operands signed
- return obs[0][0] + obs[1][0] - 1
- else:
- # one operand signed, the other unsigned (add sign bit)
- return obs[0][0] + obs[1][0] + 1 - 1
- elif v.op == "<<<":
- if obs[1][1]:
- extra = 2**(obs[1][0] - 1) - 1
- else:
- extra = 2**obs[1][0] - 1
- return obs[0][0] + extra, obs[0][1]
- elif v.op == ">>>":
- if obs[1][1]:
- extra = 2**(obs[1][0] - 1)
- else:
- extra = 0
- return obs[0][0] + extra, obs[0][1]
- elif v.op == "&" or v.op == "^" or v.op == "|":
- if not obs[0][1] and not obs[1][1]:
- # both operands unsigned
- return max(obs[0][0], obs[1][0]), False
- elif obs[0][1] and obs[1][1]:
- # both operands signed
- return max(obs[0][0], obs[1][0]), True
- elif not obs[0][1] and obs[1][1]:
- # first operand unsigned (add sign bit), second operand signed
- return max(obs[0][0] + 1, obs[1][0]), True
- else:
- # first signed, second operand unsigned (add sign bit)
- return max(obs[0][0], obs[1][0] + 1), True
- elif v.op == "<" or v.op == "<=" or v.op == "==" or v.op == "!=" \
- or v.op == ">" or v.op == ">=":
- return 1, False
- elif v.op == "~":
- return obs[0]
- else:
- raise TypeError
- elif isinstance(v, _Slice):
- return v.stop - v.start, value_bits_sign(v.value)[1]
- elif isinstance(v, Cat):
- return sum(value_bits_sign(sv)[0] for sv in v.l), False
- elif isinstance(v, Replicate):
- return (value_bits_sign(v.v)[0])*v.n, False
- elif isinstance(v, _ArrayProxy):
- bsc = map(value_bits_sign, v.choices)
- return max(bs[0] for bs in bsc), any(bs[1] for bs in bsc)
- else:
- raise TypeError
-
# Basics are FHDL structure elements that back-ends are not required to support
# but can be expressed in terms of other elements (lowered) before conversion.
class _BasicLowerer(NodeTransformer):
from migen.fhdl.structure import *
from migen.fhdl.specials import Special
-from migen.fhdl.tools import value_bits_sign, list_signals
+from migen.fhdl.tools import list_signals
class MultiRegImpl:
def __init__(self, i, o, odomain, n):