From 99fd79c20b8b5cc514f25e68520f7a9dfe586095 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sun, 10 Oct 2021 08:35:26 -0700 Subject: [PATCH] Simplified divider sign handling --- wally-pipelined/src/muldiv/intdivrestoring.sv | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/wally-pipelined/src/muldiv/intdivrestoring.sv b/wally-pipelined/src/muldiv/intdivrestoring.sv index 9dd60f8d1..64a65b0ae 100644 --- a/wally-pipelined/src/muldiv/intdivrestoring.sv +++ b/wally-pipelined/src/muldiv/intdivrestoring.sv @@ -45,7 +45,6 @@ module intdivrestoring ( logic [STEPBITS:0] step; logic Div0E, Div0M; logic DivInitE, SignXE, SignXM, SignDE, SignDM, NegWM, NegQM; - logic DivSignedM; // save inputs on the negative edge of the execute clock. // This is unusual practice, but the inputs are not guaranteed to be stable due to some hazard and forwarding logic. @@ -65,12 +64,11 @@ module intdivrestoring ( endgenerate // Extract sign bits and check fo division by zero - assign SignDE = DinE[`XLEN-1]; - assign SignXE = XinE[`XLEN-1]; + assign SignDE = DivSignedE & DinE[`XLEN-1]; + assign SignXE = DivSignedE & XinE[`XLEN-1]; assign Div0E = (DinE == 0); // pipeline registers - flopenrc #(1) DivSignedMReg(clk, reset, FlushM, ~StallM, DivSignedE, DivSignedM); flopenrc #(1) Div0eMReg(clk, reset, FlushM, ~StallM, Div0E, Div0M); flopenrc #(1) SignDMReg(clk, reset, FlushM, ~StallM, SignDE, SignDM); flopenrc #(1) SignXMReg(clk, reset, FlushM, ~StallM, SignXE, SignXM); @@ -78,9 +76,9 @@ module intdivrestoring ( // Take absolute value for signed operations, and negate D to handle subtraction in divider stages neg #(`XLEN) negd(DinE, DnE); - mux2 #(`XLEN) dabsmux(DnE, DinE, DivSignedE & SignDE, DAbsBE); // take absolute value for signed operations, and negate for subtraction setp + mux2 #(`XLEN) dabsmux(DnE, DinE, SignDE, DAbsBE); // take absolute value for signed operations, and negate for subtraction setp neg #(`XLEN) negx(XinE, XnE); - mux2 #(`XLEN) xabsmux(XinE, XnE, DivSignedE & SignXE, XInitE); // need original X as remainder if doing divide by 0 + mux2 #(`XLEN) xabsmux(XinE, XnE, SignXE, XInitE); // need original X as remainder if doing divide by 0 // initialization multiplexers on first cycle of operation (one cycle after start is asserted) mux2 #(`XLEN) wmux(WM, {`XLEN{1'b0}}, DivInitE, WE[0]); @@ -99,8 +97,8 @@ module intdivrestoring ( // Output selection logic in Memory Stage // On final setp of signed operations, negate outputs as needed - assign NegWM = DivSignedM & SignXM; // Remainder should have same sign as X - assign NegQM = DivSignedM & (SignXM ^ SignDM); // Quotient should be negative if one operand is positive and the other is negative + assign NegWM = SignXM; // Remainder should have same sign as X + assign NegQM = SignXM ^ SignDM; // Quotient should be negative if one operand is positive and the other is negative neg #(`XLEN) wneg(WM, WnM); neg #(`XLEN) qneg(XQM, XQnM); // Select appropriate output: normal, negated, or for divide by zero