Edith
Electronic design in Swithft
Serendipitously, the first woman to be professionally employed as an electrical engineer in the United States was also named Edith.
Overview
Edith is a Swift library which can generate MLIR for CIRCT dialects. It also enables using CIRCT tools to output Verilog directly from the in-memory MLIR representation.
Getting Started
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.
Installing CIRCT
The 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).
Snapshot Testing
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
.
Design Principles
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 firrtl
and 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.