Skip to content

Update to follow RFCs 37 and 38. #63

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 31 additions & 51 deletions amaranth_soc/csr/bus.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,6 @@ def __init__(self, *, addr_width, data_width):

self._addr_width = addr_width
self._data_width = data_width
self._memory_map = None

members = {
"addr": Out(self.addr_width),
Expand All @@ -217,27 +216,6 @@ def addr_width(self):
def data_width(self):
return self._data_width

@property
def memory_map(self):
if self._memory_map is None:
raise AttributeError(f"{self!r} does not have a memory map")
return self._memory_map

@memory_map.setter
def memory_map(self, memory_map):
if self.frozen:
raise ValueError(f"Signature has been frozen. Cannot set its memory map")
if memory_map is not None:
if not isinstance(memory_map, MemoryMap):
raise TypeError(f"Memory map must be an instance of MemoryMap, not {memory_map!r}")
if memory_map.addr_width != self.addr_width:
raise ValueError(f"Memory map has address width {memory_map.addr_width}, which is not "
f"the same as bus interface address width {self.addr_width}")
if memory_map.data_width != self.data_width:
raise ValueError(f"Memory map has data width {memory_map.data_width}, which is not the "
f"same as bus interface data width {self.data_width}")
self._memory_map = memory_map

@classmethod
def check_parameters(cls, *, addr_width, data_width):
"""Validate signature parameters.
Expand All @@ -264,7 +242,6 @@ def create(self, *, path=None, src_loc_at=0):
An :class:`Interface` object using this signature.
"""
return Interface(addr_width=self.addr_width, data_width=self.data_width,
memory_map=self._memory_map, # if None, do not raise an exception
path=path, src_loc_at=1 + src_loc_at)

def __eq__(self, other):
Expand Down Expand Up @@ -304,19 +281,22 @@ class Interface(wiring.PureInterface):
Address width. See :class:`Signature`.
data_width : :class:`int`
Data width. See :class:`Signature`.
memory_map: :class:`MemoryMap`
Memory map of the bus. Optional. See :class:`Signature`.
path : iter(:class:`str`)
Path to this CSR interface. Optional. See :class:`wiring.PureInterface`.

Attributes
----------
memory_map: :class:`MemoryMap`
Memory map of the bus. Optional.

Raises
------
See :meth:`Signature.check_parameters`.
"""
def __init__(self, *, addr_width, data_width, memory_map=None, path=None, src_loc_at=0):
def __init__(self, *, addr_width, data_width, path=None, src_loc_at=0):
sig = Signature(addr_width=addr_width, data_width=data_width)
sig.memory_map = memory_map
super().__init__(sig, path=path, src_loc_at=1 + src_loc_at)
self._memory_map = None

@property
def addr_width(self):
Expand All @@ -328,7 +308,21 @@ def data_width(self):

@property
def memory_map(self):
return self.signature.memory_map
if self._memory_map is None:
raise AttributeError(f"{self!r} does not have a memory map")
return self._memory_map

@memory_map.setter
def memory_map(self, memory_map):
if not isinstance(memory_map, MemoryMap):
raise TypeError(f"Memory map must be an instance of MemoryMap, not {memory_map!r}")
if memory_map.addr_width != self.addr_width:
raise ValueError(f"Memory map has address width {memory_map.addr_width}, which is not "
f"the same as bus interface address width {self.addr_width}")
if memory_map.data_width != self.data_width:
raise ValueError(f"Memory map has data width {memory_map.data_width}, which is not the "
f"same as bus interface data width {self.data_width}")
self._memory_map = memory_map

def __repr__(self):
return f"csr.Interface({self.signature!r})"
Expand Down Expand Up @@ -561,18 +555,11 @@ def chunks(self):
CSR bus providing access to registers.
"""
def __init__(self, *, addr_width, data_width, alignment=0, name=None, shadow_overlaps=None):
bus_signature = Signature(addr_width=addr_width, data_width=data_width)
bus_signature.memory_map = MemoryMap(addr_width=addr_width, data_width=data_width,
alignment=alignment, name=name)

self._signature = wiring.Signature({"bus": In(bus_signature)})
self._r_shadow = Multiplexer._Shadow(data_width, shadow_overlaps, name="r_shadow")
self._w_shadow = Multiplexer._Shadow(data_width, shadow_overlaps, name="w_shadow")
super().__init__()

@property
def signature(self):
return self._signature
super().__init__({"bus": In(Signature(addr_width=addr_width, data_width=data_width))})
self.bus.memory_map = MemoryMap(addr_width=addr_width, data_width=data_width,
alignment=alignment, name=name)
self._r_shadow = Multiplexer._Shadow(data_width, shadow_overlaps, name="r_shadow")
self._w_shadow = Multiplexer._Shadow(data_width, shadow_overlaps, name="w_shadow")

def align_to(self, alignment):
"""Align the implicit address of the next register.
Expand Down Expand Up @@ -704,17 +691,10 @@ class Decoder(wiring.Component):
CSR bus providing access to subordinate buses.
"""
def __init__(self, *, addr_width, data_width, alignment=0, name=None):
bus_signature = Signature(addr_width=addr_width, data_width=data_width)
bus_signature.memory_map = MemoryMap(addr_width=addr_width, data_width=data_width,
alignment=alignment, name=name)

self._signature = wiring.Signature({"bus": In(bus_signature)})
self._subs = dict()
super().__init__()

@property
def signature(self):
return self._signature
super().__init__({"bus": In(Signature(addr_width=addr_width, data_width=data_width))})
self.bus.memory_map = MemoryMap(addr_width=addr_width, data_width=data_width,
alignment=alignment, name=name)
self._subs = dict()

def align_to(self, alignment):
"""Align the implicit address of the next window.
Expand Down
17 changes: 8 additions & 9 deletions amaranth_soc/csr/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from . import Element, Multiplexer
from .. import event
from ..memory import MemoryMap


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

self._monitor = event.Monitor(event_map, trigger=trigger)
self._enable = Element(event_map.size, "rw", path=("enable",))
self._pending = Element(event_map.size, "rw", path=("pending",))
self._enable = Element(event_map.size, "rw")
self._pending = Element(event_map.size, "rw")

elem_size = ceil(event_map.size / data_width)
addr_width = 1 + max(log2_int(elem_size, need_pow2=False), alignment)
self._mux = Multiplexer(addr_width=addr_width, data_width=data_width,
alignment=alignment, name=name)
alignment=alignment)
self._mux.add(self._enable, name="enable")
self._mux.add(self._pending, name="pending")

self._signature = wiring.Signature({
super().__init__({
"src": Out(self._monitor.src.signature),
"bus": In(self._mux.bus.signature),
})
super().__init__()

@property
def signature(self):
return self._signature
self.bus.memory_map = MemoryMap(addr_width=addr_width, data_width=data_width,
alignment=alignment, name=name)
self.bus.memory_map.add_window(self._mux.bus.memory_map)

def elaborate(self, platform):
m = Module()
Expand Down
26 changes: 10 additions & 16 deletions amaranth_soc/csr/wishbone.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,25 +51,19 @@ def __init__(self, csr_bus, *, data_width=None, name=None):
if data_width is None:
data_width = csr_bus.data_width

wb_signature = wishbone.Signature(
addr_width=max(0, csr_bus.addr_width - log2_int(data_width // csr_bus.data_width)),
data_width=data_width,
granularity=csr_bus.data_width)

wb_signature.memory_map = MemoryMap(addr_width=csr_bus.addr_width,
data_width=csr_bus.data_width,
name=name)
wb_sig = wishbone.Signature(addr_width=max(0, csr_bus.addr_width -
log2_int(data_width // csr_bus.data_width)),
data_width=data_width, granularity=csr_bus.data_width)

super().__init__({"wb_bus": In(wb_sig)})

self.wb_bus.memory_map = MemoryMap(addr_width=csr_bus.addr_width,
data_width=csr_bus.data_width, name=name)
# Since granularity of the Wishbone interface matches the data width of the CSR bus,
# no width conversion is performed, even if the Wishbone data width is greater.
wb_signature.memory_map.add_window(csr_bus.memory_map)
self.wb_bus.memory_map.add_window(csr_bus.memory_map)

self._signature = wiring.Signature({"wb_bus": In(wb_signature)})
self._csr_bus = csr_bus
super().__init__()

@property
def signature(self):
return self._signature
self._csr_bus = csr_bus

@property
def csr_bus(self):
Expand Down
63 changes: 22 additions & 41 deletions amaranth_soc/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,36 +34,16 @@ class Signature(wiring.Signature):
"""
def __init__(self, *, trigger="level"):
self.check_parameters(trigger=trigger)

self._trigger = Source.Trigger(trigger)
self._event_map = None

members = {
super().__init__({
"i": Out(1),
"trg": In(1),
}
super().__init__(members)
})
self._trigger = Source.Trigger(trigger)

@property
def trigger(self):
return self._trigger

@property
def event_map(self):
if self._event_map is None:
raise AttributeError(f"{self!r} does not have an event map")
return self._event_map

@event_map.setter
def event_map(self, event_map):
if self.frozen:
raise ValueError(f"Signature has been frozen. Cannot set its event map")
if event_map is not None:
if not isinstance(event_map, EventMap):
raise TypeError(f"Event map must be an instance of EventMap, not {event_map!r}")
event_map.freeze()
self._event_map = event_map

def check_parameters(cls, *, trigger):
"""Validate signature parameters.

Expand All @@ -89,9 +69,7 @@ def create(self, *, path=None, src_loc_at=0):
-------
A :class:`Source` object using this signature.
"""
return Source(trigger=self.trigger,
event_map=self._event_map, # if None, do not raise an exception
path=path, src_loc_at=1 + src_loc_at)
return Source(trigger=self.trigger, path=path, src_loc_at=1 + src_loc_at)

def __eq__(self, other):
"""Compare signatures.
Expand Down Expand Up @@ -121,18 +99,26 @@ def __repr__(self):
------
See :meth:`Source.Signature.check_parameters`.
"""
def __init__(self, *, trigger="level", event_map=None, path=None, src_loc_at=0):
sig = Source.Signature(trigger=trigger)
sig.event_map = event_map
super().__init__(sig, path=path, src_loc_at=1 + src_loc_at)
def __init__(self, *, trigger="level", path=None, src_loc_at=0):
super().__init__(Source.Signature(trigger=trigger), path=path, src_loc_at=1 + src_loc_at)
self._event_map = None

@property
def trigger(self):
return self.signature.trigger

@property
def event_map(self):
return self.signature.event_map
if self._event_map is None:
raise AttributeError(f"{self!r} does not have an event map")
return self._event_map

@event_map.setter
def event_map(self, event_map):
if not isinstance(event_map, EventMap):
raise TypeError(f"Event map must be an instance of EventMap, not {event_map!r}")
event_map.freeze()
self._event_map = event_map

def __repr__(self):
return f"event.Source({self.signature!r})"
Expand Down Expand Up @@ -242,20 +228,15 @@ class Monitor(wiring.Component):
Clear selected pending events.
"""
def __init__(self, event_map, *, trigger="level"):
src_signature = Source.Signature(trigger=trigger)
src_signature.event_map = event_map

self._signature = wiring.Signature({
"src": Out(src_signature),
if not isinstance(event_map, EventMap):
raise TypeError(f"Event map must be an instance of EventMap, not {event_map!r}")
super().__init__({
"src": Out(Source.Signature(trigger=trigger)),
"enable": In(event_map.size),
"pending": In(event_map.size),
"clear": In(event_map.size),
})
super().__init__()

@property
def signature(self):
return self._signature
self.src.event_map = event_map

def elaborate(self, platform):
m = Module()
Expand Down
Loading