peakrdl-busdecoder 0.2.0__py3-none-any.whl → 0.4.0__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.
- peakrdl_busdecoder/__peakrdl__.py +3 -1
- peakrdl_busdecoder/cpuif/apb3/apb3_cpuif.py +28 -3
- peakrdl_busdecoder/cpuif/apb3/apb3_tmpl.sv +7 -0
- peakrdl_busdecoder/cpuif/apb4/apb4_cpuif.py +28 -3
- peakrdl_busdecoder/cpuif/apb4/apb4_tmpl.sv +7 -0
- peakrdl_busdecoder/cpuif/axi4lite/axi4_lite_cpuif.py +31 -6
- peakrdl_busdecoder/cpuif/axi4lite/axi4_lite_cpuif_flat.py +2 -2
- peakrdl_busdecoder/cpuif/axi4lite/{axi4lite_tmpl.sv → axi4_lite_tmpl.sv} +7 -0
- peakrdl_busdecoder/cpuif/base_cpuif.py +24 -5
- peakrdl_busdecoder/cpuif/fanin_gen.py +11 -0
- peakrdl_busdecoder/cpuif/fanin_intermediate_gen.py +142 -0
- peakrdl_busdecoder/cpuif/fanout_gen.py +11 -0
- peakrdl_busdecoder/decode_logic_gen.py +16 -0
- peakrdl_busdecoder/design_state.py +54 -1
- peakrdl_busdecoder/exporter.py +3 -1
- peakrdl_busdecoder/listener.py +6 -1
- peakrdl_busdecoder/module_tmpl.sv +2 -2
- peakrdl_busdecoder/struct_gen.py +25 -14
- {peakrdl_busdecoder-0.2.0.dist-info → peakrdl_busdecoder-0.4.0.dist-info}/METADATA +1 -1
- {peakrdl_busdecoder-0.2.0.dist-info → peakrdl_busdecoder-0.4.0.dist-info}/RECORD +25 -24
- /peakrdl_busdecoder/cpuif/axi4lite/{axi4lite_interface.py → axi4_lite_interface.py} +0 -0
- {peakrdl_busdecoder-0.2.0.dist-info → peakrdl_busdecoder-0.4.0.dist-info}/WHEEL +0 -0
- {peakrdl_busdecoder-0.2.0.dist-info → peakrdl_busdecoder-0.4.0.dist-info}/entry_points.txt +0 -0
- {peakrdl_busdecoder-0.2.0.dist-info → peakrdl_busdecoder-0.4.0.dist-info}/licenses/LICENSE +0 -0
- {peakrdl_busdecoder-0.2.0.dist-info → peakrdl_busdecoder-0.4.0.dist-info}/top_level.txt +0 -0
|
@@ -116,7 +116,9 @@ class Exporter(ExporterSubcommandPlugin):
|
|
|
116
116
|
type=int,
|
|
117
117
|
default=1,
|
|
118
118
|
help="""Maximum depth for address decoder to descend into nested
|
|
119
|
-
addressable components.
|
|
119
|
+
addressable components. Value of 0 decodes all levels (infinite depth).
|
|
120
|
+
Value of 1 decodes only top-level children. Value of 2 decodes top-level
|
|
121
|
+
and one level deeper, etc. Default is 1.
|
|
120
122
|
""",
|
|
121
123
|
)
|
|
122
124
|
|
|
@@ -52,8 +52,16 @@ class APB3Cpuif(BaseCpuif):
|
|
|
52
52
|
fanin["cpuif_rd_ack"] = "'0"
|
|
53
53
|
fanin["cpuif_rd_err"] = "'0"
|
|
54
54
|
else:
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
# Use intermediate signals for interface arrays to avoid
|
|
56
|
+
# non-constant indexing of interface arrays in procedural blocks
|
|
57
|
+
if self.is_interface and node.is_array and node.array_dimensions:
|
|
58
|
+
# Generate array index string [i0][i1]... for the intermediate signal
|
|
59
|
+
array_idx = "".join(f"[i{i}]" for i in range(len(node.array_dimensions)))
|
|
60
|
+
fanin["cpuif_rd_ack"] = f"{node.inst_name}_fanin_ready{array_idx}"
|
|
61
|
+
fanin["cpuif_rd_err"] = f"{node.inst_name}_fanin_err{array_idx}"
|
|
62
|
+
else:
|
|
63
|
+
fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
|
|
64
|
+
fanin["cpuif_rd_err"] = self.signal("PSLVERR", node, "i")
|
|
57
65
|
|
|
58
66
|
return "\n".join(map(lambda kv: f"{kv[0]} = {kv[1]};", fanin.items()))
|
|
59
67
|
|
|
@@ -62,6 +70,23 @@ class APB3Cpuif(BaseCpuif):
|
|
|
62
70
|
if node is None:
|
|
63
71
|
fanin["cpuif_rd_data"] = "'0"
|
|
64
72
|
else:
|
|
65
|
-
|
|
73
|
+
# Use intermediate signals for interface arrays to avoid
|
|
74
|
+
# non-constant indexing of interface arrays in procedural blocks
|
|
75
|
+
if self.is_interface and node.is_array and node.array_dimensions:
|
|
76
|
+
# Generate array index string [i0][i1]... for the intermediate signal
|
|
77
|
+
array_idx = "".join(f"[i{i}]" for i in range(len(node.array_dimensions)))
|
|
78
|
+
fanin["cpuif_rd_data"] = f"{node.inst_name}_fanin_data{array_idx}"
|
|
79
|
+
else:
|
|
80
|
+
fanin["cpuif_rd_data"] = self.signal("PRDATA", node, "i")
|
|
66
81
|
|
|
67
82
|
return "\n".join(map(lambda kv: f"{kv[0]} = {kv[1]};", fanin.items()))
|
|
83
|
+
|
|
84
|
+
def fanin_intermediate_assignments(
|
|
85
|
+
self, node: AddressableNode, inst_name: str, array_idx: str, master_prefix: str, indexed_path: str
|
|
86
|
+
) -> list[str]:
|
|
87
|
+
"""Generate intermediate signal assignments for APB3 interface arrays."""
|
|
88
|
+
return [
|
|
89
|
+
f"assign {inst_name}_fanin_ready{array_idx} = {master_prefix}{indexed_path}.PREADY;",
|
|
90
|
+
f"assign {inst_name}_fanin_err{array_idx} = {master_prefix}{indexed_path}.PSLVERR;",
|
|
91
|
+
f"assign {inst_name}_fanin_data{array_idx} = {master_prefix}{indexed_path}.PRDATA;",
|
|
92
|
+
]
|
|
@@ -26,6 +26,13 @@ assign {{cpuif.signal("PSLVERR")}} = cpuif_rd_err | cpuif_rd_sel.cpuif_err | cpu
|
|
|
26
26
|
// Fanout CPU Bus interface signals
|
|
27
27
|
//--------------------------------------------------------------------------
|
|
28
28
|
{{fanout|walk(cpuif=cpuif)}}
|
|
29
|
+
{%- if cpuif.is_interface %}
|
|
30
|
+
|
|
31
|
+
//--------------------------------------------------------------------------
|
|
32
|
+
// Intermediate signals for interface array fanin
|
|
33
|
+
//--------------------------------------------------------------------------
|
|
34
|
+
{{fanin_intermediate|walk(cpuif=cpuif)}}
|
|
35
|
+
{%- endif %}
|
|
29
36
|
|
|
30
37
|
//--------------------------------------------------------------------------
|
|
31
38
|
// Fanin CPU Bus interface signals
|
|
@@ -55,8 +55,16 @@ class APB4Cpuif(BaseCpuif):
|
|
|
55
55
|
fanin["cpuif_rd_ack"] = "'0"
|
|
56
56
|
fanin["cpuif_rd_err"] = "'0"
|
|
57
57
|
else:
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
# Use intermediate signals for interface arrays to avoid
|
|
59
|
+
# non-constant indexing of interface arrays in procedural blocks
|
|
60
|
+
if self.is_interface and node.is_array and node.array_dimensions:
|
|
61
|
+
# Generate array index string [i0][i1]... for the intermediate signal
|
|
62
|
+
array_idx = "".join(f"[i{i}]" for i in range(len(node.array_dimensions)))
|
|
63
|
+
fanin["cpuif_rd_ack"] = f"{node.inst_name}_fanin_ready{array_idx}"
|
|
64
|
+
fanin["cpuif_rd_err"] = f"{node.inst_name}_fanin_err{array_idx}"
|
|
65
|
+
else:
|
|
66
|
+
fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
|
|
67
|
+
fanin["cpuif_rd_err"] = self.signal("PSLVERR", node, "i")
|
|
60
68
|
|
|
61
69
|
return "\n".join(map(lambda kv: f"{kv[0]} = {kv[1]};", fanin.items()))
|
|
62
70
|
|
|
@@ -65,6 +73,23 @@ class APB4Cpuif(BaseCpuif):
|
|
|
65
73
|
if node is None:
|
|
66
74
|
fanin["cpuif_rd_data"] = "'0"
|
|
67
75
|
else:
|
|
68
|
-
|
|
76
|
+
# Use intermediate signals for interface arrays to avoid
|
|
77
|
+
# non-constant indexing of interface arrays in procedural blocks
|
|
78
|
+
if self.is_interface and node.is_array and node.array_dimensions:
|
|
79
|
+
# Generate array index string [i0][i1]... for the intermediate signal
|
|
80
|
+
array_idx = "".join(f"[i{i}]" for i in range(len(node.array_dimensions)))
|
|
81
|
+
fanin["cpuif_rd_data"] = f"{node.inst_name}_fanin_data{array_idx}"
|
|
82
|
+
else:
|
|
83
|
+
fanin["cpuif_rd_data"] = self.signal("PRDATA", node, "i")
|
|
69
84
|
|
|
70
85
|
return "\n".join(map(lambda kv: f"{kv[0]} = {kv[1]};", fanin.items()))
|
|
86
|
+
|
|
87
|
+
def fanin_intermediate_assignments(
|
|
88
|
+
self, node: AddressableNode, inst_name: str, array_idx: str, master_prefix: str, indexed_path: str
|
|
89
|
+
) -> list[str]:
|
|
90
|
+
"""Generate intermediate signal assignments for APB4 interface arrays."""
|
|
91
|
+
return [
|
|
92
|
+
f"assign {inst_name}_fanin_ready{array_idx} = {master_prefix}{indexed_path}.PREADY;",
|
|
93
|
+
f"assign {inst_name}_fanin_err{array_idx} = {master_prefix}{indexed_path}.PSLVERR;",
|
|
94
|
+
f"assign {inst_name}_fanin_data{array_idx} = {master_prefix}{indexed_path}.PRDATA;",
|
|
95
|
+
]
|
|
@@ -29,6 +29,13 @@ assign {{cpuif.signal("PSLVERR")}} = cpuif_rd_err | cpuif_rd_sel.cpuif_err | cpu
|
|
|
29
29
|
// Fanout CPU Bus interface signals
|
|
30
30
|
//--------------------------------------------------------------------------
|
|
31
31
|
{{fanout|walk(cpuif=cpuif)}}
|
|
32
|
+
{%- if cpuif.is_interface %}
|
|
33
|
+
|
|
34
|
+
//--------------------------------------------------------------------------
|
|
35
|
+
// Intermediate signals for interface array fanin
|
|
36
|
+
//--------------------------------------------------------------------------
|
|
37
|
+
{{fanin_intermediate|walk(cpuif=cpuif)}}
|
|
38
|
+
{%- endif %}
|
|
32
39
|
|
|
33
40
|
//--------------------------------------------------------------------------
|
|
34
41
|
// Fanin CPU Bus interface signals
|
|
@@ -4,14 +4,14 @@ from systemrdl.node import AddressableNode
|
|
|
4
4
|
|
|
5
5
|
from ...utils import get_indexed_path
|
|
6
6
|
from ..base_cpuif import BaseCpuif
|
|
7
|
-
from .
|
|
7
|
+
from .axi4_lite_interface import AXI4LiteSVInterface
|
|
8
8
|
|
|
9
9
|
if TYPE_CHECKING:
|
|
10
10
|
from ...exporter import BusDecoderExporter
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class AXI4LiteCpuif(BaseCpuif):
|
|
14
|
-
template_path = "
|
|
14
|
+
template_path = "axi4_lite_tmpl.sv"
|
|
15
15
|
|
|
16
16
|
def __init__(self, exp: "BusDecoderExporter") -> None:
|
|
17
17
|
super().__init__(exp)
|
|
@@ -68,9 +68,17 @@ class AXI4LiteCpuif(BaseCpuif):
|
|
|
68
68
|
fanin["cpuif_rd_ack"] = "'0"
|
|
69
69
|
fanin["cpuif_rd_err"] = "'0"
|
|
70
70
|
else:
|
|
71
|
-
#
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
# Use intermediate signals for interface arrays to avoid
|
|
72
|
+
# non-constant indexing of interface arrays in procedural blocks
|
|
73
|
+
if self.is_interface and node.is_array and node.array_dimensions:
|
|
74
|
+
# Generate array index string [i0][i1]... for the intermediate signal
|
|
75
|
+
array_idx = "".join(f"[i{i}]" for i in range(len(node.array_dimensions)))
|
|
76
|
+
fanin["cpuif_rd_ack"] = f"{node.inst_name}_fanin_ready{array_idx}"
|
|
77
|
+
fanin["cpuif_rd_err"] = f"{node.inst_name}_fanin_err{array_idx}"
|
|
78
|
+
else:
|
|
79
|
+
# Read side: ack comes from RVALID; err if RRESP[1] is set (SLVERR/DECERR)
|
|
80
|
+
fanin["cpuif_rd_ack"] = self.signal("RVALID", node, "i")
|
|
81
|
+
fanin["cpuif_rd_err"] = f"{self.signal('RRESP', node, 'i')}[1]"
|
|
74
82
|
|
|
75
83
|
return "\n".join(f"{lhs} = {rhs};" for lhs, rhs in fanin.items())
|
|
76
84
|
|
|
@@ -79,6 +87,23 @@ class AXI4LiteCpuif(BaseCpuif):
|
|
|
79
87
|
if node is None:
|
|
80
88
|
fanin["cpuif_rd_data"] = "'0"
|
|
81
89
|
else:
|
|
82
|
-
|
|
90
|
+
# Use intermediate signals for interface arrays to avoid
|
|
91
|
+
# non-constant indexing of interface arrays in procedural blocks
|
|
92
|
+
if self.is_interface and node.is_array and node.array_dimensions:
|
|
93
|
+
# Generate array index string [i0][i1]... for the intermediate signal
|
|
94
|
+
array_idx = "".join(f"[i{i}]" for i in range(len(node.array_dimensions)))
|
|
95
|
+
fanin["cpuif_rd_data"] = f"{node.inst_name}_fanin_data{array_idx}"
|
|
96
|
+
else:
|
|
97
|
+
fanin["cpuif_rd_data"] = self.signal("RDATA", node, "i")
|
|
83
98
|
|
|
84
99
|
return "\n".join(f"{lhs} = {rhs};" for lhs, rhs in fanin.items())
|
|
100
|
+
|
|
101
|
+
def fanin_intermediate_assignments(
|
|
102
|
+
self, node: AddressableNode, inst_name: str, array_idx: str, master_prefix: str, indexed_path: str
|
|
103
|
+
) -> list[str]:
|
|
104
|
+
"""Generate intermediate signal assignments for AXI4-Lite interface arrays."""
|
|
105
|
+
return [
|
|
106
|
+
f"assign {inst_name}_fanin_ready{array_idx} = {master_prefix}{indexed_path}.RVALID;",
|
|
107
|
+
f"assign {inst_name}_fanin_err{array_idx} = {master_prefix}{indexed_path}.RRESP[1];",
|
|
108
|
+
f"assign {inst_name}_fanin_data{array_idx} = {master_prefix}{indexed_path}.RDATA;",
|
|
109
|
+
]
|
|
@@ -4,7 +4,7 @@ from systemrdl.node import AddressableNode
|
|
|
4
4
|
|
|
5
5
|
from ...utils import get_indexed_path
|
|
6
6
|
from ..base_cpuif import BaseCpuif
|
|
7
|
-
from .
|
|
7
|
+
from .axi4_lite_interface import AXI4LiteFlatInterface
|
|
8
8
|
|
|
9
9
|
if TYPE_CHECKING:
|
|
10
10
|
from ...exporter import BusDecoderExporter
|
|
@@ -13,7 +13,7 @@ if TYPE_CHECKING:
|
|
|
13
13
|
class AXI4LiteCpuifFlat(BaseCpuif):
|
|
14
14
|
"""Verilator-friendly variant that flattens the AXI4-Lite interface ports."""
|
|
15
15
|
|
|
16
|
-
template_path = "
|
|
16
|
+
template_path = "axi4_lite_tmpl.sv"
|
|
17
17
|
|
|
18
18
|
def __init__(self, exp: "BusDecoderExporter") -> None:
|
|
19
19
|
super().__init__(exp)
|
|
@@ -53,6 +53,13 @@ assign {{cpuif.signal("BRESP")}} = (cpuif_wr_err | cpuif_wr_sel.cpuif_err | cpu
|
|
|
53
53
|
// Fanout CPU Bus interface signals
|
|
54
54
|
//--------------------------------------------------------------------------
|
|
55
55
|
{{fanout|walk(cpuif=cpuif)}}
|
|
56
|
+
{%- if cpuif.is_interface %}
|
|
57
|
+
|
|
58
|
+
//--------------------------------------------------------------------------
|
|
59
|
+
// Intermediate signals for interface array fanin
|
|
60
|
+
//--------------------------------------------------------------------------
|
|
61
|
+
{{fanin_intermediate|walk(cpuif=cpuif)}}
|
|
62
|
+
{%- endif %}
|
|
56
63
|
|
|
57
64
|
//--------------------------------------------------------------------------
|
|
58
65
|
// Fanin CPU Bus interface signals
|
|
@@ -7,6 +7,7 @@ from systemrdl.node import AddressableNode
|
|
|
7
7
|
|
|
8
8
|
from ..utils import clog2, get_indexed_path, is_pow2, roundup_pow2
|
|
9
9
|
from .fanin_gen import FaninGenerator
|
|
10
|
+
from .fanin_intermediate_gen import FaninIntermediateGenerator
|
|
10
11
|
from .fanout_gen import FanoutGenerator
|
|
11
12
|
|
|
12
13
|
if TYPE_CHECKING:
|
|
@@ -24,11 +25,7 @@ class BaseCpuif:
|
|
|
24
25
|
|
|
25
26
|
@property
|
|
26
27
|
def addressable_children(self) -> list[AddressableNode]:
|
|
27
|
-
return
|
|
28
|
-
child
|
|
29
|
-
for child in self.exp.ds.top_node.children(unroll=self.unroll)
|
|
30
|
-
if isinstance(child, AddressableNode)
|
|
31
|
-
]
|
|
28
|
+
return self.exp.ds.get_addressable_children_at_depth(unroll=self.unroll)
|
|
32
29
|
|
|
33
30
|
@property
|
|
34
31
|
def addr_width(self) -> int:
|
|
@@ -97,6 +94,7 @@ class BaseCpuif:
|
|
|
97
94
|
"ds": self.exp.ds,
|
|
98
95
|
"fanout": FanoutGenerator,
|
|
99
96
|
"fanin": FaninGenerator,
|
|
97
|
+
"fanin_intermediate": FaninIntermediateGenerator,
|
|
100
98
|
}
|
|
101
99
|
|
|
102
100
|
template = jj_env.get_template(self.template_path)
|
|
@@ -116,3 +114,24 @@ class BaseCpuif:
|
|
|
116
114
|
|
|
117
115
|
def readback(self, node: AddressableNode | None = None) -> str:
|
|
118
116
|
raise NotImplementedError
|
|
117
|
+
|
|
118
|
+
def fanin_intermediate_assignments(
|
|
119
|
+
self, node: AddressableNode, inst_name: str, array_idx: str, master_prefix: str, indexed_path: str
|
|
120
|
+
) -> list[str]:
|
|
121
|
+
"""Generate intermediate signal assignments for interface array fanin.
|
|
122
|
+
|
|
123
|
+
This method should be implemented by cpuif classes that use interfaces.
|
|
124
|
+
It returns a list of assignment strings that copy signals from interface
|
|
125
|
+
arrays to intermediate unpacked arrays using constant (genvar) indexing.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
node: The addressable node
|
|
129
|
+
inst_name: Instance name for the intermediate signals
|
|
130
|
+
array_idx: Array index string (e.g., "[gi0][gi1]")
|
|
131
|
+
master_prefix: Master interface prefix
|
|
132
|
+
indexed_path: Indexed path to the interface element
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
List of assignment strings
|
|
136
|
+
"""
|
|
137
|
+
return [] # Default: no intermediate assignments needed
|
|
@@ -27,6 +27,17 @@ class FaninGenerator(BusDecoderListener):
|
|
|
27
27
|
def enter_AddressableComponent(self, node: AddressableNode) -> WalkerAction | None:
|
|
28
28
|
action = super().enter_AddressableComponent(node)
|
|
29
29
|
|
|
30
|
+
should_generate = action == WalkerAction.SkipDescendants
|
|
31
|
+
if not should_generate and self._ds.max_decode_depth == 0:
|
|
32
|
+
for child in node.children():
|
|
33
|
+
if isinstance(child, AddressableNode):
|
|
34
|
+
break
|
|
35
|
+
else:
|
|
36
|
+
should_generate = True
|
|
37
|
+
|
|
38
|
+
if not should_generate:
|
|
39
|
+
return action
|
|
40
|
+
|
|
30
41
|
if node.array_dimensions:
|
|
31
42
|
for i, dim in enumerate(node.array_dimensions):
|
|
32
43
|
fb = ForLoopBody(
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"""Generator for intermediate signals needed for interface array fanin.
|
|
2
|
+
|
|
3
|
+
When using SystemVerilog interface arrays, we cannot use variable indices
|
|
4
|
+
in procedural blocks (like always_comb). This generator creates intermediate
|
|
5
|
+
signals that copy from interface arrays using generate loops, which can then
|
|
6
|
+
be safely accessed with variable indices in the fanin logic.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from collections import deque
|
|
10
|
+
from typing import TYPE_CHECKING
|
|
11
|
+
|
|
12
|
+
from systemrdl.node import AddressableNode
|
|
13
|
+
from systemrdl.walker import WalkerAction
|
|
14
|
+
|
|
15
|
+
from ..body import Body, ForLoopBody
|
|
16
|
+
from ..design_state import DesignState
|
|
17
|
+
from ..listener import BusDecoderListener
|
|
18
|
+
from ..utils import get_indexed_path
|
|
19
|
+
|
|
20
|
+
if TYPE_CHECKING:
|
|
21
|
+
from .base_cpuif import BaseCpuif
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class FaninIntermediateGenerator(BusDecoderListener):
|
|
25
|
+
"""Generates intermediate signals for interface array fanin."""
|
|
26
|
+
|
|
27
|
+
def __init__(self, ds: DesignState, cpuif: "BaseCpuif") -> None:
|
|
28
|
+
super().__init__(ds)
|
|
29
|
+
self._cpuif = cpuif
|
|
30
|
+
self._declarations: list[str] = []
|
|
31
|
+
self._stack: deque[Body] = deque()
|
|
32
|
+
self._stack.append(Body())
|
|
33
|
+
|
|
34
|
+
def enter_AddressableComponent(self, node: AddressableNode) -> WalkerAction | None:
|
|
35
|
+
action = super().enter_AddressableComponent(node)
|
|
36
|
+
|
|
37
|
+
# Only generate intermediates for interface arrays
|
|
38
|
+
# Check if cpuif has is_interface attribute (some implementations don't)
|
|
39
|
+
is_interface = getattr(self._cpuif, "is_interface", False)
|
|
40
|
+
if not is_interface or not node.array_dimensions:
|
|
41
|
+
return action
|
|
42
|
+
|
|
43
|
+
# Generate intermediate signal declarations
|
|
44
|
+
self._generate_intermediate_declarations(node)
|
|
45
|
+
|
|
46
|
+
# Generate assignment logic using generate loops
|
|
47
|
+
if node.array_dimensions:
|
|
48
|
+
for i, dim in enumerate(node.array_dimensions):
|
|
49
|
+
fb = ForLoopBody(
|
|
50
|
+
"genvar",
|
|
51
|
+
f"gi{i}",
|
|
52
|
+
dim,
|
|
53
|
+
)
|
|
54
|
+
self._stack.append(fb)
|
|
55
|
+
|
|
56
|
+
# Generate assignments from interface array to intermediates
|
|
57
|
+
self._stack[-1] += self._generate_intermediate_assignments(node)
|
|
58
|
+
|
|
59
|
+
return action
|
|
60
|
+
|
|
61
|
+
def exit_AddressableComponent(self, node: AddressableNode) -> None:
|
|
62
|
+
is_interface = getattr(self._cpuif, "is_interface", False)
|
|
63
|
+
if is_interface and node.array_dimensions:
|
|
64
|
+
for _ in node.array_dimensions:
|
|
65
|
+
b = self._stack.pop()
|
|
66
|
+
if not b:
|
|
67
|
+
continue
|
|
68
|
+
self._stack[-1] += b
|
|
69
|
+
|
|
70
|
+
super().exit_AddressableComponent(node)
|
|
71
|
+
|
|
72
|
+
def _generate_intermediate_declarations(self, node: AddressableNode) -> None:
|
|
73
|
+
"""Generate intermediate signal declarations for a node."""
|
|
74
|
+
inst_name = node.inst_name
|
|
75
|
+
|
|
76
|
+
# Array dimensions should be checked before calling this function
|
|
77
|
+
if not node.array_dimensions:
|
|
78
|
+
return
|
|
79
|
+
|
|
80
|
+
# Calculate total array size
|
|
81
|
+
array_size = 1
|
|
82
|
+
for dim in node.array_dimensions:
|
|
83
|
+
array_size *= dim
|
|
84
|
+
|
|
85
|
+
# Create array dimension string
|
|
86
|
+
array_str = "".join(f"[{dim}]" for dim in node.array_dimensions)
|
|
87
|
+
|
|
88
|
+
# Generate declarations for each fanin signal
|
|
89
|
+
# For APB3/4: PREADY, PSLVERR, PRDATA
|
|
90
|
+
# These are the signals read in fanin
|
|
91
|
+
self._declarations.append(f"logic {inst_name}_fanin_ready{array_str};")
|
|
92
|
+
self._declarations.append(f"logic {inst_name}_fanin_err{array_str};")
|
|
93
|
+
self._declarations.append(
|
|
94
|
+
f"logic [{self._cpuif.data_width - 1}:0] {inst_name}_fanin_data{array_str};"
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
def _generate_intermediate_assignments(self, node: AddressableNode) -> str:
|
|
98
|
+
"""Generate assignments from interface array to intermediate signals."""
|
|
99
|
+
inst_name = node.inst_name
|
|
100
|
+
indexed_path = get_indexed_path(node.parent, node, "gi", skip_kw_filter=True)
|
|
101
|
+
|
|
102
|
+
# Get master prefix - use getattr to avoid type errors
|
|
103
|
+
interface = getattr(self._cpuif, "_interface", None)
|
|
104
|
+
if interface is None:
|
|
105
|
+
return ""
|
|
106
|
+
master_prefix = interface.get_master_prefix()
|
|
107
|
+
|
|
108
|
+
# Array dimensions should be checked before calling this function
|
|
109
|
+
if not node.array_dimensions:
|
|
110
|
+
return ""
|
|
111
|
+
|
|
112
|
+
# Create indexed signal names for left-hand side
|
|
113
|
+
array_idx = "".join(f"[gi{i}]" for i in range(len(node.array_dimensions)))
|
|
114
|
+
|
|
115
|
+
# Delegate to cpuif to get the appropriate assignments for this interface type
|
|
116
|
+
assignments = self._cpuif.fanin_intermediate_assignments(
|
|
117
|
+
node, inst_name, array_idx, master_prefix, indexed_path
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
return "\n".join(assignments)
|
|
121
|
+
|
|
122
|
+
def get_declarations(self) -> str:
|
|
123
|
+
"""Get all intermediate signal declarations."""
|
|
124
|
+
if not self._declarations:
|
|
125
|
+
return ""
|
|
126
|
+
return "\n".join(self._declarations)
|
|
127
|
+
|
|
128
|
+
def __str__(self) -> str:
|
|
129
|
+
"""Get all intermediate signal declarations and assignments."""
|
|
130
|
+
if not self._declarations:
|
|
131
|
+
return ""
|
|
132
|
+
|
|
133
|
+
# Output declarations first
|
|
134
|
+
output = "\n".join(self._declarations)
|
|
135
|
+
output += "\n\n"
|
|
136
|
+
|
|
137
|
+
# Then output assignments
|
|
138
|
+
body_str = "\n".join(map(str, self._stack))
|
|
139
|
+
if body_str and body_str.strip():
|
|
140
|
+
output += body_str
|
|
141
|
+
|
|
142
|
+
return output
|
|
@@ -23,6 +23,17 @@ class FanoutGenerator(BusDecoderListener):
|
|
|
23
23
|
def enter_AddressableComponent(self, node: AddressableNode) -> WalkerAction | None:
|
|
24
24
|
action = super().enter_AddressableComponent(node)
|
|
25
25
|
|
|
26
|
+
should_generate = action == WalkerAction.SkipDescendants
|
|
27
|
+
if not should_generate and self._ds.max_decode_depth == 0:
|
|
28
|
+
for child in node.children():
|
|
29
|
+
if isinstance(child, AddressableNode):
|
|
30
|
+
break
|
|
31
|
+
else:
|
|
32
|
+
should_generate = True
|
|
33
|
+
|
|
34
|
+
if not should_generate:
|
|
35
|
+
return action
|
|
36
|
+
|
|
26
37
|
if node.array_dimensions:
|
|
27
38
|
for i, dim in enumerate(node.array_dimensions):
|
|
28
39
|
fb = ForLoopBody(
|
|
@@ -85,6 +85,20 @@ class DecodeLogicGenerator(BusDecoderListener):
|
|
|
85
85
|
def enter_AddressableComponent(self, node: AddressableNode) -> WalkerAction | None:
|
|
86
86
|
action = super().enter_AddressableComponent(node)
|
|
87
87
|
|
|
88
|
+
should_decode = action == WalkerAction.SkipDescendants
|
|
89
|
+
|
|
90
|
+
if not should_decode and self._ds.max_decode_depth == 0:
|
|
91
|
+
# When decoding all levels, treat leaf registers as decode boundary
|
|
92
|
+
for child in node.children():
|
|
93
|
+
if isinstance(child, AddressableNode):
|
|
94
|
+
break
|
|
95
|
+
else:
|
|
96
|
+
should_decode = True
|
|
97
|
+
|
|
98
|
+
# Only generate select logic if we're at the decode boundary
|
|
99
|
+
if not should_decode:
|
|
100
|
+
return action
|
|
101
|
+
|
|
88
102
|
conditions: list[str] = []
|
|
89
103
|
conditions.extend(self.cpuif_addr_predicate(node))
|
|
90
104
|
conditions.extend(self.cpuif_prot_predicate(node))
|
|
@@ -146,6 +160,8 @@ class DecodeLogicGenerator(BusDecoderListener):
|
|
|
146
160
|
def __str__(self) -> str:
|
|
147
161
|
body = self._decode_stack[-1]
|
|
148
162
|
if isinstance(body, IfBody):
|
|
163
|
+
if len(body) == 0:
|
|
164
|
+
return f"{self._flavor.cpuif_select}.cpuif_err = 1'b1;"
|
|
149
165
|
with body.cm(...) as b:
|
|
150
166
|
b += f"{self._flavor.cpuif_select}.cpuif_err = 1'b1;"
|
|
151
167
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from typing import TypedDict
|
|
2
2
|
|
|
3
|
-
from systemrdl.node import AddrmapNode
|
|
3
|
+
from systemrdl.node import AddressableNode, AddrmapNode
|
|
4
4
|
from systemrdl.rdltypes.user_enum import UserEnum
|
|
5
5
|
|
|
6
6
|
from .design_scanner import DesignScanner
|
|
@@ -72,3 +72,56 @@ class DesignState:
|
|
|
72
72
|
if user_addr_width < self.addr_width:
|
|
73
73
|
msg.fatal(f"User-specified address width shall be greater than or equal to {self.addr_width}.")
|
|
74
74
|
self.addr_width = user_addr_width
|
|
75
|
+
|
|
76
|
+
def get_addressable_children_at_depth(self, unroll: bool = False) -> list[AddressableNode]:
|
|
77
|
+
"""
|
|
78
|
+
Get addressable children at the decode boundary based on max_decode_depth.
|
|
79
|
+
|
|
80
|
+
max_decode_depth semantics:
|
|
81
|
+
- 0: decode all levels (return leaf registers)
|
|
82
|
+
- 1: decode only top level (return children at depth 1)
|
|
83
|
+
- 2: decode top + 1 level (return children at depth 2)
|
|
84
|
+
- N: decode down to depth N (return children at depth N)
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
unroll: Whether to unroll arrayed nodes
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
List of addressable nodes at the decode boundary
|
|
91
|
+
"""
|
|
92
|
+
from systemrdl.node import RegNode
|
|
93
|
+
|
|
94
|
+
def collect_nodes(node: AddressableNode, current_depth: int) -> list[AddressableNode]:
|
|
95
|
+
"""Recursively collect nodes at the decode boundary."""
|
|
96
|
+
result: list[AddressableNode] = []
|
|
97
|
+
|
|
98
|
+
# For depth 0, collect all leaf registers
|
|
99
|
+
if self.max_decode_depth == 0:
|
|
100
|
+
# If this is a register, it's a leaf
|
|
101
|
+
if isinstance(node, RegNode):
|
|
102
|
+
result.append(node)
|
|
103
|
+
else:
|
|
104
|
+
# Recurse into children
|
|
105
|
+
for child in node.children(unroll=unroll):
|
|
106
|
+
if isinstance(child, AddressableNode):
|
|
107
|
+
result.extend(collect_nodes(child, current_depth + 1))
|
|
108
|
+
else:
|
|
109
|
+
# For depth N, collect children at depth N
|
|
110
|
+
if current_depth == self.max_decode_depth:
|
|
111
|
+
# We're at the decode boundary - return this node
|
|
112
|
+
result.append(node)
|
|
113
|
+
elif current_depth < self.max_decode_depth:
|
|
114
|
+
# We haven't reached the boundary yet - recurse
|
|
115
|
+
for child in node.children(unroll=unroll):
|
|
116
|
+
if isinstance(child, AddressableNode):
|
|
117
|
+
result.extend(collect_nodes(child, current_depth + 1))
|
|
118
|
+
|
|
119
|
+
return result
|
|
120
|
+
|
|
121
|
+
# Start collecting from top node's children
|
|
122
|
+
nodes: list[AddressableNode] = []
|
|
123
|
+
for child in self.top_node.children(unroll=unroll):
|
|
124
|
+
if isinstance(child, AddressableNode):
|
|
125
|
+
nodes.extend(collect_nodes(child, 1))
|
|
126
|
+
|
|
127
|
+
return nodes
|
peakrdl_busdecoder/exporter.py
CHANGED
|
@@ -89,7 +89,9 @@ class BusDecoderExporter:
|
|
|
89
89
|
interface. By default, arrayed nodes are kept as arrays.
|
|
90
90
|
max_decode_depth: int
|
|
91
91
|
Maximum depth for address decoder to descend into nested addressable
|
|
92
|
-
components.
|
|
92
|
+
components. A value of 0 decodes all levels (infinite depth). A value
|
|
93
|
+
of 1 decodes only top-level children. A value of 2 decodes top-level
|
|
94
|
+
and one level deeper, etc. By default, the decoder descends 1 level deep.
|
|
93
95
|
"""
|
|
94
96
|
# If it is the root node, skip to top addrmap
|
|
95
97
|
if isinstance(node, RootNode):
|
peakrdl_busdecoder/listener.py
CHANGED
|
@@ -15,7 +15,12 @@ class BusDecoderListener(RDLListener):
|
|
|
15
15
|
def should_skip_node(self, node: AddressableNode) -> bool:
|
|
16
16
|
"""Check if this node should be skipped (not decoded)."""
|
|
17
17
|
# Check if current depth exceeds max depth
|
|
18
|
-
|
|
18
|
+
# max_decode_depth semantics:
|
|
19
|
+
# - 0 means decode all levels (infinite)
|
|
20
|
+
# - 1 means decode only top level (depth 0)
|
|
21
|
+
# - 2 means decode top + 1 level (depth 0 and 1)
|
|
22
|
+
# - N means decode down to depth N-1
|
|
23
|
+
if self._ds.max_decode_depth > 0 and self._depth >= self._ds.max_decode_depth:
|
|
19
24
|
return True
|
|
20
25
|
|
|
21
26
|
# Check if this node only contains external addressable children
|
|
@@ -51,7 +51,7 @@ module {{ds.module_name}}
|
|
|
51
51
|
//--------------------------------------------------------------------------
|
|
52
52
|
always_comb begin
|
|
53
53
|
// Default all write select signals to 0
|
|
54
|
-
cpuif_wr_sel = '0;
|
|
54
|
+
cpuif_wr_sel = '{default: '0};
|
|
55
55
|
|
|
56
56
|
if (cpuif_req && cpuif_wr_en) begin
|
|
57
57
|
// A write request is pending
|
|
@@ -66,7 +66,7 @@ module {{ds.module_name}}
|
|
|
66
66
|
//--------------------------------------------------------------------------
|
|
67
67
|
always_comb begin
|
|
68
68
|
// Default all read select signals to 0
|
|
69
|
-
cpuif_rd_sel = '0;
|
|
69
|
+
cpuif_rd_sel = '{default: '0};
|
|
70
70
|
|
|
71
71
|
if (cpuif_req && cpuif_rd_en) begin
|
|
72
72
|
// A read request is pending
|
peakrdl_busdecoder/struct_gen.py
CHANGED
|
@@ -3,7 +3,7 @@ from collections import deque
|
|
|
3
3
|
from systemrdl.node import AddressableNode
|
|
4
4
|
from systemrdl.walker import WalkerAction
|
|
5
5
|
|
|
6
|
-
from .body import
|
|
6
|
+
from .body import StructBody
|
|
7
7
|
from .design_state import DesignState
|
|
8
8
|
from .identifier_filter import kw_filter as kwf
|
|
9
9
|
from .listener import BusDecoderListener
|
|
@@ -16,42 +16,53 @@ class StructGenerator(BusDecoderListener):
|
|
|
16
16
|
) -> None:
|
|
17
17
|
super().__init__(ds)
|
|
18
18
|
|
|
19
|
-
self._stack:
|
|
20
|
-
self.
|
|
19
|
+
self._stack: list[StructBody] = [StructBody("cpuif_sel_t", True, False)]
|
|
20
|
+
self._struct_defs: list[StructBody] = []
|
|
21
|
+
self._created_struct_stack: deque[bool] = deque() # Track if we created a struct for each node
|
|
21
22
|
|
|
22
23
|
def enter_AddressableComponent(self, node: AddressableNode) -> WalkerAction | None:
|
|
23
24
|
action = super().enter_AddressableComponent(node)
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
if action == WalkerAction.SkipDescendants:
|
|
27
|
-
self._skip = True
|
|
26
|
+
skip = action == WalkerAction.SkipDescendants
|
|
28
27
|
|
|
29
|
-
if node
|
|
28
|
+
# Only create nested struct if we're not skipping and node has addressable children
|
|
29
|
+
has_addressable_children = any(isinstance(child, AddressableNode) for child in node.children())
|
|
30
|
+
if has_addressable_children and not skip:
|
|
30
31
|
# Push new body onto stack
|
|
31
|
-
body = StructBody(f"cpuif_sel_{node.inst_name}_t", True,
|
|
32
|
+
body = StructBody(f"cpuif_sel_{node.inst_name}_t", True, False)
|
|
32
33
|
self._stack.append(body)
|
|
34
|
+
self._created_struct_stack.append(True)
|
|
35
|
+
else:
|
|
36
|
+
self._created_struct_stack.append(False)
|
|
33
37
|
|
|
34
38
|
return action
|
|
35
39
|
|
|
36
40
|
def exit_AddressableComponent(self, node: AddressableNode) -> None:
|
|
37
41
|
type = "logic"
|
|
38
42
|
|
|
39
|
-
|
|
43
|
+
# Pop the created_struct flag
|
|
44
|
+
created_struct = self._created_struct_stack.pop()
|
|
45
|
+
|
|
46
|
+
# Only pop struct body if we created one
|
|
47
|
+
if created_struct:
|
|
40
48
|
body = self._stack.pop()
|
|
41
|
-
if body
|
|
42
|
-
self.
|
|
49
|
+
if body:
|
|
50
|
+
self._struct_defs.append(body)
|
|
43
51
|
type = body.name
|
|
44
52
|
|
|
45
53
|
name = kwf(node.inst_name)
|
|
46
54
|
|
|
47
55
|
if node.array_dimensions:
|
|
48
56
|
for dim in node.array_dimensions:
|
|
49
|
-
name = f"[{dim
|
|
57
|
+
name = f"{name}[{dim}]"
|
|
50
58
|
|
|
51
59
|
self._stack[-1] += f"{type} {name};"
|
|
52
60
|
|
|
53
61
|
super().exit_AddressableComponent(node)
|
|
54
62
|
|
|
55
63
|
def __str__(self) -> str:
|
|
56
|
-
self._stack[-1]
|
|
57
|
-
|
|
64
|
+
if "logic cpuif_err;" not in self._stack[-1].lines:
|
|
65
|
+
self._stack[-1] += "logic cpuif_err;"
|
|
66
|
+
bodies = [str(body) for body in self._struct_defs]
|
|
67
|
+
bodies.append(str(self._stack[-1]))
|
|
68
|
+
return "\n".join(bodies)
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
peakrdl_busdecoder/__init__.py,sha256=zKSEa8EqCrZUtGoHCuZ0uNQVQMV2isVn47CgsDj5K48,75
|
|
2
|
-
peakrdl_busdecoder/__peakrdl__.py,sha256=
|
|
3
|
-
peakrdl_busdecoder/decode_logic_gen.py,sha256=
|
|
2
|
+
peakrdl_busdecoder/__peakrdl__.py,sha256=76kLBbSWVlKkCI5ESiID1aWVcQHr4sK32ujP5kna8xU,4601
|
|
3
|
+
peakrdl_busdecoder/decode_logic_gen.py,sha256=MdZbOiW2YNudhD-Msl_5wgGhd3mMaBNhTpUl-bilgHs,5873
|
|
4
4
|
peakrdl_busdecoder/design_scanner.py,sha256=syD6IXAJWYdpq2PQPvUGflPjhR_pO35R46Ld5K5XZHQ,1562
|
|
5
|
-
peakrdl_busdecoder/design_state.py,sha256=
|
|
6
|
-
peakrdl_busdecoder/exporter.py,sha256=
|
|
5
|
+
peakrdl_busdecoder/design_state.py,sha256=_zqgn2dQH2ozK63NwqRvPV7Bty7G-BAESu3yux2cJmI,4926
|
|
6
|
+
peakrdl_busdecoder/exporter.py,sha256=ZkGBeK-c733a3Xyc2ZeiGbWgBnDDW_s9nc64QiEf6no,5356
|
|
7
7
|
peakrdl_busdecoder/identifier_filter.py,sha256=poSIS1BMscORxOuDX_nXqvdNzClhKASdAVv9aDM_aqA,3972
|
|
8
|
-
peakrdl_busdecoder/listener.py,sha256=
|
|
9
|
-
peakrdl_busdecoder/module_tmpl.sv,sha256=
|
|
8
|
+
peakrdl_busdecoder/listener.py,sha256=WZ2fma6oSpGGZwuP7Zcv1futWBalaeZeVZD7DX1KQz4,2509
|
|
9
|
+
peakrdl_busdecoder/module_tmpl.sv,sha256=Sjo05-g_oP48x0jCdEyOvpBjwYV3wiACESgaC7viN00,2877
|
|
10
10
|
peakrdl_busdecoder/package_tmpl.sv,sha256=E0_jYmXx1nEMb78WApbCvMWYlrAuNfSWB7Jw23UkBYU,852
|
|
11
11
|
peakrdl_busdecoder/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
|
-
peakrdl_busdecoder/struct_gen.py,sha256=
|
|
12
|
+
peakrdl_busdecoder/struct_gen.py,sha256=UGNdGg-S6u2JRoDExP6Mt5h3bu01fP-gQ15FcwD9gNw,2334
|
|
13
13
|
peakrdl_busdecoder/sv_int.py,sha256=W0utmnR4XCuj3FVb9OGmRZ7SwlgEyO-XghMfd1I3iGA,872
|
|
14
14
|
peakrdl_busdecoder/utils.py,sha256=Kdcee6bhubI5XVX20JQ3wo0qYJTknqrv4l8kxhSd7wI,2219
|
|
15
15
|
peakrdl_busdecoder/validate_design.py,sha256=91yuWEzj0aAZ0eqzF1TF4N17yqG-D5oK5yYxDINlPms,8857
|
|
@@ -20,29 +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=
|
|
24
|
-
peakrdl_busdecoder/cpuif/fanin_gen.py,sha256=
|
|
25
|
-
peakrdl_busdecoder/cpuif/
|
|
23
|
+
peakrdl_busdecoder/cpuif/base_cpuif.py,sha256=tSqBeV_eG5zvBaLltLY8qmJBhwuCym3rs_q4mIJT6HI,5058
|
|
24
|
+
peakrdl_busdecoder/cpuif/fanin_gen.py,sha256=ioCxjj3V3X8rHssqwuI4p_U-LKpBalATW_Qshtt8j9U,2425
|
|
25
|
+
peakrdl_busdecoder/cpuif/fanin_intermediate_gen.py,sha256=hfvMyyx5ajEzvop3dzV37dT6Jn9yjORFnUkMAT1034A,5271
|
|
26
|
+
peakrdl_busdecoder/cpuif/fanout_gen.py,sha256=0-6eMzYbf25csHaRUJCsiyFz7lxS2Mdu0bXNm6e6cFI,1850
|
|
26
27
|
peakrdl_busdecoder/cpuif/interface.py,sha256=tFObXG18ashLrXSWn5O1ZwA-VNg9CL6w9XWi3qKd1sY,6148
|
|
27
28
|
peakrdl_busdecoder/cpuif/apb3/__init__.py,sha256=Uq82IJHzlITUvjTuETvPpSzvLEYoairzzPKfPz7kuC4,119
|
|
28
|
-
peakrdl_busdecoder/cpuif/apb3/apb3_cpuif.py,sha256=
|
|
29
|
+
peakrdl_busdecoder/cpuif/apb3/apb3_cpuif.py,sha256=iQDpHpv9HQQiBm9zHlUuSCaUysraFvHA25kt2XlpKmM,4248
|
|
29
30
|
peakrdl_busdecoder/cpuif/apb3/apb3_cpuif_flat.py,sha256=5_li9azFbFc0q9CLpqQNPvbcALsNlOBwV9ROHZuZ81c,2374
|
|
30
31
|
peakrdl_busdecoder/cpuif/apb3/apb3_interface.py,sha256=hU0GUCZGYnvskmZU6NznMGgRJFliD360WgwhsQh9rqY,2147
|
|
31
|
-
peakrdl_busdecoder/cpuif/apb3/apb3_tmpl.sv,sha256=
|
|
32
|
+
peakrdl_busdecoder/cpuif/apb3/apb3_tmpl.sv,sha256=6et25KbiNkZBD1hxjSx0XZFUP9NnvVpixMSGtwJuwdA,1967
|
|
32
33
|
peakrdl_busdecoder/cpuif/apb4/__init__.py,sha256=k4JCbIrKGT8hiRvWJDcqc5xx7j9i_xYgpXU70sNaLsc,119
|
|
33
|
-
peakrdl_busdecoder/cpuif/apb4/apb4_cpuif.py,sha256=
|
|
34
|
+
peakrdl_busdecoder/cpuif/apb4/apb4_cpuif.py,sha256=SnQ1wERBkk1yc4ZiE4z__Sp2441ljFJ7b7mxGPKoiFQ,4457
|
|
34
35
|
peakrdl_busdecoder/cpuif/apb4/apb4_cpuif_flat.py,sha256=JcQ7TfW2bWA9g_uCpsmEUNQfRikx5ZImhf2VSFGIdmw,2504
|
|
35
36
|
peakrdl_busdecoder/cpuif/apb4/apb4_interface.py,sha256=Ln5jIBhCHbIYS5sxR5AjFVvcMYD_rw71VF6KqyyNUkg,2449
|
|
36
|
-
peakrdl_busdecoder/cpuif/apb4/apb4_tmpl.sv,sha256=
|
|
37
|
+
peakrdl_busdecoder/cpuif/apb4/apb4_tmpl.sv,sha256=jjzIbiNvsDeMQWOIo08TpeKbSP3NILQkP3gWdlcX9Ak,2310
|
|
37
38
|
peakrdl_busdecoder/cpuif/axi4lite/__init__.py,sha256=5XuWfPK2jDzr6egKUDJFr8l3k3lW-feLIh-lN7Mo8Ks,145
|
|
38
|
-
peakrdl_busdecoder/cpuif/axi4lite/axi4_lite_cpuif.py,sha256=
|
|
39
|
-
peakrdl_busdecoder/cpuif/axi4lite/axi4_lite_cpuif_flat.py,sha256=
|
|
40
|
-
peakrdl_busdecoder/cpuif/axi4lite/
|
|
41
|
-
peakrdl_busdecoder/cpuif/axi4lite/
|
|
39
|
+
peakrdl_busdecoder/cpuif/axi4lite/axi4_lite_cpuif.py,sha256=_DpGXEFs77AFQAAspsGZxIxQuhehjPPFgL_9hLfuQeQ,5001
|
|
40
|
+
peakrdl_busdecoder/cpuif/axi4lite/axi4_lite_cpuif_flat.py,sha256=M9f6-2XloH1UCwHctolO4Um8BfAYiivWVM5PmAfksjY,3420
|
|
41
|
+
peakrdl_busdecoder/cpuif/axi4lite/axi4_lite_interface.py,sha256=eBs3RLGGvvQen4C6MR9RUZIHuTQEidYHG4NGxlYY1Bc,3702
|
|
42
|
+
peakrdl_busdecoder/cpuif/axi4lite/axi4_lite_tmpl.sv,sha256=ketPrq715LSEs8Ar9ecXgnSe2AUAdQ70oNVmDbXc2Tc,3351
|
|
42
43
|
peakrdl_busdecoder/udps/__init__.py,sha256=gPc74OMVWTIr5vgtFArzbhEyi1OYjllR3ZFwHJ8APaY,106
|
|
43
|
-
peakrdl_busdecoder-0.
|
|
44
|
-
peakrdl_busdecoder-0.
|
|
45
|
-
peakrdl_busdecoder-0.
|
|
46
|
-
peakrdl_busdecoder-0.
|
|
47
|
-
peakrdl_busdecoder-0.
|
|
48
|
-
peakrdl_busdecoder-0.
|
|
44
|
+
peakrdl_busdecoder-0.4.0.dist-info/licenses/LICENSE,sha256=eAMIGRcnsTDZVr4qelHkJ49Rd_IiDY4_MVHU7N0UWSw,7646
|
|
45
|
+
peakrdl_busdecoder-0.4.0.dist-info/METADATA,sha256=uGopMHm1NkeK7SFCfOHcvahKg3HcWiKY59S7ixTqBVE,2560
|
|
46
|
+
peakrdl_busdecoder-0.4.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
47
|
+
peakrdl_busdecoder-0.4.0.dist-info/entry_points.txt,sha256=7Xzgt-C2F4cQu1kRLpZa0MbXSFFMC1SWEDnZkY0GH7s,73
|
|
48
|
+
peakrdl_busdecoder-0.4.0.dist-info/top_level.txt,sha256=ZIYuTsl8cYby4g8tNR_JGzbYYTrG9mqYLSBqnY1Gpmk,19
|
|
49
|
+
peakrdl_busdecoder-0.4.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|