From: Sebastien Bourdeauducq Date: Tue, 28 May 2013 14:11:34 +0000 (+0200) Subject: Make memory ports part of specials X-Git-Tag: 24jan2021_ls180~2099^2~573 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=bac62a32a9a6537ff02d71a84a9948a7dee93dc0;p=litex.git Make memory ports part of specials 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. --- diff --git a/examples/basic/memory.py b/examples/basic/memory.py index 19e011ab..352a05b5 100644 --- a/examples/basic/memory.py +++ b/examples/basic/memory.py @@ -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} diff --git a/migen/actorlib/spi.py b/migen/actorlib/spi.py index 0f3a577e..fdf72c28 100644 --- a/migen/actorlib/spi.py +++ b/migen/actorlib/spi.py @@ -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), diff --git a/migen/bus/csr.py b/migen/bus/csr.py index dc51f7e5..485a14ba 100644 --- a/migen/bus/csr.py +++ b/migen/bus/csr.py @@ -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() diff --git a/migen/bus/wishbone.py b/migen/bus/wishbone.py index a2550c42..ecb19f49 100644 --- a/migen/bus/wishbone.py +++ b/migen/bus/wishbone.py @@ -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]) diff --git a/migen/bus/wishbone2asmi.py b/migen/bus/wishbone2asmi.py index 94f86192..2c9d533d 100644 --- a/migen/bus/wishbone2asmi.py +++ b/migen/bus/wishbone2asmi.py @@ -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() diff --git a/migen/fhdl/specials.py b/migen/fhdl/specials.py index f56a7042..0f29f051 100644 --- a/migen/fhdl/specials.py +++ b/migen/fhdl/specials.py @@ -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 = "" diff --git a/migen/genlib/fifo.py b/migen/genlib/fifo.py index 6c4a4962..387f5407 100644 --- a/migen/genlib/fifo.py +++ b/migen/genlib/fifo.py @@ -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) diff --git a/migen/pytholite/compiler.py b/migen/pytholite/compiler.py index 1d450781..20f49724 100644 --- a/migen/pytholite/compiler.py +++ b/migen/pytholite/compiler.py @@ -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):