Source code for avl_axi._interface

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

from typing import Any

from cocotb.handle import HierarchyObject

parameters = [
    "CLASSIFICATION",
    "VERSION",
    "ADDR_WIDTH",
    "ARSNOOP_WIDTH",
    "AWCMO_WIDTH",
    "AWSNOOP_WIDTH",
    "BRESP_WIDTH",
    "DATA_WIDTH",
    "ID_R_WIDTH",
    "ID_W_WIDTH",
    "LOOP_R_WIDTH",
    "LOOP_W_WIDTH",
    "MECID_WIDTH",
    "MPAM_WIDTH",
    "RCHUNKNUM_WIDTH",
    "RCHUNKSTRB_WIDTH",
    "RRESP_WIDTH",
    "SECSID_WIDTH",
    "SID_WIDTH",
    "SSID_WIDTH",
    "SUBSYSID_WIDTH",
    "USER_DATA_WIDTH",
    "USER_REQ_WIDTH",
    "USER_RESP_WIDTH",
    "Atomic_Transactions",
    "Busy_Support",
    "BURST_Present",
    "CACHE_Present",
    "Cache_Line_Size",
    "Cache_Stash_Transactions",
    "CMO_On_Read",
    "CMO_On_Write",
    "Coherency_Connection_Signals",
    "Consistent_DECERR",
    "DeAllocation_Transactions",
    "Device_Normal_Independence",
    "DVM_Message_Support",
    "DVM_v8",
    "DVM_v8_1",
    "DVM_v8_4",
    "DVM_v9_2",
    "Exclusive_Accesses",
    "Fixed_Burst_Disable",
    "InvalidateHint_Transaction",
    "LEN_Present",
    "Loopback_Signals",
    "Max_Transaction_Bytes",
    "MEC_Support",
    "MMUFLOW_Present",
    "MPAM_Support",
    "MTE_Support",
    "Multi_Copy_Atomicity",
    "NSAccess_Identifiers",
    "Ordered_Write_Observation",
    "PBHA_Support",
    "Persist_CMO",
    "Poison",
    "Prefetch_Transaction",
    "PROT_Present",
    "QoS_Accept",
    "QOS_Present",
    "Read_Data_Chunking",
    "Read_Interleaving_Disabled",
    "REGION_Present",
    "Regular_Transactions_Only",
    "RLAST_Present",
    "RME_Support",
    "Shareable_Cache_Support",
    "Shareable_Transactions",
    "SIZE_Present",
    "STASHLPID_Present",
    "STASHNID_Present",
    "Trace_Signals",
    "Unique_ID_Support",
    "UnstashTranslation_Transaction",
    "Untranslated_Transactions",
    "Wakeup_Signals",
    "WLAST_Present",
    "Write_Plus_CMO",
    "WriteDeferrable_Transaction",
    "WriteNoSnoopFull_Transaction",
    "WriteZero_Transaction",
    "WSTRB_Present",
    "AXI_Transport",
    "Shared_Credits_AW",
    "Shared_Credits_W",
    "Shared_Credits_AR",
    "Num_RP_AWW",
    "Num_RP_AR",
    "NUM_CREDITS",
    "NUM_SHARED_CREDITS",
    "STRB_WIDTH",
    "RUSER_WIDTH",
    "CMO_WIDTH",
    "TAG_WIDTH",
    "TAGUPDATE_WIDTH",
    "POISON_WIDTH",
    "NUM_RP_AWW_WIDTH",
    "NUM_RP_AR_WIDTH",
]

[docs] class Interface:
[docs] def __init__(self, hdl : HierarchyObject) -> None: # noqa: C901 """ Create an interface Work around simulator specific issues with accessing signals inside generates. :param hdl: The handle to the interface :type hdl: HierarchyObject :return: None """ # 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 child in list(hdl): # Signals start with a lowercase letter if not child._name[0].isupper(): setattr(self, child._name, child) if self.CLASSIFICATION != "AXI": raise TypeError(f"Expected AXI classification, got {self.CLASSIFICATION}") if self.VERSION not in [5]: raise ValueError(f"Unsupported AXI version: {self.VERSION}") # Remove un-configured signals if self.ID_W_WIDTH == 0: delattr(self, "awid") delattr(self, "bid") if self.REGION_Present == 0: delattr(self, "awregion") delattr(self, "arregion") if self.LEN_Present == 0: delattr(self, "awlen") delattr(self, "arlen") if self.SIZE_Present == 0: delattr(self, "awsize") delattr(self, "arsize") if self.BURST_Present == 0: delattr(self, "awburst") delattr(self, "arburst") if self.Exclusive_Accesses == 0: delattr(self, "awlock") delattr(self, "arlock") if self.CACHE_Present == 0: delattr(self, "awcache") delattr(self, "arcache") if self.PROT_Present == 0: delattr(self, "awprot") delattr(self, "arprot") if self.RME_Support == 0: delattr(self, "awnse") delattr(self, "arnse") if self.QOS_Present == 0: delattr(self, "awqos") delattr(self, "arqos") if self.USER_REQ_WIDTH == 0: delattr(self, "awuser") delattr(self, "aruser") if self.Shareable_Transactions == 0: delattr(self, "awdomain") delattr(self, "ardomain") if self.AWSNOOP_WIDTH == 0: delattr(self, "awsnoop") if self.ARSNOOP_WIDTH == 0: delattr(self, "arsnoop") if self.STASHNID_Present == 0: delattr(self, "awstashnid") delattr(self, "awstashniden") delattr(self, "awstashlpid") delattr(self, "awstashlpiden") if self.Trace_Signals == 0: delattr(self, "awtrace") delattr(self, "wtrace") delattr(self, "btrace") delattr(self, "artrace") delattr(self, "rtrace") if self.Loopback_Signals == 0 or self.LOOP_W_WIDTH == 0: delattr(self, "awloop") delattr(self, "bloop") if self.Loopback_Signals == 0 or self.LOOP_R_WIDTH == 0: delattr(self, "arloop") delattr(self, "rloop") if self.Untranslated_Transactions != "v3": delattr(self, "awmmuvalid") delattr(self, "armmuvalid") if self.Untranslated_Transactions == "False" or self.SECSID_WIDTH == 0: delattr(self, "awmmusecsid") delattr(self, "armmusecsid") if self.Untranslated_Transactions == "False" or self.SID_WIDTH == 0: delattr(self, "awmmusid") delattr(self, "armmusid") if self.Untranslated_Transactions == "False" or self.SSID_WIDTH == 0: delattr(self, "awmmussidv") delattr(self, "awmmussid") delattr(self, "armmussidv") delattr(self, "armmussid") if self.MMUFLOW_Present == 0 or (self.Untranslated_Transactions not in ["v1", "True"]): delattr(self, "awmmuatst") delattr(self, "armmuatst") if self.MMUFLOW_Present == 0 or (self.Untranslated_Transactions not in ["v2", "v3"]): delattr(self, "awmmuflow") delattr(self, "armmuflow") if self.PBHA_Support == 0: delattr(self, "awpbha") delattr(self, "arpbha") if self.MEC_Support == 0: delattr(self, "awmecid") delattr(self, "armecid") if self.NSAccess_Identifiers == 0: delattr(self, "awnsaid") delattr(self, "arnsaid") if self.SUBSYSID_WIDTH == 0: delattr(self, "awsubsysid") delattr(self, "arsubsysid") if self.Atomic_Transactions == 0: delattr(self, "awatop") if self.MPAM_Support == "False": delattr(self, "awmpam") delattr(self, "armpam") if self.Unique_ID_Support == 0 or self.ID_W_WIDTH == 0: delattr(self, "awidunq") delattr(self, "bidunq") if self.Unique_ID_Support == 0 or self.ID_R_WIDTH == 0: delattr(self, "aridunq") delattr(self, "ridunq") if self.CMO_On_Write == 0: delattr(self, "awcmo") if self.MTE_Support == "False": delattr(self, "awtagop") delattr(self, "wtag") delattr(self, "wtagupdate") delattr(self, "artagop") delattr(self, "rtag") if self.WSTRB_Present == 0: delattr(self, "wstrb") if self.WLAST_Present == 0: delattr(self, "wlast") if self.USER_DATA_WIDTH == 0: delattr(self, "wuser") if self.Poison == 0: delattr(self, "wpoison") delattr(self, "rpoison") if self.BRESP_WIDTH == 0: delattr(self, "bresp") if (self.Persist_CMO == 0 or self.CMO_On_Write == 0) and self.MTE_Support != "Standard": delattr(self, "bcomp") if self.Persist_CMO == 0 or self.CMO_On_Write == 0: delattr(self, "bpersist") if self.MTE_Support != "Standard": delattr(self, "btagmatch") if self.USER_RESP_WIDTH == 0: delattr(self, "buser") if self.Busy_Support == 0: delattr(self, "bbusy") delattr(self, "rbusy") if self.ID_R_WIDTH == 0: delattr(self, "arid") delattr(self, "rid") if self.RRESP_WIDTH == 0: delattr(self, "rresp") if self.RLAST_Present == 0: delattr(self, "rlast") if self.USER_DATA_WIDTH == 0 and self.USER_RESP_WIDTH == 0: delattr(self, "ruser") if self.Read_Data_Chunking == 0: delattr(self, "archunken") delattr(self, "rchunkv") if self.Read_Data_Chunking == 0 or self.RCHUNKNUM_WIDTH == 0: delattr(self, "rchunknum") if self.Read_Data_Chunking == 0 or self.RCHUNKSTRB_WIDTH == 0: delattr(self, "rchunkstrb") if self.DVM_Message_Support == "False": delattr(self, "acvalid") delattr(self, "acready") delattr(self, "acaddr") delattr(self, "acvmidext") delattr(self, "crvalid") delattr(self, "crready") if self.DVM_Message_Support == "False" or self.Trace_Signals == 0: delattr(self, "actrace") delattr(self, "crtrace") if self.Wakeup_Signals == 0: delattr(self, "awakeup") if self.Wakeup_Signals == 0 or self.DVM_Message_Support == "False": delattr(self, "acwakeup") if self.QoS_Accept == 0: delattr(self, "varqosaccept") delattr(self, "vawqosaccept") if self.Coherency_Connection_Signals == 0: delattr(self, "syscoreq") delattr(self, "syscoack") if self.AXI_Transport != "Credited": delattr(self, "awpending") delattr(self, "awcrdt") delattr(self, "awrp") delattr(self, "wpending") delattr(self, "wcrdt") delattr(self, "wrp") delattr(self, "bpending") delattr(self, "bcrdt") delattr(self, "arpending") delattr(self, "arcrdt") delattr(self, "arrp") delattr(self, "rpending") delattr(self, "rcrdt") if self.Shared_Credits_AW == 0: delattr(self, "awcrdtsh") delattr(self, "awsharedcrd") if self.Shared_Credits_W == 0: delattr(self, "wcrdtsh") delattr(self, "wsharedcrd") if self.Shared_Credits_AR == 0: delattr(self, "arcrdtsh") delattr(self, "arsharedcrd") else: delattr(self, "awready") delattr(self, "arready") delattr(self, "wready") delattr(self, "bready") delattr(self, "rready") # Sanity checks if hasattr(self, "awlock"): if not hasattr(self, "rresp") or len(self.rresp) < 2: raise ValueError("AXI Exclusive accesses require RRESP to be 2 bits wide (minimum)") if not hasattr(self, "bresp") or len(self.bresp) < 2: raise ValueError("AXI Exclusive accesses require BRESP to be 2 bits wide (minimum)")
[docs] def set(self, name : str, value : int, idx : int = None, ) -> 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 :param idx: The index if array :type idx: int :return: None """ signal = getattr(self, name, None) if signal is not None: if idx is not None: signal[idx].value = value else: signal.value = value
[docs] def get(self, name : str, idx : int = None, default : Any = None) -> int: """ Get the value of a signal (if signal exists) :param name: The name of the signal :type name: str :param idx: The index if array :type idx: int :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: if idx is not None: return signal[idx].value else: return signal.value return default
__all__ = ["Interface"]