diff --git a/src/fpu/divremsqrt/divremsqrt.sv b/src/fpu/divremsqrt/divremsqrt.sv index 3ca85cfb4..caaa45ab2 100644 --- a/src/fpu/divremsqrt/divremsqrt.sv +++ b/src/fpu/divremsqrt/divremsqrt.sv @@ -28,7 +28,7 @@ `include "wally-config.vh" -module fdivsqrt( +module divremsqrt( input logic clk, input logic reset, input logic [`FMTBITS-1:0] FmtE, diff --git a/src/fpu/divremsqrt/divremsqrtflags.sv b/src/fpu/divremsqrt/divremsqrtflags.sv index 7924e0624..c2f0f356c 100644 --- a/src/fpu/divremsqrt/divremsqrtflags.sv +++ b/src/fpu/divremsqrt/divremsqrtflags.sv @@ -28,13 +28,13 @@ //////////////////////////////////////////////////////////////////////////////////////////////// `include "wally-config.vh" -module flags( +module divremsqrtflags( input logic Xs, // X sign input logic [`FMTBITS-1:0] OutFmt, // output format input logic InfIn, // is a Inf input being used - input logic XInf, YInf, ZInf, // inputs are infinity + input logic XInf, YInf, // inputs are infinity input logic NaNIn, // is a NaN input being used - input logic XSNaN, YSNaN, ZSNaN, // inputs are signaling NaNs + input logic XSNaN, YSNaN, // inputs are signaling NaNs input logic XZero, YZero, // inputs are zero input logic [`NE+1:0] FullRe, // Re with bits to determine sign and overflow input logic [`NE+1:0] Me, // exponent of the normalized sum @@ -49,7 +49,6 @@ module flags( output logic DivByZero, // divide by zero flag output logic Overflow, // overflow flag to select result output logic Invalid, // invalid flag to select the result - output logic IntInvalid, // invalid integer result to select output logic [4:0] PostProcFlg // flags ); diff --git a/src/fpu/divremsqrt/divremsqrtpostprocess.sv b/src/fpu/divremsqrt/divremsqrtpostprocess.sv index d0e5a618b..c210a4817 100644 --- a/src/fpu/divremsqrt/divremsqrtpostprocess.sv +++ b/src/fpu/divremsqrt/divremsqrtpostprocess.sv @@ -31,39 +31,23 @@ module divremsqrtpostprocess ( // general signals input logic Xs, Ys, // input signs - input logic [`NF:0] Xm, Ym, Zm, // input mantissas + input logic [`NF:0] Xm, Ym, // input mantissas input logic [2:0] Frm, // rounding mode 000 = rount to nearest, ties to even 001 = round twords zero 010 = round down 011 = round up 100 = round to nearest, ties to max magnitude input logic [`FMTBITS-1:0] Fmt, // precision 1 = double 0 = single input logic [2:0] OpCtrl, // choose which opperation (look below for values) input logic XZero, YZero, // inputs are zero - input logic XInf, YInf, ZInf, // inputs are infinity - input logic XNaN, YNaN, ZNaN, // inputs are NaN - input logic XSNaN, YSNaN, ZSNaN, // inputs are signaling NaNs + input logic XInf, YInf, // inputs are infinity + input logic XNaN, YNaN, // inputs are NaN + input logic XSNaN, YSNaN, // inputs are signaling NaNs input logic [1:0] PostProcSel, // select result to be written to fp register //fma signals - input logic FmaAs, // the modified Z sign - depends on instruction - input logic FmaPs, // the product's sign - input logic FmaSs, // Sum sign - input logic [`NE+1:0] FmaSe, // the sum's exponent - input logic [3*`NF+3:0] FmaSm, // the positive sum - input logic FmaASticky, // sticky bit that is calculated during alignment - input logic [$clog2(3*`NF+5)-1:0] FmaSCnt, // the normalization shift count //divide signals input logic DivSticky, // divider sticky bit input logic [`NE+1:0] DivQe, // divsqrt exponent input logic [`DIVb:0] DivQm, // divsqrt significand - // conversion signals - input logic CvtCs, // the result's sign - input logic [`NE:0] CvtCe, // the calculated expoent - input logic CvtResSubnormUf, // the convert result is subnormal or underflows - input logic [`LOGCVTLEN-1:0] CvtShiftAmt,// how much to shift by - input logic ToInt, // is fp->int (since it's writting to the integer register) - input logic [`CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (without msb) - input logic IntZero, // is the integer input zero // final results output logic [`FLEN-1:0] PostProcRes,// postprocessor final result output logic [4:0] PostProcFlg,// postprocesser flags - output logic [`XLEN-1:0] FCvtIntRes // the integer conversion result ); // general signals @@ -83,12 +67,6 @@ module divremsqrtpostprocess ( logic Invalid; // invalid flag used to select results logic Guard, Round, Sticky; // bits needed to determine rounding logic [`FMTBITS-1:0] OutFmt; // output format - // fma signals - logic [`NE+1:0] FmaMe; // exponent of the normalized sum - logic FmaSZero; // is the sum zero - logic [3*`NF+5:0] FmaShiftIn; // fma shift input - logic FmaPreResultSubnorm; // is the result subnormal - calculated before LZA corection - logic [$clog2(3*`NF+5)-1:0] FmaShiftAmt;// normalization shift amount for fma // division singals logic [`LOGNORMSHIFTSZ-1:0] DivShiftAmt; // divsqrt shif amount logic [`NORMSHIFTSZ-1:0] DivShiftIn; // divsqrt shift input @@ -109,7 +87,6 @@ module divremsqrtpostprocess ( logic Signed; // is the opperation with a signed integer? logic IntToFp; // is the opperation an int->fp conversion? logic CvtOp; // convertion opperation - logic FmaOp; // fma opperation logic DivOp; // divider opperation logic InfIn; // are any of the inputs infinity logic NaNIn; // are any of the inputs NaN @@ -125,8 +102,8 @@ module divremsqrtpostprocess ( assign Sqrt = OpCtrl[0]; // is there an input of infinity or NaN being used - assign InfIn = XInf|YInf|ZInf; - assign NaNIn = XNaN|YNaN|ZNaN; + assign InfIn = XInf|YInf; + assign NaNIn = XNaN|YNaN; // choose the ouptut format depending on the opperation // - fp -> fp: OpCtrl contains the percision of the output @@ -168,11 +145,10 @@ module divremsqrtpostprocess ( // round to nearest max magnitude // calulate result sign used in rounding unit - divremsqrtroundsign roundsign(.FmaOp, .DivOp, .CvtOp, .Sqrt, .FmaSs, .Xs, .Ys, .CvtCs, .Ms); + divremsqrtroundsign roundsign( .DivOp, .Sqrt, .Xs, .Ys, , .Ms); - divremsqrtround round(.OutFmt, .Frm, .FmaASticky, .Plus1, .PostProcSel, .CvtCe, .Qe, - .Ms, .FmaMe, .FmaOp, .CvtOp, .CvtResSubnormUf, .Mf, .ToInt, .CvtResUf, - .DivSticky, .DivOp, .UfPlus1, .FullRe, .Rf, .Re, .Sticky, .Round, .Guard, .Me); + divremsqrtround round(.OutFmt, .Frm, .Plus1, .Qe, + .Ms, .Mf, .DivSticky, .DivOp, .UfPlus1, .FullRe, .Rf, .Re, .Sticky, .Round, .Guard, .Me); /////////////////////////////////////////////////////////////////////////////// // Sign calculation @@ -186,11 +162,11 @@ module divremsqrtpostprocess ( // Flags /////////////////////////////////////////////////////////////////////////////// - divremsqrtflags flags(.XSNaN, .YSNaN, .ZSNaN, .XInf, .YInf, .ZInf, .InfIn, .XZero, .YZero, - .Xs, .Sqrt, .ToInt, .IntToFp, .Int64, .Signed, .OutFmt, .CvtCe, - .NaNIn, .FmaAs, .FmaPs, .Round, .IntInvalid, .DivByZero, - .Guard, .Sticky, .UfPlus1, .CvtOp, .DivOp, .FmaOp, .FullRe, .Plus1, - .Me, .CvtNegResMsbs, .Invalid, .Overflow, .PostProcFlg); + divremsqrtflags flags(.XSNaN, .YSNaN, .XInf, .YInf, .InfIn, .XZero, .YZero, + .Xs, .Sqrt, + .NaNIn, .Round, .DivByZero, + .Guard, .Sticky, .UfPlus1,.DivOp, .FullRe, .Plus1, + .Me, .Invalid, .Overflow, .PostProcFlg); /////////////////////////////////////////////////////////////////////////////// // Select the result @@ -198,9 +174,9 @@ module divremsqrtpostprocess ( //negateintres negateintres(.Xs, .Shifted, .Signed, .Int64, .Plus1, .CvtNegResMsbs, .CvtNegRes); - specialcase specialcase(.Xs, .Xm, .Ym, .Zm, .XZero, .IntInvalid, - .IntZero, .Frm, .OutFmt, .XNaN, .YNaN, .ZNaN, .CvtResUf, - .NaNIn, .IntToFp, .Int64, .Signed, .CvtOp, .FmaOp, .Plus1, .Invalid, .Overflow, .InfIn, .CvtNegRes, - .XInf, .YInf, .DivOp, .DivByZero, .FullRe, .CvtCe, .Rs, .Re, .Rf, .PostProcRes, .FCvtIntRes); + divremsqrtspecialcase specialcase(.Xs, .Xm, .Ym, .XZero, + .Frm, .OutFmt, .XNaN, .YNaN, + .NaNIn, .Plus1, .Invalid, .Overflow, .InfIn, + .XInf, .YInf, .DivOp, .DivByZero, .FullRe, .Rs, .Re, .Rf, .PostProcRes ); endmodule diff --git a/src/fpu/divremsqrt/divremsqrtspecialcase.sv b/src/fpu/divremsqrt/divremsqrtspecialcase.sv index ade2ccf3e..1172705f0 100644 --- a/src/fpu/divremsqrt/divremsqrtspecialcase.sv +++ b/src/fpu/divremsqrt/divremsqrtspecialcase.sv @@ -30,8 +30,8 @@ module specialcase( input logic Xs, // X sign - input logic [`NF:0] Xm, Ym, Zm, // input significand's - input logic XNaN, YNaN, ZNaN, // are the inputs NaN + input logic [`NF:0] Xm, Ym, // input significand's + input logic XNaN, YNaN, // are the inputs NaN input logic [2:0] Frm, // rounding mode input logic [`FMTBITS-1:0] OutFmt, // output format input logic InfIn, // are any inputs infinity @@ -53,7 +53,6 @@ module specialcase( logic [`FLEN-1:0] XNaNRes; // X is NaN result logic [`FLEN-1:0] YNaNRes; // Y is NaN result - logic [`FLEN-1:0] ZNaNRes; // Z is NaN result logic [`FLEN-1:0] InvalidRes; // Invalid result result logic [`FLEN-1:0] UfRes; // underflowed result result logic [`FLEN-1:0] OfRes; // overflowed result result @@ -73,7 +72,6 @@ module specialcase( if(`IEEE754) begin assign XNaNRes = {1'b0, {`NE{1'b1}}, 1'b1, Xm[`NF-2:0]}; assign YNaNRes = {1'b0, {`NE{1'b1}}, 1'b1, Ym[`NF-2:0]}; - assign ZNaNRes = {1'b0, {`NE{1'b1}}, 1'b1, Zm[`NF-2:0]}; assign InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; end else begin assign InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; @@ -87,7 +85,6 @@ module specialcase( if(`IEEE754) begin assign XNaNRes = OutFmt ? {1'b0, {`NE{1'b1}}, 1'b1, Xm[`NF-2:0]} : {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, Xm[`NF-2:`NF-`NF1]}; assign YNaNRes = OutFmt ? {1'b0, {`NE{1'b1}}, 1'b1, Ym[`NF-2:0]} : {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, Ym[`NF-2:`NF-`NF1]}; - assign ZNaNRes = OutFmt ? {1'b0, {`NE{1'b1}}, 1'b1, Zm[`NF-2:0]} : {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, Zm[`NF-2:`NF-`NF1]}; assign InvalidRes = OutFmt ? {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}} : {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)}; end else begin assign InvalidRes = OutFmt ? {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}} : {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)}; @@ -110,7 +107,6 @@ module specialcase( if(`IEEE754) begin XNaNRes = {1'b0, {`NE{1'b1}}, 1'b1, Xm[`NF-2:0]}; YNaNRes = {1'b0, {`NE{1'b1}}, 1'b1, Ym[`NF-2:0]}; - ZNaNRes = {1'b0, {`NE{1'b1}}, 1'b1, Zm[`NF-2:0]}; InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; end else begin InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; @@ -124,7 +120,6 @@ module specialcase( if(`IEEE754) begin XNaNRes = {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, Xm[`NF-2:`NF-`NF1]}; YNaNRes = {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, Ym[`NF-2:`NF-`NF1]}; - ZNaNRes = {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, Zm[`NF-2:`NF-`NF1]}; InvalidRes = {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)}; end else begin InvalidRes = {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)}; @@ -137,7 +132,6 @@ module specialcase( if(`IEEE754) begin XNaNRes = {{`FLEN-`LEN2{1'b1}}, 1'b0, {`NE2{1'b1}}, 1'b1, Xm[`NF-2:`NF-`NF2]}; YNaNRes = {{`FLEN-`LEN2{1'b1}}, 1'b0, {`NE2{1'b1}}, 1'b1, Ym[`NF-2:`NF-`NF2]}; - ZNaNRes = {{`FLEN-`LEN2{1'b1}}, 1'b0, {`NE2{1'b1}}, 1'b1, Zm[`NF-2:`NF-`NF2]}; InvalidRes = {{`FLEN-`LEN2{1'b1}}, 1'b0, {`NE2{1'b1}}, 1'b1, (`NF2-1)'(0)}; end else begin InvalidRes = {{`FLEN-`LEN2{1'b1}}, 1'b0, {`NE2{1'b1}}, 1'b1, (`NF2-1)'(0)}; @@ -151,7 +145,6 @@ module specialcase( if(`IEEE754) begin XNaNRes = (`FLEN)'(0); YNaNRes = (`FLEN)'(0); - ZNaNRes = (`FLEN)'(0); InvalidRes = (`FLEN)'(0); end else begin InvalidRes = (`FLEN)'(0); @@ -169,7 +162,6 @@ module specialcase( if(`IEEE754) begin XNaNRes = {1'b0, {`NE{1'b1}}, 1'b1, Xm[`NF-2:0]}; YNaNRes = {1'b0, {`NE{1'b1}}, 1'b1, Ym[`NF-2:0]}; - ZNaNRes = {1'b0, {`NE{1'b1}}, 1'b1, Zm[`NF-2:0]}; InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; end else begin InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; @@ -183,7 +175,6 @@ module specialcase( if(`IEEE754) begin XNaNRes = {{`FLEN-`D_LEN{1'b1}}, 1'b0, {`D_NE{1'b1}}, 1'b1, Xm[`NF-2:`NF-`D_NF]}; YNaNRes = {{`FLEN-`D_LEN{1'b1}}, 1'b0, {`D_NE{1'b1}}, 1'b1, Ym[`NF-2:`NF-`D_NF]}; - ZNaNRes = {{`FLEN-`D_LEN{1'b1}}, 1'b0, {`D_NE{1'b1}}, 1'b1, Zm[`NF-2:`NF-`D_NF]}; InvalidRes = {{`FLEN-`D_LEN{1'b1}}, 1'b0, {`D_NE{1'b1}}, 1'b1, (`D_NF-1)'(0)}; end else begin InvalidRes = {{`FLEN-`D_LEN{1'b1}}, 1'b0, {`D_NE{1'b1}}, 1'b1, (`D_NF-1)'(0)}; @@ -196,7 +187,6 @@ module specialcase( if(`IEEE754) begin XNaNRes = {{`FLEN-`S_LEN{1'b1}}, 1'b0, {`S_NE{1'b1}}, 1'b1, Xm[`NF-2:`NF-`S_NF]}; YNaNRes = {{`FLEN-`S_LEN{1'b1}}, 1'b0, {`S_NE{1'b1}}, 1'b1, Ym[`NF-2:`NF-`S_NF]}; - ZNaNRes = {{`FLEN-`S_LEN{1'b1}}, 1'b0, {`S_NE{1'b1}}, 1'b1, Zm[`NF-2:`NF-`S_NF]}; InvalidRes = {{`FLEN-`S_LEN{1'b1}}, 1'b0, {`S_NE{1'b1}}, 1'b1, (`S_NF-1)'(0)}; end else begin InvalidRes = {{`FLEN-`S_LEN{1'b1}}, 1'b0, {`S_NE{1'b1}}, 1'b1, (`S_NF-1)'(0)}; @@ -210,7 +200,6 @@ module specialcase( if(`IEEE754) begin XNaNRes = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, Xm[`NF-2:`NF-`H_NF]}; YNaNRes = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, Ym[`NF-2:`NF-`H_NF]}; - ZNaNRes = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, Zm[`NF-2:`NF-`H_NF]}; InvalidRes = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, (`H_NF-1)'(0)}; end else begin InvalidRes = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, (`H_NF-1)'(0)}; diff --git a/src/fpu/divremsqrt/drsu.sv b/src/fpu/divremsqrt/drsu.sv new file mode 100644 index 000000000..14445441d --- /dev/null +++ b/src/fpu/divremsqrt/drsu.sv @@ -0,0 +1,95 @@ +/////////////////////////////////////////// +// drsu.sv +// +// Written: kekim@hmc.edu +// Modified:19 May 2023 +// +// Purpose: Combined Divide and Square Root Floating Point and Integer Unit with postprocessing +// +// Documentation: RISC-V System on Chip Design Chapter 13 +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// +// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +`include "wally-config.vh" + +module drsu( + input logic clk, + input logic reset, + input logic [`FMTBITS-1:0] FmtE, + input logic XsE, YsE, + input logic [`NF:0] XmE, YmE, + input logic [`NE-1:0] XeE, YeE, + input logic XInfE, YInfE, + input logic XZeroE, YZeroE, + input logic XNaNE, YNaNE, + input logic XSNaNE, YSNaNE, + input logic FDivStartE, IDivStartE, + input logic StallM, + input logic FlushE, + input logic SqrtE, SqrtM, + input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // these are the src outputs before the mux choosing between them and PCE to put in srcA/B + input logic [2:0] Funct3E, Funct3M, + input logic IntDivE, W64E, + input logic [2:0] Frm, + input logic [2:0] OpCtrl, + input logic [`FMTBits:0] Fmt, + input logic [1:0] PostProcSel, + output logic FDivBusyE, IFDivStartE, FDivDoneE, + output logic [`FLEN-1:0] FResM, + output logic [`XLEN-1:0] FIntDivResultM, + output logic [4:0] FlgM +); + + // Floating-point division and square root module, with optional integer division and remainder + // Computes X/Y, sqrt(X), A/B, or A%B + + logic [`DIVb+3:0] WS, WC; // Partial remainder components + logic [`DIVb+3:0] X; // Iterator Initial Value (from dividend) + logic [`DIVb+3:0] D; // Iterator Divisor + logic [`DIVb:0] FirstU, FirstUM; // Intermediate result values + logic [`DIVb+1:0] FirstC; // Step tracker + logic Firstun; // Quotient selection + logic WZeroE; // Early termination flag + logic [`DURLEN-1:0] CyclesE; // FSM cycles + logic SpecialCaseM; // Divide by zero, square root of negative, etc. + logic DivStartE; // Enable signal for flops during stall + + // Integer div/rem signals + logic BZeroM; // Denominator is zero + logic IntDivM; // Integer operation + logic [`DIVBLEN:0] nM, mM; // Shift amounts + logic NegQuotM, ALTBM, AsM, W64M; // Special handling for postprocessor + logic [`XLEN-1:0] AM; // Original Numerator for postprocessor + logic ISpecialCaseE; // Integer div/remainder special cases + + divremsqrt divremsqrt(.clk, .reset, .XsE, .FmtE, .XmE, .YmE, + .XeE, .YeE, .SqrtE, .SqrtM, + .XInfE, .YInfE, .XZeroE, .YZeroE, + .XNaNE, .YNaNE, + .FDivStartE, .IDivStartE, .W64E, + .StallM, .DivStickyM, .FDivBusyE, .QeM, + .QmM, + .FlushE, .ForwardedSrcAE, .ForwardedSrcBE, .Funct3M, + .Funct3E, .IntDivE, .FIntDivResultM, + .FDivDoneE, .IFDivStartE); + divremsqrtpostprocess divremsqrtpostprocess(.Xs(XsE), .Ys(YsE), .Frm(Frm), .Fmt(Fmt), .OpCtrl, + .XZero(XZeroE), .YZero(YZeroE), .XInf(XInfE), .YInf(YInfE), .XNaN(XNaNE), .YNaN(YNaNE), .XSNaN(XSNaNE), + .YSNaN(YSNaNE), .PostProcSel,.DivSticky(DivStickyM), .DivQe(QeM), .DivQm(QmM), .PostProcRes(FResM), .PostProcFlg(FlgM)); +endmodule +