peakrdl-busdecoder 0.2.0__tar.gz → 0.5.0__tar.gz
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-0.5.0/.devcontainer/Dockerfile +22 -0
- peakrdl_busdecoder-0.5.0/.devcontainer/devcontainer.json +33 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/.github/workflows/release.yml +3 -4
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/.github/workflows/test.yml +9 -5
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/PKG-INFO +2 -2
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/pyproject.toml +3 -2
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/__peakrdl__.py +3 -1
- peakrdl_busdecoder-0.5.0/src/peakrdl_busdecoder/cpuif/apb3/apb3_cpuif.py +92 -0
- peakrdl_busdecoder-0.2.0/src/peakrdl_busdecoder/cpuif/apb3/apb3_cpuif.py → peakrdl_busdecoder-0.5.0/src/peakrdl_busdecoder/cpuif/apb3/apb3_cpuif_flat.py +12 -11
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/cpuif/apb3/apb3_tmpl.sv +7 -0
- peakrdl_busdecoder-0.5.0/src/peakrdl_busdecoder/cpuif/apb4/apb4_cpuif.py +95 -0
- peakrdl_busdecoder-0.2.0/src/peakrdl_busdecoder/cpuif/apb4/apb4_cpuif.py → peakrdl_busdecoder-0.5.0/src/peakrdl_busdecoder/cpuif/apb4/apb4_cpuif_flat.py +12 -12
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/cpuif/apb4/apb4_tmpl.sv +7 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/cpuif/axi4lite/axi4_lite_cpuif.py +31 -6
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/cpuif/axi4lite/axi4_lite_cpuif_flat.py +2 -2
- peakrdl_busdecoder-0.2.0/src/peakrdl_busdecoder/cpuif/axi4lite/axi4lite_tmpl.sv → peakrdl_busdecoder-0.5.0/src/peakrdl_busdecoder/cpuif/axi4lite/axi4_lite_tmpl.sv +7 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/cpuif/base_cpuif.py +24 -5
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/cpuif/fanin_gen.py +11 -0
- peakrdl_busdecoder-0.5.0/src/peakrdl_busdecoder/cpuif/fanin_intermediate_gen.py +142 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/cpuif/fanout_gen.py +11 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/cpuif/interface.py +10 -1
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/decode_logic_gen.py +19 -1
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/design_state.py +54 -1
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/exporter.py +3 -1
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/listener.py +6 -1
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/module_tmpl.sv +2 -2
- peakrdl_busdecoder-0.5.0/src/peakrdl_busdecoder/struct_gen.py +68 -0
- peakrdl_busdecoder-0.5.0/src/peakrdl_busdecoder/sv_int.py +48 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder.egg-info/PKG-INFO +2 -2
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder.egg-info/SOURCES.txt +5 -2
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/tools/shims/xargs +0 -1
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/uv.lock +1 -1
- peakrdl_busdecoder-0.2.0/src/peakrdl_busdecoder/cpuif/apb3/apb3_cpuif_flat.py +0 -68
- peakrdl_busdecoder-0.2.0/src/peakrdl_busdecoder/cpuif/apb4/apb4_cpuif_flat.py +0 -70
- peakrdl_busdecoder-0.2.0/src/peakrdl_busdecoder/struct_gen.py +0 -57
- peakrdl_busdecoder-0.2.0/src/peakrdl_busdecoder/sv_int.py +0 -21
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/.github/ISSUE_TEMPLATE/question.md +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/.github/pull_request_template.md +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/.github/workflows/build.yml +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/.github/workflows/docs.yml +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/.github/workflows/format.yml +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/.github/workflows/lint.yml +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/.github/workflows/typecheck.yml +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/.gitignore +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/.readthedocs.yaml +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/CONTRIBUTING.md +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/LICENSE +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/MANIFEST.in +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/README.md +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/Makefile +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/api.rst +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/architecture.rst +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/conf.py +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/configuring.rst +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/cpuif/apb.rst +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/cpuif/avalon.rst +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/cpuif/axi4lite.rst +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/cpuif/customizing.rst +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/cpuif/internal_protocol.rst +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/cpuif/introduction.rst +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/cpuif/passthrough.rst +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/dev_notes/Alpha-Beta Versioning +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/dev_notes/Hierarchy-and-Indexing +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/dev_notes/Program Flow +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/dev_notes/Resets +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/dev_notes/Signal Dereferencer +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/dev_notes/Validation Needed +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/dev_notes/template-layers/1-port-declaration +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/dev_notes/template-layers/1.1.hardware-interface +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/dev_notes/template-layers/2-CPUIF +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/dev_notes/template-layers/3-address-decode +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/dev_notes/template-layers/4-fields +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/dev_notes/template-layers/5-readback-mux +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/dev_notes/template-layers/6-output-port-mapping +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/diagrams/arch.png +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/diagrams/diagrams.odg +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/diagrams/rbuf.png +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/diagrams/readback.png +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/diagrams/wbuf.png +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/faq.rst +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/hwif.rst +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/img/err.svg +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/img/ok.svg +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/img/warn.svg +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/index.rst +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/licensing.rst +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/limitations.rst +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/props/addrmap.rst +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/props/field.rst +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/props/reg.rst +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/props/rhs_props.rst +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/props/signal.rst +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/rdl_features/external.rst +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/requirements.txt +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/docs/udps/intro.rst +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/hdl-src/README.md +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/hdl-src/apb3_intf.sv +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/hdl-src/apb4_intf.sv +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/hdl-src/avalon_mm_intf.sv +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/hdl-src/axi4lite_intf.sv +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/setup.cfg +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/__init__.py +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/body/__init__.py +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/body/body.py +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/body/combinational_body.py +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/body/for_loop_body.py +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/body/if_body.py +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/body/struct_body.py +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/cpuif/__init__.py +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/cpuif/apb3/__init__.py +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/cpuif/apb3/apb3_interface.py +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/cpuif/apb4/__init__.py +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/cpuif/apb4/apb4_interface.py +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/cpuif/axi4lite/__init__.py +0 -0
- /peakrdl_busdecoder-0.2.0/src/peakrdl_busdecoder/cpuif/axi4lite/axi4lite_interface.py → /peakrdl_busdecoder-0.5.0/src/peakrdl_busdecoder/cpuif/axi4lite/axi4_lite_interface.py +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/design_scanner.py +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/identifier_filter.py +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/package_tmpl.sv +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/py.typed +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/udps/__init__.py +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/utils.py +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/validate_design.py +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder.egg-info/dependency_links.txt +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder.egg-info/entry_points.txt +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder.egg-info/requires.txt +0 -0
- {peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
FROM verilator/verilator:latest
|
|
2
|
+
|
|
3
|
+
ENV DEBIAN_FRONTEND=noninteractive
|
|
4
|
+
|
|
5
|
+
RUN apt-get update && \
|
|
6
|
+
apt-get install -y --no-install-recommends \
|
|
7
|
+
python3 \
|
|
8
|
+
python3-venv \
|
|
9
|
+
python3-pip \
|
|
10
|
+
python3-dev \
|
|
11
|
+
build-essential \
|
|
12
|
+
pkg-config \
|
|
13
|
+
git \
|
|
14
|
+
curl \
|
|
15
|
+
ca-certificates && \
|
|
16
|
+
rm -rf /var/lib/apt/lists/*
|
|
17
|
+
|
|
18
|
+
ENV UV_INSTALL_DIR=/usr/local/bin
|
|
19
|
+
ENV UV_LINK_MODE=copy
|
|
20
|
+
# Install uv globally so both VS Code and terminals can use it
|
|
21
|
+
RUN curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
22
|
+
RUN uv --version
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "PeakRDL BusDecoder",
|
|
3
|
+
"build": {
|
|
4
|
+
"dockerfile": "Dockerfile"
|
|
5
|
+
},
|
|
6
|
+
"runArgs": [
|
|
7
|
+
"--init"
|
|
8
|
+
],
|
|
9
|
+
"features": {
|
|
10
|
+
"ghcr.io/devcontainers/features/common-utils:2": {
|
|
11
|
+
"username": "vscode",
|
|
12
|
+
"uid": "1000",
|
|
13
|
+
"gid": "1000",
|
|
14
|
+
"installZsh": "false",
|
|
15
|
+
"installOhMyZsh": "false"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"remoteUser": "vscode",
|
|
19
|
+
"postCreateCommand": "uv sync --frozen --all-extras --group tools --group test",
|
|
20
|
+
"customizations": {
|
|
21
|
+
"vscode": {
|
|
22
|
+
"settings": {
|
|
23
|
+
"python.defaultInterpreterPath": ".venv/bin/python",
|
|
24
|
+
"terminal.integrated.shell.linux": "/bin/bash"
|
|
25
|
+
},
|
|
26
|
+
"extensions": [
|
|
27
|
+
"ms-python.python",
|
|
28
|
+
"ms-python.vscode-pylance",
|
|
29
|
+
"ms-vscode.cpptools"
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -40,7 +40,6 @@ jobs:
|
|
|
40
40
|
|
|
41
41
|
- name: Publish to PyPI
|
|
42
42
|
if: startsWith(github.ref, 'refs/tags/')
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
run: uvx twine upload dist/*
|
|
43
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
44
|
+
with:
|
|
45
|
+
skip-existing: true
|
|
@@ -14,6 +14,8 @@ on:
|
|
|
14
14
|
jobs:
|
|
15
15
|
test:
|
|
16
16
|
runs-on: ubuntu-latest
|
|
17
|
+
container:
|
|
18
|
+
image: verilator/verilator:latest
|
|
17
19
|
permissions:
|
|
18
20
|
contents: read
|
|
19
21
|
strategy:
|
|
@@ -27,19 +29,21 @@ jobs:
|
|
|
27
29
|
uses: astral-sh/setup-uv@v3
|
|
28
30
|
with:
|
|
29
31
|
python-version: ${{ matrix.python-version }}
|
|
32
|
+
enable-cache: true
|
|
30
33
|
|
|
31
|
-
- name:
|
|
34
|
+
- name: Check Verilator version
|
|
35
|
+
run: verilator --version
|
|
36
|
+
|
|
37
|
+
- name: Install Python development packages
|
|
32
38
|
run: |
|
|
33
|
-
|
|
34
|
-
sudo apt-get install -y verilator
|
|
35
|
-
verilator --version
|
|
39
|
+
apt-get update && apt-get install -y python3-dev libpython3-dev
|
|
36
40
|
|
|
37
41
|
- name: Install dependencies
|
|
38
42
|
run: |
|
|
39
43
|
uv sync --all-extras --group test
|
|
40
44
|
|
|
41
45
|
- name: Run tests
|
|
42
|
-
run: uv run pytest tests/
|
|
46
|
+
run: uv run pytest tests/ --cov=peakrdl_busdecoder --cov-report=xml --cov-report=term
|
|
43
47
|
|
|
44
48
|
- name: Upload coverage to Codecov
|
|
45
49
|
uses: codecov/codecov-action@v4
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: peakrdl-busdecoder
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Generate a SystemVerilog bus decoder from SystemRDL for splitting CPU interfaces to multiple sub-address spaces
|
|
5
|
-
Author:
|
|
5
|
+
Author: Arnav Sacheti
|
|
6
6
|
License: LGPLv3
|
|
7
7
|
Project-URL: Source, https://github.com/arnavsacheti/PeakRDL-BusDecoder
|
|
8
8
|
Project-URL: Tracker, https://github.com/arnavsacheti/PeakRDL-BusDecoder/issues
|
|
@@ -4,11 +4,11 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "peakrdl-busdecoder"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.5.0"
|
|
8
8
|
requires-python = ">=3.10"
|
|
9
9
|
dependencies = ["jinja2>=3.1.6", "systemrdl-compiler~=1.30.1"]
|
|
10
10
|
|
|
11
|
-
authors = [{ name = "
|
|
11
|
+
authors = [{ name = "Arnav Sacheti" }]
|
|
12
12
|
description = "Generate a SystemVerilog bus decoder from SystemRDL for splitting CPU interfaces to multiple sub-address spaces"
|
|
13
13
|
readme = "README.md"
|
|
14
14
|
license = { text = "LGPLv3" }
|
|
@@ -114,3 +114,4 @@ markers = [
|
|
|
114
114
|
"simulation: marks tests as requiring cocotb simulation (deselect with '-m \"not simulation\"')",
|
|
115
115
|
"verilator: marks tests as requiring verilator simulator (deselect with '-m \"not verilator\"')",
|
|
116
116
|
]
|
|
117
|
+
filterwarnings = ["error", "ignore::UserWarning"]
|
|
@@ -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
|
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, overload
|
|
2
|
+
|
|
3
|
+
from systemrdl.node import AddressableNode
|
|
4
|
+
|
|
5
|
+
from ...utils import get_indexed_path
|
|
6
|
+
from ..base_cpuif import BaseCpuif
|
|
7
|
+
from .apb3_interface import APB3SVInterface
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from ...exporter import BusDecoderExporter
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class APB3Cpuif(BaseCpuif):
|
|
14
|
+
template_path = "apb3_tmpl.sv"
|
|
15
|
+
|
|
16
|
+
def __init__(self, exp: "BusDecoderExporter") -> None:
|
|
17
|
+
super().__init__(exp)
|
|
18
|
+
self._interface = APB3SVInterface(self)
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def is_interface(self) -> bool:
|
|
22
|
+
return self._interface.is_interface
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def port_declaration(self) -> str:
|
|
26
|
+
return self._interface.get_port_declaration("s_apb", "m_apb_")
|
|
27
|
+
|
|
28
|
+
@overload
|
|
29
|
+
def signal(self, signal: str, node: None = None, indexer: None = None) -> str: ...
|
|
30
|
+
@overload
|
|
31
|
+
def signal(self, signal: str, node: AddressableNode, indexer: str) -> str: ...
|
|
32
|
+
def signal(self, signal: str, node: AddressableNode | None = None, indexer: str | None = None) -> str:
|
|
33
|
+
return self._interface.signal(signal, node, indexer)
|
|
34
|
+
|
|
35
|
+
def fanout(self, node: AddressableNode) -> str:
|
|
36
|
+
fanout: dict[str, str] = {}
|
|
37
|
+
fanout[self.signal("PSEL", node, "gi")] = (
|
|
38
|
+
f"cpuif_wr_sel.{get_indexed_path(self.exp.ds.top_node, node, 'gi')}|cpuif_rd_sel.{get_indexed_path(self.exp.ds.top_node, node, 'gi')}"
|
|
39
|
+
)
|
|
40
|
+
fanout[self.signal("PENABLE", node, "gi")] = self.signal("PENABLE")
|
|
41
|
+
fanout[self.signal("PWRITE", node, "gi")] = (
|
|
42
|
+
f"cpuif_wr_sel.{get_indexed_path(self.exp.ds.top_node, node, 'gi')}"
|
|
43
|
+
)
|
|
44
|
+
fanout[self.signal("PADDR", node, "gi")] = self.signal("PADDR")
|
|
45
|
+
fanout[self.signal("PWDATA", node, "gi")] = "cpuif_wr_data"
|
|
46
|
+
|
|
47
|
+
return "\n".join(map(lambda kv: f"assign {kv[0]} = {kv[1]};", fanout.items()))
|
|
48
|
+
|
|
49
|
+
def fanin(self, node: AddressableNode | None = None) -> str:
|
|
50
|
+
fanin: dict[str, str] = {}
|
|
51
|
+
if node is None:
|
|
52
|
+
fanin["cpuif_rd_ack"] = "'0"
|
|
53
|
+
fanin["cpuif_rd_err"] = "'0"
|
|
54
|
+
else:
|
|
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")
|
|
65
|
+
|
|
66
|
+
return "\n".join(map(lambda kv: f"{kv[0]} = {kv[1]};", fanin.items()))
|
|
67
|
+
|
|
68
|
+
def readback(self, node: AddressableNode | None = None) -> str:
|
|
69
|
+
fanin: dict[str, str] = {}
|
|
70
|
+
if node is None:
|
|
71
|
+
fanin["cpuif_rd_data"] = "'0"
|
|
72
|
+
else:
|
|
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")
|
|
81
|
+
|
|
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
|
+
]
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
from typing import TYPE_CHECKING
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
2
2
|
|
|
3
3
|
from systemrdl.node import AddressableNode
|
|
4
4
|
|
|
5
5
|
from ...utils import get_indexed_path
|
|
6
6
|
from ..base_cpuif import BaseCpuif
|
|
7
|
-
from .apb3_interface import
|
|
7
|
+
from .apb3_interface import APB3FlatInterface
|
|
8
8
|
|
|
9
9
|
if TYPE_CHECKING:
|
|
10
10
|
from ...exporter import BusDecoderExporter
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
class
|
|
13
|
+
class APB3CpuifFlat(BaseCpuif):
|
|
14
14
|
template_path = "apb3_tmpl.sv"
|
|
15
15
|
|
|
16
16
|
def __init__(self, exp: "BusDecoderExporter") -> None:
|
|
17
17
|
super().__init__(exp)
|
|
18
|
-
self._interface =
|
|
18
|
+
self._interface = APB3FlatInterface(self)
|
|
19
19
|
|
|
20
20
|
@property
|
|
21
21
|
def is_interface(self) -> bool:
|
|
@@ -23,14 +23,15 @@ class APB3Cpuif(BaseCpuif):
|
|
|
23
23
|
|
|
24
24
|
@property
|
|
25
25
|
def port_declaration(self) -> str:
|
|
26
|
-
return self._interface.get_port_declaration("
|
|
26
|
+
return self._interface.get_port_declaration("s_apb_", "m_apb_")
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
def signal(
|
|
29
|
+
self,
|
|
30
|
+
signal: str,
|
|
31
|
+
node: AddressableNode | None = None,
|
|
32
|
+
idx: str | int | None = None,
|
|
33
|
+
) -> str:
|
|
34
|
+
return self._interface.signal(signal, node, idx)
|
|
34
35
|
|
|
35
36
|
def fanout(self, node: AddressableNode) -> str:
|
|
36
37
|
fanout: dict[str, str] = {}
|
{peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/cpuif/apb3/apb3_tmpl.sv
RENAMED
|
@@ -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
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, overload
|
|
2
|
+
|
|
3
|
+
from systemrdl.node import AddressableNode
|
|
4
|
+
|
|
5
|
+
from ...utils import get_indexed_path
|
|
6
|
+
from ..base_cpuif import BaseCpuif
|
|
7
|
+
from .apb4_interface import APB4SVInterface
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from ...exporter import BusDecoderExporter
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class APB4Cpuif(BaseCpuif):
|
|
14
|
+
template_path = "apb4_tmpl.sv"
|
|
15
|
+
|
|
16
|
+
def __init__(self, exp: "BusDecoderExporter") -> None:
|
|
17
|
+
super().__init__(exp)
|
|
18
|
+
self._interface = APB4SVInterface(self)
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def is_interface(self) -> bool:
|
|
22
|
+
return self._interface.is_interface
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def port_declaration(self) -> str:
|
|
26
|
+
"""Returns the port declaration for the APB4 interface."""
|
|
27
|
+
return self._interface.get_port_declaration("s_apb", "m_apb_")
|
|
28
|
+
|
|
29
|
+
@overload
|
|
30
|
+
def signal(self, signal: str, node: None = None, indexer: None = None) -> str: ...
|
|
31
|
+
@overload
|
|
32
|
+
def signal(self, signal: str, node: AddressableNode, indexer: str) -> str: ...
|
|
33
|
+
def signal(self, signal: str, node: AddressableNode | None = None, indexer: str | None = None) -> str:
|
|
34
|
+
return self._interface.signal(signal, node, indexer)
|
|
35
|
+
|
|
36
|
+
def fanout(self, node: AddressableNode) -> str:
|
|
37
|
+
fanout: dict[str, str] = {}
|
|
38
|
+
fanout[self.signal("PSEL", node, "gi")] = (
|
|
39
|
+
f"cpuif_wr_sel.{get_indexed_path(self.exp.ds.top_node, node, 'gi')}|cpuif_rd_sel.{get_indexed_path(self.exp.ds.top_node, node, 'gi')}"
|
|
40
|
+
)
|
|
41
|
+
fanout[self.signal("PENABLE", node, "gi")] = self.signal("PENABLE")
|
|
42
|
+
fanout[self.signal("PWRITE", node, "gi")] = (
|
|
43
|
+
f"cpuif_wr_sel.{get_indexed_path(self.exp.ds.top_node, node, 'gi')}"
|
|
44
|
+
)
|
|
45
|
+
fanout[self.signal("PADDR", node, "gi")] = self.signal("PADDR")
|
|
46
|
+
fanout[self.signal("PPROT", node, "gi")] = self.signal("PPROT")
|
|
47
|
+
fanout[self.signal("PWDATA", node, "gi")] = "cpuif_wr_data"
|
|
48
|
+
fanout[self.signal("PSTRB", node, "gi")] = "cpuif_wr_byte_en"
|
|
49
|
+
|
|
50
|
+
return "\n".join(map(lambda kv: f"assign {kv[0]} = {kv[1]};", fanout.items()))
|
|
51
|
+
|
|
52
|
+
def fanin(self, node: AddressableNode | None = None) -> str:
|
|
53
|
+
fanin: dict[str, str] = {}
|
|
54
|
+
if node is None:
|
|
55
|
+
fanin["cpuif_rd_ack"] = "'0"
|
|
56
|
+
fanin["cpuif_rd_err"] = "'0"
|
|
57
|
+
else:
|
|
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")
|
|
68
|
+
|
|
69
|
+
return "\n".join(map(lambda kv: f"{kv[0]} = {kv[1]};", fanin.items()))
|
|
70
|
+
|
|
71
|
+
def readback(self, node: AddressableNode | None = None) -> str:
|
|
72
|
+
fanin: dict[str, str] = {}
|
|
73
|
+
if node is None:
|
|
74
|
+
fanin["cpuif_rd_data"] = "'0"
|
|
75
|
+
else:
|
|
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")
|
|
84
|
+
|
|
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
|
+
]
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
from typing import TYPE_CHECKING
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
2
2
|
|
|
3
3
|
from systemrdl.node import AddressableNode
|
|
4
4
|
|
|
5
5
|
from ...utils import get_indexed_path
|
|
6
6
|
from ..base_cpuif import BaseCpuif
|
|
7
|
-
from .apb4_interface import
|
|
7
|
+
from .apb4_interface import APB4FlatInterface
|
|
8
8
|
|
|
9
9
|
if TYPE_CHECKING:
|
|
10
10
|
from ...exporter import BusDecoderExporter
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
class
|
|
13
|
+
class APB4CpuifFlat(BaseCpuif):
|
|
14
14
|
template_path = "apb4_tmpl.sv"
|
|
15
15
|
|
|
16
16
|
def __init__(self, exp: "BusDecoderExporter") -> None:
|
|
17
17
|
super().__init__(exp)
|
|
18
|
-
self._interface =
|
|
18
|
+
self._interface = APB4FlatInterface(self)
|
|
19
19
|
|
|
20
20
|
@property
|
|
21
21
|
def is_interface(self) -> bool:
|
|
@@ -23,15 +23,15 @@ class APB4Cpuif(BaseCpuif):
|
|
|
23
23
|
|
|
24
24
|
@property
|
|
25
25
|
def port_declaration(self) -> str:
|
|
26
|
-
""
|
|
27
|
-
return self._interface.get_port_declaration("s_apb", "m_apb_")
|
|
26
|
+
return self._interface.get_port_declaration("s_apb_", "m_apb_")
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
28
|
+
def signal(
|
|
29
|
+
self,
|
|
30
|
+
signal: str,
|
|
31
|
+
node: AddressableNode | None = None,
|
|
32
|
+
idx: str | int | None = None,
|
|
33
|
+
) -> str:
|
|
34
|
+
return self._interface.signal(signal, node, idx)
|
|
35
35
|
|
|
36
36
|
def fanout(self, node: AddressableNode) -> str:
|
|
37
37
|
fanout: dict[str, str] = {}
|
{peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/cpuif/apb4/apb4_tmpl.sv
RENAMED
|
@@ -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
|
{peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/cpuif/base_cpuif.py
RENAMED
|
@@ -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
|
{peakrdl_busdecoder-0.2.0 → peakrdl_busdecoder-0.5.0}/src/peakrdl_busdecoder/cpuif/fanin_gen.py
RENAMED
|
@@ -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(
|