commit c8a2c51f80c364d04ff8b86b55c8fa0444ab1391 from: Gleb Nesterov date: Sun Mar 22 13:05:26 2026 UTC Implement basic RV64I hart cycle: fetch, decode, execute commit - 1029a1177da1c59d6d27ba7c5dd653202c0ce313 commit + c8a2c51f80c364d04ff8b86b55c8fa0444ab1391 blob - /dev/null blob + dd689e20d4964ff3c5f13cea619551d57872c0e8 (mode 644) --- /dev/null +++ rvvm/rvhart.c @@ -0,0 +1,86 @@ +#include +#include + +#include "rvhart.h" +#include "rvram.h" + +struct rv_instr +rv_decode(uint32_t word) +{ + struct rv_instr i; + + i = {0}; + i.opcode = word & 0x7f; + i.rd = (word >> 7) & 0x1f; + i.rs1 = (word >> 15) & 0x1f; + i.rs2 = (word >> 20) & 0x1f; + i.funct3 = (word >> 12) & 0x7; + i.funct7 = (word >> 25) & 0x7f; + + switch (i.opcode) { + case 0x33: + i.fmt = R_FMT; + break; + case 0x13: + case 0x03: + case 0x67: + case 0x73: + i.fmt = I_FMT; + i.imm = SE(word >> 20, 12); + break; + case 0x23: + i.fmt = S_FMT; + i.imm = SE((((word >> 25) & 0x7f) << 5) | ((word >> 7) & 0x1f), 12); + break; + case 0x63: + i.fmt = B_FMT; + i.imm = SE(((word & 0x80000000) >> 19) | + ((word & 0x00000080) << 4) | + ((word & 0x7e000000) >> 20) | + ((word & 0x00000f00) >> 7), + 13); + break; + case 0x37: + case 0x17: + i.fmt = U_FMT; + i.imm = SE(word >> 12, 20) << 12; + break; + case 0x6f: + i.fmt = J_FMT; + i.imm = SE(((word & 0x80000000) >> 11) | + (word & 0x000ff000) | + ((word & 0x00100000) >> 9) | + ((word & 0x7fe00000) >> 20), + 21); + break; + default: + err(1, "rv_decode(): unknown opcode %x", i.opcode); + } + + return (i); +} + +void +rv_execute(struct rv_hart *h, struct rv_ram *m, struct rv_instr i) +{ + uint64_t next_pc = h->pc + RV_STEP_SIZE; + + switch (i.opcode) { + // TODO: Implement execution logic. + default: + err(1, "rv_execute(): unknown opcode %x", i.opcode); + } + + h->rfile[0] = 0; + h->pc = next_pc; +} + +void +rv_step(struct rv_hart *h, struct rv_ram *m) { + uint32_t word; + struct rv_instr i; + + word = (uint32_t)rv_ram_read(m, h->pc); + i = rv_decode(word); + rv_execute(h, i); +} blob - /dev/null blob + dc3aee9e339cb3ba5f080fc76655ebe2ce253379 (mode 644) --- /dev/null +++ rvvm/rvhart.h @@ -0,0 +1,41 @@ +#ifndef _RVHART_H_ +#define _RVHART_H_ + +#include + +#include "rvram.h" + +#define RV_RFILE_SIZE 32 +#define RV_STEP_SIZE 4 + +#define SE(val, bits) (((int64_t)(val) << (64 - (bits))) >> (64 - (bits))) + +enum rv_instrfmt { + R_FMT, + I_FMT, + S_FMT, + B_FMT, + U_FMT, + J_FMT +}; + +struct rv_instr { + enum rv_instrfmt fmt; + uint8_t opcode; + uint8_t rd; + uint8_t rs1; + uint8_t rs2; + uint8_t funct3; + uint8_t funct7; + int64_t imm; +}; + +struct rv_hart { + uint64_t pc; + uint64_t rfile[RV_RFILE_SIZE]; +}; + +struct rv_instr rv_decode(uint32_t word); +void rv_execute(struct rv_hart *h, struct rv_ram *m, struct rv_instr i); +void rv_step(struct rv_hart *h, struct rv_ram *m); +#endif