from typing import TYPE_CHECKING from systemrdl.node import AddressableNode from ...utils import get_indexed_path from ..base_cpuif import BaseCpuif from .apb3_interface import APB3FlatInterface if TYPE_CHECKING: from ...exporter import BusDecoderExporter class APB3CpuifFlat(BaseCpuif): template_path = "apb3_tmpl.sv" def __init__(self, exp: "BusDecoderExporter") -> None: super().__init__(exp) self._interface = APB3FlatInterface(self) @property def is_interface(self) -> bool: return self._interface.is_interface @property def port_declaration(self) -> str: return self._interface.get_port_declaration("s_apb_", "m_apb_") def signal( self, signal: str, node: AddressableNode | None = None, idx: str | int | None = None, ) -> str: return self._interface.signal(signal, node, idx) def fanout(self, node: AddressableNode) -> str: fanout: dict[str, str] = {} fanout[self.signal("PSEL", node)] = ( f"cpuif_wr_sel.{get_indexed_path(self.exp.ds.top_node, node, 'i')}|cpuif_rd_sel.{get_indexed_path(self.exp.ds.top_node, node, 'i')}" ) fanout[self.signal("PENABLE", node)] = self.signal("PENABLE") fanout[self.signal("PWRITE", node)] = ( f"cpuif_wr_sel.{get_indexed_path(self.exp.ds.top_node, node, 'i')}" ) fanout[self.signal("PADDR", node)] = self.signal("PADDR") fanout[self.signal("PWDATA", node)] = "cpuif_wr_data" return "\n".join(map(lambda kv: f"assign {kv[0]} = {kv[1]};", fanout.items())) def fanin(self, node: AddressableNode | None = None) -> str: fanin: dict[str, str] = {} if node is None: fanin["cpuif_rd_ack"] = "'0" fanin["cpuif_rd_err"] = "'0" else: fanin["cpuif_rd_ack"] = self.signal("PREADY", node) fanin["cpuif_rd_err"] = self.signal("PSLVERR", node) return "\n".join(map(lambda kv: f"{kv[0]} = {kv[1]};", fanin.items())) def readback(self, node: AddressableNode | None = None) -> str: fanin: dict[str, str] = {} if node is None: fanin["cpuif_rd_data"] = "'0" else: fanin["cpuif_rd_data"] = self.signal("PRDATA", node) return "\n".join(map(lambda kv: f"{kv[0]} = {kv[1]};", fanin.items()))