Skip to content

Commit 701bb34

Browse files
committed
Add base SystemC support
1 parent d1c2a3d commit 701bb34

24 files changed

Lines changed: 5667 additions & 63 deletions

.github/workflows/general.yml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,17 +61,33 @@ jobs:
6161
- name: Install software - Icarus Verilog
6262
run: tool/gh_actions/install_iverilog.sh
6363

64+
- name: Install software - Accellera SystemC
65+
run: tool/gh_actions/install_systemc.sh
66+
67+
- name: Pre-build SystemC PCH and Makefile
68+
run: tool/gh_actions/setup_systemc_pch.sh
69+
6470
- name: Run project tests
6571
run: tool/gh_actions/run_tests.sh
6672

73+
- name: Run SystemC tests
74+
run: dart test test/systemc_vector_test.dart
75+
76+
- name: Clean SystemC temporary files
77+
run: tool/gh_actions/cleanup_systemc_tmp.sh
78+
6779
- name: Check temporary test files
6880
run: tool/gh_actions/check_tmp_test.sh
6981

7082
# https://github.com/devcontainers/ci/blob/main/docs/github-action.md
7183
- name: Build dev container and run tests in it
7284
uses: devcontainers/ci@v0.3
7385
with:
74-
runCmd: tool/gh_actions/run_tests.sh
86+
runCmd: |
87+
tool/gh_actions/run_tests.sh
88+
dart test test/systemc_vector_test.dart
89+
tool/gh_actions/cleanup_systemc_tmp.sh
90+
tool/gh_actions/check_tmp_test.sh
7591
7692
deploy-documentation:
7793
name: Deploy Documentation

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
[![Chat](https://img.shields.io/discord/1001179329411166267?label=Chat)](https://discord.gg/jubxF84yGw)
1010
[![License](https://img.shields.io/badge/License-BSD--3-blue)](https://github.com/intel/rohd/blob/main/LICENSE)
1111
[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](https://github.com/intel/rohd/blob/main/CODE_OF_CONDUCT.md)
12-
[![Coverage](https://raw.githubusercontent.com/intel/rohd/refs/heads/badges/coverage/main.svg)](https://github.com/intel/rohd/blob/main/.github/workflows/coverage.yml)
1312

1413
ROHD (pronounced like "road") is a framework for describing and verifying hardware in the Dart programming language.
1514

@@ -45,7 +44,7 @@ You can also open this repository in a GitHub Codespace to run the example in yo
4544
- **Simple and fast build**, free of complex build systems and EDA vendor tools
4645
- Can use the excellent pub.dev **package manager** and all the packages it has to offer
4746
- Built-in event-based **fast simulator** with **4-value** (0, 1, X, and Z) support and a **waveform dumper** to .vcd file format
48-
- Conversion of modules to equivalent, human-readable, structurally similar **SystemVerilog** for integration or downstream tool consumption
47+
- Conversion of modules to equivalent, human-readable, structurally similar **SystemVerilog** and **SystemC** for integration or downstream tool consumption
4948
- **Run-time dynamic** module port definitions (numbers, names, widths, etc.) and internal module logic, including recursive module contents
5049
- Leverage the [ROHD Hardware Component Library (ROHD-HCL)](https://github.com/intel/rohd-hcl) with reusable and configurable design and verification components.
5150
- Simple, free, **open source tool stack** without any headaches from library dependencies, file ordering, elaboration/analysis options, +defines, etc.
@@ -69,5 +68,6 @@ One of ROHD's goals is to help grow an open-source community around reusable har
6968
ROHD is under active development. If you're interested in contributing, have feedback or a question, or found a bug, please see [CONTRIBUTING.md](https://github.com/intel/rohd/blob/main/CONTRIBUTING.md).
7069

7170
----------------
71+
7272
Copyright (C) 2021-2026 Intel Corporation
7373
SPDX-License-Identifier: BSD-3-Clause

dart_test.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Test configuration for ROHD.
2+
#
3+
# To exclude FFI-dependent tests (e.g. in CI without native code support):
4+
# dart test --preset no-ffi
5+
#
6+
# To run all tests including FFI (requires native shared libraries):
7+
# dart test
8+
9+
tags:
10+
ffi:
11+
# Tests requiring dart:ffi and native shared libraries.
12+
13+
presets:
14+
no-ffi:
15+
exclude_tags: ffi

doc/architecture.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ The `Simulator` acts as a statically accessible driver of the overall simulation
2424

2525
### Synthesizer
2626

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

2929
## Organization
3030

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

4545
### Synthesizers
4646

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

4949
### Utilities
5050

doc/user_guide/_docs/A21-generation.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ last_modified_at: 2023-11-13
55
toc: true
66
---
77

8-
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.
8+
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.
99

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

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

2929
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.
3030

31+
## SystemC generation
32+
33+
ROHD can also generate SystemC (C++ with the SystemC library) from the same hardware description. Use the `generateSystemC` helper method:
34+
35+
```dart
36+
void main() async {
37+
final myModule = MyModule();
38+
await myModule.build();
39+
40+
final generatedSc = myModule.generateSystemC();
41+
42+
// write it to a file
43+
File('myHardware.h').writeAsStringSync(generatedSc);
44+
}
45+
```
46+
47+
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>`).
48+
49+
For more control over SystemC generation, use `SynthBuilder` with `SystemCSynthesizer()` directly.
50+
3151
## Controlling naming
3252

3353
### Modules

doc/user_guide/_get-started/01-overview.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Features of ROHD include:
1919
- **Simple and fast build**, free of complex build systems and EDA vendor tools
2020
- Can use the excellent pub.dev **package manager** and all the packages it has to offer
2121
- Built-in event-based **fast simulator** with **4-value** (0, 1, X, and Z) support and a **waveform dumper** to .vcd file format
22-
- Conversion of modules to equivalent, human-readable, structurally similar **SystemVerilog** for integration or downstream tool consumption
22+
- Conversion of modules to equivalent, human-readable, structurally similar **SystemVerilog** and **SystemC** for integration or downstream tool consumption
2323
- **Run-time dynamic** module port definitions (numbers, names, widths, etc.) and internal module logic, including recursive module contents
2424
- Leverage the [ROHD Hardware Component Library (ROHD-HCL)](https://github.com/intel/rohd-hcl) with reusable and configurable design and verification components.
2525
- Simple, free, **open source tool stack** without any headaches from library dependencies, file ordering, elaboration/analysis options, +defines, etc.

lib/src/module.dart

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import 'package:meta/meta.dart';
1414
import 'package:rohd/rohd.dart';
1515
import 'package:rohd/src/collections/traverseable_collection.dart';
1616
import 'package:rohd/src/diagnostics/inspector_service.dart';
17+
import 'package:rohd/src/synthesizers/systemc/systemc.dart';
1718
import 'package:rohd/src/utilities/config.dart';
1819
import 'package:rohd/src/utilities/namer.dart';
1920
import 'package:rohd/src/utilities/sanitizer.dart';
@@ -1155,6 +1156,27 @@ abstract class Module {
11551156
.getSynthFileContents()
11561157
.join('\n\n////////////////////\n\n');
11571158
}
1159+
1160+
/// Returns a synthesized SystemC version of this [Module].
1161+
///
1162+
/// Generates SystemC code that is equivalent to the hardware described by
1163+
/// this module, using the same naming strategy as [generateSynth].
1164+
String generateSystemC() {
1165+
if (!_hasBuilt) {
1166+
throw ModuleNotBuiltException(this);
1167+
}
1168+
1169+
final synthBuilder = SynthBuilder(this, SystemCSynthesizer());
1170+
final moduleContents =
1171+
synthBuilder.getSynthFileContents().map((e) => e.contents).join('\n');
1172+
return '// Generated by ROHD - www.github.com/intel/rohd\n'
1173+
'// Generation time: ${Timestamper.stamp()}\n'
1174+
'// ROHD Version: ${Config.version}\n'
1175+
'\n'
1176+
'#include <systemc.h>\n'
1177+
'\n'
1178+
'$moduleContents';
1179+
}
11581180
}
11591181

11601182
extension on LogicStructure {

lib/src/modules/conditionals/flop.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,11 @@ class FlipFlop extends Module with SystemVerilog {
8888
/// Only initialized if a constant value is provided.
8989
late LogicValue _resetValueConst;
9090

91+
/// Returns the constant reset value if one was provided, or null if the
92+
/// reset value is a port or no reset exists.
93+
LogicValue? get constantResetValue =>
94+
_reset != null && _resetValuePort == null ? _resetValueConst : null;
95+
9196
/// Indicates whether provided `reset` signals should be treated as an async
9297
/// reset. If no `reset` is provided, this will have no effect.
9398
final bool asyncReset;

lib/src/modules/conditionals/sequential.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,14 @@ class Sequential extends Always {
135135
/// The input edge triggers used in this block.
136136
final List<_SequentialTrigger> _triggers = [];
137137

138+
/// Returns the edge polarity for each trigger input port.
139+
///
140+
/// Each entry pairs the trigger input port name with whether the trigger
141+
/// fires on a positive edge (`true`) or negative edge (`false`).
142+
List<({String portName, bool isPosedge})> get triggerEdges => _triggers
143+
.map((t) => (portName: t.signal.name, isPosedge: t.isPosedge))
144+
.toList();
145+
138146
/// When `false`, an [SignalRedrivenException] will be thrown during
139147
/// simulation if the same signal is driven multiple times within this
140148
/// [Sequential].
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright (C) 2021-2026 Intel Corporation
2+
// SPDX-License-Identifier: BSD-3-Clause
3+
//
4+
// systemc_synthesizer.dart
5+
// Definition for SystemC Synthesizer
6+
//
7+
// 2026 May
8+
// Author: Desmond A. Kirkpatrick <desmond.a.kirkpatrick@intel.com>
9+
10+
import 'package:rohd/rohd.dart';
11+
import 'package:rohd/src/synthesizers/systemc/systemc_synthesis_result.dart';
12+
13+
/// A [Synthesizer] which generates equivalent SystemC as the given [Module].
14+
///
15+
/// Attempts to maintain signal naming and structure as much as possible,
16+
/// using the same naming strategy as the SystemVerilog synthesizer.
17+
class SystemCSynthesizer extends Synthesizer {
18+
@override
19+
bool generatesDefinition(Module module) =>
20+
// ignore: deprecated_member_use_from_same_package
21+
!((module is CustomSystemVerilog) ||
22+
(module is SystemVerilog &&
23+
module.generatedDefinitionType == DefinitionGenerationType.none));
24+
25+
@override
26+
SynthesisResult synthesize(Module module,
27+
String Function(Module module) getInstanceTypeOfModule) =>
28+
SystemCSynthesisResult(module, getInstanceTypeOfModule);
29+
}

0 commit comments

Comments
 (0)