In addition to rewriting a large part my processing module project, I've also been trying to streamline the development experience. I had acquired a new laptop and repurposed my old one for a home development server. Both of these had a fresh OS installed, so the project needed to be set up from scratch. This used to be a time-consuming, error-prone process with many steps for installing Chisel, configuring Emacs, and downloading all of the dependencies for building and testing. Downloading dependencies is itself a tricky process that includes opening source files in Emacs and waiting for the language server to start up, so it's difficult to automate. The language server, which enables fast error checking and autocompletion in Emacs, requires many plugins to be loaded, which I would prefer not to have in my default minimal configuration.
I had previously tried out a Docker image made for the Chipyard project, and it was easy to use and included everything needed to produce a System-on-Chip design. I liked that a single download took care of all the dependencies and utilities. It's also important to me that the project setup not leak out onto the rest of my system. The source code itself should remain on the host filesystem, so that every single change is preserved, but everything surrounding it should be contained and able to be reverted quickly. In addition, the Docker instance started up quickly and did not add much overhead to my system.
So, I started following the very good online documentation to write my own Dockerfile that is based on the Chipyard one. It downloads all of the Chisel dependencies and builds the appropriate version of Verilator. Emacs is included along with a specialized configuration and language server plugins so that my editor runs from within the instance. A terminal emulator is also installed to run on startup. This way, nothing more needs to be downloaded when the Docker instance is running; the system is ready to be used completely offline. When launching the instance, two virtual filesystem mounts are created: one for the source code, and one for an X11-related file (/tmp/.X11-unix) so that GUIs can be displayed with the host window manager. This setup has been tested to work successfully on my Linux home server (Ubuntu 21.10) and my main Windows laptop (WSL2).