Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Sebastien Bourdeauducq committed May 28, 2013
1 parent 70ffe86 commit bac62a3
Show file tree
Hide file tree
Showing 8 changed files with 31 additions and 17 deletions.
1 change: 1 addition & 0 deletions examples/basic/memory.py
Expand Up @@ -6,6 +6,7 @@ def __init__(self):
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}

Expand Down
1 change: 1 addition & 0 deletions migen/actorlib/spi.py
Expand Up @@ -92,6 +92,7 @@ def __init__(self, layout, depth=1024):
self.specials += mem
wp = mem.get_port(write_capable=True)
rp = mem.get_port()
self.specials += wp, rp

self.comb += [
self.busy.eq(0),
Expand Down
2 changes: 1 addition & 1 deletion migen/bus/csr.py
Expand Up @@ -80,9 +80,9 @@ def __init__(self, mem_or_size, address, read_only=None, init=None, bus=None):

###

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()
Expand Down
2 changes: 1 addition & 1 deletion migen/bus/wishbone.py
Expand Up @@ -200,8 +200,8 @@ def __init__(self, mem_or_size, read_only=None, init=None, bus=None):
###

# 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])
Expand Down
2 changes: 1 addition & 1 deletion migen/bus/wishbone2asmi.py
Expand Up @@ -135,5 +135,5 @@ def get_fragment(self):
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()
28 changes: 16 additions & 12 deletions migen/fhdl/specials.py
Expand Up @@ -150,10 +150,11 @@ def emit_verilog(instance, ns):

(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
Expand All @@ -164,6 +165,20 @@ def __init__(self, adr, dat_r, we=None, dat_w=None,
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)
Expand Down Expand Up @@ -199,17 +214,6 @@ def get_port(self, write_capable=False, async_read=False,
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 = ""
Expand Down
4 changes: 4 additions & 0 deletions migen/genlib/fifo.py
Expand Up @@ -40,6 +40,7 @@ def __init__(self, width, depth):
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),
Expand All @@ -48,6 +49,7 @@ def __init__(self, width, depth):
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)
Expand Down Expand Up @@ -103,12 +105,14 @@ def __init__(self, width, depth):
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)
Expand Down
8 changes: 6 additions & 2 deletions migen/pytholite/compiler.py
Expand Up @@ -237,8 +237,12 @@ def do_finalize(self):
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):
Expand Down

0 comments on commit bac62a3

Please sign in to comment.