Memory Map¶
- class torii.lib.mem.map.MemoryMap(*, addr_width: int, data_width: int, alignment: int = 0, name: str | None = None) None ¶
Memory map.
A memory map is a hierarchical description of an address space, describing the structure of address decoders of peripherals as well as bus bridges. It is built by adding resources (range allocations for registers, memory, etc) and windows (range allocations for bus bridges), and can be queried later to determine the address of any given resource from a specific vantage point in the design.
Address assignment
To simplify address assignment, each memory map has an implicit next address, starting at 0. If a resource or a window is added without specifying an address explicitly, the implicit next address is used. In any case, the implicit next address is set to the address immediately following the newly added resource or window.
- Parameters:
addr_width (int) – Address width.
data_width (int) – Data width.
alignment (log2 of int) – Range alignment. Each added resource and window will be placed at an address that is a multiple of
2 ** alignment
, and its size will be rounded up to be a multiple of2 ** alignment
.name (str | None) – Name of the address range.
- freeze() None ¶
Freeze the memory map.
Once the memory map is frozen, its visible state becomes immutable. Resources and windows cannot be added anymore, and its address width cannot be extended further.
- add_resource(resource: object, *, name: str, size: int, addr: int | None = None, alignment: int | None = None, extend: bool = False) tuple[int, int] ¶
Add a resource.
A resource is any device on the bus that is a destination for bus transactions, e.g. a register or a memory block.
- Parameters:
resource (object) – Arbitrary object representing a resource.
name (str) – Name of the resource. It must not collide with the name of other resources or windows present in this memory map.
addr (int | None) – Address of the resource. If
None
, the implicit next address will be used. Otherwise, the exact specified address (which must be a multiple of2 ** max(alignment, self.alignment)
) will be used.size (int) – Size of the resource, in minimal addressable units. Rounded up to a multiple of
2 ** max(alignment, self.alignment)
.alignment (log2 of int | None) – Alignment of the resource. If not specified, the memory map alignment is used.
extend (bool) – Allow memory map extension. If
True
, the upper bound of the address space is raised as needed, in order to fit a resource that would otherwise be out of bounds.
- Return type:
- Returns:
tuple[int, int] – A tuple
[start, end)
describing the address range assigned to the resource.- Raises:
ValueError – If one of the following occurs: - this memory map is frozen; - the requested address and size, after alignment, would overlap with any resources or windows that have already been added, or would be out of bounds; - the resource has already been added to this memory map; - the name of the resource is already present in the namespace of this memory map;
- resources()¶
Iterate local resources and their address ranges.
Non-recursively iterate resources in ascending order of their address.
- Returns:
Generator[] – Yields a tuple
resource, name, (start, end)
describing the address range assigned to the resource.
- add_window(window: MemoryMap, *, addr: int | None = None, sparse: int | None = None, extend: bool = False) tuple[int, int, int] ¶
Add a window.
A window is a device on a bus that provides access to a different bus, i.e. a bus bridge. It performs address translation, such that the devices on a subordinate bus have different addresses; the memory map reflects this address translation when resources are looked up through the window.
Sparse addressing
If a narrow bus is bridged to a wide bus, the bridge can perform sparse or dense address translation. In the sparse case, each transaction on the wide bus results in one transaction on the narrow bus; high data bits on the wide bus are ignored, and any contiguous resource on the narrow bus becomes discontiguous on the wide bus. In the dense case, each transaction on the wide bus results in several transactions on the narrow bus, and any contiguous resource on the narrow bus stays contiguous on the wide bus.
- Parameters:
window (
MemoryMap
) – A memory map describing the layout of the window. It is frozen as a side-effect of being added to this memory map.addr (int or None) – Address of the window. If
None
, the implicit next address will be used after aligning it to2 ** window.addr_width
. Otherwise, the exact specified address (which must be a multiple of2 ** window.addr_width
) will be used.sparse (bool or None) – Address translation type. Ignored if the datapath widths of both memory maps are equal; must be specified otherwise.
extend (bool) – Allow memory map extension. If
True
, the upper bound of the address space is raised as needed, in order to fit a window that would otherwise be out of bounds.
- Return type:
- Returns:
tuple[int, int, int] – A tuple
(start, end, ratio)
describing the address range assigned to the window. When bridging buses of unequal data width,ratio
is the amount of contiguous addresses on the narrower bus that are accessed for each transaction on the wider bus. Otherwise, it is always 1.- Raises:
ValueError – If one of the following occurs: - this memory map is frozen; - the requested address and size, after alignment, would overlap with any resources or windows that have already been added, or would be out of bounds; - the added memory map has a wider datapath than this memory map; - dense address translation is used and the datapath width of this memory map is not an integer multiple of the datapath of the added memory map; - the name of the added memory map is already present in the namespace of this memory map; - the added memory map has no name, and the name of one of its subordinate resources or windows is already present in the namespace of this memory map;
- windows()¶
Iterate local windows and their address ranges.
Non-recursively iterate windows in ascending order of their address.
- Returns:
Generator – Yields a tuple
window, (start, end, ratio)
describing the address range assigned to the window. When bridging buses of unequal data width,ratio
is the amount of contiguous addresses on the narrower bus that are accessed for each transaction on the wider bus. Otherwise, it is always 1.
- window_patterns() Generator[tuple[MemoryMap, tuple[str, int]]] ¶
Iterate local windows and patterns that match their address ranges.
Non-recursively iterate windows in ascending order of their address.
- Return type:
- Returns:
Generator[tuple[MemoryMap, tuple[str, int]]] – Yields a tuple
window, (pattern, ratio)
describing the address range assigned to the window.pattern
is aself.addr_width
wide pattern that may be used inCase
ormatch
to determine if an address signal is within the address range ofwindow
. When bridging buses of unequal data width,ratio
is the amount of contiguous addresses on the narrower bus that are accessed for each transaction on the wider bus. Otherwise, it is always 1.
- all_resources() Generator[ResourceInfo] ¶
Iterate all resources and their address ranges.
Recursively iterate all resources in ascending order of their address, performing address translation for resources that are located behind a window.
- Return type:
- Returns:
Generator[ResourceInfo] – Yields instances of
ResourceInfo
describing the resource and its address range.
- find_resource(resource: object) ResourceInfo ¶
Find address range corresponding to a resource.
Recursively find the address range of a resource, performing address translation for resources that are located behind a window.
- Parameters:
resource (
object
) – Resource previously added to this memory map or any windows.- Return type:
- Returns:
ResourceInfo – An instance of
ResourceInfo
describing the resource and its address range.- Raises:
KeyError – If the resource is not found.
- class torii.lib.mem.map.ResourceInfo(resource: object, name: str | Iterable[str], start: int, end: int, width: int) None ¶
Resource metadata.
A wrapper class for resource objects, with their assigned name and address range.
- Parameters:
resource (object) – Arbitrary object representing a resource. See
MemoryMap.add_resource()
for details.name (iter(str)) – Name assigned to the resource. It is prefixed by the name of each window sitting between the resource and the memory map from which this
ResourceInfo
was obtained. SeeMemoryMap.add_window()
for details.start (int) – Start of the address range assigned to the resource.
end (int) – End of the address range assigned to the resource.
width (int) – Amount of data bits accessed at each address. It may be equal to the data width of the memory map from which this
ResourceInfo
was obtained, or less if the resource is located behind a window that uses sparse addressing.