// https://github.com/cnlohr/mini-rv32ima/tree/master/mini-rv32ima // Copyright 2022 Charles Lohr, you may use this file or any portions herein under any of the BSD, MIT, or CC0 licenses. // 23.01.15 converted to Arduino by mchris // This Version can run on an Arduino Nano #include "minirv32ima.h" uint32_t ram_amt = MINI_RV32_RAM_SIZE; // online RISCV interpreter // https://www.cs.cornell.edu/courses/cs3410/2019sp/riscv/interpreter/ // online assembler // https://riscvasm.lucasteske.dev/ /* .global _boot .text _boot: andi x1,x1,0 addi x2,x2,1 loop: addi x2,x2,1 jal x3,loop */ uint8_t ram_image[] = { 0x93, 0xf0, 0x00, 0x00, // andi x1,x1,0 ; register x1 loeschen 0x13, 0x01, 0x11, 0x00, // addi x2,x2,1 ; register x2 incrementieren 0x13, 0x01, 0x11, 0x00, // addi x2,x2,1 ; register x2 incrementieren 0xef, 0xf1, 0xdf, 0xff // jal x3,loop ; 4 bytes zurueckspringen und addresse in X3 }; struct MiniRV32IMAState * core; struct MiniRV32IMAState state; void benchmark() { static uint32_t elapsedUs = 0; unsigned long totalTime; unsigned long startTime = micros(); int numberOfSteps = 1000; RiscV_execute( core, ram_image, 0, elapsedUs++, numberOfSteps); totalTime = micros() - startTime; Serial.print("time for 1000 steps [us]:"); Serial.println(totalTime); Serial.print("micro seconds per step:"); Serial.println(totalTime / 1000); } void resetCpu() { int dtb_ptr = 0; core->pc = MINIRV32_RAM_IMAGE_OFFSET; for (int n = 0; n < 32; n++) core->regs[n] = 0; core->regs[10] = 0x00; //hart ID core->regs[11] = dtb_ptr ? (dtb_ptr + MINIRV32_RAM_IMAGE_OFFSET) : 0; //dtb_pa (Must be valid pointer) (Should be pointer to dtb) core->extraflags |= 3; // Machine-mode. } void setup() { Serial.begin(115200); // put your setup code here, to run once: // The core lives at the end of RAM. //core = (struct MiniRV32IMAState *)(ram_image + ram_amt - sizeof( struct MiniRV32IMAState )); core = &state; resetCpu(); Serial.println("RiscV on Arduino"); benchmark(); Serial.println("type any key"); while (Serial.available() == 0); resetCpu(); } void dump() { uint32_t * regs = core->regs; Serial.print("pc:"); Serial.print(core->pc, HEX); for (int n = 0; n < 32; n++) { Serial.print(" x"); Serial.print(n); Serial.print(":"); Serial.print(regs[n], HEX); } Serial.println(""); /* Serial.print("ra ");Serial.println(regs[1]); Serial.print("sp ");Serial.println(regs[2]); Serial.print("gp ");Serial.println(regs[3]); Serial.print("tp ");Serial.println(regs[4]); Serial.print("t0 ");Serial.println(regs[5]); Serial.print("t1 ");Serial.println(regs[6]); Serial.print("t2 ");Serial.println(regs[7]); Serial.print("fp ");Serial.println(regs[8]); Serial.print("s1 ");Serial.println(regs[9]); Serial.print("a0 ");Serial.println(regs[10]); Serial.print("a1 ");Serial.println(regs[11]); Serial.print("a2 ");Serial.println(regs[12]); Serial.print("a3 ");Serial.println(regs[13]); Serial.print("a4 ");Serial.println(regs[14]); Serial.print("a5 ");Serial.println(regs[15]); */ //Serial.println("==="); } void loop() { static uint32_t elapsedUs = 0; int numberOfSteps = 1; RiscV_execute( core, ram_image, 0, elapsedUs++, numberOfSteps); dump(); delay(1000); }