diff --git a/.github/configs/mlc_config.json b/.github/configs/mlc_config.json index 0c4421967..5eb00f934 100644 --- a/.github/configs/mlc_config.json +++ b/.github/configs/mlc_config.json @@ -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$" }, diff --git a/README.md b/README.md index a996ccccb..8b8401699 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/doc/tutorials/chapter_6/00_combinational_logic.md b/doc/tutorials/chapter_6/00_combinational_logic.md index 618f78f99..4b978185a 100644 --- a/doc/tutorials/chapter_6/00_combinational_logic.md +++ b/doc/tutorials/chapter_6/00_combinational_logic.md @@ -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 @@ -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([ diff --git a/doc/user_guide/_docs/A07-bus-ranges-and-swizzling.md b/doc/user_guide/_docs/A07-bus-ranges-and-swizzling.md index f4a21d4fd..2994505aa 100644 --- a/doc/user_guide/_docs/A07-bus-ranges-and-swizzling.md +++ b/doc/user_guide/_docs/A07-bus-ranges-and-swizzling.md @@ -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 diff --git a/doc/user_guide/_docs/A13-custom-module-behavior-inline-system-verilog.md b/doc/user_guide/_docs/A13-custom-module-behavior-inline-system-verilog.md index 5d4186ad1..0183b3e84 100644 --- a/doc/user_guide/_docs/A13-custom-module-behavior-inline-system-verilog.md +++ b/doc/user_guide/_docs/A13-custom-module-behavior-inline-system-verilog.md @@ -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. diff --git a/doc/user_guide/_docs/B02-comparisons-with-alternatives.md b/doc/user_guide/_docs/B02-comparisons-with-alternatives.md index f359f5323..60874aad3 100644 --- a/doc/user_guide/_docs/B02-comparisons-with-alternatives.md +++ b/doc/user_guide/_docs/B02-comparisons-with-alternatives.md @@ -2,85 +2,171 @@ title: "Comparison with Alternatives" permalink: /docs/comparison-with-alternatives/ excerpt: "Comparison with Alternatives" -last_modified_at: 2024-01-04 +last_modified_at: 2026-07-17 toc: true --- -There are a lot of options for developing hardware. This section briefly discusses popular alternatives to ROHD and some of their strengths and weaknesses. +There are a lot of options for developing hardware. This section briefly discusses some popular alternatives to ROHD and some of their strengths and weaknesses. It is not intended to be an exhaustive list or a ranking; each approach makes different trade-offs, and these projects continue to evolve. -### SystemVerilog +There is a conceptual difference between a *compiled hardware language* and an *embedded generator framework*. ROHD falls in the latter category: it is a Dart package for constructing and simulating a hardware model and generating outputs such as SystemVerilog. By contrast, a compiled hardware language has its own syntax and compiler. These are not rigid categories; many tools combine a host language, hardware-specific compiler passes, intermediate representations, and external simulators. -SystemVerilog is the most popular HDL (hardware descriptive language). It is based on Verilog, with additional software-like constructs added on top of it. Some major drawbacks of SystemVerilog are: +- **Language expressiveness:** A purpose-built language can provide concise, hardware-specific syntax and enforce hardware-specific rules. An embedded framework stays within the syntax of its host language, but can use that language's metaprogramming, libraries, and tooling to control hardware construction. +- **Source alignment:** A compiler can preserve source names and locations in generated RTL, although optimization may transform them. An embedded framework cannot necessarily infer the names of host-language variables. ROHD therefore names hardware objects explicitly, keeping the Dart program independent from the object model it constructs. This trades some convenience in simple code for explicit control in highly configurable generators. +- **Optimization and predictability:** Lowering and optimization can improve generated RTL or enable higher-level abstractions, but can also make the output less recognizable and changes less predictable. Downstream synthesis tools already perform extensive optimization, so a front end must balance additional transformations against source mapping and readability. ROHD favors structurally recognizable output and mechanical simplifications over architectural optimization. +- **Algorithm abstraction:** HLS and some compiler-based languages derive scheduling, pipelining, resource sharing, or other microarchitectural decisions from higher-level intent and constraints. That can make design-space exploration much faster, but the resulting cycle-level implementation is partly a compiler decision. ROHD generally keeps those decisions explicit and builds abstraction through composition of hardware objects. +- **Determination of synthesizability:** Traditional HDLs can contain elaboration-time constructs, synthesizable RTL, and verification-only behavior in the same language. Tool support and synthesizable subsets can vary. ROHD separates Dart code that constructs hardware from the hardware objects themselves, making the boundary clearer, although users can still deliberately integrate custom SystemVerilog and non-synthesizable models. +- **Automation development:** Building an EDA tool around a source language often requires parsing that language, integrating with a compiler or intermediate representation, and generating an output format. Shared infrastructure such as CIRCT can reduce that burden. ROHD takes another approach: after a design is built, its modules, signals, hierarchy, and connectivity are available directly as a native Dart object model. A developer can write analyses, design checks, visualizations, or other hardware automation using normal Dart code without first parsing SystemVerilog. Since ROHD also handles SystemVerilog generation, new automation can focus on its hardware-specific purpose and still produce RTL for existing downstream flows. This substantially lowers the barrier for users to create their own EDA tooling. +- **Ecosystem:** Editors, static analysis, reusable packages, documentation, and community are extremely valuable. An embedded framework immediately gains much of its host language's ecosystem, although hardware-specific tooling still has to be built. A purpose-built language starts with less general tooling but can offer deeper hardware-aware diagnostics and editor features. -- SystemVerilog is old, verbose, and limited, which makes code more bug-prone -- Integration of IPs at SOC level with SystemVerilog is very difficult and time-consuming. -- Validation collateral is hard to develop, debug, share, and reuse when it is written in SystemVerilog. -- Building requires building packages with proper `include ordering based on dependencies, ordering of files read by compilers in .f files, correctly specifiying order of package and library dependencies, and correct analysis and elaboration options. This is an area that drains many engineers' time debugging. -- Build and simulation are dependent on expensive EDA vendor tools or incomplete open-source alternatives. Every tool has its own intricacies, dependencies, licensing, switches, etc. and different tools may synthesize or simulate the same code in a functionally inequivalent way. -- Designing configurable and flexible modules in pure SystemVerilog usually requires parameterization, compile-time defines, and "generate" blocks, which can be challenging to use, difficult to debug, and restrictive on approaches. - - People often rely on perl scripts to bridge the gap for iteratively generating more complex hardware or stitching together large numbers of modules. -- Testbenches are, at the end of the day, software. SystemVerilog is arguably a terrible programming language, since it is primarily focused at hardware description, which makes developing testbenches excessively challenging. Basic software quality-of-life features are missing in SystemVerilog. - - Mitigating the problem by connecting to other languages through DPI calls (e.g. C++ or SystemC) has it's own complexities with extra header files, difficulty modelling parallel execution and edge events, passing callbacks, etc. - - UVM throws macros and boilerplate at the problem, which doesn't resolve the underlying limitations. +## SystemVerilog -ROHD aims to enable all the best parts of SystemVerilog, while completely eliminating each of the above issues. Build is automatic and part of Dart, packages and files can just be imported as needed, no vendor tools are required, hardware can be constructed using all available software constructs, and Dart is a fully-featured modern software language with modern features. +SystemVerilog is the dominant industry-standard language for digital hardware design and verification. The IEEE standard covers behavioral, RTL, and gate-level modeling as well as assertions, coverage, object-oriented programming, and constrained-random verification. Its broad vendor support, existing IP, and mature verification ecosystem are major strengths. Relative to ROHD, some trade-offs are: -You can read more about SystemVerilog here: +- SystemVerilog is a large language with decades of accumulated features. Synthesizable subsets and support for newer constructs vary across tools. +- RTL authors must reason about details such as blocking versus non-blocking assignments, implicit widths and signedness, sensitivity and scheduling semantics, and nets versus variables. These distinctions are powerful, but mistakes can be subtle. +- Multi-file builds may require explicit package, library, include, and file ordering plus tool-specific analysis and elaboration options. +- Parameterization, `generate` constructs, macros, and interfaces support reusable RTL, but complex generation and integration often lead teams to add scripts or other tooling around the language. +- SystemVerilog has capable verification features, including assertions, constrained randomization, functional coverage, classes, and UVM. Large class-based environments can also become verbose and require substantial methodology and tooling expertise. +- Commercial tools provide the broadest language and methodology support. Open-source support continues to improve, but supported subsets and behavior still vary between tools. -### Chisel +ROHD takes a different front-end approach while retaining SystemVerilog as an integration format. Hardware generation and testbench code use Dart, ROHD simulation and generation do not require a vendor tool, and generated RTL can enter the same lint, simulation, synthesis, and implementation flows as hand-written SystemVerilog. -Chisel is a domain specific language (DSL) built on top of [Scala](https://www.scala-lang.org/), which is built on top of the Java virtual machine (JVM). The goals of Chisel are somewhat aligned with the goals of ROHD. Chisel can also convert to SystemVerilog. +You can read more in the [IEEE 1800-2023 SystemVerilog standard overview](https://standards.ieee.org/ieee/1800/7743/) or on Wikipedia at . -- The syntax of Scala (and thus Chisel) is probably less familiar-feeling to most hardware engineers, and it can be more verbose than ROHD with Dart. -- Scala and the JVM are arguably less user friendly to debug than Dart code. -- Chisel is focused mostly on the hardware *designer* rather than the *validator*. Many of the design choices for the language are centered around making it easier to parameterize and synthesize logic. ROHD was created with validators in mind. -- Chisel generates logic that's closer to a netlist than what a similar implementation in SystemVerilog would look like. This can make it difficult to debug or validate generated code. ROHD generates structurally similar SystemVerilog that looks close to how you might write it. +VHDL is another of the most popular HDLs, with many similar characteristics to Verilog . + +## Chisel + +Chisel (Constructing Hardware in a Scala Embedded Language) is a hardware construction language embedded in [Scala](https://www.scala-lang.org/). A Scala program elaborates a hardware graph, which is lowered through FIRRTL and CIRCT to SystemVerilog. Its goals overlap substantially with ROHD's. + +- Both projects use a general-purpose, statically typed host language for parameterization and hardware construction. The choice between Scala/JVM and Dart brings different syntax, build systems, libraries, and debugging experiences. +- Scala and its functional programming style are less familiar to many hardware engineers than C-style imperative languages. Productive Chisel can also involve Scala-specific concepts such as implicits or givens, type-level programming, higher-order functions, and extensive operator overloading. Developers must distinguish Scala constructs that execute during elaboration from Chisel constructs that the DSL and compiler interpret as hardware. ROHD never converts a Dart language semantic into hardware: Dart executes as ordinary software and constructs explicit hardware objects, and only those objects are converted to RTL. Dart control flow can determine which objects are constructed, but Dart variables, statements, and classes do not themselves acquire hardware meaning. +- A common complaint about Chisel is that the Scala/JVM toolchain can feel heavy and less approachable. Build configuration, dependency and version compatibility, compiler plugins, and startup time add friction, while debugging may cross Scala elaboration, FIRRTL/CIRCT lowering, generated SystemVerilog, and an external simulator. ROHD's Dart toolchain and more direct generation path generally provide a simpler development and debugging workflow. +- Modern Chisel uses a Scala compiler plugin to capture source-level information such as many `val` names and propagate it into generated hardware. This can make simple code more concise, but it also means that aspects of the Scala source affect the hardware model and generated output. ROHD instead keeps Dart source semantics separate from the object model and names hardware objects explicitly. +- Chisel's compiler stack performs lowering and optimization through intermediate representations. This enables powerful transformations, but generated SystemVerilog can be less structurally aligned with the source than ROHD's more direct output. CIRCT provides options to tune Chisel's emission style. +- Chisel provides first-party ChiselSim APIs for stimulus and checking, but ChiselSim requires a compatible external simulator such as Verilator or VCS. ROHD includes its event-driven simulator directly in the package. +- Both systems elaborate configuration using their host language. Chisel commonly passes Scala parameters into module construction; ROHD can also derive configuration from `Logic` objects connected during construction. Read more about Chisel here: -### MyHDL (Python) +## MyHDL (Python) -There have been a number of attempts to create a HDL on top of Python, but it appears the MyHDL is one of the most mature options. MyHDL has many similar goals to ROHD, but chose to develop in Python instead of Dart. MyHDL can also convert to SystemVerilog. +MyHDL is a long-running Python package for hardware modeling, simulation, and conversion. Hardware blocks are Python functions, and decorators create concurrent generator processes. Subject to a convertible subset, MyHDL emits Verilog or VHDL. -- MyHDL uses "generators" and decorators to help model concurrent behavior of hardware, which is arguably less user-friendly and intuitive than async/await and event based simulation in ROHD. -- While Python is a great programming language for the right purposes, some language features of Dart make it better for representing hardware. Above is already mentioned Dart's isolates and async/await, which don't exist in the same way in Python. Dart is statically typed with null safety while Python is dynamically typed, which can make static analysis (including intellisense, type safety, etc.) more challenging in Python. Python can also be challenging to scale to large programs without careful architecting. -- Python is inherently slower to execute than Dart. -- MyHDL has support for cosimulation via VPI calls to SystemVerilog simulators. +- MyHDL and ROHD both use a general-purpose host language for elaboration and include a simulator. MyHDL models hardware processes with Python generators, decorators, and `Signal.next`; ROHD constructs an object graph and uses Dart events, `Future`s, and `async`/`await` for testbench interaction. +- Modern Python also supports `async`/`await`, but MyHDL's hardware process API predates those features and remains generator-based. +- Dart's static type system and null safety provide stronger compile-time checking and IDE inference by default than dynamically typed Python. Python offers a much larger package ecosystem and broad familiarity. +- For work that executes in the host language, such as elaboration and built-in simulation, the standard CPython interpreter generally runs pure Python more slowly than Dart's JIT- or AOT-compiled runtime. That difference can become significant as generators and testbenches scale. Python flows can move performance-critical work into native extensions or external HDL simulators, so it does not imply that every Python-based hardware flow is slower end to end. +- MyHDL's conversion output is normally flattened, while ROHD generally preserves module hierarchy in generated SystemVerilog. +- MyHDL can co-simulate passive Verilog through simulator-specific PLI modules, including VPI integration for Icarus Verilog. ROHD Cosim supports integration with external SystemVerilog simulators separately from ROHD's built-in simulation. Read more about MyHDL here: -### High-Level Synthesis (HLS) +## High-Level Synthesis (HLS) -High-Level Synthesis (HLS) uses a subset of C++ and SystemC to describe algorithms and functionality, which EDA vendor tools can compile into SystemVerilog. The real strength of HLS is that it enables design exploration to optimize a higher-level functional intent for area, power, and/or performance through proper staging and knowledge of the characteristics of the targeted process. +High-Level Synthesis (HLS) derives an RTL implementation from a higher-level algorithmic model. Commercial tools commonly accept C, C++, or SystemC, while research tools also use domain-specific languages and intermediate representations. The compiler schedules operations, chooses clock-cycle boundaries, allocates or shares resources, structures memories, and emits RTL such as Verilog or VHDL. -- HLS is a step above/away from RTL-level modelling, which is a strength in some situations but might not be the right level in others. -- HLS uses C++/SystemC, which is arguably a less "friendly" language to use than Dart. +- HLS can explore many implementations of an algorithm against area, power, performance, latency, and throughput goals much faster than implementing each candidate by hand. +- The trade-off is that important microarchitectural decisions are made jointly by source code, constraints, directives, and the compiler. Understanding cycle behavior and achieving a specific structure can require familiarity with that tool's scheduling and cost model. +- C and C++ are familiar, but they are not especially user-friendly hardware modeling languages. Their low-level type and memory semantics, undefined behavior, templates, build systems, and often difficult diagnostics remain, while an HLS tool accepts only particular coding patterns plus tool-specific constraints and directives. SystemC adds hardware concepts, but also adds a class- and template-heavy library and its own simulation semantics. Dart and ROHD provide a more modern language, stronger default safety, and a hardware-focused API without pretending that ordinary software code is hardware. +- HLS is strongest for self-contained computational kernels. Integration into a real design often requires exact control of ports, individual wires, clocks and resets, protocols, memories, existing IP, and hierarchy. Many HLS flows expose those details through interface synthesis, prescribed protocols, pragmas, or tool-specific wrappers rather than a natural, general wire-level composition model. Designers commonly have to drop the generated kernel into a conventional RTL environment to assemble the complete system. +- ROHD works at the RTL construction level: designers normally choose state, resources, cycle boundaries, ports, and connectivity explicitly, while reusable generators automate composition. It can therefore express both detailed wire-level integration and higher-level reusable structure in the same object model. Read more about one example of an HLS tool (Cadence's Stratus tool) here: There are a number of other attempts to make HLS better, including [XLS](https://github.com/google/xls) and [Dahlia](https://capra.cs.cornell.edu/dahlia/) & [Calyx](https://capra.cs.cornell.edu/calyx/). There are discussions on ways to reasonably incorporate some of the strengths of HLS approaches into ROHD. -### Transaction Level Verilog (TL-Verilog) +## CIRCT + +CIRCT (Circuit IR Compilers and Tools) is not primarily an end-user hardware language. It is an open-source compiler infrastructure project that applies LLVM and MLIR techniques to hardware design. CIRCT provides reusable intermediate-representation dialects, transformations, analyses, and Verilog/SystemVerilog emission across abstractions including RTL, finite-state machines, pipelines, dataflow, and verification. -Transaction Level Verilog (TL-Verilog) is like an extension on top of SystemVerilog that makes pipelining simpler and more concise. +- CIRCT is most directly useful to authors of hardware languages and EDA tools. For example, its `firtool` lowers the FIRRTL produced by Chisel into SystemVerilog. +- Its shared infrastructure can reduce the cost of building a new language or flow and provides configurable lowering for the differing capabilities and lint rules of downstream tools. +- ROHD is an end-user Dart framework with its own object model, simulator, and SystemVerilog generator. CIRCT operates lower in the tool stack, so the projects are more complementary than direct substitutes. -- TL-Verilog makes RTL design easier, especially when pipelining, but doesn't really add much in terms of verification -- ROHD also supports a [pipelining abstraction](https://intel.github.io/rohd-website/docs/pipelines/). +Read more about CIRCT here: . + +## Transaction Level Verilog (TL-Verilog) + +Transaction-Level Verilog (TL-Verilog) introduces new syntax for pipelines, transactions, validity, hierarchy, and state on top of a Verilog workflow. In practical terms, SandPiper acts as a source-to-source compiler or sophisticated preprocessor: it expands TL-Verilog constructs, including implied pipeline registers, into ordinary Verilog or SystemVerilog for standard downstream tools. TL-Verilog files can also contain regions of raw SystemVerilog. + +- TL-Verilog makes timing changes and pipeline alignment more concise by keeping signals in a pipeline context. Makerchip integrates compilation, simulation, diagrams, and organized waveforms for design and debug. +- The trade-off is adopting another language syntax and making SandPiper part of the build flow. The generated RTL remains compatible with existing tools, but the concise source is not itself standard SystemVerilog. +- ROHD also supports a [pipelining abstraction](https://intel.github.io/rohd-website/docs/pipelines/), but uses Dart objects and composition rather than adding purpose-built syntax to Verilog. Read more about TL-Verilog here: -### PyMTL +## PyMTL -PyMTL is another attempt at creating an HDL in Python. It is developed at Cornell University and the third version (PyMTL 3) is currently in Beta. PyMTL aims to resolve a lot of the same things as ROHD, but with Python. It supports conversion to SystemVerilog and simulation. +PyMTL 3 is an open-source Python framework for hardware generation, simulation, and verification developed at Cornell. It supports multiple modeling levels, including functional, cycle-level, RTL, and imported Verilog components. Its current project README still describes version 3 as beta software under active development. -- The Python language trade-offs described in the above section on MyHDL apply to PyMTL as well. +- PyMTL and ROHD both aim to keep generation, simulation, and verification in one environment rather than treating the HDL generator as an isolated front end. +- PyMTL emphasizes multi-level modeling and Python interoperability, with passes for Verilog translation and Verilator-backed integration. ROHD uses Dart, includes four-state event-driven simulation, and emits SystemVerilog. +- The static-versus-dynamic typing trade-offs discussed for MyHDL also apply, while Python offers a larger existing scientific and verification ecosystem. Read more about PyMTL here: or -### cocotb +## cocotb -cocotb is a Python-based testbench framework for testing SystemVerilog and VHDL designs. It makes no attempt to represent hardware or create a simulator, but rather connects to other hardware simulators via things like VPI calls. +cocotb is a Python coroutine-based cosimulation testbench framework for verifying VHDL and SystemVerilog RTL. It is not a hardware generator framework and does not provide the HDL simulator itself. Instead, it controls a supported simulator through interfaces such as VPI, VHPI, or FLI and lets tests drive and inspect the design from Python. The cosimulation capabilities of cocotb are gratefully leveraged within the [ROHD Cosim](https://github.com/intel/rohd-cosim) package for cosimulation with SystemVerilog simulators. Read more about cocotb here: or + +## Spade + +Spade is a compiled RTL hardware description language inspired by modern software languages. It has a strong type system, first-class pipelines with compiler-checked latency, dedicated editor and build tooling, and Verilog output. + +- Spade and ROHD both work at RTL and emphasize predictable hardware with explicit control rather than using HLS to infer a microarchitecture. +- Spade does not prioritize human-readable generated Verilog. Its documented goal is instead a clear two-way mapping between source signal names and generated names for waveforms and tooling. ROHD places more emphasis on human-readable, structurally similar generated SystemVerilog that can be inspected and debugged directly. +- Spade's purpose-built compiler can enforce hardware-specific timing and type rules, and its source-aware tooling can present complex Spade types during debug. ROHD instead offers the full Dart language for generation and verification, together with a built-in event-driven simulator. + +Read more about Spade here: . + +## PipelineC + +PipelineC is a C-like HDL with compiler-managed automatic pipelining for pure functions. It primarily generates human-readable VHDL, with a path to Verilog when needed, and occupies a middle ground between explicit RTL and HLS. + +- PipelineC is a strong fit when automatic pipelining of computational functions is a primary goal. +- ROHD normally keeps cycle boundaries explicit and predictable, while offering reusable pipeline abstractions and broader support for testbench and event-driven simulation code in the same language. + +Read more about PipelineC here: . + +## SUS + +SUS is a compiled synchronous RTL language that generates SystemVerilog. Its distinguishing features include latency counting for pipelines, explicit hardware domains, compile-time metaprogramming, and hardware-aware editor feedback. + +- SUS provides a purpose-built syntax and compiler that can reason directly about latency and hardware domains. +- ROHD supports both synthesizable construction and non-synthesizable event-driven models, and uses Dart rather than introducing a new language and toolchain. + +Read more about SUS here: . + +## DFiant HDL (DFHDL) + +DFHDL is an embedded Scala hardware description framework. It supports dataflow, register-transfer, and event-driven levels of abstraction, with dataflow firing rules intended to enable timing- and device-agnostic descriptions. + +- DFHDL and ROHD both gain metaprogramming and abstraction capabilities by embedding hardware construction in a general-purpose language. +- DFHDL emphasizes multiple hardware abstraction domains and dataflow semantics. ROHD emphasizes explicit structural construction, a built-in simulator, and structurally similar SystemVerilog generation using the Dart ecosystem. + +Read more about DFHDL here: . + +## Bluespec + +Bluespec is a high-level hardware description language available as Bluespec SystemVerilog and Bluespec Haskell. Its defining abstraction is *guarded atomic actions*: designers describe rules and invariants, and the compiler determines a valid schedule. The open-source BSC toolchain emits Verilog and includes the Bluesim simulator. + +- Bluespec's rules can make complex concurrent behavior highly composable, while its compiler handles scheduling conflicts. +- That scheduling step also puts more behavior in the compiler's hands. ROHD keeps cycle-level structure more explicit and uses composition in Dart rather than a separate rule-based language. + +Read more about Bluespec here: . + +## Clash + +Clash is a functional hardware description language based on Haskell's syntax and semantics. It uses strong types, higher-order functions, and streams of values to describe hardware, and it generates synthesizable VHDL, Verilog, or SystemVerilog. It also provides an interactive REPL for testing components. + +- Clash is especially attractive for functional, strongly typed, and highly parametric circuit descriptions. +- ROHD uses Dart's imperative and object-oriented styles, executes Dart to construct the hardware model at generation time, and includes a four-state event-driven simulator. The choice often comes down to the preferred programming model and ecosystem. + +Earlier Haskell-embedded hardware description projects such as Lava helped establish this style; Clash is the more actively maintained comparison today. + +Read more about Clash here: . diff --git a/doc/user_guide/_get-started/01-overview.md b/doc/user_guide/_get-started/01-overview.md index c1a98cdc1..60595da54 100644 --- a/doc/user_guide/_get-started/01-overview.md +++ b/doc/user_guide/_get-started/01-overview.md @@ -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: @@ -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. @@ -63,3 +63,45 @@ Try out Dart instantly from your browser here (it supports ROHD too!): For more information on Dart and tutorials, see and + +## 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. diff --git a/lib/src/exceptions/module/port_rules_violation_exception.dart b/lib/src/exceptions/module/port_rules_violation_exception.dart index 29e5f2ab7..f1db83f56 100644 --- a/lib/src/exceptions/module/port_rules_violation_exception.dart +++ b/lib/src/exceptions/module/port_rules_violation_exception.dart @@ -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'); diff --git a/lib/src/modules/conditionals/case.dart b/lib/src/modules/conditionals/case.dart index 61b90fff3..a3cf3efc8 100644 --- a/lib/src/modules/conditionals/case.dart +++ b/lib/src/modules/conditionals/case.dart @@ -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); diff --git a/lib/src/modules/conditionals/conditional.dart b/lib/src/modules/conditionals/conditional.dart index 2a52a6b21..995810459 100644 --- a/lib/src/modules/conditionals/conditional.dart +++ b/lib/src/modules/conditionals/conditional.dart @@ -179,7 +179,7 @@ abstract class Conditional { String verilogContents(int indent, Map inputsNameMap, Map 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();