* Initial plan * Refactor cpuif classes to use Interface abstraction Co-authored-by: arnavsacheti <36746504+arnavsacheti@users.noreply.github.com> * Fix type annotation consistency in Interface.signal() Co-authored-by: arnavsacheti <36746504+arnavsacheti@users.noreply.github.com> * Add runtime validation and documentation for indexer types Co-authored-by: arnavsacheti <36746504+arnavsacheti@users.noreply.github.com> * Remove unused variable in SVInterface.signal() Co-authored-by: arnavsacheti <36746504+arnavsacheti@users.noreply.github.com> * Fix master port directions in APB3 and APB4 flat interfaces Co-authored-by: arnavsacheti <36746504+arnavsacheti@users.noreply.github.com> * Fix AXI4LiteCpuifFlat and apply code formatting Co-authored-by: arnavsacheti <36746504+arnavsacheti@users.noreply.github.com> * PSELx -> PSEL * cleanup marker warnings --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: arnavsacheti <36746504+arnavsacheti@users.noreply.github.com>
69 lines
2.3 KiB
Python
69 lines
2.3 KiB
Python
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()))
|