Skip to content

Commit

Permalink
Make memory ports part of specials
Browse files Browse the repository at this point in the history
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.
Sebastien Bourdeauducq committed May 28, 2013
1 parent 70ffe86 commit bac62a3
Showing 8 changed files with 31 additions and 17 deletions.
1 change: 1 addition & 0 deletions examples/basic/memory.py
Original file line number Diff line number Diff line change
@@ -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}

1 change: 1 addition & 0 deletions migen/actorlib/spi.py
Original file line number Diff line number Diff line change
@@ -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),
2 changes: 1 addition & 1 deletion migen/bus/csr.py
Original file line number Diff line number Diff line change
@@ -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()
2 changes: 1 addition & 1 deletion migen/bus/wishbone.py
Original file line number Diff line number Diff line change
@@ -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])
2 changes: 1 addition & 1 deletion migen/bus/wishbone2asmi.py
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
@@ -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)
@@ -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 = ""
4 changes: 4 additions & 0 deletions migen/genlib/fifo.py
Original file line number Diff line number Diff line change
@@ -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),
@@ -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)
@@ -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)
8 changes: 6 additions & 2 deletions migen/pytholite/compiler.py
Original file line number Diff line number Diff line change
@@ -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):

0 comments on commit bac62a3

Please sign in to comment.