cpu-architectureriscv

In a RISC-V architecture, do jump instructions (conditional or JAL/JALR) increase the PC by 4 as the rest of the instructions?


I'm working on a RISC-V CPU emulator and have all instructions implemented. The thing is that I'm not sure if the jumps are failing. This is the current implementation I have for BGEU to make an example:

void CPU::BGEU() {
uint8_t rs1 = instDecoded.registers[0];
uint8_t rs2 = instDecoded.registers[1];
uint32_t inmediate = instDecoded.inmediate;

if (static_cast<uint32_t>(registers[rs1]) >= static_cast<uint32_t>(registers[rs2])) 
    pc += inmediate;
}

I have another method called "clock" which executes the instruction and then add 4 to PC, but I don't know if after a jump I should add 4.


Solution

  • Control Transfer Instructions

    In the RISC-V architecture, control transfer instructions, which include the unconditional jumps and conditional branches, manipulate the program counter (PC) differently compared to regular instructions. While most instructions simply advance the PC by 4 bytes, control transfer instructions adjust the PC based on specific conditions or targets.

    1. Unconditional jumps

    In such operations, the PC is supposed to jump to a specific target address. Example: JAL (Jump and Link), JALR (Jump and Link Register)

    JAL

    Directly jumps to a computed address derived from the current PC added to an immediate offset (of J-type encoding). It stores the address of the next sequential instruction (PC + 4) into register rd.

    target address = PC + immediate offset

    JALR

    Jumps to an address calculated by adding a base register value (rs1) to a 12-bit immediate offset (of I-type encoding), then setting the least significant bit of this result to 0 to align with the 2-byte boundary (for the compressed instruction set). Similar to JAL, it stores the next instruction's address in register rd.

    target address = (rs1 + immediate offset) & ~1

    2. Conditional Branches

    Example: BEQ (branch equality),BNE (branch inequality), BLT[U] (branch less than or equality, where U is added for unsigned), BGE[U] (branch greater than or equality, where U is added for unsigned))

    Behavior:

    Clock

    Purpose: The clock in a CPU emulator synchronizes the sequence of operations, ensuring accurate timing and control over the instruction execution cycle.

    Design Implementation: Each instruction type should handle its PC adjustments to respect their unique requirements in logic. This modular approach ensures clarity and reduces errors in emulation, especially around the handling of the PC.

    Therefore, all of the instructions defined should handle the calculation of target address individually instead of being handled by the clock method universally.

    Conclusion

    Hence, to summarize the recommended corrections: