diff --git a/pipelined/src/fpu/fdivsqrt.sv b/pipelined/src/fpu/fdivsqrt.sv index 7548337fa..abf20befa 100644 --- a/pipelined/src/fpu/fdivsqrt.sv +++ b/pipelined/src/fpu/fdivsqrt.sv @@ -62,7 +62,7 @@ module fdivsqrt( logic [`DIVb:0] FirstS, FirstSM, FirstQ, FirstQM; logic [`DIVb-1:0] FirstC; logic NegSticky; - logic [`DIVCOPIES-1:0] qn; + logic Firstqn; logic WZero; fdivsqrtpreproc fdivsqrtpreproc( @@ -74,9 +74,9 @@ module fdivsqrt( .XNaNE, .YNaNE, .XInfE, .YInfE, .EarlyTermShiftE(EarlyTermShiftM), .WZero); fdivsqrtiter fdivsqrtiter( - .clk, .qn, .D, .FirstS, .FirstSM, .FirstQ, .FirstQM, .FirstC, .SqrtE, .SqrtM, + .clk, .Firstqn, .D, .FirstS, .FirstSM, .FirstQ, .FirstQM, .FirstC, .SqrtE, .SqrtM, .X,.Dpreproc, .FirstWS(WS), .FirstWC(WC), .NextWSN, .NextWCN, .DivStart(DivStartE), .Xe(XeE), .Ye(YeE), .XZeroE, .YZeroE, .DivBusy); - fdivsqrtpostproc fdivsqrtpostproc(.WS, .WC, .D, .FirstS, .FirstSM, .FirstQ, .FirstQM, .FirstC, .qn, .SqrtM, .QmM, .WZero, .DivSM); + fdivsqrtpostproc fdivsqrtpostproc(.WS, .WC, .D, .FirstS, .FirstSM, .FirstQ, .FirstQM, .FirstC, .Firstqn, .SqrtM, .QmM, .WZero, .DivSM); endmodule \ No newline at end of file diff --git a/pipelined/src/fpu/fdivsqrtiter.sv b/pipelined/src/fpu/fdivsqrtiter.sv index aad7d4e78..ad73cb957 100644 --- a/pipelined/src/fpu/fdivsqrtiter.sv +++ b/pipelined/src/fpu/fdivsqrtiter.sv @@ -45,7 +45,7 @@ module fdivsqrtiter( output logic [`DIVb:0] FirstS, FirstSM, output logic [`DIVb:0] FirstQ, FirstQM, output logic [`DIVb-1:0] FirstC, - output logic [`DIVCOPIES-1:0] qn, + output logic Firstqn, output logic [`DIVb+3:0] FirstWS, FirstWC ); @@ -71,6 +71,8 @@ module fdivsqrtiter( logic [`DIVb:0] SMNext[`DIVCOPIES-1:0];// U1.b logic [`DIVb-1:0] C[`DIVCOPIES-1:0]; // 0.b logic [`DIVb-1:0] initC; // 0.b + logic [`DIVCOPIES-1:0] qn; + /* verilator lint_on UNOPTFLAT */ logic [`DIVb+3:0] WSN, WCN; // Q4.N-1 @@ -169,5 +171,6 @@ module fdivsqrtiter( assign FirstQ = Q[0]; assign FirstQM = QM[0]; assign FirstC = C[0]; + assign Firstqn = qn[0]; endmodule diff --git a/pipelined/src/fpu/fdivsqrtpostproc.sv b/pipelined/src/fpu/fdivsqrtpostproc.sv index d5152f79f..157955b64 100644 --- a/pipelined/src/fpu/fdivsqrtpostproc.sv +++ b/pipelined/src/fpu/fdivsqrtpostproc.sv @@ -35,7 +35,7 @@ module fdivsqrtpostproc( input logic [`DIVN-2:0] D, // U0.N-1 input logic [`DIVb:0] FirstS, FirstSM, FirstQ, FirstQM, input logic [`DIVb-1:0] FirstC, - input logic [`DIVCOPIES-1:0] qn, + input logic Firstqn, input logic SqrtM, output logic [`DIVb-(`RADIX/4):0] QmM, output logic WZero, @@ -46,14 +46,23 @@ module fdivsqrtpostproc( logic NegSticky; // check for early termination on an exact result. If the result is not exact, the sticky should be set + logic weq0; + aplusbeq0 #(`DIVb+4) wspluswceq0(WS, WC, weq0); + if (`RADIX == 2) begin logic [`DIVb+3:0] FZero; logic [`DIVb+2:0] FirstK; + logic wfeq0; + logic [`DIVb+3:0] WCF, WSF; + assign FirstK = ({3'b111, FirstC<<1} & ~({3'b111, FirstC<<1} << 1)); assign FZero = SqrtM ? {FirstSM[`DIVb], FirstSM, 2'b0} | {FirstK,1'b0} : {3'b1,D,{`DIVb-`DIVN+2{1'b0}}}; - assign WZero = ((WS^WC)=={WS[`DIVb+2:0]|WC[`DIVb+2:0], 1'b0})|(((WS+WC+FZero)==0)&qn[`DIVCOPIES-1]); + csa #(`DIVb+4) fadd(WS, WC, FZero, 1'b0, WSF, WCF); // compute {WCF, WSF} = {WS + WC + FZero}; + aplusbeq0 #(`DIVb+4) wcfpluswsfeq0(WCF, WSF, wfeq0); +// assign WZero = weq0|(wfeq0&qn[`DIVCOPIES-1]); + assign WZero = weq0|(wfeq0 & Firstqn); end else begin - assign WZero = ((WS^WC)=={WS[`DIVb+2:0]|WC[`DIVb+2:0], 1'b0}); + assign WZero = weq0; end assign DivSM = ~WZero; diff --git a/pipelined/src/generic/aplusbeq0.sv b/pipelined/src/generic/aplusbeq0.sv new file mode 100644 index 000000000..7f33fc0ab --- /dev/null +++ b/pipelined/src/generic/aplusbeq0.sv @@ -0,0 +1,46 @@ +/////////////////////////////////////////// +// aplusbeq0.sv +// +// Written: David_Harris@hmc.edu 9/7/2022 +// Modified: +// +// Purpose: Determine if A+B = 0. Used in FP divider. +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// MIT LICENSE +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. +//////////////////////////////////////////////////////////////////////////////////////////////// + +`include "wally-config.vh" + +module aplusbeq0 #(parameter WIDTH = 8) ( + input logic [WIDTH-1:0] a, b, + output logic zero); + + logic [WIDTH-1:0] x; + logic [WIDTH-1:0] orshift; + + // The sum is zero if the bitwise XOR is equal to the bitwise OR shifted left by 1, for all columns + // *** explain, cite book + + assign x = a ^ b; + assign orshift = {a[WIDTH-2:0] | b[WIDTH-2:0], 1'b0}; + assign zero = (x == orshift); +endmodule \ No newline at end of file