Use new module, autoreg and eventmanager Migen APIs
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Sun, 10 Mar 2013 18:32:38 +0000 (19:32 +0100)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Sun, 10 Mar 2013 18:32:38 +0000 (19:32 +0100)
21 files changed:
common/csrbase.h
milkymist/asmicon/__init__.py
milkymist/asmicon/bankmachine.py
milkymist/asmicon/multiplexer.py
milkymist/asmicon/refresher.py
milkymist/asmiprobe/__init__.py
milkymist/dfii/__init__.py
milkymist/framebuffer/__init__.py
milkymist/identifier/__init__.py
milkymist/lm32/__init__.py
milkymist/m1crg/__init__.py
milkymist/minimac3/__init__.py
milkymist/norflash/__init__.py
milkymist/s6ddrphy/__init__.py
milkymist/timer/__init__.py
milkymist/uart/__init__.py
software/include/hw/id.h [deleted file]
software/include/hw/identifier.h [new file with mode: 0644]
software/libbase/board.c
software/libbase/timer.c
top.py

index 89b730dc73914da368963d6d43b45ca42e04cefd..c9f7b1a3c7c5dbdb1c85c8871b2f7f6cad36be0d 100644 (file)
@@ -1,12 +1,12 @@
 #ifndef __CSRBASE_H
 #define __CSRBASE_H
 
-#define UART_BASE      0xe0000000
-#define DFII_BASE      0xe0000800
-#define ID_BASE                0xe0001000
-#define TIMER0_BASE    0xe0001800
-#define MINIMAC_BASE   0xe0002000
-#define FB_BASE                0xe0002800
-#define ASMIPROBE_BASE 0xe0003000
+#define UART_BASE              0xe0000000
+#define DFII_BASE              0xe0000800
+#define IDENTIFIER_BASE                0xe0001000
+#define TIMER0_BASE            0xe0001800
+#define MINIMAC_BASE           0xe0002000
+#define FB_BASE                        0xe0002800
+#define ASMIPROBE_BASE         0xe0003000
 
 #endif /* __CSRBASE_H */
index 9f93a5e13e495254bf8fe724aa9fee12456fee6b..828ccd642e67aa1143f65eeccad6fc3b5dffc933 100644 (file)
@@ -1,4 +1,5 @@
 from migen.fhdl.structure import *
+from migen.fhdl.module import Module
 from migen.bus import dfi, asmibus
 
 from milkymist.asmicon.refresher import *
@@ -34,13 +35,12 @@ class TimingSettings:
                self.write_time = write_time
                self.slot_time = slot_time
 
-class ASMIcon:
+class ASMIcon(Module):
        def __init__(self, phy_settings, geom_settings, timing_settings, full_selector=False):
                self.phy_settings = phy_settings
                self.geom_settings = geom_settings
                self.timing_settings = timing_settings
                self.full_selector = full_selector
-               self.finalized = False
                
                self.dfi = dfi.Interface(self.geom_settings.mux_a,
                        self.geom_settings.bank_a,
@@ -50,26 +50,14 @@ class ASMIcon:
                self.address_align = log2_int(burst_length)
                aw = self.geom_settings.bank_a + self.geom_settings.row_a + self.geom_settings.col_a - self.address_align
                dw = self.phy_settings.dfi_d*self.phy_settings.nphases
-               self.hub = asmibus.Hub(aw, dw, self.timing_settings.slot_time)
+               self.submodules.hub = asmibus.Hub(aw, dw, self.timing_settings.slot_time)
        
-       def finalize(self):
-               if self.finalized:
-                       raise FinalizeError
-               self.finalized = True
-               self.hub.finalize()
+       def do_finalize(self):
                slots = self.hub.get_slots()
-               self.refresher = Refresher(self.geom_settings.mux_a, self.geom_settings.bank_a,
+               self.submodules.refresher = Refresher(self.geom_settings.mux_a, self.geom_settings.bank_a,
                        self.timing_settings.tRP, self.timing_settings.tREFI, self.timing_settings.tRFC)
-               self.bank_machines = [BankMachine(self.geom_settings, self.timing_settings, self.address_align, i, slots, self.full_selector)
+               self.submodules.bank_machines = [BankMachine(self.geom_settings, self.timing_settings, self.address_align, i, slots, self.full_selector)
                        for i in range(2**self.geom_settings.bank_a)]
-               self.multiplexer = Multiplexer(self.phy_settings, self.geom_settings, self.timing_settings,
+               self.submodules.multiplexer = Multiplexer(self.phy_settings, self.geom_settings, self.timing_settings,
                        self.bank_machines, self.refresher,
                        self.dfi, self.hub)
-       
-       def get_fragment(self):
-               if not self.finalized:
-                       raise FinalizeError
-               return self.hub.get_fragment() + \
-                       self.refresher.get_fragment() + \
-                       sum([bm.get_fragment() for bm in self.bank_machines], Fragment()) + \
-                       self.multiplexer.get_fragment()
index 07244e97e22603f831e9b8d44a1f6c6493c2fe62..0e296fb0a26db43d006b382b8100929dd598141d 100644 (file)
@@ -1,4 +1,5 @@
 from migen.fhdl.structure import *
+from migen.fhdl.module import Module
 from migen.bus.asmibus import *
 from migen.genlib.roundrobin import *
 from migen.genlib.fsm import FSM
@@ -33,97 +34,81 @@ class _AddressSlicer:
                else:
                        return Cat(Replicate(0, self.address_align), address[:self._b1])
 
-class _Selector:
+class _Selector(Module):
        def __init__(self, slicer, bankn, slots):
-               self.slicer = slicer
-               self.bankn = bankn
-               self.slots = slots
-               
-               self.nslots = len(self.slots)
+               nslots = len(slots)
                self.stb = Signal()
                self.ack = Signal()
-               self.tag = Signal(max=self.nslots)
-               self.adr = Signal(self.slots[0].adr.nbits)
+               self.tag = Signal(max=nslots)
+               self.adr = Signal(slots[0].adr.nbits)
                self.we = Signal()
                
                # derived classes should drive rr.request
-               self.rr = RoundRobin(self.nslots, SP_CE)
+               self.submodules.rr = RoundRobin(nslots, SP_CE)
        
-       def get_fragment(self):
-               comb = []
-               rr = self.rr
-               
+               ###
+
                # Multiplex
+               rr = self.rr
                state = Signal(2)
-               comb += [
-                       state.eq(Array(slot.state for slot in self.slots)[rr.grant]),
-                       self.adr.eq(Array(slot.adr for slot in self.slots)[rr.grant]),
-                       self.we.eq(Array(slot.we for slot in self.slots)[rr.grant]),
+               self.comb += [
+                       state.eq(Array(slot.state for slot in slots)[rr.grant]),
+                       self.adr.eq(Array(slot.adr for slot in slots)[rr.grant]),
+                       self.we.eq(Array(slot.we for slot in slots)[rr.grant]),
                        self.stb.eq(
-                               (self.slicer.bank(self.adr) == self.bankn) \
+                               (slicer.bank(self.adr) == bankn) \
                                & (state == SLOT_PENDING)),
                        rr.ce.eq(self.ack | ~self.stb),
                        self.tag.eq(rr.grant)
                ]
-               comb += [If((rr.grant == i) & self.stb & self.ack, slot.process.eq(1))
-                       for i, slot in enumerate(self.slots)]
-                       
-               return Fragment(comb) + rr.get_fragment()
+               self.comb += [If((rr.grant == i) & self.stb & self.ack, slot.process.eq(1))
+                       for i, slot in enumerate(slots)]
+
+               self.complete_selector(slicer, bankn, slots)
 
 class _SimpleSelector(_Selector):
-       def get_fragment(self):
-               comb = []
-               for i, slot in enumerate(self.slots):
-                       comb.append(self.rr.request[i].eq(
-                               (self.slicer.bank(slot.adr) == self.bankn) & \
-                               (slot.state == SLOT_PENDING)
-                       ))
-       
-               return Fragment(comb) + _Selector.get_fragment(self)
+       def complete_selector(self, slicer, bankn, slots):
+               for i, slot in enumerate(slots):
+                       self.comb += self.rr.request[i].eq(
+                               (slicer.bank(slot.adr) == bankn) & \
+                               (slot.state == SLOT_PENDING))
 
 class _FullSelector(_Selector):
-       def get_fragment(self):
-               comb = []
-               sync = []
+       def complete_selector(self, slicer, bankn, slots):
                rr = self.rr
 
                # List outstanding requests for our bank
                outstandings = []
-               for slot in self.slots:
+               for slot in slots:
                        outstanding = Signal()
-                       comb.append(outstanding.eq(
-                               (self.slicer.bank(slot.adr) == self.bankn) & \
-                               (slot.state == SLOT_PENDING)
-                       ))
+                       self.comb += outstanding.eq(
+                               (slicer.bank(slot.adr) == bankn) & \
+                               (slot.state == SLOT_PENDING))
                        outstandings.append(outstanding)
                
                # Row tracking
-               openrow_r = Signal(self.slicer.geom_settings.row_a)
-               openrow_n = Signal(self.slicer.geom_settings.row_a)
-               openrow = Signal(self.slicer.geom_settings.row_a)
-               comb += [
-                       openrow_n.eq(self.slicer.row(self.adr)),
+               openrow_r = Signal(slicer.geom_settings.row_a)
+               openrow_n = Signal(slicer.geom_settings.row_a)
+               openrow = Signal(slicer.geom_settings.row_a)
+               self.comb += [
+                       openrow_n.eq(slicer.row(self.adr)),
                        If(self.stb,
                                openrow.eq(openrow_n)
                        ).Else(
                                openrow.eq(openrow_r)
                        )
                ]
-               sync += [
-                       If(self.stb & self.ack,
-                               openrow_r.eq(openrow_n)
-                       )
-               ]
+               self.sync += If(self.stb & self.ack, openrow_r.eq(openrow_n))
                hits = []
-               for slot, os in zip(self.slots, outstandings):
+               for slot, os in zip(slots, outstandings):
                        hit = Signal()
-                       comb.append(hit.eq((self.slicer.row(slot.adr) == openrow) & os))
+                       self.comb += hit.eq((slicer.row(slot.adr) == openrow) & os)
                        hits.append(hit)
                
                # Determine best request
                rr = RoundRobin(self.nslots, SP_CE)
                has_hit = Signal()
-               comb.append(has_hit.eq(optree("|", hits)))
+               self.comb += has_hit.eq(optree("|", hits))
                
                best_hit = [rr.request[i].eq(hit)
                        for i, hit in enumerate(hits)]
@@ -135,84 +120,72 @@ class _FullSelector(_Selector):
                                *best_fallback
                        )
                
-               if self.slots[0].time:
+               if slots[0].time:
                        # Implement anti-starvation timer
                        matures = []
-                       for slot, os in zip(self.slots, outstandings):
+                       for slot, os in zip(slots, outstandings):
                                mature = Signal()
                                comb.append(mature.eq(slot.mature & os))
                                matures.append(mature)
                        has_mature = Signal()
-                       comb.append(has_mature.eq(optree("|", matures)))
+                       self.comb += has_mature.eq(optree("|", matures))
                        best_mature = [rr.request[i].eq(mature)
                                for i, mature in enumerate(matures)]
                        select_stmt = If(has_mature, *best_mature).Else(select_stmt)
-               comb.append(select_stmt)
-               
-               return Fragment(comb, sync) + _Selector.get_fragment(self)
+               self.comb += select_stmt
 
-class _Buffer:
+class _Buffer(Module):
        def __init__(self, source):
-               self.source = source
-               
                self.stb = Signal()
                self.ack = Signal()
-               self.tag = Signal(self.source.tag.bv)
-               self.adr = Signal(self.source.adr.bv)
+               self.tag = Signal(source.tag.bv)
+               self.adr = Signal(source.adr.bv)
                self.we = Signal()
        
-       def get_fragment(self):
+               ###
+
                en = Signal()
-               comb = [
+               self.comb += [
                        en.eq(self.ack | ~self.stb),
-                       self.source.ack.eq(en)
+                       source.ack.eq(en)
                ]
-               sync = [
+               self.sync += [
                        If(en,
-                               self.stb.eq(self.source.stb),
-                               self.tag.eq(self.source.tag),
-                               self.adr.eq(self.source.adr),
-                               self.we.eq(self.source.we)
+                               self.stb.eq(source.stb),
+                               self.tag.eq(source.tag),
+                               self.adr.eq(source.adr),
+                               self.we.eq(source.we)
                        )
                ]
-               return Fragment(comb, sync)
        
-class BankMachine:
+class BankMachine(Module):
        def __init__(self, geom_settings, timing_settings, address_align, bankn, slots, full_selector):
-               self.geom_settings = geom_settings
-               self.timing_settings = timing_settings
-               self.address_align = address_align
-               self.bankn = bankn
-               self.slots = slots
-               self.full_selector = full_selector
-               
                self.refresh_req = Signal()
                self.refresh_gnt = Signal()
                self.cmd = CommandRequestRW(geom_settings.mux_a, geom_settings.bank_a,
                        bits_for(len(slots)-1))
 
-       def get_fragment(self):
-               comb = []
-               sync = []
-               
+               ###
+
                # Sub components
-               slicer = _AddressSlicer(self.geom_settings, self.address_align)
-               if self.full_selector:
-                       selector = _FullSelector(slicer, self.bankn, self.slots)
-                       buf = _Buffer(selector)
-                       cmdsource = buf
+               slicer = _AddressSlicer(geom_settings, address_align)
+               if full_selector:
+                       selector = _FullSelector(slicer, bankn, slots)
+                       self.submodules.buf = _Buffer(selector)
+                       cmdsource = self.buf
                else:
-                       selector = _SimpleSelector(slicer, self.bankn, self.slots)
+                       selector = _SimpleSelector(slicer, bankn, slots)
                        cmdsource = selector
+               self.submodules += selector
                
                # Row tracking
                has_openrow = Signal()
-               openrow = Signal(self.geom_settings.row_a)
+               openrow = Signal(geom_settings.row_a)
                hit = Signal()
-               comb.append(hit.eq(openrow == slicer.row(cmdsource.adr)))
+               self.comb += hit.eq(openrow == slicer.row(cmdsource.adr))
                track_open = Signal()
                track_close = Signal()
-               sync += [
+               self.sync += [
                        If(track_open,
                                has_openrow.eq(1),
                                openrow.eq(slicer.row(cmdsource.adr))
@@ -224,8 +197,8 @@ class BankMachine:
                
                # Address generation
                s_row_adr = Signal()
-               comb += [
-                       self.cmd.ba.eq(self.bankn),
+               self.comb += [
+                       self.cmd.ba.eq(bankn),
                        If(s_row_adr,
                                self.cmd.a.eq(slicer.row(cmdsource.adr))
                        ).Else(
@@ -233,14 +206,14 @@ class BankMachine:
                        )
                ]
                
-               comb.append(self.cmd.tag.eq(cmdsource.tag))
+               self.comb += self.cmd.tag.eq(cmdsource.tag)
                
                # Respect write-to-precharge specification
                precharge_ok = Signal()
-               t_unsafe_precharge = 2 + self.timing_settings.tWR - 1
+               t_unsafe_precharge = 2 + timing_settings.tWR - 1
                unsafe_precharge_count = Signal(max=t_unsafe_precharge+1)
-               comb.append(precharge_ok.eq(unsafe_precharge_count == 0))
-               sync += [
+               self.comb += precharge_ok.eq(unsafe_precharge_count == 0)
+               self.sync += [
                        If(self.cmd.stb & self.cmd.ack & self.cmd.is_write,
                                unsafe_precharge_count.eq(t_unsafe_precharge)
                        ).Elif(~precharge_ok,
@@ -250,9 +223,10 @@ class BankMachine:
                
                # Control and command generation FSM
                fsm = FSM("REGULAR", "PRECHARGE", "ACTIVATE", "REFRESH", delayed_enters=[
-                       ("TRP", "ACTIVATE", self.timing_settings.tRP-1),
-                       ("TRCD", "REGULAR", self.timing_settings.tRCD-1)
+                       ("TRP", "ACTIVATE", timing_settings.tRP-1),
+                       ("TRCD", "REGULAR", timing_settings.tRCD-1)
                ])
+               self.submodules += fsm
                fsm.act(fsm.REGULAR,
                        If(self.refresh_req,
                                fsm.next_state(fsm.REFRESH)
@@ -298,12 +272,3 @@ class BankMachine:
                        track_close.eq(1),
                        If(~self.refresh_req, fsm.next_state(fsm.REGULAR))
                )
-               
-               if self.full_selector:
-                       buf_fragment = buf.get_fragment()
-               else:
-                       buf_fragment = Fragment()
-               return Fragment(comb, sync) + \
-                       selector.get_fragment() + \
-                       buf_fragment + \
-                       fsm.get_fragment()
index 0f257841c6f130cf99d67a5d8d54ba53e9d65b3b..ae254418cdd18811b70b2932cf4696a2f1107a9a 100644 (file)
@@ -1,4 +1,5 @@
 from migen.fhdl.structure import *
+from migen.fhdl.module import Module
 from migen.genlib.roundrobin import *
 from migen.genlib.misc import optree
 from migen.genlib.fsm import FSM
@@ -20,171 +21,141 @@ class CommandRequestRW(CommandRequest):
                self.is_write = Signal()
                self.tag = Signal(tagbits)
 
-class _CommandChooser:
+class _CommandChooser(Module):
        def __init__(self, requests, tagbits):
-               self.requests = requests
-               
                self.want_reads = Signal()
                self.want_writes = Signal()
                # NB: cas_n/ras_n/we_n are 1 when stb is inactive
-               self.cmd = CommandRequestRW(len(self.requests[0].a), len(self.requests[0].ba), tagbits)
+               self.cmd = CommandRequestRW(len(requests[0].a), len(requests[0].ba), tagbits)
        
-       def get_fragment(self):
-               comb = []
-               sync = []
-               
-               rr = RoundRobin(len(self.requests), SP_CE)
+               ###
+
+               rr = RoundRobin(len(requests), SP_CE)
+               self.submodules += rr
                
-               comb += [rr.request[i].eq(req.stb & ((req.is_read == self.want_reads) | (req.is_write == self.want_writes)))
-                       for i, req in enumerate(self.requests)]
+               self.comb += [rr.request[i].eq(req.stb & ((req.is_read == self.want_reads) | (req.is_write == self.want_writes)))
+                       for i, req in enumerate(requests)]
                
                stb = Signal()
-               comb.append(stb.eq(Array(req.stb for req in self.requests)[rr.grant]))
+               self.comb += stb.eq(Array(req.stb for req in requests)[rr.grant])
                for name in ["a", "ba", "is_read", "is_write", "tag"]:
-                       choices = Array(getattr(req, name) for req in self.requests)
-                       comb.append(getattr(self.cmd, name).eq(choices[rr.grant]))
+                       choices = Array(getattr(req, name) for req in requests)
+                       self.comb += getattr(self.cmd, name).eq(choices[rr.grant])
                for name in ["cas_n", "ras_n", "we_n"]:
                        # we should only assert those signals when stb is 1
-                       choices = Array(getattr(req, name) for req in self.requests)
-                       comb.append(If(self.cmd.stb, getattr(self.cmd, name).eq(choices[rr.grant])))
-               comb.append(self.cmd.stb.eq(stb \
+                       choices = Array(getattr(req, name) for req in requests)
+                       self.comb += If(self.cmd.stb, getattr(self.cmd, name).eq(choices[rr.grant]))
+               self.comb += self.cmd.stb.eq(stb \
                        & (self.cmd.is_read == self.want_reads) \
-                       & (self.cmd.is_write == self.want_writes)))
+                       & (self.cmd.is_write == self.want_writes))
                
-               comb += [If(self.cmd.stb & self.cmd.ack & (rr.grant == i), req.ack.eq(1))
-                       for i, req in enumerate(self.requests)]
-               comb.append(rr.ce.eq(self.cmd.ack))
-               
-               return Fragment(comb, sync) + rr.get_fragment()
+               self.comb += [If(self.cmd.stb & self.cmd.ack & (rr.grant == i), req.ack.eq(1))
+                       for i, req in enumerate(requests)]
+               self.comb += rr.ce.eq(self.cmd.ack)
 
-class _Steerer:
+class _Steerer(Module):
        def __init__(self, commands, dfi):
-               self.commands = commands
-               self.dfi = dfi
-               
-               ncmd = len(self.commands)
-               nph = len(self.dfi.phases)
+               ncmd = len(commands)
+               nph = len(dfi.phases)
                self.sel = [Signal(max=ncmd) for i in range(nph)]
        
-       def get_fragment(self):
-               comb = []
-               sync = []
+               ###
+       
                def stb_and(cmd, attr):
                        if not hasattr(cmd, "stb"):
                                return 0
                        else:
                                return cmd.stb & getattr(cmd, attr)
-               for phase, sel in zip(self.dfi.phases, self.sel):
-                       comb += [
+               for phase, sel in zip(dfi.phases, self.sel):
+                       self.comb += [
                                phase.cke.eq(1),
                                phase.cs_n.eq(0)
                        ]
-                       sync += [
-                               phase.address.eq(Array(cmd.a for cmd in self.commands)[sel]),
-                               phase.bank.eq(Array(cmd.ba for cmd in self.commands)[sel]),
-                               phase.cas_n.eq(Array(cmd.cas_n for cmd in self.commands)[sel]),
-                               phase.ras_n.eq(Array(cmd.ras_n for cmd in self.commands)[sel]),
-                               phase.we_n.eq(Array(cmd.we_n for cmd in self.commands)[sel]),
-                               phase.rddata_en.eq(Array(stb_and(cmd, "is_read") for cmd in self.commands)[sel]),
-                               phase.wrdata_en.eq(Array(stb_and(cmd, "is_write") for cmd in self.commands)[sel])
+                       self.sync += [
+                               phase.address.eq(Array(cmd.a for cmd in commands)[sel]),
+                               phase.bank.eq(Array(cmd.ba for cmd in commands)[sel]),
+                               phase.cas_n.eq(Array(cmd.cas_n for cmd in commands)[sel]),
+                               phase.ras_n.eq(Array(cmd.ras_n for cmd in commands)[sel]),
+                               phase.we_n.eq(Array(cmd.we_n for cmd in commands)[sel]),
+                               phase.rddata_en.eq(Array(stb_and(cmd, "is_read") for cmd in commands)[sel]),
+                               phase.wrdata_en.eq(Array(stb_and(cmd, "is_write") for cmd in commands)[sel])
                        ]
-               return Fragment(comb, sync)
 
-class _Datapath:
+class _Datapath(Module):
        def __init__(self, timing_settings, command, dfi, hub):
-               self.timing_settings = timing_settings
-               self.command = command
-               self.dfi = dfi
-               self.hub = hub
-       
-       def get_fragment(self):
-               comb = []
-               sync = []
-               tagbits = len(self.hub.tag_call)
+               tagbits = len(hub.tag_call)
                
                rd_valid = Signal()
                rd_tag = Signal(tagbits)
                wr_valid = Signal()
                wr_tag = Signal(tagbits)
-               comb += [
-                       self.hub.call.eq(rd_valid | wr_valid),
+               self.comb += [
+                       hub.call.eq(rd_valid | wr_valid),
                        If(wr_valid,
-                               self.hub.tag_call.eq(wr_tag)
+                               hub.tag_call.eq(wr_tag)
                        ).Else(
-                               self.hub.tag_call.eq(rd_tag)
+                               hub.tag_call.eq(rd_tag)
                        )
                ]
                
-               rd_delay = self.timing_settings.rd_delay + 1
+               rd_delay = timing_settings.rd_delay + 1
                rd_valid_d = [Signal() for i in range(rd_delay)]
                rd_tag_d = [Signal(tagbits) for i in range(rd_delay)]
                for i in range(rd_delay):
                        if i:
-                               sync += [
+                               self.sync += [
                                        rd_valid_d[i].eq(rd_valid_d[i-1]),
                                        rd_tag_d[i].eq(rd_tag_d[i-1])
                                ]
                        else:
-                               sync += [
-                                       rd_valid_d[i].eq(self.command.stb & self.command.ack & self.command.is_read),
-                                       rd_tag_d[i].eq(self.command.tag)
+                               self.sync += [
+                                       rd_valid_d[i].eq(command.stb & command.ack & command.is_read),
+                                       rd_tag_d[i].eq(command.tag)
                                ]               
-               comb += [
+               self.comb += [
                        rd_valid.eq(rd_valid_d[-1]),
                        rd_tag.eq(rd_tag_d[-1]),
-                       wr_valid.eq(self.command.stb & self.command.ack & self.command.is_write),
-                       wr_tag.eq(self.command.tag),
+                       wr_valid.eq(command.stb & command.ack & command.is_write),
+                       wr_tag.eq(command.tag),
                ]
                
-               all_rddata = [p.rddata for p in self.dfi.phases]
-               all_wrdata = [p.wrdata for p in self.dfi.phases]
-               all_wrdata_mask = [p.wrdata_mask for p in self.dfi.phases]
-               comb += [
-                       self.hub.dat_r.eq(Cat(*all_rddata)),
-                       Cat(*all_wrdata).eq(self.hub.dat_w),
-                       Cat(*all_wrdata_mask).eq(self.hub.dat_wm)
+               all_rddata = [p.rddata for p in dfi.phases]
+               all_wrdata = [p.wrdata for p in dfi.phases]
+               all_wrdata_mask = [p.wrdata_mask for p in dfi.phases]
+               self.comb += [
+                       hub.dat_r.eq(Cat(*all_rddata)),
+                       Cat(*all_wrdata).eq(hub.dat_w),
+                       Cat(*all_wrdata_mask).eq(hub.dat_wm)
                ]
-               
-               return Fragment(comb, sync)
 
-class Multiplexer:
+class Multiplexer(Module):
        def __init__(self, phy_settings, geom_settings, timing_settings, bank_machines, refresher, dfi, hub):
-               self.phy_settings = phy_settings
-               self.geom_settings = geom_settings
-               self.timing_settings = timing_settings
-               self.bank_machines = bank_machines
-               self.refresher = refresher
-               self.dfi = dfi
-               self.hub = hub
-               
-               assert(self.phy_settings.nphases == len(dfi.phases))
-               if self.phy_settings.nphases != 2:
+               assert(phy_settings.nphases == len(dfi.phases))
+               if phy_settings.nphases != 2:
                        raise NotImplementedError("TODO: multiplexer only supports 2 phases")
        
-       def get_fragment(self):
-               comb = []
-               sync = []
-               
                # Command choosing
-               requests = [bm.cmd for bm in self.bank_machines]
-               tagbits = len(self.hub.tag_call)
+               requests = [bm.cmd for bm in bank_machines]
+               tagbits = len(hub.tag_call)
                choose_cmd = _CommandChooser(requests, tagbits)
                choose_req = _CommandChooser(requests, tagbits)
-               comb += [
+               self.comb += [
                        choose_cmd.want_reads.eq(0),
                        choose_cmd.want_writes.eq(0)
                ]
+               self.submodules += choose_cmd, choose_req
                
                # Command steering
-               nop = CommandRequest(self.geom_settings.mux_a, self.geom_settings.bank_a)
-               commands = [nop, choose_cmd.cmd, choose_req.cmd, self.refresher.cmd] # nop must be 1st
+               nop = CommandRequest(geom_settings.mux_a, geom_settings.bank_a)
+               commands = [nop, choose_cmd.cmd, choose_req.cmd, refresher.cmd] # nop must be 1st
                (STEER_NOP, STEER_CMD, STEER_REQ, STEER_REFRESH) = range(4)
-               steerer = _Steerer(commands, self.dfi)
+               steerer = _Steerer(commands, dfi)
+               self.submodules += steerer
                
                # Read/write turnaround
                read_available = Signal()
                write_available = Signal()
-               comb += [
+               self.comb += [
                        read_available.eq(optree("|", [req.stb & req.is_read for req in requests])),
                        write_available.eq(optree("|", [req.stb & req.is_write for req in requests]))
                ]
@@ -195,42 +166,40 @@ class Multiplexer:
                        if timeout:
                                t = timeout - 1
                                time = Signal(max=t+1)
-                               comb.append(max_time.eq(time == 0))
-                               sync.append(
-                                       If(~en,
+                               self.comb += max_time.eq(time == 0)
+                               self.sync += If(~en,
                                                time.eq(t)
                                        ).Elif(~max_time,
                                                time.eq(time - 1)
                                        )
-                               )
                        else:
-                               comb.append(max_time.eq(0))
+                               self.comb += max_time.eq(0)
                        return en, max_time
-               read_time_en, max_read_time = anti_starvation(self.timing_settings.read_time)
-               write_time_en, max_write_time = anti_starvation(self.timing_settings.write_time)
+               read_time_en, max_read_time = anti_starvation(timing_settings.read_time)
+               write_time_en, max_write_time = anti_starvation(timing_settings.write_time)
                
                # Refresh
-               comb += [bm.refresh_req.eq(self.refresher.req)
-                       for bm in self.bank_machines]
+               self.comb += [bm.refresh_req.eq(refresher.req) for bm in bank_machines]
                go_to_refresh = Signal()
-               comb.append(go_to_refresh.eq(
-                       optree("&", [bm.refresh_gnt for bm in self.bank_machines])))
+               self.comb += go_to_refresh.eq(optree("&", [bm.refresh_gnt for bm in bank_machines]))
                
                # Datapath
-               datapath = _Datapath(self.timing_settings, choose_req.cmd, self.dfi, self.hub)
+               datapath = _Datapath(timing_settings, choose_req.cmd, dfi, hub)
+               self.submodules += datapath
                
                # Control FSM
                fsm = FSM("READ", "WRITE", "REFRESH", delayed_enters=[
-                       ("RTW", "WRITE", self.timing_settings.rd_delay),
-                       ("WTR", "READ", self.timing_settings.tWR)
+                       ("RTW", "WRITE", timing_settings.rd_delay),
+                       ("WTR", "READ", timing_settings.tWR)
                ])
+               self.submodules += fsm
                fsm.act(fsm.READ,
                        read_time_en.eq(1),
                        choose_req.want_reads.eq(1),
                        choose_cmd.cmd.ack.eq(1),
                        choose_req.cmd.ack.eq(1),
-                       steerer.sel[1-self.phy_settings.rdphase].eq(STEER_CMD),
-                       steerer.sel[self.phy_settings.rdphase].eq(STEER_REQ),
+                       steerer.sel[1-phy_settings.rdphase].eq(STEER_CMD),
+                       steerer.sel[phy_settings.rdphase].eq(STEER_REQ),
                        If(write_available,
                                # TODO: switch only after several cycles of ~read_available?
                                If(~read_available | max_read_time, fsm.next_state(fsm.RTW))
@@ -242,8 +211,8 @@ class Multiplexer:
                        choose_req.want_writes.eq(1),
                        choose_cmd.cmd.ack.eq(1),
                        choose_req.cmd.ack.eq(1),
-                       steerer.sel[1-self.phy_settings.wrphase].eq(STEER_CMD),
-                       steerer.sel[self.phy_settings.wrphase].eq(STEER_REQ),
+                       steerer.sel[1-phy_settings.wrphase].eq(STEER_CMD),
+                       steerer.sel[phy_settings.wrphase].eq(STEER_REQ),
                        If(read_available,
                                If(~write_available | max_write_time, fsm.next_state(fsm.WTR))
                        ),
@@ -251,14 +220,7 @@ class Multiplexer:
                )
                fsm.act(fsm.REFRESH,
                        steerer.sel[0].eq(STEER_REFRESH),
-                       If(~self.refresher.req, fsm.next_state(fsm.READ))
+                       If(~refresher.req, fsm.next_state(fsm.READ))
                )
                # FIXME: workaround for zero-delay loop simulation problem with Icarus Verilog
-               comb.append(self.refresher.ack.eq(fsm._state == fsm.REFRESH))
-               
-               return Fragment(comb, sync) + \
-                       choose_cmd.get_fragment() + \
-                       choose_req.get_fragment() + \
-                       steerer.get_fragment() + \
-                       datapath.get_fragment() + \
-                       fsm.get_fragment()
+               self.comb += refresher.ack.eq(fsm._state == fsm.REFRESH)
index 641bb2321bb7bb45f0d05137d6a146688536f40b..3ad0334b3f074cf2cd16ba4e74ad985c65716f5d 100644 (file)
@@ -1,28 +1,23 @@
 from migen.fhdl.structure import *
+from migen.fhdl.module import Module
 from migen.genlib.misc import timeline
 from migen.genlib.fsm import FSM
 
 from milkymist.asmicon.multiplexer import *
 
-class Refresher:
+class Refresher(Module):
        def __init__(self, a, ba, tRP, tREFI, tRFC):
-               self.tRP = tRP
-               self.tREFI = tREFI
-               self.tRFC = tRFC
-               
                self.req = Signal()
                self.ack = Signal() # 1st command 1 cycle after assertion of ack
                self.cmd = CommandRequest(a, ba)
        
-       def get_fragment(self):
-               comb = []
-               sync = []
-               
+               ###
+
                # Refresh sequence generator:
                # PRECHARGE ALL --(tRP)--> AUTO REFRESH --(tRFC)--> done
                seq_start = Signal()
                seq_done = Signal()
-               sync += [
+               self.sync += [
                        self.cmd.a.eq(2**10),
                        self.cmd.ba.eq(0),
                        self.cmd.cas_n.eq(1),
@@ -30,28 +25,28 @@ class Refresher:
                        self.cmd.we_n.eq(1),
                        seq_done.eq(0)
                ]
-               sync += timeline(seq_start, [
+               self.sync += timeline(seq_start, [
                        (1, [
                                self.cmd.ras_n.eq(0),
                                self.cmd.we_n.eq(0)
                        ]),
-                       (1+self.tRP, [
+                       (1+tRP, [
                                self.cmd.cas_n.eq(0),
                                self.cmd.ras_n.eq(0)
                        ]),
-                       (1+self.tRP+self.tRFC, [
+                       (1+tRP+tRFC, [
                                seq_done.eq(1)
                        ])
                ])
                
                # Periodic refresh counter
-               counter = Signal(max=self.tREFI)
+               counter = Signal(max=tREFI)
                start = Signal()
-               sync += [
+               self.sync += [
                        start.eq(0),
                        If(counter == 0,
                                start.eq(1),
-                               counter.eq(self.tREFI - 1)
+                               counter.eq(tREFI - 1)
                        ).Else(
                                counter.eq(counter - 1)
                        )
@@ -59,6 +54,7 @@ class Refresher:
                
                # Control FSM
                fsm = FSM("IDLE", "WAIT_GRANT", "WAIT_SEQ")
+               self.submodules += fsm
                fsm.act(fsm.IDLE, If(start, fsm.next_state(fsm.WAIT_GRANT)))
                fsm.act(fsm.WAIT_GRANT,
                        self.req.eq(1),
@@ -71,5 +67,3 @@ class Refresher:
                        self.req.eq(1),
                        If(seq_done, fsm.next_state(fsm.IDLE))
                )
-               
-               return Fragment(comb, sync) + fsm.get_fragment()
index 014740e9c3188835ea8992c13ffa83ac076d771c..698448504b30ba6f0338f1e2c32e46e8e85c12a0 100644 (file)
@@ -1,36 +1,33 @@
 from migen.fhdl.structure import *
+from migen.fhdl.module import Module
 from migen.bank.description import *
-from migen.bank import csrgen
 
-class ASMIprobe:
-       def __init__(self, address, hub, trace_depth=16):
-               self.hub = hub
-               self.trace_depth = trace_depth
-               
-               slot_count = len(self.hub.get_slots())
-               assert(self.trace_depth < 256)
+class ASMIprobe(Module):
+       def __init__(self, hub, trace_depth=16):
+               slots = hub.get_slots()
+               slot_count = len(slots)
+               assert(trace_depth < 256)
                assert(slot_count < 256)
                
                self._slot_count = RegisterField("slot_count", 8, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
                self._trace_depth = RegisterField("trace_depth", 8, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
-               self._slot_status = [RegisterField("slot_status", 2, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
+               self._slot_status = [RegisterField("slot_status" + str(i), 2, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
                        for i in range(slot_count)]
-               self._trace = [RegisterField("trace", 8, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
-                       for i in range(self.trace_depth)]
+               self._trace = [RegisterField("trace" + str(i), 8, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
+                       for i in range(trace_depth)]
 
-               self.bank = csrgen.Bank([self._slot_count, self._trace_depth]
-                       + self._slot_status + self._trace, address=address)
-       
-       def get_fragment(self):
-               slots = self.hub.get_slots()
-               comb = [
-                       self._slot_count.field.w.eq(len(slots)),
-                       self._trace_depth.field.w.eq(self.trace_depth)
+               ###
+               
+               self.comb += [
+                       self._slot_count.field.w.eq(slot_count),
+                       self._trace_depth.field.w.eq(trace_depth)
                ]
                for slot, status in zip(slots, self._slot_status):
-                       comb.append(status.field.w.eq(slot.state))
+                       self.comb += status.field.w.eq(slot.state)
                shift_tags = [self._trace[n].field.w.eq(self._trace[n+1].field.w)
                        for n in range(len(self._trace) - 1)]
-               shift_tags.append(self._trace[-1].field.w.eq(self.hub.tag_call))
-               sync = [If(self.hub.call, *shift_tags)]
-               return Fragment(comb, sync) + self.bank.get_fragment()
+               shift_tags.append(self._trace[-1].field.w.eq(hub.tag_call))
+               self.sync += If(hub.call, *shift_tags)
+
+       def get_registers(self):
+               return [self._slot_count, self._trace_depth] + self._slot_status + self._trace
index cedca621297170e3bece3d0d33739880e124eb0d..dc71c8204681d18c166d4f5543e8f39983994c30 100644 (file)
@@ -1,12 +1,10 @@
 from migen.fhdl.structure import *
+from migen.fhdl.module import Module
 from migen.bus import dfi
 from migen.bank.description import *
-from migen.bank import csrgen
 
-class PhaseInjector:
+class PhaseInjector(Module, AutoReg):
        def __init__(self, phase):
-               self.phase = phase
-               
                self._cs = Field("cs", 1, WRITE_ONLY, READ_ONLY)
                self._we = Field("we", 1, WRITE_ONLY, READ_ONLY)
                self._cas = Field("cas", 1, WRITE_ONLY, READ_ONLY)
@@ -17,45 +15,38 @@ class PhaseInjector:
                        [self._cs, self._we, self._cas, self._ras, self._wren, self._rden])
                self._command_issue = RegisterRaw("command_issue")
                
-               self._address = RegisterField("address", len(self.phase.address))
-               self._baddress = RegisterField("baddress", len(self.phase.bank))
+               self._address = RegisterField("address", len(phase.address))
+               self._baddress = RegisterField("baddress", len(phase.bank))
                
-               self._wrdata = RegisterField("wrdata", len(self.phase.wrdata))
-               self._rddata = RegisterField("rddata", len(self.phase.rddata), READ_ONLY, WRITE_ONLY)
+               self._wrdata = RegisterField("wrdata", len(phase.wrdata))
+               self._rddata = RegisterField("rddata", len(phase.rddata), READ_ONLY, WRITE_ONLY)
        
-       def get_registers(self):
-               return [self._command, self._command_issue,
-                       self._address, self._baddress,
-                       self._wrdata, self._rddata]
-               
-       def get_fragment(self):
-               comb = [
+               ###
+
+               self.comb += [
                        If(self._command_issue.re,
-                               self.phase.cs_n.eq(~self._cs.r),
-                               self.phase.we_n.eq(~self._we.r),
-                               self.phase.cas_n.eq(~self._cas.r),
-                               self.phase.ras_n.eq(~self._ras.r)
+                               phase.cs_n.eq(~self._cs.r),
+                               phase.we_n.eq(~self._we.r),
+                               phase.cas_n.eq(~self._cas.r),
+                               phase.ras_n.eq(~self._ras.r)
                        ).Else(
-                               self.phase.cs_n.eq(1),
-                               self.phase.we_n.eq(1),
-                               self.phase.cas_n.eq(1),
-                               self.phase.ras_n.eq(1)
+                               phase.cs_n.eq(1),
+                               phase.we_n.eq(1),
+                               phase.cas_n.eq(1),
+                               phase.ras_n.eq(1)
                        ),
-                       self.phase.address.eq(self._address.field.r),
-                       self.phase.bank.eq(self._baddress.field.r),
-                       self.phase.wrdata_en.eq(self._command_issue.re & self._wren.r),
-                       self.phase.rddata_en.eq(self._command_issue.re & self._rden.r),
-                       self.phase.wrdata.eq(self._wrdata.field.r),
-                       self.phase.wrdata_mask.eq(0)
-               ]
-               sync = [
-                       If(self.phase.rddata_valid, self._rddata.field.w.eq(self.phase.rddata))
+                       phase.address.eq(self._address.field.r),
+                       phase.bank.eq(self._baddress.field.r),
+                       phase.wrdata_en.eq(self._command_issue.re & self._wren.r),
+                       phase.rddata_en.eq(self._command_issue.re & self._rden.r),
+                       phase.wrdata.eq(self._wrdata.field.r),
+                       phase.wrdata_mask.eq(0)
                ]
-               return Fragment(comb, sync)
+               self.sync += If(phase.rddata_valid, self._rddata.field.w.eq(phase.rddata))
 
-class DFIInjector:
-       def __init__(self, csr_address, a, ba, d, nphases=1):
-               self._int = dfi.Interface(a, ba, d, nphases)
+class DFIInjector(Module, AutoReg):
+       def __init__(self, a, ba, d, nphases=1):
+               inti = dfi.Interface(a, ba, d, nphases)
                self.slave = dfi.Interface(a, ba, d, nphases)
                self.master = dfi.Interface(a, ba, d, nphases)
                
@@ -63,19 +54,12 @@ class DFIInjector:
                self._cke = Field("cke")
                self._control = RegisterFields("control", [self._sel, self._cke])
                
-               self._phase_injectors = [PhaseInjector(phase) for phase in self._int.phases]
-               
-               registers = sum([pi.get_registers() for pi in self._phase_injectors], [self._control])
-               self.bank = csrgen.Bank(registers, address=csr_address)
+               for n, phase in enumerate(inti.phases):
+                       setattr(self.submodules, "pi" + str(n), PhaseInjector(phase))
+       
+               ###
        
-       def get_fragment(self):
-               connect_int = dfi.interconnect_stmts(self._int, self.master)
+               connect_inti = dfi.interconnect_stmts(inti, self.master)
                connect_slave = dfi.interconnect_stmts(self.slave, self.master)
-               comb = [
-                       If(self._sel.r, *connect_slave).Else(*connect_int)
-               ]
-               comb += [phase.cke.eq(self._cke.r) for phase in self._int.phases]
-               
-               return Fragment(comb) \
-                       + sum([pi.get_fragment() for pi in self._phase_injectors], Fragment()) \
-                       + self.bank.get_fragment()
+               self.comb += If(self._sel.r, *connect_slave).Else(*connect_inti)
+               self.comb += [phase.cke.eq(self._cke.r) for phase in inti.phases]
index 4106ce8cdb3697ee439760fec07e5ceb717e0969..f0b6b1c3de120a697b9f5517caa5b593a372c094 100644 (file)
@@ -1,12 +1,12 @@
 from migen.fhdl.structure import *
 from migen.fhdl.specials import Instance
+from migen.fhdl.module import Module
 from migen.flow.actor import *
 from migen.flow.network import *
 from migen.flow.transactions import *
 from migen.flow import plumbing
 from migen.actorlib import misc, dma_asmi, structuring, sim, spi
 from migen.bank.description import *
-from migen.bank import csrgen
 
 _hbits = 11
 _vbits = 11
@@ -47,7 +47,7 @@ class _FrameInitiator(spi.SingleGenerator):
                ]
                spi.SingleGenerator.__init__(self, layout, spi.MODE_CONTINUOUS)
 
-class VTG(Actor):
+class VTG(Module, Actor):
        def __init__(self):
                Actor.__init__(self,
                        ("timing", Sink, [
@@ -62,8 +62,7 @@ class VTG(Actor):
                        ("pixels", Sink, _pixel_layout),
                        ("dac", Source, _dac_layout)
                )
-       
-       def get_fragment(self):
+
                hactive = Signal()
                vactive = Signal()
                active = Signal()
@@ -73,7 +72,7 @@ class VTG(Actor):
                vcounter = Signal(_vbits)
                
                skip = _bpc - _bpc_dac
-               comb = [
+               self.comb += [
                        active.eq(hactive & vactive),
                        If(active,
                                self.token("dac").r.eq(self.token("pixels").r[skip:]),
@@ -86,7 +85,7 @@ class VTG(Actor):
                        self.endpoints["dac"].stb.eq(generate_en)
                ]
                tp = self.token("timing")
-               sync = [
+               self.sync += [
                        self.endpoints["timing"].ack.eq(0),
                        If(generate_en & self.endpoints["dac"].ack,
                                hcounter.eq(hcounter + 1),
@@ -111,10 +110,8 @@ class VTG(Actor):
                                If(vcounter == tp.vsync_end, self.token("dac").vsync.eq(0))
                        )
                ]
-               
-               return Fragment(comb, sync)
 
-class FIFO(Actor):
+class FIFO(Module, Actor):
        def __init__(self):
                Actor.__init__(self, ("dac", Sink, _dac_layout))
                
@@ -124,13 +121,14 @@ class FIFO(Actor):
                self.vga_g = Signal(_bpc_dac)
                self.vga_b = Signal(_bpc_dac)
        
-       def get_fragment(self):
+               ###
+
                data_width = 2+3*_bpc_dac
                fifo_full = Signal()
                fifo_write_en = Signal()
                fifo_data_out = Signal(data_width)
                fifo_data_in = Signal(data_width)
-               asfifo = Instance("asfifo",
+               self.specials += Instance("asfifo",
                        Instance.Parameter("data_width", data_width),
                        Instance.Parameter("address_width", 8),
        
@@ -146,17 +144,15 @@ class FIFO(Actor):
                        
                        Instance.Input("rst", 0))
                t = self.token("dac")
-               return Fragment(
-                       [
-                               Cat(self.vga_hsync_n, self.vga_vsync_n, self.vga_r, self.vga_g, self.vga_b).eq(asfifo.get_io("data_out")),
-                               
-                               self.endpoints["dac"].ack.eq(~fifo_full),
-                               fifo_write_en.eq(self.endpoints["dac"].stb),
-                               fifo_data_in.eq(Cat(~t.hsync, ~t.vsync, t.r, t.g, t.b)),
-                               
-                               self.busy.eq(0)
-                       ],
-                       specials={asfifo})
+               self.comb += [
+                       Cat(self.vga_hsync_n, self.vga_vsync_n, self.vga_r, self.vga_g, self.vga_b).eq(fifo_data_out),
+                       
+                       self.endpoints["dac"].ack.eq(~fifo_full),
+                       fifo_write_en.eq(self.endpoints["dac"].stb),
+                       fifo_data_in.eq(Cat(~t.hsync, ~t.vsync, t.r, t.g, t.b)),
+                       
+                       self.busy.eq(0)
+               ]
 
 def sim_fifo_gen():
        while True:
@@ -165,9 +161,8 @@ def sim_fifo_gen():
                print("H/V:" + str(t.value["hsync"]) + str(t.value["vsync"])
                        + " " + str(t.value["r"]) + " " + str(t.value["g"]) + " " + str(t.value["b"]))
 
-
-class Framebuffer:
-       def __init__(self, address, asmiport, simulation=False):
+class Framebuffer(Module):
+       def __init__(self, asmiport, simulation=False):
                asmi_bits = asmiport.hub.aw
                alignment_bits = bits_for(asmiport.hub.dw//8) - 1
                length_bits = _hbits + _vbits + 2 - alignment_bits
@@ -199,10 +194,9 @@ class Framebuffer:
                        "hres", "hsync_start", "hsync_end", "hscan", 
                        "vres", "vsync_start", "vsync_end", "vscan"])
                g.add_connection(vtg, fifo)
-               self._comp_actor = CompositeActor(g, debugger=False)
+               self.submodules._comp_actor = CompositeActor(g, debugger=False)
                
-               self.bank = csrgen.Bank(fi.get_registers() + self._comp_actor.get_registers(),
-                       address=address)
+               self._registers = fi.get_registers() + self._comp_actor.get_registers()
                
                # Pads
                self.vga_psave_n = Signal()
@@ -216,12 +210,11 @@ class Framebuffer:
                        self.vga_g = fifo.vga_g
                        self.vga_b = fifo.vga_b
 
-       def get_fragment(self):
-               comb = [
+               self.comb += [
                        self.vga_sync_n.eq(0),
                        self.vga_psave_n.eq(1),
                        self.vga_blank_n.eq(1)
                ]
-               return self.bank.get_fragment() \
-                       + self._comp_actor.get_fragment() \
-                       + Fragment(comb)
+
+       def get_registers(self):
+               return self._registers
index 9ddeda789d717af5ac55c3338ba7ba558783c579..8d56f27c55a9fc689b3af0a75d663a8b11c88c3f 100644 (file)
@@ -1,8 +1,8 @@
+import re
+
 from migen.fhdl.structure import *
+from migen.fhdl.module import Module
 from migen.bank.description import *
-from migen.bank import csrgen
-
-import re
 
 def encode_version(version):
        match = re.match("(\d+)\.(\d+)(\.(\d+))?(rc(\d+))?", version, re.IGNORECASE)
@@ -15,22 +15,16 @@ def encode_version(version):
                r |= int(rc)
        return r
 
-class Identifier:
-       def __init__(self, address, sysid, version, frequency):
-               self.sysid = sysid
-               self.version = encode_version(version)
-               self.frequency = frequency
-               
+class Identifier(Module, AutoReg):
+       def __init__(self, sysid, version, frequency):
                self._r_sysid = RegisterField("sysid", 16, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
                self._r_version = RegisterField("version", 16, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
                self._r_frequency = RegisterField("frequency", 32, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
-               regs = [self._r_sysid, self._r_version, self._r_frequency]
-               self.bank = csrgen.Bank(regs, address=address)
                
-       def get_fragment(self):
-               comb = [
-                       self._r_sysid.field.w.eq(self.sysid),
-                       self._r_version.field.w.eq(self.version),
-                       self._r_frequency.field.w.eq(self.frequency)
+               ###
+
+               self.comb += [
+                       self._r_sysid.field.w.eq(sysid),
+                       self._r_version.field.w.eq(encode_version(version)),
+                       self._r_frequency.field.w.eq(frequency)
                ]
-               return self.bank.get_fragment() + Fragment(comb)
index e2c743f981745917762b25b700e1da86f04b60c3..6f398498c811d70b786e273ba6194019c8935ca8 100644 (file)
@@ -1,23 +1,27 @@
 from migen.fhdl.structure import *
 from migen.fhdl.specials import Instance
+from migen.fhdl.module import Module
 from migen.bus import wishbone
 
-class LM32:
+class LM32(Module):
        def __init__(self):
                self.ibus = i = wishbone.Interface()
                self.dbus = d = wishbone.Interface()
                self.interrupt = Signal(32)
                self.ext_break = Signal()
-               self._i_adr_o = Signal(32)
-               self._d_adr_o = Signal(32)
-               self._inst = Instance("lm32_top",
+
+               ###
+
+               i_adr_o = Signal(32)
+               d_adr_o = Signal(32)
+               self.specials += Instance("lm32_top",
                        Instance.ClockPort("clk_i"),
                        Instance.ResetPort("rst_i"),
                        
                        Instance.Input("interrupt", self.interrupt),
                        #Instance.Input("ext_break", self.ext_break),
                
-                       Instance.Output("I_ADR_O", self._i_adr_o),
+                       Instance.Output("I_ADR_O", i_adr_o),
                        Instance.Output("I_DAT_O", i.dat_w),
                        Instance.Output("I_SEL_O", i.sel),
                        Instance.Output("I_CYC_O", i.cyc),
@@ -31,7 +35,7 @@ class LM32:
                        Instance.Input("I_ERR_I", i.err),
                        Instance.Input("I_RTY_I", 0),
                        
-                       Instance.Output("D_ADR_O", self._d_adr_o),
+                       Instance.Output("D_ADR_O", d_adr_o),
                        Instance.Output("D_DAT_O", d.dat_w),
                        Instance.Output("D_SEL_O", d.sel),
                        Instance.Output("D_CYC_O", d.cyc),
@@ -45,9 +49,7 @@ class LM32:
                        Instance.Input("D_ERR_I", d.err),
                        Instance.Input("D_RTY_I", 0))
 
-       def get_fragment(self):
-               comb = [
-                       self.ibus.adr.eq(self._i_adr_o[2:]),
-                       self.dbus.adr.eq(self._d_adr_o[2:])
+               self.comb += [
+                       self.ibus.adr.eq(i_adr_o[2:]),
+                       self.dbus.adr.eq(d_adr_o[2:])
                ]
-               return Fragment(comb, specials={self._inst})
index baef94975bbecfa1574c38111565860273efac80..8218a5061e2065a4f246a85a13508780bb0ae8e2 100644 (file)
@@ -2,9 +2,10 @@ from fractions import Fraction
 
 from migen.fhdl.structure import *
 from migen.fhdl.specials import Instance
+from migen.fhdl.module import Module
 from mibuild.crg import CRG
 
-class M1CRG(CRG):
+class M1CRG(Module, CRG):
        def __init__(self, infreq, outfreq1x):
                self.clk50_pad = Signal()
                self.trigger_reset = Signal()
@@ -56,7 +57,4 @@ class M1CRG(CRG):
                        setattr(self, name, s)
                        inst_items.append(Instance.Output(name, s))  
                
-               self._inst = Instance("m1crg", *inst_items)
-
-       def get_fragment(self):
-               return Fragment(specials={self._inst})
+               self.specials += Instance("m1crg", *inst_items)
index 8c8d68d40f6ea195fff8214f8eef3fb42c683760..cdbdf45edd989454c9c54ff9230d5cb5cad08a87 100644 (file)
@@ -1,14 +1,14 @@
 from migen.fhdl.structure import *
 from migen.fhdl.specials import Instance
+from migen.fhdl.module import Module
 from migen.bank.description import *
 from migen.bank.eventmanager import *
-from migen.bank import csrgen
 from migen.bus import wishbone
 
 _count_width = 11
 
-class MiniMAC:
-       def __init__(self, address):
+class MiniMAC(Module, AutoReg):
+       def __init__(self):
                # PHY signals
                self.phy_tx_clk = Signal()
                self.phy_tx_data = Signal(4)
@@ -28,52 +28,52 @@ class MiniMAC:
                self._rx_count_1 = RegisterField("rx_count_1", _count_width, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
                self._tx_count = RegisterField("tx_count", _count_width, access_dev=READ_WRITE)
                self._tx_start = RegisterRaw("tx_start")
-               regs = [self._phy_reset, self._rx_count_0, self._rx_count_1, self._tx_count, self._tx_start]
                
-               self._rx_event_0 = EventSourcePulse()
-               self._rx_event_1 = EventSourcePulse()
-               self._tx_event = EventSourcePulse()
-               self.events = EventManager(self._rx_event_0, self._rx_event_1, self._tx_event)
+               self.submodules.ev = EventManager()
+               self.ev.rx0 = EventSourcePulse()
+               self.ev.rx1 = EventSourcePulse()
+               self.ev.tx = EventSourcePulse()
+               self.ev.finalize()
                
-               self.bank = csrgen.Bank(regs + self.events.get_registers(), address=address)
                self.membus = wishbone.Interface()
                
-       def get_fragment(self):
+               ###
+
                init = Signal(reset=1)
+               self.sync += init.eq(0)
                rx_ready_0 = Signal()
                rx_ready_1 = Signal()
-               rx_pending_0 = self._rx_event_0.pending
-               rx_pending_1 = self._rx_event_1.pending
+               rx_pending_0 = self.ev.rx0.pending
+               rx_pending_1 = self.ev.rx1.pending
                rx_pending_0_r = Signal()
                rx_pending_1_r = Signal()
-               comb = [
+               self.comb += [
                        self.phy_rst_n.eq(~self._phy_reset.field.r),
                        
                        rx_ready_0.eq(init | (rx_pending_0_r & ~rx_pending_0)),
                        rx_ready_1.eq(init | (rx_pending_1_r & ~rx_pending_1)),
                        
                        self._tx_count.field.w.eq(0),
-                       self._tx_count.field.we.eq(self._tx_event.trigger)
+                       self._tx_count.field.we.eq(self.ev.tx.trigger)
                ]
-               sync = [
-                       init.eq(0),
+               self.sync += [
                        rx_pending_0_r.eq(rx_pending_0),
                        rx_pending_1_r.eq(rx_pending_1)
                ]
-               inst = Instance("minimac3",
+               self.specials += Instance("minimac3",
                                Instance.ClockPort("sys_clk"),
                                Instance.ResetPort("sys_rst"),
 
-                               Instance.Output("rx_done_0", self._rx_event_0.trigger),
+                               Instance.Output("rx_done_0", self.ev.rx0.trigger),
                                Instance.Output("rx_count_0", self._rx_count_0.field.w),
-                               Instance.Output("rx_done_1", self._rx_event_1.trigger),
+                               Instance.Output("rx_done_1", self.ev.rx1.trigger),
                                Instance.Output("rx_count_1", self._rx_count_1.field.w),
                                Instance.Input("rx_ready_0", rx_ready_0),
                                Instance.Input("rx_ready_1", rx_ready_1),
 
                                Instance.Input("tx_start", self._tx_start.re),
                                Instance.Input("tx_count", self._tx_count.field.r),
-                               Instance.Output("tx_done", self._tx_event.trigger),
+                               Instance.Output("tx_done", self.ev.tx.trigger),
                                
                                Instance.Input("wb_adr_i", self.membus.adr),
                                Instance.Input("wb_dat_i", self.membus.dat_w),
@@ -94,6 +94,3 @@ class MiniMAC:
                                Instance.Input("phy_rx_er", self.phy_rx_er),
                                Instance.Input("phy_col", self.phy_col),
                                Instance.Input("phy_crs", self.phy_crs))
-               return Fragment(comb, sync, specials={inst}) \
-                       + self.events.get_fragment() \
-                       + self.bank.get_fragment()
index e8e97f3124f4c3817d92fbd414be540bc760e2e8..f88d881891f222a4029276b05771cba1b35650f2 100644 (file)
@@ -1,12 +1,10 @@
 from migen.fhdl.structure import *
+from migen.fhdl.module import Module
 from migen.bus import wishbone
 from migen.genlib.misc import timeline
 
-class NorFlash:
+class NorFlash(Module):
        def __init__(self, adr_width, rd_timing):
-               self.adr_width = adr_width
-               self.rd_timing = rd_timing
-               
                self.bus = wishbone.Interface()
                self.adr = Signal(adr_width-1)
                self.d = Signal(16)
@@ -14,18 +12,18 @@ class NorFlash:
                self.we_n = Signal()
                self.ce_n = Signal()
        
-       def get_fragment(self):
-               comb = [self.oe_n.eq(0), self.we_n.eq(1),
+               ###
+       
+               self.comb += [self.oe_n.eq(0), self.we_n.eq(1),
                        self.ce_n.eq(0)]
-               sync = timeline(self.bus.cyc & self.bus.stb, [
-                       (0, [self.adr.eq(Cat(0, self.bus.adr[:self.adr_width-2]))]),
-                       (self.rd_timing, [
+               self.sync += timeline(self.bus.cyc & self.bus.stb, [
+                       (0, [self.adr.eq(Cat(0, self.bus.adr[:adr_width-2]))]),
+                       (rd_timing, [
                                self.bus.dat_r[16:].eq(self.d),
-                               self.adr.eq(Cat(1, self.bus.adr[:self.adr_width-2]))]),
-                       (2*self.rd_timing, [
+                               self.adr.eq(Cat(1, self.bus.adr[:adr_width-2]))]),
+                       (2*rd_timing, [
                                self.bus.dat_r[:16].eq(self.d),
                                self.bus.ack.eq(1)]),
-                       (2*self.rd_timing + 1, [
+                       (2*rd_timing + 1, [
                                self.bus.ack.eq(0)])
                ])
-               return Fragment(comb, sync)
index 3f16baf1f6254e7810eb2424fbe12c32fc38f6b5..873f7d332a81b0d44c2317f3fe07c1a947503bf3 100644 (file)
@@ -1,8 +1,9 @@
 from migen.fhdl.structure import *
 from migen.fhdl.specials import Instance
+from migen.fhdl.module import Module
 from migen.bus import dfi
 
-class S6DDRPHY:
+class S6DDRPHY(Module):
        def __init__(self, a, ba, d):
                inst_items = [
                        Instance.Parameter("NUM_AD", a),
@@ -39,7 +40,4 @@ class S6DDRPHY:
                inst_items += [Instance.Output(name, signal)
                        for name, signal in self.dfi.get_standard_names(False, True)]
                
-               self._inst = Instance("s6ddrphy", *inst_items)
-
-       def get_fragment(self):
-               return Fragment(specials={self._inst})
+               self.specials += Instance("s6ddrphy", *inst_items)
index 85b5cb53ab5cdb195ece10110eea3a346d650fb7..be51d33a8509ce56f68eb918d5f867308d5778c1 100644 (file)
@@ -1,30 +1,26 @@
 from migen.fhdl.structure import *
+from migen.fhdl.module import Module
 from migen.bank.description import *
 from migen.bank.eventmanager import *
-from migen.bank import csrgen
 
-class Timer:
-       def __init__(self, address, width=32):
+class Timer(Module, AutoReg):
+       def __init__(self, width=32):
                self._en = RegisterField("en")
                self._value = RegisterField("value", width, access_dev=READ_WRITE)
                self._reload = RegisterField("reload", width)
-               regs = [self._en, self._value, self._reload]
                
-               self.event = EventSourceLevel()
-               self.events = EventManager(self.event)
-               
-               self.bank = csrgen.Bank(regs + self.events.get_registers(), address=address)
+               self.submodules.ev = EventManager()
+               self.ev.zero = EventSourceLevel()
+               self.ev.finalize()
+
+               ###
 
-       def get_fragment(self):
-               comb = [
+               self.comb += [
                        If(self._value.field.r == 0,
                                self._value.field.w.eq(self._reload.field.r)
                        ).Else(
                                self._value.field.w.eq(self._value.field.r - 1)
                        ),
                        self._value.field.we.eq(self._en.field.r),
-                       self.event.trigger.eq(self._value.field.r != 0)
+                       self.ev.zero.trigger.eq(self._value.field.r != 0)
                ]
-               return Fragment(comb) \
-                       + self.events.get_fragment() \
-                       + self.bank.get_fragment()
index 597885ff5d6895e200bd0a427c1db76238c3ae79..d1eca795022459bf44f2d03f2ee57d7fffce6fd5 100644 (file)
@@ -1,29 +1,28 @@
 from migen.fhdl.structure import *
+from migen.fhdl.module import Module
+from migen.genlib.cdc import MultiReg
 from migen.bank.description import *
 from migen.bank.eventmanager import *
-from migen.bank import csrgen
 
-class UART:
-       def __init__(self, address, clk_freq, baud=115200):
+class UART(Module, AutoReg):
+       def __init__(self, clk_freq, baud=115200):
                self._rxtx = RegisterRaw("rxtx", 8)
                self._divisor = RegisterField("divisor", 16, reset=int(clk_freq/baud/16))
                
-               self._tx_event = EventSourceLevel()
-               self._rx_event = EventSourcePulse()
-               self.events = EventManager(self._tx_event, self._rx_event)
-               self.bank = csrgen.Bank([self._rxtx, self._divisor] + self.events.get_registers(),
-                       address=address)
+               self.submodules.ev = EventManager()
+               self.ev.tx = EventSourceLevel()
+               self.ev.rx = EventSourcePulse()
+               self.ev.finalize()
 
                self.tx = Signal(reset=1)
                self.rx = Signal()
        
-       def get_fragment(self):
+               ###
+
                enable16 = Signal()
                enable16_counter = Signal(16)
-               comb = [
-                       enable16.eq(enable16_counter == 0)
-               ]
-               sync = [
+               self.comb += enable16.eq(enable16_counter == 0)
+               self.sync += [
                        enable16_counter.eq(enable16_counter - 1),
                        If(enable16,
                                enable16_counter.eq(self._divisor.field.r - 1))
@@ -33,8 +32,8 @@ class UART:
                tx_reg = Signal(8)
                tx_bitcount = Signal(4)
                tx_count16 = Signal(4)
-               tx_busy = self._tx_event.trigger
-               sync += [
+               tx_busy = self.ev.tx.trigger
+               self.sync += [
                        If(self._rxtx.re,
                                tx_reg.eq(self._rxtx.r),
                                tx_bitcount.eq(0),
@@ -59,20 +58,16 @@ class UART:
                ]
                
                # RX
-               rx0 = Signal() # sychronize
                rx = Signal()
-               sync += [
-                       rx0.eq(self.rx),
-                       rx.eq(rx0)
-               ]
+               self.specials += MultiReg(self.rx, "ext", rx, "sys")
                rx_r = Signal()
                rx_reg = Signal(8)
                rx_bitcount = Signal(4)
                rx_count16 = Signal(4)
                rx_busy = Signal()
-               rx_done = self._rx_event.trigger
+               rx_done = self.ev.rx.trigger
                rx_data = self._rxtx.w
-               sync += [
+               self.sync += [
                        rx_done.eq(0),
                        If(enable16,
                                rx_r.eq(rx),
@@ -104,7 +99,3 @@ class UART:
                                )
                        )
                ]
-               
-               return self.bank.get_fragment() \
-                       + self.events.get_fragment() \
-                       + Fragment(comb, sync)
diff --git a/software/include/hw/id.h b/software/include/hw/id.h
deleted file mode 100644 (file)
index 574dbb6..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef __HW_ID_H
-#define __HW_ID_H
-
-#include <hw/common.h>
-#include <csrbase.h>
-
-#define ID_CSR(x)              MMPTR(ID_BASE+(x))
-
-#define CSR_ID_SYSTEMH         ID_CSR(0x00)
-#define CSR_ID_SYSTEML         ID_CSR(0x04)
-#define CSR_ID_VERSIONH                ID_CSR(0x08)
-#define CSR_ID_VERSIONL                ID_CSR(0x0C)
-#define CSR_ID_FREQ3           ID_CSR(0x10)
-#define CSR_ID_FREQ2           ID_CSR(0x14)
-#define CSR_ID_FREQ1           ID_CSR(0x18)
-#define CSR_ID_FREQ0           ID_CSR(0x1C)
-
-#endif /* __HW_ID_H */
diff --git a/software/include/hw/identifier.h b/software/include/hw/identifier.h
new file mode 100644 (file)
index 0000000..3c13ca9
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef __HW_IDENTIFIER_H
+#define __HW_IDENTIFIER_H
+
+#include <hw/common.h>
+#include <csrbase.h>
+
+#define IDENTIFIER_CSR(x)              MMPTR(IDENTIFIER_BASE+(x))
+
+#define CSR_IDENTIFIER_SYSTEMH         IDENTIFIER_CSR(0x00)
+#define CSR_IDENTIFIER_SYSTEML         IDENTIFIER_CSR(0x04)
+#define CSR_IDENTIFIER_VERSIONH                IDENTIFIER_CSR(0x08)
+#define CSR_IDENTIFIER_VERSIONL                IDENTIFIER_CSR(0x0C)
+#define CSR_IDENTIFIER_FREQ3           IDENTIFIER_CSR(0x10)
+#define CSR_IDENTIFIER_FREQ2           IDENTIFIER_CSR(0x14)
+#define CSR_IDENTIFIER_FREQ1           IDENTIFIER_CSR(0x18)
+#define CSR_IDENTIFIER_FREQ0           IDENTIFIER_CSR(0x1C)
+
+#endif /* __HW_IDENTIFIER_H */
index b58900a22290e2f67bbdb748cb622a556c140bb5..97b18a3bc940de215d0a2b47db5f2d16f10fbab3 100644 (file)
@@ -1,4 +1,4 @@
-#include <hw/id.h>
+#include <hw/identifier.h>
 #include <hw/gpio.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -27,7 +27,7 @@ static const struct board_desc *get_board_desc_id(unsigned short int id)
 
 static const struct board_desc *get_board_desc(void)
 {
-       return get_board_desc_id((CSR_ID_SYSTEMH << 8) | CSR_ID_SYSTEML);
+       return get_board_desc_id((CSR_IDENTIFIER_SYSTEMH << 8) | CSR_IDENTIFIER_SYSTEML);
 }
 
 int get_pcb_revision(void)
@@ -54,10 +54,10 @@ void get_soc_version(unsigned int *major, unsigned int *minor, unsigned int *sub
 {
        unsigned int id;
 
-       id = CSR_ID_VERSIONH;
+       id = CSR_IDENTIFIER_VERSIONH;
        *major = (id & 0xf0) >> 4;
        *minor = id & 0x0f;
-       id = CSR_ID_VERSIONL;
+       id = CSR_IDENTIFIER_VERSIONL;
        *subminor = (id & 0xf0) >> 4;
        *rc = id & 0x0f;
 }
index c2c4b9da3ef291bac6a2e631d4c767ad29fac6bb..ea25eb5e8f4bad1316fa03bc552c8ee394ba4acb 100644 (file)
@@ -1,14 +1,14 @@
 #include <hw/timer.h>
-#include <hw/id.h>
+#include <hw/identifier.h>
 
 #include "timer.h"
 
 unsigned int get_system_frequency(void)
 {
-       return (CSR_ID_FREQ3 << 24)
-               |(CSR_ID_FREQ2 << 16)
-               |(CSR_ID_FREQ1 << 8)
-               |CSR_ID_FREQ0;
+       return (CSR_IDENTIFIER_FREQ3 << 24)
+               |(CSR_IDENTIFIER_FREQ2 << 16)
+               |(CSR_IDENTIFIER_FREQ1 << 8)
+               |CSR_IDENTIFIER_FREQ0;
 }
 
 void timer_enable(int en)
diff --git a/top.py b/top.py
index 70e1e78b570b8f11564ff292d8190711a93d1400..715183ace73b75e77b558afef76a7ec76f74e60c 100644 (file)
--- a/top.py
+++ b/top.py
@@ -2,8 +2,9 @@ from fractions import Fraction
 from math import ceil
 
 from migen.fhdl.structure import *
-from migen.fhdl import verilog, autofragment
+from migen.fhdl.module import Module
 from migen.bus import wishbone, wishbone2asmi, csr, wishbone2csr, dfi
+from migen.bank import csrgen
 
 from milkymist import m1crg, lm32, norflash, uart, s6ddrphy, dfii, asmicon, \
        identifier, timer, minimac3, framebuffer, asmiprobe
@@ -57,12 +58,17 @@ def interrupt_n(name):
 
 version = get_macros("common/version.h")["VERSION"][1:-1]
 
-class SoC:
+def csr_address_map(name, memory):
+       if memory is not None:
+               name += "_" + memory.name_override
+       return csr_offset(name.upper())
+
+class SoC(Module):
        def __init__(self):
                #
                # ASMI
                #
-               self.asmicon = asmicon.ASMIcon(sdram_phy, sdram_geom, sdram_timing)
+               self.submodules.asmicon = asmicon.ASMIcon(sdram_phy, sdram_geom, sdram_timing)
                asmiport_wb = self.asmicon.hub.get_port()
                asmiport_fb = self.asmicon.hub.get_port(2)
                self.asmicon.finalize()
@@ -70,21 +76,21 @@ class SoC:
                #
                # DFI
                #
-               self.ddrphy = s6ddrphy.S6DDRPHY(sdram_geom.mux_a, sdram_geom.bank_a, sdram_phy.dfi_d)
-               self.dfii = dfii.DFIInjector(csr_offset("DFII"),
-                       sdram_geom.mux_a, sdram_geom.bank_a, sdram_phy.dfi_d, sdram_phy.nphases)
-               self.dficon0 = dfi.Interconnect(self.dfii.master, self.ddrphy.dfi)
-               self.dficon1 = dfi.Interconnect(self.asmicon.dfi, self.dfii.slave)
+               self.submodules.ddrphy = s6ddrphy.S6DDRPHY(sdram_geom.mux_a, sdram_geom.bank_a, sdram_phy.dfi_d)
+               self.submodules.dfii = dfii.DFIInjector(sdram_geom.mux_a, sdram_geom.bank_a, sdram_phy.dfi_d,
+                       sdram_phy.nphases)
+               self.submodules.dficon0 = dfi.Interconnect(self.dfii.master, self.ddrphy.dfi)
+               self.submodules.dficon1 = dfi.Interconnect(self.asmicon.dfi, self.dfii.slave)
 
                #
                # WISHBONE
                #
-               self.cpu = lm32.LM32()
-               self.norflash = norflash.NorFlash(25, 12)
-               self.sram = wishbone.SRAM(sram_size)
-               self.minimac = minimac3.MiniMAC(csr_offset("MINIMAC"))
-               self.wishbone2asmi = wishbone2asmi.WB2ASMI(l2_size//4, asmiport_wb)
-               self.wishbone2csr = wishbone2csr.WB2CSR()
+               self.submodules.cpu = lm32.LM32()
+               self.submodules.norflash = norflash.NorFlash(25, 12)
+               self.submodules.sram = wishbone.SRAM(sram_size)
+               self.submodules.minimac = minimac3.MiniMAC()
+               self.submodules.wishbone2asmi = wishbone2asmi.WB2ASMI(l2_size//4, asmiport_wb)
+               self.submodules.wishbone2csr = wishbone2csr.WB2CSR()
                
                # norflash     0x00000000 (shadow @0x80000000)
                # SRAM/debug   0x10000000 (shadow @0x90000000)
@@ -92,7 +98,7 @@ class SoC:
                # Ethernet     0x30000000 (shadow @0xb0000000)
                # SDRAM        0x40000000 (shadow @0xc0000000)
                # CSR bridge   0x60000000 (shadow @0xe0000000)
-               self.wishbonecon = wishbone.InterconnectShared(
+               self.submodules.wishbonecon = wishbone.InterconnectShared(
                        [
                                self.cpu.ibus,
                                self.cpu.dbus
@@ -108,39 +114,29 @@ class SoC:
                #
                # CSR
                #
-               self.uart = uart.UART(csr_offset("UART"), clk_freq, baud=115200)
-               self.identifier = identifier.Identifier(csr_offset("ID"), 0x4D31, version, int(clk_freq))
-               self.timer = timer.Timer(csr_offset("TIMER0"))
-               self.fb = framebuffer.Framebuffer(csr_offset("FB"), asmiport_fb)
-               self.asmiprobe = asmiprobe.ASMIprobe(csr_offset("ASMIPROBE"), self.asmicon.hub)
-               self.csrcon = csr.Interconnect(self.wishbone2csr.csr, [
-                       self.uart.bank.bus,
-                       self.dfii.bank.bus,
-                       self.identifier.bank.bus,
-                       self.timer.bank.bus,
-                       self.minimac.bank.bus,
-                       self.fb.bank.bus,
-                       self.asmiprobe.bank.bus
-               ])
+               self.submodules.uart = uart.UART(clk_freq, baud=115200)
+               self.submodules.identifier = identifier.Identifier(0x4D31, version, int(clk_freq))
+               self.submodules.timer0 = timer.Timer()
+               self.submodules.fb = framebuffer.Framebuffer(asmiport_fb)
+               self.submodules.asmiprobe = asmiprobe.ASMIprobe(self.asmicon.hub)
+
+               self.submodules.csrbankarray = csrgen.BankArray(self, csr_address_map)
+               self.submodules.csrcon = csr.Interconnect(self.wishbone2csr.csr, self.csrbankarray.get_buses())
+
+               #
+               # Interrupts
+               #
+               self.comb += [
+                       self.cpu.interrupt[interrupt_n("UART")].eq(self.uart.ev.irq),
+                       self.cpu.interrupt[interrupt_n("TIMER0")].eq(self.timer0.ev.irq),
+                       self.cpu.interrupt[interrupt_n("MINIMAC")].eq(self.minimac.ev.irq)
+               ]
                
                #
                # Clocking
                #
-               self.crg = m1crg.M1CRG(50*MHz, clk_freq)
-
-       def get_fragment(self):
-               comb = [
-                       #
-                       # Interrupts
-                       #
-                       self.cpu.interrupt[interrupt_n("UART")].eq(self.uart.events.irq),
-                       self.cpu.interrupt[interrupt_n("TIMER0")].eq(self.timer.events.irq),
-                       self.cpu.interrupt[interrupt_n("MINIMAC")].eq(self.minimac.events.irq),
-                       #
-                       # DDR PHY strobes
-                       #
+               self.submodules.crg = m1crg.M1CRG(50*MHz, clk_freq)
+               self.comb += [
                        self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb),
                        self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb)
                ]
-               glue = Fragment(comb)
-               return glue + autofragment.from_attributes(self)