Export master interface address widths in package parameters (#16)
* Initial plan * Add master address width parameters to exported package Co-authored-by: arnavsacheti <36746504+arnavsacheti@users.noreply.github.com> --------- 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:
@@ -17,6 +17,7 @@ from .identifier_filter import kw_filter as kwf
|
|||||||
from .listener import BusDecoderListener
|
from .listener import BusDecoderListener
|
||||||
from .struct_gen import StructGenerator
|
from .struct_gen import StructGenerator
|
||||||
from .sv_int import SVInt
|
from .sv_int import SVInt
|
||||||
|
from .utils import clog2
|
||||||
from .validate_design import DesignValidator
|
from .validate_design import DesignValidator
|
||||||
|
|
||||||
|
|
||||||
@@ -60,6 +61,7 @@ class BusDecoderExporter:
|
|||||||
)
|
)
|
||||||
self.jj_env.filters["kwf"] = kwf # type: ignore
|
self.jj_env.filters["kwf"] = kwf # type: ignore
|
||||||
self.jj_env.filters["walk"] = self.walk # type: ignore
|
self.jj_env.filters["walk"] = self.walk # type: ignore
|
||||||
|
self.jj_env.filters["clog2"] = clog2 # type: ignore
|
||||||
|
|
||||||
def export(self, node: RootNode | AddrmapNode, output_dir: str, **kwargs: Unpack[ExporterKwargs]) -> None:
|
def export(self, node: RootNode | AddrmapNode, output_dir: str, **kwargs: Unpack[ExporterKwargs]) -> None:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -14,5 +14,8 @@ package {{ds.package_name}};
|
|||||||
localparam {{ds.module_name.upper()}}_DATA_WIDTH = {{ds.cpuif_data_width}};
|
localparam {{ds.module_name.upper()}}_DATA_WIDTH = {{ds.cpuif_data_width}};
|
||||||
localparam {{ds.module_name.upper()}}_MIN_ADDR_WIDTH = {{ds.addr_width}};
|
localparam {{ds.module_name.upper()}}_MIN_ADDR_WIDTH = {{ds.addr_width}};
|
||||||
localparam {{ds.module_name.upper()}}_SIZE = {{SVInt(ds.top_node.size)}};
|
localparam {{ds.module_name.upper()}}_SIZE = {{SVInt(ds.top_node.size)}};
|
||||||
|
{%- for child in cpuif.addressable_children %}
|
||||||
|
localparam {{ds.module_name.upper()}}_{{child.inst_name.upper()}}_ADDR_WIDTH = {{child.size|clog2}};
|
||||||
|
{%- endfor %}
|
||||||
endpackage
|
endpackage
|
||||||
{# (eof newline anchor) #}
|
{# (eof newline anchor) #}
|
||||||
|
|||||||
@@ -193,3 +193,90 @@ class TestBusDecoderExporter:
|
|||||||
assert "reg1" in module_content
|
assert "reg1" in module_content
|
||||||
assert "reg2" in module_content
|
assert "reg2" in module_content
|
||||||
assert "reg3" in module_content
|
assert "reg3" in module_content
|
||||||
|
|
||||||
|
def test_master_address_widths_export(
|
||||||
|
self, compile_rdl: Callable[..., AddrmapNode], tmp_path: Path
|
||||||
|
) -> None:
|
||||||
|
"""Test exporting master address width parameters for child addrmaps."""
|
||||||
|
rdl_source = """
|
||||||
|
addrmap child1 {
|
||||||
|
reg {
|
||||||
|
field {
|
||||||
|
sw=rw;
|
||||||
|
hw=r;
|
||||||
|
} data[31:0];
|
||||||
|
} reg1 @ 0x0;
|
||||||
|
reg {
|
||||||
|
field {
|
||||||
|
sw=rw;
|
||||||
|
hw=r;
|
||||||
|
} data[31:0];
|
||||||
|
} reg2 @ 0x4;
|
||||||
|
};
|
||||||
|
|
||||||
|
addrmap child2 {
|
||||||
|
reg {
|
||||||
|
field {
|
||||||
|
sw=rw;
|
||||||
|
hw=r;
|
||||||
|
} data[15:0];
|
||||||
|
} reg2 @ 0x0;
|
||||||
|
};
|
||||||
|
|
||||||
|
addrmap parent {
|
||||||
|
external child1 c1 @ 0x0000;
|
||||||
|
external child2 c2 @ 0x1000;
|
||||||
|
};
|
||||||
|
"""
|
||||||
|
top = compile_rdl(rdl_source, top="parent")
|
||||||
|
|
||||||
|
exporter = BusDecoderExporter()
|
||||||
|
output_dir = str(tmp_path)
|
||||||
|
exporter.export(top, output_dir, cpuif_cls=APB4Cpuif)
|
||||||
|
|
||||||
|
package_file = tmp_path / "parent_pkg.sv"
|
||||||
|
assert package_file.exists()
|
||||||
|
|
||||||
|
package_content = package_file.read_text()
|
||||||
|
assert "package parent_pkg" in package_content
|
||||||
|
# Check for master address width parameters
|
||||||
|
assert "localparam PARENT_C1_ADDR_WIDTH = 3" in package_content
|
||||||
|
assert "localparam PARENT_C2_ADDR_WIDTH = 2" in package_content
|
||||||
|
|
||||||
|
def test_master_address_widths_with_arrays(
|
||||||
|
self, compile_rdl: Callable[..., AddrmapNode], tmp_path: Path
|
||||||
|
) -> None:
|
||||||
|
"""Test exporting master address width parameters for arrayed child addrmaps."""
|
||||||
|
rdl_source = """
|
||||||
|
addrmap child {
|
||||||
|
reg {
|
||||||
|
field {
|
||||||
|
sw=rw;
|
||||||
|
hw=r;
|
||||||
|
} data[31:0];
|
||||||
|
} reg1 @ 0x0;
|
||||||
|
reg {
|
||||||
|
field {
|
||||||
|
sw=rw;
|
||||||
|
hw=r;
|
||||||
|
} data[31:0];
|
||||||
|
} reg2 @ 0x4;
|
||||||
|
};
|
||||||
|
|
||||||
|
addrmap parent {
|
||||||
|
external child children[4] @ 0x0 += 0x100;
|
||||||
|
};
|
||||||
|
"""
|
||||||
|
top = compile_rdl(rdl_source, top="parent")
|
||||||
|
|
||||||
|
exporter = BusDecoderExporter()
|
||||||
|
output_dir = str(tmp_path)
|
||||||
|
exporter.export(top, output_dir, cpuif_cls=APB4Cpuif)
|
||||||
|
|
||||||
|
package_file = tmp_path / "parent_pkg.sv"
|
||||||
|
assert package_file.exists()
|
||||||
|
|
||||||
|
package_content = package_file.read_text()
|
||||||
|
assert "package parent_pkg" in package_content
|
||||||
|
# Check for master address width parameter - array should have a single parameter
|
||||||
|
assert "localparam PARENT_CHILDREN_ADDR_WIDTH = 3" in package_content
|
||||||
|
|||||||
Reference in New Issue
Block a user