mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Removed unnecessary muxes from shiftcorrection; changed flag to --nightly in lint-wally
This commit is contained in:
parent
135e2753ac
commit
db330b35b2
@ -11,7 +11,7 @@ GREEN='\033[0;32m'
|
|||||||
NC='\033[0m' # No Color
|
NC='\033[0m' # No Color
|
||||||
fails=0
|
fails=0
|
||||||
|
|
||||||
if [ "$1" == "-nightly" ]; then
|
if [ "$1" == "--nightly" ]; then
|
||||||
configs=(rv32e rv64gc rv32gc rv32imc rv32i rv64i) # fdqh_rv64gc
|
configs=(rv32e rv64gc rv32gc rv32imc rv32i rv64i) # fdqh_rv64gc
|
||||||
derivconfigs=`ls $WALLY/config/deriv`
|
derivconfigs=`ls $WALLY/config/deriv`
|
||||||
for entry in $derivconfigs
|
for entry in $derivconfigs
|
||||||
|
@ -99,7 +99,6 @@ localparam RK = LOGR*DIVCOPIES; // r*k bits
|
|||||||
|
|
||||||
// intermediate division parameters not directly used in fdivsqrt hardware
|
// intermediate division parameters not directly used in fdivsqrt hardware
|
||||||
localparam FPDIVMINb = NF + 2; // minimum length of fractional part: Nf result bits + guard and round bits + 1 extra bit to allow sqrt being shifted right
|
localparam FPDIVMINb = NF + 2; // minimum length of fractional part: Nf result bits + guard and round bits + 1 extra bit to allow sqrt being shifted right
|
||||||
//localparam FPDIVMINb = NF + 2 + (RADIX == 2); // minimum length of fractional part: Nf result bits + guard and round bits + 1 extra bit for preshifting radix2 square root right, if radix4 doesn't use a right shift. This version saves one cycle on double-precision with R=4,k=4. However, it doesn't work yet because C is too short, so k is incorrectly calculated as a 1 in the lsb after the last step.
|
|
||||||
localparam DIVMINb = ((FPDIVMINb<XLEN) & IDIV_ON_FPU) ? XLEN : FPDIVMINb; // minimum fractional bits b = max(XLEN, FPDIVMINb)
|
localparam DIVMINb = ((FPDIVMINb<XLEN) & IDIV_ON_FPU) ? XLEN : FPDIVMINb; // minimum fractional bits b = max(XLEN, FPDIVMINb)
|
||||||
localparam RESBITS = DIVMINb + LOGR; // number of bits in a result: r integer + b fractional
|
localparam RESBITS = DIVMINb + LOGR; // number of bits in a result: r integer + b fractional
|
||||||
|
|
||||||
@ -111,12 +110,18 @@ localparam DIVBLEN = $clog2(DIVb+1); // enough bi
|
|||||||
|
|
||||||
// largest length in IEU/FPU
|
// largest length in IEU/FPU
|
||||||
localparam BASECVTLEN = `max(XLEN, NF); // convert length excluding Zfa fcvtmod.w.d
|
localparam BASECVTLEN = `max(XLEN, NF); // convert length excluding Zfa fcvtmod.w.d
|
||||||
localparam CVTLEN = ZFA_SUPPORTED ? `max(BASECVTLEN, 32'd84) : BASECVTLEN; // fcvtmod.w.d needs at least 32+52 because a double with 52 fractional bits might be into upper bits of 32 bit word
|
localparam CVTLEN = (ZFA_SUPPORTED & D_SUPPORTED) ? `max(BASECVTLEN, 32'd84) : BASECVTLEN; // fcvtmod.w.d needs at least 32+52 because a double with 52 fractional bits might be into upper bits of 32 bit word
|
||||||
localparam LLEN = `max($unsigned(FLEN), $unsigned(XLEN));
|
localparam LLEN = `max($unsigned(FLEN), $unsigned(XLEN));
|
||||||
localparam LOGCVTLEN = $unsigned($clog2(CVTLEN+1));
|
localparam LOGCVTLEN = $unsigned($clog2(CVTLEN+1));
|
||||||
|
|
||||||
|
// NORMSHIFTSIZE is the bits out of the normalization shifter
|
||||||
|
// RV32F: max(32+23+1, 2(23)+4, 3(23)+6) = 3*23+6 = 75
|
||||||
|
// RV64F: max(64+23+1, 64 + 23 + 2, 3*23+6) = 89
|
||||||
|
// RV64D: max(84+52+1, 64+52+2, 3*52+6) = 162
|
||||||
localparam NORMSHIFTSZ = `max(`max((CVTLEN+NF+1), (DIVb + 1 + NF + 1)), (3*NF+6));
|
localparam NORMSHIFTSZ = `max(`max((CVTLEN+NF+1), (DIVb + 1 + NF + 1)), (3*NF+6));
|
||||||
localparam LOGNORMSHIFTSZ = ($clog2(NORMSHIFTSZ));
|
|
||||||
localparam CORRSHIFTSZ = `max((NORMSHIFTSZ-2), (DIVMINb + 1 + NF));
|
localparam LOGNORMSHIFTSZ = ($clog2(NORMSHIFTSZ)); // log_2(NORMSHIFTSZ)
|
||||||
|
localparam CORRSHIFTSZ = NORMSHIFTSZ-2; // Drop leading 2 integer bits
|
||||||
|
|
||||||
|
|
||||||
// Disable spurious Verilator warnings
|
// Disable spurious Verilator warnings
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
module shiftcorrection import cvw::*; #(parameter cvw_t P) (
|
module shiftcorrection import cvw::*; #(parameter cvw_t P) (
|
||||||
input logic [P.NORMSHIFTSZ-1:0] Shifted, // the shifted sum before LZA correction
|
input logic [P.NORMSHIFTSZ-1:0] Shifted, // normalization shifter output
|
||||||
// divsqrt
|
// divsqrt
|
||||||
input logic DivOp, // is it a divsqrt operation
|
input logic DivOp, // is it a divsqrt operation
|
||||||
input logic DivResSubnorm, // is the divsqrt result subnormal
|
input logic DivResSubnorm, // is the divsqrt result subnormal
|
||||||
@ -41,37 +41,39 @@ module shiftcorrection import cvw::*; #(parameter cvw_t P) (
|
|||||||
input logic FmaSZero,
|
input logic FmaSZero,
|
||||||
// output
|
// output
|
||||||
output logic [P.NE+1:0] FmaMe, // exponent of the normalized sum
|
output logic [P.NE+1:0] FmaMe, // exponent of the normalized sum
|
||||||
output logic [P.CORRSHIFTSZ-1:0] Mf, // the shifted sum before LZA correction
|
output logic [P.CORRSHIFTSZ-1:0] Mf, // the shifted sum after correction
|
||||||
output logic [P.NE+1:0] Ue // corrected exponent for divider
|
output logic [P.NE+1:0] Ue // corrected exponent for divider
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [P.CORRSHIFTSZ-1:0] CorrSumShifted; // the shifted sum after LZA correction
|
logic [P.CORRSHIFTSZ-1:0] CorrShifted; // the shifted sum after LZA correction
|
||||||
logic [P.CORRSHIFTSZ-1:0] CorrQm0, CorrQm1; // portions of Shifted to select for CorrQmShifted
|
|
||||||
logic [P.CORRSHIFTSZ-1:0] CorrQmShifted; // the shifted divsqrt result after one bit shift
|
|
||||||
logic ResSubnorm; // is the result Subnormal
|
logic ResSubnorm; // is the result Subnormal
|
||||||
logic LZAPlus1; // add one or two to the sum's exponent due to LZA correction
|
logic LZAPlus1; // add one or two to the sum's exponent due to LZA correction
|
||||||
logic LeftShiftQm; // should the divsqrt result be shifted one to the left
|
logic LeftShiftQm; // should the divsqrt result be shifted one to the left
|
||||||
|
logic RightShift; // shift right by 1
|
||||||
|
|
||||||
// LZA correction
|
// *** 4/16/24 this code is a mess and needs cleaning and explaining
|
||||||
assign LZAPlus1 = Shifted[P.NORMSHIFTSZ-1];
|
// define bit widths
|
||||||
|
// seems to shift by 0, 1, or 2. right and left shift is confusing
|
||||||
|
|
||||||
|
// FMA LZA correction
|
||||||
// correct the shifting error caused by the LZA
|
// correct the shifting error caused by the LZA
|
||||||
// - the only possible mantissa for a plus two is all zeroes
|
// - the only possible mantissa for a plus two is all zeroes
|
||||||
// - a one has to propigate all the way through a sum. so we can leave the bottom statement alone
|
// - a one has to propagate all the way through a sum. so we can leave the bottom statement alone
|
||||||
mux2 #(P.NORMSHIFTSZ-2) lzacorrmux(Shifted[P.NORMSHIFTSZ-3:0], Shifted[P.NORMSHIFTSZ-2:1], LZAPlus1, CorrSumShifted);
|
assign LZAPlus1 = Shifted[P.NORMSHIFTSZ-1];
|
||||||
|
|
||||||
// correct the shifting of the divsqrt caused by producing a result in (2, .5] range
|
// correct the shifting of the divsqrt caused by producing a result in (0.5, 2) range
|
||||||
// condition: if the msb is 1 or the exponent was one, but the shifted quotent was < 1 (Subnorm)
|
// condition: if the msb is 1 or the exponent was one, but the shifted quotent was < 1 (Subnorm)
|
||||||
assign LeftShiftQm = (LZAPlus1|(DivUe==1&~LZAPlus1));
|
assign LeftShiftQm = (LZAPlus1|(DivUe==1&~LZAPlus1));
|
||||||
assign CorrQm0 = Shifted[P.NORMSHIFTSZ-3:P.NORMSHIFTSZ-P.CORRSHIFTSZ-2];
|
|
||||||
assign CorrQm1 = Shifted[P.NORMSHIFTSZ-2:P.NORMSHIFTSZ-P.CORRSHIFTSZ-1];
|
assign RightShift = FmaOp ? LZAPlus1 : LeftShiftQm;
|
||||||
mux2 #(P.CORRSHIFTSZ) divcorrmux(CorrQm0, CorrQm1, LeftShiftQm, CorrQmShifted);
|
|
||||||
|
// one bit right shift for FMA or division
|
||||||
|
mux2 #(P.NORMSHIFTSZ-2) corrmux(Shifted[P.NORMSHIFTSZ-3:0], Shifted[P.NORMSHIFTSZ-2:1], RightShift, CorrShifted);
|
||||||
|
|
||||||
// if the result of the divider was calculated to be subnormal, then the result was correctly normalized, so select the top shifted bits
|
// if the result of the divider was calculated to be subnormal, then the result was correctly normalized, so select the top shifted bits
|
||||||
always_comb
|
always_comb
|
||||||
if(FmaOp) Mf = {CorrSumShifted};
|
if (FmaOp | DivOp & !DivResSubnorm) Mf = CorrShifted;
|
||||||
else if (DivOp&~DivResSubnorm) Mf = CorrQmShifted;
|
else Mf = Shifted[P.NORMSHIFTSZ-1:2];
|
||||||
else Mf = Shifted[P.NORMSHIFTSZ-1:P.NORMSHIFTSZ-P.CORRSHIFTSZ];
|
|
||||||
|
|
||||||
// Determine sum's exponent
|
// Determine sum's exponent
|
||||||
// main exponent issues:
|
// main exponent issues:
|
||||||
@ -86,7 +88,7 @@ module shiftcorrection import cvw::*; #(parameter cvw_t P) (
|
|||||||
// recalculate if the result is subnormal after LZA correction
|
// recalculate if the result is subnormal after LZA correction
|
||||||
assign ResSubnorm = FmaPreResultSubnorm&~Shifted[P.NORMSHIFTSZ-2]&~Shifted[P.NORMSHIFTSZ-1];
|
assign ResSubnorm = FmaPreResultSubnorm&~Shifted[P.NORMSHIFTSZ-2]&~Shifted[P.NORMSHIFTSZ-1];
|
||||||
|
|
||||||
// the quotent is in the range [.5,2) if there is no early termination
|
// the quotent is in the range (.5,2) if there is no early termination
|
||||||
// if the quotent < 1 and not Subnormal then subtract 1 to account for the normalization shift
|
// 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 & DivSubnormShiftPos) ? 0 : DivUe - {(P.NE+1)'(0), ~LZAPlus1};
|
||||||
endmodule
|
endmodule
|
||||||
|
Loading…
Reference in New Issue
Block a user