Electronic design in Swithft
Serendipitously, the first woman to be professionally employed as an electrical engineer in the United States was also named Edith.
The root type in Edith is
Circuit. Currently, the only thing circuits can do is define modules, which are analogous to Verilog modules. This is accomplished by conforming a type to the
CircuitModule protocol, and the calling
circuit.define on an instance of that type. Examples of this pattern can be found in Circuit Tests.
Tools/build-dependencies script installs CIRCT using MLIRSwift’s
build-dependencies tool. The MLIRSwift documentation describes ways to customize this process. The Troubleshooting section has some useful information if you run into issues (particularly with pkg-config).
We currently test Edith using snapshot tests, meaning instead of writing explicit unit tests we simply track the MLIR and Verilog output for a few designs. This is implemented using the
snapshot function defined in
Snapshot Test.swift. Snapshots can be updated by setting the
EDITH_SNAPSHOT_OUTPUT_PATH environment variable like so:
EDITH_SNAPSHOT_OUTPUT_PATH=$PWD/Tests/EdithTests/Snapshots swift test.
Only bind opinionated CIRCT dialects
The distinction here is between dialects that the circt community has discussed and blessed (like
comb and the incoming
seq), as compared to dialects which seek to represent existing languages with high fidelity (like
sv). The thought here is that the latter dialects are meant for compatibility with existing tools and thus have vestigial constructs which may not survive the CIRCT design process. This isn’t to say that dialects like the SystemVerilog dialect cannot or should not be bound, just that they should not be bound as part of Edith.
Push as much as possible into MLIR
MLIR is designed to support common program representations like abstract syntax trees. As such, we should avoid defining anything resembling an AST in Edith. Instead, Edith operations should directly create MLIR primitives. One common pattern is for operations of values to directly emit new MLIR operations into their operands’ block.