rggen-systemrdl 0.1.0
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.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +66 -0
- data/lib/rggen/systemrdl/converter/addrmap.rb +49 -0
- data/lib/rggen/systemrdl/converter/base.rb +165 -0
- data/lib/rggen/systemrdl/converter/field.rb +514 -0
- data/lib/rggen/systemrdl/converter/mem.rb +23 -0
- data/lib/rggen/systemrdl/converter/reg.rb +29 -0
- data/lib/rggen/systemrdl/converter/regfile.rb +29 -0
- data/lib/rggen/systemrdl/global/ignore_precedence.rb +27 -0
- data/lib/rggen/systemrdl/loader.rb +21 -0
- data/lib/rggen/systemrdl/version.rb +7 -0
- data/lib/rggen/systemrdl.rb +20 -0
- data/notes/bit_field_type_mapping.md +105 -0
- data/notes/bit_field_type_matrix.md +80 -0
- data/notes/external_reg_regfile_mapping.md +37 -0
- data/notes/interrupt_aggregation_policy.md +50 -0
- data/notes/precedence_handling_policy.md +38 -0
- data/notes/systemrdl_rggen_gap_analysis.md +132 -0
- data/notes/systemrdl_to_rggen_mapping.md +264 -0
- data/notes/systemrdl_to_rggen_todo.md +34 -0
- data/notes/udp_handling_policy.md +181 -0
- metadata +80 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# bit_field type mapping (RgGen type ← SystemRDL field properties)
|
|
2
|
+
|
|
3
|
+
Confirmed mapping from SystemRDL field property combinations to RgGen bit_field types.
|
|
4
|
+
Reference: RgGen RTL templates at
|
|
5
|
+
rggen/rggen-systemverilog `lib/rggen/systemverilog/rtl/bit_field/type`.
|
|
6
|
+
|
|
7
|
+
## Baseline conventions
|
|
8
|
+
- `sw` reaching the converter is one of rw / r / w / rw1 / w1 (sw=na and all invalid sw/hw combos
|
|
9
|
+
in Table 12 are errored by the front-end; see systemrdl notes/implicit_constraints.md).
|
|
10
|
+
- SystemRDL "Error – meaningless" combos and SW-write-loss combos (sw∈{w,rw} & hw∈{w,rw} without
|
|
11
|
+
we/wel) are errored by the front-end; the converter assumes inputs already passed those checks.
|
|
12
|
+
- HW-update principle: RgGen `rw`/`ro`/`wo` (plain storage) have NO hardware update path, so for
|
|
13
|
+
those, hw ∈ {r, na}. Fields where HW writes the value (hw=rw/w) map to HW-input-capable types
|
|
14
|
+
(`rohw`, `row1trg`, ...) or are unrepresentable — never to plain rw/ro/wo.
|
|
15
|
+
- "Other properties not allowed" on a type means: if any property outside that type's listed set
|
|
16
|
+
is present, the field does NOT map to that type (→ another type, or error if none fits).
|
|
17
|
+
|
|
18
|
+
## Type table
|
|
19
|
+
The combinations below list the distinguishing properties per type. Full per-property conditions
|
|
20
|
+
(including which properties must be absent) are in `bit_field_type_matrix.md`; they are not
|
|
21
|
+
repeated here.
|
|
22
|
+
|
|
23
|
+
### Basic access (no side effects)
|
|
24
|
+
| RgGen type | SystemRDL combination | Notes |
|
|
25
|
+
| ---------- | --------------------- | ----- |
|
|
26
|
+
| `rw` | sw=rw, hw∈{r,na} | Plain storage. |
|
|
27
|
+
| `ro` (ext) | sw=r, hw drives value (hw=rw/w) | Value comes from hardware. |
|
|
28
|
+
| `ro` (ref) | sw=r, hw=r/na, `next` = another field | Value comes from the referenced field (`reference` = the `next` target). |
|
|
29
|
+
| `rof` | sw=r, hw=na | Returns fixed `initial_value` (constant). hw=na only (not r). |
|
|
30
|
+
| `wo` | sw=w, hw=r | Write-only storage. |
|
|
31
|
+
| `rohw` | sw=r, hw∈{rw,w}, `we` required (true or another field) | HW value taken in under `we` (valid). |
|
|
32
|
+
| `rwhw` | sw=rw, hw∈{rw,w}, `we` required (true or another field) | read/write version of `rohw`; HW value taken in under `we` (valid). `we` avoids the SW-write-loss error. |
|
|
33
|
+
| `rowo` | — NOT SUPPORTED | Would require merging two fields (sw=r + sw=w) at the same bit position. Bit-field overlap is an ERROR (see below). |
|
|
34
|
+
|
|
35
|
+
### Read side-effect
|
|
36
|
+
| RgGen type | SystemRDL combination | Notes |
|
|
37
|
+
| ---------- | --------------------- | ----- |
|
|
38
|
+
| `rc` | sw=r, onread=rclr, hwset=true | `reference`(mask) NOT specifiable (SystemRDL has no mask). |
|
|
39
|
+
| `rs` | sw=r, onread=rset, hwclr=true | `rs` takes NO reference. |
|
|
40
|
+
| `wrc` | sw=rw, hw∈{r,na}, onread=rclr | |
|
|
41
|
+
| `wrs` | sw=rw, hw∈{r,na}, onread=rset | |
|
|
42
|
+
|
|
43
|
+
### Write side-effect: clear / set / toggle
|
|
44
|
+
Polarity: SystemRDL woclr/woset (write-ONE) → RgGen w1c/w1s; wzc/wzs (write-ZERO) → w0c/w0s;
|
|
45
|
+
wot/wzt (toggle) → w1t/w0t. clear-family needs hwset=true; set-family needs hwclr=true;
|
|
46
|
+
toggle-family takes neither.
|
|
47
|
+
| RgGen type | SystemRDL combination | Notes |
|
|
48
|
+
| ---------- | --------------------- | ----- |
|
|
49
|
+
| `w0c` | sw=rw, hw∈{r,na}, onwrite=wzc, hwset=true | mask NOT specifiable. |
|
|
50
|
+
| `w1c` | sw=rw, hw∈{r,na}, onwrite=woclr, hwset=true | mask NOT specifiable. |
|
|
51
|
+
| `w0s` | sw=rw, hw∈{r,na}, onwrite=wzs, hwclr=true | |
|
|
52
|
+
| `w1s` | sw=rw, hw∈{r,na}, onwrite=woset, hwclr=true | |
|
|
53
|
+
| `w0t` | sw=rw, hw∈{r,na}, onwrite=wzt | |
|
|
54
|
+
| `w1t` | sw=rw, hw∈{r,na}, onwrite=wot | |
|
|
55
|
+
| `wc` | sw=rw, hw∈{r,na}, onwrite=wclr, hwset=true | mask NOT specifiable. |
|
|
56
|
+
| `ws` | sw=rw, hw∈{r,na}, onwrite=wset, hwclr=true | |
|
|
57
|
+
| `woc` | sw=w, hw=r, onwrite=wclr, hwset=true | write-only version of wc. |
|
|
58
|
+
| `wos` | sw=w, hw=r, onwrite=wset, hwclr=true | write-only version of ws. |
|
|
59
|
+
|
|
60
|
+
### Write + read combined (all: sw=rw, hw∈{r,na})
|
|
61
|
+
| RgGen type | SystemRDL combination |
|
|
62
|
+
| ---------- | --------------------- |
|
|
63
|
+
| `w0crs` | onwrite=wzc, onread=rset |
|
|
64
|
+
| `w1crs` | onwrite=woclr, onread=rset |
|
|
65
|
+
| `wcrs` | onwrite=wclr, onread=rset |
|
|
66
|
+
| `w0src` | onwrite=wzs, onread=rclr |
|
|
67
|
+
| `w1src` | onwrite=woset, onread=rclr |
|
|
68
|
+
| `wsrc` | onwrite=wset, onread=rclr |
|
|
69
|
+
|
|
70
|
+
### Read/write with control signal (signal = true → external input; = other field → reference)
|
|
71
|
+
| RgGen type | SystemRDL combination | Notes |
|
|
72
|
+
| ---------- | --------------------- | ----- |
|
|
73
|
+
| `rwl` | sw=rw, swwel (=true or other field) | lock, active-low. |
|
|
74
|
+
| `rwe` | sw=rw, swwe (=true or other field) | enable, active-high. |
|
|
75
|
+
| `rwc` | sw=rw, hw∈{r,na}, hwclr (=true or other field) | clear. |
|
|
76
|
+
| `rws` | sw=rw, hw∈{r,na}, hwset (=true or other field) | set. |
|
|
77
|
+
|
|
78
|
+
### Trigger output
|
|
79
|
+
| RgGen type | SystemRDL combination | Notes |
|
|
80
|
+
| ---------- | --------------------- | ----- |
|
|
81
|
+
| `rwtrg` | `rw` combination + swacc=true | |
|
|
82
|
+
| `rotrg` | `ro` combination + swacc=true | |
|
|
83
|
+
| `wotrg` | `wo` combination + swacc=true | |
|
|
84
|
+
| `rowotrg`| — NOT GENERATED | `rowo` is not supported (bit-field overlap is an error). |
|
|
85
|
+
| `w1trg` | sw=rw, hw∈{r,na}, singlepulse=true | width=1/reset=0 etc. guaranteed by front-end. |
|
|
86
|
+
| `w0trg` | — NOT GENERATED | singlepulse requires write-1, so write-0 trigger has no SystemRDL source. |
|
|
87
|
+
| `row0trg`| — NOT GENERATED | follows w0trg. |
|
|
88
|
+
| `row1trg`| — NOT GENERATED | would need sw=rw + hw=rw/w + singlepulse, but sw=rw/w means value write in SystemRDL, so this combination is not expressible. (Also likely errored by front-end SW-write-loss.) |
|
|
89
|
+
|
|
90
|
+
### Write once
|
|
91
|
+
| RgGen type | SystemRDL combination | Notes |
|
|
92
|
+
| ---------- | --------------------- | ----- |
|
|
93
|
+
| `w1` | sw=rw1, hw∈{r,na} | |
|
|
94
|
+
| `wo1` | sw=w1, hw=r | |
|
|
95
|
+
|
|
96
|
+
### Special / not generated
|
|
97
|
+
| RgGen type | Status |
|
|
98
|
+
| ---------- | ------ |
|
|
99
|
+
| `counter` | Front-end does NOT support SystemRDL `counter` yet → out of first-release scope (target type deferred; see TODO). |
|
|
100
|
+
| `reserved` | SystemRDL has no equivalent concept → never generated from SystemRDL. |
|
|
101
|
+
| `custom` | First release: NOT used (held/deferred). Combinations that fit no named type are errors; using `custom` to catch them is future work (verification cost too high for v1). |
|
|
102
|
+
|
|
103
|
+
## Mask reference
|
|
104
|
+
RgGen types whose `reference` means a read/write data mask (`rc`, `w0c`, `w1c`, `wc`) cannot
|
|
105
|
+
receive that mask from SystemRDL (no mask concept in SystemRDL) → such fields are reference-less.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# bit_field type decision matrix (SystemRDL properties → RgGen type)
|
|
2
|
+
|
|
3
|
+
One consolidated table. Left columns are SystemRDL input properties (what the converter reads to
|
|
4
|
+
decide the type). The right column is the resulting RgGen type. Types that can take a reference
|
|
5
|
+
are split into multiple rows so each row's property combination is unambiguous.
|
|
6
|
+
|
|
7
|
+
Legend:
|
|
8
|
+
- Empty cell = property must NOT be set (if set, the field maps to a different type or errors).
|
|
9
|
+
- A value (e.g. `rw`, `rclr`, `true`, `ref`) = required value in that cell.
|
|
10
|
+
- In a signal/reference cell (`next`, swwe, swwel, hwclr, hwset, we): `true` = external input;
|
|
11
|
+
`ref` = reference to another field instance. (`next` takes only `ref`, not `true`.)
|
|
12
|
+
- `r/na` = either r or na.
|
|
13
|
+
- `rw/w` = hw writes the value; read side (rw vs w) is NOT distinguished (the hw output port is
|
|
14
|
+
generated either way; whether user logic observes it is the user's concern).
|
|
15
|
+
|
|
16
|
+
| RgGen type | sw | hw | next | onread | onwrite | hwset | hwclr | swwe | swwel | we | swacc | singlepulse |
|
|
17
|
+
| ---------- | ---- | ----- | ---- | ------ | ------- | ----- | ----- | ---- | ----- | ---- | ----- | ----------- |
|
|
18
|
+
| `rw` | rw | r/na | | | | | | | | | | |
|
|
19
|
+
| `ro` (ext) | r | rw/w | | | | | | | | | | |
|
|
20
|
+
| `ro` (ref) | r | r/na | ref | | | | | | | | | |
|
|
21
|
+
| `rof` | r | na | | | | | | | | | | |
|
|
22
|
+
| `wo` | w | r | | | | | | | | | | |
|
|
23
|
+
| `rohw` (ext) | r | rw/w | | | | | | | | true | | |
|
|
24
|
+
| `rohw` (ref) | r | rw/w | | | | | | | | ref | | |
|
|
25
|
+
| `rwhw` (ext) | rw | rw/w | | | | | | | | true | | |
|
|
26
|
+
| `rwhw` (ref) | rw | rw/w | | | | | | | | ref | | |
|
|
27
|
+
| `rc` | r | r/na | | rclr | | true | | | | | | |
|
|
28
|
+
| `rs` | r | r/na | | rset | | | true | | | | | |
|
|
29
|
+
| `wrc` | rw | r/na | | rclr | | | | | | | | |
|
|
30
|
+
| `wrs` | rw | r/na | | rset | | | | | | | | |
|
|
31
|
+
| `w0c` | rw | r/na | | | wzc | true | | | | | | |
|
|
32
|
+
| `w1c` | rw | r/na | | | woclr | true | | | | | | |
|
|
33
|
+
| `w0s` | rw | r/na | | | wzs | | true | | | | | |
|
|
34
|
+
| `w1s` | rw | r/na | | | woset | | true | | | | | |
|
|
35
|
+
| `w0t` | rw | r/na | | | wzt | | | | | | | |
|
|
36
|
+
| `w1t` | rw | r/na | | | wot | | | | | | | |
|
|
37
|
+
| `wc` | rw | r/na | | | wclr | true | | | | | | |
|
|
38
|
+
| `ws` | rw | r/na | | | wset | | true | | | | | |
|
|
39
|
+
| `woc` | w | r | | | wclr | true | | | | | | |
|
|
40
|
+
| `wos` | w | r | | | wset | | true | | | | | |
|
|
41
|
+
| `w0crs` | rw | r/na | | rset | wzc | | | | | | | |
|
|
42
|
+
| `w1crs` | rw | r/na | | rset | woclr | | | | | | | |
|
|
43
|
+
| `wcrs` | rw | r/na | | rset | wclr | | | | | | | |
|
|
44
|
+
| `w0src` | rw | r/na | | rclr | wzs | | | | | | | |
|
|
45
|
+
| `w1src` | rw | r/na | | rclr | woset | | | | | | | |
|
|
46
|
+
| `wsrc` | rw | r/na | | rclr | wset | | | | | | | |
|
|
47
|
+
| `rwl` (ext) | rw | r/na | | | | | | | true | | | |
|
|
48
|
+
| `rwl` (ref) | rw | r/na | | | | | | | ref | | | |
|
|
49
|
+
| `rwe` (ext) | rw | r/na | | | | | | true | | | | |
|
|
50
|
+
| `rwe` (ref) | rw | r/na | | | | | | ref | | | | |
|
|
51
|
+
| `rwc` (ext) | rw | r/na | | | | | true | | | | | |
|
|
52
|
+
| `rwc` (ref) | rw | r/na | | | | | ref | | | | | |
|
|
53
|
+
| `rws` (ext) | rw | r/na | | | | true | | | | | | |
|
|
54
|
+
| `rws` (ref) | rw | r/na | | | | ref | | | | | | |
|
|
55
|
+
| `rwtrg` | rw | r/na | | | | | | | | | true | |
|
|
56
|
+
| `rotrg` (ext) | r | rw/w | | | | | | | | | true | |
|
|
57
|
+
| `rotrg` (ref) | r | r/na | ref | | | | | | | | true | |
|
|
58
|
+
| `wotrg` | w | r | | | | | | | | | true | |
|
|
59
|
+
| `w1trg` | rw | r/na | | | | | | | | | | true |
|
|
60
|
+
| `w1` | rw1 | r/na | | | | | | | | | | |
|
|
61
|
+
| `wo1` | w1 | r | | | | | | | | | | |
|
|
62
|
+
|
|
63
|
+
## General error rules (apply to all types)
|
|
64
|
+
- `hw = rw1` or `hw = w1` (write-once on the hardware side) — RgGen has no corresponding concept.
|
|
65
|
+
ERROR for every type. (The hw column values in the table above are limited to r / na / rw / w;
|
|
66
|
+
rw1/w1 on hw are always rejected.)
|
|
67
|
+
|
|
68
|
+
## Not generated / not supported (no row above)
|
|
69
|
+
- `w0trg`, `row0trg`, `row1trg` — not expressible in SystemRDL.
|
|
70
|
+
- `rowo`, `rowotrg` — not supported; bit-field overlap is an error.
|
|
71
|
+
- `counter`, `intr` — front-end does not support them yet.
|
|
72
|
+
- `reserved`, `indirect` — no SystemRDL equivalent.
|
|
73
|
+
- `custom` — held for v1.
|
|
74
|
+
|
|
75
|
+
## Reference (RgGen output) per type
|
|
76
|
+
- `ro` (ref) / `rotrg` (ref): reference = the `next` target field.
|
|
77
|
+
- `rwl`/`rwe`/`rwc`/`rws` (ref rows): reference = the swwel/swwe/hwclr/hwset target field.
|
|
78
|
+
- `rohw`/`rwhw` (ref rows): reference = the `we` target field (valid signal source).
|
|
79
|
+
- `rc`/`w0c`/`w1c`/`wc`: RgGen reference means a data mask; NOT settable from SystemRDL → no reference.
|
|
80
|
+
- All other types: no reference.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# External reg / regfile → RgGen: Deferred Design Notes
|
|
2
|
+
|
|
3
|
+
This document records the conversion approach that was worked out for external `reg`/`regfile`,
|
|
4
|
+
so it is available when the feature is picked up later. The key point is that RgGen cannot
|
|
5
|
+
generate at reg/regfile granularity, so the contents must be wrapped in a register_block. (This
|
|
6
|
+
is unlike a nested addrmap, which is itself an RTL generation unit and maps directly to a
|
|
7
|
+
register_block without wrapping — see `systemrdl_to_rggen_mapping.md`.)
|
|
8
|
+
|
|
9
|
+
Note: the RgGen "External + child block reference" extension (rggen/rggen#291) is NOT a
|
|
10
|
+
prerequisite for this. #291 lets the user name the child register_block and avoid entering its
|
|
11
|
+
size by hand, but external reg/regfile can also be converted without it by computing the region
|
|
12
|
+
size in the converter (the same size-calculation approach used for `mem`).
|
|
13
|
+
|
|
14
|
+
## Trigger
|
|
15
|
+
|
|
16
|
+
Each of the following is an independent implementation boundary handled the same way:
|
|
17
|
+
- an external `reg` (`Reg#external` = true),
|
|
18
|
+
- an external `regfile` (`RegFile#external` = true).
|
|
19
|
+
|
|
20
|
+
## Two outputs
|
|
21
|
+
|
|
22
|
+
Each such subtree produces TWO outputs:
|
|
23
|
+
1. On the enclosing map, reserve its address region as an RgGen `external` register. Its `address`
|
|
24
|
+
and `size` come from the model (`address`/`size`).
|
|
25
|
+
2. Synthesize a NEW register_block that wraps the reg/regfile, and place the reg/regfile inside
|
|
26
|
+
it. Unlike a nested addrmap (which is itself a register_block and goes through the normal
|
|
27
|
+
conversion flow), a reg/regfile cannot itself become a register_block — RgGen cannot generate
|
|
28
|
+
at reg/regfile granularity — so an enclosing register_block hierarchy has to be created for it.
|
|
29
|
+
The synthesized block is what lets RgGen actually generate the contents.
|
|
30
|
+
|
|
31
|
+
## Rules for the synthesized wrapping register_block
|
|
32
|
+
|
|
33
|
+
- Name: the ancestor instance names joined with `__` (e.g. regfile `foo[2]` containing external
|
|
34
|
+
reg `bar` → `foo__0__bar`). Array subscripts also use `__`, so the separator is uniform.
|
|
35
|
+
- Addresses inside the synthesized block are re-based to a 0 offset (it is an independent block).
|
|
36
|
+
- `bridge` is NOT part of the trigger; it only indicates whether the external boundary involves
|
|
37
|
+
bus/protocol conversion.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Interrupt Aggregation and Port Generation Policy
|
|
2
|
+
|
|
3
|
+
This document records the implementation policy for how interrupt outputs are aggregated and exposed at module boundaries in generated RTL. The SystemRDL specification fixes register-level aggregation but is silent on how the resulting `intr`/`halt` outputs are surfaced at the boundary of `addrmap` modules. The choices below are implementation decisions and not behavior mandated by the specification.
|
|
4
|
+
|
|
5
|
+
## Scope
|
|
6
|
+
|
|
7
|
+
The decisions here govern the backend (RTL generator). The elaborator's responsibility is to produce the elaborated model in which `intr` fields, their `enable`/`mask` (and `haltenable`/`haltmask`) bindings, and the `next` connections among interrupt registers are all preserved. The behavior described below is how the backend then translates that model into module ports and aggregation logic.
|
|
8
|
+
|
|
9
|
+
## Register-Level Aggregation (Specification-Mandated)
|
|
10
|
+
|
|
11
|
+
SystemRDL 10.8 specifies that a register containing one or more `intr` fields implicitly has an `intr` register property representing the inclusive OR of all interrupt bits in the register after any field `enable`/`mask` logic. If `haltenable`/`haltmask` is specified on at least one field, the register also has a `halt` property representing the OR of those bits after haltenable/haltmask. The `intr` property is always present on an interrupt register (10.8.1 b); the `halt` property is present only when haltenable or haltmask exists (10.8.1 c). These are register-level outputs in the SystemRDL sense: they exist as values that the language permits to be referenced on the right-hand side of an assignment.
|
|
12
|
+
|
|
13
|
+
This document does not modify the register-level aggregation rule; it follows the specification.
|
|
14
|
+
|
|
15
|
+
## Boundary Port Exposure (Implementation Policy)
|
|
16
|
+
|
|
17
|
+
SystemRDL does not specify how a register's `intr`/`halt` output is realized at an `addrmap` module's HDL boundary. The specification merely makes the aggregated value a referenceable property; whether and how it becomes an external port is left to the implementation.
|
|
18
|
+
|
|
19
|
+
### Decision
|
|
20
|
+
|
|
21
|
+
For every register that has an `intr` output (and likewise for `halt`), the enclosing `addrmap` module exposes that register's `intr` output as a port on the module boundary. The same applies to `halt`. Aggregation stops at the register level; the `addrmap` module does not perform additional OR-reduction across multiple registers.
|
|
22
|
+
|
|
23
|
+
When an `addrmap` is instantiated inside another `addrmap`, the child `addrmap` is treated as an external component (per 13.4.1 c-4: "addrmap instances are always considered external"). The child module's per-register `intr`/`halt` ports appear on the parent's interface to the child instance. Aggregation across registers, or across child `addrmap` instances, is performed by user-written aggregation registers in the parent (the pattern shown in the specification's 17.2 example).
|
|
24
|
+
|
|
25
|
+
### Rationale
|
|
26
|
+
|
|
27
|
+
This policy keeps the backend's behavior close to what the specification actually says, without adding implementation-defined aggregation rules:
|
|
28
|
+
|
|
29
|
+
- The specification defines aggregation only at the register level. Per-register boundary exposure preserves that granularity; aggregating further at the `addrmap` level would introduce an `intr`/`halt` semantics that the specification does not describe.
|
|
30
|
+
- Typical CSR designs have only a small number of interrupt registers per `addrmap`, so the per-register port count is manageable in practice and does not produce unwieldy module interfaces.
|
|
31
|
+
- Per-register ports allow multiple categories of interrupts (e.g. priority levels, error vs. event, distinct CPU targets) to be exposed independently. An `addrmap`-level aggregated port would be limited to a single `intr` and a single `halt`, constraining the designer to that one categorization.
|
|
32
|
+
- Hierarchical aggregation through nested `addrmap`s is consistent with how SystemRDL itself handles cross-block interrupt aggregation: by user-written aggregation registers connecting lower-level `intr` outputs via `next`. The boundary behavior chosen here lines up with that pattern: each register's `intr` is available as a port; aggregation across registers (whether within an `addrmap` or across `addrmap`s) is the user's responsibility, expressed via aggregation registers and `next` references.
|
|
33
|
+
|
|
34
|
+
### Status
|
|
35
|
+
|
|
36
|
+
The register-level aggregation (10.8) is specification-mandated and is followed. The boundary exposure policy -- per-register ports, no `addrmap`-level aggregation -- is an implementation choice that the specification does not constrain. Other tools may make different choices (for example, exposing only the top-level aggregated output, or providing both per-register and `addrmap`-level outputs). Behavior may therefore differ across tools at the boundary, even when the SystemRDL input is the same.
|
|
37
|
+
|
|
38
|
+
If a use case requires `addrmap`-level aggregation in addition to per-register exposure, this policy can be extended without contradicting the specification, because the specification does not forbid additional `addrmap`-level outputs; it simply does not require them.
|
|
39
|
+
|
|
40
|
+
## Final Interrupt Pin to the Outside
|
|
41
|
+
|
|
42
|
+
The SystemRDL specification does not describe how a chip-level interrupt pin is produced from the per-register `intr` outputs. Within a SystemRDL design, the only mechanism for combining interrupts across registers is the user-written aggregation register (see 17.2 example).
|
|
43
|
+
|
|
44
|
+
Under this policy, the final external interrupt pin is the `intr` port of a register that aggregates the relevant lower-level `intr` signals via `next`. When that register is contained directly in the top-level `addrmap`, its `intr` port appears on the top-level module's boundary and constitutes the chip-level interrupt output. There is no separate "top-level interrupt pin" mechanism; the final pin is simply a register-level `intr` port on the top module, just like any other register's `intr` port.
|
|
45
|
+
|
|
46
|
+
## Comparison with Other Implementations
|
|
47
|
+
|
|
48
|
+
PeakRDL-regblock follows the same register-level boundary policy described above (per-register `intr`/`halt` outputs at the module boundary; no `addrmap`-level aggregation). This is the most direct reading of the specification and tends to be the convergent choice across implementations that prioritize specification fidelity.
|
|
49
|
+
|
|
50
|
+
Implementations that perform `addrmap`-level aggregation, or that expose only a single top-level interrupt port, exist in some tools as a generation option, but they go beyond what the specification describes.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Precedence Handling Policy
|
|
2
|
+
|
|
3
|
+
This document records how RgGen handles the SystemRDL `precedence` property, which is silent on the spec's part regarding its compatibility with implementations that fix software/hardware precedence rather than making it per-field configurable.
|
|
4
|
+
|
|
5
|
+
## Background
|
|
6
|
+
|
|
7
|
+
SystemRDL defines the `precedence` field property (clause 9.10) to control which side wins when software and hardware attempt to write the same field on the same cycle:
|
|
8
|
+
|
|
9
|
+
- `precedence = sw` (the default) -- software takes precedence over hardware.
|
|
10
|
+
- `precedence = hw` -- hardware takes precedence over software.
|
|
11
|
+
|
|
12
|
+
RgGen, by contrast, fixes hardware-side precedence in all field types. The rationale is that software writes are inherently retryable by the host -- the host can read the field back and re-issue the write if it sees the value did not stick -- whereas hardware writes typically signal a time-sensitive event (an error capture, a completion notification, a state transition) that has no comparable retry mechanism. Granting hardware precedence is therefore the safer default: the side that cannot easily recover from being overwritten is the side that wins.
|
|
13
|
+
|
|
14
|
+
This creates a mismatch between the SystemRDL default (`sw`) and RgGen's fixed behavior (`hw`). A SystemRDL file that omits `precedence` is, by the spec's default, requesting software precedence -- the opposite of what RgGen will actually produce. Silently accepting such input would invert the field's semantics without notice.
|
|
15
|
+
|
|
16
|
+
A further complication: by the time SystemRDL elaboration completes, the origin of a property value -- whether it was written explicitly by the user or filled in from the default -- is generally lost. The elaborated model only carries the final value. RgGen therefore cannot distinguish "the user wrote `precedence = sw`" from "the user omitted `precedence` and the default of `sw` was applied"; both reach the backend as `precedence = sw`.
|
|
17
|
+
|
|
18
|
+
This rules out any policy that depends on telling explicit and defaulted values apart. The handling must work purely from the effective value as it appears in the elaborated model.
|
|
19
|
+
|
|
20
|
+
## Solution: A `precedence` Ignore Mode
|
|
21
|
+
|
|
22
|
+
RgGen introduces a configuration flag, the `precedence` ignore mode, that selects between two behaviors. The flag is set at the project level via RgGen configuration; it is not a SystemRDL property and cannot be changed per-field or per-register.
|
|
23
|
+
|
|
24
|
+
### Ignore Mode On
|
|
25
|
+
|
|
26
|
+
The `precedence` property is treated as something RgGen does not implement. The elaborated value of `precedence` on each field is simply not consulted by the RtL generator; every field is generated with hardware precedence regardless of what its `precedence` value happens to be.
|
|
27
|
+
|
|
28
|
+
No diagnostic is emitted. A SystemRDL file may contain `precedence = sw`, `precedence = hw`, or omit the property entirely; in all cases the generated RTL is the same.
|
|
29
|
+
|
|
30
|
+
This mode silently sets aside whatever the SystemRDL source requests via `precedence`. It is therefore not the default: making the silent override the default would build a hidden inversion of semantics into the standard behavior. Users select this mode explicitly when they accept that trade-off in exchange for being able to process SystemRDL files that omit `precedence` without further annotation.
|
|
31
|
+
|
|
32
|
+
### Ignore Mode Off (Default)
|
|
33
|
+
|
|
34
|
+
The elaborated value of `precedence` is checked on every field. If it is `sw`, the field is rejected as an error; if it is `hw`, it is accepted.
|
|
35
|
+
|
|
36
|
+
Because elaboration cannot distinguish an explicit value from a defaulted one, this mode rejects every field whose `precedence` is `sw` for any reason, including fields where the user simply omitted the property. As a practical consequence, the SystemRDL source must set `precedence = hw` explicitly on every field that should be accepted -- typically via `default precedence = hw;` at the addrmap or register scope, which sets the scope-wide default rather than requiring per-field annotation.
|
|
37
|
+
|
|
38
|
+
This mode is the default. The reason is that any disagreement between the SystemRDL request and RgGen's actual behavior is surfaced as an explicit error rather than being silently overridden. A SystemRDL file is processed only when its `precedence` settings are consistent with the hardware-precedence model that RgGen produces; otherwise the user is required to acknowledge the mismatch, either by adding `default precedence = hw;` (matching RgGen's behavior at the source level) or by explicitly selecting ignore mode on (accepting the override). The default refuses to perform a silent semantic inversion.
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# SystemRDL vs RgGen Gap Analysis
|
|
2
|
+
|
|
3
|
+
A comparison of SystemRDL 2.0 against RgGen ([wiki](https://github.com/rggen/rggen/wiki/Register-Map-Specifications)). This document organizes each SystemRDL feature by its handling policy in RgGen -- mapped, not supported, or already implemented -- as a reference for SystemRDL input support.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Already Supported in RgGen
|
|
8
|
+
|
|
9
|
+
SystemRDL concepts for which RgGen already provides equivalent or near-equivalent functionality. SystemRDL input can be mapped directly.
|
|
10
|
+
|
|
11
|
+
| SystemRDL Concept | RgGen Equivalent | Notes |
|
|
12
|
+
| ----------------------------- | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
13
|
+
| `regfile` component | `register_file` | Hierarchical grouping |
|
|
14
|
+
| `external reg` | `external` register type | Single external register |
|
|
15
|
+
| `encode` (enumeration) | `label` | Named enumerated values |
|
|
16
|
+
| `counter` (basic) | `counter` bit field type | RgGen has a counter type (up/down/clear). NOTE: SystemRDL conversion does not support it yet — the front-end (systemrdl elaborator) does not handle `counter`, so it is out of current scope. |
|
|
17
|
+
| `swacc` | `rwtrg` / `rotrg` / `wotrg` | Read/write trigger outputs (via `swacc=true`). `swmod` has no faithful target → error. See matrix. |
|
|
18
|
+
| `singlepulse` | `w1trg` | Write-1 pulse. `w0trg` is not generated (singlepulse triggers on write-1). See matrix. |
|
|
19
|
+
| `errextbus` | Error input on `rggen_bus_if` (default) | rggen_bus_if has an error input by default, so an explicit `errextbus` needs no action → ignored. |
|
|
20
|
+
| Register arrays | `size` + `step` | Multi-dimensional supported (front-end array flattening applies; see systemrdl_to_rggen_mapping.md) |
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 2. Mapping Strategy for SystemRDL Bit Field Types
|
|
25
|
+
|
|
26
|
+
The detailed and authoritative mapping from SystemRDL field property combinations to RgGen bit
|
|
27
|
+
field types now lives in dedicated notes:
|
|
28
|
+
|
|
29
|
+
- [bit_field_type_matrix.md](bit_field_type_matrix.md) — the full decision matrix (every
|
|
30
|
+
SystemRDL property column vs. each RgGen type), used as the converter's dispatch reference.
|
|
31
|
+
- [bit_field_type_mapping.md](bit_field_type_mapping.md) — a per-type migration guide describing
|
|
32
|
+
each RgGen type's distinguishing properties and reference semantics.
|
|
33
|
+
|
|
34
|
+
Cross-cutting property policies and the full list of properties/structures that are rejected as
|
|
35
|
+
errors are in [systemrdl_to_rggen_mapping.md](systemrdl_to_rggen_mapping.md) (field layer).
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## 3. Implementation Plan
|
|
40
|
+
|
|
41
|
+
Features for which an implementation plan or handling policy has been defined. Some are tracked as issues for future implementation; others have their handling policy documented in a separate notes file.
|
|
42
|
+
|
|
43
|
+
| Feature | Issue | Status |
|
|
44
|
+
| ---------------------------------------------------------------------- | ---------------------------------------------------- | -------------- |
|
|
45
|
+
| **Alias register type** | rggen/rggen#287 | Filed |
|
|
46
|
+
| **Interrupt support** (trigger extension + block-level aggregation) | rggen/rggen#290 | Filed. NOTE: SystemRDL conversion does not support `intr` yet — front-end does not handle it, so out of current scope. |
|
|
47
|
+
| **External + child block reference** | rggen/rggen#291 | Filed |
|
|
48
|
+
| **Counter saturate/wrap boundary behavior** (spec-level specification) | rggen/rggen#292 | Filed |
|
|
49
|
+
| **User-Defined Properties (UDP)** | See [udp_handling_policy.md](udp_handling_policy.md) | Policy defined |
|
|
50
|
+
| **`precedence` property handling** | See [precedence_handling_policy.md](precedence_handling_policy.md); conversion behavior summarized in [systemrdl_to_rggen_mapping.md](systemrdl_to_rggen_mapping.md) | Policy defined |
|
|
51
|
+
|
|
52
|
+
### Mapping Coverage by Issue
|
|
53
|
+
|
|
54
|
+
| SystemRDL Feature | Corresponding RgGen Extension |
|
|
55
|
+
| --------------------------------------- | --------------------------------------------------------------------------------- |
|
|
56
|
+
| `alias` keyword | rggen/rggen#287 alias register type |
|
|
57
|
+
| `intr` field property + sticky variants | rggen/rggen#290 (existing `w1c` family + trigger + aggregation) |
|
|
58
|
+
| Trigger mode (level/edge) | rggen/rggen#290 `trigger` option |
|
|
59
|
+
| Interrupt aggregation (OR output) | rggen/rggen#290 block-level `interrupt` attribute |
|
|
60
|
+
| `external regfile { ... }` | External + child block reference |
|
|
61
|
+
| `mem` component | External + child block reference (mementries x memwidth normalized to byte_size) |
|
|
62
|
+
| `incrsaturate` / `decrsaturate` | Counter saturate/wrap boundary behavior (this feature) |
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## 4. Resolved on the SystemRDL Parser / Elaborator Side
|
|
67
|
+
|
|
68
|
+
Language constructs that exist in SystemRDL but are resolved at elaboration time. By the time data reaches the RgGen internal model, these are already materialized, so RgGen DSL does not need equivalent mechanisms.
|
|
69
|
+
|
|
70
|
+
| SystemRDL Feature | Resolution Strategy |
|
|
71
|
+
| ------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- |
|
|
72
|
+
| `default` keyword scope inheritance | Expanded to each field during elaboration |
|
|
73
|
+
| Dynamic property assignment (`inst->prop = value;`) | Final values resolved during elaboration |
|
|
74
|
+
| Parameterized components (`#(WIDTH = 8)`) | Instantiated with concrete values during elaboration |
|
|
75
|
+
| Addressing (`@` explicit address, `%=` alignment, `alignment` property, compact / regalign / fullalign modes) | Concrete addresses finalized during elaboration |
|
|
76
|
+
| Mixed anonymous/named definitions | Uniquified during elaboration |
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## 5. Not Supported
|
|
81
|
+
|
|
82
|
+
Features that exist in SystemRDL but are deliberately not supported in RgGen. **All items in this section are rejected with an explicit error during SystemRDL input processing.**
|
|
83
|
+
|
|
84
|
+
### 5.1 Out of Scope (Beyond CSR Tool Responsibility)
|
|
85
|
+
|
|
86
|
+
| Feature | Reason |
|
|
87
|
+
| ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
88
|
+
| `signal` component | RgGen does not have a first-class signal concept. HW access properties (`we`, `wel`, `hwclr`, `hwset`, `swwe`, `swwel`, etc.) can be expressed via the boolean form (auto-generated external ports) or field references (internal control), covering practical use cases without an explicit signal declaration. |
|
|
89
|
+
| Reset signals (`resetsignal`, `field_reset`, `cpuif_reset`) | Uniformly rejected. RgGen targets a single reset domain (`i_rst_n`); supporting signal-based reset specifications would entail multiple reset domains and the associated RDC (Reset Domain Crossing) analysis, which is beyond CSR tool scope. Only constant reset values via `initial_value` are supported. |
|
|
90
|
+
| Counter `overflow` / `underflow` output | HW-to-HW event signals, outside CSR domain |
|
|
91
|
+
| Counter `incrthreshold` / `decrthreshold` | Same as above |
|
|
92
|
+
| `constraint` block | Verification-specific syntax with limited demand |
|
|
93
|
+
|
|
94
|
+
### 5.2 No Corresponding Feature
|
|
95
|
+
|
|
96
|
+
| Feature | Notes |
|
|
97
|
+
| ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
98
|
+
| Field overlap within a register (10.1 d) | RgGen does not have a mechanism to place multiple fields at overlapping bit positions within a register. The SystemRDL exception for read-only / write-only pairs is rejected (no `rowo`). See [systemrdl_to_rggen_mapping.md](systemrdl_to_rggen_mapping.md). |
|
|
99
|
+
| Register address not aligned to bus width | RgGen does not support placing a register at an address that is not a multiple of the configured bus width. The constraint `(address % bus_width) == 0` applies to every register, whether its address was assigned via `@` or by automatic allocation. |
|
|
100
|
+
| `sharedextbus` | Combines multiple external components into a single bus interface. RgGen has no feature to merge external interfaces, so the intent cannot be represented → rejected as error. See [systemrdl_to_rggen_mapping.md](systemrdl_to_rggen_mapping.md). |
|
|
101
|
+
|
|
102
|
+
### 5.3 Low Usage Frequency
|
|
103
|
+
|
|
104
|
+
| Feature | Notes |
|
|
105
|
+
| -------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
|
|
106
|
+
| `anded` / `ored` / `xored` (field-level reduction) | Rare in practice; no RgGen feature → rejected as error. Interrupt aggregation use case is covered by rggen/rggen#290 |
|
|
107
|
+
| `swmod` (as a standalone property) | No faithful RgGen target → rejected as error. (`swacc` IS supported: it drives `rwtrg`/`rotrg`/`wotrg`; see [bit_field_type_matrix.md](bit_field_type_matrix.md).) |
|
|
108
|
+
| `hwenable` / `hwmask` (bit-level HW write control) | Rare in practice; no RgGen feature → rejected as error. Per-bit control can be expressed by splitting into separate fields with `rwe`/`rwl` |
|
|
109
|
+
| `bridge` addrmap (multi-view) | Limited real-world use |
|
|
110
|
+
| `struct` definition and usage | Used only within SystemRDL source (UDP types, component parameters, struct members) and does not survive elaboration. Rare in practical CSR descriptions. |
|
|
111
|
+
|
|
112
|
+
Note: For `hwenable` / `hwmask`, equivalent semantics can be expressed using `rwe` / `rwl`.
|
|
113
|
+
|
|
114
|
+
### 5.4 High Parser Implementation Cost
|
|
115
|
+
|
|
116
|
+
| Feature | Notes |
|
|
117
|
+
| --------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
118
|
+
| Preprocessor (Perl-embedded templates, Verilog-style `` `include `` / `` `define `` / `` `ifdef ``) | Implementing these in the SystemRDL parser carries a high cost, particularly for tracking token positions through template expansion to produce meaningful error messages. The core register modeling concern is far removed from preprocessor semantics. |
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## 6. Architecturally Unnecessary
|
|
123
|
+
|
|
124
|
+
SystemRDL properties that exist because SystemRDL is a description language only, and have no role in RgGen's integrated spec + RTL/RAL generation architecture. Some are automatically resolved by RgGen's own mechanisms; others have no corresponding concept and are simply ignored.
|
|
125
|
+
|
|
126
|
+
| Feature | RgGen Resolution |
|
|
127
|
+
| ---------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
|
128
|
+
| `hdl_path` / `hdl_path_slice` / `hdl_path_gate` etc. | Automatically embedded during RAL generation, based on RgGen's own RTL hierarchy |
|
|
129
|
+
| `donttest` / `dontcompare` / `internal` | Handled standardly on the RAL generation side |
|
|
130
|
+
| `name` | Descriptive display name for documentation; RgGen has no corresponding concept and silently ignores the property |
|
|
131
|
+
|
|
132
|
+
**Input handling**: Silently discard (no warning needed). User-provided HDL paths would not match RgGen's generated RTL hierarchy anyway.
|