A Hardware Description Language based on the Rust Programming Language
This turned out to be a complete rewrite of rust-hdl
from the ground up. The goal is
to satisfy four key capabilities, all of which were missing in rust-hdl
:
- High performance simulation
- "It's just Rust" syntax
- Trivial reusability
- Support for enums with payloads
The high performance simulation issue is quite important. As you build larger and more complicated/complex designs, the simulation time becomes a limiting factor for writing comprehensive test benches and running designs through thorough software validation. To first order, RHDL is roughly 1 to 2 orders of magnitude faster than RustHDL.
RustHDL was essentially a set of structured patterns to help you write hierarchical strongly typed Verilog. But it resulted in several strange "rules" that you needed to remember such as
- signals need to be read from
.val()
and written to.next
- local signals are needed for all temporary variables/bindings
- connecting signals and data from multiple modules was fairly complicated
RHDL takes a completely different approach. Here, the ideas are:
- The code is just Rust.
- The supported subset of Rust is broad, and includes things like matches, if-expressions, let bindings, type inference and generics, early returns, etc. References/pointers and lambdas are not supported.
- Data and state are handled in a transparent manner with larger state machines encapsulating the state of smaller ones.
- State advancement is handled at the top level, where things like clock crossings are also dealt with.
This design encourages a highly functional style of coding. Testing is much more trivial, since the individual functions can be tested using standard Rust test practice.
The composability of the state and the functional nature of the state machine descriptions means that reusing components (which are defined as a tuple of state, constants, types and a computer kernel) is completely trivial.
The hardware world is a good one for using Rust enum's to model various data structures. Packets, opcodes, and data elements frequently make sense to be modelled as Rust enums. RustHDL only supported C style enums with no payloads. RHDL, by contrast, supports and encourages the use of enums.
There are several risks in the RHDL design that RustHDL either did not have, or sidestepped.
- The infrastructure for writing a DSL based on rustlang is nacent.
rustc
itself is not targetted at reuse and repurposing.rust-analyzer
includes only the front end of a Rust compiler, and not the middle parts. - RustHDL used procedural macros to try and convert the AST into something that could be synthesized into Verilog. Procedural macros have some severe limitations, including the inability to share state between them and the lack of context for the processing.
- Time and effort - RustHDL was an out-growth of my commercially sponsored work at the time, and there is fielded production quality firmware which was built with it. Unfortunately, I no longer get paid to write firmware. So progress is slower. I consider this more a schedule risk than a technical one.
- Import and improve the finite-width bits classes from
rust-hdl
- Add full fledged signed bit support
- Create a high-performance logging infrastructure to log at speed
- Add support for aggregate data types based on bits (e.g., structs, tuples, arrays)
- Add support for enums that include bits
- Allow for enums to have customized layouts for the discriminant
- Provide a visualization tool for enums, and structs
- Develop a hardware-compatible intermediate representation (RHIF)
- Write a bootstrap compiler that can convert AST from Rust to RHIF
- Write a type inference engine that can perform run time type inference
- Provide support for calling other HDL kernels from within another one
- Import undefined bindings from the calling scope
- Move to a standard library of functions that can be synthesized and used
- Build a test infrastructure to compare Verilog with Rust results
- Write a compiler capable of handling multiple kernels
- Write a RHIF -> Verilog assembler
- Convert to SSA form
- Add basic optimization passes
- Build a data flow graph from the RHIF
- Identify registers with Rust source code to make human friendly diagnostics
- Propogate the register details to the RHIF and Verilog codes.
- Add timing estimator using longest path heuristics.
- Port the
RustHDL
widget library toRHDL
- Port the various FPGA BSPs to
RustHDL
fromRHDL
.
Some other topics I'm thinking about
- Build a verilator bridge so that the Verilog code can be tested from Rust, using Verilator to simulate the Verilog
- Add support for zero-sized signals. This is needed for black box modules and synchronous automatons (no non-clock inputs)
-
Make logging pure. The global approach feels "weird". - Clean up the generated verilog, or clean up the RHIF so that the verilog is easier to read/understand.