diff --git a/src/fpu/divremsqrt/divremsqrtfdivsqrtcycles.sv b/src/fpu/divremsqrt/divremsqrtfdivsqrtcycles.sv new file mode 100644 index 000000000..9ca4ef503 --- /dev/null +++ b/src/fpu/divremsqrt/divremsqrtfdivsqrtcycles.sv @@ -0,0 +1,83 @@ +/////////////////////////////////////////// +// fdivsqrtcycles.sv +// +// Written: David_Harris@hmc.edu, me@KatherineParry.com, cturek@hmc.edu, amaiuolo@hmc.edu +// Modified: 18 April 2022 +// +// Purpose: Determine number of cycles for divsqrt +// +// Documentation: RISC-V System on Chip Design Chapter 13 +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// https://github.com/openhwgroup/cvw +// +// 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. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module divremsqrtfdivsqrtcycles import cvw::*; #(parameter cvw_t P) ( + input logic [P.FMTBITS-1:0] FmtE, + input logic SqrtE, + input logic IntDivE, + input logic [P.DIVBLEN-1:0] IntResultBitsE, + output logic [P.DURLEN:0] CyclesE +); + + logic [P.DIVBLEN-1:0] Nf, FPResultBitsE, ResultBitsE; // number of fractional (result) bits + + /* verilator lint_off WIDTH */ + if (P.FPSIZES == 1) + assign Nf = P.NF; + else if (P.FPSIZES == 2) + always_comb + case (FmtE) + 1'b0: Nf = P.NF1; + 1'b1: Nf = P.NF; + endcase + else if (P.FPSIZES == 3) + always_comb + case (FmtE) + P.FMT: Nf = P.NF; + P.FMT1: Nf = P.NF1; + P.FMT2: Nf = P.NF2; + default: Nf = 'x; // shouldn't happen + endcase + else if (P.FPSIZES == 4) + always_comb + case(FmtE) + P.S_FMT: Nf = P.S_NF; + P.D_FMT: Nf = P.D_NF; + P.H_FMT: Nf = P.H_NF; + P.Q_FMT: Nf = P.Q_NF; + endcase + + // Cycle logic + // P.DIVCOPIES = k. P.LOGR = log(R) = r. P.RK = rk. + // Integer division needs p fractional + r integer result bits + // FP Division needs at least Nf fractional bits + 2 guard/round bits and one integer digit (LOG R integer bits) = Nf + 2 + r bits + // FP Sqrt needs at least Nf fractional bits and 2 guard/round bits. The integer bit is always initialized to 1 and does not need a cycle. + // The datapath produces rk bits per cycle, so Cycles = ceil (ResultBitsE / rk) + + always_comb begin + FPResultBitsE = Nf + 2 + P.LOGR; // Nf + two fractional bits for round/guard; integer bit implicit because starting at n=1 + + if (P.IDIV_ON_FPU) ResultBitsE = IntDivE ? IntResultBitsE : FPResultBitsE; + else ResultBitsE = FPResultBitsE; + + CyclesE = (ResultBitsE-1)/(P.RK) + 1; // ceil (ResultBitsE/rk) + end + /* verilator lint_on WIDTH */ + +endmodule diff --git a/src/fpu/divremsqrt/divremsqrtfdivsqrtexpcalc.sv b/src/fpu/divremsqrt/divremsqrtfdivsqrtexpcalc.sv new file mode 100644 index 000000000..fe1207252 --- /dev/null +++ b/src/fpu/divremsqrt/divremsqrtfdivsqrtexpcalc.sv @@ -0,0 +1,79 @@ +/////////////////////////////////////////// +// fdivsqrtexpcalc.sv +// +// Written: David_Harris@hmc.edu, me@KatherineParry.com, cturek@hmc.edu +// Modified:13 January 2022 +// +// Purpose: Exponent caclulation for divide and square root +// +// Documentation: RISC-V System on Chip Design Chapter 13 +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// https://github.com/openhwgroup/cvw +// +// 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. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module divremsqrtfdivsqrtexpcalc import cvw::*; #(parameter cvw_t P) ( + input logic [P.FMTBITS-1:0] Fmt, + input logic [P.NE-1:0] Xe, Ye, // input exponents + input logic Sqrt, + input logic [P.DIVBLEN-1:0] ell, m, // number of leading 0s in Xe and Ye + output logic [P.NE+1:0] Ue // result exponent + ); + + logic [P.NE-2:0] Bias; + logic [P.NE+1:0] SXExp; + logic [P.NE+1:0] SExp; + logic [P.NE+1:0] DExp; + + // Determine exponent bias according to the format + + if (P.FPSIZES == 1) begin + assign Bias = (P.NE-1)'(P.BIAS); + + end else if (P.FPSIZES == 2) begin + assign Bias = Fmt ? (P.NE-1)'(P.BIAS) : (P.NE-1)'(P.BIAS1); + + end else if (P.FPSIZES == 3) begin + always_comb + case (Fmt) + P.FMT: Bias = (P.NE-1)'(P.BIAS); + P.FMT1: Bias = (P.NE-1)'(P.BIAS1); + P.FMT2: Bias = (P.NE-1)'(P.BIAS2); + default: Bias = 'x; + endcase + + end else if (P.FPSIZES == 4) begin + always_comb + case (Fmt) + 2'h3: Bias = (P.NE-1)'(P.Q_BIAS); + 2'h1: Bias = (P.NE-1)'(P.D_BIAS); + 2'h0: Bias = (P.NE-1)'(P.S_BIAS); + 2'h2: Bias = (P.NE-1)'(P.H_BIAS); + endcase + end + + // Square root exponent = (Xe - l - bias) / 2 + bias; l accounts for subnorms + assign SXExp = {2'b0, Xe} - {{(P.NE+1-P.DIVBLEN){1'b0}}, ell} - (P.NE+2)'(P.BIAS); + assign SExp = {SXExp[P.NE+1], SXExp[P.NE+1:1]} + {2'b0, Bias}; + + // division exponent = (Xe-l) - (Ye-m) + bias; l and m account for subnorms + assign DExp = ({2'b0, Xe} - {{(P.NE+1-P.DIVBLEN){1'b0}}, ell} - {2'b0, Ye} + {{(P.NE+1-P.DIVBLEN){1'b0}}, m} + {3'b0, Bias}); + + // Select square root or division exponent + assign Ue = Sqrt ? SExp : DExp; +endmodule diff --git a/src/fpu/divremsqrt/divremsqrtfdivsqrtpreproc.sv b/src/fpu/divremsqrt/divremsqrtfdivsqrtpreproc.sv index 61f9931ab..f39eb7ed5 100644 --- a/src/fpu/divremsqrt/divremsqrtfdivsqrtpreproc.sv +++ b/src/fpu/divremsqrt/divremsqrtfdivsqrtpreproc.sv @@ -217,11 +217,11 @@ module divremsqrtfdivsqrtpreproc import cvw::*; #(parameter cvw_t P) ( flopen #(P.DIVb+4) dreg(clk, IFDivStartE, {3'b000, Dnorm}, D); // Floating-point exponent - fdivsqrtexpcalc #(P) expcalc(.Fmt(FmtE), .Xe, .Ye, .Sqrt(SqrtE), .ell, .m(mE), .Ue(UeE)); + divremsqrtfdivsqrtexpcalc #(P) expcalc(.Fmt(FmtE), .Xe, .Ye, .Sqrt(SqrtE), .ell, .m(mE), .Ue(UeE)); flopen #(P.NE+2) expreg(clk, IFDivStartE, UeE, UeM); // Number of FSM cycles (to FSM) - fdivsqrtcycles #(P) cyclecalc(.FmtE, .SqrtE, .IntDivE, .IntResultBitsE, .CyclesE); + divremsqrtfdivsqrtcycles #(P) cyclecalc(.FmtE, .SqrtE, .IntDivE, .IntResultBitsE, .CyclesE); if (P.IDIV_ON_FPU) begin:intpipelineregs logic [P.DIVBLEN-1:0] IntDivNormShiftE, IntRemNormShiftE, IntNormShiftE; diff --git a/src/fpu/divremsqrt/divremsqrtintspecialcase.sv b/src/fpu/divremsqrt/divremsqrtintspecialcase.sv index f15f2d075..ff1519aad 100644 --- a/src/fpu/divremsqrt/divremsqrtintspecialcase.sv +++ b/src/fpu/divremsqrt/divremsqrtintspecialcase.sv @@ -12,4 +12,4 @@ always_comb if (RemOpM) IntDivResultM = AM; else IntDivResultM = 0; end else IntDivResultM = PreIntResultM[P.XLEN-1:0]; -endmodule \ No newline at end of file +endmodule diff --git a/src/fpu/divremsqrt/divremsqrtround.sv b/src/fpu/divremsqrt/divremsqrtround.sv index 7a7e46964..428288783 100644 --- a/src/fpu/divremsqrt/divremsqrtround.sv +++ b/src/fpu/divremsqrt/divremsqrtround.sv @@ -265,3 +265,4 @@ module divremsqrtround import cvw::*; #(parameter cvw_t P) ( endmodule + diff --git a/src/fpu/divremsqrt/divremsqrtroundsign.sv b/src/fpu/divremsqrt/divremsqrtroundsign.sv index b0dd4270b..0f808836a 100644 --- a/src/fpu/divremsqrt/divremsqrtroundsign.sv +++ b/src/fpu/divremsqrt/divremsqrtroundsign.sv @@ -42,4 +42,4 @@ module divremsqrtroundsign import cvw::*; #(parameter cvw_t P) ( // Select sign for rounding calulation assign Ms = (Qs&DivOp); -endmodule \ No newline at end of file +endmodule diff --git a/src/fpu/divremsqrt/divremsqrtshiftcorrection.sv b/src/fpu/divremsqrt/divremsqrtshiftcorrection.sv index 6b119ed6c..a82756e1e 100644 --- a/src/fpu/divremsqrt/divremsqrtshiftcorrection.sv +++ b/src/fpu/divremsqrt/divremsqrtshiftcorrection.sv @@ -91,4 +91,4 @@ module divremsqrtshiftcorrection import cvw::*; #(parameter cvw_t P) ( // if the quotent < 1 and not Subnormal then subtract 1 to account for the normalization shift assign Ue = (DivResSubnorm & DivSubnormShiftPos) ? '0 : DivUe - {(P.NE+1)'(0), ~LZAPlus1}; //assign Ue = (DivResSubnorm ) ? '0 : DivUe - {(P.NE+1)'(0), ~LZAPlus1}; -endmodule \ No newline at end of file +endmodule diff --git a/src/fpu/divremsqrt/divremsqrtspecialcase.sv b/src/fpu/divremsqrt/divremsqrtspecialcase.sv index d7f569add..975c6de3c 100644 --- a/src/fpu/divremsqrt/divremsqrtspecialcase.sv +++ b/src/fpu/divremsqrt/divremsqrtspecialcase.sv @@ -237,4 +237,4 @@ module divremsqrtspecialcase import cvw::*; #(parameter cvw_t P) ( else if(KillRes) PostProcRes = UfRes; else PostProcRes = NormRes; -endmodule \ No newline at end of file +endmodule