cocotbext-ral 0.5.2__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 (46) hide show
  1. cocotbext_ral-0.5.2/LICENSE +21 -0
  2. cocotbext_ral-0.5.2/MANIFEST.in +3 -0
  3. cocotbext_ral-0.5.2/PKG-INFO +211 -0
  4. cocotbext_ral-0.5.2/README.md +177 -0
  5. cocotbext_ral-0.5.2/cocotbext/ral/__init__.py +22 -0
  6. cocotbext_ral-0.5.2/cocotbext/ral/access_policy.py +66 -0
  7. cocotbext_ral-0.5.2/cocotbext/ral/adapters/__init__.py +6 -0
  8. cocotbext_ral-0.5.2/cocotbext/ral/adapters/json_loader.py +133 -0
  9. cocotbext_ral-0.5.2/cocotbext/ral/adapters/rdl_loader.py +144 -0
  10. cocotbext_ral-0.5.2/cocotbext/ral/backdoor.py +67 -0
  11. cocotbext_ral-0.5.2/cocotbext/ral/checker.py +75 -0
  12. cocotbext_ral-0.5.2/cocotbext/ral/codegen.py +172 -0
  13. cocotbext_ral-0.5.2/cocotbext/ral/debug.py +32 -0
  14. cocotbext_ral-0.5.2/cocotbext/ral/experimental.py +22 -0
  15. cocotbext_ral-0.5.2/cocotbext/ral/integrated_runtime_ral.py +321 -0
  16. cocotbext_ral-0.5.2/cocotbext/ral/monitor.py +208 -0
  17. cocotbext_ral-0.5.2/cocotbext/ral/register_model.py +491 -0
  18. cocotbext_ral-0.5.2/cocotbext/ral/rmw_policy.py +54 -0
  19. cocotbext_ral-0.5.2/cocotbext/ral/runtime_predictor.py +133 -0
  20. cocotbext_ral-0.5.2/cocotbext/ral/runtime_ral.py +843 -0
  21. cocotbext_ral-0.5.2/cocotbext/ral/safe_runtime_ral.py +53 -0
  22. cocotbext_ral-0.5.2/cocotbext/ral/state.py +130 -0
  23. cocotbext_ral-0.5.2/cocotbext/ral/transaction_logger.py +494 -0
  24. cocotbext_ral-0.5.2/cocotbext/ral/version.py +1 -0
  25. cocotbext_ral-0.5.2/cocotbext/ral/volatile_policy.py +36 -0
  26. cocotbext_ral-0.5.2/cocotbext_ral.egg-info/PKG-INFO +211 -0
  27. cocotbext_ral-0.5.2/cocotbext_ral.egg-info/SOURCES.txt +44 -0
  28. cocotbext_ral-0.5.2/cocotbext_ral.egg-info/dependency_links.txt +1 -0
  29. cocotbext_ral-0.5.2/cocotbext_ral.egg-info/requires.txt +13 -0
  30. cocotbext_ral-0.5.2/cocotbext_ral.egg-info/top_level.txt +1 -0
  31. cocotbext_ral-0.5.2/pyproject.toml +43 -0
  32. cocotbext_ral-0.5.2/setup.cfg +4 -0
  33. cocotbext_ral-0.5.2/tests/test_access_policies.py +45 -0
  34. cocotbext_ral-0.5.2/tests/test_backdoor.py +125 -0
  35. cocotbext_ral-0.5.2/tests/test_checker.py +92 -0
  36. cocotbext_ral-0.5.2/tests/test_debug.py +80 -0
  37. cocotbext_ral-0.5.2/tests/test_json_loader.py +116 -0
  38. cocotbext_ral-0.5.2/tests/test_model_search.py +180 -0
  39. cocotbext_ral-0.5.2/tests/test_register_model.py +177 -0
  40. cocotbext_ral-0.5.2/tests/test_rmw_policy.py +100 -0
  41. cocotbext_ral-0.5.2/tests/test_runtime_predictor.py +38 -0
  42. cocotbext_ral-0.5.2/tests/test_runtime_predictor_comprehensive.py +254 -0
  43. cocotbext_ral-0.5.2/tests/test_runtime_ral.py +92 -0
  44. cocotbext_ral-0.5.2/tests/test_state.py +161 -0
  45. cocotbext_ral-0.5.2/tests/test_transaction_logger.py +303 -0
  46. cocotbext_ral-0.5.2/tests/test_volatile_policy.py +73 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 cocotbext-ral contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,3 @@
1
+ include LICENSE
2
+ include README.md
3
+ recursive-include cocotbext *.py
@@ -0,0 +1,211 @@
1
+ Metadata-Version: 2.4
2
+ Name: cocotbext-ral
3
+ Version: 0.5.2
4
+ Summary: Python-native Register Abstraction Layer (RAL) for cocotb with a data-driven runtime architecture
5
+ License-Expression: MIT
6
+ Project-URL: Homepage, https://github.com/stephencoTT/cocotbext-ral
7
+ Project-URL: Issues, https://github.com/stephencoTT/cocotbext-ral/issues
8
+ Keywords: cocotb,ral,register model,verification,eda
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Framework :: cocotb
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)
21
+ Requires-Python: >=3.9
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Provides-Extra: cocotb
25
+ Requires-Dist: cocotb>=1.8.0; extra == "cocotb"
26
+ Requires-Dist: cocotbext-axi>=0.1.16; extra == "cocotb"
27
+ Provides-Extra: rdl
28
+ Requires-Dist: systemrdl-compiler>=1.15; extra == "rdl"
29
+ Provides-Extra: dev
30
+ Requires-Dist: pytest>=7.0; extra == "dev"
31
+ Provides-Extra: all
32
+ Requires-Dist: cocotbext-ral[cocotb,dev,rdl]; extra == "all"
33
+ Dynamic: license-file
34
+
35
+ # cocotbext-ral
36
+
37
+ A Python-native Register Abstraction Layer (RAL) for [cocotb](https://www.cocotb.org/).
38
+
39
+ `cocotbext-ral` provides UVM-like register modeling, access-type-aware prediction, and automated checking -- all in pure Python, designed for cocotb hardware verification.
40
+
41
+ ## Features
42
+
43
+ - **Runtime-backed architecture** with clean separation of register spec vs mutable state
44
+ - **Full access-type coverage**: RW, RO, WO, W1C, W1S, RCLR, RSET
45
+ - **Smart volatile inference**: RO, RCLR, RSET fields default to volatile (overridable)
46
+ - **Safe field writes** that reject unsafe read-modify-write sequences
47
+ - **Backdoor resolution** that scales to replicated blocks and chiplets
48
+ - **Transaction logging** with detailed per-transaction file output
49
+ - **Pure-Python core** -- model, predictor, and policies work without cocotb
50
+
51
+ ## Architecture
52
+
53
+ ```
54
+ RegisterModel (spec)
55
+ |
56
+ RuntimeState (per-instance mutable state)
57
+ |
58
+ RuntimePredictor + AccessPolicy
59
+ |
60
+ RuntimeRAL -> SafeRuntimeRAL -> IntegratedRuntimeRAL
61
+ | |
62
+ Backdoor Transaction Log
63
+ ```
64
+
65
+ ## Installation
66
+
67
+ ```bash
68
+ pip install cocotbext-ral
69
+ ```
70
+
71
+ Optional extras:
72
+
73
+ ```bash
74
+ pip install cocotbext-ral[cocotb] # cocotb + cocotbext-axi
75
+ pip install cocotbext-ral[rdl] # SystemRDL compiler
76
+ pip install cocotbext-ral[all] # Everything
77
+ ```
78
+
79
+ ## Quick start
80
+
81
+ ### With cocotb simulation
82
+
83
+ ```python
84
+ import cocotb
85
+ from cocotbext.axi import AxiLiteMaster, AxiLiteBus
86
+ from cocotbext.ral import IntegratedRuntimeRAL
87
+ from cocotbext.ral.adapters import load_json
88
+
89
+ @cocotb.test()
90
+ async def test_registers(dut):
91
+ model = load_json("registers.json")
92
+
93
+ ral = IntegratedRuntimeRAL("my_ip", model, dut_handle=dut, txn_log=True)
94
+ master = AxiLiteMaster(AxiLiteBus.from_prefix(dut, "s_axil"), dut.clk, dut.rst)
95
+ ral.attach_master(master, protocol="axil", interface="dut.s_axil")
96
+
97
+ # Write and read with automatic prediction checking
98
+ await ral.write("CTRL", 0x01)
99
+ val = await ral.read("CTRL")
100
+
101
+ # Field-level access with RMW safety
102
+ await ral.write_field("CTRL", "enable", 1)
103
+ en = await ral.read_field("CTRL", "enable")
104
+
105
+ # Check results
106
+ ral.raise_on_errors()
107
+ ral.close_txn_log()
108
+ ```
109
+
110
+ ### Standalone (no cocotb)
111
+
112
+ The core model, predictor, and policy layers have zero dependencies:
113
+
114
+ ```python
115
+ from cocotbext.ral import RegisterModel, Register, RegisterField, SwAccess
116
+ from cocotbext.ral.runtime_predictor import RuntimePredictor
117
+
118
+ model = RegisterModel("my_ip")
119
+ reg = Register("CTRL", address=0x0, size_bits=32, fields=[
120
+ RegisterField("enable", lsb=0, msb=0, reset_value=0, sw_access=SwAccess.RW),
121
+ RegisterField("irq", lsb=8, msb=15, reset_value=0xFF, sw_access=SwAccess.W1C),
122
+ ])
123
+ model.add_register(reg, hierarchical_name="block.CTRL")
124
+
125
+ pred = RuntimePredictor(model)
126
+ pred.predict_write(0x0, 0x01)
127
+ result = pred.predict_read(0x0, 0x01)
128
+ assert result.passed
129
+ ```
130
+
131
+ ## API classes
132
+
133
+ | Class | Description |
134
+ |---|---|
135
+ | `IntegratedRuntimeRAL` | **Recommended.** Runtime state + RMW safety + backdoor + transaction log |
136
+ | `SafeRuntimeRAL` | Runtime state + RMW safety checks |
137
+ | `RuntimeRAL` | Runtime state-backed prediction |
138
+ | `RuntimePredictor` | Standalone prediction engine (no cocotb needed) |
139
+ | `RuntimeState` | Per-instance mutable register state |
140
+ | `AccessPolicy` | Per-field read/write behavior |
141
+ | `TransactionLogger` | Detailed file-based transaction logging |
142
+ | `BackdoorResolver` | HDL path resolution (base, Prefix, Mapping variants) |
143
+ | `RegisterModel` | Structural register specification |
144
+
145
+ ## Register loading
146
+
147
+ ```python
148
+ from cocotbext.ral.adapters import load_json, load_rdl
149
+
150
+ model = load_json("registers.json") # RDL-generated JSON
151
+ model = load_rdl("regs.rdl", top_name="my_ip", incdir=[]) # SystemRDL source
152
+ ```
153
+
154
+ ## Access types
155
+
156
+ | SwAccess | Write behavior | Read behavior | Volatile by default |
157
+ |---|---|---|---|
158
+ | `RW` | Update value | Check prediction | No |
159
+ | `RO` | Ignored | Not checked | Yes |
160
+ | `WO` | Update value | Not checked | No |
161
+ | `W1C` | Clear written-1 bits | Check prediction | No |
162
+ | `W1S` | Set written-1 bits | Check prediction | No |
163
+ | `RCLR` | Ignored | Clears to 0 after read | Yes |
164
+ | `RSET` | Ignored | Sets to all-1s after read | Yes |
165
+
166
+ Aliases: `WOCLR`=`W1C`, `WOSET`=`W1S`, `RC`=`RCLR`, `RS`=`RSET`
167
+
168
+ ## Transaction logging
169
+
170
+ Enable detailed per-transaction file output:
171
+
172
+ ```python
173
+ # Default filename (register_txns.log)
174
+ ral = IntegratedRuntimeRAL("ip", model, txn_log=True)
175
+
176
+ # Custom path
177
+ ral = IntegratedRuntimeRAL("ip", model, txn_log="my_regs.log")
178
+
179
+ # Phase annotations
180
+ ral.set_txn_phase("Phase 1: Reset value check")
181
+ await ral.write(addr, value)
182
+
183
+ # Summary and close
184
+ ral.close_txn_log()
185
+ ```
186
+
187
+ Each transaction entry includes: model path, address, data, protocol, interface HDL path, status (PASS/FAIL/SKIP), mirror state, per-field breakdown, and RMW safety assessment.
188
+
189
+ ## Testing
190
+
191
+ ```bash
192
+ pip install -e .[dev]
193
+ pytest
194
+ ```
195
+
196
+ 146 tests covering: register model (including search / group helpers), runtime predictor (all access types), access policies, RMW safety, backdoor resolvers, runtime state, volatile policy, debug helpers, checker, JSON loader, transaction logger, and RuntimeRAL construction / reset / check-toggle helpers.
197
+
198
+ ## Documentation
199
+
200
+ Read in this order:
201
+
202
+ 1. [Quick Start](docs/START_GUIDE.md) -- 10-step walkthrough covering all access types and the common flows.
203
+ 2. [Architecture](docs/ARCHITECTURE.md) -- layer-by-layer design and the rationale behind each decision.
204
+ 3. API reference (pick what you need):
205
+ - [Core Model](docs/api/CORE_MODEL.md) -- `RegisterModel`, `Register`, `RegisterField`, `SwAccess`.
206
+ - [Runtime API](docs/api/RUNTIME_API.md) -- `IntegratedRuntimeRAL`, `SafeRuntimeRAL`, mirror update modes, RMW logging, search / bulk APIs.
207
+ - [Integration and Loaders](docs/api/INTEGRATION_AND_LOADERS.md) -- JSON/RDL loaders, backdoor resolvers, transaction logging.
208
+
209
+ ## License
210
+
211
+ MIT
@@ -0,0 +1,177 @@
1
+ # cocotbext-ral
2
+
3
+ A Python-native Register Abstraction Layer (RAL) for [cocotb](https://www.cocotb.org/).
4
+
5
+ `cocotbext-ral` provides UVM-like register modeling, access-type-aware prediction, and automated checking -- all in pure Python, designed for cocotb hardware verification.
6
+
7
+ ## Features
8
+
9
+ - **Runtime-backed architecture** with clean separation of register spec vs mutable state
10
+ - **Full access-type coverage**: RW, RO, WO, W1C, W1S, RCLR, RSET
11
+ - **Smart volatile inference**: RO, RCLR, RSET fields default to volatile (overridable)
12
+ - **Safe field writes** that reject unsafe read-modify-write sequences
13
+ - **Backdoor resolution** that scales to replicated blocks and chiplets
14
+ - **Transaction logging** with detailed per-transaction file output
15
+ - **Pure-Python core** -- model, predictor, and policies work without cocotb
16
+
17
+ ## Architecture
18
+
19
+ ```
20
+ RegisterModel (spec)
21
+ |
22
+ RuntimeState (per-instance mutable state)
23
+ |
24
+ RuntimePredictor + AccessPolicy
25
+ |
26
+ RuntimeRAL -> SafeRuntimeRAL -> IntegratedRuntimeRAL
27
+ | |
28
+ Backdoor Transaction Log
29
+ ```
30
+
31
+ ## Installation
32
+
33
+ ```bash
34
+ pip install cocotbext-ral
35
+ ```
36
+
37
+ Optional extras:
38
+
39
+ ```bash
40
+ pip install cocotbext-ral[cocotb] # cocotb + cocotbext-axi
41
+ pip install cocotbext-ral[rdl] # SystemRDL compiler
42
+ pip install cocotbext-ral[all] # Everything
43
+ ```
44
+
45
+ ## Quick start
46
+
47
+ ### With cocotb simulation
48
+
49
+ ```python
50
+ import cocotb
51
+ from cocotbext.axi import AxiLiteMaster, AxiLiteBus
52
+ from cocotbext.ral import IntegratedRuntimeRAL
53
+ from cocotbext.ral.adapters import load_json
54
+
55
+ @cocotb.test()
56
+ async def test_registers(dut):
57
+ model = load_json("registers.json")
58
+
59
+ ral = IntegratedRuntimeRAL("my_ip", model, dut_handle=dut, txn_log=True)
60
+ master = AxiLiteMaster(AxiLiteBus.from_prefix(dut, "s_axil"), dut.clk, dut.rst)
61
+ ral.attach_master(master, protocol="axil", interface="dut.s_axil")
62
+
63
+ # Write and read with automatic prediction checking
64
+ await ral.write("CTRL", 0x01)
65
+ val = await ral.read("CTRL")
66
+
67
+ # Field-level access with RMW safety
68
+ await ral.write_field("CTRL", "enable", 1)
69
+ en = await ral.read_field("CTRL", "enable")
70
+
71
+ # Check results
72
+ ral.raise_on_errors()
73
+ ral.close_txn_log()
74
+ ```
75
+
76
+ ### Standalone (no cocotb)
77
+
78
+ The core model, predictor, and policy layers have zero dependencies:
79
+
80
+ ```python
81
+ from cocotbext.ral import RegisterModel, Register, RegisterField, SwAccess
82
+ from cocotbext.ral.runtime_predictor import RuntimePredictor
83
+
84
+ model = RegisterModel("my_ip")
85
+ reg = Register("CTRL", address=0x0, size_bits=32, fields=[
86
+ RegisterField("enable", lsb=0, msb=0, reset_value=0, sw_access=SwAccess.RW),
87
+ RegisterField("irq", lsb=8, msb=15, reset_value=0xFF, sw_access=SwAccess.W1C),
88
+ ])
89
+ model.add_register(reg, hierarchical_name="block.CTRL")
90
+
91
+ pred = RuntimePredictor(model)
92
+ pred.predict_write(0x0, 0x01)
93
+ result = pred.predict_read(0x0, 0x01)
94
+ assert result.passed
95
+ ```
96
+
97
+ ## API classes
98
+
99
+ | Class | Description |
100
+ |---|---|
101
+ | `IntegratedRuntimeRAL` | **Recommended.** Runtime state + RMW safety + backdoor + transaction log |
102
+ | `SafeRuntimeRAL` | Runtime state + RMW safety checks |
103
+ | `RuntimeRAL` | Runtime state-backed prediction |
104
+ | `RuntimePredictor` | Standalone prediction engine (no cocotb needed) |
105
+ | `RuntimeState` | Per-instance mutable register state |
106
+ | `AccessPolicy` | Per-field read/write behavior |
107
+ | `TransactionLogger` | Detailed file-based transaction logging |
108
+ | `BackdoorResolver` | HDL path resolution (base, Prefix, Mapping variants) |
109
+ | `RegisterModel` | Structural register specification |
110
+
111
+ ## Register loading
112
+
113
+ ```python
114
+ from cocotbext.ral.adapters import load_json, load_rdl
115
+
116
+ model = load_json("registers.json") # RDL-generated JSON
117
+ model = load_rdl("regs.rdl", top_name="my_ip", incdir=[]) # SystemRDL source
118
+ ```
119
+
120
+ ## Access types
121
+
122
+ | SwAccess | Write behavior | Read behavior | Volatile by default |
123
+ |---|---|---|---|
124
+ | `RW` | Update value | Check prediction | No |
125
+ | `RO` | Ignored | Not checked | Yes |
126
+ | `WO` | Update value | Not checked | No |
127
+ | `W1C` | Clear written-1 bits | Check prediction | No |
128
+ | `W1S` | Set written-1 bits | Check prediction | No |
129
+ | `RCLR` | Ignored | Clears to 0 after read | Yes |
130
+ | `RSET` | Ignored | Sets to all-1s after read | Yes |
131
+
132
+ Aliases: `WOCLR`=`W1C`, `WOSET`=`W1S`, `RC`=`RCLR`, `RS`=`RSET`
133
+
134
+ ## Transaction logging
135
+
136
+ Enable detailed per-transaction file output:
137
+
138
+ ```python
139
+ # Default filename (register_txns.log)
140
+ ral = IntegratedRuntimeRAL("ip", model, txn_log=True)
141
+
142
+ # Custom path
143
+ ral = IntegratedRuntimeRAL("ip", model, txn_log="my_regs.log")
144
+
145
+ # Phase annotations
146
+ ral.set_txn_phase("Phase 1: Reset value check")
147
+ await ral.write(addr, value)
148
+
149
+ # Summary and close
150
+ ral.close_txn_log()
151
+ ```
152
+
153
+ Each transaction entry includes: model path, address, data, protocol, interface HDL path, status (PASS/FAIL/SKIP), mirror state, per-field breakdown, and RMW safety assessment.
154
+
155
+ ## Testing
156
+
157
+ ```bash
158
+ pip install -e .[dev]
159
+ pytest
160
+ ```
161
+
162
+ 146 tests covering: register model (including search / group helpers), runtime predictor (all access types), access policies, RMW safety, backdoor resolvers, runtime state, volatile policy, debug helpers, checker, JSON loader, transaction logger, and RuntimeRAL construction / reset / check-toggle helpers.
163
+
164
+ ## Documentation
165
+
166
+ Read in this order:
167
+
168
+ 1. [Quick Start](docs/START_GUIDE.md) -- 10-step walkthrough covering all access types and the common flows.
169
+ 2. [Architecture](docs/ARCHITECTURE.md) -- layer-by-layer design and the rationale behind each decision.
170
+ 3. API reference (pick what you need):
171
+ - [Core Model](docs/api/CORE_MODEL.md) -- `RegisterModel`, `Register`, `RegisterField`, `SwAccess`.
172
+ - [Runtime API](docs/api/RUNTIME_API.md) -- `IntegratedRuntimeRAL`, `SafeRuntimeRAL`, mirror update modes, RMW logging, search / bulk APIs.
173
+ - [Integration and Loaders](docs/api/INTEGRATION_AND_LOADERS.md) -- JSON/RDL loaders, backdoor resolvers, transaction logging.
174
+
175
+ ## License
176
+
177
+ MIT
@@ -0,0 +1,22 @@
1
+ """Cocotb Register Abstraction Layer (RAL).
2
+
3
+ Generic, reusable RAL with zero Quasar-specific dependencies.
4
+ """
5
+
6
+ from .version import __version__
7
+ from .register_model import RegisterField, Register, RegisterBlock, RegisterModel, SwAccess, Memory
8
+ from .runtime_predictor import RuntimePredictor, PredictionResult, FieldResult
9
+ from .state import RuntimeState, RegisterState, FieldState
10
+ from .checker import Checker
11
+
12
+ # Runtime-backed RAL APIs.
13
+ from .runtime_ral import RuntimeRAL
14
+ from .safe_runtime_ral import SafeRuntimeRAL
15
+ from .integrated_runtime_ral import IntegratedRuntimeRAL
16
+ from .transaction_logger import TransactionLogger
17
+
18
+ # Cocotb-dependent classes.
19
+ try:
20
+ from .monitor import ApbRalMonitor, AxiLiteRalMonitor, AxiRalMonitor
21
+ except ImportError:
22
+ pass
@@ -0,0 +1,66 @@
1
+ """Field access policy helpers for the runtime path.
2
+
3
+ Supports common SystemRDL-style semantics including RW, RO, WO, W1C, W1S,
4
+ RCLR, and RSET.
5
+ """
6
+
7
+ from dataclasses import dataclass
8
+
9
+ from .register_model import RegisterField, SwAccess
10
+ from .state import FieldState
11
+ from .volatile_policy import check_allowed as _volatile_check_allowed
12
+
13
+
14
+ @dataclass(frozen=True)
15
+ class AccessPolicy:
16
+ """Behavioral policy for a field's software-visible access semantics."""
17
+
18
+ sw_access: SwAccess
19
+
20
+ def apply_write(self, field: RegisterField, state: FieldState, write_value: int) -> None:
21
+ """Apply a software write to runtime field state."""
22
+ value = write_value & field.mask
23
+
24
+ if self.sw_access == SwAccess.RW:
25
+ state.mirrored = value
26
+ elif self.sw_access == SwAccess.WO:
27
+ state.mirrored = value
28
+ elif self.sw_access == SwAccess.W1C:
29
+ state.mirrored &= ~value
30
+ state.mirrored &= field.mask
31
+ elif self.sw_access == SwAccess.W1S:
32
+ state.mirrored |= value
33
+ state.mirrored &= field.mask
34
+ elif self.sw_access in (SwAccess.RO, SwAccess.RCLR, SwAccess.RSET):
35
+ return
36
+
37
+ state.desired = state.mirrored
38
+ state.dirty = False
39
+
40
+ def apply_read_side_effect(self, field: RegisterField, state: FieldState) -> None:
41
+ """Apply any state change caused by reading the field."""
42
+ if self.sw_access == SwAccess.RCLR:
43
+ state.mirrored = 0
44
+ state.desired = 0
45
+ elif self.sw_access == SwAccess.RSET:
46
+ state.mirrored = field.mask
47
+ state.desired = field.mask
48
+
49
+ def check_on_read(self, field: RegisterField, state: FieldState) -> bool:
50
+ """Return True if the field should be checked on reads."""
51
+ if not _volatile_check_allowed(field, state):
52
+ return False
53
+ return self.sw_access in (
54
+ SwAccess.RW,
55
+ SwAccess.W1C,
56
+ SwAccess.W1S,
57
+ SwAccess.RCLR,
58
+ SwAccess.RSET,
59
+ )
60
+
61
+
62
+ class PolicyRegistry:
63
+ """Minimal registry from field spec to runtime policy object."""
64
+
65
+ def policy_for(self, field: RegisterField) -> AccessPolicy:
66
+ return AccessPolicy(field.sw_access)
@@ -0,0 +1,6 @@
1
+ from .json_loader import load_json
2
+
3
+ try:
4
+ from .rdl_loader import load_rdl
5
+ except ImportError:
6
+ pass
@@ -0,0 +1,133 @@
1
+ """Load a RegisterModel from RDL-generated JSON.
2
+
3
+ Parses the hierarchical JSON format produced by create_reg_json.py
4
+ (addrmap -> regfile -> reg -> field) into the RAL RegisterModel.
5
+ """
6
+
7
+ import json
8
+ from typing import Union
9
+ from pathlib import Path
10
+
11
+ from ..register_model import (
12
+ Memory,
13
+ RegisterField,
14
+ Register,
15
+ RegisterBlock,
16
+ RegisterModel,
17
+ SwAccess,
18
+ )
19
+
20
+
21
+ def _map_sw_access(sw_access_str: str, woclr: int) -> SwAccess:
22
+ """Map JSON sw_access string + woclr flag to SwAccess enum."""
23
+ sw = sw_access_str.lower()
24
+ if sw == "rw" and woclr:
25
+ return SwAccess.WOCLR
26
+ if sw == "rw":
27
+ return SwAccess.RW
28
+ if sw == "r":
29
+ return SwAccess.RO
30
+ if sw == "w":
31
+ return SwAccess.WO
32
+ # Default to RW for unknown access types
33
+ return SwAccess.RW
34
+
35
+
36
+ def _parse_node(
37
+ node: dict,
38
+ model: RegisterModel,
39
+ base_address: int,
40
+ name_prefix: str,
41
+ ):
42
+ """Recursively walk the JSON hierarchy, accumulating addresses and names."""
43
+ node_type = node.get("type", "")
44
+ inst_name = node.get("inst_name", "")
45
+ addr_offset = node.get("addr_offset", 0)
46
+ current_address = base_address + addr_offset
47
+
48
+ # Build hierarchical name
49
+ if name_prefix:
50
+ current_name = f"{name_prefix}.{inst_name}"
51
+ else:
52
+ current_name = inst_name
53
+
54
+ if node_type == "reg":
55
+ # Parse fields
56
+ fields = []
57
+ for child in node.get("children", []):
58
+ if child.get("type") == "field":
59
+ reset_val = child.get("reset", 0)
60
+ if not isinstance(reset_val, (int, float)):
61
+ reset_val = 0
62
+ reset_val = int(reset_val)
63
+
64
+ sw_access = _map_sw_access(
65
+ child.get("sw_access", "rw"),
66
+ child.get("woclr", 0),
67
+ )
68
+ field = RegisterField(
69
+ name=child["inst_name"],
70
+ lsb=child["lsb"],
71
+ msb=child["msb"],
72
+ reset_value=reset_val,
73
+ sw_access=sw_access,
74
+ )
75
+ fields.append(field)
76
+
77
+ reg = Register(
78
+ name=inst_name,
79
+ address=current_address,
80
+ size_bits=node.get("regsize", 32),
81
+ fields=fields,
82
+ description=node.get("desc", ""),
83
+ )
84
+ model.add_register(reg, hierarchical_name=current_name)
85
+ return
86
+
87
+ if node_type == "mem":
88
+ # Parse memory regions (SRAM, apertures, FIFOs, etc.)
89
+ memwidth = node.get("memwidth", 32)
90
+ mementries = node.get("mementries", 0)
91
+ size_bytes = (memwidth * mementries) // 8
92
+ mem = Memory(
93
+ name=inst_name,
94
+ base_address=current_address,
95
+ size_bytes=size_bytes,
96
+ description=node.get("desc", ""),
97
+ )
98
+ mem.hierarchical_name = current_name
99
+ model.add_memory(mem, hierarchical_name=current_name)
100
+ return
101
+
102
+ # For addrmap, regfile, or any container: recurse into children
103
+ for child in node.get("children", []):
104
+ child_type = child.get("type", "")
105
+ if child_type in ("addrmap", "regfile", "reg", "mem"):
106
+ _parse_node(child, model, current_address, current_name)
107
+
108
+
109
+ def load_json(
110
+ json_path: Union[str, Path],
111
+ model_name: str = "",
112
+ ) -> RegisterModel:
113
+ """Load a RegisterModel from an RDL-generated JSON file.
114
+
115
+ Args:
116
+ json_path: Path to the JSON register description file.
117
+ model_name: Optional name for the model. Defaults to the root
118
+ inst_name from the JSON.
119
+
120
+ Returns:
121
+ A populated RegisterModel.
122
+ """
123
+ json_path = Path(json_path)
124
+ with open(json_path, "r") as f:
125
+ root = json.load(f)
126
+
127
+ name = model_name or root.get("inst_name", json_path.stem)
128
+ model = RegisterModel(name=name)
129
+
130
+ # The root is typically an addrmap — recurse from there
131
+ _parse_node(root, model, base_address=0, name_prefix="")
132
+
133
+ return model