Another way to build emulators that I am very interested in is to start from a spec, and automatically translate it into executable code. High-fidelity emulators have a lot of potential for testing and verification.
The best example I know of is Sail [1]. Among other, they have RISC-V spec [2] and a bunch of compiler back-ends. They can already generate C or OCaml emulators, and I have been working on a new Rust back-end recently.
[1]: https://github.com/rems-project/sail
[2]: https://github.com/riscv/sail-riscv