Source code for avl_apb._interface

# Copyright 2025 Apheleia
#
# Description:
# Apheleia Verification Library Interface

from typing import Any

from cocotb.handle import HierarchyObject

parameters = [
    "CLASSIFICATION",
    "VERSION",
    "PSEL_WIDTH",
    "ADDR_WIDTH",
    "DATA_WIDTH",
    "Protection_Support",
    "RME_Support",
    "Pstrb_Support",
    "Wakeup_Signal",
    "USER_REQ_WIDTH",
    "USER_DATA_WIDTH",
    "USER_RESP_WIDTH",
    "PSTRB_WIDTH",
]

signals = [
  "paddr",
  "pauser",
  "pbuser",
  "pclk",
  "penable",
  "pnse",
  "pprot",
  "prdata",
  "pready",
  "presetn",
  "pruser",
  "psel",
  "pslverr",
  "pstrb",
  "pwakeup",
  "pwdata",
  "pwrite",
  "pwuser",
]

[docs] class Interface:
[docs] def __init__(self, hdl : HierarchyObject) -> None: """ Create an interface Work around simulator specific issues with accessing signals inside generates. """ # Parameters for p in parameters: # Parameters not exposed by list() in some simulators - look up explicitly v = getattr(hdl, p) if isinstance(v.value, bytes): setattr(self, p, str(v.value.decode("utf-8"))) else: setattr(self, p, int(v.value)) # Signals for s in signals: # Some simulators do not expose signals inside interfaces through list(hdl). # Populate the _sub_handle cache explicitly. child = getattr(hdl, s) setattr(self, child._name, child) if self.CLASSIFICATION != "APB": raise TypeError(f"Expected APB classification, got {self.CLASSIFICATION}") if self.VERSION not in [2, 3, 4, 5]: raise ValueError(f"Unsupported APB version: {self.VERSION}") if self.PSEL_WIDTH < 1: raise ValueError(f"Invalid PSEL_WIDTH: {self.PSEL_WIDTH}") # Remove un-configured signals if self.VERSION < 3: delattr(self, "pready") delattr(self, "pslverr") if self.VERSION < 4 or self.Protection_Support == 0: delattr(self, "pprot") if self.VERSION < 4 or self.Pstrb_Support == 0: delattr(self, "pstrb") if self.VERSION < 5 or self.RME_Support == 0: delattr(self, "pnse") if self.VERSION < 5 or self.Wakeup_Signal == 0: delattr(self, "pwakeup") if self.VERSION < 5 or self.USER_REQ_WIDTH == 0: delattr(self, "pauser") if self.VERSION < 5 or self.USER_DATA_WIDTH == 0: delattr(self, "pwuser") delattr(self, "pruser") if self.VERSION < 5 or self.USER_RESP_WIDTH == 0: delattr(self, "pbuser")
[docs] def set(self, name : str, value : int) -> None: """ Set the value of a signal (if signal exists) :param name: The name of the signal :type name: str :param value: The value to set :type value: int :return: None """ signal = getattr(self, name, None) if signal is not None: signal.value = value
[docs] def get(self, name : str, default : Any = None) -> int: """ Get the value of a signal (if signal exists) :param name: The name of the signal :type name: str :param default: The default value to return if signal does not exist :type default: Any :return: The value of the signal or the default value :rtype: int """ signal = getattr(self, name, None) if signal is not None: return int(signal.value) return default
__all__ = ["Interface"]