peakrdl-busdecoder 0.6.4__py3-none-any.whl → 0.6.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  import functools
2
4
  from typing import TYPE_CHECKING, Any
3
5
 
@@ -69,7 +71,7 @@ class Exporter(ExporterSubcommandPlugin):
69
71
  def get_cpuifs(self) -> dict[str, type[BaseCpuif]]:
70
72
  return get_cpuifs(map(tuple, self.cfg["cpuifs"].items()))
71
73
 
72
- def add_exporter_arguments(self, arg_group: "argparse.ArgumentParser") -> None: # type: ignore
74
+ def add_exporter_arguments(self, arg_group: argparse._ActionsContainer) -> None:
73
75
  cpuifs = self.get_cpuifs()
74
76
 
75
77
  arg_group.add_argument(
@@ -122,7 +124,7 @@ class Exporter(ExporterSubcommandPlugin):
122
124
  """,
123
125
  )
124
126
 
125
- def do_export(self, top_node: "AddrmapNode", options: "argparse.Namespace") -> None:
127
+ def do_export(self, top_node: AddrmapNode, options: argparse.Namespace) -> None:
126
128
  cpuifs = self.get_cpuifs()
127
129
 
128
130
  x = BusDecoderExporter()
@@ -45,42 +45,53 @@ class APB3Cpuif(BaseCpuif):
45
45
  fanout[self.signal("PADDR", node, "gi")] = self.signal("PADDR")
46
46
  fanout[self.signal("PWDATA", node, "gi")] = "cpuif_wr_data"
47
47
 
48
- return "\n".join(map(lambda kv: f"assign {kv[0]} = {kv[1]};", fanout.items()))
48
+ return "\n".join(f"assign {kv[0]} = {kv[1]};" for kv in fanout.items())
49
49
 
50
- def fanin(self, node: AddressableNode | None = None) -> str:
50
+ def fanin_wr(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
51
51
  fanin: dict[str, str] = {}
52
52
  if node is None:
53
- fanin["cpuif_rd_ack"] = "'0"
54
- fanin["cpuif_rd_err"] = "'0"
53
+ fanin["cpuif_wr_ack"] = "'0"
54
+ fanin["cpuif_wr_err"] = "'0"
55
+ if error:
56
+ fanin["cpuif_wr_ack"] = "'1"
57
+ fanin["cpuif_wr_err"] = "cpuif_wr_sel.cpuif_err"
55
58
  else:
56
59
  # Use intermediate signals for interface arrays to avoid
57
60
  # non-constant indexing of interface arrays in procedural blocks
58
61
  if self.is_interface and node.is_array and node.array_dimensions:
59
62
  # Generate array index string [i0][i1]... for the intermediate signal
60
63
  array_idx = "".join(f"[i{i}]" for i in range(len(node.array_dimensions)))
61
- fanin["cpuif_rd_ack"] = f"{node.inst_name}_fanin_ready{array_idx}"
62
- fanin["cpuif_rd_err"] = f"{node.inst_name}_fanin_err{array_idx}"
64
+ fanin["cpuif_wr_ack"] = f"{node.inst_name}_fanin_ready{array_idx}"
65
+ fanin["cpuif_wr_err"] = f"{node.inst_name}_fanin_err{array_idx}"
63
66
  else:
64
- fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
65
- fanin["cpuif_rd_err"] = self.signal("PSLVERR", node, "i")
66
-
67
- return "\n".join(map(lambda kv: f"{kv[0]} = {kv[1]};", fanin.items()))
67
+ fanin["cpuif_wr_ack"] = self.signal("PREADY", node, "i")
68
+ fanin["cpuif_wr_err"] = self.signal("PSLVERR", node, "i")
69
+ return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
68
70
 
69
- def readback(self, node: AddressableNode | None = None) -> str:
71
+ def fanin_rd(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
70
72
  fanin: dict[str, str] = {}
71
73
  if node is None:
74
+ fanin["cpuif_rd_ack"] = "'0"
75
+ fanin["cpuif_rd_err"] = "'0"
72
76
  fanin["cpuif_rd_data"] = "'0"
77
+ if error:
78
+ fanin["cpuif_rd_ack"] = "'1"
79
+ fanin["cpuif_rd_err"] = "cpuif_rd_sel.cpuif_err"
73
80
  else:
74
81
  # Use intermediate signals for interface arrays to avoid
75
82
  # non-constant indexing of interface arrays in procedural blocks
76
83
  if self.is_interface and node.is_array and node.array_dimensions:
77
84
  # Generate array index string [i0][i1]... for the intermediate signal
78
85
  array_idx = "".join(f"[i{i}]" for i in range(len(node.array_dimensions)))
86
+ fanin["cpuif_rd_ack"] = f"{node.inst_name}_fanin_ready{array_idx}"
87
+ fanin["cpuif_rd_err"] = f"{node.inst_name}_fanin_err{array_idx}"
79
88
  fanin["cpuif_rd_data"] = f"{node.inst_name}_fanin_data{array_idx}"
80
89
  else:
90
+ fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
91
+ fanin["cpuif_rd_err"] = self.signal("PSLVERR", node, "i")
81
92
  fanin["cpuif_rd_data"] = self.signal("PRDATA", node, "i")
82
93
 
83
- return "\n".join(map(lambda kv: f"{kv[0]} = {kv[1]};", fanin.items()))
94
+ return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
84
95
 
85
96
  def fanin_intermediate_assignments(
86
97
  self, node: AddressableNode, inst_name: str, array_idx: str, master_prefix: str, indexed_path: str
@@ -51,24 +51,34 @@ class APB3CpuifFlat(BaseCpuif):
51
51
  fanout[self.signal("PADDR", node, "gi")] = f"{{{'-'.join(addr_comp)}}}[{clog2(node.size) - 1}:0]"
52
52
  fanout[self.signal("PWDATA", node, "gi")] = "cpuif_wr_data"
53
53
 
54
- return "\n".join(map(lambda kv: f"assign {kv[0]} = {kv[1]};", fanout.items()))
54
+ return "\n".join(f"assign {kv[0]} = {kv[1]};" for kv in fanout.items())
55
55
 
56
- def fanin(self, node: AddressableNode | None = None) -> str:
56
+ def fanin_wr(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
57
57
  fanin: dict[str, str] = {}
58
58
  if node is None:
59
- fanin["cpuif_rd_ack"] = "'0"
60
- fanin["cpuif_rd_err"] = "'0"
59
+ fanin["cpuif_wr_ack"] = "'0"
60
+ fanin["cpuif_wr_err"] = "'0"
61
+ if error:
62
+ fanin["cpuif_wr_ack"] = "'1"
63
+ fanin["cpuif_wr_err"] = "cpuif_wr_sel.cpuif_err"
61
64
  else:
62
- fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
63
- fanin["cpuif_rd_err"] = self.signal("PSLVERR", node, "i")
65
+ fanin["cpuif_wr_ack"] = self.signal("PREADY", node, "i")
66
+ fanin["cpuif_wr_err"] = self.signal("PSLVERR", node, "i")
64
67
 
65
- return "\n".join(map(lambda kv: f"{kv[0]} = {kv[1]};", fanin.items()))
68
+ return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
66
69
 
67
- def readback(self, node: AddressableNode | None = None) -> str:
70
+ def fanin_rd(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
68
71
  fanin: dict[str, str] = {}
69
72
  if node is None:
73
+ fanin["cpuif_rd_ack"] = "'0"
74
+ fanin["cpuif_rd_err"] = "'0"
70
75
  fanin["cpuif_rd_data"] = "'0"
76
+ if error:
77
+ fanin["cpuif_rd_ack"] = "'1"
78
+ fanin["cpuif_rd_err"] = "cpuif_rd_sel.cpuif_err"
71
79
  else:
80
+ fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
81
+ fanin["cpuif_rd_err"] = self.signal("PSLVERR", node, "i")
72
82
  fanin["cpuif_rd_data"] = self.signal("PRDATA", node, "i")
73
83
 
74
- return "\n".join(map(lambda kv: f"{kv[0]} = {kv[1]};", fanin.items()))
84
+ return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
@@ -19,8 +19,8 @@ assign cpuif_rd_addr = {{cpuif.signal("PADDR")}};
19
19
  assign cpuif_wr_data = {{cpuif.signal("PWDATA")}};
20
20
 
21
21
  assign {{cpuif.signal("PRDATA")}} = cpuif_rd_data;
22
- assign {{cpuif.signal("PREADY")}} = cpuif_rd_ack;
23
- assign {{cpuif.signal("PSLVERR")}} = cpuif_rd_err | cpuif_rd_sel.cpuif_err | cpuif_wr_sel.cpuif_err;
22
+ assign {{cpuif.signal("PREADY")}} = cpuif_rd_ack | cpuif_wr_ack;
23
+ assign {{cpuif.signal("PSLVERR")}} = cpuif_rd_err | cpuif_wr_err;
24
24
 
25
25
  //--------------------------------------------------------------------------
26
26
  // Fanout CPU Bus interface signals
@@ -48,42 +48,54 @@ class APB4Cpuif(BaseCpuif):
48
48
  fanout[self.signal("PWDATA", node, "gi")] = "cpuif_wr_data"
49
49
  fanout[self.signal("PSTRB", node, "gi")] = "cpuif_wr_byte_en"
50
50
 
51
- return "\n".join(map(lambda kv: f"assign {kv[0]} = {kv[1]};", fanout.items()))
51
+ return "\n".join(f"assign {kv[0]} = {kv[1]};" for kv in fanout.items())
52
52
 
53
- def fanin(self, node: AddressableNode | None = None) -> str:
53
+ def fanin_wr(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
54
54
  fanin: dict[str, str] = {}
55
55
  if node is None:
56
- fanin["cpuif_rd_ack"] = "'0"
57
- fanin["cpuif_rd_err"] = "'0"
56
+ fanin["cpuif_wr_ack"] = "'0"
57
+ fanin["cpuif_wr_err"] = "'0"
58
+ if error:
59
+ fanin["cpuif_wr_ack"] = "'1"
60
+ fanin["cpuif_wr_err"] = "cpuif_wr_sel.cpuif_err"
58
61
  else:
59
62
  # Use intermediate signals for interface arrays to avoid
60
63
  # non-constant indexing of interface arrays in procedural blocks
61
64
  if self.is_interface and node.is_array and node.array_dimensions:
62
65
  # Generate array index string [i0][i1]... for the intermediate signal
63
66
  array_idx = "".join(f"[i{i}]" for i in range(len(node.array_dimensions)))
64
- fanin["cpuif_rd_ack"] = f"{node.inst_name}_fanin_ready{array_idx}"
65
- fanin["cpuif_rd_err"] = f"{node.inst_name}_fanin_err{array_idx}"
67
+ fanin["cpuif_wr_ack"] = f"{node.inst_name}_fanin_ready{array_idx}"
68
+ fanin["cpuif_wr_err"] = f"{node.inst_name}_fanin_err{array_idx}"
66
69
  else:
67
- fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
68
- fanin["cpuif_rd_err"] = self.signal("PSLVERR", node, "i")
70
+ fanin["cpuif_wr_ack"] = self.signal("PREADY", node, "i")
71
+ fanin["cpuif_wr_err"] = self.signal("PSLVERR", node, "i")
69
72
 
70
- return "\n".join(map(lambda kv: f"{kv[0]} = {kv[1]};", fanin.items()))
73
+ return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
71
74
 
72
- def readback(self, node: AddressableNode | None = None) -> str:
75
+ def fanin_rd(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
73
76
  fanin: dict[str, str] = {}
74
77
  if node is None:
78
+ fanin["cpuif_rd_ack"] = "'0"
79
+ fanin["cpuif_rd_err"] = "'0"
75
80
  fanin["cpuif_rd_data"] = "'0"
81
+ if error:
82
+ fanin["cpuif_rd_ack"] = "'1"
83
+ fanin["cpuif_rd_err"] = "cpuif_rd_sel.cpuif_err"
76
84
  else:
77
85
  # Use intermediate signals for interface arrays to avoid
78
86
  # non-constant indexing of interface arrays in procedural blocks
79
87
  if self.is_interface and node.is_array and node.array_dimensions:
80
88
  # Generate array index string [i0][i1]... for the intermediate signal
81
89
  array_idx = "".join(f"[i{i}]" for i in range(len(node.array_dimensions)))
90
+ fanin["cpuif_rd_ack"] = f"{node.inst_name}_fanin_ready{array_idx}"
91
+ fanin["cpuif_rd_err"] = f"{node.inst_name}_fanin_err{array_idx}"
82
92
  fanin["cpuif_rd_data"] = f"{node.inst_name}_fanin_data{array_idx}"
83
93
  else:
94
+ fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
95
+ fanin["cpuif_rd_err"] = self.signal("PSLVERR", node, "i")
84
96
  fanin["cpuif_rd_data"] = self.signal("PRDATA", node, "i")
85
97
 
86
- return "\n".join(map(lambda kv: f"{kv[0]} = {kv[1]};", fanin.items()))
98
+ return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
87
99
 
88
100
  def fanin_intermediate_assignments(
89
101
  self, node: AddressableNode, inst_name: str, array_idx: str, master_prefix: str, indexed_path: str
@@ -53,24 +53,33 @@ class APB4CpuifFlat(BaseCpuif):
53
53
  fanout[self.signal("PWDATA", node, "gi")] = "cpuif_wr_data"
54
54
  fanout[self.signal("PSTRB", node, "gi")] = "cpuif_wr_byte_en"
55
55
 
56
- return "\n".join(map(lambda kv: f"assign {kv[0]} = {kv[1]};", fanout.items()))
56
+ return "\n".join(f"assign {kv[0]} = {kv[1]};" for kv in fanout.items())
57
57
 
58
- def fanin(self, node: AddressableNode | None = None) -> str:
58
+ def fanin_wr(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
59
59
  fanin: dict[str, str] = {}
60
60
  if node is None:
61
- fanin["cpuif_rd_ack"] = "'0"
62
- fanin["cpuif_rd_err"] = "'0"
61
+ fanin["cpuif_wr_ack"] = "'0"
62
+ fanin["cpuif_wr_err"] = "'0"
63
+ if error:
64
+ fanin["cpuif_wr_ack"] = "'1"
65
+ fanin["cpuif_wr_err"] = "cpuif_wr_sel.cpuif_err"
63
66
  else:
64
- fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
65
- fanin["cpuif_rd_err"] = self.signal("PSLVERR", node, "i")
66
-
67
- return "\n".join(map(lambda kv: f"{kv[0]} = {kv[1]};", fanin.items()))
67
+ fanin["cpuif_wr_ack"] = self.signal("PREADY", node, "i")
68
+ fanin["cpuif_wr_err"] = self.signal("PSLVERR", node, "i")
69
+ return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
68
70
 
69
- def readback(self, node: AddressableNode | None = None) -> str:
71
+ def fanin_rd(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
70
72
  fanin: dict[str, str] = {}
71
73
  if node is None:
74
+ fanin["cpuif_rd_ack"] = "'0"
75
+ fanin["cpuif_rd_err"] = "'0"
72
76
  fanin["cpuif_rd_data"] = "'0"
77
+ if error:
78
+ fanin["cpuif_rd_ack"] = "'1"
79
+ fanin["cpuif_rd_err"] = "cpuif_rd_sel.cpuif_err"
73
80
  else:
81
+ fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
82
+ fanin["cpuif_rd_err"] = self.signal("PSLVERR", node, "i")
74
83
  fanin["cpuif_rd_data"] = self.signal("PRDATA", node, "i")
75
84
 
76
- return "\n".join(map(lambda kv: f"{kv[0]} = {kv[1]};", fanin.items()))
85
+ return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
@@ -20,8 +20,8 @@ assign cpuif_wr_data = {{cpuif.signal("PWDATA")}};
20
20
  assign cpuif_wr_byte_en = {{cpuif.signal("PSTRB")}};
21
21
 
22
22
  assign {{cpuif.signal("PRDATA")}} = cpuif_rd_data;
23
- assign {{cpuif.signal("PREADY")}} = cpuif_rd_ack;
24
- assign {{cpuif.signal("PSLVERR")}} = cpuif_rd_err | cpuif_rd_sel.cpuif_err | cpuif_wr_sel.cpuif_err;
23
+ assign {{cpuif.signal("PREADY")}} = cpuif_rd_ack | cpuif_wr_ack;
24
+ assign {{cpuif.signal("PSLVERR")}} = cpuif_rd_err | cpuif_wr_err;
25
25
 
26
26
  //--------------------------------------------------------------------------
27
27
  // Fanout CPU Bus interface signals
@@ -63,38 +63,50 @@ class AXI4LiteCpuif(BaseCpuif):
63
63
 
64
64
  return "\n".join(f"assign {lhs} = {rhs};" for lhs, rhs in fanout.items())
65
65
 
66
- def fanin(self, node: AddressableNode | None = None) -> str:
66
+ def fanin_wr(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
67
67
  fanin: dict[str, str] = {}
68
68
  if node is None:
69
- fanin["cpuif_rd_ack"] = "'0"
70
- fanin["cpuif_rd_err"] = "'0"
69
+ fanin["cpuif_wr_ack"] = "'0"
70
+ fanin["cpuif_wr_err"] = "'0"
71
+ if error:
72
+ fanin["cpuif_wr_ack"] = "'1"
73
+ fanin["cpuif_wr_err"] = "cpuif_wr_sel.cpuif_err"
71
74
  else:
72
75
  # Use intermediate signals for interface arrays to avoid
73
76
  # non-constant indexing of interface arrays in procedural blocks
74
77
  if self.is_interface and node.is_array and node.array_dimensions:
75
78
  # Generate array index string [i0][i1]... for the intermediate signal
76
79
  array_idx = "".join(f"[i{i}]" for i in range(len(node.array_dimensions)))
77
- fanin["cpuif_rd_ack"] = f"{node.inst_name}_fanin_ready{array_idx}"
78
- fanin["cpuif_rd_err"] = f"{node.inst_name}_fanin_err{array_idx}"
80
+ fanin["cpuif_wr_ack"] = f"{node.inst_name}_fanin_ready{array_idx}"
81
+ fanin["cpuif_wr_err"] = f"{node.inst_name}_fanin_err{array_idx}"
79
82
  else:
80
83
  # Read side: ack comes from RVALID; err if RRESP[1] is set (SLVERR/DECERR)
81
- fanin["cpuif_rd_ack"] = self.signal("RVALID", node, "i")
82
- fanin["cpuif_rd_err"] = f"{self.signal('RRESP', node, 'i')}[1]"
84
+ fanin["cpuif_wr_ack"] = self.signal("BVALID", node, "i")
85
+ fanin["cpuif_wr_err"] = f"{self.signal('BRESP', node, 'i')}[1]"
83
86
 
84
87
  return "\n".join(f"{lhs} = {rhs};" for lhs, rhs in fanin.items())
85
88
 
86
- def readback(self, node: AddressableNode | None = None) -> str:
89
+ def fanin_rd(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
87
90
  fanin: dict[str, str] = {}
88
91
  if node is None:
92
+ fanin["cpuif_rd_ack"] = "'0"
93
+ fanin["cpuif_rd_err"] = "'0"
89
94
  fanin["cpuif_rd_data"] = "'0"
95
+ if error:
96
+ fanin["cpuif_rd_ack"] = "'1"
97
+ fanin["cpuif_rd_err"] = "cpuif_rd_sel.cpuif_err"
90
98
  else:
91
99
  # Use intermediate signals for interface arrays to avoid
92
100
  # non-constant indexing of interface arrays in procedural blocks
93
101
  if self.is_interface and node.is_array and node.array_dimensions:
94
102
  # Generate array index string [i0][i1]... for the intermediate signal
95
103
  array_idx = "".join(f"[i{i}]" for i in range(len(node.array_dimensions)))
104
+ fanin["cpuif_rd_ack"] = f"{node.inst_name}_fanin_ready{array_idx}"
105
+ fanin["cpuif_rd_err"] = f"{node.inst_name}_fanin_err{array_idx}"
96
106
  fanin["cpuif_rd_data"] = f"{node.inst_name}_fanin_data{array_idx}"
97
107
  else:
108
+ fanin["cpuif_rd_ack"] = self.signal("RVALID", node, "i")
109
+ fanin["cpuif_rd_err"] = f"{self.signal('RRESP', node, 'i')}[1]"
98
110
  fanin["cpuif_rd_data"] = self.signal("RDATA", node, "i")
99
111
 
100
112
  return "\n".join(f"{lhs} = {rhs};" for lhs, rhs in fanin.items())
@@ -72,23 +72,33 @@ class AXI4LiteCpuifFlat(BaseCpuif):
72
72
 
73
73
  return "\n".join(f"assign {lhs} = {rhs};" for lhs, rhs in fanout.items())
74
74
 
75
- def fanin(self, node: AddressableNode | None = None) -> str:
75
+ def fanin_wr(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
76
76
  fanin: dict[str, str] = {}
77
77
  if node is None:
78
- fanin["cpuif_rd_ack"] = "'0"
79
- fanin["cpuif_rd_err"] = "'0"
78
+ fanin["cpuif_wr_ack"] = "'0"
79
+ fanin["cpuif_wr_err"] = "'0"
80
+ if error:
81
+ fanin["cpuif_wr_ack"] = "'1"
82
+ fanin["cpuif_wr_err"] = "cpuif_wr_sel.cpuif_err"
80
83
  else:
81
84
  # Read side: ack comes from RVALID; err if RRESP[1] is set (SLVERR/DECERR)
82
- fanin["cpuif_rd_ack"] = self.signal("RVALID", node, "i")
83
- fanin["cpuif_rd_err"] = f"{self.signal('RRESP', node, 'i')}[1]"
85
+ fanin["cpuif_wr_ack"] = self.signal("BVALID", node, "i")
86
+ fanin["cpuif_wr_err"] = f"{self.signal('BRESP', node, 'i')}[1]"
84
87
 
85
88
  return "\n".join(f"{lhs} = {rhs};" for lhs, rhs in fanin.items())
86
89
 
87
- def readback(self, node: AddressableNode | None = None) -> str:
90
+ def fanin_rd(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
88
91
  fanin: dict[str, str] = {}
89
92
  if node is None:
93
+ fanin["cpuif_rd_ack"] = "'0"
94
+ fanin["cpuif_rd_err"] = "'0"
90
95
  fanin["cpuif_rd_data"] = "'0"
96
+ if error:
97
+ fanin["cpuif_rd_ack"] = "'1"
98
+ fanin["cpuif_rd_err"] = "cpuif_rd_sel.cpuif_err"
91
99
  else:
100
+ fanin["cpuif_rd_ack"] = self.signal("RVALID", node, "i")
101
+ fanin["cpuif_rd_err"] = f"{self.signal('RRESP', node, 'i')}[1]"
92
102
  fanin["cpuif_rd_data"] = self.signal("RDATA", node, "i")
93
103
 
94
104
  return "\n".join(f"{lhs} = {rhs};" for lhs, rhs in fanin.items())
@@ -82,15 +82,15 @@ class BaseCpuif:
82
82
  loader=loader,
83
83
  undefined=jj.StrictUndefined,
84
84
  )
85
- jj_env.tests["array"] = self.check_is_array # type: ignore
86
- jj_env.filters["clog2"] = clog2 # type: ignore
87
- jj_env.filters["is_pow2"] = is_pow2 # type: ignore
88
- jj_env.filters["roundup_pow2"] = roundup_pow2 # type: ignore
89
- jj_env.filters["address_slice"] = self.get_address_slice # type: ignore
90
- jj_env.filters["get_path"] = lambda x: get_indexed_path(self.exp.ds.top_node, x, "i") # type: ignore
91
- jj_env.filters["walk"] = self.exp.walk # type: ignore
92
-
93
- context = { # type: ignore
85
+ jj_env.tests["array"] = self.check_is_array
86
+ jj_env.filters["clog2"] = clog2
87
+ jj_env.filters["is_pow2"] = is_pow2
88
+ jj_env.filters["roundup_pow2"] = roundup_pow2
89
+ jj_env.filters["address_slice"] = self.get_address_slice
90
+ jj_env.filters["get_path"] = lambda x: get_indexed_path(self.exp.ds.top_node, x, "i")
91
+ jj_env.filters["walk"] = self.exp.walk
92
+
93
+ context = {
94
94
  "cpuif": self,
95
95
  "ds": self.exp.ds,
96
96
  "fanout": FanoutGenerator,
@@ -110,10 +110,10 @@ class BaseCpuif:
110
110
  def fanout(self, node: AddressableNode, array_stack: deque[int]) -> str:
111
111
  raise NotImplementedError
112
112
 
113
- def fanin(self, node: AddressableNode | None = None) -> str:
113
+ def fanin_wr(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
114
114
  raise NotImplementedError
115
115
 
116
- def readback(self, node: AddressableNode | None = None) -> str:
116
+ def fanin_rd(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
117
117
  raise NotImplementedError
118
118
 
119
119
  def fanin_intermediate_assignments(
@@ -20,8 +20,8 @@ class FaninGenerator(BusDecoderListener):
20
20
 
21
21
  self._stack: deque[Body] = deque()
22
22
  cb = CombinationalBody()
23
- cb += cpuif.fanin()
24
- cb += cpuif.readback()
23
+ cb += cpuif.fanin_wr()
24
+ cb += cpuif.fanin_rd()
25
25
  self._stack.append(cb)
26
26
 
27
27
  def enter_AddressableComponent(self, node: AddressableNode) -> WalkerAction | None:
@@ -48,15 +48,13 @@ class FaninGenerator(BusDecoderListener):
48
48
  self._stack.append(fb)
49
49
 
50
50
  ifb = IfBody()
51
- with ifb.cm(
52
- 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)}"
53
- ) as b:
54
- b += self._cpuif.fanin(node)
51
+ with ifb.cm(f"cpuif_wr_sel.{get_indexed_path(self._cpuif.exp.ds.top_node, node)}") as b:
52
+ b += self._cpuif.fanin_wr(node)
55
53
  self._stack[-1] += ifb
56
54
 
57
55
  ifb = IfBody()
58
56
  with ifb.cm(f"cpuif_rd_sel.{get_indexed_path(self._cpuif.exp.ds.top_node, node)}") as b:
59
- b += self._cpuif.readback(node)
57
+ b += self._cpuif.fanin_rd(node)
60
58
  self._stack[-1] += ifb
61
59
 
62
60
  return action
@@ -72,4 +70,14 @@ class FaninGenerator(BusDecoderListener):
72
70
  super().exit_AddressableComponent(node)
73
71
 
74
72
  def __str__(self) -> str:
73
+ wr_ifb = IfBody()
74
+ with wr_ifb.cm("cpuif_wr_sel.cpuif_err") as b:
75
+ self._cpuif.fanin_wr(error=True)
76
+ self._stack[-1] += wr_ifb
77
+
78
+ rd_ifb = IfBody()
79
+ with rd_ifb.cm("cpuif_rd_sel.cpuif_err") as b:
80
+ self._cpuif.fanin_rd(error=True)
81
+ self._stack[-1] += rd_ifb
82
+
75
83
  return "\n".join(map(str, self._stack))
@@ -78,7 +78,7 @@ class SVInterface(Interface):
78
78
 
79
79
  # When unrolled, current_idx is set - append it to the name
80
80
  if child.current_idx is not None:
81
- base = f"{base}_{'_'.join(map(str, child.current_idx))}"
81
+ base = f"{base}_{'_'.join(map(str, child.current_idx))}" # ty: ignore
82
82
 
83
83
  # Only add array dimensions if this should be treated as an array
84
84
  if self.cpuif.check_is_array(child):
@@ -58,9 +58,9 @@ class BusDecoderExporter:
58
58
  loader=c_loader,
59
59
  undefined=jj.StrictUndefined,
60
60
  )
61
- self.jj_env.filters["kwf"] = kwf # type: ignore
62
- self.jj_env.filters["walk"] = self.walk # type: ignore
63
- self.jj_env.filters["clog2"] = clog2 # type: ignore
61
+ self.jj_env.filters["kwf"] = kwf
62
+ self.jj_env.filters["walk"] = self.walk
63
+ self.jj_env.filters["clog2"] = clog2
64
64
 
65
65
  def export(self, node: RootNode | AddrmapNode, output_dir: str, **kwargs: Unpack[ExporterKwargs]) -> None:
66
66
  """
@@ -98,7 +98,7 @@ class BusDecoderExporter:
98
98
  else:
99
99
  top_node = node
100
100
 
101
- self.ds = DesignState(top_node, kwargs)
101
+ self.ds = DesignState(top_node, kwargs) # ty: ignore
102
102
 
103
103
  cpuif_cls: type[BaseCpuif] = kwargs.pop("cpuif_cls", None) or APB4Cpuif
104
104
 
@@ -113,7 +113,7 @@ class BusDecoderExporter:
113
113
  DesignValidator(self).do_validate()
114
114
 
115
115
  # Build Jinja template context
116
- context = { # type: ignore
116
+ context = {
117
117
  "version": version("peakrdl-busdecoder"),
118
118
  "cpuif": self.cpuif,
119
119
  "cpuif_decode": DecodeLogicGenerator,
@@ -62,7 +62,6 @@ def ref_is_internal(top_node: AddrmapNode, ref: Node | PropertyReference) -> boo
62
62
  else:
63
63
  current_node = ref
64
64
 
65
- # pyrefly: ignore[bad-assignment] - false positive due to circular type checking
66
65
  while current_node is not None:
67
66
  if current_node == top_node:
68
67
  # reached top node without finding any external components
@@ -74,7 +74,9 @@ class DesignValidator(RDLListener):
74
74
  f"instance '{node.inst_name}' must be a multiple of {alignment}",
75
75
  node.inst.inst_src_ref,
76
76
  )
77
- if node.is_array and (node.array_stride % alignment) != 0: # type: ignore # is_array implies stride is not none
77
+ if node.is_array and (
78
+ node.array_stride is not None and (node.array_stride % alignment) != 0
79
+ ): # is_array implies stride is not none
78
80
  self.msg.error(
79
81
  "Unaligned registers are not supported. Address stride of "
80
82
  f"instance array '{node.inst_name}' must be a multiple of {alignment}",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: peakrdl-busdecoder
3
- Version: 0.6.4
3
+ Version: 0.6.6
4
4
  Summary: Generate a SystemVerilog bus decoder from SystemRDL for splitting CPU interfaces to multiple sub-address spaces
5
5
  Author: Arnav Sacheti
6
6
  License: LGPLv3
@@ -1,9 +1,9 @@
1
1
  peakrdl_busdecoder/__init__.py,sha256=zKSEa8EqCrZUtGoHCuZ0uNQVQMV2isVn47CgsDj5K48,75
2
- peakrdl_busdecoder/__peakrdl__.py,sha256=76kLBbSWVlKkCI5ESiID1aWVcQHr4sK32ujP5kna8xU,4601
2
+ peakrdl_busdecoder/__peakrdl__.py,sha256=TtP7daoKSy-x53x6b62xlZu6lQJ6Vp3-v_OqnpsGcig,4618
3
3
  peakrdl_busdecoder/decode_logic_gen.py,sha256=q4qSmufJI28eX75A532BOoNfIufljq3gHNLdqKbRqio,6060
4
4
  peakrdl_busdecoder/design_scanner.py,sha256=syD6IXAJWYdpq2PQPvUGflPjhR_pO35R46Ld5K5XZHQ,1562
5
5
  peakrdl_busdecoder/design_state.py,sha256=_zqgn2dQH2ozK63NwqRvPV7Bty7G-BAESu3yux2cJmI,4926
6
- peakrdl_busdecoder/exporter.py,sha256=Ozxu73-CCKDBkWYGACHOTX9qsqHhV7vup1wHq1HBKaY,5261
6
+ peakrdl_busdecoder/exporter.py,sha256=MbIcKK9ttXNhxJ2J8x8EvNO4QBzo60OnbqXH4KtjuPc,5211
7
7
  peakrdl_busdecoder/identifier_filter.py,sha256=poSIS1BMscORxOuDX_nXqvdNzClhKASdAVv9aDM_aqA,3972
8
8
  peakrdl_busdecoder/listener.py,sha256=WZ2fma6oSpGGZwuP7Zcv1futWBalaeZeVZD7DX1KQz4,2509
9
9
  peakrdl_busdecoder/module_tmpl.sv,sha256=g0g7Xij4ol2H_g8sw9o1_lZdMf78eVyt95AROzc__nU,2850
@@ -11,8 +11,8 @@ peakrdl_busdecoder/package_tmpl.sv,sha256=VWPkW7LpZTKuK7BMtpCqLxgyi9u5Fh6fwCRq7a
11
11
  peakrdl_busdecoder/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  peakrdl_busdecoder/struct_gen.py,sha256=UGNdGg-S6u2JRoDExP6Mt5h3bu01fP-gQ15FcwD9gNw,2334
13
13
  peakrdl_busdecoder/sv_int.py,sha256=D57h4sgqnQWQtPw80OeDZk_i2_t2aOTsihmASB4NkGo,1788
14
- peakrdl_busdecoder/utils.py,sha256=Kdcee6bhubI5XVX20JQ3wo0qYJTknqrv4l8kxhSd7wI,2219
15
- peakrdl_busdecoder/validate_design.py,sha256=74MM3MC1kII0s2HqfEBvhWvD2rummn429X7qmtPjsSI,7523
14
+ peakrdl_busdecoder/utils.py,sha256=MeLWATeumUKlfobuoI6yL3nx9Mk8BNZeKD9xq0e8I6U,2134
15
+ peakrdl_busdecoder/validate_design.py,sha256=DyGhOR61kd-Lrd34q9hQZWMk7_D0LrMWHoLbzk9tRAM,7566
16
16
  peakrdl_busdecoder/body/__init__.py,sha256=ZFTs8xIxeLyasyabLtGp7kClmmLlJpqdKJ854pmvTJg,311
17
17
  peakrdl_busdecoder/body/body.py,sha256=X4T3iCr94cgoz76tt2WtvhGGCweUFpUr9ogD6ol0LIg,466
18
18
  peakrdl_busdecoder/body/combinational_body.py,sha256=2FqbGHi405oEMAKlBfXz4hnLSn8Sr60kkFIUcL9oXf4,195
@@ -20,30 +20,30 @@ peakrdl_busdecoder/body/for_loop_body.py,sha256=lJYfDiB7MF9_mfbGEApoVHRViBCqpGRs
20
20
  peakrdl_busdecoder/body/if_body.py,sha256=S4oVS7yz04R1i-23W-aWpVcVZa5dW-H0FL_KnMy-Wsc,3261
21
21
  peakrdl_busdecoder/body/struct_body.py,sha256=74ItYoYD-GqEidxc-ncV5y8fzGoM47NI4GnnweclmS8,624
22
22
  peakrdl_busdecoder/cpuif/__init__.py,sha256=T8YrELGuOBIPgj1e86tNJ5tSCf7fXpPadqa71v5MEx8,59
23
- peakrdl_busdecoder/cpuif/base_cpuif.py,sha256=PBRPLAkg_QYVnHXsd0O7gQhRGqJzJQlZh_HGSk6vRGg,5113
24
- peakrdl_busdecoder/cpuif/fanin_gen.py,sha256=ioCxjj3V3X8rHssqwuI4p_U-LKpBalATW_Qshtt8j9U,2425
23
+ peakrdl_busdecoder/cpuif/base_cpuif.py,sha256=RknbZXMFsBcjR6FyPzF3mD4_lPQZxRDpt-5Vwbj5ef8,5036
24
+ peakrdl_busdecoder/cpuif/fanin_gen.py,sha256=QnbJ_rTCI1HqP7cIGDGbS0q8rBhDzM_7FWcYEMotjP8,2661
25
25
  peakrdl_busdecoder/cpuif/fanin_intermediate_gen.py,sha256=hfvMyyx5ajEzvop3dzV37dT6Jn9yjORFnUkMAT1034A,5271
26
26
  peakrdl_busdecoder/cpuif/fanout_gen.py,sha256=-kopGBHC07D9VreygfN0VubHGVVO51og4lAFq6B1oV8,1876
27
- peakrdl_busdecoder/cpuif/interface.py,sha256=4NYJHv2rr50YLm_eB9I89Y4XUckMD42ZtHskU0_Nm8o,6448
27
+ peakrdl_busdecoder/cpuif/interface.py,sha256=0xp_4K6DZMGOePbFgLEOIaVemjMS5pnQp7izKmzgu4s,6462
28
28
  peakrdl_busdecoder/cpuif/apb3/__init__.py,sha256=Uq82IJHzlITUvjTuETvPpSzvLEYoairzzPKfPz7kuC4,119
29
- peakrdl_busdecoder/cpuif/apb3/apb3_cpuif.py,sha256=Gst5RM2Qwpk-OxBjLE6mK2SAuN7xqV1nMi79AvD4q5Y,4303
30
- peakrdl_busdecoder/cpuif/apb3/apb3_cpuif_flat.py,sha256=Hv-JNx3LBbxOWYnud97XS26G3OvNCrbMis_T6zkYhmw,2718
29
+ peakrdl_busdecoder/cpuif/apb3/apb3_cpuif.py,sha256=1NVcgUY-fT5A9OhHDXkSqtdqCWz5ITdoNgZ4b9Qz0iU,4989
30
+ peakrdl_busdecoder/cpuif/apb3/apb3_cpuif_flat.py,sha256=VIdHu5bijNnNN7uCCfCFSE2kGp7f3Ouyv5_l1BFVUq8,3233
31
31
  peakrdl_busdecoder/cpuif/apb3/apb3_interface.py,sha256=PQwMtjETR9-c9S1BzjdWieCis2qoOfUyRQAWcD3ScyE,2170
32
- peakrdl_busdecoder/cpuif/apb3/apb3_tmpl.sv,sha256=6et25KbiNkZBD1hxjSx0XZFUP9NnvVpixMSGtwJuwdA,1967
32
+ peakrdl_busdecoder/cpuif/apb3/apb3_tmpl.sv,sha256=mxJ55myE0ZeOGW3TTBRmdlUdHq4Yv-6vyHA674S3e3g,1947
33
33
  peakrdl_busdecoder/cpuif/apb4/__init__.py,sha256=k4JCbIrKGT8hiRvWJDcqc5xx7j9i_xYgpXU70sNaLsc,119
34
- peakrdl_busdecoder/cpuif/apb4/apb4_cpuif.py,sha256=HarcUUxJcWLraijVaqHVWQOW_9TERD-fyfo3m_uzVhw,4512
35
- peakrdl_busdecoder/cpuif/apb4/apb4_cpuif_flat.py,sha256=4uNfunrRR8uu0WcgUZFilFlj-Og1eJDKBDT4aMps4wI,2860
34
+ peakrdl_busdecoder/cpuif/apb4/apb4_cpuif.py,sha256=JS8-wSmcSXfkyHGzmiyN-G-_5qdvdMwmYxpKn7uQgU4,5199
35
+ peakrdl_busdecoder/cpuif/apb4/apb4_cpuif_flat.py,sha256=yk80xCLoF9OQE51kkb1CmqVW_eirMoy_KyZ4tkurAh0,3374
36
36
  peakrdl_busdecoder/cpuif/apb4/apb4_interface.py,sha256=dnVWHi1NZScIR7sLYVfxbJDrU-Fm221O1XvHMdpSyi4,2472
37
- peakrdl_busdecoder/cpuif/apb4/apb4_tmpl.sv,sha256=woX7UBWvg_mtnrBKSel60p269d1sFgGelzgA5kISxew,2020
37
+ peakrdl_busdecoder/cpuif/apb4/apb4_tmpl.sv,sha256=C4ccTQvfpY-JmH9y4lWr8Qbw25OO3_suyjSa_c6XnSY,2001
38
38
  peakrdl_busdecoder/cpuif/axi4lite/__init__.py,sha256=5XuWfPK2jDzr6egKUDJFr8l3k3lW-feLIh-lN7Mo8Ks,145
39
- peakrdl_busdecoder/cpuif/axi4lite/axi4_lite_cpuif.py,sha256=bSHP_xYczv30-F62wZYe3rqma458qi6sqSzLAKApiGE,5056
40
- peakrdl_busdecoder/cpuif/axi4lite/axi4_lite_cpuif_flat.py,sha256=47yz1o6yoGFyoIswdka946n_kkwsApUhqYO_xNKekR4,3868
39
+ peakrdl_busdecoder/cpuif/axi4lite/axi4_lite_cpuif.py,sha256=61Cvj2ndSOns61E0DfTo356k46owuNPSrusqs0FBM70,5770
40
+ peakrdl_busdecoder/cpuif/axi4lite/axi4_lite_cpuif_flat.py,sha256=gzXmQX15e0OZcYaXDvXNqQhGLqSHM3qkGCs7qk_lNf8,4410
41
41
  peakrdl_busdecoder/cpuif/axi4lite/axi4_lite_interface.py,sha256=EXW-nPJwMF_oCPdJ4XmreiLwhnpqSca9iViosh2rEXM,3721
42
42
  peakrdl_busdecoder/cpuif/axi4lite/axi4_lite_tmpl.sv,sha256=ketPrq715LSEs8Ar9ecXgnSe2AUAdQ70oNVmDbXc2Tc,3351
43
43
  peakrdl_busdecoder/udps/__init__.py,sha256=gPc74OMVWTIr5vgtFArzbhEyi1OYjllR3ZFwHJ8APaY,106
44
- peakrdl_busdecoder-0.6.4.dist-info/licenses/LICENSE,sha256=eAMIGRcnsTDZVr4qelHkJ49Rd_IiDY4_MVHU7N0UWSw,7646
45
- peakrdl_busdecoder-0.6.4.dist-info/METADATA,sha256=O_6RiPtNmfNn-_Fs9vihEuVFEVkSd2AuPG2J6SiHya4,2797
46
- peakrdl_busdecoder-0.6.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
47
- peakrdl_busdecoder-0.6.4.dist-info/entry_points.txt,sha256=7Xzgt-C2F4cQu1kRLpZa0MbXSFFMC1SWEDnZkY0GH7s,73
48
- peakrdl_busdecoder-0.6.4.dist-info/top_level.txt,sha256=ZIYuTsl8cYby4g8tNR_JGzbYYTrG9mqYLSBqnY1Gpmk,19
49
- peakrdl_busdecoder-0.6.4.dist-info/RECORD,,
44
+ peakrdl_busdecoder-0.6.6.dist-info/licenses/LICENSE,sha256=eAMIGRcnsTDZVr4qelHkJ49Rd_IiDY4_MVHU7N0UWSw,7646
45
+ peakrdl_busdecoder-0.6.6.dist-info/METADATA,sha256=NBh_tp01j-ohVg_PgfGhDAqtHCGcA5yZl0yHgTPRZXM,2797
46
+ peakrdl_busdecoder-0.6.6.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
47
+ peakrdl_busdecoder-0.6.6.dist-info/entry_points.txt,sha256=7Xzgt-C2F4cQu1kRLpZa0MbXSFFMC1SWEDnZkY0GH7s,73
48
+ peakrdl_busdecoder-0.6.6.dist-info/top_level.txt,sha256=ZIYuTsl8cYby4g8tNR_JGzbYYTrG9mqYLSBqnY1Gpmk,19
49
+ peakrdl_busdecoder-0.6.6.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5