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: 75d33a0c0518
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: 8e11fcf1d004
Choose a head ref
  • 2 commits
  • 4 files changed
  • 1 contributor

Commits on Apr 14, 2013

  1. fhdl: support len() on all values

    Sebastien Bourdeauducq committed Apr 14, 2013
    Copy the full SHA
    ea63389 View commit details
  2. bus/csr/SRAM: fix Module conversion errors

    Sebastien Bourdeauducq committed Apr 14, 2013
    Copy the full SHA
    8e11fcf View commit details
Showing with 86 additions and 86 deletions.
  1. +3 −3 migen/bus/csr.py
  2. +81 −3 migen/fhdl/structure.py
  3. +1 −79 migen/fhdl/tools.py
  4. +1 −1 migen/genlib/cdc.py
6 changes: 3 additions & 3 deletions migen/bus/csr.py
Original file line number Diff line number Diff line change
@@ -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,
84 changes: 81 additions & 3 deletions migen/fhdl/structure.py
Original file line number Diff line number Diff line change
@@ -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
80 changes: 1 addition & 79 deletions migen/fhdl/tools.py
Original file line number Diff line number Diff line change
@@ -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):
2 changes: 1 addition & 1 deletion migen/genlib/cdc.py
Original file line number Diff line number Diff line change
@@ -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):