a21ab913e79dc7a9b4c59c877ae1439c04df915f
2 from nmigen
.utils
import log2_int
4 from nmigen_soc
import wishbone
5 from nmigen_soc
.memory
import MemoryMap
6 from nmigen_soc
.periph
import ConstantMap
8 from . import Peripheral
11 __all__
= ["SRAMPeripheral"]
14 class SRAMPeripheral(Peripheral
, Elaboratable
):
15 """SRAM storage peripheral.
30 bus : :class:`nmigen_soc.wishbone.Interface`
31 Wishbone bus interface.
33 # TODO raise bus.err if read-only and a bus write is attempted.
34 def __init__(self
, *, size
, data_width
=32, granularity
=8, writable
=True):
37 if not isinstance(size
, int) or size
<= 0 or size
& size
-1:
38 raise ValueError("Size must be an integer power of two, not {!r}"
40 if size
< data_width
// granularity
:
41 raise ValueError("Size {} cannot be lesser than the data width/granularity ratio "
43 .format(size
, data_width
// granularity
, data_width
, granularity
))
45 self
._mem
= Memory(depth
=(size
* granularity
) // data_width
, width
=data_width
,
48 self
.bus
= wishbone
.Interface(addr_width
=log2_int(self
._mem
.depth
),
49 data_width
=self
._mem
.width
, granularity
=granularity
,
50 features
={"cti", "bte"})
52 map = MemoryMap(addr_width
=log2_int(size
), data_width
=granularity
)
53 map.add_resource(self
._mem
, size
=size
)
54 self
.bus
.memory_map
= map
57 self
.granularity
= granularity
58 self
.writable
= writable
69 def constant_map(self
):
74 def elaborate(self
, platform
):
77 incr
= Signal
.like(self
.bus
.adr
)
79 with m
.Switch(self
.bus
.bte
):
80 with m
.Case(wishbone
.BurstTypeExt
.LINEAR
):
81 m
.d
.comb
+= incr
.eq(self
.bus
.adr
+ 1)
82 with m
.Case(wishbone
.BurstTypeExt
.WRAP_4
):
83 m
.d
.comb
+= incr
[:2].eq(self
.bus
.adr
[:2] + 1)
84 m
.d
.comb
+= incr
[2:].eq(self
.bus
.adr
[2:])
85 with m
.Case(wishbone
.BurstTypeExt
.WRAP_8
):
86 m
.d
.comb
+= incr
[:3].eq(self
.bus
.adr
[:3] + 1)
87 m
.d
.comb
+= incr
[3:].eq(self
.bus
.adr
[3:])
88 with m
.Case(wishbone
.BurstTypeExt
.WRAP_16
):
89 m
.d
.comb
+= incr
[:4].eq(self
.bus
.adr
[:4] + 1)
90 m
.d
.comb
+= incr
[4:].eq(self
.bus
.adr
[4:])
92 m
.submodules
.mem_rp
= mem_rp
= self
._mem
.read_port()
93 m
.d
.comb
+= self
.bus
.dat_r
.eq(mem_rp
.data
)
95 with m
.If(self
.bus
.ack
):
96 m
.d
.sync
+= self
.bus
.ack
.eq(0)
98 with m
.If(self
.bus
.cyc
& self
.bus
.stb
):
99 m
.d
.sync
+= self
.bus
.ack
.eq(1)
100 with m
.If((self
.bus
.cti
== wishbone
.CycleType
.INCR_BURST
) & self
.bus
.ack
):
101 m
.d
.comb
+= mem_rp
.addr
.eq(incr
)
103 m
.d
.comb
+= mem_rp
.addr
.eq(self
.bus
.adr
)
106 m
.submodules
.mem_wp
= mem_wp
= self
._mem
.write_port(granularity
=self
.granularity
)
107 m
.d
.comb
+= mem_wp
.addr
.eq(mem_rp
.addr
)
108 m
.d
.comb
+= mem_wp
.data
.eq(self
.bus
.dat_w
)
109 with m
.If(self
.bus
.cyc
& self
.bus
.stb
& self
.bus
.we
):
110 m
.d
.comb
+= mem_wp
.en
.eq(self
.bus
.sel
)