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] 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+1:0] FirstC; // Step tracker
|
||||
logic Firstun; // Quotient selection
|
||||
logic WZeroE; // Early termination flag
|
||||
logic [`DURLEN-1:0] cycles; // 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] nE, nM, mM; // Shift amounts
|
||||
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
|
||||
|
||||
fdivsqrtpreproc fdivsqrtpreproc( // Preprocessor
|
||||
.clk, .IFDivStartE, .Xm(XmE), .Ym(YmE), .Xe(XeE), .Ye(YeE),
|
||||
.Fmt(FmtE), .Sqrt(SqrtE), .XZeroE, .Funct3E, .QeM, .X, .D,
|
||||
fdivsqrtpreproc fdivsqrtpreproc( // Preprocessor
|
||||
.clk, .IFDivStartE, .Xm(XmE), .Ym(YmE), .Xe(XeE), .Ye(YeE),
|
||||
.FmtE, .SqrtE, .XZeroE, .Funct3E, .QeM, .X, .D, .cycles,
|
||||
// Int-specific
|
||||
.ForwardedSrcAE, .ForwardedSrcBE, .IntDivE, .W64E, .ISpecialCaseE,
|
||||
.nE, .BZeroM, .nM, .mM, .AM,
|
||||
.BZeroM, .nM, .mM, .AM,
|
||||
.IntDivM, .W64M, .NegQuotM, .ALTBM, .AsM);
|
||||
|
||||
fdivsqrtfsm fdivsqrtfsm( // FSM
|
||||
.clk, .reset, .FmtE, .XInfE, .YInfE, .XZeroE, .YZeroE, .XNaNE, .YNaNE,
|
||||
fdivsqrtfsm fdivsqrtfsm( // FSM
|
||||
.clk, .reset, .XInfE, .YInfE, .XZeroE, .YZeroE, .XNaNE, .YNaNE,
|
||||
.FDivStartE, .XsE, .SqrtE, .WZeroE, .FlushE, .StallM,
|
||||
.FDivBusyE, .IFDivStartE, .FDivDoneE, .SpecialCaseM,
|
||||
.FDivBusyE, .IFDivStartE, .FDivDoneE, .SpecialCaseM, .cycles,
|
||||
// Int-specific
|
||||
.IDivStartE, .ISpecialCaseE, .nE, .IntDivE);
|
||||
.IDivStartE, .ISpecialCaseE, .IntDivE);
|
||||
|
||||
fdivsqrtiter fdivsqrtiter( // CSA Iterator
|
||||
fdivsqrtiter fdivsqrtiter( // CSA Iterator
|
||||
.clk, .IFDivStartE, .FDivBusyE, .SqrtE, .X, .D,
|
||||
.FirstU, .FirstUM, .FirstC, .Firstun, .FirstWS(WS), .FirstWC(WC));
|
||||
|
||||
fdivsqrtpostproc fdivsqrtpostproc( // Postprocessor
|
||||
fdivsqrtpostproc fdivsqrtpostproc( // Postprocessor
|
||||
.clk, .reset, .StallM, .WS, .WC, .D, .FirstU, .FirstUM, .FirstC,
|
||||
.SqrtE, .Firstun, .SqrtM, .SpecialCaseM,
|
||||
.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"
|
||||
|
||||
module fdivsqrtfsm(
|
||||
input logic clk,
|
||||
input logic reset,
|
||||
input logic [`FMTBITS-1:0] FmtE,
|
||||
input logic XInfE, YInfE,
|
||||
input logic XZeroE, YZeroE,
|
||||
input logic XNaNE, YNaNE,
|
||||
input logic FDivStartE, IDivStartE,
|
||||
input logic XsE,
|
||||
input logic SqrtE,
|
||||
input logic StallM,
|
||||
input logic FlushE,
|
||||
input logic WZeroE,
|
||||
input logic IntDivE,
|
||||
input logic [`DIVBLEN:0] nE,
|
||||
input logic ISpecialCaseE,
|
||||
output logic IFDivStartE,
|
||||
output logic FDivBusyE, FDivDoneE,
|
||||
output logic SpecialCaseM
|
||||
input logic clk, reset,
|
||||
input logic XInfE, YInfE,
|
||||
input logic XZeroE, YZeroE,
|
||||
input logic XNaNE, YNaNE,
|
||||
input logic FDivStartE, IDivStartE,
|
||||
input logic XsE, WZeroE,
|
||||
input logic SqrtE,
|
||||
input logic StallM, FlushE,
|
||||
input logic IntDivE,
|
||||
input logic ISpecialCaseE,
|
||||
input logic [`DURLEN-1:0] cycles,
|
||||
output logic IFDivStartE,
|
||||
output logic FDivBusyE, FDivDoneE,
|
||||
output logic SpecialCaseM
|
||||
);
|
||||
|
||||
typedef enum logic [1:0] {IDLE, BUSY, DONE} statetype;
|
||||
statetype state;
|
||||
|
||||
logic [`DURLEN-1:0] step;
|
||||
logic [`DURLEN-1:0] cycles;
|
||||
logic SpecialCaseE, FSpecialCaseE;
|
||||
logic [`DURLEN-1:0] step;
|
||||
|
||||
// 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;
|
||||
@ -67,47 +62,6 @@ module fdivsqrtfsm(
|
||||
else assign SpecialCaseE = FSpecialCaseE;
|
||||
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
|
||||
if (reset | FlushE) begin
|
||||
state <= #1 IDLE;
|
||||
|
@ -33,8 +33,8 @@ module fdivsqrtpreproc (
|
||||
input logic IFDivStartE,
|
||||
input logic [`NF:0] Xm, Ym,
|
||||
input logic [`NE-1:0] Xe, Ye,
|
||||
input logic [`FMTBITS-1:0] Fmt,
|
||||
input logic Sqrt,
|
||||
input logic [`FMTBITS-1:0] FmtE,
|
||||
input logic SqrtE,
|
||||
input logic XZeroE,
|
||||
input logic [2:0] Funct3E,
|
||||
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 IntDivE, W64E,
|
||||
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 AsM, BZeroM,
|
||||
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 [`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 [`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 AZeroE, BZeroE; // A or B is Zero for integer 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
|
||||
if (`RADIX == 2) assign SqrtX = {3'b111, PreSqrtX};
|
||||
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
|
||||
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);
|
||||
|
||||
// Number of FSM cycles (to FSM)
|
||||
fdivsqrtcycles cyclecalc(.FmtE, .SqrtE, .IntDivE, .nE, .cycles);
|
||||
endmodule
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user