2 from nmigen
.utils
import *
4 from .bus
import Interface
10 class SRAM(Elaboratable
):
13 def __init__(self
, memory
, read_only
=False, bus
=None,
14 granularity
=None, features
=frozenset()):
15 if not isinstance(memory
, Memory
):
16 raise TypeError("Memory {!r} is not a Memory"
19 self
.read_only
= read_only
20 # Define total address space:
21 # - Base: equals memory.depth
22 # - Has an additional ReadPort: add rdport.depth
23 # - Has an additional WirtePort: add wrport.depth
24 self
._memdepth
= self
.memory
.depth
* 2
26 self
._memdepth
+= self
.memory
.depth
28 bus
= Interface(addr_width
=max(0, log2_int(self
._memdepth
, need_pow2
=False)),
29 data_width
=self
.memory
.width
,
30 granularity
=granularity
,
35 self
.granularity
= bus
.granularity
37 def elaborate(self
, platform
):
40 if self
.memory
.width
> len(self
.bus
.dat_r
):
41 raise NotImplementedError
44 m
.submodules
.rdport
= rdport
= self
.memory
.read_port()
46 rdport
.addr
.eq(self
.bus
.adr
[:len(rdport
.addr
)]),
47 self
.bus
.dat_r
.eq(rdport
.data
)
51 if not self
.read_only
:
52 m
.submodules
.wrport
= wrport
= self
.memory
.write_port(granularity
=self
.granularity
)
54 wrport
.addr
.eq(self
.bus
.adr
[:len(rdport
.addr
)]),
55 wrport
.data
.eq(self
.bus
.dat_w
)
58 m
.d
.comb
+= wrport
.en
[i
].eq(self
.bus
.cyc
& self
.bus
.stb
& self
.bus
.we
& self
.bus
.sel
[i
])
61 m
.d
.sync
+= self
.bus
.ack
.eq(0)
62 with m
.If(self
.bus
.cyc
& self
.bus
.stb
& ~self
.bus
.ack
):
63 m
.d
.sync
+= self
.bus
.ack
.eq(1)