forked from Github_Repos/cvw
created fdivsqrtcycles, moved cycles calculation from FSM to preproc
This commit is contained in:
parent
871d495ca1
commit
30bd1e2a33
@ -57,42 +57,43 @@ module fdivsqrt(
|
|||||||
|
|
||||||
logic [`DIVb+3:0] WS, WC; // Partial remainder components
|
logic [`DIVb+3:0] WS, WC; // Partial remainder components
|
||||||
logic [`DIVb+3:0] X; // Iterator Initial Value (from dividend)
|
logic [`DIVb+3:0] X; // Iterator Initial Value (from dividend)
|
||||||
logic [`DIVb+3:0] D; // Iterator Divisor
|
logic [`DIVb+3:0] D; // Iterator Divisor
|
||||||
logic [`DIVb:0] FirstU, FirstUM; // Intermediate result values
|
logic [`DIVb:0] FirstU, FirstUM; // Intermediate result values
|
||||||
logic [`DIVb+1:0] FirstC; // Step tracker
|
logic [`DIVb+1:0] FirstC; // Step tracker
|
||||||
logic Firstun; // Quotient selection
|
logic Firstun; // Quotient selection
|
||||||
logic WZeroE; // Early termination flag
|
logic WZeroE; // Early termination flag
|
||||||
|
logic [`DURLEN-1:0] cycles; // FSM cycles
|
||||||
logic SpecialCaseM; // Divide by zero, square root of negative, etc.
|
logic SpecialCaseM; // Divide by zero, square root of negative, etc.
|
||||||
logic DivStartE; // Enable signal for flops during stall
|
logic DivStartE; // Enable signal for flops during stall
|
||||||
|
|
||||||
// Integer div/rem signals
|
// Integer div/rem signals
|
||||||
logic BZeroM; // Denominator is zero
|
logic BZeroM; // Denominator is zero
|
||||||
logic IntDivM; // Integer operation
|
logic IntDivM; // Integer operation
|
||||||
logic [`DIVBLEN:0] nE, nM, mM; // Shift amounts
|
logic [`DIVBLEN:0] nM, mM; // Shift amounts
|
||||||
logic NegQuotM, ALTBM, AsM, W64M; // Special handling for postprocessor
|
logic NegQuotM, ALTBM, AsM, W64M; // Special handling for postprocessor
|
||||||
logic [`XLEN-1:0] AM; // Original Numerator for postprocessor
|
logic [`XLEN-1:0] AM; // Original Numerator for postprocessor
|
||||||
logic ISpecialCaseE; // Integer div/remainder special cases
|
logic ISpecialCaseE; // Integer div/remainder special cases
|
||||||
|
|
||||||
fdivsqrtpreproc fdivsqrtpreproc( // Preprocessor
|
fdivsqrtpreproc fdivsqrtpreproc( // Preprocessor
|
||||||
.clk, .IFDivStartE, .Xm(XmE), .Ym(YmE), .Xe(XeE), .Ye(YeE),
|
.clk, .IFDivStartE, .Xm(XmE), .Ym(YmE), .Xe(XeE), .Ye(YeE),
|
||||||
.Fmt(FmtE), .Sqrt(SqrtE), .XZeroE, .Funct3E, .QeM, .X, .D,
|
.FmtE, .SqrtE, .XZeroE, .Funct3E, .QeM, .X, .D, .cycles,
|
||||||
// Int-specific
|
// Int-specific
|
||||||
.ForwardedSrcAE, .ForwardedSrcBE, .IntDivE, .W64E, .ISpecialCaseE,
|
.ForwardedSrcAE, .ForwardedSrcBE, .IntDivE, .W64E, .ISpecialCaseE,
|
||||||
.nE, .BZeroM, .nM, .mM, .AM,
|
.BZeroM, .nM, .mM, .AM,
|
||||||
.IntDivM, .W64M, .NegQuotM, .ALTBM, .AsM);
|
.IntDivM, .W64M, .NegQuotM, .ALTBM, .AsM);
|
||||||
|
|
||||||
fdivsqrtfsm fdivsqrtfsm( // FSM
|
fdivsqrtfsm fdivsqrtfsm( // FSM
|
||||||
.clk, .reset, .FmtE, .XInfE, .YInfE, .XZeroE, .YZeroE, .XNaNE, .YNaNE,
|
.clk, .reset, .XInfE, .YInfE, .XZeroE, .YZeroE, .XNaNE, .YNaNE,
|
||||||
.FDivStartE, .XsE, .SqrtE, .WZeroE, .FlushE, .StallM,
|
.FDivStartE, .XsE, .SqrtE, .WZeroE, .FlushE, .StallM,
|
||||||
.FDivBusyE, .IFDivStartE, .FDivDoneE, .SpecialCaseM,
|
.FDivBusyE, .IFDivStartE, .FDivDoneE, .SpecialCaseM, .cycles,
|
||||||
// Int-specific
|
// Int-specific
|
||||||
.IDivStartE, .ISpecialCaseE, .nE, .IntDivE);
|
.IDivStartE, .ISpecialCaseE, .IntDivE);
|
||||||
|
|
||||||
fdivsqrtiter fdivsqrtiter( // CSA Iterator
|
fdivsqrtiter fdivsqrtiter( // CSA Iterator
|
||||||
.clk, .IFDivStartE, .FDivBusyE, .SqrtE, .X, .D,
|
.clk, .IFDivStartE, .FDivBusyE, .SqrtE, .X, .D,
|
||||||
.FirstU, .FirstUM, .FirstC, .Firstun, .FirstWS(WS), .FirstWC(WC));
|
.FirstU, .FirstUM, .FirstC, .Firstun, .FirstWS(WS), .FirstWC(WC));
|
||||||
|
|
||||||
fdivsqrtpostproc fdivsqrtpostproc( // Postprocessor
|
fdivsqrtpostproc fdivsqrtpostproc( // Postprocessor
|
||||||
.clk, .reset, .StallM, .WS, .WC, .D, .FirstU, .FirstUM, .FirstC,
|
.clk, .reset, .StallM, .WS, .WC, .D, .FirstU, .FirstUM, .FirstC,
|
||||||
.SqrtE, .Firstun, .SqrtM, .SpecialCaseM,
|
.SqrtE, .Firstun, .SqrtM, .SpecialCaseM,
|
||||||
.QmM, .WZeroE, .DivStickyM,
|
.QmM, .WZeroE, .DivStickyM,
|
||||||
|
76
src/fpu/fdivsqrt/fdivsqrtcycles.sv
Normal file
76
src/fpu/fdivsqrt/fdivsqrtcycles.sv
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
///////////////////////////////////////////
|
||||||
|
// fdivsqrt.sv
|
||||||
|
//
|
||||||
|
// Written: David_Harris@hmc.edu, me@KatherineParry.com, cturek@hmc.edu, amaiuolo@hmc.edu
|
||||||
|
// Modified: 18 April 2022
|
||||||
|
//
|
||||||
|
// Purpose: Combined Divide and Square Root Floating Point and Integer Unit
|
||||||
|
//
|
||||||
|
// 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 fdivsqrtcycles(
|
||||||
|
input logic [`FMTBITS-1:0] FmtE,
|
||||||
|
input logic SqrtE,
|
||||||
|
input logic IntDivE,
|
||||||
|
input logic [`DIVBLEN:0] nE,
|
||||||
|
output logic [`DURLEN-1:0] cycles
|
||||||
|
);
|
||||||
|
logic [`DURLEN+1:0] Nf, fbits; // number of fractional bits
|
||||||
|
// DIVN = `NF+3
|
||||||
|
// NS = NF + 1
|
||||||
|
// N = NS or NS+2 for div/sqrt.
|
||||||
|
|
||||||
|
/* verilator lint_off WIDTH */
|
||||||
|
if (`FPSIZES == 1)
|
||||||
|
assign Nf = `NF;
|
||||||
|
else if (`FPSIZES == 2)
|
||||||
|
always_comb
|
||||||
|
case (FmtE)
|
||||||
|
1'b0: Nf = `NF1;
|
||||||
|
1'b1: Nf = `NF;
|
||||||
|
endcase
|
||||||
|
else if (`FPSIZES == 3)
|
||||||
|
always_comb
|
||||||
|
case (FmtE)
|
||||||
|
`FMT: Nf = `NF;
|
||||||
|
`FMT1: Nf = `NF1;
|
||||||
|
`FMT2: Nf = `NF2;
|
||||||
|
endcase
|
||||||
|
else if (`FPSIZES == 4)
|
||||||
|
always_comb
|
||||||
|
case(FmtE)
|
||||||
|
`S_FMT: Nf = `S_NF;
|
||||||
|
`D_FMT: Nf = `D_NF;
|
||||||
|
`H_FMT: Nf = `H_NF;
|
||||||
|
`Q_FMT: Nf = `Q_NF;
|
||||||
|
endcase
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
if (SqrtE) fbits = Nf + 2 + 2; // Nf + two fractional bits for round/guard + 2 for right shift by up to 2
|
||||||
|
else fbits = Nf + 2 + `LOGR; // Nf + two fractional bits for round/guard + integer bits - try this when placing results in msbs
|
||||||
|
if (`IDIV_ON_FPU) cycles = IntDivE ? ((nE + 1)/`DIVCOPIES) : (fbits + (`LOGR*`DIVCOPIES)-1)/(`LOGR*`DIVCOPIES);
|
||||||
|
else cycles = (fbits + (`LOGR*`DIVCOPIES)-1)/(`LOGR*`DIVCOPIES);
|
||||||
|
end
|
||||||
|
/* verilator lint_on WIDTH */
|
||||||
|
|
||||||
|
endmodule
|
@ -29,32 +29,27 @@
|
|||||||
`include "wally-config.vh"
|
`include "wally-config.vh"
|
||||||
|
|
||||||
module fdivsqrtfsm(
|
module fdivsqrtfsm(
|
||||||
input logic clk,
|
input logic clk, reset,
|
||||||
input logic reset,
|
input logic XInfE, YInfE,
|
||||||
input logic [`FMTBITS-1:0] FmtE,
|
input logic XZeroE, YZeroE,
|
||||||
input logic XInfE, YInfE,
|
input logic XNaNE, YNaNE,
|
||||||
input logic XZeroE, YZeroE,
|
input logic FDivStartE, IDivStartE,
|
||||||
input logic XNaNE, YNaNE,
|
input logic XsE, WZeroE,
|
||||||
input logic FDivStartE, IDivStartE,
|
input logic SqrtE,
|
||||||
input logic XsE,
|
input logic StallM, FlushE,
|
||||||
input logic SqrtE,
|
input logic IntDivE,
|
||||||
input logic StallM,
|
input logic ISpecialCaseE,
|
||||||
input logic FlushE,
|
input logic [`DURLEN-1:0] cycles,
|
||||||
input logic WZeroE,
|
output logic IFDivStartE,
|
||||||
input logic IntDivE,
|
output logic FDivBusyE, FDivDoneE,
|
||||||
input logic [`DIVBLEN:0] nE,
|
output logic SpecialCaseM
|
||||||
input logic ISpecialCaseE,
|
|
||||||
output logic IFDivStartE,
|
|
||||||
output logic FDivBusyE, FDivDoneE,
|
|
||||||
output logic SpecialCaseM
|
|
||||||
);
|
);
|
||||||
|
|
||||||
typedef enum logic [1:0] {IDLE, BUSY, DONE} statetype;
|
typedef enum logic [1:0] {IDLE, BUSY, DONE} statetype;
|
||||||
statetype state;
|
statetype state;
|
||||||
|
|
||||||
logic [`DURLEN-1:0] step;
|
|
||||||
logic [`DURLEN-1:0] cycles;
|
|
||||||
logic SpecialCaseE, FSpecialCaseE;
|
logic SpecialCaseE, FSpecialCaseE;
|
||||||
|
logic [`DURLEN-1:0] step;
|
||||||
|
|
||||||
// FDivStartE and IDivStartE come from fctrl, reflecitng the start of floating-point and possibly integer division
|
// FDivStartE and IDivStartE come from fctrl, reflecitng the start of floating-point and possibly integer division
|
||||||
assign IFDivStartE = (FDivStartE | (IDivStartE & `IDIV_ON_FPU)) & (state == IDLE) & ~StallM;
|
assign IFDivStartE = (FDivStartE | (IDivStartE & `IDIV_ON_FPU)) & (state == IDLE) & ~StallM;
|
||||||
@ -67,47 +62,6 @@ module fdivsqrtfsm(
|
|||||||
else assign SpecialCaseE = FSpecialCaseE;
|
else assign SpecialCaseE = FSpecialCaseE;
|
||||||
flopenr #(1) SpecialCaseReg(clk, reset, IFDivStartE, SpecialCaseE, SpecialCaseM); // save SpecialCase for checking in fdivsqrtpostproc
|
flopenr #(1) SpecialCaseReg(clk, reset, IFDivStartE, SpecialCaseE, SpecialCaseM); // save SpecialCase for checking in fdivsqrtpostproc
|
||||||
|
|
||||||
// DIVN = `NF+3
|
|
||||||
// NS = NF + 1
|
|
||||||
// N = NS or NS+2 for div/sqrt.
|
|
||||||
|
|
||||||
// *** CT 4/13/23 move cycles calculation back to preprocesor
|
|
||||||
/* verilator lint_off WIDTH */
|
|
||||||
logic [`DURLEN+1:0] Nf, fbits; // number of fractional bits
|
|
||||||
if (`FPSIZES == 1)
|
|
||||||
assign Nf = `NF;
|
|
||||||
else if (`FPSIZES == 2)
|
|
||||||
always_comb
|
|
||||||
case (FmtE)
|
|
||||||
1'b0: Nf = `NF1;
|
|
||||||
1'b1: Nf = `NF;
|
|
||||||
endcase
|
|
||||||
else if (`FPSIZES == 3)
|
|
||||||
always_comb
|
|
||||||
case (FmtE)
|
|
||||||
`FMT: Nf = `NF;
|
|
||||||
`FMT1: Nf = `NF1;
|
|
||||||
`FMT2: Nf = `NF2;
|
|
||||||
endcase
|
|
||||||
else if (`FPSIZES == 4)
|
|
||||||
always_comb
|
|
||||||
case(FmtE)
|
|
||||||
`S_FMT: Nf = `S_NF;
|
|
||||||
`D_FMT: Nf = `D_NF;
|
|
||||||
`H_FMT: Nf = `H_NF;
|
|
||||||
`Q_FMT: Nf = `Q_NF;
|
|
||||||
endcase
|
|
||||||
|
|
||||||
|
|
||||||
always_comb begin
|
|
||||||
if (SqrtE) fbits = Nf + 2 + 2; // Nf + two fractional bits for round/guard + 2 for right shift by up to 2
|
|
||||||
else fbits = Nf + 2 + `LOGR; // Nf + two fractional bits for round/guard + integer bits - try this when placing results in msbs
|
|
||||||
if (`IDIV_ON_FPU) cycles = IntDivE ? ((nE + 1)/`DIVCOPIES) : (fbits + (`LOGR*`DIVCOPIES)-1)/(`LOGR*`DIVCOPIES);
|
|
||||||
else cycles = (fbits + (`LOGR*`DIVCOPIES)-1)/(`LOGR*`DIVCOPIES);
|
|
||||||
end
|
|
||||||
|
|
||||||
/* verilator lint_on WIDTH */
|
|
||||||
|
|
||||||
always_ff @(posedge clk) begin
|
always_ff @(posedge clk) begin
|
||||||
if (reset | FlushE) begin
|
if (reset | FlushE) begin
|
||||||
state <= #1 IDLE;
|
state <= #1 IDLE;
|
||||||
|
@ -33,8 +33,8 @@ module fdivsqrtpreproc (
|
|||||||
input logic IFDivStartE,
|
input logic IFDivStartE,
|
||||||
input logic [`NF:0] Xm, Ym,
|
input logic [`NF:0] Xm, Ym,
|
||||||
input logic [`NE-1:0] Xe, Ye,
|
input logic [`NE-1:0] Xe, Ye,
|
||||||
input logic [`FMTBITS-1:0] Fmt,
|
input logic [`FMTBITS-1:0] FmtE,
|
||||||
input logic Sqrt,
|
input logic SqrtE,
|
||||||
input logic XZeroE,
|
input logic XZeroE,
|
||||||
input logic [2:0] Funct3E,
|
input logic [2:0] Funct3E,
|
||||||
output logic [`NE+1:0] QeM,
|
output logic [`NE+1:0] QeM,
|
||||||
@ -43,7 +43,8 @@ module fdivsqrtpreproc (
|
|||||||
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 [`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 IntDivE, W64E,
|
input logic IntDivE, W64E,
|
||||||
output logic ISpecialCaseE,
|
output logic ISpecialCaseE,
|
||||||
output logic [`DIVBLEN:0] nE, nM, mM,
|
output logic [`DURLEN-1:0] cycles,
|
||||||
|
output logic [`DIVBLEN:0] nM, mM,
|
||||||
output logic NegQuotM, ALTBM, IntDivM, W64M,
|
output logic NegQuotM, ALTBM, IntDivM, W64M,
|
||||||
output logic AsM, BZeroM,
|
output logic AsM, BZeroM,
|
||||||
output logic [`XLEN-1:0] AM
|
output logic [`XLEN-1:0] AM
|
||||||
@ -54,7 +55,7 @@ module fdivsqrtpreproc (
|
|||||||
logic [`DIVb+3:0] DivX, DivXShifted, SqrtX, PreShiftX; // Variations of dividend, to be muxed
|
logic [`DIVb+3:0] DivX, DivXShifted, SqrtX, PreShiftX; // Variations of dividend, to be muxed
|
||||||
logic [`NE+1:0] QeE; // Quotient Exponent (FP only)
|
logic [`NE+1:0] QeE; // Quotient Exponent (FP only)
|
||||||
logic [`DIVb-1:0] IFX, IFD; // Correctly-sized inputs for iterator, selected from int or fp input
|
logic [`DIVb-1:0] IFX, IFD; // Correctly-sized inputs for iterator, selected from int or fp input
|
||||||
logic [`DIVBLEN:0] mE, ell; // Leading zeros of inputs
|
logic [`DIVBLEN:0] mE, nE, ell; // Leading zeros of inputs
|
||||||
logic NumerZeroE; // Numerator is zero (X or A)
|
logic NumerZeroE; // Numerator is zero (X or A)
|
||||||
logic AZeroE, BZeroE; // A or B is Zero for integer division
|
logic AZeroE, BZeroE; // A or B is Zero for integer division
|
||||||
logic signedDiv; // signed division
|
logic signedDiv; // signed division
|
||||||
@ -169,10 +170,13 @@ module fdivsqrtpreproc (
|
|||||||
// Sqrt is initialized on step one as R(X-1), so depends on Radix
|
// Sqrt is initialized on step one as R(X-1), so depends on Radix
|
||||||
if (`RADIX == 2) assign SqrtX = {3'b111, PreSqrtX};
|
if (`RADIX == 2) assign SqrtX = {3'b111, PreSqrtX};
|
||||||
else assign SqrtX = {2'b11, PreSqrtX, 1'b0};
|
else assign SqrtX = {2'b11, PreSqrtX, 1'b0};
|
||||||
mux2 #(`DIVb+4) prexmux(DivX, SqrtX, Sqrt, PreShiftX);
|
mux2 #(`DIVb+4) prexmux(DivX, SqrtX, SqrtE, PreShiftX);
|
||||||
|
|
||||||
// Floating-point exponent
|
// Floating-point exponent
|
||||||
fdivsqrtexpcalc expcalc(.Fmt, .Xe, .Ye, .Sqrt, .XZero(XZeroE), .ell, .m(mE), .Qe(QeE));
|
fdivsqrtexpcalc expcalc(.Fmt(FmtE), .Xe, .Ye, .Sqrt(SqrtE), .XZero(XZeroE), .ell, .m(mE), .Qe(QeE));
|
||||||
flopen #(`NE+2) expreg(clk, IFDivStartE, QeE, QeM);
|
flopen #(`NE+2) expreg(clk, IFDivStartE, QeE, QeM);
|
||||||
|
|
||||||
|
// Number of FSM cycles (to FSM)
|
||||||
|
fdivsqrtcycles cyclecalc(.FmtE, .SqrtE, .IntDivE, .nE, .cycles);
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user