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: b75fb7f97c5e
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: f93695f60e8b
Choose a head ref
  • 12 commits
  • 8 files changed
  • 1 contributor

Commits on Mar 9, 2013

  1. Use common definition for FinalizeError

    Sebastien Bourdeauducq committed Mar 9, 2013
    Copy the full SHA
    2b8dc52 View commit details
  2. fhdl/autofragment: empty build_fragment by default

    Sebastien Bourdeauducq committed Mar 9, 2013
    Copy the full SHA
    6da8eb9 View commit details
  3. fhdl/autofragment: fix submodules

    Sebastien Bourdeauducq committed Mar 9, 2013
    Copy the full SHA
    f53acb9 View commit details
  4. fhdl/tools/flat_iteration: generalize

    Sebastien Bourdeauducq committed Mar 9, 2013
    Copy the full SHA
    72fb6fd View commit details
  5. fhdl/autofragment: remove legacy functions

    Sebastien Bourdeauducq committed Mar 9, 2013
    Copy the full SHA
    d0d2df3 View commit details
  6. migen/fhdl/autofragment: factorize

    Sebastien Bourdeauducq committed Mar 9, 2013
    Copy the full SHA
    d0676e2 View commit details
  7. bank/description: AutoReg

    Sebastien Bourdeauducq committed Mar 9, 2013
    Copy the full SHA
    f147442 View commit details
  8. bank/csrgen: BankArray

    Sebastien Bourdeauducq committed Mar 9, 2013
    Copy the full SHA
    68fe4c2 View commit details

Commits on Mar 10, 2013

  1. bank/description/AutoReg: check that get_memories and get_registers a…

    …re callable
    Sebastien Bourdeauducq committed Mar 10, 2013
    Copy the full SHA
    cddbc11 View commit details
  2. fhdl/module: replace autofragment

    Sebastien Bourdeauducq committed Mar 10, 2013
    Copy the full SHA
    17e0dfe View commit details
  3. bus/asmibus: use fhdl.module API

    Sebastien Bourdeauducq committed Mar 10, 2013
    Copy the full SHA
    174e8cb View commit details
  4. bank/eventmanager: use module and autoreg

    Sebastien Bourdeauducq committed Mar 10, 2013
    Copy the full SHA
    f93695f View commit details
Showing with 293 additions and 237 deletions.
  1. +44 −0 migen/bank/csrgen.py
  2. +44 −11 migen/bank/description.py
  3. +25 −24 migen/bank/eventmanager.py
  4. +48 −75 migen/bus/asmibus.py
  5. +0 −123 migen/fhdl/autofragment.py
  6. +129 −0 migen/fhdl/module.py
  7. +3 −1 migen/fhdl/tools.py
  8. +0 −3 migen/pytholite/reg.py
44 changes: 44 additions & 0 deletions migen/bank/csrgen.py
Original file line number Diff line number Diff line change
@@ -84,3 +84,47 @@ def get_fragment(self):
sync.append(If(field.we, field.storage.eq(field.w)))

return Fragment(comb, sync)

# address_map(name, memory) returns the CSR offset at which to map
# the CSR object (register bank or memory).
# If memory=None, the object is the register bank of object source.name.
# Otherwise, it is a memory object belonging to source.name.
# address_map is called exactly once for each object at each call to
# scan(), so it can have side effects.
class BankArray:
def __init__(self, source, address_map):
self.source = source
self.address_map = address_map
self.scan()

def scan(self):
self.banks = []
self.srams = []
for name, obj in self.source.__dict__.items():
if hasattr(obj, "get_registers"):
registers = obj.get_registers()
else:
registers = []
if hasattr(obj, "get_memories"):
memories = obj.get_memories()
for memory in memories:
mapaddr = self.address_map(name, memory)
mmap = csr.SRAM(memory, mapaddr)
registers += mmap.get_registers()
self.srams.append(mmap)
if registers:
mapaddr = self.address_map(name, None)
rmap = Bank(registers, mapaddr)
self.banks.append(rmap)

def get_banks(self):
return self.banks

def get_srams(self):
return self.srams

def get_buses(self):
return [i.bus for i in self.banks + self.srams]

def get_fragment(self):
return sum([i.get_fragment() for i in self.banks + self.srams], Fragment())
55 changes: 44 additions & 11 deletions migen/bank/description.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
from migen.fhdl.structure import *
from copy import copy

def regprefix(prefix, registers):
for register in registers:
register.name = prefix + register.name
return registers
from migen.fhdl.structure import *
from migen.fhdl.specials import Memory

def memprefix(prefix, memories):
for memory in memories:
memory.name_override = prefix + memory.name_override
return memories
class Register(HUID):
pass

class RegisterRaw:
class RegisterRaw(Register):
def __init__(self, name, size=1):
Register.__init__(self)
self.name = name
self.size = size
self.re = Signal()
@@ -37,8 +34,9 @@ def __init__(self, name, size=1, access_bus=READ_WRITE, access_dev=READ_ONLY, re
self.w = Signal(self.size)
self.we = Signal()

class RegisterFields:
class RegisterFields(Register):
def __init__(self, name, fields):
Register.__init__(self)
self.name = name
self.fields = fields

@@ -47,6 +45,41 @@ def __init__(self, name, size=1, access_bus=READ_WRITE, access_dev=READ_ONLY, re
self.field = Field(name, size, access_bus, access_dev, reset, atomic_write)
RegisterFields.__init__(self, name, [self.field])

def regprefix(prefix, registers):
r = []
for register in registers:
c = copy(register)
c.name = prefix + c.name
r.append(c)
return r

def memprefix(prefix, memories):
r = []
for memory in memories:
c = copy(memory)
c.name_override = prefix + c.name_override
r.append(c)
return memories

class AutoReg:
def get_memories(self):
r = []
for k, v in self.__dict__.items():
if isinstance(v, Memory):
r.append(v)
elif hasattr(v, "get_memories") and callable(v.get_memories):
r += memprefix(k + "_", v.get_memories())
return sorted(r, key=lambda x: x.huid)

def get_registers(self):
r = []
for k, v in self.__dict__.items():
if isinstance(v, Register):
r.append(v)
elif hasattr(v, "get_registers") and callable(v.get_registers):
r += regprefix(k + "_", v.get_registers())
return sorted(r, key=lambda x: x.huid)

(ALIAS_NON_ATOMIC, ALIAS_ATOMIC_HOLD, ALIAS_ATOMIC_COMMIT) = range(3)

class FieldAlias:
49 changes: 25 additions & 24 deletions migen/bank/eventmanager.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from migen.fhdl.structure import *
from migen.fhdl.module import Module
from migen.bank.description import *
from migen.genlib.misc import optree

class EventSource:
class EventSource(HUID):
def __init__(self):
HUID.__init__(self)
self.trigger = Signal()
self.pending = Signal()

@@ -13,52 +15,51 @@ class EventSourcePulse(EventSource):
class EventSourceLevel(EventSource):
pass

class EventManager:
def __init__(self, *sources):
self.sources = sources
class EventManager(Module, AutoReg):
def __init__(self):
self.irq = Signal()
n = len(self.sources)

def do_finalize(self):
sources_u = [v for v in self.__dict__.values() if isinstance(v, EventSource)]
sources = sorted(sources_u, key=lambda x: x.huid)
n = len(sources)
self.status = RegisterRaw("status", n)
self.pending = RegisterRaw("pending", n)
self.enable = RegisterFields("enable",
[Field("s" + str(i), access_bus=READ_WRITE, access_dev=READ_ONLY) for i in range(n)])

def get_registers(self):
return [self.status, self.pending, self.enable]

def get_fragment(self):
comb = []
sync = []


# status
for i, source in enumerate(self.sources):
for i, source in enumerate(sources):
if isinstance(source, EventSourcePulse):
comb.append(self.status.w[i].eq(0))
self.comb += self.status.w[i].eq(0)
elif isinstance(source, EventSourceLevel):
comb.append(self.status.w[i].eq(source.trigger))
self.comb += self.status.w[i].eq(source.trigger)
else:
raise TypeError

# pending
for i, source in enumerate(self.sources):
for i, source in enumerate(sources):
# W1C
sync.append(If(self.pending.re & self.pending.r[i], source.pending.eq(0)))
self.sync += If(self.pending.re & self.pending.r[i], source.pending.eq(0))
if isinstance(source, EventSourcePulse):
# set on a positive trigger pulse
sync.append(If(source.trigger, source.pending.eq(1)))
self.sync += If(source.trigger, source.pending.eq(1))
elif isinstance(source, EventSourceLevel):
# set on the falling edge of the trigger
old_trigger = Signal()
sync += [
self.sync += [
old_trigger.eq(source.trigger),
If(~source.trigger & old_trigger, source.pending.eq(1))
]
else:
raise TypeError
comb.append(self.pending.w[i].eq(source.pending))
self.comb += self.pending.w[i].eq(source.pending)

# IRQ
irqs = [self.pending.w[i] & field.r for i, field in enumerate(self.enable.fields)]
comb.append(self.irq.eq(optree("|", irqs)))

return Fragment(comb, sync)
self.comb += self.irq.eq(optree("|", irqs))

def __setattr__(self, name, value):
if isinstance(value, EventSource) and self.finalized:
raise FinalizeError
object.__setattr__(self, name, value)
Loading