Skip to content

Commit

Permalink
Add a parameter for M extension support
Browse files Browse the repository at this point in the history
  • Loading branch information
robotman2412 committed Jan 5, 2024
1 parent 8ebd220 commit 4677d7a
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 13 deletions.
10 changes: 6 additions & 4 deletions hdl/boa32_cpu.sv
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,13 @@ module boa32_cpu#(
parameter entrypoint = 32'h4000_0000,
// CPU-local memory-mapped I/O address.
parameter cpummio = 32'hff00_0000,
// CSR mhartid value.
// CSR mhartid value (CPU number).
parameter hartid = 32'h0000_0000,
// Print debug messages about CPU state.
parameter debug = 0,
// Support RVC instructions.
// Support M (multiply/divide) instructions.
parameter has_m = 1,
// Support C (compressed) instructions.
parameter has_c = 1
)(
// CPU clock.
Expand Down Expand Up @@ -479,7 +481,7 @@ module boa32_cpu#(
// Data hazard avoicance.
fw_stall_if
);
boa_stage_id#(.debug(debug), .has_c(has_c)) st_id(
boa_stage_id#(.debug(debug), .has_m(has_m), .has_c(has_c)) st_id(
clk, rst, clear_id,
// Pipeline input.
if_id_valid && !fw_stall_if, if_id_pc, if_id_insn, if_id_trap && !fw_stall_if, if_id_cause,
Expand All @@ -492,7 +494,7 @@ module boa32_cpu#(
// Data hazard avoidance.
fw_stall_id, use_rs1_bt, fw_rs1_bt, fw_in_bt
);
boa_stage_ex st_ex(
boa_stage_ex#(.has_m(has_m)) st_ex (
clk, rst, clear_ex,
// Pipeline input.
id_ex_valid && !fw_stall_id, id_ex_pc, id_ex_insn, id_ex_ilen, id_ex_use_rd, fw_rs1_ex ? fw_in_rs1_ex : id_ex_rs1_val, fw_rs2_ex ? fw_in_rs2_ex : id_ex_rs2_val, id_ex_branch, id_ex_branch_predict, id_ex_trap && !fw_stall_id, id_ex_cause,
Expand Down
22 changes: 16 additions & 6 deletions hdl/stages/boa_stage_ex.sv
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
// Boa³² pipline stage: EX (ALU and address calculation).
module boa_stage_ex#(
// Divider latency, 0 to 33.
parameter div_latency = 2
// Only applicable if has_m is 1.
parameter div_latency = 2,
// Support M (multiply/divide) instructions.
parameter has_m = 1
)(
// CPU clock.
input logic clk,
Expand Down Expand Up @@ -158,22 +161,29 @@ module boa_stage_ex#(
logic[31:0] div_res;
logic[31:0] mod_res;
logic[31:0] shx_res;
boa_mul_simple mul(mul_u_lhs, mul_u_rhs, r_rs1_val, r_rs2_val, mul_res);
generate
if (div_latency == 0) begin: l0
if (has_m) begin: mul
boa_mul_simple mul(mul_u_lhs, mul_u_rhs, r_rs1_val, r_rs2_val, mul_res);
end else begin: nomul
assign mul_res = 'bx;
end
if (has_m && div_latency == 0) begin: l0div
boa_div_simple div(
div_u, r_rs1_val, r_rs2_val, div_res, mod_res
);
end else begin: l1
end else if (has_m) begin: l1div
boa_div_pipelined#(.latency(div_latency)) div(
clk, div_u, r_rs1_val, r_rs2_val, div_res, mod_res
);
end else begin: nodiv
assign div_res = 'bx;
assign mod_res = 'bx;
end
endgenerate
boa_shift_simple shift(shr_arith, shr, r_rs1_val, op_rhs_mux, shx_res);

// Computation delay module.
wire is_divmod = d_valid && d_insn[6:2] == `RV_OP_OP && d_insn[25] && d_insn[14];
wire is_divmod = has_m && d_valid && d_insn[6:2] == `RV_OP_OP && d_insn[25] && d_insn[14];
boa_delay_comp#(div_latency) div_delay(clk, is_divmod, stall_req);

// Adder mode.
Expand Down Expand Up @@ -226,7 +236,7 @@ module boa_stage_ex#(
logic[31:0] out_mux;
always @(*) begin
if (is_op) begin
if (muldiv_en) begin
if (has_m && muldiv_en) begin
// MULDIV instructions.
casez (r_insn[14:12])
3'b000: out_mux = mul_res[31:0];
Expand Down
4 changes: 3 additions & 1 deletion hdl/stages/boa_stage_id.sv
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
module boa_stage_id#(
// Print debug messages about CPU state.
parameter debug = 0,
// Support RVC instructions.
// Support M (multiply/divide) instructions.
parameter has_m = 1,
// Support C (compressed) instructions.
parameter has_c = 1
)(
// CPU clock.
Expand Down
8 changes: 8 additions & 0 deletions sim/riscv-tests/bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ int main(int argc, char **argv) {
// Add exit handlers.
atexit(atexit_func);

bool catch_ebreak = getenv("CATCH_EBREAK");

// Set UART to nonblocking.
stdin_orig_flags = fcntl(0, F_GETFL);
fcntl(fileno(stdin), F_SETFL, stdin_orig_flags | O_NONBLOCK);
Expand Down Expand Up @@ -55,6 +57,12 @@ int main(int argc, char **argv) {
trace->dump(i * 10);
top->clk ^= 1;

if (top->is_ebreak && top->clk && catch_ebreak) {
printf("Trace / breakpoint trap\n");
printf("PC = 0x%08x\n", top->epc << 1);
ec = -3;
break;
}
if (top->is_ecall && top->clk) {
int a0 = top->regs[10];
int a7 = top->regs[17];
Expand Down
12 changes: 10 additions & 2 deletions sim/riscv-tests/hdl/top.sv
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@
module top(
input logic clk,
output logic is_ecall,
output logic[31:0] regs[31:0]
output logic is_ebreak,
output logic[31:0] regs[31:0],
output logic[31:1] epc
);
`include "boa_fileio.svh"
`include "boa_defines.svh"

// To host time.
assign is_ecall = cpu.csr_ex.ex_trap && cpu.csr_ex.ex_cause == `RV_ECAUSE_M_ECALL;
assign is_ebreak = cpu.csr_ex.ex_trap && cpu.csr_ex.ex_cause == `RV_ECAUSE_EBREAK;
assign epc = cpu.csr_ex.ex_epc;
assign regs[0] = 0;
assign regs[31:1] = cpu.st_id.regfile.storage;

Expand Down Expand Up @@ -46,7 +50,11 @@ module top(
end

// The boa CPU core.
boa32_cpu#(32'h8000_0000) cpu(
boa32_cpu#(
.entrypoint(32'h8000_0000),
.has_c(1),
.has_m(1)
) cpu (
clk, clk, rst, pbus, dbus, 0
);
endmodule
Expand Down

0 comments on commit 4677d7a

Please sign in to comment.