Make memory ports part of specials
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Tue, 28 May 2013 14:11:34 +0000 (16:11 +0200)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Tue, 28 May 2013 14:11:34 +0000 (16:11 +0200)
This is needed to handle cases where a single memory has ports
in two different modules, and one of these modules is subject
to clock domain remapping. The clock domain of the port in that
module only must be remapped.

examples/basic/memory.py
migen/actorlib/spi.py
migen/bus/csr.py
migen/bus/wishbone.py
migen/bus/wishbone2asmi.py
migen/fhdl/specials.py
migen/genlib/fifo.py
migen/pytholite/compiler.py

index 19e011abd149469970858633597cba158922a33b..352a05b585cbdfbbb28f3d2ed333393a7b109e2b 100644 (file)
@@ -6,6 +6,7 @@ class Example(Module):
                self.specials.mem = Memory(32, 100, init=[5, 18, 32])
                p1 = self.mem.get_port(write_capable=True, we_granularity=8)
                p2 = self.mem.get_port(has_re=True, clock_domain="rd")
+               self.specials += p1, p2
                self.ios = {p1.adr, p1.dat_r, p1.we, p1.dat_w,
                        p2.adr, p2.dat_r, p2.re}
 
index 0f3a577e0b90df0ccd228452995935c6a42a5228..fdf72c281bfbe99babe69514eb8b568dc17aaec5 100644 (file)
@@ -92,6 +92,7 @@ class Collector(Module, AutoCSR):
                self.specials += mem
                wp = mem.get_port(write_capable=True)
                rp = mem.get_port()
+               self.specials += wp, rp
                
                self.comb += [
                        self.busy.eq(0),
index dc51f7e5ed50945da229c70241486e354e687f58..485a14baaae35e22f4ff85cee2dbcfb23c7714b8 100644 (file)
@@ -80,9 +80,9 @@ class SRAM(Module):
        
                ###
 
-               self.specials += mem
                port = mem.get_port(write_capable=not read_only,
                        we_granularity=data_width if not read_only and word_bits else 0)
+               self.specials += mem, port
                
                sel = Signal()
                sel_r = Signal()
index a2550c42ae41953568dd1fb38a7b52f90fbb7795..ecb19f49833379087810768fdda2b36e5b9078a3 100644 (file)
@@ -200,8 +200,8 @@ class SRAM(Module):
                ###
        
                # memory
-               self.specials += mem
                port = mem.get_port(write_capable=not read_only, we_granularity=8)
+               self.specials += mem, port
                # generate write enable signal
                if not read_only:
                        self.comb += [port.we[i].eq(self.bus.cyc & self.bus.stb & self.bus.we & self.bus.sel[i])
index 94f86192c3096923425fa575b02d8fdb1d25ddfd..2c9d533d3921fbe6a17425e8c6d0872b888f4566 100644 (file)
@@ -135,5 +135,5 @@ class WB2ASMI:
                        fsm.next_state(fsm.TEST_HIT)
                )
                
-               return Fragment(comb, sync, specials={data_mem, tag_mem}) \
+               return Fragment(comb, sync, specials={data_mem, tag_mem, data_port, tag_port}) \
                        + fsm.get_fragment()
index f56a7042a9cc6a70852ceeb1aff597d6ca0ce5dc..0f29f05109154dcca613080784b6af55f74ff40a 100644 (file)
@@ -150,10 +150,11 @@ class Instance(Special):
 
 (READ_FIRST, WRITE_FIRST, NO_CHANGE) = range(3)
 
-class _MemoryPort:
+class _MemoryPort(Special):
        def __init__(self, adr, dat_r, we=None, dat_w=None,
          async_read=False, re=None, we_granularity=0, mode=WRITE_FIRST,
          clock_domain="sys"):
+               Special.__init__(self)
                self.adr = adr
                self.dat_r = dat_r
                self.we = we
@@ -164,6 +165,20 @@ class _MemoryPort:
                self.mode = mode
                self.clock = ClockSignal(clock_domain)
 
+       def iter_expressions(self):
+               for attr, target_context in [
+                 ("adr", SPECIAL_INPUT),
+                 ("we", SPECIAL_INPUT),
+                 ("dat_w", SPECIAL_INPUT),
+                 ("re", SPECIAL_INPUT),
+                 ("dat_r", SPECIAL_OUTPUT),
+                 ("clock", SPECIAL_INPUT)]:
+                       yield self, attr, target_context
+
+       @staticmethod
+       def emit_verilog(port, ns):
+               return "" # done by parent Memory object
+
 class Memory(Special):
        def __init__(self, width, depth, init=None, name=None):
                Special.__init__(self)
@@ -199,17 +214,6 @@ class Memory(Special):
                self.ports.append(mp)
                return mp
 
-       def iter_expressions(self):
-               for p in self.ports:
-                       for attr, target_context in [
-                         ("adr", SPECIAL_INPUT),
-                         ("we", SPECIAL_INPUT),
-                         ("dat_w", SPECIAL_INPUT),
-                         ("re", SPECIAL_INPUT),
-                         ("dat_r", SPECIAL_OUTPUT),
-                         ("clock", SPECIAL_INPUT)]:
-                               yield p, attr, target_context
-
        @staticmethod
        def emit_verilog(memory, ns):
                r = ""
index 6c4a4962aa9bc9e5f1c649351a63be0007d1d42c..387f5407c91eac78a1648e0c3e06121d907c8601 100644 (file)
@@ -40,6 +40,7 @@ class SyncFIFO(Module, _FIFOInterface):
                self.specials += storage
 
                wrport = storage.get_port(write_capable=True)
+               self.specials += wrport
                self.comb += [
                        wrport.adr.eq(produce),
                        wrport.dat_w.eq(self.din),
@@ -48,6 +49,7 @@ class SyncFIFO(Module, _FIFOInterface):
                self.sync += If(do_write, _inc(produce, depth))
 
                rdport = storage.get_port(async_read=True)
+               self.specials += rdport
                self.comb += [
                        rdport.adr.eq(consume),
                        self.dout.eq(rdport.dat_r)
@@ -103,12 +105,14 @@ class AsyncFIFO(Module, _FIFOInterface):
                storage = Memory(width, depth)
                self.specials += storage
                wrport = storage.get_port(write_capable=True, clock_domain="write")
+               self.specials += wrport
                self.comb += [
                        wrport.adr.eq(produce.q_binary[:-1]),
                        wrport.dat_w.eq(self.din),
                        wrport.we.eq(produce.ce)
                ]
                rdport = storage.get_port(clock_domain="read")
+               self.specials += rdport
                self.comb += [
                        rdport.adr.eq(consume.q_binary[:-1]),
                        self.dout.eq(rdport.dat_r)
index 1d4507816714d513c8d6629af258ab956f4557a7..20f4972461e4846737f757d99f6e87a794f7b9b2 100644 (file)
@@ -237,8 +237,12 @@ class Pytholite(UnifiedIOObject):
                UnifiedIOObject.do_finalize(self)
                if self.get_dataflow():
                        self.busy.reset = 1
-               self.memory_ports = dict((mem, mem.get_port(write_capable=True, we_granularity=8))
-                       for mem in self.__dict__.values() if isinstance(mem, Memory))
+               self.memory_ports = dict()
+               for mem in self.__dict__.values():
+                       if isinstance(mem, Memory):
+                               port = mem.get_port(write_capable=True, we_granularity=8)
+                               self.specials += port
+                               self.memory_ports[mem] = port
                self._compile()
 
        def _compile(self):