mirror of
https://github.com/vortexgpgpu/vortex.git
synced 2025-04-24 05:47:35 -04:00
Fix MULW DIVW DIVUW, update current_status.txt
This commit is contained in:
parent
49ff848f3d
commit
864349d812
6 changed files with 61 additions and 28 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 #(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue