Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
  • 2 commits
  • 4 files changed
  • 0 commit comments
  • 1 contributor
View
6 migen/bus/csr.py
@@ -61,14 +61,14 @@ def __init__(self, mem_or_size, address, read_only=None, bus=None):
else:
mem = Memory(data_width, mem_or_size//(data_width//8))
if mem.width > data_width:
- csrw_per_memw = (self.mem.width + data_width - 1)//data_width
+ csrw_per_memw = (mem.width + data_width - 1)//data_width
word_bits = bits_for(csrw_per_memw-1)
else:
csrw_per_memw = 1
word_bits = 0
page_bits = _compute_page_bits(mem.depth + word_bits)
if page_bits:
- self._page = CSRStorage(page_bits, name=self.mem.name_override + "_page")
+ self._page = CSRStorage(page_bits, name=mem.name_override + "_page")
else:
self._page = None
if read_only is None:
@@ -94,7 +94,7 @@ def __init__(self, mem_or_size, address, read_only=None, bus=None):
if word_bits:
word_index = Signal(word_bits)
word_expanded = Signal(csrw_per_memw*data_width)
- sync.append(word_index.eq(self.bus.adr[:word_bits]))
+ self.sync += word_index.eq(self.bus.adr[:word_bits])
self.comb += [
word_expanded.eq(port.dat_r),
If(sel_r,
View
84 migen/fhdl/structure.py
@@ -109,6 +109,9 @@ def __getitem__(self, key):
def eq(self, r):
return _Assign(self, r)
+
+ def __len__(self):
+ return value_bits_sign(self)[0]
def __hash__(self):
return HUID.__hash__(self)
@@ -164,9 +167,6 @@ def __init__(self, bits_sign=None, name=None, variable=False, reset=0, name_over
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)) + ">"
@@ -299,3 +299,81 @@ def __add__(self, other):
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
View
80 migen/fhdl/tools.py
@@ -1,7 +1,7 @@
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):
@@ -117,84 +117,6 @@ def insert_reset(rst, sl):
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):
View
2  migen/genlib/cdc.py
@@ -1,6 +1,6 @@
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):

No commit comments for this range

Something went wrong with that request. Please try again.