InnocentZero's Treasure Chest

HomeFeedAbout MeList of interesting people

24 Oct 2025

RISCV ISA

RISCV ISA

Open source. Has 32 int and 32 FP registers. Also has XLEN variable, which is either 32 or 64 for 32-bit and 64-bit processors respectively.

There are 13 callee saved registers. 12 of them are explicitly called saved registers, and the first one of them (s0) is the frame pointer (equivalent to base pointer in AMD64). The 13 one is the stack register.

Register ABI Name Description Saver
x0 zero Zero always  
x1 ra Return address caller
x2 sp Stack Pointer callee
x3 gp Global Pointer  
x4 tp Thread Pointer  
x5-x7 t0-t2 Temps caller
x8 s0 /fp saved / frame pointer (base pointer effectively) callee
x9 s1 saved register callee
x10-x11 a0-a1 Fn args/ return values callee
x12-x18 a2-a7 Fn args caller
x18-x27 s2-s11 Saved registers callee
x27-x31 t3-t6 Temporaries caller

Maximum memory depends on the size of the address bus from the load store unit to the memory.

The caller saved registers have to be explicitly saved by the caller function in a stack frame before calling the other function. On the other hand, callee saved functions are guaranteed to stay the same across function calls and there is no need for functions to save them.

RISCV Instructions

The ones listed below are called R-type or register-type instructions.

  • add rd, rs1, rs2: add the contents of rs1 and rs2 and store it in rd. Signed addition. Also has the unsigned version. Similarly, sub, and, or, xor also exist.
  • mul/mulh rd, rs1, rs2: multiplies and stores the lower/upper 32 bits in rd.
  • div/rem rd, rs1, rs2: stores the quotient/remainder.
  • sll rd, rs1, rs2: Left shift the number in rs1 by the value in rs2 and store in rd.
  • srl rd, rs1, rs2: Right shift the number in rs1 by the value in rs2 and store in rd. Zero extends.
  • sra rd, rs1, rs2: Right shift the number in rs1 by the value in rs2 and store in rd. Sign extends.

All of these also have an immediate version where the last argument is a hardcoded literal that is 12 bits.

These are called I-type or immediate-type instructions.

  • l(b/h/w) rd, imm(rs1): loads a byte/half-word/word to rd=(dest. register) from =*(rs1 + imm)
  • l(b/h/w)u rd, imm(rs1): loads a byte/half-word/word to rd=(dest. register) from =*(rs1 + imm). This one zero-extends on the left.

These are also I-type instructions.

The below one instruction is S-type instruction (for obvious reasons).

  • s(b/h/w) rd, imm(rs1): stores a byte/half-word/word to *(rs1 + imm) from the contents of rd.

The below instruction is called B-type or branch-type instruction.

  • blt/bltu r1, r2, label/offset: if r1 < r2 (signed or unsigned), jump to label or symbol. Can jump to atmost 4 KiB. (13 bits with the lsb always 0, the rest are used for determining values).

The above instructions have greater than, greater than equal to variants as well. Also immediate variants of all.

Function call instructions

All of these can jump to at most 1 MiB as they take an immediate value of 20 bits apart from the lsb that's always 0.

The below type is called a J-type instruction.

  • jal rd, imm: Jump to pc + imm, and store pc + 4 in register rd.

The below one is an I-type and NOT J-type.

  • jalr rd, rs1, imm: Jump to rs1 + imm, storing pc + 4 in the register rd. Used for function pointers.

Both of the ones below are aliases.

  • j label: alias to jal zero, label, discards the return address
  • ret rs1: return to the address in rs1, if no argument is specified use ra (return address register/ x1). Alias to jalr zero, rs1, 0

For function calls we also need a stack-based execution. x2 register is the stack pointer that points to the top of the stack. Frame pointer s0 saves the base of the stack. These mark the stack frame in the stack.

Always load and save values relative to the frame pointer.

Registers a0 to a7 are used to pass function arguments from one function to another. These are 8 parameters. If we have more, then you need to use the stack.

Control and status registers

  • csrrw rd, csr, rs: atomic swap values
  • csrrs rd, csr, rs: atomic copy to rd and set the bits that are set in rs.
  • csrrc rd, csr, rs: atomic copy to rd and reset the bits that are reset in rs.

Atomic means that interrupts won't stop the entire set of operations that is going on. If one of the operands is x0/zero, then that copying doesn't happen.

Executing instructions

If we are using an operating system:

  • Proxy Kernel is handling syscalls, mapping memory, program counter according to memory map, etc.

If we are without an operating system:

  • Manually write the .text section to the flash memory.
  • Load the .data section to the RAM.
  • Set/reset the program counter to the required memory. It resets to a fixed value called as reset vector.
  • Address out of range is your skill issue.
  • Instruction fetched by the instruction pointer. 32 bits in width.
  • Then it is sent to control ROM. This does not have microcodes and are instead hardcoded using combinational circuits.

Register Bank

Has all the registers and 2 mux + 1 demux to select the register to use. There is dual porting to read two source registers at once (hence two muxes).

Program Counter

This keeps track of the next instruction to be executed. Usually incremented by 4 unless branches. It resets to a fixed value called as reset vector.

Instructions and data are fetched every rising edge of the clock and that is when the program counter is also incremented by 4. The instruction fetched is later stored in the instruction register.

The instruction register sends it to the control unit which later sends signals to whatever is responsible.

It also gets reset at interrupts to an interrupt vector and begins to consume instructions from there.

ALU

Performs arithmetic (no shit). Has the gen module before it that generates the immediate instruction from the opcode, regardless of whether it was an I-type or not.

After this, there is a 2:1 mux that has a select line coming from the Control Unit that decides whether or not the immediate values has to be selected or not, the other option being 0.


Other posts
Creative Commons License
This website by innocentzer0 is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.