Skip to content
Open
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
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: Clean SystemC temporary files
run: tool/gh_actions/cleanup_systemc_tmp.sh

- 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
tool/gh_actions/cleanup_systemc_tmp.sh
tool/gh_actions/check_tmp_test.sh

deploy-documentation:
name: Deploy Documentation
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
[![Chat](https://img.shields.io/discord/1001179329411166267?label=Chat)](https://discord.gg/jubxF84yGw)
[![License](https://img.shields.io/badge/License-BSD--3-blue)](https://github.com/intel/rohd/blob/main/LICENSE)
[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](https://github.com/intel/rohd/blob/main/CODE_OF_CONDUCT.md)
[![Coverage](https://raw.githubusercontent.com/intel/rohd/refs/heads/badges/coverage/main.svg)](https://github.com/intel/rohd/blob/main/.github/workflows/coverage.yml)

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

Expand Down Expand Up @@ -45,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 All @@ -69,5 +68,6 @@ One of ROHD's goals is to help grow an open-source community around reusable har
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).

----------------

Copyright (C) 2021-2026 Intel Corporation
SPDX-License-Identifier: BSD-3-Clause
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
38 changes: 34 additions & 4 deletions 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,15 +28,45 @@ 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 port types

Generated ports have explicit object and data types by default: inputs are `input wire logic`, outputs are `output var logic`, and inouts are `inout wire logic`. Use a `SystemVerilogSynthesizerConfiguration` to omit either category and rely on SystemVerilog's implicit types:
Generated ports default to `input logic`, `output logic`, and `inout wire`, preserving the traditional ROHD declarations. Use a `SystemVerilogSynthesizerConfiguration` to independently control whether object types, such as `wire` and `var`, and data types, such as `logic`, are explicit for each port direction:

```dart
final generatedSv = myModule.generateSynth(
configuration: const SystemVerilogSynthesizerConfiguration(
portObjectType: SystemVerilogPortType.implicit,
portDataType: SystemVerilogPortType.implicit,
inputPortType: SystemVerilogPortTypeConfiguration(
objectType: SystemVerilogPortType.explicit,
dataType: SystemVerilogPortType.implicit,
),
outputPortType: SystemVerilogPortTypeConfiguration(
objectType: SystemVerilogPortType.implicit,
dataType: SystemVerilogPortType.implicit,
),
inOutPortType: SystemVerilogPortTypeConfiguration(
objectType: SystemVerilogPortType.implicit,
dataType: SystemVerilogPortType.explicit,
),
),
);
```
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
22 changes: 22 additions & 0 deletions lib/src/module.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ 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/synthesizers/systemc/systemc.dart';
import 'package:rohd/src/utilities/config.dart';
import 'package:rohd/src/utilities/namer.dart';
import 'package:rohd/src/utilities/sanitizer.dart';
Expand Down Expand Up @@ -1161,6 +1162,27 @@ abstract class Module {
SystemVerilogSynthesizer(configuration: configuration),
).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() {
Comment thread
desmonddak marked this conversation as resolved.
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
Loading
Loading