rvemu

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit 4446e4fbe7569a37b01c06a28e26ef64c45c6e8c
Author: Michail Konstantinos Dimopoulos <mk@mcdim.xyz>
Date:   Mon, 16 Mar 2026 23:49:55 +0200

Initial commit

Diffstat:
AMakefile | 2++
Aconfig.h | 2++
Amain.c | 167+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 171 insertions(+), 0 deletions(-)

diff --git a/Makefile b/Makefile @@ -0,0 +1,2 @@ +all: + gcc main.c diff --git a/config.h b/config.h @@ -0,0 +1,2 @@ +#define MEM_SIZE (32 * 1024 * 1024) + diff --git a/main.c b/main.c @@ -0,0 +1,167 @@ +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> + +typedef struct { + uint32_t x[32]; /* general purpose registers */ + uint32_t pc; +} cpu_state_t; + +typedef struct { + uint8_t opcode; + uint8_t rd, rs1, rs2; + uint8_t funct3, funct7; +} rtype_t; + +void print_bin16(uint16_t x) { + for (int i = 15; i >= 0; i--) { + putchar((x >> i) & 1 ? '1' : '0'); + /*if (i % 4 == 0) putchar(' '); grouping */ + } +} + +void print_bin32(uint32_t x) { + for (int i = 31; i >= 0; i--) { + putchar((x >> i) & 1 ? '1' : '0'); + } +} + +void print_binless(uint32_t x, int a) { + for (int i = a-1; i >= 0; i--) { + putchar((x >> i) & 1 ? '1' : '0'); + } +} + +/* +R-TYPE INSTRUCTION DECODING +31 25 24 20 19 15 14 12 11 7 6 0 ++------------+--------+--------+--------+---------+--------+ +| funct7 | rs2 | rs1 | funct3 | rd | opcode | ++------------+--------+--------+--------+---------+--------+ +opcode 0x33 0110011 +*/ +void exec_op(cpu_state_t *cpu, uint32_t inst) { + printf("TYPE R\n"); + rtype_t r; + r.rd = (inst >> 7) & 31; + r.funct3 = (inst >> 12) & 7; + r.rs1 = (inst >> 15) & 31; + r.rs2 = (inst >> 20) & 31; + r.funct7 = (inst >> 25) & 127; + + /* print */ + printf("f7 rs2 rs1 f3 rd opcode\n"); + print_binless(r.funct7, 7); + printf(" "); + print_binless(r.rs2, 5); + printf(" "); + print_binless(r.rs1, 5); + printf(" "); + print_binless(r.funct3, 3); + printf(" "); + print_binless(r.rd, 5); + printf("\n"); + + /* */ + + switch(r.funct3) { + case 0x0: + printf("HI\n\n"); + switch(r.funct7) { + case 0x00: + printf("ADD\n"); + printf("rs1:%d\nrs2:%d\nrd:%d\n",cpu->x[r.rs1],cpu->x[r.rs2],cpu->x[r.rd]); + + int x = cpu->x[r.rs1]+cpu->x[r.rs2]; + + printf("%d\n", x); + + if (r.rd != 0) { + cpu->x[r.rd] = x; + } + + printf("rd:%d\n", cpu->x[r.rd]); + + break; + case 0x20: + printf("SUB\n"); + printf("rs1:%d\nrs2:%d\nrd:%d\n",cpu->x[r.rs1],cpu->x[r.rs2],cpu->x[r.rd]); + + x = cpu->x[r.rs1]-cpu->x[r.rs2]; + + if (r.rd != 0) { + cpu->x[r.rd] = x; + } + + printf("rd:%d\n", cpu->x[r.rd]); + break; + } + break; + case 0x4: + printf("XOR\n"); + break; + case 0x6: + printf("OR\n"); + break; + case 0x7: + printf("AND\n"); + printf("rs1:%d\nrs2:%d\nrd:%d",cpu->x[r.rs1],cpu->x[r.rs2],cpu->x[r.rd]); + + int x = r.rs1&r.rs2; + printf("%d\n", x); + break; + } +} + +int main() { + + /* function pointer dispatch */ + typedef void (*exec_fn)(cpu_state_t *, uint32_t inst); + static exec_fn opcode_table[128]; + opcode_table[0x33] = exec_op; + /*opcode_table[0x13] = exec_op_imm; + opcode_table[0x03] = exec_load; + opcode_table[0x23] = exec_store; + opcode_table[0x63] = exec_branch; + opcode_table[0x73] = exec_system;*/ + + + /*0000000111110000011100000110011*/ + //uint32_t inst = 0x01F07033; + /*0000000111110000000000000110011*/ + uint32_t inst = 0x01F00033; + + // f7 rs2 rs1 f3 rd opcode + // 0000000 00001 00010 000 00000 0110011 + inst = 0x00110033; + + // f7 rs2 rs1 f3 rd opcode + // 0100000 00001 00010 000 00011 0110011 + //inst = 0x401101B3; + + print_bin32(inst); + printf("\n"); + + /* decode instruction */ + uint16_t opcode = inst & 127; + printf("opcode:"); + printf("\n"); + print_bin16(opcode); + printf("\n"); + + exec_fn fn = opcode_table[opcode]; + cpu_state_t cpu; + cpu.x[1] = 5; + cpu.x[2] = 14; + + + if (!fn) { + //illegal(NULL, inst); + fprintf(stderr, "Illegal opcode\n"); + return EXIT_FAILURE; + } + + fn(&cpu,inst); + + return 0; +}