non memory instructions
parent
4b68fa8a64
commit
ee7ff194c4
|
@ -39,6 +39,9 @@
|
||||||
`define INS_ENVOP_CALL 12'b000000000000
|
`define INS_ENVOP_CALL 12'b000000000000
|
||||||
`define INS_ENVOP_BREAK 12'b000000000001
|
`define INS_ENVOP_BREAK 12'b000000000001
|
||||||
|
|
||||||
|
`define F3_DONT_CARE 3'b???
|
||||||
|
`define F7_DONT_CARE 7'b???????
|
||||||
|
|
||||||
// RISC-V CPU Hart
|
// RISC-V CPU Hart
|
||||||
module hart(
|
module hart(
|
||||||
clk,
|
clk,
|
||||||
|
@ -129,7 +132,7 @@ module hart(
|
||||||
`INS_FENCE,
|
`INS_FENCE,
|
||||||
`INS_REGOP: t_d_imm = 0;
|
`INS_REGOP: t_d_imm = 0;
|
||||||
|
|
||||||
default: $error("INVALID INSTRUCTION");
|
default: $error("INVALID INSTRUCTION %b", t_d_op);
|
||||||
endcase
|
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);
|
$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);
|
||||||
|
@ -147,18 +150,135 @@ module hart(
|
||||||
@(posedge clk);
|
@(posedge clk);
|
||||||
$display("== EXECUTE ==");
|
$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
|
// write back
|
||||||
@(posedge clk);
|
@(posedge clk);
|
||||||
$display("== WRITE REGISTERS ==");
|
$display("== WRITE REGISTERS ==");
|
||||||
|
|
||||||
case (t_d_op)
|
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;
|
if (t_d_rd != 0) reg_int[t_d_rd] = t_e_result;
|
||||||
end
|
end
|
||||||
default:;
|
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
// finish up
|
// finish up
|
||||||
reg_pc += 4;
|
reg_pc = t_e_branch ? t_e_address : reg_pc + 4;
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
4
makefile
4
makefile
|
@ -25,7 +25,7 @@ build/kernel.mem: build/kernel
|
||||||
|
|
||||||
build/kernel: ${KERNEL_SOURCES}
|
build/kernel: ${KERNEL_SOURCES}
|
||||||
clang ${KERNEL_SOURCES} -o build/kernel \
|
clang ${KERNEL_SOURCES} -o build/kernel \
|
||||||
--target=riscv64 \
|
--target=riscv32 \
|
||||||
-nostdlib \
|
-nostdlib \
|
||||||
-march=rv64i \
|
-march=rv32i \
|
||||||
-Xlinker --oformat=binary
|
-Xlinker --oformat=binary
|
|
@ -1,37 +1,12 @@
|
||||||
_start:
|
_start:
|
||||||
li x5, 120
|
li x1, 0
|
||||||
li x0, 1
|
li x2, 1
|
||||||
li x5, 214
|
li x3, 0
|
||||||
li x18, -121
|
li x4, 0
|
||||||
li x31, -130
|
li x5, 32
|
||||||
li x1, 0
|
fib:
|
||||||
li x2, 0
|
add x3, x1, x2
|
||||||
li x3, 0
|
mv x1, x2
|
||||||
li x4, 0
|
mv x2, x3
|
||||||
li x5, 0
|
add x4, x4, 1
|
||||||
li x6, 0
|
bne x4, x5, fib
|
||||||
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
|
|
Loading…
Reference in New Issue