The base RISC-V ISA is pretty simple, so you could learn it by writing your own emulator. I ended up writing one, and now I'm using it for scripting in game engines :)
There are very few instructions for RV32I and RV64I - and you don't have to support both. Just pick one and implement the basic instructions. Then compile a cross-compiler from https://github.com/riscv/riscv-gnu-toolchain that is configured for either rv32i or rv64, like so:
./configure --prefix=$HOME/riscv --with-arch=rv32i
The toolchain repo is pretty big so make sure you do a shallow clone.
Well, while an emulator can be anything, it can also be very little. A userspace emulator is one that just loads an ELF binary, provides hooks for system calls, and then just simulates instructions from there. You don't technically need to support page protections, but it's certainly nice to have and it help you to narrow down problems both inside and outside the guest environment.
The riscv-gnu-toolchain does indeed build everything for you, but it has 3 "settings", so to speak:
1. The default is newlib, which is a smaller embedded C-library, but it's enough to have most of C and C++ supported. Running "make" or "make newlib" does the same thing.
2. "make linux" will build a static glibc, with threads support. I don't recommend it, as you will have emulate pthreads, which are very heavy. If you really want threads, I can give you some pointers on how to make your own light-weight ones. And, of course, so can many others.
3. "make musl". Not sure if this works completely, but I do believe it's an option. It would have threads too.
There is also a more complicated 4th option, which is to use an embedded RISC-V compiler, which you can get from here:
I don't recommend it, because it has nothing. You will have to write your entry code and all the libc stuff too. That can be fun, of course. And you get to have really small binaries!
My emulator produces debug executables which prints every instruction line by line, and it supports register-dumping too, so it could help you compare for divergences if you are having trouble with some instructions: https://github.com/fwsGonzo/libriscv
If you want to emulate an OS you will have to write guest and host drivers (both sides), which is a very complicated thing to do. However, it's a perfect opportunity to add the first level of concurrency: Running the host and the guest in separate threads! There is also emulating interrupts, various hardware timers and having a page table in guest memory with protection levels. A lot of work!
I think the easiest way to get started with RISC-V is to look at QEMU, which is an emulator. It can emulate the virtio bus, including graphics. I used this in my OSblog: http://osblog.stephenmarz.com which uses an emulated, 64-bit RISC-V CPU.