"CIRCT" stands for "Circuit IR Compilers and Tools". One might also interpret it as the recursively as "CIRCT IR Compiler and Tools". The T can be selectively expanded as Tool, Translator, Team, Technology, Target, Tree, Type, ... we're ok with the ambiguity.
The EDA industry has well-known and widely used proprietary and open source tools. However, these tools are inconsistent, have usability concerns, and were not designed together into a common platform. Furthermore these tools are generally built with Verilog (also VHDL) as the IRs that they interchange. Verilog has well known design issues, and limitations, e.g. suffering from poor location tracking support.
The CIRCT project is an (experimental!) effort looking to apply MLIR and the LLVM development methodology to the domain of hardware design tools. Many of us dream of having reusable infrastructure that is modular, uses library-based design techniques, is more consistent, and builds on the best practices in compiler infrastructure and compiler design techniques.
By working together, we hope that we can build a new center of gravity to draw contributions from the small (but enthusiastic!) community of people who work on open hardware tooling. In turn we hope this will propel open tools forward, enables new higher-level abstractions for hardware design, and perhaps some pieces may even be adopted by proprietary tools in time.
For more information, please see our longer charter document.
These commands can be used to set this up on a Mac:
-
Install Dependencies of LLVM/MLIR according to the instructions, including cmake and ninja.
-
Check out LLVM and CIRCT repos. CIRCT contains LLVM as a git submodule. The LLVM repo here includes staged changes to MLIR which may be necessary to support CIRCT. It also represents the version of LLVM that has been tested. MLIR is still changing relatively rapidly, so feel free to use the current version of LLVM, but APIs may have changed.
$ cd ~/Projects
$ git clone git@github.com:circt/circt.git
$ git submodule init
$ git submodule update
- Build and test LLVM/MLIR:
$ cd circt
$ mkdir llvm/build
$ cd llvm/build
$ cmake -G Ninja ../llvm -DLLVM_ENABLE_PROJECTS="mlir" -DLLVM_TARGETS_TO_BUILD="X86;RISCV" -DLLVM_ENABLE_ASSERTIONS=ON -DCMAKE_BUILD_TYPE=DEBUG
$ ninja
$ ninja check-mlir
- Build and test CIRCT:
$ cd ~/Projects
$ mkdir circt/build
$ cd circt/build
$ cmake -G Ninja .. -DMLIR_DIR=~/Projects/circt/llvm/build/lib/cmake/mlir -DLLVM_DIR=~/Projects/circt/llvm/build/lib/cmake/llvm -DLLVM_ENABLE_ASSERTIONS=ON -DCMAKE_BUILD_TYPE=DEBUG
$ ninja
$ ninja check-circt
The -DCMAKE_BUILD_TYPE=DEBUG
flag enables debug information, which makes the
whole tree compile slower, but allows you to step through code into the LLVM
and MLIR frameworks.
To get something that runs fast, use -DCMAKE_BUILD_TYPE=Release
or
-DCMAKE_BUILD_TYPE=RelWithDebInfo
if you want to go fast and optionally if
you want debug info to go with it. Release
mode makes a very large difference
in performance.
- Optionally configure your environment:
It is useful to add the .../circt/build/bin
and .../circt/llvm/build/bin
directories to the end
of your PATH, allowing you to use the tools like circt-opt
in a natural way on
the command line. Similarly, you need to be in the build directory to invoke
ninja, which is super annoying. You might find a bash/zsh alias like this to
be useful:
build() {
(cd $HOME/Projects/circt/build/; ninja $1 $2 $3)
}
This allows you to invoke build check-circt
from any directory and have it do
the right thing.
The project is small so there are few formal process yet. We generally follow the LLVM and MLIR community practices, but we currently use pull requests and GitHub issues. Here are some high-level guidelines:
-
Please use clang-format in the LLVM style. There are good plugins for common editors like VSCode, Atom, etc, or you can run it manually. This makes code easier to read and understand.
-
Beyond mechanical formatting issues, please follow the LLVM Coding Standards.
-
Please practice "incremental development", preferring to send a small series of incremental patches rather than large patches. There are other policies in the LLVM Developer Policy document that are worth skimming.
-
Please use "Squash and Merge" in PRs when they are approved - we don't need the intra-change history in the repository history.
-
Please create a PRs to get a code review. For reviewers, it is good to look at the primary author of the code you are touching to make sure they are at least CC'd on the PR.
This project depends on MLIR and LLVM, and it is occasionally useful to improve them. To get set up for this:
- Follow the "How to Contribute" instructions, and install the right tools, e.g. 'arcanist' and
clang-format
. - Get an LLVM Phabricator account
- Ask for LLVM commit access, the barrier is low.
The patch flow goes like this:
- Check out the LLVM mono repo (as described above).
- Make changes to your codebase.
- Stage your changes with
git add
. - Run clang-format to tidy up the details of the patch with
git clang-format origin/master
- Create a patch in Phabricator with
arc diff
. - Iterate on review, changing your code and sending another patch with
arc diff
.
When your review converges and your patch is approved, do the following:
- commit your changes with
git commit
- rebase your changes with
git pull --rebase
- retest your patch with
ninja check-mlir
(or whatever other target makes sense) - push your changes with
git push