Source code for avl_ral._ral

# Copyright 2026 Apheleia
#
# Description:
# Apheleia Verification Library Register Abstraction Component

from fnmatch import fnmatch

import avl
from peakrdl_ipxact import IPXACTImporter
from systemrdl import RDLCompileError, RDLCompiler
from systemrdl.component import Addrmap
from systemrdl.node import FieldNode, RegNode

from ._reg import Reg


[docs] class RAL(avl.Component):
[docs] def __init__(self, name : str, parent : avl.Component | None) -> None: """ Initialize the example environment with a simple memory model and an x86 QEMU agent. :param name: The name of the environment. :type name: str :param parent: The parent component in the AVL hierarchy. :type parent: avl.Component :return: None """ super().__init__(name, parent) self._rdlc_ : RDLCompiler = RDLCompiler() """SystemRDL Compiler""" self._addrmaps_ : dict[str, Addrmap] = {} """List of address maps""" self._class_overrides_ = { RegNode : Reg, }
def __str__(self) -> str: """ Custom String Formatting :return: The formatted string :rtype: str """ _str_ = "" for addrmap in self._addrmaps_.values(): _str_ += str(addrmap.children()[0]) return _str_ def _assign_addrmaps_(self) -> None: """ Assign the address maps to the component :return: None """ for name, comp in self._rdlc_.root.comp_defs.items(): if isinstance(comp, Addrmap): root = self._rdlc_.elaborate(name) self._addrmaps_[name] = root def _load_rdl_(self, path : str) -> None: """ Load the RAL definition from RDL file :param path: The path to the RAL definition file :type path: str :return: None """ try: self._rdlc_.compile_file(path) except RDLCompileError as e: self.fatal(f"RDL Compilation failed: {e}") self._assign_addrmaps_() def _load_ipxact_(self, path : str) -> None: """ Load the RAL definition from IPXACT XML :param path: The path to the XML definition file :type path: str :return: None """ try: ipxact = IPXACTImporter(self._rdlc_) ipxact.import_file(path) except RDLCompileError as e: self.fatal(f"IPXACT Compilation failed: {e}") self._assign_addrmaps_()
[docs] def load_definition(self, path : str) -> None: """ Load the RAL definition from a file :param path: The path to the RAL definition file :type path: str :return: None """ if path.endswith(".rdl"): self._load_rdl_(path) elif path.endswith(".xml"): self._load_ipxact_(path) else: self.fatal(f"Unsupported RDL file type: {path}")
[docs] def find_by_name(self, addrmaps : list[Addrmap] = None, name : str = "*", types : tuple[type] = None) -> list[RegNode | FieldNode]: """ Find a node by name :param addrmaps: The address maps to search :type addrmaps: list[Addrmap] :param name: The name to search for :type name: str :param types: The types to search for :type types: tuple[type] :return: The found node :rtype: list[RegNode | FieldNode] """ matches = [] if addrmaps is None: addrmaps = self._addrmaps_.values() if types is None: types = (RegNode, FieldNode) for addrmap in addrmaps: for node in addrmap.descendants(): if isinstance(node, types): if "." in name: if fnmatch(node.get_rel_path(addrmap), name): matches.append(node) else: if fnmatch(node.inst_name, name): matches.append(node) return matches
[docs] def find_by_address(self, addrmaps : list[Addrmap] = None, address : int = 0, types : tuple[type] = None) -> list[RegNode | FieldNode]: """ Find a node by Address :param addrmaps: The address maps to search :type addrmaps: list[Addrmap] :param address: The address to search for :type address: int :param types: The types to search for :type types: tuple[type] :return: The found node :rtype: list[RegNode | FieldNode] """ matches = [] for m in self.find_by_name(addrmaps=addrmaps, name = "*", types=types): if isinstance(m, FieldNode): if m.parent.absolute_address == address: matches.append(m) else: if m.absolute_address == address: matches.append(m) return matches
[docs] def assign_callbacks(self, addrmaps : list[Addrmap] = None, read : callable = None, write : callable = None) -> None: """ Assign callbacks to the RAL :param addrmaps: The address maps to assign callbacks to :type addrmaps: list[Addrmap] :param read: The read callback :type read: callable :param write: The write callback :type write: callable :return: None """ if addrmaps is None: addrmaps = self._addrmaps_.values() for addrmap in addrmaps: if read is not None: addrmap.read_callback = read if write is not None: addrmap.write_callback = write
__all__ = ["RAL"]