You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Adds support for SystemVerilog parameter overrides on ExternalSV descriptors and propagates those overrides through both Verilator compilation and PyCDE wrapper generation.
Copy file name to clipboardExpand all lines: python/assassyn/codegen/simulator/verilator.md
+5-4Lines changed: 5 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -49,7 +49,7 @@ Dataclass capturing the direction, type information, and host language types for
49
49
50
50
### `ExternalFFIModule`
51
51
52
-
Dataclass that tracks all information for a generated crate: crate name, paths, symbol prefix, IO port descriptors, clock/reset flags, and the produced shared library metadata.
52
+
Dataclass that tracks all information for a generated crate: crate name, paths, symbol prefix, IO port descriptors, clock/reset flags, parameter overrides, and the produced shared library metadata.
53
53
54
54
These types appear in `__all__`, making them available to other generator components.
55
55
@@ -72,7 +72,8 @@ Creates an `ExternalFFIModule` spec from an `ExternalSV` **class** (rather than
72
72
3. Allocates unique crate and dynamic library names
73
73
4. Copies the SystemVerilog source to the crate's `rtl/` directory
74
74
5. Calls `_collect_ports_from_class` to partition ports into inputs and outputs
75
-
6. Returns a fully populated `ExternalFFIModule`with the class name as`original_module_name`
75
+
6. Copies `metadata["parameters"]` (ifany) into the spec so Verilator can apply `-G` overrides
76
+
7. Returns a fully populated `ExternalFFIModule`with the class name as`original_module_name`
@@ -97,14 +98,14 @@ Writes `Cargo.toml`, `src/lib.rs`, and `src/wrapper.cpp` for a given spec before
97
98
98
99
Runs the full native toolchain:
99
100
1. Ensures the `.sv`fileis present (`_ensure_sv_source`).
100
-
2. Calls Verilator (`_run_verilator_compile`) into `build/verilated`.
101
+
2. Calls Verilator (`_run_verilator_compile`) into `build/verilated`, passing any`ExternalSV` parameter overrides via `-G`.
101
102
3. Collects all generated C++ sources (`_gather_source_files`).
102
103
4. Builds the shared library via `_build_compile_command`and`_run_subprocess`.
103
104
5. Writes `.verilator-lib-path` so the Rust wrapper knows where to load the artifact.
104
105
105
106
### `_write_manifest_file`
106
107
107
-
Takes a manifest path plus a list of specs and rewrites the JSON summary in a single helper. This avoids duplicating the `json.dumps(..., indent=2)` call across the different generation entry points.
108
+
Takes a manifest path plus a list of specs and rewrites the JSON summary (including `parameters`) in a single helper. This avoids duplicating the `json.dumps(..., indent=2)` call across the different generation entry points.
Copy file name to clipboardExpand all lines: python/assassyn/codegen/verilog/_expr/intrinsics.md
+2-1Lines changed: 2 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -107,7 +107,8 @@ This function generates Verilog code for block intrinsic operations, which are c
107
107
- The cleanup phase incorporates these stored predicates into post-wait assignments and triggers via `get_pred`
108
108
109
109
4.**EXTERNAL_INSTANTIATE / ExternalIntrinsic**: Creates and wires external modules in-line
110
-
-`ExternalIntrinsic` instances are handled before the opcode switch, generating calls to `<wrapper>::new()` and wiring all inputs
110
+
-`ExternalIntrinsic` instances are handled before the opcode switch, generating calls to `@modparams` wrappers and wiring all inputs
111
+
- Parameter overrides from `ExternalSV.metadata()["parameters"]` are formatted and passed into the wrapper factory before port connections
111
112
- Updates the dumper's bookkeeping (`external_instance_names`, `external_wrapper_names`, `external_output_exposures`) while consulting the shared `ExternalRegistry` for instance owners and cross-module consumers
112
113
113
114
The function integrates with the credit-based pipeline architecture by managing execution conditions and finish signals.
Copy file name to clipboardExpand all lines: python/assassyn/codegen/verilog/design.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -112,7 +112,7 @@ The CIRCTDumper class is the main visitor that converts Assassyn IR into Verilog
112
112
1.**Execution Control**: `wait_until` and per-expression `meta_cond` metadata decide when statements run, while FINISH gating now reads the precomputed `finish_sites` stored in module metadata instead of collecting tuples during emission.
113
113
2.**Module State**: `current_module` tracks traversal context, while port declarations are derived from immutable metadata instead of mutating dumper dictionaries.
114
114
3.**Array Management**: `array_metadata`, `memory_defs`, and ownership metadata ensure multi-port register arrays are emitted while memory payloads (`array.is_payload(memory)` returning `True`) are routed through dedicated generators.
115
-
4.**External Integration**: `external_metadata` (an `ExternalRegistry`) captures external classes, instance ownership, and cross-module reads. Runtime maps (`external_wrapper_names`, `external_instance_names`, `external_wire_assignments`, `external_wire_outputs`, and `external_output_exposures`) reuse that registry to materialise expose/valid ports and wire consumers to producers without recomputing analysis.
115
+
4.**External Integration**: `external_metadata` (an `ExternalRegistry`) captures external classes, instance ownership, and cross-module reads. Runtime maps (`external_wrapper_names`, `external_instance_names`, `external_wire_assignments`, `external_wire_outputs`, and `external_output_exposures`) reuse that registry to materialise expose/valid ports and wire consumers to producers without recomputing analysis.`_generate_external_module_wrapper` now emits `@modparams` wrappers and threads `ExternalSV.metadata()["parameters"]` into instantiations so SystemVerilog parameter overrides propagate into PyCDE.
116
116
5.**Expression Naming**: `expr_to_name` and `name_counters` guarantee deterministic signal names whenever expression results must be reused across statements.
117
117
6.**Code Generation**: `code`, `logs`, and `indent` store emitted lines and diagnostic information used later by the testbench.
118
118
7.**Module Metadata**: `module_metadata` maps each `Module` to its `ModuleMetadata`. The structure tracks FINISH intrinsics, async calls, FIFO interactions (annotated with `expr.meta_cond`), and every array/value exposure required for cleanup. These entries are populated before the dumper is constructed via [`collect_fifo_metadata`](./analysis.md), so `CIRCTDumper` receives a frozen snapshot and never mutates it during emission. See [metadata module](/python/assassyn/codegen/verilog/metadata.md) for details. The dumper exposes this information via convenience helpers such as `async_callers(module)`, which forwards to the frozen `AsyncLedger` stored on the interaction matrix.
* The decorator validates that the class extends `ExternalSV`, walks `__annotations__`, and gathers all `WireIn`/`WireOut`/`RegOut` definitions into the `_wires` metadata table.
40
41
* Configuration fields such as `__source__`, `__module_name__`, `__has_clock__`, and `__has_reset__` are captured so code generation stages can decide how to wrap and clock the external block.
42
+
*`__parameters__` (optional dict) captures SystemVerilog parameter overrides; values may be `int`/`bool`/`str` (or `PathLike`, converted to `str`, with `bool` coerced to `int`) and are surfaced to both Verilator (`-G`) and PyCDE wrapper generation.
41
43
* The decorated class remains callable; invoking it runs through the metaclass and returns an `ExternalIntrinsic` instead of a Python object. There is no longer a mutable Python instance that exposes setters/getters.
***Construction**: The metaclass intercepts calls to the class and routes them to `_create_external_intrinsic`, which wraps the request in an `ExternalIntrinsic`.
48
50
***Metadata**: `_wires` stores port declarations (direction + kind + dtype) while `_metadata` records auxiliary fields such as `module_name`, `source`, clock/reset booleans, etc. Downstream code generation stages read these tables directly.
51
+
***Parameters**: `__parameters__` is folded into `_metadata["parameters"]` so simulator + Verilog backends can apply SV parameter overrides consistently.
52
+
***Parameter Access**: `ExternalSV.parameters()` returns a copy of the normalized parameter map.
49
53
***No Mutable Instance**: The descriptor no longer inherits from `Downstream` or exposes mutation APIs like `in_assign`. All connectivity is described by the returned intrinsic and its operands.
50
54
***Debugging Support**: `__repr__` is implemented on the Python side for better logging, but day-to-day interaction happens through the intrinsic nodes.
0 commit comments