Yes, the RISC-V is going to be a 'better' project just because of the gcc toolchain and the ISA. But the question is whether it is a good learning project.
Yes it is. Because it's very-very simple, and the instruction encoding was designed for easy implementation of decoding logic. So all you need for RV32I implementation is a simple ALU that can do additions (subtraction is addition of 2's complement of one of arguments), shifts and bitwise operations. That's it. All of those operations can be synthesized using high-level HDL commands, and so do not require complicated logic in HDL.
Again, the simplest implementation is fetch-decode-execute-memory access-register writeback (decode can be combined with execution, and even with fetch, though for FPGAs I wouldn't recommend that as it will severely limit the frequency for no good reason), and so 4-5 states FSM will get you going. Once you have that working, you can work on pipelining this core to get much higher throughput if you want.
Just take my word for it - take a specification, read RV32I section only, then start from the clean sheet and try implementing ALU which can do the following operations (below assuming Verilog/SystemVerilog, but I'm sure VHDL has equivalent operators too):
1. signed addition - operator "+", just make sure your arguments are signed.
2. signed subtraction - you can use addition with 2's complement, or operator "-". Again, make sure your arguments are treated as signed.
3. shift left (operator "<<" is all you need).
4. set less than - operator "<"
5. set less than unsigned - same as above, but cast operands to unsigned types.
6. XOR - operator "^"
7. shift right logical - operator ">>".
8. shift right arithmetic - operator ">>>".
9. OR - operator |
10. AND - operator &.
That's all you will need to implement a full set of RV32I. As you can see, there is zero black magic, and all of that code would be nearly identical if you'd write it in C.
Once you have that, add a fetch unit which will load commands from the memory (again, a very straightforward code like command <= mem[current_instruction_pointer];
For decoding block just take a look at encodings (there is a table of command encodings at the end of the spec PDF) and you will see that the logic is very simple - you will need to know how to access vector subranges and a command to merge subranges into a single vector ("{}" in Verilog/SV). This will tell you an ALU operation you need to do (if any) and its' operands (wither directly, or indirectly via register indices). For control transfer commands, absolute jumps are the easiest - you optionally write back a register (for jump-and-link commands), change the current_instruction_pointer and restart from cycle 1. For conditional jumps, I prefer to create a mini-ALU which performs condition checks ("==", "!=", "<", ">=" is all you need), and if result is true - you do exact same thing as with unconditional jump.
After that implement memory access (again, very simple "mem[addr] <= value;" for writes, or "reg_data <= mem[addr];" for reads, writes will require a clock cycle, which is why I placed memory access into separate state). For non-memory related register writes, this section can be skipped entirely, though I'd recommend you implement it as a pass-through to make pipelining easier down the line.
And a final state is register writeback - "registers[reg_index] <= reg_data;".
So as you can see, there is nothing very complicated here. I highly recommend you actually do all of the above yourself first, without looking at others' code. It won't take much time, trust me.