Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion cv32e40p-example.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,16 @@ generator = "systemverilog" # preprocess with sv2v
include_dirs = ["./cv32e40p/rtl/include"]
top_module = "cv32e40p_core"

# Verilog module parameter overrides — emitted as p_<NAME> on the Instance.
# Override any of these from Python via
# `load_wrapper_from_toml("cv32e40p.toml", parameters={"FPU": 1})`.
[parameters]
COREV_PULP = 0
COREV_CLUSTER = 0
FPU = 0 # keep 0 to avoid pulling in the FPU wrapper
ZFINX = 0
NUM_MHPMCOUNTERS = 1

[clocks]
sys = "clk_i" # wrapper generates i_clk_i = ClockSignal()

Expand Down Expand Up @@ -241,7 +251,6 @@ MySoC = MySoC

## Caveats

- **Parameters aren't set by the wrapper.** CV32E40P uses its module defaults (`FPU = 0`, `COREV_PULP = 0`, `COREV_CLUSTER = 0`). If you need different values, you'd either need to extend the wrapper or add an `Instance(..., p_FPU=1, ...)` manually.
- **All module ports must appear in `map`.** Unmapped ports will not be connected (the wrapper only wires what you listed).
- **APU/FPU ports exist even when `FPU = 0`** — they must still be wired or tied off. If you don't need the FPU, tie `apu_gnt_i = 0`, `apu_rvalid_i = 0`, `apu_result_i = 0`, `apu_flags_i = 0` in your design and leave the output APU signals unconnected (they'll be driven but go nowhere).
- **Debug interface:** tie `debug_req_i = 0` and ignore `debug_*_o` outputs unless you're wiring up a JTAG debug transport.
Expand Down
23 changes: 23 additions & 0 deletions rtl-wrapper.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,29 @@ Auto-mapping is built in for these interfaces — the wrapper parses the Verilog

For other interfaces, or when the Verilog uses non-standard names, provide an explicit `map` in TOML.

## Verilog module parameters

Verilog `parameter` / `localparam` values can be overridden from TOML, from Python, or both. Declare defaults in the TOML `[parameters]` table:

```toml
name = "wb_timer"

[parameters]
DATA_WIDTH = 32
ADDR_WIDTH = 4
```

At load time, pass a `parameters=` kwarg to override specific values. The Python kwarg wins on collisions; parameters you don't mention fall back to the TOML defaults:

```python
# DATA_WIDTH=64 (override), ADDR_WIDTH=4 (TOML default)
timer = load_wrapper_from_toml("wb_timer.toml", parameters={"DATA_WIDTH": 64})
```

The merged set is emitted as `p_<NAME>=<value>` kwargs on the `Instance(...)` at elaboration — equivalent to `Instance("wb_timer", p_DATA_WIDTH=64, p_ADDR_WIDTH=4, …)`.

When a `[generate]` section is present, the merged parameters are also fed into the generator's template substitution, so SpinalHDL Scala args, sv2v `-D` defines, and yosys-slang `-D` / `--top` placeholders all see the final values. The same `{name}` substitution works in `[ports.*] params = { … }` — writing `params = { addr_width = "{ADDR_WIDTH}" }` resolves against the merged parameters.

## Preprocessing SystemVerilog sources

If your external RTL is SystemVerilog that uses packages/interfaces/typedefs, add a `[generate]` section to preprocess it:
Expand Down