One of the simplest practical processors I know is my own S16X4, built on the Steamer-16 architecture by Myron Plichota. (I hope I spelled that right. Typing from memory here.) RISC-V is offers a substantially more complex ISA to decode. In the interests of agile methodology, theoretically, I should be able to always have a shippable product. Considering the scope of the project, how do I reconcile continuous testing with having a minimum viable processor?
I'm thinking of just replicating the original 12 instructions of the original S16X4; the idea is that instruction set defines the minimum viable RISC-V subset. To recap the S16X4 instructions:
- NOP
- LIT (loads a word-width literal into the data stack)
- FWM (fetch word from memory)
- SWM (store word to memory)
- ADD
- AND
- XOR
- ZGO (branch if top of stack is zero)
- GO (unconditional branch)
- NZGO (branch if top of stack is not zero)
- FBM (fetch byte from memory)
- SBM (store byte to memory)
The closest analogs in the RISC-V are as follows:
NOP --> ADDI X0, X0, 0, so we need to support at least the ADDI instruction.
LIT --> ADDI Xn, Xn, imm12, possibly followed by further SLLI Xn, Xn, shamt / ADDI Xn, Xn, imm12 pairs as appropriate to load the full register width with desired data. So, besides ADDI, we also need SLLI.
FWM/FBM --> LBU, LHU, LWU, LDU. These are simple enough to implement as-is, since the func3 bits of the opcode can be directly exposed to the external bus to determine transfer size.
SWM/SBM --> SB, SH, SW, SD.
ADD, AND, XOR --> These involve register-register operations, so these three instructions translate naturally to their RISC-V counterparts. And, honestly, supporting their immediate versions is easy enough to implement we might as well implement ANDI and XORI as well. In fact, XORI will be required if we want to perform 2's compliment negation on a register.
ZGO, NZGO, GO --> BEQ, BNE, JAL. Easy peasy.
And that's it, I think. So the absolute minimum RISC-V instruction subset to support includes:
- ADDI
- SLLI
- ADD
- AND
- XOR
- LBU
- LHU
- LWU
- LDU
- SB
- SH
- SW
- SD
- BEQ
- BNE
- JAL
Wow, not bad! Only 16 instructions! Supporting more instructions can be done by fleshing out the rest of the instruction decoder and/or pipeline incrementally from here. The only instruction format not supported is U-format, used only by LUI and AUIPC; however, given the rest of the implementation already works, these are pretty trivial instructions to add.
Things not covered are CSRRW, CSRRS, CSRRC, ECALL, EBREAK, ERET, WFI, and FENCE instructions. With the exception of ECALL, EBREAK, and ERET, these instructions are actually somewhat more complicated to implement anyway, and should be implemented only after we have a minimal instruction set to debug with. I think.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.