Skip to content

Commit 737673b

Browse files
committed
Update to follow RFCs 37 and 38.
Memory maps are now assigned to {csr,wisbhone}.Interface objects instead of their Signature (which can no longer hold mutable state), as things were before 9ffaf94. See amaranth-lang#62.
1 parent ad9f7d4 commit 737673b

File tree

9 files changed

+194
-379
lines changed

9 files changed

+194
-379
lines changed

amaranth_soc/csr/bus.py

+31-51
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,6 @@ def __init__(self, *, addr_width, data_width):
198198

199199
self._addr_width = addr_width
200200
self._data_width = data_width
201-
self._memory_map = None
202201

203202
members = {
204203
"addr": Out(self.addr_width),
@@ -217,27 +216,6 @@ def addr_width(self):
217216
def data_width(self):
218217
return self._data_width
219218

220-
@property
221-
def memory_map(self):
222-
if self._memory_map is None:
223-
raise AttributeError(f"{self!r} does not have a memory map")
224-
return self._memory_map
225-
226-
@memory_map.setter
227-
def memory_map(self, memory_map):
228-
if self.frozen:
229-
raise ValueError(f"Signature has been frozen. Cannot set its memory map")
230-
if memory_map is not None:
231-
if not isinstance(memory_map, MemoryMap):
232-
raise TypeError(f"Memory map must be an instance of MemoryMap, not {memory_map!r}")
233-
if memory_map.addr_width != self.addr_width:
234-
raise ValueError(f"Memory map has address width {memory_map.addr_width}, which is not "
235-
f"the same as bus interface address width {self.addr_width}")
236-
if memory_map.data_width != self.data_width:
237-
raise ValueError(f"Memory map has data width {memory_map.data_width}, which is not the "
238-
f"same as bus interface data width {self.data_width}")
239-
self._memory_map = memory_map
240-
241219
@classmethod
242220
def check_parameters(cls, *, addr_width, data_width):
243221
"""Validate signature parameters.
@@ -264,7 +242,6 @@ def create(self, *, path=None, src_loc_at=0):
264242
An :class:`Interface` object using this signature.
265243
"""
266244
return Interface(addr_width=self.addr_width, data_width=self.data_width,
267-
memory_map=self._memory_map, # if None, do not raise an exception
268245
path=path, src_loc_at=1 + src_loc_at)
269246

270247
def __eq__(self, other):
@@ -304,19 +281,22 @@ class Interface(wiring.PureInterface):
304281
Address width. See :class:`Signature`.
305282
data_width : :class:`int`
306283
Data width. See :class:`Signature`.
307-
memory_map: :class:`MemoryMap`
308-
Memory map of the bus. Optional. See :class:`Signature`.
309284
path : iter(:class:`str`)
310285
Path to this CSR interface. Optional. See :class:`wiring.PureInterface`.
311286
287+
Attributes
288+
----------
289+
memory_map: :class:`MemoryMap`
290+
Memory map of the bus. Optional.
291+
312292
Raises
313293
------
314294
See :meth:`Signature.check_parameters`.
315295
"""
316-
def __init__(self, *, addr_width, data_width, memory_map=None, path=None, src_loc_at=0):
296+
def __init__(self, *, addr_width, data_width, path=None, src_loc_at=0):
317297
sig = Signature(addr_width=addr_width, data_width=data_width)
318-
sig.memory_map = memory_map
319298
super().__init__(sig, path=path, src_loc_at=1 + src_loc_at)
299+
self._memory_map = None
320300

321301
@property
322302
def addr_width(self):
@@ -328,7 +308,21 @@ def data_width(self):
328308

329309
@property
330310
def memory_map(self):
331-
return self.signature.memory_map
311+
if self._memory_map is None:
312+
raise AttributeError(f"{self!r} does not have a memory map")
313+
return self._memory_map
314+
315+
@memory_map.setter
316+
def memory_map(self, memory_map):
317+
if not isinstance(memory_map, MemoryMap):
318+
raise TypeError(f"Memory map must be an instance of MemoryMap, not {memory_map!r}")
319+
if memory_map.addr_width != self.addr_width:
320+
raise ValueError(f"Memory map has address width {memory_map.addr_width}, which is not "
321+
f"the same as bus interface address width {self.addr_width}")
322+
if memory_map.data_width != self.data_width:
323+
raise ValueError(f"Memory map has data width {memory_map.data_width}, which is not the "
324+
f"same as bus interface data width {self.data_width}")
325+
self._memory_map = memory_map
332326

333327
def __repr__(self):
334328
return f"csr.Interface({self.signature!r})"
@@ -561,18 +555,11 @@ def chunks(self):
561555
CSR bus providing access to registers.
562556
"""
563557
def __init__(self, *, addr_width, data_width, alignment=0, name=None, shadow_overlaps=None):
564-
bus_signature = Signature(addr_width=addr_width, data_width=data_width)
565-
bus_signature.memory_map = MemoryMap(addr_width=addr_width, data_width=data_width,
566-
alignment=alignment, name=name)
567-
568-
self._signature = wiring.Signature({"bus": In(bus_signature)})
569-
self._r_shadow = Multiplexer._Shadow(data_width, shadow_overlaps, name="r_shadow")
570-
self._w_shadow = Multiplexer._Shadow(data_width, shadow_overlaps, name="w_shadow")
571-
super().__init__()
572-
573-
@property
574-
def signature(self):
575-
return self._signature
558+
super().__init__({"bus": In(Signature(addr_width=addr_width, data_width=data_width))})
559+
self.bus.memory_map = MemoryMap(addr_width=addr_width, data_width=data_width,
560+
alignment=alignment, name=name)
561+
self._r_shadow = Multiplexer._Shadow(data_width, shadow_overlaps, name="r_shadow")
562+
self._w_shadow = Multiplexer._Shadow(data_width, shadow_overlaps, name="w_shadow")
576563

577564
def align_to(self, alignment):
578565
"""Align the implicit address of the next register.
@@ -704,17 +691,10 @@ class Decoder(wiring.Component):
704691
CSR bus providing access to subordinate buses.
705692
"""
706693
def __init__(self, *, addr_width, data_width, alignment=0, name=None):
707-
bus_signature = Signature(addr_width=addr_width, data_width=data_width)
708-
bus_signature.memory_map = MemoryMap(addr_width=addr_width, data_width=data_width,
709-
alignment=alignment, name=name)
710-
711-
self._signature = wiring.Signature({"bus": In(bus_signature)})
712-
self._subs = dict()
713-
super().__init__()
714-
715-
@property
716-
def signature(self):
717-
return self._signature
694+
super().__init__({"bus": In(Signature(addr_width=addr_width, data_width=data_width))})
695+
self.bus.memory_map = MemoryMap(addr_width=addr_width, data_width=data_width,
696+
alignment=alignment, name=name)
697+
self._subs = dict()
718698

719699
def align_to(self, alignment):
720700
"""Align the implicit address of the next window.

amaranth_soc/csr/event.py

+8-9
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
from . import Element, Multiplexer
1010
from .. import event
11+
from ..memory import MemoryMap
1112

1213

1314
__all__ = ["EventMonitor"]
@@ -53,25 +54,23 @@ def __init__(self, event_map, *, trigger="level", data_width, alignment=0, name=
5354
raise ValueError(f"Alignment must be a non-negative integer, not {alignment!r}")
5455

5556
self._monitor = event.Monitor(event_map, trigger=trigger)
56-
self._enable = Element(event_map.size, "rw", path=("enable",))
57-
self._pending = Element(event_map.size, "rw", path=("pending",))
57+
self._enable = Element(event_map.size, "rw")
58+
self._pending = Element(event_map.size, "rw")
5859

5960
elem_size = ceil(event_map.size / data_width)
6061
addr_width = 1 + max(log2_int(elem_size, need_pow2=False), alignment)
6162
self._mux = Multiplexer(addr_width=addr_width, data_width=data_width,
62-
alignment=alignment, name=name)
63+
alignment=alignment)
6364
self._mux.add(self._enable, name="enable")
6465
self._mux.add(self._pending, name="pending")
6566

66-
self._signature = wiring.Signature({
67+
super().__init__({
6768
"src": Out(self._monitor.src.signature),
6869
"bus": In(self._mux.bus.signature),
6970
})
70-
super().__init__()
71-
72-
@property
73-
def signature(self):
74-
return self._signature
71+
self.bus.memory_map = MemoryMap(addr_width=addr_width, data_width=data_width,
72+
alignment=alignment, name=name)
73+
self.bus.memory_map.add_window(self._mux.bus.memory_map)
7574

7675
def elaborate(self, platform):
7776
m = Module()

amaranth_soc/csr/wishbone.py

+10-16
Original file line numberDiff line numberDiff line change
@@ -51,25 +51,19 @@ def __init__(self, csr_bus, *, data_width=None, name=None):
5151
if data_width is None:
5252
data_width = csr_bus.data_width
5353

54-
wb_signature = wishbone.Signature(
55-
addr_width=max(0, csr_bus.addr_width - log2_int(data_width // csr_bus.data_width)),
56-
data_width=data_width,
57-
granularity=csr_bus.data_width)
58-
59-
wb_signature.memory_map = MemoryMap(addr_width=csr_bus.addr_width,
60-
data_width=csr_bus.data_width,
61-
name=name)
54+
wb_sig = wishbone.Signature(addr_width=max(0, csr_bus.addr_width -
55+
log2_int(data_width // csr_bus.data_width)),
56+
data_width=data_width, granularity=csr_bus.data_width)
57+
58+
super().__init__({"wb_bus": In(wb_sig)})
59+
60+
self.wb_bus.memory_map = MemoryMap(addr_width=csr_bus.addr_width,
61+
data_width=csr_bus.data_width, name=name)
6262
# Since granularity of the Wishbone interface matches the data width of the CSR bus,
6363
# no width conversion is performed, even if the Wishbone data width is greater.
64-
wb_signature.memory_map.add_window(csr_bus.memory_map)
64+
self.wb_bus.memory_map.add_window(csr_bus.memory_map)
6565

66-
self._signature = wiring.Signature({"wb_bus": In(wb_signature)})
67-
self._csr_bus = csr_bus
68-
super().__init__()
69-
70-
@property
71-
def signature(self):
72-
return self._signature
66+
self._csr_bus = csr_bus
7367

7468
@property
7569
def csr_bus(self):

amaranth_soc/event.py

+22-41
Original file line numberDiff line numberDiff line change
@@ -34,36 +34,16 @@ class Signature(wiring.Signature):
3434
"""
3535
def __init__(self, *, trigger="level"):
3636
self.check_parameters(trigger=trigger)
37-
38-
self._trigger = Source.Trigger(trigger)
39-
self._event_map = None
40-
41-
members = {
37+
super().__init__({
4238
"i": Out(1),
4339
"trg": In(1),
44-
}
45-
super().__init__(members)
40+
})
41+
self._trigger = Source.Trigger(trigger)
4642

4743
@property
4844
def trigger(self):
4945
return self._trigger
5046

51-
@property
52-
def event_map(self):
53-
if self._event_map is None:
54-
raise AttributeError(f"{self!r} does not have an event map")
55-
return self._event_map
56-
57-
@event_map.setter
58-
def event_map(self, event_map):
59-
if self.frozen:
60-
raise ValueError(f"Signature has been frozen. Cannot set its event map")
61-
if event_map is not None:
62-
if not isinstance(event_map, EventMap):
63-
raise TypeError(f"Event map must be an instance of EventMap, not {event_map!r}")
64-
event_map.freeze()
65-
self._event_map = event_map
66-
6747
def check_parameters(cls, *, trigger):
6848
"""Validate signature parameters.
6949
@@ -89,9 +69,7 @@ def create(self, *, path=None, src_loc_at=0):
8969
-------
9070
A :class:`Source` object using this signature.
9171
"""
92-
return Source(trigger=self.trigger,
93-
event_map=self._event_map, # if None, do not raise an exception
94-
path=path, src_loc_at=1 + src_loc_at)
72+
return Source(trigger=self.trigger, path=path, src_loc_at=1 + src_loc_at)
9573

9674
def __eq__(self, other):
9775
"""Compare signatures.
@@ -121,18 +99,26 @@ def __repr__(self):
12199
------
122100
See :meth:`Source.Signature.check_parameters`.
123101
"""
124-
def __init__(self, *, trigger="level", event_map=None, path=None, src_loc_at=0):
125-
sig = Source.Signature(trigger=trigger)
126-
sig.event_map = event_map
127-
super().__init__(sig, path=path, src_loc_at=1 + src_loc_at)
102+
def __init__(self, *, trigger="level", path=None, src_loc_at=0):
103+
super().__init__(Source.Signature(trigger=trigger), path=path, src_loc_at=1 + src_loc_at)
104+
self._event_map = None
128105

129106
@property
130107
def trigger(self):
131108
return self.signature.trigger
132109

133110
@property
134111
def event_map(self):
135-
return self.signature.event_map
112+
if self._event_map is None:
113+
raise AttributeError(f"{self!r} does not have an event map")
114+
return self._event_map
115+
116+
@event_map.setter
117+
def event_map(self, event_map):
118+
if not isinstance(event_map, EventMap):
119+
raise TypeError(f"Event map must be an instance of EventMap, not {event_map!r}")
120+
event_map.freeze()
121+
self._event_map = event_map
136122

137123
def __repr__(self):
138124
return f"event.Source({self.signature!r})"
@@ -242,20 +228,15 @@ class Monitor(wiring.Component):
242228
Clear selected pending events.
243229
"""
244230
def __init__(self, event_map, *, trigger="level"):
245-
src_signature = Source.Signature(trigger=trigger)
246-
src_signature.event_map = event_map
247-
248-
self._signature = wiring.Signature({
249-
"src": Out(src_signature),
231+
if not isinstance(event_map, EventMap):
232+
raise TypeError(f"Event map must be an instance of EventMap, not {event_map!r}")
233+
super().__init__({
234+
"src": Out(Source.Signature(trigger=trigger)),
250235
"enable": In(event_map.size),
251236
"pending": In(event_map.size),
252237
"clear": In(event_map.size),
253238
})
254-
super().__init__()
255-
256-
@property
257-
def signature(self):
258-
return self._signature
239+
self.src.event_map = event_map
259240

260241
def elaborate(self, platform):
261242
m = Module()

0 commit comments

Comments
 (0)