030ad9073730e6fcb1e97b9b5c6f4b49f1c46936
1 from nmigen
import Elaboratable
, Memory
, Module
2 from nmigen
.utils
import log2_int
4 from nmigen_soc
.wishbone
.bus
import Interface
10 class SRAM(Elaboratable
):
11 """SRAM module carrying a volatile memory block (implemented with
12 :class:`Memory`) that can be read and write (or only read if the
13 SRAM is read-only) through a Wishbone bus.
15 If no Wishbone bus is specified during initialisation, this creates
16 one whose address width is just enough to fit the whole memory
17 (i.e. equals to the log2(memory depth) rounded up), and whose data
18 width is equal to the memory width.
22 memory : :class:`Memory`
23 The memory to be accessed via the Wishbone bus.
25 Whether or not the memory is read-only. Defaults to False.
26 bus : :class:`Interface` or None
27 The Wishbone bus interface providing access to the read/write
28 ports of the memory. Optional and defaults to None, which
29 lets this module to instantiate one as described above, having
30 the granularity, features and alignment as specified by their
31 corresponding parameters.
32 granularity : int or None
33 If the Wishbone bus is not sepcified, this is the granularity
34 of the Wishbone bus. Optional. See :class:`Interface`.
36 If the Wishbone bus is not sepcified, this is the optional signal
37 set for the Wishbone bus. See :class:`Interface`.
41 memory : :class:`Memory`
42 The memory to be accessed via the Wishbone bus.
43 bus : :class:`Interface`
44 The Wishbone bus interface providing access to the read/write
48 def __init__(self
, memory
, read_only
=False, bus
=None,
49 granularity
=None, features
=frozenset()):
50 if not isinstance(memory
, Memory
):
51 raise TypeError("Memory {!r} is not a Memory"
54 self
.read_only
= read_only
56 bus
= Interface(addr_width
=log2_int(self
.memory
.depth
,
58 data_width
=self
.memory
.width
,
59 granularity
=granularity
,
64 self
.granularity
= bus
.granularity
66 def elaborate(self
, platform
):
69 if self
.memory
.width
> len(self
.bus
.dat_r
):
70 raise NotImplementedError
73 m
.submodules
.rdport
= rdport
= self
.memory
.read_port()
75 rdport
.addr
.eq(self
.bus
.adr
[:len(rdport
.addr
)]),
76 self
.bus
.dat_r
.eq(rdport
.data
)
80 if not self
.read_only
:
81 m
.submodules
.wrport
= wrport
= self
.memory
.write_port(
82 granularity
=self
.granularity
)
84 wrport
.addr
.eq(self
.bus
.adr
[:len(rdport
.addr
)]),
85 wrport
.data
.eq(self
.bus
.dat_w
)
88 m
.d
.comb
+= wrport
.en
[i
].eq(self
.bus
.cyc
& self
.bus
.stb
&
89 self
.bus
.we
& self
.bus
.sel
[i
])
92 m
.d
.sync
+= self
.bus
.ack
.eq(0)
93 with m
.If(self
.bus
.cyc
& self
.bus
.stb
& ~self
.bus
.ack
):
94 m
.d
.sync
+= self
.bus
.ack
.eq(1)