peakrdl-busdecoder 0.6.5__tar.gz → 0.6.6__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.
Files changed (124) hide show
  1. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/PKG-INFO +1 -1
  2. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/configuring.rst +1 -1
  3. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/licensing.rst +1 -1
  4. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/pyproject.toml +1 -1
  5. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/cpuif/apb3/apb3_cpuif.py +20 -9
  6. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/cpuif/apb3/apb3_cpuif_flat.py +16 -6
  7. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/cpuif/apb3/apb3_tmpl.sv +2 -2
  8. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/cpuif/apb4/apb4_cpuif.py +20 -8
  9. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/cpuif/apb4/apb4_cpuif_flat.py +16 -7
  10. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/cpuif/apb4/apb4_tmpl.sv +2 -2
  11. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/cpuif/axi4lite/axi4_lite_cpuif.py +20 -8
  12. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/cpuif/axi4lite/axi4_lite_cpuif_flat.py +16 -6
  13. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/cpuif/base_cpuif.py +2 -2
  14. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/cpuif/fanin_gen.py +15 -7
  15. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder.egg-info/PKG-INFO +1 -1
  16. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/uv.lock +4 -1
  17. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/.devcontainer/Dockerfile +0 -0
  18. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/.devcontainer/devcontainer.json +0 -0
  19. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  20. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  21. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/.github/ISSUE_TEMPLATE/question.md +0 -0
  22. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/.github/pull_request_template.md +0 -0
  23. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/.github/workflows/build.yml +0 -0
  24. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/.github/workflows/docs.yml +0 -0
  25. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/.github/workflows/format.yml +0 -0
  26. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/.github/workflows/lint.yml +0 -0
  27. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/.github/workflows/release.yml +0 -0
  28. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/.github/workflows/test.yml +0 -0
  29. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/.github/workflows/typecheck.yml +0 -0
  30. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/.gitignore +0 -0
  31. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/.readthedocs.yaml +0 -0
  32. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/CONTRIBUTING.md +0 -0
  33. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/LICENSE +0 -0
  34. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/MANIFEST.in +0 -0
  35. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/README.md +0 -0
  36. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/Makefile +0 -0
  37. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/api.rst +0 -0
  38. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/architecture.rst +0 -0
  39. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/conf.py +0 -0
  40. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/cpuif/apb.rst +0 -0
  41. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/cpuif/avalon.rst +0 -0
  42. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/cpuif/axi4lite.rst +0 -0
  43. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/cpuif/customizing.rst +0 -0
  44. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/cpuif/internal_protocol.rst +0 -0
  45. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/cpuif/introduction.rst +0 -0
  46. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/cpuif/passthrough.rst +0 -0
  47. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/dev_notes/Alpha-Beta Versioning +0 -0
  48. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/dev_notes/Hierarchy-and-Indexing +0 -0
  49. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/dev_notes/Program Flow +0 -0
  50. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/dev_notes/Resets +0 -0
  51. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/dev_notes/Signal Dereferencer +0 -0
  52. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/dev_notes/Validation Needed +0 -0
  53. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/dev_notes/template-layers/1-port-declaration +0 -0
  54. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/dev_notes/template-layers/1.1.hardware-interface +0 -0
  55. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/dev_notes/template-layers/2-CPUIF +0 -0
  56. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/dev_notes/template-layers/3-address-decode +0 -0
  57. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/dev_notes/template-layers/4-fields +0 -0
  58. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/dev_notes/template-layers/5-readback-mux +0 -0
  59. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/dev_notes/template-layers/6-output-port-mapping +0 -0
  60. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/diagrams/arch.png +0 -0
  61. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/diagrams/diagrams.odg +0 -0
  62. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/diagrams/rbuf.png +0 -0
  63. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/diagrams/readback.png +0 -0
  64. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/diagrams/wbuf.png +0 -0
  65. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/faq.rst +0 -0
  66. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/hwif.rst +0 -0
  67. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/img/err.svg +0 -0
  68. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/img/ok.svg +0 -0
  69. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/img/warn.svg +0 -0
  70. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/index.rst +0 -0
  71. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/limitations.rst +0 -0
  72. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/props/addrmap.rst +0 -0
  73. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/props/field.rst +0 -0
  74. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/props/reg.rst +0 -0
  75. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/props/rhs_props.rst +0 -0
  76. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/props/signal.rst +0 -0
  77. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/rdl_features/external.rst +0 -0
  78. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/requirements.txt +0 -0
  79. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/docs/udps/intro.rst +0 -0
  80. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/hdl-src/README.md +0 -0
  81. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/hdl-src/apb3_intf.sv +0 -0
  82. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/hdl-src/apb4_intf.sv +0 -0
  83. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/hdl-src/avalon_mm_intf.sv +0 -0
  84. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/hdl-src/axi4lite_intf.sv +0 -0
  85. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/setup.cfg +0 -0
  86. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/__init__.py +0 -0
  87. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/__peakrdl__.py +0 -0
  88. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/body/__init__.py +0 -0
  89. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/body/body.py +0 -0
  90. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/body/combinational_body.py +0 -0
  91. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/body/for_loop_body.py +0 -0
  92. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/body/if_body.py +0 -0
  93. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/body/struct_body.py +0 -0
  94. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/cpuif/__init__.py +0 -0
  95. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/cpuif/apb3/__init__.py +0 -0
  96. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/cpuif/apb3/apb3_interface.py +0 -0
  97. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/cpuif/apb4/__init__.py +0 -0
  98. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/cpuif/apb4/apb4_interface.py +0 -0
  99. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/cpuif/axi4lite/__init__.py +0 -0
  100. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/cpuif/axi4lite/axi4_lite_interface.py +0 -0
  101. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/cpuif/axi4lite/axi4_lite_tmpl.sv +0 -0
  102. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/cpuif/fanin_intermediate_gen.py +0 -0
  103. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/cpuif/fanout_gen.py +0 -0
  104. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/cpuif/interface.py +0 -0
  105. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/decode_logic_gen.py +0 -0
  106. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/design_scanner.py +0 -0
  107. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/design_state.py +0 -0
  108. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/exporter.py +0 -0
  109. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/identifier_filter.py +0 -0
  110. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/listener.py +0 -0
  111. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/module_tmpl.sv +0 -0
  112. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/package_tmpl.sv +0 -0
  113. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/py.typed +0 -0
  114. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/struct_gen.py +0 -0
  115. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/sv_int.py +0 -0
  116. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/udps/__init__.py +0 -0
  117. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/utils.py +0 -0
  118. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder/validate_design.py +0 -0
  119. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder.egg-info/SOURCES.txt +0 -0
  120. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder.egg-info/dependency_links.txt +0 -0
  121. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder.egg-info/entry_points.txt +0 -0
  122. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder.egg-info/requires.txt +0 -0
  123. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/src/peakrdl_busdecoder.egg-info/top_level.txt +0 -0
  124. {peakrdl_busdecoder-0.6.5 → peakrdl_busdecoder-0.6.6}/tools/shims/xargs +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: peakrdl-busdecoder
3
- Version: 0.6.5
3
+ Version: 0.6.6
4
4
  Summary: Generate a SystemVerilog bus decoder from SystemRDL for splitting CPU interfaces to multiple sub-address spaces
5
5
  Author: Arnav Sacheti
6
6
  License: LGPLv3
@@ -1,7 +1,7 @@
1
1
  .. _peakrdl_cfg:
2
2
 
3
3
  Configuring PeakRDL-BusDecoder
4
- ============================
4
+ ==============================
5
5
 
6
6
  If using the `PeakRDL command line tool <https://peakrdl.readthedocs.io/>`_,
7
7
  some aspects of the ``busdecoder`` command have additional configuration options
@@ -15,7 +15,7 @@ be contrary to this project's philosophy.
15
15
 
16
16
 
17
17
  What is covered by the LGPL v3 license?
18
- --------------------------------------
18
+ ---------------------------------------
19
19
  The LGPL license is intended for the code generator itself. This includes all
20
20
  Python sources, Jinja template files, as well as testcase infrastructure not
21
21
  explicitly mentioned in the exemptions below.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "peakrdl-busdecoder"
7
- version = "0.6.5"
7
+ version = "0.6.6"
8
8
  requires-python = ">=3.10"
9
9
  dependencies = [
10
10
  "jinja2~=3.1",
@@ -47,37 +47,48 @@ class APB3Cpuif(BaseCpuif):
47
47
 
48
48
  return "\n".join(f"assign {kv[0]} = {kv[1]};" for kv in fanout.items())
49
49
 
50
- def fanin(self, node: AddressableNode | None = None) -> str:
50
+ def fanin_wr(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
51
51
  fanin: dict[str, str] = {}
52
52
  if node is None:
53
- fanin["cpuif_rd_ack"] = "'0"
54
- fanin["cpuif_rd_err"] = "'0"
53
+ fanin["cpuif_wr_ack"] = "'0"
54
+ fanin["cpuif_wr_err"] = "'0"
55
+ if error:
56
+ fanin["cpuif_wr_ack"] = "'1"
57
+ fanin["cpuif_wr_err"] = "cpuif_wr_sel.cpuif_err"
55
58
  else:
56
59
  # Use intermediate signals for interface arrays to avoid
57
60
  # non-constant indexing of interface arrays in procedural blocks
58
61
  if self.is_interface and node.is_array and node.array_dimensions:
59
62
  # Generate array index string [i0][i1]... for the intermediate signal
60
63
  array_idx = "".join(f"[i{i}]" for i in range(len(node.array_dimensions)))
61
- fanin["cpuif_rd_ack"] = f"{node.inst_name}_fanin_ready{array_idx}"
62
- fanin["cpuif_rd_err"] = f"{node.inst_name}_fanin_err{array_idx}"
64
+ fanin["cpuif_wr_ack"] = f"{node.inst_name}_fanin_ready{array_idx}"
65
+ fanin["cpuif_wr_err"] = f"{node.inst_name}_fanin_err{array_idx}"
63
66
  else:
64
- fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
65
- fanin["cpuif_rd_err"] = self.signal("PSLVERR", node, "i")
66
-
67
+ fanin["cpuif_wr_ack"] = self.signal("PREADY", node, "i")
68
+ fanin["cpuif_wr_err"] = self.signal("PSLVERR", node, "i")
67
69
  return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
68
70
 
69
- def readback(self, node: AddressableNode | None = None) -> str:
71
+ def fanin_rd(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
70
72
  fanin: dict[str, str] = {}
71
73
  if node is None:
74
+ fanin["cpuif_rd_ack"] = "'0"
75
+ fanin["cpuif_rd_err"] = "'0"
72
76
  fanin["cpuif_rd_data"] = "'0"
77
+ if error:
78
+ fanin["cpuif_rd_ack"] = "'1"
79
+ fanin["cpuif_rd_err"] = "cpuif_rd_sel.cpuif_err"
73
80
  else:
74
81
  # Use intermediate signals for interface arrays to avoid
75
82
  # non-constant indexing of interface arrays in procedural blocks
76
83
  if self.is_interface and node.is_array and node.array_dimensions:
77
84
  # Generate array index string [i0][i1]... for the intermediate signal
78
85
  array_idx = "".join(f"[i{i}]" for i in range(len(node.array_dimensions)))
86
+ fanin["cpuif_rd_ack"] = f"{node.inst_name}_fanin_ready{array_idx}"
87
+ fanin["cpuif_rd_err"] = f"{node.inst_name}_fanin_err{array_idx}"
79
88
  fanin["cpuif_rd_data"] = f"{node.inst_name}_fanin_data{array_idx}"
80
89
  else:
90
+ fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
91
+ fanin["cpuif_rd_err"] = self.signal("PSLVERR", node, "i")
81
92
  fanin["cpuif_rd_data"] = self.signal("PRDATA", node, "i")
82
93
 
83
94
  return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
@@ -53,22 +53,32 @@ class APB3CpuifFlat(BaseCpuif):
53
53
 
54
54
  return "\n".join(f"assign {kv[0]} = {kv[1]};" for kv in fanout.items())
55
55
 
56
- def fanin(self, node: AddressableNode | None = None) -> str:
56
+ def fanin_wr(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
57
57
  fanin: dict[str, str] = {}
58
58
  if node is None:
59
- fanin["cpuif_rd_ack"] = "'0"
60
- fanin["cpuif_rd_err"] = "'0"
59
+ fanin["cpuif_wr_ack"] = "'0"
60
+ fanin["cpuif_wr_err"] = "'0"
61
+ if error:
62
+ fanin["cpuif_wr_ack"] = "'1"
63
+ fanin["cpuif_wr_err"] = "cpuif_wr_sel.cpuif_err"
61
64
  else:
62
- fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
63
- fanin["cpuif_rd_err"] = self.signal("PSLVERR", node, "i")
65
+ fanin["cpuif_wr_ack"] = self.signal("PREADY", node, "i")
66
+ fanin["cpuif_wr_err"] = self.signal("PSLVERR", node, "i")
64
67
 
65
68
  return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
66
69
 
67
- def readback(self, node: AddressableNode | None = None) -> str:
70
+ def fanin_rd(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
68
71
  fanin: dict[str, str] = {}
69
72
  if node is None:
73
+ fanin["cpuif_rd_ack"] = "'0"
74
+ fanin["cpuif_rd_err"] = "'0"
70
75
  fanin["cpuif_rd_data"] = "'0"
76
+ if error:
77
+ fanin["cpuif_rd_ack"] = "'1"
78
+ fanin["cpuif_rd_err"] = "cpuif_rd_sel.cpuif_err"
71
79
  else:
80
+ fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
81
+ fanin["cpuif_rd_err"] = self.signal("PSLVERR", node, "i")
72
82
  fanin["cpuif_rd_data"] = self.signal("PRDATA", node, "i")
73
83
 
74
84
  return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
@@ -19,8 +19,8 @@ assign cpuif_rd_addr = {{cpuif.signal("PADDR")}};
19
19
  assign cpuif_wr_data = {{cpuif.signal("PWDATA")}};
20
20
 
21
21
  assign {{cpuif.signal("PRDATA")}} = cpuif_rd_data;
22
- assign {{cpuif.signal("PREADY")}} = cpuif_rd_ack;
23
- assign {{cpuif.signal("PSLVERR")}} = cpuif_rd_err | cpuif_rd_sel.cpuif_err | cpuif_wr_sel.cpuif_err;
22
+ assign {{cpuif.signal("PREADY")}} = cpuif_rd_ack | cpuif_wr_ack;
23
+ assign {{cpuif.signal("PSLVERR")}} = cpuif_rd_err | cpuif_wr_err;
24
24
 
25
25
  //--------------------------------------------------------------------------
26
26
  // Fanout CPU Bus interface signals
@@ -50,37 +50,49 @@ class APB4Cpuif(BaseCpuif):
50
50
 
51
51
  return "\n".join(f"assign {kv[0]} = {kv[1]};" for kv in fanout.items())
52
52
 
53
- def fanin(self, node: AddressableNode | None = None) -> str:
53
+ def fanin_wr(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
54
54
  fanin: dict[str, str] = {}
55
55
  if node is None:
56
- fanin["cpuif_rd_ack"] = "'0"
57
- fanin["cpuif_rd_err"] = "'0"
56
+ fanin["cpuif_wr_ack"] = "'0"
57
+ fanin["cpuif_wr_err"] = "'0"
58
+ if error:
59
+ fanin["cpuif_wr_ack"] = "'1"
60
+ fanin["cpuif_wr_err"] = "cpuif_wr_sel.cpuif_err"
58
61
  else:
59
62
  # Use intermediate signals for interface arrays to avoid
60
63
  # non-constant indexing of interface arrays in procedural blocks
61
64
  if self.is_interface and node.is_array and node.array_dimensions:
62
65
  # Generate array index string [i0][i1]... for the intermediate signal
63
66
  array_idx = "".join(f"[i{i}]" for i in range(len(node.array_dimensions)))
64
- fanin["cpuif_rd_ack"] = f"{node.inst_name}_fanin_ready{array_idx}"
65
- fanin["cpuif_rd_err"] = f"{node.inst_name}_fanin_err{array_idx}"
67
+ fanin["cpuif_wr_ack"] = f"{node.inst_name}_fanin_ready{array_idx}"
68
+ fanin["cpuif_wr_err"] = f"{node.inst_name}_fanin_err{array_idx}"
66
69
  else:
67
- fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
68
- fanin["cpuif_rd_err"] = self.signal("PSLVERR", node, "i")
70
+ fanin["cpuif_wr_ack"] = self.signal("PREADY", node, "i")
71
+ fanin["cpuif_wr_err"] = self.signal("PSLVERR", node, "i")
69
72
 
70
73
  return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
71
74
 
72
- def readback(self, node: AddressableNode | None = None) -> str:
75
+ def fanin_rd(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
73
76
  fanin: dict[str, str] = {}
74
77
  if node is None:
78
+ fanin["cpuif_rd_ack"] = "'0"
79
+ fanin["cpuif_rd_err"] = "'0"
75
80
  fanin["cpuif_rd_data"] = "'0"
81
+ if error:
82
+ fanin["cpuif_rd_ack"] = "'1"
83
+ fanin["cpuif_rd_err"] = "cpuif_rd_sel.cpuif_err"
76
84
  else:
77
85
  # Use intermediate signals for interface arrays to avoid
78
86
  # non-constant indexing of interface arrays in procedural blocks
79
87
  if self.is_interface and node.is_array and node.array_dimensions:
80
88
  # Generate array index string [i0][i1]... for the intermediate signal
81
89
  array_idx = "".join(f"[i{i}]" for i in range(len(node.array_dimensions)))
90
+ fanin["cpuif_rd_ack"] = f"{node.inst_name}_fanin_ready{array_idx}"
91
+ fanin["cpuif_rd_err"] = f"{node.inst_name}_fanin_err{array_idx}"
82
92
  fanin["cpuif_rd_data"] = f"{node.inst_name}_fanin_data{array_idx}"
83
93
  else:
94
+ fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
95
+ fanin["cpuif_rd_err"] = self.signal("PSLVERR", node, "i")
84
96
  fanin["cpuif_rd_data"] = self.signal("PRDATA", node, "i")
85
97
 
86
98
  return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
@@ -55,22 +55,31 @@ class APB4CpuifFlat(BaseCpuif):
55
55
 
56
56
  return "\n".join(f"assign {kv[0]} = {kv[1]};" for kv in fanout.items())
57
57
 
58
- def fanin(self, node: AddressableNode | None = None) -> str:
58
+ def fanin_wr(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
59
59
  fanin: dict[str, str] = {}
60
60
  if node is None:
61
- fanin["cpuif_rd_ack"] = "'0"
62
- fanin["cpuif_rd_err"] = "'0"
61
+ fanin["cpuif_wr_ack"] = "'0"
62
+ fanin["cpuif_wr_err"] = "'0"
63
+ if error:
64
+ fanin["cpuif_wr_ack"] = "'1"
65
+ fanin["cpuif_wr_err"] = "cpuif_wr_sel.cpuif_err"
63
66
  else:
64
- fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
65
- fanin["cpuif_rd_err"] = self.signal("PSLVERR", node, "i")
66
-
67
+ fanin["cpuif_wr_ack"] = self.signal("PREADY", node, "i")
68
+ fanin["cpuif_wr_err"] = self.signal("PSLVERR", node, "i")
67
69
  return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
68
70
 
69
- def readback(self, node: AddressableNode | None = None) -> str:
71
+ def fanin_rd(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
70
72
  fanin: dict[str, str] = {}
71
73
  if node is None:
74
+ fanin["cpuif_rd_ack"] = "'0"
75
+ fanin["cpuif_rd_err"] = "'0"
72
76
  fanin["cpuif_rd_data"] = "'0"
77
+ if error:
78
+ fanin["cpuif_rd_ack"] = "'1"
79
+ fanin["cpuif_rd_err"] = "cpuif_rd_sel.cpuif_err"
73
80
  else:
81
+ fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i")
82
+ fanin["cpuif_rd_err"] = self.signal("PSLVERR", node, "i")
74
83
  fanin["cpuif_rd_data"] = self.signal("PRDATA", node, "i")
75
84
 
76
85
  return "\n".join(f"{kv[0]} = {kv[1]};" for kv in fanin.items())
@@ -20,8 +20,8 @@ assign cpuif_wr_data = {{cpuif.signal("PWDATA")}};
20
20
  assign cpuif_wr_byte_en = {{cpuif.signal("PSTRB")}};
21
21
 
22
22
  assign {{cpuif.signal("PRDATA")}} = cpuif_rd_data;
23
- assign {{cpuif.signal("PREADY")}} = cpuif_rd_ack;
24
- assign {{cpuif.signal("PSLVERR")}} = cpuif_rd_err | cpuif_rd_sel.cpuif_err | cpuif_wr_sel.cpuif_err;
23
+ assign {{cpuif.signal("PREADY")}} = cpuif_rd_ack | cpuif_wr_ack;
24
+ assign {{cpuif.signal("PSLVERR")}} = cpuif_rd_err | cpuif_wr_err;
25
25
 
26
26
  //--------------------------------------------------------------------------
27
27
  // Fanout CPU Bus interface signals
@@ -63,38 +63,50 @@ class AXI4LiteCpuif(BaseCpuif):
63
63
 
64
64
  return "\n".join(f"assign {lhs} = {rhs};" for lhs, rhs in fanout.items())
65
65
 
66
- def fanin(self, node: AddressableNode | None = None) -> str:
66
+ def fanin_wr(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
67
67
  fanin: dict[str, str] = {}
68
68
  if node is None:
69
- fanin["cpuif_rd_ack"] = "'0"
70
- fanin["cpuif_rd_err"] = "'0"
69
+ fanin["cpuif_wr_ack"] = "'0"
70
+ fanin["cpuif_wr_err"] = "'0"
71
+ if error:
72
+ fanin["cpuif_wr_ack"] = "'1"
73
+ fanin["cpuif_wr_err"] = "cpuif_wr_sel.cpuif_err"
71
74
  else:
72
75
  # Use intermediate signals for interface arrays to avoid
73
76
  # non-constant indexing of interface arrays in procedural blocks
74
77
  if self.is_interface and node.is_array and node.array_dimensions:
75
78
  # Generate array index string [i0][i1]... for the intermediate signal
76
79
  array_idx = "".join(f"[i{i}]" for i in range(len(node.array_dimensions)))
77
- fanin["cpuif_rd_ack"] = f"{node.inst_name}_fanin_ready{array_idx}"
78
- fanin["cpuif_rd_err"] = f"{node.inst_name}_fanin_err{array_idx}"
80
+ fanin["cpuif_wr_ack"] = f"{node.inst_name}_fanin_ready{array_idx}"
81
+ fanin["cpuif_wr_err"] = f"{node.inst_name}_fanin_err{array_idx}"
79
82
  else:
80
83
  # Read side: ack comes from RVALID; err if RRESP[1] is set (SLVERR/DECERR)
81
- fanin["cpuif_rd_ack"] = self.signal("RVALID", node, "i")
82
- fanin["cpuif_rd_err"] = f"{self.signal('RRESP', node, 'i')}[1]"
84
+ fanin["cpuif_wr_ack"] = self.signal("BVALID", node, "i")
85
+ fanin["cpuif_wr_err"] = f"{self.signal('BRESP', node, 'i')}[1]"
83
86
 
84
87
  return "\n".join(f"{lhs} = {rhs};" for lhs, rhs in fanin.items())
85
88
 
86
- def readback(self, node: AddressableNode | None = None) -> str:
89
+ def fanin_rd(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
87
90
  fanin: dict[str, str] = {}
88
91
  if node is None:
92
+ fanin["cpuif_rd_ack"] = "'0"
93
+ fanin["cpuif_rd_err"] = "'0"
89
94
  fanin["cpuif_rd_data"] = "'0"
95
+ if error:
96
+ fanin["cpuif_rd_ack"] = "'1"
97
+ fanin["cpuif_rd_err"] = "cpuif_rd_sel.cpuif_err"
90
98
  else:
91
99
  # Use intermediate signals for interface arrays to avoid
92
100
  # non-constant indexing of interface arrays in procedural blocks
93
101
  if self.is_interface and node.is_array and node.array_dimensions:
94
102
  # Generate array index string [i0][i1]... for the intermediate signal
95
103
  array_idx = "".join(f"[i{i}]" for i in range(len(node.array_dimensions)))
104
+ fanin["cpuif_rd_ack"] = f"{node.inst_name}_fanin_ready{array_idx}"
105
+ fanin["cpuif_rd_err"] = f"{node.inst_name}_fanin_err{array_idx}"
96
106
  fanin["cpuif_rd_data"] = f"{node.inst_name}_fanin_data{array_idx}"
97
107
  else:
108
+ fanin["cpuif_rd_ack"] = self.signal("RVALID", node, "i")
109
+ fanin["cpuif_rd_err"] = f"{self.signal('RRESP', node, 'i')}[1]"
98
110
  fanin["cpuif_rd_data"] = self.signal("RDATA", node, "i")
99
111
 
100
112
  return "\n".join(f"{lhs} = {rhs};" for lhs, rhs in fanin.items())
@@ -72,23 +72,33 @@ class AXI4LiteCpuifFlat(BaseCpuif):
72
72
 
73
73
  return "\n".join(f"assign {lhs} = {rhs};" for lhs, rhs in fanout.items())
74
74
 
75
- def fanin(self, node: AddressableNode | None = None) -> str:
75
+ def fanin_wr(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
76
76
  fanin: dict[str, str] = {}
77
77
  if node is None:
78
- fanin["cpuif_rd_ack"] = "'0"
79
- fanin["cpuif_rd_err"] = "'0"
78
+ fanin["cpuif_wr_ack"] = "'0"
79
+ fanin["cpuif_wr_err"] = "'0"
80
+ if error:
81
+ fanin["cpuif_wr_ack"] = "'1"
82
+ fanin["cpuif_wr_err"] = "cpuif_wr_sel.cpuif_err"
80
83
  else:
81
84
  # Read side: ack comes from RVALID; err if RRESP[1] is set (SLVERR/DECERR)
82
- fanin["cpuif_rd_ack"] = self.signal("RVALID", node, "i")
83
- fanin["cpuif_rd_err"] = f"{self.signal('RRESP', node, 'i')}[1]"
85
+ fanin["cpuif_wr_ack"] = self.signal("BVALID", node, "i")
86
+ fanin["cpuif_wr_err"] = f"{self.signal('BRESP', node, 'i')}[1]"
84
87
 
85
88
  return "\n".join(f"{lhs} = {rhs};" for lhs, rhs in fanin.items())
86
89
 
87
- def readback(self, node: AddressableNode | None = None) -> str:
90
+ def fanin_rd(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
88
91
  fanin: dict[str, str] = {}
89
92
  if node is None:
93
+ fanin["cpuif_rd_ack"] = "'0"
94
+ fanin["cpuif_rd_err"] = "'0"
90
95
  fanin["cpuif_rd_data"] = "'0"
96
+ if error:
97
+ fanin["cpuif_rd_ack"] = "'1"
98
+ fanin["cpuif_rd_err"] = "cpuif_rd_sel.cpuif_err"
91
99
  else:
100
+ fanin["cpuif_rd_ack"] = self.signal("RVALID", node, "i")
101
+ fanin["cpuif_rd_err"] = f"{self.signal('RRESP', node, 'i')}[1]"
92
102
  fanin["cpuif_rd_data"] = self.signal("RDATA", node, "i")
93
103
 
94
104
  return "\n".join(f"{lhs} = {rhs};" for lhs, rhs in fanin.items())
@@ -110,10 +110,10 @@ class BaseCpuif:
110
110
  def fanout(self, node: AddressableNode, array_stack: deque[int]) -> str:
111
111
  raise NotImplementedError
112
112
 
113
- def fanin(self, node: AddressableNode | None = None) -> str:
113
+ def fanin_wr(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
114
114
  raise NotImplementedError
115
115
 
116
- def readback(self, node: AddressableNode | None = None) -> str:
116
+ def fanin_rd(self, node: AddressableNode | None = None, *, error: bool = False) -> str:
117
117
  raise NotImplementedError
118
118
 
119
119
  def fanin_intermediate_assignments(
@@ -20,8 +20,8 @@ class FaninGenerator(BusDecoderListener):
20
20
 
21
21
  self._stack: deque[Body] = deque()
22
22
  cb = CombinationalBody()
23
- cb += cpuif.fanin()
24
- cb += cpuif.readback()
23
+ cb += cpuif.fanin_wr()
24
+ cb += cpuif.fanin_rd()
25
25
  self._stack.append(cb)
26
26
 
27
27
  def enter_AddressableComponent(self, node: AddressableNode) -> WalkerAction | None:
@@ -48,15 +48,13 @@ class FaninGenerator(BusDecoderListener):
48
48
  self._stack.append(fb)
49
49
 
50
50
  ifb = IfBody()
51
- with ifb.cm(
52
- f"cpuif_rd_sel.{get_indexed_path(self._cpuif.exp.ds.top_node, node)} || cpuif_wr_sel.{get_indexed_path(self._cpuif.exp.ds.top_node, node)}"
53
- ) as b:
54
- b += self._cpuif.fanin(node)
51
+ with ifb.cm(f"cpuif_wr_sel.{get_indexed_path(self._cpuif.exp.ds.top_node, node)}") as b:
52
+ b += self._cpuif.fanin_wr(node)
55
53
  self._stack[-1] += ifb
56
54
 
57
55
  ifb = IfBody()
58
56
  with ifb.cm(f"cpuif_rd_sel.{get_indexed_path(self._cpuif.exp.ds.top_node, node)}") as b:
59
- b += self._cpuif.readback(node)
57
+ b += self._cpuif.fanin_rd(node)
60
58
  self._stack[-1] += ifb
61
59
 
62
60
  return action
@@ -72,4 +70,14 @@ class FaninGenerator(BusDecoderListener):
72
70
  super().exit_AddressableComponent(node)
73
71
 
74
72
  def __str__(self) -> str:
73
+ wr_ifb = IfBody()
74
+ with wr_ifb.cm("cpuif_wr_sel.cpuif_err") as b:
75
+ self._cpuif.fanin_wr(error=True)
76
+ self._stack[-1] += wr_ifb
77
+
78
+ rd_ifb = IfBody()
79
+ with rd_ifb.cm("cpuif_rd_sel.cpuif_err") as b:
80
+ self._cpuif.fanin_rd(error=True)
81
+ self._stack[-1] += rd_ifb
82
+
75
83
  return "\n".join(map(str, self._stack))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: peakrdl-busdecoder
3
- Version: 0.6.5
3
+ Version: 0.6.6
4
4
  Summary: Generate a SystemVerilog bus decoder from SystemRDL for splitting CPU interfaces to multiple sub-address spaces
5
5
  Author: Arnav Sacheti
6
6
  License: LGPLv3
@@ -311,6 +311,9 @@ dependencies = [
311
311
  { name = "scapy" },
312
312
  ]
313
313
  sdist = { url = "https://files.pythonhosted.org/packages/4e/f9/1474d5503af6f8c979a33e3489c0e6886b6ffb1af3d00419d2e0da1dd274/cocotb_bus-0.3.0.tar.gz", hash = "sha256:9762b29273ff062f52160e57274e3cb106d14e7e776515de1372c1d73546b005", size = 29991, upload-time = "2025-11-22T00:19:31.734Z" }
314
+ wheels = [
315
+ { url = "https://files.pythonhosted.org/packages/ea/43/8b3f96cf401c2a7f6e907ccc86d3b73433eeaf5525df90b630d8c112474b/cocotb_bus-0.3.0-py3-none-any.whl", hash = "sha256:b4f06cce2462a8f9487b42c46b0ff3afd253f0fa4f67a0c382ebe0ba614229eb", size = 36206, upload-time = "2026-01-15T04:51:43.009Z" },
316
+ ]
314
317
 
315
318
  [[package]]
316
319
  name = "colorama"
@@ -655,7 +658,7 @@ wheels = [
655
658
 
656
659
  [[package]]
657
660
  name = "peakrdl-busdecoder"
658
- version = "0.6.5"
661
+ version = "0.6.6"
659
662
  source = { editable = "." }
660
663
  dependencies = [
661
664
  { name = "jinja2" },