From ee7ff194c4ef542f77ece663ee7400343ce6a8c9 Mon Sep 17 00:00:00 2001 From: xwashere Date: Fri, 29 Dec 2023 15:00:02 -0500 Subject: [PATCH] non memory instructions --- board/parts/hart.sv | 128 ++++++++++++++++++++++++++++++++++++++++++-- makefile | 4 +- os/kernel/boot.s | 49 +++++------------ 3 files changed, 138 insertions(+), 43 deletions(-) diff --git a/board/parts/hart.sv b/board/parts/hart.sv index 431a597..33afb65 100644 --- a/board/parts/hart.sv +++ b/board/parts/hart.sv @@ -39,6 +39,9 @@ `define INS_ENVOP_CALL 12'b000000000000 `define INS_ENVOP_BREAK 12'b000000000001 +`define F3_DONT_CARE 3'b??? +`define F7_DONT_CARE 7'b??????? + // RISC-V CPU Hart module hart( clk, @@ -129,7 +132,7 @@ module hart( `INS_FENCE, `INS_REGOP: t_d_imm = 0; - default: $error("INVALID INSTRUCTION"); + default: $error("INVALID INSTRUCTION %b", t_d_op); endcase $display("INS: %7b %3b %7b %d %d -> %d", t_d_op, t_d_f3, t_d_f7, t_d_r1, t_d_r2, t_d_rd); @@ -146,19 +149,136 @@ module hart( // execute @(posedge clk); $display("== EXECUTE =="); + + t_e_address = 0; + t_e_branch = 0; + t_e_result = 0; + + casez ({ t_d_op, t_d_f3, t_d_f7 }) + { `INS_LUI, `F3_DONT_CARE, `F7_DONT_CARE }: t_e_result = t_d_imm; + { `INS_AUIPC, `F3_DONT_CARE, `F7_DONT_CARE }: t_e_result = t_d_imm + reg_pc; + { `INS_JAL, `F3_DONT_CARE, `F7_DONT_CARE }: begin + t_e_result = reg_pc + 4; + t_e_address = reg_pc + t_d_imm; + t_e_branch = 1; + end + { `INS_JALR, `F3_DONT_CARE, `F7_DONT_CARE }: begin + t_e_result = reg_pc + 4; + t_e_address = (t_r_a + t_d_imm) & ~1; + t_e_branch = 1; + end + { `INS_BRANCH, `INS_BRANCH_EQ, `F7_DONT_CARE }: begin + if (t_r_a == t_r_b) begin + t_e_address = reg_pc + t_d_imm; + t_e_branch = 1; + end + end + { `INS_BRANCH, `INS_BRANCH_NE, `F7_DONT_CARE }: begin + if (t_r_a != t_r_b) begin + t_e_address = reg_pc + t_d_imm; + t_e_branch = 1; + end + end + { `INS_BRANCH, `INS_BRANCH_LT, `F7_DONT_CARE }: begin + if ($signed(t_r_a) < $signed(t_r_b)) begin + t_e_address = reg_pc + t_d_imm; + t_e_branch = 1; + end + end + { `INS_BRANCH, `INS_BRANCH_GE, `F7_DONT_CARE }: begin + if ($signed(t_r_a) >= $signed(t_r_b)) begin + t_e_address = reg_pc + t_d_imm; + t_e_branch = 1; + end + end + { `INS_BRANCH, `INS_BRANCH_LTU, `F7_DONT_CARE }: begin + if (t_r_a < t_r_b) begin + t_e_address = reg_pc + t_d_imm; + t_e_branch = 1; + end + end + { `INS_BRANCH, `INS_BRANCH_GEU, `F7_DONT_CARE }: begin + if (t_r_a >= t_r_b) begin + t_e_address = reg_pc + t_d_imm; + t_e_branch = 1; + end + end + { `INS_LOAD, `F3_DONT_CARE, `F7_DONT_CARE }: $error("NOT IMPLEMENTED"); + { `INS_STORE, `F3_DONT_CARE, `F7_DONT_CARE }: $error("NOT IMPLEMENTED"); + { `INS_IMMOP, `INS_ALUOP_ADD, `F7_DONT_CARE }: begin + t_e_result = $signed(t_r_a) + $signed(t_d_imm); + end + { `INS_IMMOP, `INS_ALUOP_SLT, `F7_DONT_CARE }: begin + t_e_result = $signed(t_r_a) < $signed(t_d_imm) ? 1 : 0; + end + { `INS_IMMOP, `INS_ALUOP_SLTU, `F7_DONT_CARE }: begin + t_e_result = t_r_a < t_d_imm ? 1 : 0; + end + { `INS_IMMOP, `INS_ALUOP_XOR, `F7_DONT_CARE }: begin + t_e_result = t_r_a ^ t_d_imm; + end + { `INS_IMMOP, `INS_ALUOP_OR, `F7_DONT_CARE }: begin + t_e_result = t_r_a | t_d_imm; + end + { `INS_IMMOP, `INS_ALUOP_AND, `F7_DONT_CARE }: begin + t_e_result = t_r_a & t_d_imm; + end + { `INS_IMMOP, `INS_ALUOP_SLL, 7'b0000000 }: begin + t_e_result = t_r_a << (t_d_imm & 31); + end + { `INS_IMMOP, `INS_ALUOP_SRL, 7'b0000000 }: begin + t_e_result = t_r_a >> (t_d_imm & 31); + end + { `INS_IMMOP, `INS_ALUOP_SRL, 7'b0100000 }: begin + t_e_result = t_r_a >>> (t_d_imm & 31); + end + { `INS_REGOP, `INS_ALUOP_ADD, 7'b0000000 }: begin + t_e_result = $signed(t_r_a) + $signed(t_r_b); + end + { `INS_REGOP, `INS_ALUOP_ADD, 7'b0100000 }: begin + t_e_result = $signed(t_r_a) - $signed(t_r_b); + end + { `INS_REGOP, `INS_ALUOP_SLT, 7'b0000000 }: begin + t_e_result = $signed(t_r_a) < $signed(t_r_b) ? 1 : 0; + end + { `INS_REGOP, `INS_ALUOP_SLTU, 7'b0000000 }: begin + t_e_result = t_r_a < t_r_b ? 1 : 0; + end + { `INS_REGOP, `INS_ALUOP_XOR, 7'b0000000 }: begin + t_e_result = t_r_a ^ t_r_b; + end + { `INS_REGOP, `INS_ALUOP_OR, 7'b0000000 }: begin + t_e_result = t_r_a | t_r_b; + end + { `INS_REGOP, `INS_ALUOP_AND, 7'b0000000 }: begin + t_e_result = t_r_a & t_r_b; + end + { `INS_REGOP, `INS_ALUOP_SLL, 7'b0000000 }: begin + t_e_result = t_r_a << (t_r_b & 31); + end + { `INS_REGOP, `INS_ALUOP_SRL, 7'b0000000 }: begin + t_e_result = t_r_a >> (t_r_b & 31); + end + { `INS_REGOP, `INS_ALUOP_SRL, 7'b0100000 }: begin + t_e_result = t_r_a >>> (t_r_b & 31); + end + { `INS_FENCE, `F3_DONT_CARE, `F7_DONT_CARE }:; + { `INS_ENVOP, `F3_DONT_CARE, `F7_DONT_CARE }:; + default: $error("INVALID INSTRUCTION"); + endcase // write back @(posedge clk); $display("== WRITE REGISTERS =="); case (t_d_op) - `INS_BRANCH, `INS_STORE, `INS_FENCE, `INS_ENVOP: begin + `INS_BRANCH, `INS_STORE, `INS_FENCE, `INS_ENVOP:; + default: begin if (t_d_rd != 0) reg_int[t_d_rd] = t_e_result; end - default:; endcase // finish up - reg_pc += 4; + reg_pc = t_e_branch ? t_e_address : reg_pc + 4; end endmodule \ No newline at end of file diff --git a/makefile b/makefile index ea7a953..e3a93ab 100644 --- a/makefile +++ b/makefile @@ -25,7 +25,7 @@ build/kernel.mem: build/kernel build/kernel: ${KERNEL_SOURCES} clang ${KERNEL_SOURCES} -o build/kernel \ - --target=riscv64 \ + --target=riscv32 \ -nostdlib \ - -march=rv64i \ + -march=rv32i \ -Xlinker --oformat=binary \ No newline at end of file diff --git a/os/kernel/boot.s b/os/kernel/boot.s index a2658b1..450e8b7 100644 --- a/os/kernel/boot.s +++ b/os/kernel/boot.s @@ -1,37 +1,12 @@ -_start: - li x5, 120 - li x0, 1 - li x5, 214 - li x18, -121 - li x31, -130 - li x1, 0 - li x2, 0 - li x3, 0 - li x4, 0 - li x5, 0 - li x6, 0 - li x7, 0 - li x8, 0 - li x9, 0 - li x10, 0 - li x11, 0 - li x12, 0 - li x13, 0 - li x14, 0 - li x15, 0 - li x16, 0 - li x17, 0 - li x18, 0 - li x19, 0 - li x20, 0 - li x21, 0 - li x22, 0 - li x23, 0 - li x24, 0 - li x25, 0 - li x26, 0 - li x27, 0 - li x28, 0 - li x29, 0 - li x30, 0 - li x31, 0 \ No newline at end of file +_start: + li x1, 0 + li x2, 1 + li x3, 0 + li x4, 0 + li x5, 32 +fib: + add x3, x1, x2 + mv x1, x2 + mv x2, x3 + add x4, x4, 1 + bne x4, x5, fib \ No newline at end of file