Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
360926e
Add Typed operations to retain LogicStructures
desmonddak Sep 2, 2026
421ad2d
add support for Const LogicStructure and fix tests
desmonddak Sep 2, 2026
ee8c5f8
update doc and tests
desmonddak Sep 4, 2026
62ca033
go back to generateSynth() for now in testing verilog
desmonddak Sep 4, 2026
33f0d29
ambiguity on typedCases, missing propagation of LogicArrayOf through …
desmonddak Sep 5, 2026
4832b3c
added issues resolved, fixed SystemVerilog assignment issue
desmonddak Sep 8, 2026
ff8243e
fixed SV golden expected output
desmonddak Sep 8, 2026
85671c8
typedlogicarray checks in external sims
desmonddak Oct 8, 2026
a0ba8d2
Preserve scalar operation compatibility
desmonddak Oct 8, 2026
0115418
Restrict packed array output collapse
desmonddak Oct 8, 2026
5c06013
Internalize structure signatures for 0.7.0
desmonddak Oct 8, 2026
6055759
remove deprecations
desmonddak Oct 8, 2026
4fe9b6a
doc update
desmonddak Oct 8, 2026
d5c6021
Ignore flaky external markdown link hosts
desmonddak Oct 8, 2026
0cc2a7f
Document LogicEnum integration plans
desmonddak Oct 8, 2026
8742b56
Retain 0.7 service compatibility APIs
desmonddak Oct 9, 2026
c983c57
Integrate typed operations with TypedLogicArray
desmonddak Oct 9, 2026
1a5f1df
a format was missed
desmonddak Oct 10, 2026
fdb418f
Add typed ready-valid structure pipeline
desmonddak Oct 11, 2026
375c7e6
Preserve aggregate structure assignment metadata
desmonddak Oct 11, 2026
42cddf1
Generalize ready-valid pipeline payloads
desmonddak Oct 11, 2026
c75bf5f
Integrate LogicEnum with typed operations
desmonddak Oct 14, 2026
a70797f
Validate typed-array operation codecs
desmonddak Oct 14, 2026
4e8b954
Clarify 0.7 deprecation policy
desmonddak Oct 14, 2026
9d78c89
Keep release changes under Next Release
desmonddak Oct 14, 2026
5e15527
Share packed array rewrite across synthesizers
desmonddak Oct 15, 2026
3b5153f
Preserve signal types through pipelines
desmonddak Oct 16, 2026
860c0f4
types not needed
desmonddak Oct 16, 2026
0c372a5
Restore rebased compatibility contracts
desmonddak Oct 19, 2026
1e62b45
Narrow output mapping test matrix
desmonddak Oct 19, 2026
9ff4b5e
minor readme update
desmonddak Oct 19, 2026
47d55f8
Address typed operation review feedback
desmonddak Oct 19, 2026
1918cdb
Narrow array synthesis test coverage
desmonddak Oct 19, 2026
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
6 changes: 6 additions & 0 deletions .github/configs/mlc_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@
{
"pattern":"^https://intel\\.github\\.io(?:/|$)"
},
{
"pattern":"^https://marketplace\\.visualstudio\\.com"
},
{
"pattern":"^https://pub\\.dev"
},
{
"pattern":"^https://pymtl3.readthedocs.io/en/latest/$"
},
Expand Down
31 changes: 31 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,37 @@
- Netlist JSON format is now `0.1.0`, preserving enum types and encodings on retained netnames using Yosys-style attributes, including constant-driven enum uses (<https://github.com/intel/rohd/pull/599>).
- Refined the typed-array hierarchy so `LogicArray` directly specializes `TypedLogicArray<Logic, LogicValue>`, and strengthened custom `TypedLogicArray` cloning to preserve runtime types, codecs, unpacked dimensions, and constructor-only naming prefixes without exposing them as public axis metadata (<https://github.com/intel/rohd/pull/686>).
- Expanded `TypedLogicArray` support for recursively nested typed and ordinary arrays, structures containing array fields, mixed packed/unpacked dimensions, structured net and inout ports, and recursive netlist type metadata. Fixed generated SystemVerilog for array-valued elements to use packed offsets consistent with declarations and module-port connections, avoiding invalid chained selections in Icarus and Verilator (<https://github.com/intel/rohd/pull/686>).
- Preserved configured SystemVerilog output object types for nested arrays and added the opt-in `iverilogWorkaroundForUnpackedArrayVariables` setting for child-driven unpacked array variables that remain unknown in Icarus Verilog 12.0 (<https://github.com/intel/rohd/pull/686>).
- `LogicArray` remains source-compatible for construction and operations. Its `value` and `previousValue` now return shape-carrying `LogicValueArray` instances, which remain `LogicValue` subtypes; code relying on their exact concrete runtime types may observe this behavior change (<https://github.com/intel/rohd/pull/686>).
- Added support for structures with constant leaves when their `clone()` implementation produces driveable fields, preserving domain-specific constant structures through generic operations.
- Integrated `LogicEnum` with generic operations. Enum mappings are preserved through typed operation results, enum members can be used as `cases` keys, and incompatible enum mappings are rejected.
- Fixed generic operations to reject incompatible `LogicEnum` mappings inside structures and typed arrays, and to preserve mapped enum constant reset values in netlist register cells.
- `Pipeline.get`, `PipelineStageInfo.get`, and `PipelineStageInfo.getAbs` now preserve each identifier's concrete type through stage reconstruction and SSA, allowing structures, typed arrays, enums, and scalar signals in one pipeline. `ReadyValidPipeline` retains its established multi-signal API and gains the same per-identifier typed access without separate payload pipeline classes.
- Preserved aggregate structure assignment metadata through synthesis and netlist generation.
- Fixed SystemVerilog synthesis of internally computed packed logic assigned to packed-array outputs, retaining required intermediate declarations.
- Upgraded `Mux`, `FlipFlop`, `Passthrough`, `mux`, `flop`, `cases`,
`selectIndex`, and `selectFrom` to preserve compatible concrete `Logic`
subtypes, including nested `LogicArray` and `TypedLogicArray` boundaries.
Removed the parallel structure-only operation APIs.
- **Migration:** plain `Const` and `LogicNet` sources no longer infer
driveable outputs for operations that construct hardware. Request
`<Logic>`, for example `flop<Logic>(clk, Const(1))`, to normalize them.
Use an operation `outputGenerator` when an explicit output representation is
required, including mixed packed and structured `cases` branches.
- **Migration:** type-preserving operations on `TypedLogicArray` operands now
require the identical `valueCodec` instance. Reuse a shared codec or cross
an explicit `packed` boundary to reinterpret compatible bits.
- **Breaking:** Removed compatibility APIs deprecated before `0.6.11`. Use the
canonical `ExternalSystemVerilogModule`, `FiniteStateMachine`, `Sequential`,
`If.block`, `Logic.port`, `LogicValue` `of...` constructors, `SystemVerilog`,
`SynthFileContents`, and instance `clone()` APIs. Apply interface port names
at connection time with `uniquify`; use canonical operation outputs such as
`out` and `sum`; and access signal values through `value`. Compatibility APIs
first deprecated in `0.6.11` remain available, including `generateSynth`,
`WaveDumper`, `hierarchyJSON`, and `contentsByName`.
- Added public `cloneTyped()` and `namedTyped()` conveniences for retaining a
receiver's static type. `Const.cloneTyped()` remains a literal clone;
`Const.namedTyped()` is rejected because a named alias must be driveable.
- Added configurable waveform timescales, recording windows, and output overwrite policies (<https://github.com/intel/rohd/pull/671>).
- Added opt-in `DebugSession` setup for source tracing, netlist and FLC services, and live waveform recording (<https://github.com/intel/rohd/pull/707>).
- Expanded reusable `rohd_devtools_widgets` components for hierarchy browsing, signal formatting, bit expansion, overlays, help, capture, and cross-probing (<https://github.com/intel/rohd/pull/736>).
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ You can also open this repository in a GitHub Codespace to run the example in yo
- Makes **validation collateral** simpler to develop and debug. The [ROHD Verification Framework](https://github.com/intel/rohd-vf) helps build well-structured testbenches
- Powerful capabilities like the [ROHD Schematic Viewer](https://github.com/rohd-schematic-viewer) for high-fidelity rendering of ROHD designs as well as [ROHD Wave Viewer](https://github.com/rohd-wave-viewer) for viewing simulation waveforms even for complex ROHD structures
- Debug your design with [ROHD Live Debugger](https://github.com/intel/rohd/rohd_devtools_extension), an integrated debugger with cross-probing into ROHD source and synthesized RTL output from schematics rendering and waveform display all connected to live RTL simulation
- Support for **cosimulation with verilog modules** (via [ROHD Cosim](https://github.com/intel/rohd-cosim)) and **instantiation of verilog modules** in generated SystemVerilog code
- Support for **cosimulation with Verilog modules** (via [ROHD Cosim](https://github.com/intel/rohd-cosim)) and **instantiation of Verilog modules** in generated SystemVerilog code

ROHD is *not* a new language, it is *not* a hardware description language (HDL), and it is *not* a version of High-Level Synthesis (HLS). ROHD can be classified as a generator framework, extending a powerful software language into the hardware domain and providing a full suite of tools and capabilities to accelerate hardware design and validation.

Expand Down
179 changes: 179 additions & 0 deletions doc/logic_enum_netlist_metadata.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
# LogicEnum JSON Netlist Metadata

## Purpose

This note defines the proposed JSON-netlist work needed after `LogicEnum<T
extends Enum>` from #599 is merged.

The JSON netlist must always preserve hardware behavior as packed bits. The
proposal adds optional metadata so ROHD-aware tools can also preserve the
source-level enum domain, member names, and explicit encodings.

## Current behavior and gap

An enum member can lower to a mapped packed constant, so a generic netlist can
represent its hardware value correctly. For example, a member mapped to
`2'b10` remains two constant bits with that value.

That is not enough for source-aware consumers. Without additional metadata,
the netlist cannot distinguish:

```text
2'b10
```

from:

```text
Mode.execute, where Mode.execute is encoded as 2'b10
```

The SystemVerilog backend can emit enum typedefs and symbolic values, but the
JSON netlist backend currently has no equivalent enum-definition or
enum-reference serialization.

## Design principles

1. `LogicEnum` remains a driveable signal, not a `Const` subtype.
2. Enum member literals continue to lower to ordinary packed constant bits.
3. Metadata supplements bit-accurate netlist output; it must not change
ordinary netlist semantics or require generic netlist consumers to
understand enums.
4. Metadata is emitted only for typed ports and retained named nets, not every
anonymous temporary signal.
5. Explicit conversion to packed `Logic` erases enum-domain metadata.
6. Incompatible enum mappings must never acquire equivalence solely from
matching width.

## Proposed representation

Declare enum definitions once per generated module in module attributes:

```json
{
"attributes": {
"rohd_enum_definitions": {
"Mode": {
"width": 2,
"members": {
"idle": "00",
"execute": "10",
"halt": "11"
}
}
}
}
}
```

Reference the definition from typed ports and retained named nets:

```json
{
"ports": {
"state": {
"direction": "input",
"bits": [1, 2],
"attributes": {
"rohd_enum": "Mode"
}
}
},
"netnames": {
"next_state": {
"bits": [3, 4],
"attributes": {
"rohd_enum": "Mode"
}
}
}
}
```

The exact attribute spelling may change, but the schema must be stable,
versioned, and documented. Member encodings should use an unambiguous
most-significant-bit-first binary representation with no implied ordinal
meaning.

## Synthesis integration

The shared synthesis model should carry an optional enum-domain descriptor
containing:

- enum definition identity;
- width;
- member-to-encoding mapping;
- preferred/reserved definition-name policy; and
- compatibility identity based on Dart enum type and exact mapping.

The netlist translator should consume that descriptor when emitting:

- module-level enum definitions;
- input, output, and inout port attributes;
- retained named internal net attributes; and
- hierarchy boundary metadata where the child and parent domains remain
compatible.

Constant folding must continue to emit raw bit constants. A named enum signal
driven by a legal enum constant may retain its enum attribute; a standalone
constant has no independent enum domain.

## Configuration and versioning

Add a configuration option similar to:

```dart
const NetlistSynthesizerConfiguration(
preserveEnumMetadata: true,
);
```

When disabled, the generated netlist must omit all enum metadata while
preserving exactly the same ports, cells, wire IDs, and packed constant bits.

Adding this schema requires a `NetlistSynthesizer.formatVersion` update and
documentation describing compatibility expectations for consumers.

## Validation

Extend netlist validation to check:

- each enum reference names a definition in its module;
- referenced width matches the associated port or net width;
- member names are unique and valid identifiers for the metadata schema;
- member encodings have the declared width and are unique;
- disabled metadata emits no enum references; and
- aliases and hierarchy transformations do not leave dangling references.

## Required tests

| Scenario | Required assertion |
| --- | --- |
| Enum input and output | Raw bit IDs remain correct and both port attributes reference the expected definition. |
| Named internal enum net | Retained net has the expected enum attribute. |
| Sparse mapping | Metadata preserves non-ordinal member encodings exactly. |
| Enum constant assignment | Netlist retains raw constant bits; the typed destination retains its enum metadata. |
| FSM | State ports/nets retain their mapping, including reset-state encoding. |
| Hierarchy | Compatible enum domains remain annotated across a parent/child boundary. |
| Type mismatch | Incompatible mapping/type connections fail before netlist emission or are explicitly lowered through a packed boundary. |
| Packed conversion | An explicit `Logic` conversion drops enum metadata. |
| Disabled metadata | No enum metadata is emitted and packed netlist behavior is unchanged. |
| Validation | Malformed or dangling enum attributes are rejected. |

Tests should compare both parsed JSON structure and behaviorally relevant bit
connections. They should not rely only on pretty-printed JSON strings.

## Non-goals

- Emitting SystemVerilog typedef syntax in JSON netlists.
- Making a `LogicEnum` signal a constant object.
- Attaching domain metadata to anonymous temporary expressions.
- Treating a whole `LogicStructure`, such as a floating-point value, as an
enum. Structured literals and codecs are a separate abstraction.

## Acceptance criteria

The work is complete when a ROHD-aware netlist consumer can recover the enum
domain and exact member encodings for retained enum signals, while a generic
consumer can ignore the metadata and still consume a correct packed-bit
netlist.
155 changes: 155 additions & 0 deletions doc/logic_enum_typed_operations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
# LogicEnum Integration with Generic Typed Operations

## Purpose

This note records the work required in #704 after `LogicEnum<T extends Enum>`
from #599 is merged and rebased onto the current codebase.

The goal is to make `LogicEnum<T>` a first-class scalar domain type for the
existing generic operation APIs. This work must extend `mux`, `flop`, `cases`,
selection, and passthrough rather than introducing parallel typed-operation
APIs.

## Preconditions

Before implementing this work:

1. Rebase #599 onto current `main`.
2. Preserve the existing `LogicEnum<T>` mapping, clone, assignment, case, FSM,
and SystemVerilog contracts.
3. Keep the generic operation APIs introduced by #704 as the only public
operation spellings.

## Domain and literal contract

`LogicEnum<T>` is a driveable domain signal, not a `Const` subtype.

- A `LogicEnum<T>` clone must retain its Dart enum type, mapping, width,
`definitionName`, and definition-name reservation policy while creating a
driveable signal.
- A Dart enum member is a domain literal only in the context of a
`LogicEnum<T>` mapping. It must never silently mean the member ordinal.
- `getsEnum`, `put`, `inject`, and conditional assignment map a member through
the receiving enum's explicit mapping.
- A packed `Const` may drive an enum only when its exact value is represented
in the enum mapping.
- Raw packed `Logic` may cross into an enum domain under the enum's existing
runtime validation policy. It is an explicit bit-level boundary.
- Requesting `<Logic>` is the explicit domain-erasure path for an operation
result.

These rules match the existing distinction between a literal source and a
driveable operation output.

## Operation behavior

### Mux

`mux<T>` and `Mux<T>` must infer `LogicEnum<T>` from enum operands.

- The default result schema is `d0`, including its mapping and configuration.
- An output generator can intentionally select another compatible enum schema.
- Inputs with different Dart enum types or incompatible mappings must be
rejected rather than reinterpreted by width.
- A constant control without an output generator returns the selected source by
identity.
- A supplied output generator is invoked once and materializes a fresh,
driveable result even for a constant control.
- `mux<Logic>` deliberately drops enum-domain information and operates on
packed bits.

### Flop

`flop<T>` and `FlipFlop<T>` must preserve `LogicEnum<T>`.

- The default result schema is `d`.
- A reset by enum member must use the output mapping.
- A packed reset constant is legal only when its encoding belongs to the
output mapping.
- An unmapped reset value must fail with a mapping-specific diagnostic.
- A reset signal with a compatible enum domain must preserve that domain across
the register boundary.
- `flop<Logic>` is the explicit packed, driveable normalization path.

### Cases

`cases<T>` must distinguish enum selector literals from enum result literals.

- An enum expression may use members of its mapping as case keys.
- Keys not present in the expression mapping must be rejected.
- A bare enum member cannot be a result value because it has no independent
output mapping.
- Result values must be enum signals, or callers must supply an enum output
generator.
- The default result prototype remains the first typed branch unless an output
generator is supplied.
- Mixed packed and enum result branches require an explicit output schema.

### Selection and passthrough

`selectFrom`, `selectIndex`, and `Passthrough` must preserve concrete
`LogicEnum<T>` types and their mappings for homogeneous inputs. Explicit
`Logic` output requests intentionally erase the domain.

## Required test matrix

Add real `LogicEnum` coverage to `test/typed_operations_test.dart`; the
existing scalar-domain test double is not sufficient proof of enum behavior.

| Surface | Required coverage |
| --- | --- |
| Clone and naming | Static type, mapping, width, definition name, reserved definition name, and driveability survive `cloneTyped` and `namedTyped`. |
| Mux | Inferred type, `d0` schema, output generator, constant-control identity, generator materialization, sparse mappings, mapping mismatch rejection, and `<Logic>` erasure. |
| Flop | Inferred type, enable, synchronous/asynchronous reset, enum-member reset, legal packed reset, rejected unmapped reset, and `<Logic>` normalization. |
| Cases | Enum expression/member keys, typed result signals, rejected bare result members, default behavior, mixed packed/domain branches, and output generators. |
| Selection | `selectFrom` and `selectIndex` retain enum type and reject incompatible mappings. |
| Passthrough | Default schema preservation and explicit output generator behavior. |
| Arrays | `TypedLogicArray<LogicEnum<T>, LogicValue>` works through the relevant operations and preserves its element builder and dimensions. |
| Structures | Structures with enum leaves work through mux, flop, cases, selection, and module hierarchy. |
| Backends | ROHD functional simulation, SystemVerilog with enums enabled and disabled, Icarus, and Verilator agree. |

Every synthesized scenario should have a representative nested-composition
test, not only a root-module test.

## FSM coverage

`FiniteStateMachine<T extends Enum>` is a primary user of `LogicEnum`.

Add or retain tests for:

- reset to an enum state;
- legal transitions and default transitions;
- sparse and non-ordinal mappings;
- direct enum-member case labels;
- typed current and next state access;
- generated SystemVerilog enum typedefs and symbolic state members; and
- functional and external-simulator agreement.

Constraining FSM state identifiers to `Enum` is a breaking API change and
needs a release migration note.

## Structures and structured literals

`LogicEnum` should support enum leaves in a `LogicStructure`, but it should
not become a general structured-value abstraction.

A type such as `FloatingPoint` should remain a `LogicStructure` with a
separate literal/codec API, for example `FloatingPoint.one()` or
`FloatingPoint.fromDouble(1.0)`. Such a literal may use constant leaves, but
its `clone()` must construct driveable leaves so generic operations can create
a driveable output while retaining the `FloatingPoint` static type.

This follows the existing structured-constant operation contract and keeps
finite scalar enum domains distinct from arbitrary structured encodings.

## Acceptance criteria

The work is complete when:

1. No parallel typed operation API is introduced.
2. Enum type and mapping information is retained by every applicable generic
operation unless the caller explicitly requests `Logic`.
3. Invalid mappings and unmapped literals fail explicitly.
4. The test matrix above passes in ROHD simulation and emitted-SystemVerilog
simulation.
5. The migration and domain-erasure rules are documented for users.
Loading
Loading