Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/migen
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 47ef0d13904e
Choose a base ref
...
head repository: m-labs/migen
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 408a85f0226e
Choose a head ref
  • 2 commits
  • 1 file changed
  • 1 contributor

Commits on Mar 29, 2016

  1. Copy the full SHA
    a2a1c30 View commit details
  2. Copy the full SHA
    408a85f View commit details
Showing with 28 additions and 27 deletions.
  1. +28 −27 migen/fhdl/bitcontainer.py
55 changes: 28 additions & 27 deletions migen/fhdl/bitcontainer.py
Original file line number Diff line number Diff line change
@@ -26,6 +26,21 @@ def bits_for(n, require_sign_bit=False):
return r


def _bitwise_binary_bits_sign(a, b):
if not a[1] and not b[1]:
# both operands unsigned
return max(a[0], b[0]), False
elif a[1] and b[1]:
# both operands signed
return max(a[0], b[0]), True
elif not a[1] and b[1]:
# first operand unsigned (add sign bit), second operand signed
return max(a[0] + 1, b[0]), True
else:
# first signed, second operand unsigned (add sign bit)
return max(a[0], b[0] + 1), True


def value_bits_sign(v):
"""Bit length and signedness of a value.
@@ -53,18 +68,13 @@ def value_bits_sign(v):
elif isinstance(v, f._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
if len(obs) == 1:
if v.op == "-" and not obs[0][1]:
return obs[0][0] + 1, True
else:
return obs[0]
n, s = _bitwise_binary_bits_sign(*obs)
return n + 1, s
elif v.op == "*":
if not obs[0][1] and not obs[1][1]:
# both operands unsigned
@@ -88,23 +98,14 @@ def value_bits_sign(v):
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
return _bitwise_binary_bits_sign(*obs)
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]
elif v.op == "m":
return _bitwise_binary_bits_sign(obs[1], obs[2])
else:
raise TypeError
elif isinstance(v, f._Slice):