Fix APB PREADY not asserted on invalid address decode errors (#40)
Fix APB PREADY signal to assert during error conditions Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: arnavsacheti <36746504+arnavsacheti@users.noreply.github.com>
This commit is contained in:
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "peakrdl-busdecoder"
|
||||
version = "0.6.5"
|
||||
version = "0.6.6"
|
||||
requires-python = ">=3.10"
|
||||
dependencies = [
|
||||
"jinja2~=3.1",
|
||||
|
||||
@@ -47,11 +47,36 @@ class APB3Cpuif(BaseCpuif):
|
||||
|
||||
return "\n".join(f"assign {kv[0]} = {kv[1]};" for kv in fanout.items())
|
||||
|
||||
def fanin(self, node: AddressableNode | None = None) -> str:
|
||||
def fanin_wr(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
|
||||
fanin: dict[str, str] = {}
|
||||
if node is None:
|
||||
fanin["cpuif_wr_ack"] = "'0"
|
||||
fanin["cpuif_wr_err"] = "'0"
|
||||
if error:
|
||||
fanin["cpuif_wr_ack"] = "'1"
|
||||
fanin["cpuif_wr_err"] = "cpuif_wr_sel.cpuif_err"
|
||||
else:
|
||||
# Use intermediate signals for interface arrays to avoid
|
||||
# non-constant indexing of interface arrays in procedural blocks
|
||||
if self.is_interface and node.is_array and node.array_dimensions:
|
||||
# Generate array index string [i0][i1]... for the intermediate signal
|
||||
array_idx = "".join(f"[i{i}]" for i in range(len(node.array_dimensions)))
|
||||
fanin["cpuif_wr_ack"] = f"{node.inst_name}_fanin_ready{array_idx}"
|
||||
fanin["cpuif_wr_err"] = f"{node.inst_name}_fanin_err{array_idx}"
|
||||
else:
|
||||
fanin["cpuif_wr_ack"] = self.signal("PREADY", node, "i")
|
||||
fanin["cpuif_wr_err"] = self.signal("PSLVERR", node, "i")
|
||||
return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
|
||||
|
||||
def fanin_rd(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
|
||||
fanin: dict[str, str] = {}
|
||||
if node is None:
|
||||
fanin["cpuif_rd_ack"] = "'0"
|
||||
fanin["cpuif_rd_err"] = "'0"
|
||||
fanin["cpuif_rd_data"] = "'0"
|
||||
if error:
|
||||
fanin["cpuif_rd_ack"] = "'1"
|
||||
fanin["cpuif_rd_err"] = "cpuif_rd_sel.cpuif_err"
|
||||
else:
|
||||
# Use intermediate signals for interface arrays to avoid
|
||||
# non-constant indexing of interface arrays in procedural blocks
|
||||
@@ -60,24 +85,10 @@ class APB3Cpuif(BaseCpuif):
|
||||
array_idx = "".join(f"[i{i}]" for i in range(len(node.array_dimensions)))
|
||||
fanin["cpuif_rd_ack"] = f"{node.inst_name}_fanin_ready{array_idx}"
|
||||
fanin["cpuif_rd_err"] = f"{node.inst_name}_fanin_err{array_idx}"
|
||||
fanin["cpuif_rd_data"] = f"{node.inst_name}_fanin_data{array_idx}"
|
||||
else:
|
||||
fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
|
||||
fanin["cpuif_rd_err"] = self.signal("PSLVERR", node, "i")
|
||||
|
||||
return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
|
||||
|
||||
def readback(self, node: AddressableNode | None = None) -> str:
|
||||
fanin: dict[str, str] = {}
|
||||
if node is None:
|
||||
fanin["cpuif_rd_data"] = "'0"
|
||||
else:
|
||||
# Use intermediate signals for interface arrays to avoid
|
||||
# non-constant indexing of interface arrays in procedural blocks
|
||||
if self.is_interface and node.is_array and node.array_dimensions:
|
||||
# Generate array index string [i0][i1]... for the intermediate signal
|
||||
array_idx = "".join(f"[i{i}]" for i in range(len(node.array_dimensions)))
|
||||
fanin["cpuif_rd_data"] = f"{node.inst_name}_fanin_data{array_idx}"
|
||||
else:
|
||||
fanin["cpuif_rd_data"] = self.signal("PRDATA", node, "i")
|
||||
|
||||
return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
|
||||
|
||||
@@ -53,22 +53,32 @@ class APB3CpuifFlat(BaseCpuif):
|
||||
|
||||
return "\n".join(f"assign {kv[0]} = {kv[1]};" for kv in fanout.items())
|
||||
|
||||
def fanin(self, node: AddressableNode | None = None) -> str:
|
||||
def fanin_wr(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
|
||||
fanin: dict[str, str] = {}
|
||||
if node is None:
|
||||
fanin["cpuif_wr_ack"] = "'0"
|
||||
fanin["cpuif_wr_err"] = "'0"
|
||||
if error:
|
||||
fanin["cpuif_wr_ack"] = "'1"
|
||||
fanin["cpuif_wr_err"] = "cpuif_wr_sel.cpuif_err"
|
||||
else:
|
||||
fanin["cpuif_wr_ack"] = self.signal("PREADY", node, "i")
|
||||
fanin["cpuif_wr_err"] = self.signal("PSLVERR", node, "i")
|
||||
|
||||
return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
|
||||
|
||||
def fanin_rd(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
|
||||
fanin: dict[str, str] = {}
|
||||
if node is None:
|
||||
fanin["cpuif_rd_ack"] = "'0"
|
||||
fanin["cpuif_rd_err"] = "'0"
|
||||
fanin["cpuif_rd_data"] = "'0"
|
||||
if error:
|
||||
fanin["cpuif_rd_ack"] = "'1"
|
||||
fanin["cpuif_rd_err"] = "cpuif_rd_sel.cpuif_err"
|
||||
else:
|
||||
fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
|
||||
fanin["cpuif_rd_err"] = self.signal("PSLVERR", node, "i")
|
||||
|
||||
return "\n".join(f"{kv[0]} = {kv[1]};" for kv in 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, "i")
|
||||
|
||||
return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
|
||||
|
||||
@@ -19,8 +19,8 @@ assign cpuif_rd_addr = {{cpuif.signal("PADDR")}};
|
||||
assign cpuif_wr_data = {{cpuif.signal("PWDATA")}};
|
||||
|
||||
assign {{cpuif.signal("PRDATA")}} = cpuif_rd_data;
|
||||
assign {{cpuif.signal("PREADY")}} = cpuif_rd_ack;
|
||||
assign {{cpuif.signal("PSLVERR")}} = cpuif_rd_err | cpuif_rd_sel.cpuif_err | cpuif_wr_sel.cpuif_err;
|
||||
assign {{cpuif.signal("PREADY")}} = cpuif_rd_ack | cpuif_wr_ack;
|
||||
assign {{cpuif.signal("PSLVERR")}} = cpuif_rd_err | cpuif_wr_err;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Fanout CPU Bus interface signals
|
||||
|
||||
@@ -50,11 +50,37 @@ class APB4Cpuif(BaseCpuif):
|
||||
|
||||
return "\n".join(f"assign {kv[0]} = {kv[1]};" for kv in fanout.items())
|
||||
|
||||
def fanin(self, node: AddressableNode | None = None) -> str:
|
||||
def fanin_wr(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
|
||||
fanin: dict[str, str] = {}
|
||||
if node is None:
|
||||
fanin["cpuif_wr_ack"] = "'0"
|
||||
fanin["cpuif_wr_err"] = "'0"
|
||||
if error:
|
||||
fanin["cpuif_wr_ack"] = "'1"
|
||||
fanin["cpuif_wr_err"] = "cpuif_wr_sel.cpuif_err"
|
||||
else:
|
||||
# Use intermediate signals for interface arrays to avoid
|
||||
# non-constant indexing of interface arrays in procedural blocks
|
||||
if self.is_interface and node.is_array and node.array_dimensions:
|
||||
# Generate array index string [i0][i1]... for the intermediate signal
|
||||
array_idx = "".join(f"[i{i}]" for i in range(len(node.array_dimensions)))
|
||||
fanin["cpuif_wr_ack"] = f"{node.inst_name}_fanin_ready{array_idx}"
|
||||
fanin["cpuif_wr_err"] = f"{node.inst_name}_fanin_err{array_idx}"
|
||||
else:
|
||||
fanin["cpuif_wr_ack"] = self.signal("PREADY", node, "i")
|
||||
fanin["cpuif_wr_err"] = self.signal("PSLVERR", node, "i")
|
||||
|
||||
return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
|
||||
|
||||
def fanin_rd(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
|
||||
fanin: dict[str, str] = {}
|
||||
if node is None:
|
||||
fanin["cpuif_rd_ack"] = "'0"
|
||||
fanin["cpuif_rd_err"] = "'0"
|
||||
fanin["cpuif_rd_data"] = "'0"
|
||||
if error:
|
||||
fanin["cpuif_rd_ack"] = "'1"
|
||||
fanin["cpuif_rd_err"] = "cpuif_rd_sel.cpuif_err"
|
||||
else:
|
||||
# Use intermediate signals for interface arrays to avoid
|
||||
# non-constant indexing of interface arrays in procedural blocks
|
||||
@@ -63,24 +89,10 @@ class APB4Cpuif(BaseCpuif):
|
||||
array_idx = "".join(f"[i{i}]" for i in range(len(node.array_dimensions)))
|
||||
fanin["cpuif_rd_ack"] = f"{node.inst_name}_fanin_ready{array_idx}"
|
||||
fanin["cpuif_rd_err"] = f"{node.inst_name}_fanin_err{array_idx}"
|
||||
fanin["cpuif_rd_data"] = f"{node.inst_name}_fanin_data{array_idx}"
|
||||
else:
|
||||
fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
|
||||
fanin["cpuif_rd_err"] = self.signal("PSLVERR", node, "i")
|
||||
|
||||
return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
|
||||
|
||||
def readback(self, node: AddressableNode | None = None) -> str:
|
||||
fanin: dict[str, str] = {}
|
||||
if node is None:
|
||||
fanin["cpuif_rd_data"] = "'0"
|
||||
else:
|
||||
# Use intermediate signals for interface arrays to avoid
|
||||
# non-constant indexing of interface arrays in procedural blocks
|
||||
if self.is_interface and node.is_array and node.array_dimensions:
|
||||
# Generate array index string [i0][i1]... for the intermediate signal
|
||||
array_idx = "".join(f"[i{i}]" for i in range(len(node.array_dimensions)))
|
||||
fanin["cpuif_rd_data"] = f"{node.inst_name}_fanin_data{array_idx}"
|
||||
else:
|
||||
fanin["cpuif_rd_data"] = self.signal("PRDATA", node, "i")
|
||||
|
||||
return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
|
||||
|
||||
@@ -55,22 +55,31 @@ class APB4CpuifFlat(BaseCpuif):
|
||||
|
||||
return "\n".join(f"assign {kv[0]} = {kv[1]};" for kv in fanout.items())
|
||||
|
||||
def fanin(self, node: AddressableNode | None = None) -> str:
|
||||
def fanin_wr(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
|
||||
fanin: dict[str, str] = {}
|
||||
if node is None:
|
||||
fanin["cpuif_wr_ack"] = "'0"
|
||||
fanin["cpuif_wr_err"] = "'0"
|
||||
if error:
|
||||
fanin["cpuif_wr_ack"] = "'1"
|
||||
fanin["cpuif_wr_err"] = "cpuif_wr_sel.cpuif_err"
|
||||
else:
|
||||
fanin["cpuif_wr_ack"] = self.signal("PREADY", node, "i")
|
||||
fanin["cpuif_wr_err"] = self.signal("PSLVERR", node, "i")
|
||||
return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
|
||||
|
||||
def fanin_rd(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
|
||||
fanin: dict[str, str] = {}
|
||||
if node is None:
|
||||
fanin["cpuif_rd_ack"] = "'0"
|
||||
fanin["cpuif_rd_err"] = "'0"
|
||||
fanin["cpuif_rd_data"] = "'0"
|
||||
if error:
|
||||
fanin["cpuif_rd_ack"] = "'1"
|
||||
fanin["cpuif_rd_err"] = "cpuif_rd_sel.cpuif_err"
|
||||
else:
|
||||
fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
|
||||
fanin["cpuif_rd_err"] = self.signal("PSLVERR", node, "i")
|
||||
|
||||
return "\n".join(f"{kv[0]} = {kv[1]};" for kv in 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, "i")
|
||||
|
||||
return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
|
||||
|
||||
@@ -20,8 +20,8 @@ assign cpuif_wr_data = {{cpuif.signal("PWDATA")}};
|
||||
assign cpuif_wr_byte_en = {{cpuif.signal("PSTRB")}};
|
||||
|
||||
assign {{cpuif.signal("PRDATA")}} = cpuif_rd_data;
|
||||
assign {{cpuif.signal("PREADY")}} = cpuif_rd_ack;
|
||||
assign {{cpuif.signal("PSLVERR")}} = cpuif_rd_err | cpuif_rd_sel.cpuif_err | cpuif_wr_sel.cpuif_err;
|
||||
assign {{cpuif.signal("PREADY")}} = cpuif_rd_ack | cpuif_wr_ack;
|
||||
assign {{cpuif.signal("PSLVERR")}} = cpuif_rd_err | cpuif_wr_err;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Fanout CPU Bus interface signals
|
||||
|
||||
@@ -63,11 +63,38 @@ class AXI4LiteCpuif(BaseCpuif):
|
||||
|
||||
return "\n".join(f"assign {lhs} = {rhs};" for lhs, rhs in fanout.items())
|
||||
|
||||
def fanin(self, node: AddressableNode | None = None) -> str:
|
||||
def fanin_wr(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
|
||||
fanin: dict[str, str] = {}
|
||||
if node is None:
|
||||
fanin["cpuif_wr_ack"] = "'0"
|
||||
fanin["cpuif_wr_err"] = "'0"
|
||||
if error:
|
||||
fanin["cpuif_wr_ack"] = "'1"
|
||||
fanin["cpuif_wr_err"] = "cpuif_wr_sel.cpuif_err"
|
||||
else:
|
||||
# Use intermediate signals for interface arrays to avoid
|
||||
# non-constant indexing of interface arrays in procedural blocks
|
||||
if self.is_interface and node.is_array and node.array_dimensions:
|
||||
# Generate array index string [i0][i1]... for the intermediate signal
|
||||
array_idx = "".join(f"[i{i}]" for i in range(len(node.array_dimensions)))
|
||||
fanin["cpuif_wr_ack"] = f"{node.inst_name}_fanin_ready{array_idx}"
|
||||
fanin["cpuif_wr_err"] = f"{node.inst_name}_fanin_err{array_idx}"
|
||||
else:
|
||||
# Read side: ack comes from RVALID; err if RRESP[1] is set (SLVERR/DECERR)
|
||||
fanin["cpuif_wr_ack"] = self.signal("BVALID", node, "i")
|
||||
fanin["cpuif_wr_err"] = f"{self.signal('BRESP', node, 'i')}[1]"
|
||||
|
||||
return "\n".join(f"{lhs} = {rhs};" for lhs, rhs in fanin.items())
|
||||
|
||||
def fanin_rd(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
|
||||
fanin: dict[str, str] = {}
|
||||
if node is None:
|
||||
fanin["cpuif_rd_ack"] = "'0"
|
||||
fanin["cpuif_rd_err"] = "'0"
|
||||
fanin["cpuif_rd_data"] = "'0"
|
||||
if error:
|
||||
fanin["cpuif_rd_ack"] = "'1"
|
||||
fanin["cpuif_rd_err"] = "cpuif_rd_sel.cpuif_err"
|
||||
else:
|
||||
# Use intermediate signals for interface arrays to avoid
|
||||
# non-constant indexing of interface arrays in procedural blocks
|
||||
@@ -76,25 +103,10 @@ class AXI4LiteCpuif(BaseCpuif):
|
||||
array_idx = "".join(f"[i{i}]" for i in range(len(node.array_dimensions)))
|
||||
fanin["cpuif_rd_ack"] = f"{node.inst_name}_fanin_ready{array_idx}"
|
||||
fanin["cpuif_rd_err"] = f"{node.inst_name}_fanin_err{array_idx}"
|
||||
else:
|
||||
# Read side: ack comes from RVALID; err if RRESP[1] is set (SLVERR/DECERR)
|
||||
fanin["cpuif_rd_ack"] = self.signal("RVALID", node, "i")
|
||||
fanin["cpuif_rd_err"] = f"{self.signal('RRESP', node, 'i')}[1]"
|
||||
|
||||
return "\n".join(f"{lhs} = {rhs};" for lhs, rhs in fanin.items())
|
||||
|
||||
def readback(self, node: AddressableNode | None = None) -> str:
|
||||
fanin: dict[str, str] = {}
|
||||
if node is None:
|
||||
fanin["cpuif_rd_data"] = "'0"
|
||||
else:
|
||||
# Use intermediate signals for interface arrays to avoid
|
||||
# non-constant indexing of interface arrays in procedural blocks
|
||||
if self.is_interface and node.is_array and node.array_dimensions:
|
||||
# Generate array index string [i0][i1]... for the intermediate signal
|
||||
array_idx = "".join(f"[i{i}]" for i in range(len(node.array_dimensions)))
|
||||
fanin["cpuif_rd_data"] = f"{node.inst_name}_fanin_data{array_idx}"
|
||||
else:
|
||||
fanin["cpuif_rd_ack"] = self.signal("RVALID", node, "i")
|
||||
fanin["cpuif_rd_err"] = f"{self.signal('RRESP', node, 'i')}[1]"
|
||||
fanin["cpuif_rd_data"] = self.signal("RDATA", node, "i")
|
||||
|
||||
return "\n".join(f"{lhs} = {rhs};" for lhs, rhs in fanin.items())
|
||||
|
||||
@@ -72,23 +72,33 @@ class AXI4LiteCpuifFlat(BaseCpuif):
|
||||
|
||||
return "\n".join(f"assign {lhs} = {rhs};" for lhs, rhs in fanout.items())
|
||||
|
||||
def fanin(self, node: AddressableNode | None = None) -> str:
|
||||
def fanin_wr(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
|
||||
fanin: dict[str, str] = {}
|
||||
if node is None:
|
||||
fanin["cpuif_wr_ack"] = "'0"
|
||||
fanin["cpuif_wr_err"] = "'0"
|
||||
if error:
|
||||
fanin["cpuif_wr_ack"] = "'1"
|
||||
fanin["cpuif_wr_err"] = "cpuif_wr_sel.cpuif_err"
|
||||
else:
|
||||
# Read side: ack comes from RVALID; err if RRESP[1] is set (SLVERR/DECERR)
|
||||
fanin["cpuif_wr_ack"] = self.signal("BVALID", node, "i")
|
||||
fanin["cpuif_wr_err"] = f"{self.signal('BRESP', node, 'i')}[1]"
|
||||
|
||||
return "\n".join(f"{lhs} = {rhs};" for lhs, rhs in fanin.items())
|
||||
|
||||
def fanin_rd(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
|
||||
fanin: dict[str, str] = {}
|
||||
if node is None:
|
||||
fanin["cpuif_rd_ack"] = "'0"
|
||||
fanin["cpuif_rd_err"] = "'0"
|
||||
fanin["cpuif_rd_data"] = "'0"
|
||||
if error:
|
||||
fanin["cpuif_rd_ack"] = "'1"
|
||||
fanin["cpuif_rd_err"] = "cpuif_rd_sel.cpuif_err"
|
||||
else:
|
||||
# Read side: ack comes from RVALID; err if RRESP[1] is set (SLVERR/DECERR)
|
||||
fanin["cpuif_rd_ack"] = self.signal("RVALID", node, "i")
|
||||
fanin["cpuif_rd_err"] = f"{self.signal('RRESP', node, 'i')}[1]"
|
||||
|
||||
return "\n".join(f"{lhs} = {rhs};" for lhs, rhs in 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("RDATA", node, "i")
|
||||
|
||||
return "\n".join(f"{lhs} = {rhs};" for lhs, rhs in fanin.items())
|
||||
|
||||
@@ -110,10 +110,10 @@ class BaseCpuif:
|
||||
def fanout(self, node: AddressableNode, array_stack: deque[int]) -> str:
|
||||
raise NotImplementedError
|
||||
|
||||
def fanin(self, node: AddressableNode | None = None) -> str:
|
||||
def fanin_wr(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
|
||||
raise NotImplementedError
|
||||
|
||||
def readback(self, node: AddressableNode | None = None) -> str:
|
||||
def fanin_rd(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
|
||||
raise NotImplementedError
|
||||
|
||||
def fanin_intermediate_assignments(
|
||||
|
||||
@@ -20,8 +20,8 @@ class FaninGenerator(BusDecoderListener):
|
||||
|
||||
self._stack: deque[Body] = deque()
|
||||
cb = CombinationalBody()
|
||||
cb += cpuif.fanin()
|
||||
cb += cpuif.readback()
|
||||
cb += cpuif.fanin_wr()
|
||||
cb += cpuif.fanin_rd()
|
||||
self._stack.append(cb)
|
||||
|
||||
def enter_AddressableComponent(self, node: AddressableNode) -> WalkerAction | None:
|
||||
@@ -48,15 +48,13 @@ class FaninGenerator(BusDecoderListener):
|
||||
self._stack.append(fb)
|
||||
|
||||
ifb = IfBody()
|
||||
with ifb.cm(
|
||||
f"cpuif_rd_sel.{get_indexed_path(self._cpuif.exp.ds.top_node, node)} || cpuif_wr_sel.{get_indexed_path(self._cpuif.exp.ds.top_node, node)}"
|
||||
) as b:
|
||||
b += self._cpuif.fanin(node)
|
||||
with ifb.cm(f"cpuif_wr_sel.{get_indexed_path(self._cpuif.exp.ds.top_node, node)}") as b:
|
||||
b += self._cpuif.fanin_wr(node)
|
||||
self._stack[-1] += ifb
|
||||
|
||||
ifb = IfBody()
|
||||
with ifb.cm(f"cpuif_rd_sel.{get_indexed_path(self._cpuif.exp.ds.top_node, node)}") as b:
|
||||
b += self._cpuif.readback(node)
|
||||
b += self._cpuif.fanin_rd(node)
|
||||
self._stack[-1] += ifb
|
||||
|
||||
return action
|
||||
@@ -72,4 +70,14 @@ class FaninGenerator(BusDecoderListener):
|
||||
super().exit_AddressableComponent(node)
|
||||
|
||||
def __str__(self) -> str:
|
||||
wr_ifb = IfBody()
|
||||
with wr_ifb.cm("cpuif_wr_sel.cpuif_err") as b:
|
||||
self._cpuif.fanin_wr(error=True)
|
||||
self._stack[-1] += wr_ifb
|
||||
|
||||
rd_ifb = IfBody()
|
||||
with rd_ifb.cm("cpuif_rd_sel.cpuif_err") as b:
|
||||
self._cpuif.fanin_rd(error=True)
|
||||
self._stack[-1] += rd_ifb
|
||||
|
||||
return "\n".join(map(str, self._stack))
|
||||
|
||||
5
uv.lock
generated
5
uv.lock
generated
@@ -311,6 +311,9 @@ dependencies = [
|
||||
{ name = "scapy" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/4e/f9/1474d5503af6f8c979a33e3489c0e6886b6ffb1af3d00419d2e0da1dd274/cocotb_bus-0.3.0.tar.gz", hash = "sha256:9762b29273ff062f52160e57274e3cb106d14e7e776515de1372c1d73546b005", size = 29991, upload-time = "2025-11-22T00:19:31.734Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ea/43/8b3f96cf401c2a7f6e907ccc86d3b73433eeaf5525df90b630d8c112474b/cocotb_bus-0.3.0-py3-none-any.whl", hash = "sha256:b4f06cce2462a8f9487b42c46b0ff3afd253f0fa4f67a0c382ebe0ba614229eb", size = 36206, upload-time = "2026-01-15T04:51:43.009Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colorama"
|
||||
@@ -655,7 +658,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "peakrdl-busdecoder"
|
||||
version = "0.6.5"
|
||||
version = "0.6.6"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "jinja2" },
|
||||
|
||||
Reference in New Issue
Block a user