Skip to content
3 changes: 3 additions & 0 deletions .github/configs/mlc_config.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{
"ignorePatterns": [
{
"pattern": "^https://standards.ieee.org/ieee/1800/7743/$"
},
{
"pattern": "^https://www.cadence.com/en_US/home/tools/digital-design-and-signoff/synthesis/stratus-high-level-synthesis.html$"
},
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
[![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.
ROHD (pronounced like "road") is a silicon-proven framework for describing and verifying hardware in the Dart programming language.

## Documentation

Expand Down
24 changes: 12 additions & 12 deletions doc/tutorials/chapter_6/00_combinational_logic.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,39 +85,39 @@ If.block([

### Add the condition inside the conditional Block

`Iff(condition, then: [])`: `Iff` Statement, if condition is matched, then execute the `then` condition.
`Iff(condition, [])`: `Iff` Statement, if condition is matched, then execute the `then` condition.

```dart
// template
If.block([
Iff(condition, then: [
Iff(condition, [
// You can wrap condition here
]),
]); // If.block

// example
If.block([
Iff(a.eq(0), then: [
Iff(a.eq(0), [
sum < 0
]),
]); // If.block
```

`ElseIf(condition, then: [])`: `ElseIf` Statement, if the condition in `Iff` is not matched, its will skip and look for next condition in `ElseIf` condition, then execute the `then`.
`ElseIf(condition, [])`: `ElseIf` Statement, if the condition in `Iff` is not matched, its will skip and look for next condition in `ElseIf` condition, then execute the `then`.

```dart
// template
If.block([
Iff(condition, then: []), // If statement
ElseIf(condition, then: []) // Else If Statement
Iff(condition, []), // If statement
ElseIf(condition, []) // Else If Statement
]); // If.block

// example
If.block([
Iff(a.eq(0), then: [
Iff(a.eq(0), [
sum < 1
]), // If statement
ElseIf(b.eq(0), then: [
ElseIf(b.eq(0), [
sum < 0
]) // Else If Statement
]); // If.block
Expand All @@ -127,17 +127,17 @@ If.block([

```dart
If.block([
Iff(condition, then: []), // If statement
ElseIf(condition, then: []), // Else If Statement
Iff(condition, []), // If statement
ElseIf(condition, []), // Else If Statement
Else([]) // execute this
]); // If.block

// example
If.block([
Iff(a.eq(0), then: [
Iff(a.eq(0), [
sum < 0
]), // If statement
ElseIf(b.eq(0), then: [
ElseIf(b.eq(0), [
sum < 1
]), // Else If Statement
Else([
Expand Down
4 changes: 2 additions & 2 deletions doc/user_guide/_docs/A07-bus-ranges-and-swizzling.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ var a = Logic(width:8),
e = Logic(width: 9);


// assign b to the bottom 3 bits of a
// assign b to be driven by the bottom 3 bits of a
b <= a.slice(2,0);

// assign d to the top bit of a
// assign d to be driven by the top bit of a
d <= a[7];

// construct e by swizzling bits from b, c, and d
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ last_modified_at: 2024-6-3
toc: true
---

Many of the basic built-in gates in Dart implement custom behavior. An implementation of the `NotGate` is shown below as an example. There is different syntax for functions which can be inlined versus those which cannot (the `~` can be inlined). In this case, the `InlineSystemVerilog` mixin is used, but if it were not inlineable, you could use the `SystemVerilog` mixin instead. Note that it is mandatory to provide an initial value computation when the module is first created for non-sequential modules.
Many of the basic built-in gates in ROHD implement custom behavior. An implementation of the `NotGate` is shown below as an example. There is different syntax for functions which can be inlined versus those which cannot (the `~` can be inlined). In this case, the `InlineSystemVerilog` mixin is used, but if it were not inlineable, you could use the `SystemVerilog` mixin instead. Note that it is mandatory to provide an initial value computation when the module is first created for non-sequential modules.

```dart
/// A gate [Module] that performs bit-wise inversion.
Expand Down
168 changes: 127 additions & 41 deletions doc/user_guide/_docs/B02-comparisons-with-alternatives.md

Large diffs are not rendered by default.

50 changes: 46 additions & 4 deletions doc/user_guide/_get-started/01-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
title: "Overview"
permalink: /get-started/overview/
excerpt: "Overview of ROHD framework."
last_modified_at: 2024-01-04
last_modified_at: 2026-07-16
toc: true
---

## Describing Hardware in Dart with ROHD

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

Features of ROHD include:

Expand Down Expand Up @@ -40,9 +40,9 @@ One of ROHD's goals is to help grow an open-source community around reusable har

## Why Dart?

Dart is a modern, relatively new language developed by Google. It is designed with client-side application development in mind (e.g. apps and websites), but also has great performance for general tasks. It adopts some of the most loved syntax and features from languages like C++, Java, C#, JavaScript/TypeScript, and Kotlin. Dart is extremely user-friendly, fun to use, and **easy to learn**. The excellent, fast static analysis with a modern IDE with autocomplete makes it easy to learn as you work. Dart has a lot of great modern language features, including null safety.
[Dart](https://dart.dev/) is a modern, relatively new, [extremely popular](https://survey.stackoverflow.co/2024/technology#most-popular-technologies) ([top-20](https://redmonk.com/sogrady/2024/09/12/language-rankings-6-24/)) language developed by Google. It is designed with client-side application development in mind (e.g. apps and websites), but also has great performance for general tasks. It adopts some of the most loved syntax and features from languages like C++, Java, C#, JavaScript/TypeScript, and Kotlin. Dart is extremely user-friendly, fun to use, and [**easy to learn** with **excellent documentation**](https://dart.dev/language). The excellent, fast static analysis with a modern IDE with autocomplete makes it easy to learn as you work. Dart has a lot of great modern language features, including null safety.

Because it is designed with asynchronous requests in mind (i.e. sending a request to a server and not freezing the application while it waits for a response), Dart has `async`/`await` and `Future`s built in, with [concurrent programming](https://dart.dev/language/concurrency). These constructs enable code to execute in parallel without multithreading. These chacteristics make modelling hardware very easy.
Because it is designed with asynchronous requests in mind (i.e. sending a request to a server and not freezing the application while it waits for a response), Dart has `async`/`await` and `Future`s built in, with [concurrent programming](https://dart.dev/language/concurrency). These constructs enable code to execute in parallel without multithreading. These characteristics make modelling, interacting with, and verifying hardware very easy.

Dart can compile to native machine code, but also includes its own high-performance VM and a JIT compiler. During development, you can use a feature called "hot reload" to change code while the program is actively executing.

Expand All @@ -63,3 +63,45 @@ Try out Dart instantly from your browser here (it supports ROHD too!): <https://
See some Dart language samples here: <https://dart.dev/language>

For more information on Dart and tutorials, see <https://dart.dev/> and <https://dart.dev/overview>

## Trusting ROHD

A reasonable concern when adopting any hardware generator is whether the model that was developed and simulated matches the generated RTL. ROHD addresses that concern by keeping generation inspectable, testing the same behavior through independent simulation paths, and making the complete implementation available for review.

### Inspectable, structural generation

ROHD is an RTL construction framework, not an HLS compiler that infers a microarchitecture from an algorithm. Modules, signals, assignments, and conditional or sequential logic in a ROHD model are translated into recognizable SystemVerilog structures. Module hierarchy and user-provided names are preserved where the generated structure permits it.

Generation is not a literal one-object-to-one-declaration mapping. ROHD performs mechanical simplifications such as collapsing intermediate connections and pruning unused objects. These transformations reduce unnecessary generated code without choosing an architecture on the designer's behalf. The result is intended to remain human-readable and structurally close enough to the model that a reviewer can trace signals and module boundaries through the generated RTL.

Generated SystemVerilog is also an ordinary artifact: it can be inspected, diffed, linted, simulated, synthesized, or checked with formal tools before it is accepted into a downstream flow.

### Safer SystemVerilog by construction

ROHD does not expose arbitrary SystemVerilog syntax for synthesizable hardware construction. Its APIs describe hardware intent, and the generator selects the appropriate SystemVerilog construct. This makes entire classes of legal-looking but incorrect RTL difficult or impossible to express.

For example, a conditional assignment is written the same way inside ROHD `Combinational` and `Sequential` blocks. The generator emits blocking assignments (`=`) in the corresponding `always_comb` block and non-blocking assignments (`<=`) in the corresponding `always_ff` block. A developer cannot accidentally select the wrong assignment semantics because that choice is not exposed by the ROHD API.

ROHD also checks widths and block configurations and detects problematic patterns such as combinational write-after-read that could produce simulation and synthesis mismatches. These restrictions do not guarantee that every constructible design is correct, but they substantially reduce the SystemVerilog surface area where subtle mistakes can hide.

Producing lint-clean SystemVerilog is also an explicit design goal. ROHD prefers explicit, sometimes more verbose output when it avoids common lint or portability issues, sanitizes and uniquifies generated names, manages widths, and removes unnecessary intermediate signals and assignments. The cross-simulator test infrastructure treats unexpected Icarus Verilog warnings as failures by default, and targeted tests protect against known lint-sensitive generation patterns. No generator can guarantee zero diagnostics under every vendor and ruleset, but ROHD actively designs and tests its output to minimize them.

### The same tests through independent simulators

The ROHD test suite repeatedly checks the boundary between the in-memory model and generated SystemVerilog. Its [`SimCompare`](https://github.com/intel/rohd/blob/main/lib/src/utilities/simcompare.dart) utility applies test vectors to the built-in ROHD simulator, converts those vectors into a SystemVerilog testbench, and runs the generated design with Icarus Verilog. The [tests](https://github.com/intel/rohd/tree/main/test) use this pattern across arithmetic, conditional and sequential logic, arrays, interfaces, nets, naming, and module composition.

The [continuous integration workflow](https://github.com/intel/rohd/blob/main/.github/workflows/general.yml) installs Icarus Verilog and runs the project tests for every pull request and every push to the main branch. A change to simulation or generation therefore has to satisfy both execution paths before it can be merged.

### Deliberately conservative simulation semantics

ROHD supports four-state values (`0`, `1`, `x`, and `z`), but it does not attempt to reproduce every permissive or tool-specific corner of SystemVerilog simulation. Ambiguous behavior is generally rejected or propagated as unknown instead of being accepted silently. For example, transitions involving `x` or `z` are not treated as valid clock edges, and conditional logic propagates unknown values when selecting a deterministic branch would hide ambiguity.

This conservative behavior helps expose questionable assumptions earlier. It also means that designs which intentionally depend on simulator-specific `x` or `z` behavior deserve explicit comparison in the downstream SystemVerilog simulator.

### Trusting ROHD like any other EDA tool

Trust in an EDA tool is not all-or-nothing. Engineers decide how much confidence to place in simulators, synthesizers, linters, and formal tools based on their testing, track record, transparency, and the consequences of a failure. Familiarity and vendor reputation can make established SystemVerilog tools feel unquestionably reliable, but those tools also contain bugs, can disagree with one another, and are part of the same chain of human-written software.

ROHD belongs in that same evaluation. Its structural output, independent simulation paths, automated regression testing, open-source implementation, and use in real silicon are evidence that can inform a team's confidence. They are not a claim that ROHD is infallible or more trustworthy than every alternative, just as the history of an established EDA tool is not proof that it is infallible.

The appropriate level of additional checking depends on the project and the cost of being wrong, not simply on whether the tool is ROHD or a familiar SystemVerilog tool. A team may rely on normal regression testing for one design and add independent simulation, output review, or formal analysis for another. That proportional judgment is a normal part of using any EDA tool.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class PortRulesViolationException extends RohdException {
' in module $module on signal $signal.'
' Logic within a Module should only communicate outside of itself'
' by consuming inputs/inouts and'
' driving outputs/inouts of that itself.'
' driving outputs/inouts of itself.'
' See https://intel.github.io/rohd-website/docs/modules/'
' for more information. $additionalMessage');

Expand Down
2 changes: 1 addition & 1 deletion lib/src/modules/conditionals/case.dart
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ class Case extends Conditional {
CaseItem? foundMatch;

for (final item in items) {
// match on the first matchinig item
// match on the first matching item
if (isMatch(driverValue(item.value), driverValue(expression))) {
for (final conditional in item.then) {
conditional.execute(drivenSignals, guard);
Expand Down
2 changes: 1 addition & 1 deletion lib/src/modules/conditionals/conditional.dart
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ abstract class Conditional {
String verilogContents(int indent, Map<String, String> inputsNameMap,
Map<String, String> outputsNameMap, String assignOperator);

/// Calculates an amount of padding to provie at the beginning of each new
/// Calculates an amount of padding to provide at the beginning of each new
/// line based on [indent].
static String calcPadding(int indent) => List.filled(indent, ' ').join();

Expand Down
Loading