non memory instructions

master
xwashere 2023-12-29 15:00:02 -05:00
parent 4b68fa8a64
commit ee7ff194c4
Signed by: XWasHere
GPG Key ID: 042F8BFA1B0EF93B
3 changed files with 138 additions and 43 deletions

View File

@ -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

View File

@ -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

View File

@ -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
_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