Initial commit
This commit is contained in:
parent
29b805476f
commit
1267567eb6
|
|
@ -0,0 +1,10 @@
|
||||||
|
module main
|
||||||
|
|
||||||
|
import vm
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println('Hello World!')
|
||||||
|
|
||||||
|
vm.start_vm()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
module main
|
||||||
|
|
||||||
|
import vm
|
||||||
|
|
||||||
|
|
||||||
|
mut stdin := [1024]u8;
|
||||||
|
mut stdout := [1024]u8;
|
||||||
|
|
||||||
|
|
||||||
|
fn read(input [u8])
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn exit() {
|
||||||
|
exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write(input [u8])
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn request_control()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
module main
|
||||||
|
|
||||||
|
import readline { read_line }
|
||||||
|
|
||||||
|
import kernel
|
||||||
|
|
||||||
|
cmds := {
|
||||||
|
'EXIT' : 0
|
||||||
|
'READ' : 1
|
||||||
|
'WRITE' : 2
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sh(){
|
||||||
|
|
||||||
|
print("# ")
|
||||||
|
mut read_line := readline.Readline{}
|
||||||
|
cmd := read_line()!
|
||||||
|
|
||||||
|
sys_code := cmds[cmd] or { panic('Command not found:\n')}
|
||||||
|
kernel.do_syscall(sys_code)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
module main
|
||||||
|
|
||||||
|
import kernel
|
||||||
|
|
||||||
|
enum syscalls {
|
||||||
|
EXIT,
|
||||||
|
READ,
|
||||||
|
WRITE
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_syscall(sys_code int)
|
||||||
|
{
|
||||||
|
match sys_code :
|
||||||
|
0 { kernel.exit() }
|
||||||
|
1 { kernel.read() }
|
||||||
|
2 { kernel.write() }
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fn start_assembler()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
|
||||||
|
module main
|
||||||
|
|
||||||
|
import vm
|
||||||
|
|
||||||
|
struct Alu{
|
||||||
|
pub mut:
|
||||||
|
a u8
|
||||||
|
b u8
|
||||||
|
s u8
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (alu Alu) sum() { alu.s = alu.a + alu.b; }
|
||||||
|
fn (alu Alu) sub() { alu.s = alu.a - alu.b; }
|
||||||
|
fn (alu Alu) mul() { alu.s = alu.a * alu.b; }
|
||||||
|
fn (alu Alu) div() { alu.s = alu.a / alu.b; }
|
||||||
|
|
||||||
|
fn (alu Alu) or() { alu.s = alu.a | alu.b }
|
||||||
|
fn (alu Alu) and() { alu.s = alu.a & alu.b }
|
||||||
|
fn (alu Alu) xor() { alu.s = alu.a ^ alu.b }
|
||||||
|
fn (alu Alu) sll() { alu.s = alu.a << alu.b }
|
||||||
|
fn (alu Alu) sra() { alu.s = alu.a >> alu.b }
|
||||||
|
fn (alu Alu) slt() { alu.s = alu.a < alu.b ? 1 : 0}
|
||||||
|
fn (alu Alu) slt() { alu.s = alu.a > alu.b ? 1 : 0}
|
||||||
|
fn (alu Alu) beq() { alu.s = alu.a == alu.b ? 1 : 0}
|
||||||
|
|
||||||
|
struct CPU{
|
||||||
|
pub:
|
||||||
|
num_of_registers := 32
|
||||||
|
|
||||||
|
pub mut:
|
||||||
|
pc u32
|
||||||
|
registers[num_of_registers]u8
|
||||||
|
alu Alu
|
||||||
|
cpu_control = none
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn (cpu CPU) start_cpu()
|
||||||
|
{
|
||||||
|
cpu.pc := 0
|
||||||
|
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
u32 instruction := cpu.fetch()
|
||||||
|
cpu.decode(instruction)
|
||||||
|
cpu.run()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (cpu CPU) fetch()
|
||||||
|
{
|
||||||
|
u32 instruction := vm.RAM[cpu.pc];
|
||||||
|
cpu.pc += 4
|
||||||
|
|
||||||
|
return instruction
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (cpu CPU) decode(u32 instruction)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (cpu CPU) run(u32 instruction)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,287 @@
|
||||||
|
module main
|
||||||
|
|
||||||
|
import vm.hardware as vm
|
||||||
|
|
||||||
|
struct J{
|
||||||
|
pub mut:
|
||||||
|
rd i8
|
||||||
|
imm u32
|
||||||
|
}
|
||||||
|
|
||||||
|
struct R{
|
||||||
|
pub mut:
|
||||||
|
rd u8;
|
||||||
|
rs1 u8;
|
||||||
|
rs2 u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct I{
|
||||||
|
pub mut:
|
||||||
|
rd u8;
|
||||||
|
rs1 u8;
|
||||||
|
imm u16;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct U{
|
||||||
|
pub mut:
|
||||||
|
rd u8;
|
||||||
|
imm u32;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct B{
|
||||||
|
pub mut:
|
||||||
|
rs1 u8;
|
||||||
|
rs2 u8;
|
||||||
|
imm u16;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Instruction{
|
||||||
|
pub mut:
|
||||||
|
fmt_r R
|
||||||
|
fmt_i I
|
||||||
|
fmt_b B
|
||||||
|
fmt_u U
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (inst Instruction) add() {
|
||||||
|
|
||||||
|
mut rd := inst.fmt_r.rd
|
||||||
|
mut rs1 := inst.fmt_r.rs1
|
||||||
|
mut rs2 := inst.fmt_r.rs2
|
||||||
|
|
||||||
|
vm.cpu.registers[rd] = vm.cpu.alu.sum(vm.cpu.registers[rs1], vm.cpu.registers[rs2])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (inst Instruction) sub() {
|
||||||
|
|
||||||
|
mut rd := inst.fmt_r.rd
|
||||||
|
mut rs1 := inst.fmt_r.rs1
|
||||||
|
mut rs2 := inst.fmt_r.rs2
|
||||||
|
|
||||||
|
vm.cpu.registers[rd] = vm.cpu.alu.sub(vm.cpu.registers[rs1], vm.cpu.registers[rs2])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (inst Instruction) xor() {
|
||||||
|
|
||||||
|
mut rd := inst.fmt_r.rd
|
||||||
|
mut rs1 := inst.fmt_r.rs1
|
||||||
|
mut rs2 := inst.fmt_r.rs2
|
||||||
|
|
||||||
|
vm.cpu.registers[rd] = vm.cpu.alu.xor(vm.cpu.registers[rs1], vm.cpu.registers[rs2])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (inst Instruction) _or () {
|
||||||
|
|
||||||
|
mut rd := inst.fmt_r.rd
|
||||||
|
mut rs1 := inst.fmt_r.rs1
|
||||||
|
mut rs2 := inst.fmt_r.rs2
|
||||||
|
|
||||||
|
vm.cpu.registers[rd] = vm.cpu.alu._or(vm.cpu.registers[rs1], vm.cpu.registers[rs2])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (inst Instruction) and() {
|
||||||
|
|
||||||
|
mut rd := inst.fmt_r.rd
|
||||||
|
mut rs1 := inst.fmt_r.rs1
|
||||||
|
mut rs2 := inst.fmt_r.rs2
|
||||||
|
|
||||||
|
vm.cpu.registers[rd] = vm.cpu.alu.and(vm.cpu.registers[rs1], vm.cpu.registers[rs2])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (inst Instruction) sll() {
|
||||||
|
|
||||||
|
mut rd := inst.fmt_r.rd
|
||||||
|
mut rs1 := inst.fmt_r.rs1
|
||||||
|
mut rs2 := inst.fmt_r.rs2
|
||||||
|
|
||||||
|
vm.cpu.registers[rd] = vm.cpu.alu.sll(vm.cpu.registers[rs1], vm.cpu.registers[rs2])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (inst Instruction) sra() {
|
||||||
|
|
||||||
|
mut rd := inst.fmt_r.rd
|
||||||
|
mut rs1 := inst.fmt_r.rs1
|
||||||
|
mut rs2 := inst.fmt_r.rs2
|
||||||
|
|
||||||
|
vm.cpu.registers[rd] = vm.cpu.alu.sra(vm.cpu.registers[rs1], vm.cpu.registers[rs2])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (inst Instruction) slt() {
|
||||||
|
|
||||||
|
mut rd := inst.fmt_r.rd
|
||||||
|
mut rs1 := inst.fmt_r.rs1
|
||||||
|
mut rs2 := inst.fmt_r.rs2
|
||||||
|
|
||||||
|
vm.cpu.registers[rd] = vm.cpu.alu.slt(vm.cpu.registers[rs1], vm.cpu.registers[rs2])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (inst Instruction) sltu() { inst.slt() }
|
||||||
|
|
||||||
|
fn (inst Instruction) lw() {
|
||||||
|
mut rd := inst.fmt_i.rd
|
||||||
|
mut rs1 := inst.fmt_i.rs1
|
||||||
|
mut imm := inst.fmt_i.imm
|
||||||
|
|
||||||
|
vm.cpu.registers[rd] = vm.RAM[vm.cpu.slu.sum(vm.cpu.registers[rs1], imm)]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (inst Instruction) beq() {
|
||||||
|
mut rs1 := inst.fmt_b.rs1
|
||||||
|
mut rs2 := inst.fmt_b.rs2
|
||||||
|
mut imm := inst.fmt_b.imm
|
||||||
|
|
||||||
|
vm.cpu.alu.beq(vm.cpu.registers[rs1], vm.cpu.registers[rs2])
|
||||||
|
|
||||||
|
if vm.cpu.alu.s == 1 { vm.cpu.pc += imm }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (inst Instruction) bne() {
|
||||||
|
|
||||||
|
mut rs1 := inst.fmt_b.rs1
|
||||||
|
mut rs2 := inst.fmt_b.rs2
|
||||||
|
mut imm := inst.fmt_b.imm
|
||||||
|
|
||||||
|
vm.cpu.alu.beq(vm.cpu.registers[rs1], vm.cpu.registers[rs2])
|
||||||
|
|
||||||
|
if vm.cpu.alu.s == 0 { vm.cpu.pc += imm }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (inst Instruction) blt() {
|
||||||
|
|
||||||
|
mut rs1 := inst.fmt_b.rs1
|
||||||
|
mut rs2 := inst.fmt_b.rs2
|
||||||
|
mut imm := inst.fmt_b.imm
|
||||||
|
|
||||||
|
vm.cpu.alu.slt(vm.cpu.registers[rs1], vm.cpu.registers[rs2])
|
||||||
|
|
||||||
|
if vm.cpu.alu.s == 1 { vm.cpu.pc += imm }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (inst Instruction) bge() {
|
||||||
|
|
||||||
|
mut rs1 := inst.fmt_b.rs1
|
||||||
|
mut rs2 := inst.fmt_b.rs2
|
||||||
|
mut imm := inst.fmt_b.imm
|
||||||
|
|
||||||
|
vm.cpu.alu.beq(vm.cpu.registers[rs1], vm.cpu.registers[rs2])
|
||||||
|
if vm.cpu.alu.s == 1 { vm.cpu.pc += imm }
|
||||||
|
|
||||||
|
vm.cpu.alu.slt(vm.cpu.registers[rs1], vm.cpu.registers[rs2])
|
||||||
|
if vm.cpu.alu.s == 1 { vm.cpu.pc += imm }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (inst Instruction) bltu() { inst.blt() }
|
||||||
|
|
||||||
|
fn (inst Instruction) bgeu() { inst.bgeu() }
|
||||||
|
|
||||||
|
fn (inst Instruction) jal() {
|
||||||
|
mut rd := inst.fmt_j.rd
|
||||||
|
mut imm := inst.fmt_j.imm
|
||||||
|
|
||||||
|
vm.cpu.registers[rd] = vm.cpu.pc + 4
|
||||||
|
vm.cpu.pc += imm
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (inst Instruction) jalr() {
|
||||||
|
|
||||||
|
mut rd := inst.fmt_i.rd
|
||||||
|
mut rs1 := inst.fmt_i.rs1
|
||||||
|
mut imm := inst.fmt_i.imm
|
||||||
|
|
||||||
|
vm.cpu.registers[rd] = vm.cpu.pc + 4
|
||||||
|
vm.cpu.pc = vm.cpu.registers[rs1] + imm
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (inst Instruction) lui() {
|
||||||
|
|
||||||
|
mut rd := inst.fmt_u.rd
|
||||||
|
mut imm := inst.fmt_u.imm
|
||||||
|
|
||||||
|
vm.cpu.registers[rd] = vm.cpu.alu.sll(imm, 12)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (inst Instruction) auipc() {
|
||||||
|
mut rd := inst.fmt_u.rd
|
||||||
|
mut imm := inst.fmt_u.imm
|
||||||
|
|
||||||
|
vm.cpu.registers[rd] = vm.cpu.pc + vm.cpu.alu.sll(imm, 12)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (inst Instruction) ecall() {
|
||||||
|
vm.cpu.cpu_control = 'kernel'
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (inst Instruction) addi() {
|
||||||
|
|
||||||
|
mut rd := inst.fmt_i.rd
|
||||||
|
mut rs1 := inst.fmt_i.rs1
|
||||||
|
mut imm := inst.fmt_i.imm
|
||||||
|
|
||||||
|
vm.cpu.registers[rd] = vm.cpu.alu.addi(vm.cpu.registers[rs1], imm)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (inst Instruction) subi() {
|
||||||
|
|
||||||
|
mut rd := inst.fmt_i.rd
|
||||||
|
mut rs1 := inst.fmt_i.rs1
|
||||||
|
mut imm := inst.fmt_i.imm
|
||||||
|
|
||||||
|
vm.cpu.registers[rd] = vm.cpu.alu.subi(vm.cpu.registers[rs1], imm)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (inst Instruction) xori() {
|
||||||
|
|
||||||
|
mut rd := inst.fmt_i.rd
|
||||||
|
mut rs1 := inst.fmt_i.rs1
|
||||||
|
mut imm := inst.fmt_i.imm
|
||||||
|
|
||||||
|
vm.cpu.registers[rd] = vm.cpu.alu.xori(vm.cpu.registers[rs1], imm)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (inst Instruction) ori () {
|
||||||
|
|
||||||
|
mut rd := inst.fmt_i.rd
|
||||||
|
mut rs1 := inst.fmt_i.rs1
|
||||||
|
mut imm := inst.fmt_i.imm
|
||||||
|
|
||||||
|
vm.cpu.registers[rd] = vm.cpu.alu.ori(vm.cpu.registers[rs1], imm)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (inst Instruction) andi() {
|
||||||
|
|
||||||
|
mut rd := inst.fmt_i.rd
|
||||||
|
mut rs1 := inst.fmt_i.rs1
|
||||||
|
mut imm := inst.fmt_i.imm
|
||||||
|
|
||||||
|
vm.cpu.registers[rd] = vm.cpu.alu.andi(vm.cpu.registers[rs1], imm)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (inst Instruction) slli() {
|
||||||
|
|
||||||
|
mut rd := inst.fmt_i.rd
|
||||||
|
mut rs1 := inst.fmt_i.rs1
|
||||||
|
mut imm := inst.fmt_i.imm
|
||||||
|
|
||||||
|
vm.cpu.registers[rd] = vm.cpu.alu.slli(vm.cpu.registers[rs1], imm)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (inst Instruction) srai() {
|
||||||
|
|
||||||
|
mut rd := inst.fmt_i.rd
|
||||||
|
mut rs1 := inst.fmt_i.rs1
|
||||||
|
mut imm := inst.fmt_i.imm
|
||||||
|
|
||||||
|
vm.cpu.registers[rd] = vm.cpu.alu.srai(vm.cpu.registers[rs1], imm)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (inst Instruction) slti() {
|
||||||
|
|
||||||
|
mut rd := inst.fmt_i.rd
|
||||||
|
mut rs1 := inst.fmt_i.rs1
|
||||||
|
mut imm := inst.fmt_i.imm
|
||||||
|
|
||||||
|
vm.cpu.registers[rd] = vm.cpu.alu.slti(vm.cpu.registers[rs1], imm)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (inst Instruction) sltiu() { inst.slti() }
|
||||||
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
module main
|
||||||
|
|
||||||
|
import cpu
|
||||||
|
|
||||||
|
|
||||||
|
mut hardware := Hardware{ram: RAM{}, cpu: Cpu{}}
|
||||||
|
|
||||||
|
struct Hardware
|
||||||
|
{
|
||||||
|
pub mut:
|
||||||
|
ram RAM;
|
||||||
|
cpu cpu.CPU;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct RAM
|
||||||
|
{
|
||||||
|
pub:
|
||||||
|
mem_size_in_mb := 100
|
||||||
|
|
||||||
|
pub mut:
|
||||||
|
memory[mem_size_in_mb]u32
|
||||||
|
current_memory_addess u32
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fn load_instructions(asm_instructions[string])
|
||||||
|
{
|
||||||
|
for mut instruction in asm_instructions {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn start_assembler()
|
||||||
|
{
|
||||||
|
mut instructions := {"ADD s0, s1, s2", "ADDI s0, s1, s2", "MUL s2, s3, s3"}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn start_vm()
|
||||||
|
{
|
||||||
|
// Load asm instructions, converts to machine instructions and save in memory
|
||||||
|
start_assembler()
|
||||||
|
// Get in memory, decode and run instructions
|
||||||
|
cpu.start_cpu()
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
Module {
|
||||||
|
name: 'riscv_vm'
|
||||||
|
description: 'Virtual Machine for RISCV CPU'
|
||||||
|
version: '0.0.0'
|
||||||
|
license: 'MIT'
|
||||||
|
dependencies: []
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit f3d331096556256d477b129cb199d193795ae35f
|
||||||
Loading…
Reference in New Issue