Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
82e900e
move synthesis naming to a common naming utility so all synthesizers …
desmonddak Apr 17, 2026
85f88ce
dart 3.11 parameter_assignments pickiness
desmonddak Apr 17, 2026
b1de1e5
Merge branch 'main' into central_naming
desmonddak Apr 17, 2026
b7087c4
conflict resolved and dart format . works
desmonddak Apr 17, 2026
4a55214
properly assign naming spaces for instances vs signals
desmonddak Apr 18, 2026
ed7be36
format issue
desmonddak Apr 18, 2026
ab09aed
Controllable enforcement of signal vs instance name uniqueness.
desmonddak Apr 19, 2026
520d280
Refactored to Namer class. No external API changes for ROHD
desmonddak Apr 19, 2026
61d0319
signal registry
desmonddak Apr 20, 2026
becdb36
module context name uniquification instead of signal/instance split
desmonddak May 1, 2026
a86f80c
Merge branch 'main' into central_naming
desmonddak May 3, 2026
d5904a6
cleanup of port vs signal name assumptions, constant merging and sign…
desmonddak May 3, 2026
3645293
Add ModuleServices singleton and SvService
desmonddak May 6, 2026
f918ec7
first passing version of SystemC translated tests
desmonddak May 8, 2026
91604b1
SystemC and SV tests are comingled.
desmonddak May 8, 2026
810eec7
we need sudo in installation scripts
desmonddak May 8, 2026
6c39020
avoid a race and using a lock for SystemC
desmonddak May 8, 2026
340af62
cascade introduced
desmonddak May 9, 2026
0b4732b
use BigInt.one shifted instead of a platform-dependent constant
desmonddak May 9, 2026
6aeb6aa
JS platform skip SystemC
desmonddak May 9, 2026
832ef9f
cleanup tmp_test after systemc tests
desmonddak May 9, 2026
4b92fc6
create test dir
desmonddak May 9, 2026
824a191
cascade issue
desmonddak May 9, 2026
de589e5
yet another JS issue
desmonddak May 9, 2026
d0e985b
trying to match devcontainer to normal ci
desmonddak May 9, 2026
60974d7
dart tests using ffi to drive systemc
desmonddak May 21, 2026
1951d17
fixed recent analyzer failure (version change)
desmonddak May 21, 2026
e4d931d
skip FFI tests in CI as dart:ffi is not available
desmonddak May 21, 2026
0ea6f1e
remove netlist leakage into this branch
desmonddak May 22, 2026
d1da6a2
module_services_test only on vm
desmonddak May 22, 2026
1989dd0
resolve naming crash for systemc and ensure names are aligned
desmonddak May 23, 2026
6ca2e8c
fix perf problem reported by Carlos
desmonddak May 27, 2026
cb11009
feat(systemc): scLineMap records all assignment LHS positions
desmonddak May 27, 2026
881fb08
formatting
desmonddak May 28, 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
14 changes: 13 additions & 1 deletion .github/workflows/general.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,29 @@ jobs:
- name: Install software - Icarus Verilog
run: tool/gh_actions/install_iverilog.sh

- name: Install software - Accellera SystemC
run: tool/gh_actions/install_systemc.sh

- name: Pre-build SystemC PCH and Makefile
run: tool/gh_actions/setup_systemc_pch.sh

- name: Run project tests
run: tool/gh_actions/run_tests.sh

- name: Run SystemC tests
run: dart test test/systemc_vector_test.dart

- name: Check temporary test files
run: tool/gh_actions/check_tmp_test.sh

# https://github.com/devcontainers/ci/blob/main/docs/github-action.md
- name: Build dev container and run tests in it
uses: devcontainers/ci@v0.3
with:
runCmd: tool/gh_actions/run_tests.sh
runCmd: |
tool/gh_actions/run_tests.sh
dart test test/systemc_vector_test.dart
tool/gh_actions/check_tmp_test.sh

deploy-documentation:
name: Deploy Documentation
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ You can also open this repository in a GitHub Codespace to run the example in yo
- **Simple and fast build**, free of complex build systems and EDA vendor tools
- Can use the excellent pub.dev **package manager** and all the packages it has to offer
- Built-in event-based **fast simulator** with **4-value** (0, 1, X, and Z) support and a **waveform dumper** to .vcd file format
- Conversion of modules to equivalent, human-readable, structurally similar **SystemVerilog** for integration or downstream tool consumption
- Conversion of modules to equivalent, human-readable, structurally similar **SystemVerilog** and **SystemC** for integration or downstream tool consumption
- **Run-time dynamic** module port definitions (numbers, names, widths, etc.) and internal module logic, including recursive module contents
- Leverage the [ROHD Hardware Component Library (ROHD-HCL)](https://github.com/intel/rohd-hcl) with reusable and configurable design and verification components.
- Simple, free, **open source tool stack** without any headaches from library dependencies, file ordering, elaboration/analysis options, +defines, etc.
Expand Down
15 changes: 15 additions & 0 deletions dart_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Test configuration for ROHD.
#
# To exclude FFI-dependent tests (e.g. in CI without native code support):
# dart test --preset no-ffi
#
# To run all tests including FFI (requires native shared libraries):
# dart test

tags:
ffi:
# Tests requiring dart:ffi and native shared libraries.

presets:
no-ffi:
exclude_tags: ffi
4 changes: 2 additions & 2 deletions doc/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ The `Simulator` acts as a statically accessible driver of the overall simulation

### Synthesizer

A separate type of object responsible for taking a `Module` and converting it to some output, such as SystemVerilog.
A separate type of object responsible for taking a `Module` and converting it to some output, such as SystemVerilog or SystemC.

## Organization

Expand All @@ -44,7 +44,7 @@ Contains a collection of `Module` implementations that can be used as primitive

### Synthesizers

Contains logic for synthesizing `Module`s into some output. It is structured to maximize reusability across different output types (including those not yet supported).
Contains logic for synthesizing `Module`s into some output (e.g. SystemVerilog, SystemC). It is structured to maximize reusability across different output types.

### Utilities

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import '../../chapter_3/answers/helper.dart';
import '../../chapter_5/answers/full_subtractor.dart';

class FullSubtractorComb extends FullSubtractor {
@override
FullSubtractorComb(super.a, super.b, super.borrowIn) {
// Declare input and output
final a = input('a');
Expand Down
22 changes: 21 additions & 1 deletion doc/user_guide/_docs/A21-generation.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ last_modified_at: 2023-11-13
toc: true
---

Hardware in ROHD is convertible to an output format via `Synthesizer`s, the most popular of which is SystemVerilog. Hardware in ROHD can be converted to logically equivalent, human-readable SystemVerilog with structure, hierarchy, ports, and names maintained.
Hardware in ROHD is convertible to an output format via `Synthesizer`s. The most popular output format is SystemVerilog, with SystemC also available. Hardware in ROHD can be converted to logically equivalent, human-readable SystemVerilog or SystemC with structure, hierarchy, ports, and names maintained.

The simplest way to generate SystemVerilog is with the helper method `generateSynth` in `Module`:

Expand All @@ -28,6 +28,26 @@ void main() async {

The `generateSynth` function will return a `String` with the SystemVerilog `module` definitions for the top-level it is called on, as well as any sub-modules (recursively). You can dump the entire contents to a file and use it anywhere you would any other SystemVerilog.

## SystemC generation

ROHD can also generate SystemC (C++ with the SystemC library) from the same hardware description. Use the `generateSystemC` helper method:

```dart
void main() async {
final myModule = MyModule();
await myModule.build();

final generatedSc = myModule.generateSystemC();

// write it to a file
File('myHardware.h').writeAsStringSync(generatedSc);
}
```

The generated SystemC uses `SC_MODULE`, `SC_METHOD`, and `SC_CTHREAD` constructs. Combinational logic becomes `SC_METHOD` processes, sequential logic (flip-flops and `Sequential` blocks) sharing the same clock and reset are consolidated into a single `SC_CTHREAD`, and sub-modules are instantiated with port bindings. All signal types map to SystemC equivalents (`bool`, `sc_uint<N>`, `sc_biguint<N>`).

For more control over SystemC generation, use `SynthBuilder` with `SystemCSynthesizer()` directly.

## Controlling naming

### Modules
Expand Down
2 changes: 1 addition & 1 deletion doc/user_guide/_get-started/01-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Features of ROHD include:
- **Simple and fast build**, free of complex build systems and EDA vendor tools
- Can use the excellent pub.dev **package manager** and all the packages it has to offer
- Built-in event-based **fast simulator** with **4-value** (0, 1, X, and Z) support and a **waveform dumper** to .vcd file format
- Conversion of modules to equivalent, human-readable, structurally similar **SystemVerilog** for integration or downstream tool consumption
- Conversion of modules to equivalent, human-readable, structurally similar **SystemVerilog** and **SystemC** for integration or downstream tool consumption
- **Run-time dynamic** module port definitions (numbers, names, widths, etc.) and internal module logic, including recursive module contents
- Leverage the [ROHD Hardware Component Library (ROHD-HCL)](https://github.com/intel/rohd-hcl) with reusable and configurable design and verification components.
- Simple, free, **open source tool stack** without any headaches from library dependencies, file ordering, elaboration/analysis options, +defines, etc.
Expand Down
1 change: 1 addition & 0 deletions lib/rohd.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (C) 2021-2023 Intel Corporation
// SPDX-License-Identifier: BSD-3-Clause

export 'src/diagnostics/module_services.dart';
export 'src/exceptions/exceptions.dart';
export 'src/external.dart';
export 'src/finite_state_machine.dart';
Expand Down
78 changes: 78 additions & 0 deletions lib/src/diagnostics/module_services.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright (C) 2026 Intel Corporation
// SPDX-License-Identifier: BSD-3-Clause
//
// module_services.dart
// Singleton service registry for DevTools integration.
//
// 2026 April 25
// Author: Desmond Kirkpatrick <desmond.a.kirkpatrick@intel.com>

import 'dart:convert';

import 'package:rohd/rohd.dart';
import 'package:rohd/src/diagnostics/inspector_service.dart';

/// Singleton service registry that provides a unified query surface for
/// DevTools and other inspection tools.
///
/// Services register themselves here on construction; DevTools evaluates
/// getters on [instance] via `EvalOnDartLibrary` to pull data.
///
/// **Auto-registered:**
/// - [rootModule] / [hierarchyJSON] — set by [Module.build].
///
/// **Opt-in (registered by service constructors):**
/// - [svService] — SystemVerilog synthesis results.
///
/// Additional services (netlist, trace, waveform) can be added by setting
/// the corresponding field after construction.
class ModuleServices {
ModuleServices._();

/// The singleton instance.
static final ModuleServices instance = ModuleServices._();

// ─── Hierarchy (auto-registered by Module.build) ──────────────

/// The most recently built top-level [Module].
///
/// Set automatically at the end of [Module.build].
Module? rootModule;

/// Returns the module hierarchy as a JSON string.
///
/// DevTools evaluates this via `EvalOnDartLibrary` to display
/// the module hierarchy.
String get hierarchyJSON {
ModuleTree.rootModuleInstance = rootModule;
return ModuleTree.instance.hierarchyJSON;
}

/// Returns the primary inspector JSON for DevTools.
///
/// Returns the hierarchy JSON. Downstream branches (e.g. netlist) may
/// override this to return richer data when available.
String get inspectorJSON => hierarchyJSON;

// ─── SystemVerilog service (opt-in) ───────────────────────────

/// The active [SvService], if one has been registered.
SvService? svService;

/// Returns SV synthesis metadata as JSON, or an unavailable status.
String get svJSON =>
svService != null ? jsonEncode(svService!.toJson()) : _unavailable('sv');

// ─── Helpers ──────────────────────────────────────────────────

static String _unavailable(String service) => jsonEncode(<String, String>{
'status': 'unavailable',
'reason': '$service service not registered',
});

/// Resets all services. Intended for test teardown.
void reset() {
rootModule = null;
svService = null;
}
}
44 changes: 40 additions & 4 deletions lib/src/module.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2021-2025 Intel Corporation
// Copyright (C) 2021-2026 Intel Corporation
// SPDX-License-Identifier: BSD-3-Clause
//
// module.dart
Expand All @@ -11,11 +11,10 @@ import 'dart:async';
import 'dart:collection';

import 'package:meta/meta.dart';

import 'package:rohd/rohd.dart';
import 'package:rohd/src/collections/traverseable_collection.dart';
import 'package:rohd/src/diagnostics/inspector_service.dart';
import 'package:rohd/src/utilities/config.dart';
import 'package:rohd/src/utilities/namer.dart';
import 'package:rohd/src/utilities/sanitizer.dart';
import 'package:rohd/src/utilities/timestamper.dart';
import 'package:rohd/src/utilities/uniquifier.dart';
Expand Down Expand Up @@ -52,6 +51,22 @@ abstract class Module {
/// An internal mapping of input names to their sources to this [Module].
late final Map<String, Logic> _inputSources = {};

// ─── Central naming (Namer) ─────────────────────────────────────

/// Central namer that owns both the signal and instance namespaces.
/// Initialized lazily on first access (after build).
@internal
late final Namer namer = _createNamer();

Namer _createNamer() {
assert(hasBuilt, 'Module must be built before canonical names are bound.');
return Namer.forModule(
inputs: _inputs,
outputs: _outputs,
inOuts: _inOuts,
);
}

/// An internal mapping of inOut names to their sources to this [Module].
late final Map<String, Logic> _inOutSources = {};

Expand Down Expand Up @@ -317,7 +332,7 @@ abstract class Module {

_hasBuilt = true;

ModuleTree.rootModuleInstance = this;
ModuleServices.instance.rootModule = this;
}

/// Confirms that the post-[build] hierarchy is valid.
Expand Down Expand Up @@ -1131,6 +1146,27 @@ abstract class Module {
.getSynthFileContents()
.join('\n\n////////////////////\n\n');
}

/// Returns a synthesized SystemC version of this [Module].
///
/// Generates SystemC code that is equivalent to the hardware described by
/// this module, using the same naming strategy as [generateSynth].
String generateSystemC() {
if (!_hasBuilt) {
throw ModuleNotBuiltException(this);
}

final synthBuilder = SynthBuilder(this, SystemCSynthesizer());
final moduleContents =
synthBuilder.getSynthFileContents().map((e) => e.contents).join('\n');
return '// Generated by ROHD - www.github.com/intel/rohd\n'
'// Generation time: ${Timestamper.stamp()}\n'
'// ROHD Version: ${Config.version}\n'
'\n'
'#include <systemc.h>\n'
'\n'
'$moduleContents';
}
}

extension on LogicStructure {
Expand Down
5 changes: 5 additions & 0 deletions lib/src/modules/conditionals/flop.dart
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ class FlipFlop extends Module with SystemVerilog {
/// Only initialized if a constant value is provided.
late LogicValue _resetValueConst;

/// Returns the constant reset value if one was provided, or null if the
/// reset value is a port or no reset exists.
LogicValue? get constantResetValue =>
_reset != null && _resetValuePort == null ? _resetValueConst : null;

/// Indicates whether provided `reset` signals should be treated as an async
/// reset. If no `reset` is provided, this will have no effect.
final bool asyncReset;
Expand Down
8 changes: 8 additions & 0 deletions lib/src/modules/conditionals/sequential.dart
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,14 @@ class Sequential extends Always {
/// The input edge triggers used in this block.
final List<_SequentialTrigger> _triggers = [];

/// Returns the edge polarity for each trigger input port.
///
/// Each entry pairs the trigger input port name with whether the trigger
/// fires on a positive edge (`true`) or negative edge (`false`).
List<({String portName, bool isPosedge})> get triggerEdges => _triggers
.map((t) => (portName: t.signal.name, isPosedge: t.isPosedge))
.toList();

/// When `false`, an [SignalRedrivenException] will be thrown during
/// simulation if the same signal is driven multiple times within this
/// [Sequential].
Expand Down
2 changes: 1 addition & 1 deletion lib/src/synthesizers/synth_builder.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2021-2025 Intel Corporation
// Copyright (C) 2021-2026 Intel Corporation
// SPDX-License-Identifier: BSD-3-Clause
//
// synth_builder.dart
Expand Down
3 changes: 1 addition & 2 deletions lib/src/synthesizers/synthesizer.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
// Copyright (C) 2021-2023 Intel Corporation
// Copyright (C) 2021-2026 Intel Corporation
// SPDX-License-Identifier: BSD-3-Clause
//
// synthesizer.dart
// Generic definition for something that synthesizes output files
//
// 2021 August 26
// Author: Max Korbel <max.korbel@intel.com>
//

import 'package:rohd/rohd.dart';

Expand Down
1 change: 1 addition & 0 deletions lib/src/synthesizers/synthesizers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export 'synth_builder.dart';
export 'synth_file_contents.dart';
export 'synthesis_result.dart';
export 'synthesizer.dart';
export 'systemc/systemc.dart';
export 'systemverilog/systemverilog.dart';
29 changes: 29 additions & 0 deletions lib/src/synthesizers/systemc/systemc.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (C) 2021-2026 Intel Corporation
// SPDX-License-Identifier: BSD-3-Clause
//
// systemc_synthesizer.dart
// Definition for SystemC Synthesizer
//
// 2026 May
// Author: Desmond A. Kirkpatrick <desmond.a.kirkpatrick@intel.com>

import 'package:rohd/rohd.dart';
import 'package:rohd/src/synthesizers/systemc/systemc_synthesis_result.dart';

/// A [Synthesizer] which generates equivalent SystemC as the given [Module].
///
/// Attempts to maintain signal naming and structure as much as possible,
/// using the same naming strategy as the SystemVerilog synthesizer.
class SystemCSynthesizer extends Synthesizer {
@override
bool generatesDefinition(Module module) =>
// ignore: deprecated_member_use_from_same_package
!((module is CustomSystemVerilog) ||
(module is SystemVerilog &&
module.generatedDefinitionType == DefinitionGenerationType.none));

@override
SynthesisResult synthesize(Module module,
String Function(Module module) getInstanceTypeOfModule) =>
SystemCSynthesisResult(module, getInstanceTypeOfModule);
}
Loading
Loading