When you implement the functionality of a piece of hardware in software, the software is said to "emulate" the hardware. The emulators you are used to are emulators, not because they are emulating a console (ex. N64), but because they're emulating the hardware that was used to build that console (ex. a MIPS processor). That said, oftentimes console emulators need to account for specific quirks/bugs that were introduced specifically because of choices the console designers made. Ex. maybe the specific processor and memory they used for the N64 have a weird interaction that game devs at the time abused, and if your emulation doesn't ensure that quirk works the same way, then some games won't run.
At the risk of adding unnecessary detail, a VM might use emulation or it might not. The QEMU package is often used for virtualization, but despite its name (Quick Emulator) if the system you're virtualizing matches the architecture of the system you're running on, no emulation is needed.
\1a) In this case, it is risc-v hardware running software (built for risc-v) that emulates x86_64 hardware so that it can run an x86_64 binary.
\1b) A compatibility layer is less well defined, but in general refers to: whatever environment is needed to get a binary running that was originally built for a different environment. This usually includes a set of libraries that the binary is going to assume are loaded, as well as accounting for any other possible unique attributes in the structure of the executable. But if the binary, the compatibility layer, and the CPU are all x86_64, then there's no emulation involved.
\2) to get a binary built for x86_64 windows running on risc-v Linux, you will need both emulation and a compatibility layer. In theory those two don't need to be developed in tandem, or even know about each other at runtime, but i expect that there may be performance optimizations possible if they are aware if each other.
I mentioned QEMU because my first thought when reading this was, isn't this a prime usecase for QEMU?
Yes, JIT is used for both, but we don't call JITing of Java/.Net bytecode "emulation" because there is no hardware that natively runs bytecode that we are emulating. Unlike x86_64 asm, bytecode is designed to be JITed. But yes, JITing is the defacto strategy for efficiently emulating one piece of hardware on another.