Fix MULW DIVW DIVUW, update current_status.txt

This commit is contained in:
Shashank Holla 2023-04-02 18:32:15 -04:00 committed by Blaise Tine
parent 49ff848f3d
commit 864349d812
6 changed files with 61 additions and 28 deletions

View file

@ -142,13 +142,13 @@ rv64ui-p-xor.hex ✅
rv64ui-p-xori.hex ✅
rv64um-p-div.hex ✅
rv64um-p-divu.hex ✅
rv64um-p-divuw.hex ❌ exitcode=5
rv64um-p-divw.hex ❌ exitcode=5
rv64um-p-mul.hex ❌ exitcode=15
rv64um-p-divuw.hex
rv64um-p-divw.hex
rv64um-p-mul.hex
rv64um-p-mulh.hex ❌ exitcode=15
rv64um-p-mulhsu.hex ❌ exitcode=15
rv64um-p-mulhu.hex ❌ exitcode=15
rv64um-p-mulw.hex ❌ exitcode=7
rv64um-p-mulhu.hex
rv64um-p-mulw.hex
rv64um-p-rem.hex ✅
rv64um-p-remu.hex ✅
rv64um-p-remuw.hex ❌ exitcode=5

View file

@ -176,6 +176,7 @@ void dpi_idiv(bool enable, long int a, long int b, bool is_signed, long int* quo
*remainder = dividen % divisor;
}
}
dpi_trace(1, "DIV - %d %lld %lld %lld %lld %lld %lld\n",is_signed , a, b, dividen, divisor, *quotient, *remainder);
}
///////////////////////////////////////////////////////////////////////////////

View file

@ -145,17 +145,24 @@
`define INST_BR_LESS(x) x[2]
`define INST_BR_STATIC(x) x[3]
`define INST_MUL_MUL 3'h0
`define INST_MUL_MULH 3'h1
`define INST_MUL_MULHSU 3'h2
`define INST_MUL_MULHU 3'h3
`define INST_MUL_DIV 3'h4
`define INST_MUL_DIVU 3'h5
`define INST_MUL_REM 3'h6
`define INST_MUL_REMU 3'h7
`define INST_MUL_BITS 3
`define INST_MUL_MUL 4'h0
`define INST_MUL_MULH 4'h1
`define INST_MUL_MULHSU 4'h2
`define INST_MUL_MULHU 4'h3
`define INST_MUL_DIV 4'h4
`define INST_MUL_DIVU 4'h5
`define INST_MUL_REM 4'h6
`define INST_MUL_REMU 4'h7
`define INST_MUL_BITS 4
`define INST_MUL_IS_DIV(x) x[2]
// RV64M instruction versions
`define INST_MUL_MULW 4'b1000
`define INST_MUL_DIVW 4'b1100
`define INST_MUL_DIVUW 4'b1101
`define INST_MUL_REMW 4'b1110
`define INST_MUL_REMUW 4'b1111
`define INST_FMT_B 3'b000
`define INST_FMT_H 3'b001
`define INST_FMT_W 3'b010

View file

@ -48,6 +48,9 @@ task trace_ex_op (
`INST_MUL_DIVU: `TRACE(level, ("DIVU"));
`INST_MUL_REM: `TRACE(level, ("REM"));
`INST_MUL_REMU: `TRACE(level, ("REMU"));
`INST_MUL_MULW: `TRACE(level, ("MULW"));
`INST_MUL_DIVW: `TRACE(level, ("DIVW"));
`INST_MUL_DIVUW: `TRACE(level, ("DIVUW"));
default: `TRACE(level, ("?"));
endcase
end else begin

View file

@ -151,12 +151,26 @@ module VX_decode #(
`INST_R_W: begin
// ADDW, SUBW, SLLW, SRLW, SRAW
ex_type = `EX_ALU;
case (func3)
3'h0: op_type = (func7[5]) ? `INST_OP_BITS'(`INST_ALU_SUB_W) : `INST_OP_BITS'(`INST_ALU_ADD_W);
3'h1: op_type = `INST_OP_BITS'(`INST_ALU_SLL_W);
3'h5: op_type = (func7[5]) ? `INST_OP_BITS'(`INST_ALU_SRA_W) : `INST_OP_BITS'(`INST_ALU_SRL_W);
default:;
endcase
ex_type = `EX_ALU;
`ifdef EXT_M_ENABLE
if (func7[0]) begin
case (func3)
3'h0: op_type = `INST_OP_BITS'(`INST_MUL_MULW);
3'h4: op_type = `INST_OP_BITS'(`INST_MUL_DIVW);
3'h5: op_type = `INST_OP_BITS'(`INST_MUL_DIVUW);
3'h6: op_type = `INST_OP_BITS'(`INST_MUL_REMW);
3'h7: op_type = `INST_OP_BITS'(`INST_MUL_REMUW);
default:;
endcase
op_mod = 2;
end else
`endif
case (func3)
3'h0: op_type = (func7[5]) ? `INST_OP_BITS'(`INST_ALU_SUB_W) : `INST_OP_BITS'(`INST_ALU_ADD_W);
3'h1: op_type = `INST_OP_BITS'(`INST_ALU_SLL_W);
3'h5: op_type = (func7[5]) ? `INST_OP_BITS'(`INST_ALU_SRA_W) : `INST_OP_BITS'(`INST_ALU_SRL_W);
default:;
endcase
use_rd = 1;
`USED_IREG (rd);
`USED_IREG (rs1);

View file

@ -49,9 +49,10 @@ module VX_muldiv (
wire mul_valid_in = valid_in && !is_div_op;
wire mul_ready_in = ~stall_out || ~mul_valid_out;
wire is_mulh_in = (alu_op != `INST_MUL_MUL);
wire is_mulh_in = (alu_op != `INST_MUL_MUL) && (alu_op != `INST_MUL_MULW);
wire is_signed_mul_a = (alu_op != `INST_MUL_MULHU);
wire is_signed_mul_b = (alu_op != `INST_MUL_MULHU && alu_op != `INST_MUL_MULHSU);
wire is_mulw = (alu_op == `INST_MUL_MULW);
`ifdef IMUL_DPI
@ -61,10 +62,12 @@ module VX_muldiv (
for (genvar i = 0; i < `NUM_THREADS; ++i) begin
wire [`XLEN-1:0] mul_resultl, mul_resulth;
wire [`XLEN-1:0] alu_in1_dpi = is_mulw ? (alu_in1[i] & 64'hFFFFFFFF) : alu_in1[i];
wire [`XLEN-1:0] alu_in2_dpi = is_mulw ? (alu_in2[i] & 64'hFFFFFFFF) : alu_in2[i];
always @(*) begin
dpi_imul (mul_fire_in, alu_in1[i], alu_in2[i], is_signed_mul_a, is_signed_mul_b, mul_resultl, mul_resulth);
dpi_imul (mul_fire_in, alu_in1_dpi, alu_in2_dpi, is_signed_mul_a, is_signed_mul_b, mul_resultl, mul_resulth);
end
assign mul_result_tmp[i] = is_mulh_in ? mul_resulth : mul_resultl;
assign mul_result_tmp[i] = is_mulh_in ? mul_resulth : (is_mulw ? `XLEN'($signed(mul_resultl[31:0])) : mul_resultl);
end
VX_shift_register #(
@ -82,7 +85,7 @@ module VX_muldiv (
`else
wire is_mulh_out;
//TODO handle mulw when not using DPI
for (genvar i = 0; i < `NUM_THREADS; ++i) begin
wire [`XLEN:0] mul_in1 = {is_signed_mul_a && alu_in1[i][`XLEN-1], alu_in1[i]};
wire [`XLEN:0] mul_in2 = {is_signed_mul_b && alu_in2[i][`XLEN-1], alu_in2[i]};
@ -132,24 +135,29 @@ module VX_muldiv (
wire div_wb_out;
wire is_rem_op_in = (alu_op == `INST_MUL_REM) || (alu_op == `INST_MUL_REMU);
wire is_signed_div = (alu_op == `INST_MUL_DIV) || (alu_op == `INST_MUL_REM);
wire is_signed_div = (alu_op == `INST_MUL_DIV) || (alu_op == `INST_MUL_REM) || (alu_op == `INST_MUL_DIVW);
wire div_valid_in = valid_in && is_div_op;
wire div_ready_out = ~stall_out && ~mul_valid_out; // arbitration prioritizes MUL
wire div_ready_in;
wire div_valid_out;
wire is_divw = (alu_op == `INST_MUL_DIVW);
wire is_divuw = (alu_op == `INST_MUL_DIVUW);
`ifdef IDIV_DPI
wire [`NUM_THREADS-1:0][`XLEN-1:0] div_result_tmp;
wire div_fire_in = div_valid_in && div_ready_in;
for (genvar i = 0; i < `NUM_THREADS; ++i) begin
wire [`XLEN-1:0] div_quotient, div_remainder;
wire [`XLEN-1:0] alu_in1_dpi = is_divuw ? (alu_in1[i] & 64'hFFFFFFFF) : (is_divw ? `XLEN'($signed(alu_in1[i][31:0])): alu_in1[i]);
wire [`XLEN-1:0] alu_in2_dpi = is_divuw ? (alu_in2[i] & 64'hFFFFFFFF) : (is_divw ? `XLEN'($signed(alu_in2[i][31:0])): alu_in2[i]);
always @(*) begin
dpi_idiv (div_fire_in, alu_in1[i], alu_in2[i], is_signed_div, div_quotient, div_remainder);
dpi_idiv (div_fire_in, alu_in1_dpi, alu_in2_dpi, is_signed_div, div_quotient, div_remainder);
end
assign div_result_tmp[i] = is_rem_op_in ? div_remainder : div_quotient;
wire [`XLEN-1:0] div_quotient_out = (is_divuw | is_divw) ? `XLEN'($signed(div_quotient[31:0])) : div_quotient;
assign div_result_tmp[i] = is_rem_op_in ? div_remainder : div_quotient_out;
end
VX_shift_register #(