Skip to content

Commit 622c7ac

Browse files
committed
Update to follow RFCs 37 and 38.
Memory maps and event maps are now assigned to Interface objects instead of Signature objects (which can no longer hold mutable state), as things were before 9ffaf94. See #62.
1 parent ad9f7d4 commit 622c7ac

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)