format + module update

This commit is contained in:
Arnav Sacheti
2025-10-13 22:06:51 -07:00
parent 54a199ca9c
commit 066d9ca99e
12 changed files with 109 additions and 139 deletions

View File

@@ -1,16 +1,17 @@
from typing import TYPE_CHECKING
import functools
from typing import TYPE_CHECKING
from peakrdl.plugins.exporter import ExporterSubcommandPlugin
from peakrdl.config import schema
from peakrdl.plugins.entry_points import get_entry_points
from peakrdl.plugins.exporter import ExporterSubcommandPlugin
from .exporter import BusDecoderExporter
from .cpuif import BaseCpuif, apb3, apb4
from .exporter import BusDecoderExporter
from .udps import ALL_UDPS
if TYPE_CHECKING:
import argparse
from systemrdl.node import AddrmapNode
@@ -23,7 +24,7 @@ class Exporter(ExporterSubcommandPlugin):
"cpuifs": {"*": schema.PythonObjectImport()},
}
@functools.lru_cache()
@functools.lru_cache
def get_cpuifs(self) -> dict[str, type[BaseCpuif]]:
# All built-in CPUIFs
cpuifs: dict[str, type[BaseCpuif]] = {

View File

@@ -3,17 +3,18 @@ from typing import TYPE_CHECKING
from systemrdl.node import FieldNode, RegNode
from systemrdl.walker import WalkerAction
from .utils import get_indexed_path
from .forloop_generator import RDLForLoopGenerator
from .sv_int import SVInt
from .utils import get_indexed_path
if TYPE_CHECKING:
from systemrdl.node import AddressableNode, AddrmapNode
from .exporter import BusDecoderExporter
from systemrdl.node import AddrmapNode, AddressableNode
class AddressDecode:
def __init__(self, exp: "BusDecoderExporter"):
def __init__(self, exp: "BusDecoderExporter") -> None:
self.exp = exp
@property

View File

@@ -9,25 +9,49 @@
`endif
{% endif -%}
//======================================================
// APB Fanout
//======================================================
assign cpuif_req = {{cpuif.signal("PSELx")}};
assign cpuif_wr_en = {{cpuif.signal("PWRITE")}};
assign cpuif_wr_data = {{cpuif.signal("PWDATA")}};
assign cpuif_rd_en = !{{cpuif.signal("PWRITE")}};
{%- for child in cpuif.addressable_children -%}
{%- if child is array -%}
for (genvar g_{{child.inst_name|lower}}_idx = 0; g_{{child.inst_name|lower}}_idx < N_{{child.inst_name|upper}}S; g_{{child.inst_name|lower}}_idx++) begin : g_passthrough_{{child.inst_name|lower}}
assign {{self.signal("PCLK", child, f"g_{child.inst_name.lower()}_idx")}} = {{self.signal("PCLK")}};
assign {{self.signal("PRESETn", child, f"g_{child.inst_name.lower()}_idx")}} = {{self.signal("PRESETn")}};
assign {{self.signal("PENABLE", child, f"g_{child.inst_name.lower()}_idx")}} = {{self.signal("PENABLE")}};
assign {{self.signal("PWRITE", child, f"g_{child.inst_name.lower()}_idx")}} = {{self.signal("PWRITE")}};
assign {{self.signal("PADDR", child, f"g_{child.inst_name.lower()}_idx")}} = {{self.signal("PADDR")}} [{{child.addr_width - 1}}:0]; // FIXME: Check slicing
assign {{self.signal("PWDATA", child, f"g_{child.inst_name.lower()}_idx")}} = {{self.signal("PWDATA")}};
assign {{cpuif.signal("PCLK", child, f"g_{child.inst_name.lower()}_idx")}} = {{cpuif.signal("PCLK")}};
assign {{cpuif.signal("PRESETn", child, f"g_{child.inst_name.lower()}_idx")}} = {{cpuif.signal("PRESETn")}};
assign {{cpuif.signal("PSELx", child, f"g_{child.inst_name.lower()}_idx")}} = (cpuif_wr_req[{{loop.indx}}] || cpuif_rd_req[{{loop.indx}}]) ? 1'b1 : 1'b0;
assign {{cpuif.signal("PENABLE", child, f"g_{child.inst_name.lower()}_idx")}} = {{cpuif.signal("PENABLE")}};
assign {{cpuif.signal("PWRITE", child, f"g_{child.inst_name.lower()}_idx")}} = (cpuif_wr_req[{{loop.index}}]) ? 1'b1 : 1'b0;
assign {{cpuif.signal("PADDR", child, f"g_{child.inst_name.lower()}_idx")}} = {{cpuif.get_address_slice(cpuif_wr_addr, child)}};
assign {{cpuif.signal("PWDATA", child, f"g_{child.inst_name.lower()}_idx")}} = cpuif_wr_data;
assign cpuif_rd_ack[loop.index] = {{cpuif.signal("PREADY", child)}};
assign cpuif_rd_data[loop.index] = {{cpuif.signal("PRDATA", child)}};
assign cpuif_rd_err[loop.index] = {{cpuif.signal("PSLVERR", child)}};
end
{%- else -%}
assign {{self.signal("PCLK", child)}} = {{self.signal("PCLK")}};
assign {{self.signal("PRESETn", child)}} = {{self.signal("PRESETn")}};
assign {{self.signal("PENABLE", child)}} = {{self.signal("PENABLE")}};
assign {{self.signal("PWRITE", child)}} = {{self.signal("PWRITE")}};
assign {{self.signal("PADDR", child)}} = {{self.signal("PADDR")}} [{{child.addr_width - 1}}:0]; // FIXME: Check slicing
assign {{self.signal("PWDATA", child)}} = {{self.signal("PWDATA")}};
assign {{cpuif.signal("PCLK", child)}} = {{cpuif.signal("PCLK")}};
assign {{cpuif.signal("PRESETn", child)}} = {{cpuif.signal("PRESETn")}};
assign {{cpuif.signal("PSELx", child)}} = (cpuif_wr_sel[{{loop.index0}}] || cpuif_rd_sel[{{loop.index0}}]) ? 1'b1 : 1'b0;
assign {{cpuif.signal("PENABLE", child)}} = {{cpuif.signal("PENABLE")}};
assign {{cpuif.signal("PWRITE", child)}} = (cpuif_wr_req[{{loop.index}}]) ? 1'b1 : 1'b0;
assign {{cpuif.signal("PADDR", child)}} = {{cpuif.get_address_slice(cpuif_wr_addr, child)}};
assign {{cpuif.signal("PWDATA", child)}} = cpuif_wr_data;
assign cpuif_rd_ack[loop.index] = {{cpuif.signal("PREADY", child)}};
assign cpuif_rd_data[loop.index] = {{cpuif.signal("PRDATA", child)}};
assign cpuif_rd_err[loop.index] = {{cpuif.signal("PSLVERR", child)}};
{%- endif -%}
{%- endfor -%}
{%- endfor -%}
always_comb begin
{{cpuif.signal("PREADY")}} = 1'b0;
{{cpuif.signal("PRDATA")}} = '0;
{{cpuif.signal("PSLVERR")}} = 1'b0;
for(int i = 0; i < {{cpuif.addressable_children | length}}; i++) begin
if (cpuif_rd_sel[i]) begin
{{cpuif.signal("PREADY")}} = cpuif_rd_ack[i];
{{cpuif.signal("PRDATA")}} = cpuif_rd_data[i];
{{cpuif.signal("PSLVERR")}} = cpuif_rd_err[i];
end
end
end

View File

@@ -9,111 +9,53 @@
`endif
{% endif -%}
//======================================================
// APB Fanout
//======================================================
assign cpuif_req = {{cpuif.signal("PSELx")}};
assign cpuif_wr_en = {{cpuif.signal("PWRITE")}};
assign cpuif_wr_data = {{cpuif.signal("PWDATA")}};
assign cpuif_rd_en = !{{cpuif.signal("PWRITE")}};
{%- for child in cpuif.addressable_children -%}
{%- if child is array -%}
for (genvar g_{{child.inst_name|lower}}_idx = 0; g_{{child.inst_name|lower}}_idx < N_{{child.inst_name|upper}}S; g_{{child.inst_name|lower}}_idx++) begin : g_passthrough_{{child.inst_name|lower}}
assign {{self.signal("PCLK", child, f"g_{child.inst_name.lower()}_idx")}} = {{self.signal("PCLK")}};
assign {{self.signal("PRESETn", child, f"g_{child.inst_name.lower()}_idx")}} = {{self.signal("PRESETn")}};
assign {{self.signal("PSELx", child, f"g_{child.inst_name.lower()}_idx")}} = (cpuif_wr_sel[{{loop.index}}] || cpuif_rd_sel[{{loop.index}}]) ? 1'b1 : 1'b0;
assign {{self.signal("PENABLE", child, f"g_{child.inst_name.lower()}_idx")}} = {{self.signal("PENABLE")}};
assign {{self.signal("PWRITE", child, f"g_{child.inst_name.lower()}_idx")}} = {{self.signal("PWRITE")}};
assign {{self.signal("PADDR", child, f"g_{child.inst_name.lower()}_idx")}} = {{self.signal("PADDR")}} [{{child.addr_width - 1}}:0]; // FIXME: Check slicing
assign {{self.signal("PWRITE", child, f"g_{child.inst_name.lower()}_idx")}} = (cpuif_wr_sel[{{loop.index}}]) ? 1'b1 : 1'b0;
assign {{self.signal("PADDR", child, f"g_{child.inst_name.lower()}_idx")}} = {{cpuif.get_address_slice(cpuif_wr_addr, child)}};
assign {{self.signal("PPROT", child, f"g_{child.inst_name.lower()}_idx")}} = {{self.signal("PPROT")}};
assign {{self.signal("PWDATA", child, f"g_{child.inst_name.lower()}_idx")}} = {{self.signal("PWDATA")}};
assign {{self.signal("PWDATA", child, f"g_{child.inst_name.lower()}_idx")}} = cpuif_wr_data;
assign {{self.signal("PSTRB", child, f"g_{child.inst_name.lower()}_idx")}} = {{self.signal("PSTRB")}};
assign cpuif_rd_ack[loop.index] = {{cpuif.signal("PREADY", child)}};
assign cpuif_rd_data[loop.index] = {{cpuif.signal("PRDATA", child)}};
assign cpuif_rd_err[loop.index] = {{cpuif.signal("PSLVERR", child)}};
end
{%- else -%}
assign {{self.signal("PCLK", child)}} = {{self.signal("PCLK")}};
assign {{self.signal("PRESETn", child)}} = {{self.signal("PRESETn")}};
assign {{self.signal("PSELx", child)}} = (cpuif_wr_sel[{{loop.index0}}] || cpuif_rd_sel[{{loop.index0}}]) ? 1'b1 : 1'b0;
assign {{self.signal("PENABLE", child)}} = {{self.signal("PENABLE")}};
assign {{self.signal("PWRITE", child)}} = {{self.signal("PWRITE")}};
assign {{self.signal("PADDR", child)}} = {{self.signal("PADDR")}} [{{child.addr_width - 1}}:0]; // FIXME: Check slicing
assign {{self.signal("PWRITE", child)}} = cpuif_wr_sel[{{loop.index}}] ? 1'b1 : 1'b0;
assign {{self.signal("PADDR", child)}} = {{cpuif.get_address_slice(cpuif_wr_addr, child)}};
assign {{self.signal("PPROT", child)}} = {{self.signal("PPROT")}};
assign {{self.signal("PWDATA", child)}} = {{self.signal("PWDATA")}};
assign {{self.signal("PWDATA", child)}} = cpuif_wr_data;
assign {{self.signal("PSTRB", child)}} = {{self.signal("PSTRB")}};
assign cpuif_rd_ack[loop.index] = {{cpuif.signal("PREADY", child)}};
assign cpuif_rd_data[loop.index] = {{cpuif.signal("PRDATA", child)}};
assign cpuif_rd_err[loop.index] = {{cpuif.signal("PSLVERR", child)}};
{%- endif -%}
{%- endfor -%}
//======================================================
// Address Decode Logic
//======================================================
always_comb begin
// Default all PSELx signals to 0
{%- for child in cpuif.addressable_children -%}
{%- if child is array -%}
for (int {{child.inst_name|lower}}_idx = 0; {{child.inst_name|lower}}_idx < N_{{child.inst_name|upper}}S; {{child.inst_name|lower}}_idx++) begin
{{self.signal("PSELx", child, f"{child.inst_name.lower()}_idx")}} = 1'b0;
end
{%- else -%}
{{self.signal("PSELx", child)}} = 1'b0;
{%- endif -%}
{%- endfor -%}
{{cpuif.signal("PREADY")}} = 1'b0;
{{cpuif.signal("PRDATA")}} = '0;
{{cpuif.signal("PSLVERR")}} = 1'b0;
if ({{self.signal("PSELx")}}) begin
{%- for child in cpuif.addressable_children -%}
{%- if loop.first -%}
if ({{cpuif.get_address_decode_condition(child)}}) begin
{%- else -%}
end else if ({{cpuif.get_address_decode_condition(child)}}) begin
{%- endif -%}
// Address matched for {{child.inst_name}}
{%- if child is array -%}
for (genvar {{child.inst_name|lower}}_idx = 0; {{child.inst_name|lower}}_idx < N_{{child.inst_name|upper}}S; {{child.inst_name|lower}}_idx++) begin
{{self.signal("PSELx", child, f"{child.inst_name.lower()}_idx")}} = 1'b1;
end
{%- else -%}
{{self.signal("PSELx", child)}} = 1'b1;
{%- endif -%}
{%- if loop.last -%}
end else begin
// No address matched
{%- endif -%}
{%- endfor -%}
for(int i = 0; i < {{cpuif.addressable_children | length}}; i++) begin
if (cpuif_rd_sel[i]) begin
{{cpuif.signal("PREADY")}} = cpuif_rd_ack[i];
{{cpuif.signal("PRDATA")}} = cpuif_rd_data[i];
{{cpuif.signal("PSLVERR")}} = cpuif_rd_err[i];
end
end else begin
// PSELx is low, nothing to do
end
end
//======================================================
// Read Data Mux
//======================================================
always_comb begin
// Default read data to 0
{{self.signal("PRDATA")}} = '0;
{{self.signal("PREADY")}} = 1'b1;
{{self.signal("PSLVERR")}} = 1'b0;
if ({{self.signal("PSELx")}} && !{{self.signal("PWRITE")}} && {{self.signal("PENABLE")}}) begin
{%- for child in cpuif.addressable_children -%}
{%- if loop.first -%}
if ({{cpuif.get_address_decode_condition(child)}}) begin
{%- else -%}
end else if ({{cpuif.get_address_decode_condition(child)}}) begin
{%- endif -%}
// Address matched for {{child.inst_name}}
{%- if child is array -%}
for (genvar {{child.inst_name|lower}}_idx = 0; {{child.inst_name|lower}}_idx < N_{{child.inst_name|upper}}S; {{child.inst_name|lower}}_idx++) begin
{{self.signal("PRDATA")}} = {{self.signal("PRDATA", child, f"{child.inst_name.lower()}_idx")}};
{{self.signal("PREADY")}} = {{self.signal("PREADY", child, f"{child.inst_name.lower()}_idx")}};
{{self.signal("PSLVERR")}} = {{self.signal("PSLVERR", child, f"{child.inst_name.lower()}_idx")}};
end
{%- else -%}
{{self.signal("PRDATA")}} = {{self.signal("PRDATA", child)}};
{{self.signal("PREADY")}} = {{self.signal("PREADY", child)}};
{{self.signal("PSLVERR")}} = {{self.signal("PSLVERR", child)}};
{%- endif -%}
{%- if loop.last -%}
end else begin
// No address matched
{{self.signal("PRDATA")}} = {'hdeadbeef}[{{ds.data_width - 1}}:0]; // Indicate error on no match
{{self.signal("PSLVERR")}} = 1'b1; // Indicate error on no match
end
{%- endif -%}
{%- endfor -%}
end else begin
// Not a read transfer, nothing to do
end
end

View File

@@ -1,6 +1,6 @@
from typing import TYPE_CHECKING
import inspect
import os
from typing import TYPE_CHECKING
import jinja2 as jj
from systemrdl.node import AddressableNode

View File

@@ -1,9 +1,10 @@
from typing import TYPE_CHECKING
from systemrdl.node import AddrmapNode, FieldNode, RegNode, AddressableNode
from systemrdl.node import AddressableNode, AddrmapNode, FieldNode, RegNode
if TYPE_CHECKING:
from .exporter import BusDecoderExporter, DesignState
from .addr_decode import AddressDecode
from .exporter import BusDecoderExporter, DesignState
class Dereferencer:
@@ -12,7 +13,7 @@ class Dereferencer:
into Verilog identifiers
"""
def __init__(self, exp: "BusDecoderExporter"):
def __init__(self, exp: "BusDecoderExporter") -> None:
self.exp = exp
@property

View File

@@ -6,14 +6,14 @@ from systemrdl.node import AddrmapNode, RootNode
from systemrdl.rdltypes.user_enum import UserEnum
from .addr_decode import AddressDecode
from .dereferencer import Dereferencer
from .identifier_filter import kw_filter as kwf
from .utils import clog2
from .scan_design import DesignScanner
from .validate_design import DesignValidator
from .cpuif import BaseCpuif
from .cpuif.apb4 import APB4Cpuif
from .dereferencer import Dereferencer
from .identifier_filter import kw_filter as kwf
from .scan_design import DesignScanner
from .sv_int import SVInt
from .utils import clog2
from .validate_design import DesignValidator
if TYPE_CHECKING:
pass

View File

@@ -1,5 +1,5 @@
from typing import TYPE_CHECKING
import textwrap
from typing import TYPE_CHECKING
from systemrdl.walker import RDLListener, RDLWalker, WalkerAction
@@ -12,7 +12,7 @@ class Body:
self.children: list[str | Body] = []
def __str__(self) -> str:
s = "\n".join((str(x) for x in self.children))
s = "\n".join(str(x) for x in self.children)
return s

View File

@@ -22,6 +22,8 @@ module {{ds.module_name}}
// CPU Bus interface logic
//--------------------------------------------------------------------------
logic cpuif_req;
logic cpuif_wr_en;
logic cpuif_rd_en;
logic [{{cpuif.addr_width-1}}:0] cpuif_wr_addr;
logic [{{cpuif.addr_width-1}}:0] cpuif_rd_addr;
@@ -30,9 +32,9 @@ module {{ds.module_name}}
logic [{{cpuif.data_width-1}}:0] cpuif_wr_data;
logic [{{cpuif.data_width//8-1}}:0] cpuif_wr_byte_en;
logic cpuif_rd_ack;
logic cpuif_rd_err;
logic [{{cpuif.data_width-1}}:0] cpuif_rd_data;
logic cpuif_rd_ack [{{cpuif.addressable_children|length}}];
logic cpuif_rd_err [{{cpuif.addressable_children|length}}];
logic [{{cpuif.data_width-1}}:0] cpuif_rd_data [{{cpuif.addressable_children|length}}];
//--------------------------------------------------------------------------
// Child instance signals
@@ -56,12 +58,12 @@ module {{ds.module_name}}
// A write request is pending
{%- for child in cpuif.addressable_children -%}
{%- if loop.first -%}
if ({{cpuif.get_address_decode_condition(child)}}) begin
if {{child|address_decode}} begin
{%- else -%}
end else if ({{cpuif.get_address_decode_condition(child)}}) begin
end else if {{child|address_decode}} begin
{%- endif -%}
// Address matched for {{child.inst_name}}
cpuif_wr_sel[{{loop.index0}}] = 1'b1;
cpuif_wr_sel[{{loop.index}}] = 1'b1;
{%- endfor -%}
end else begin
// No address match, all select signals remain 0
@@ -79,16 +81,16 @@ module {{ds.module_name}}
// Default all read select signals to 0
cpuif_rd_sel = '0;
if (cpuif_req && !cpuif_wr_en) begin
if (cpuif_req && cpuif_rd_en) begin
// A read request is pending
{%- for child in cpuif.addressable_children -%}
{%- if loop.first -%}
if ({{cpuif.get_address_decode_condition(child)}}) begin
if {{child|address_decode}} begin
{%- else -%}
end else if ({{cpuif.get_address_decode_condition(child)}}) begin
end else if {{child|address_decode}} begin
{%- endif -%}
// Address matched for {{child.inst_name}}
cpuif_rd_sel[{{loop.index0}}] = 1'b1;
cpuif_rd_sel[{{loop.index}}] = 1'b1;
{%- endfor -%}
end else begin
// No address match, all select signals remain 0

View File

@@ -1,10 +1,11 @@
from typing import TYPE_CHECKING
from systemrdl.walker import RDLListener, RDLWalker, WalkerAction
from systemrdl.node import RegNode
from systemrdl.walker import RDLListener, RDLWalker, WalkerAction
if TYPE_CHECKING:
from systemrdl.node import Node, AddressableNode, AddrmapNode
from systemrdl.node import AddressableNode, AddrmapNode, Node
from .exporter import DesignState

View File

@@ -1,8 +1,9 @@
import re
from typing import Match, overload
from re import Match
from typing import overload
from systemrdl.node import AddrmapNode, Node
from systemrdl.rdltypes.references import PropertyReference
from systemrdl.node import Node, AddrmapNode
from .identifier_filter import kw_filter as kwf
from .sv_int import SVInt

View File

@@ -1,13 +1,10 @@
from typing import TYPE_CHECKING
from systemrdl.walker import RDLListener, RDLWalker, WalkerAction
from systemrdl.node import AddressableNode, AddrmapNode, FieldNode, Node, RegfileNode, RegNode, SignalNode
from systemrdl.rdltypes import PropertyReference
from systemrdl.node import Node, RegNode, FieldNode, SignalNode, AddressableNode
from systemrdl.node import RegfileNode, AddrmapNode
from systemrdl.walker import RDLListener, RDLWalker, WalkerAction
from .utils import roundup_pow2, is_pow2
from .utils import ref_is_internal
from .utils import is_pow2, ref_is_internal, roundup_pow2
if TYPE_CHECKING:
from .exporter import BusDecoderExporter